@angular/router 19.0.0-next.0 → 19.0.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +1 -1
  2. package/fesm2022/router.mjs +86 -96
  3. package/fesm2022/router.mjs.map +1 -1
  4. package/fesm2022/testing.mjs +11 -11
  5. package/fesm2022/upgrade.mjs +1 -1
  6. package/index.d.ts +1 -1
  7. package/package.json +4 -10
  8. package/testing/index.d.ts +1 -1
  9. package/upgrade/index.d.ts +1 -1
  10. package/esm2022/index.mjs +0 -13
  11. package/esm2022/public_api.mjs +0 -15
  12. package/esm2022/router.mjs +0 -5
  13. package/esm2022/src/apply_redirects.mjs +0 -124
  14. package/esm2022/src/components/empty_outlet.mjs +0 -49
  15. package/esm2022/src/create_router_state.mjs +0 -52
  16. package/esm2022/src/create_url_tree.mjs +0 -420
  17. package/esm2022/src/directives/router_link.mjs +0 -361
  18. package/esm2022/src/directives/router_link_active.mjs +0 -237
  19. package/esm2022/src/directives/router_outlet.mjs +0 -388
  20. package/esm2022/src/errors.mjs +0 -2
  21. package/esm2022/src/events.mjs +0 -588
  22. package/esm2022/src/index.mjs +0 -31
  23. package/esm2022/src/models.mjs +0 -45
  24. package/esm2022/src/models_deprecated.mjs +0 -9
  25. package/esm2022/src/navigation_canceling_error.mjs +0 -33
  26. package/esm2022/src/navigation_transition.mjs +0 -437
  27. package/esm2022/src/operators/activate_routes.mjs +0 -190
  28. package/esm2022/src/operators/check_guards.mjs +0 -157
  29. package/esm2022/src/operators/prioritized_guard_value.mjs +0 -40
  30. package/esm2022/src/operators/recognize.mjs +0 -15
  31. package/esm2022/src/operators/resolve_data.mjs +0 -92
  32. package/esm2022/src/operators/switch_tap.mjs +0 -25
  33. package/esm2022/src/page_title_strategy.mjs +0 -89
  34. package/esm2022/src/private_export.mjs +0 -12
  35. package/esm2022/src/provide_router.mjs +0 -549
  36. package/esm2022/src/recognize.mjs +0 -321
  37. package/esm2022/src/route_reuse_strategy.mjs +0 -79
  38. package/esm2022/src/router.mjs +0 -571
  39. package/esm2022/src/router_config.mjs +0 -18
  40. package/esm2022/src/router_config_loader.mjs +0 -137
  41. package/esm2022/src/router_module.mjs +0 -226
  42. package/esm2022/src/router_outlet_context.mjs +0 -90
  43. package/esm2022/src/router_preloader.mjs +0 -162
  44. package/esm2022/src/router_scroller.mjs +0 -111
  45. package/esm2022/src/router_state.mjs +0 -419
  46. package/esm2022/src/shared.mjs +0 -97
  47. package/esm2022/src/statemanager/state_manager.mjs +0 -200
  48. package/esm2022/src/url_handling_strategy.mjs +0 -45
  49. package/esm2022/src/url_tree.mjs +0 -643
  50. package/esm2022/src/utils/collection.mjs +0 -75
  51. package/esm2022/src/utils/config.mjs +0 -191
  52. package/esm2022/src/utils/config_matching.mjs +0 -150
  53. package/esm2022/src/utils/functional_guards.mjs +0 -69
  54. package/esm2022/src/utils/navigations.mjs +0 -44
  55. package/esm2022/src/utils/preactivation.mjs +0 -154
  56. package/esm2022/src/utils/tree.mjs +0 -94
  57. package/esm2022/src/utils/type_guards.mjs +0 -46
  58. package/esm2022/src/utils/view_transition.mjs +0 -61
  59. package/esm2022/src/version.mjs +0 -18
  60. package/esm2022/testing/index.mjs +0 -13
  61. package/esm2022/testing/public_api.mjs +0 -15
  62. package/esm2022/testing/src/router_testing_harness.mjs +0 -127
  63. package/esm2022/testing/src/router_testing_module.mjs +0 -75
  64. package/esm2022/testing/src/testing.mjs +0 -15
  65. package/esm2022/testing/testing.mjs +0 -5
  66. package/esm2022/upgrade/index.mjs +0 -13
  67. package/esm2022/upgrade/public_api.mjs +0 -15
  68. package/esm2022/upgrade/src/upgrade.mjs +0 -128
  69. package/esm2022/upgrade/upgrade.mjs +0 -5
@@ -1,643 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC All Rights Reserved.
4
- *
5
- * Use of this source code is governed by an MIT-style license that can be
6
- * found in the LICENSE file at https://angular.io/license
7
- */
8
- import { Injectable, ɵRuntimeError as RuntimeError } from '@angular/core';
9
- import { convertToParamMap, PRIMARY_OUTLET } from './shared';
10
- import { equalArraysOrString, shallowEqual } from './utils/collection';
11
- import * as i0 from "@angular/core";
12
- const pathCompareMap = {
13
- 'exact': equalSegmentGroups,
14
- 'subset': containsSegmentGroup,
15
- };
16
- const paramCompareMap = {
17
- 'exact': equalParams,
18
- 'subset': containsParams,
19
- 'ignored': () => true,
20
- };
21
- export function containsTree(container, containee, options) {
22
- return (pathCompareMap[options.paths](container.root, containee.root, options.matrixParams) &&
23
- paramCompareMap[options.queryParams](container.queryParams, containee.queryParams) &&
24
- !(options.fragment === 'exact' && container.fragment !== containee.fragment));
25
- }
26
- function equalParams(container, containee) {
27
- // TODO: This does not handle array params correctly.
28
- return shallowEqual(container, containee);
29
- }
30
- function equalSegmentGroups(container, containee, matrixParams) {
31
- if (!equalPath(container.segments, containee.segments))
32
- return false;
33
- if (!matrixParamsMatch(container.segments, containee.segments, matrixParams)) {
34
- return false;
35
- }
36
- if (container.numberOfChildren !== containee.numberOfChildren)
37
- return false;
38
- for (const c in containee.children) {
39
- if (!container.children[c])
40
- return false;
41
- if (!equalSegmentGroups(container.children[c], containee.children[c], matrixParams))
42
- return false;
43
- }
44
- return true;
45
- }
46
- function containsParams(container, containee) {
47
- return (Object.keys(containee).length <= Object.keys(container).length &&
48
- Object.keys(containee).every((key) => equalArraysOrString(container[key], containee[key])));
49
- }
50
- function containsSegmentGroup(container, containee, matrixParams) {
51
- return containsSegmentGroupHelper(container, containee, containee.segments, matrixParams);
52
- }
53
- function containsSegmentGroupHelper(container, containee, containeePaths, matrixParams) {
54
- if (container.segments.length > containeePaths.length) {
55
- const current = container.segments.slice(0, containeePaths.length);
56
- if (!equalPath(current, containeePaths))
57
- return false;
58
- if (containee.hasChildren())
59
- return false;
60
- if (!matrixParamsMatch(current, containeePaths, matrixParams))
61
- return false;
62
- return true;
63
- }
64
- else if (container.segments.length === containeePaths.length) {
65
- if (!equalPath(container.segments, containeePaths))
66
- return false;
67
- if (!matrixParamsMatch(container.segments, containeePaths, matrixParams))
68
- return false;
69
- for (const c in containee.children) {
70
- if (!container.children[c])
71
- return false;
72
- if (!containsSegmentGroup(container.children[c], containee.children[c], matrixParams)) {
73
- return false;
74
- }
75
- }
76
- return true;
77
- }
78
- else {
79
- const current = containeePaths.slice(0, container.segments.length);
80
- const next = containeePaths.slice(container.segments.length);
81
- if (!equalPath(container.segments, current))
82
- return false;
83
- if (!matrixParamsMatch(container.segments, current, matrixParams))
84
- return false;
85
- if (!container.children[PRIMARY_OUTLET])
86
- return false;
87
- return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next, matrixParams);
88
- }
89
- }
90
- function matrixParamsMatch(containerPaths, containeePaths, options) {
91
- return containeePaths.every((containeeSegment, i) => {
92
- return paramCompareMap[options](containerPaths[i].parameters, containeeSegment.parameters);
93
- });
94
- }
95
- /**
96
- * @description
97
- *
98
- * Represents the parsed URL.
99
- *
100
- * Since a router state is a tree, and the URL is nothing but a serialized state, the URL is a
101
- * serialized tree.
102
- * UrlTree is a data structure that provides a lot of affordances in dealing with URLs
103
- *
104
- * @usageNotes
105
- * ### Example
106
- *
107
- * ```
108
- * @Component({templateUrl:'template.html'})
109
- * class MyComponent {
110
- * constructor(router: Router) {
111
- * const tree: UrlTree =
112
- * router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment');
113
- * const f = tree.fragment; // return 'fragment'
114
- * const q = tree.queryParams; // returns {debug: 'true'}
115
- * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
116
- * const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33'
117
- * g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor'
118
- * g.children['support'].segments; // return 1 segment 'help'
119
- * }
120
- * }
121
- * ```
122
- *
123
- * @publicApi
124
- */
125
- export class UrlTree {
126
- constructor(
127
- /** The root segment group of the URL tree */
128
- root = new UrlSegmentGroup([], {}),
129
- /** The query params of the URL */
130
- queryParams = {},
131
- /** The fragment of the URL */
132
- fragment = null) {
133
- this.root = root;
134
- this.queryParams = queryParams;
135
- this.fragment = fragment;
136
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
137
- if (root.segments.length > 0) {
138
- throw new RuntimeError(4015 /* RuntimeErrorCode.INVALID_ROOT_URL_SEGMENT */, 'The root `UrlSegmentGroup` should not contain `segments`. ' +
139
- 'Instead, these segments belong in the `children` so they can be associated with a named outlet.');
140
- }
141
- }
142
- }
143
- get queryParamMap() {
144
- this._queryParamMap ??= convertToParamMap(this.queryParams);
145
- return this._queryParamMap;
146
- }
147
- /** @docsNotRequired */
148
- toString() {
149
- return DEFAULT_SERIALIZER.serialize(this);
150
- }
151
- }
152
- /**
153
- * @description
154
- *
155
- * Represents the parsed URL segment group.
156
- *
157
- * See `UrlTree` for more information.
158
- *
159
- * @publicApi
160
- */
161
- export class UrlSegmentGroup {
162
- constructor(
163
- /** The URL segments of this group. See `UrlSegment` for more information */
164
- segments,
165
- /** The list of children of this group */
166
- children) {
167
- this.segments = segments;
168
- this.children = children;
169
- /** The parent node in the url tree */
170
- this.parent = null;
171
- Object.values(children).forEach((v) => (v.parent = this));
172
- }
173
- /** Whether the segment has child segments */
174
- hasChildren() {
175
- return this.numberOfChildren > 0;
176
- }
177
- /** Number of child segments */
178
- get numberOfChildren() {
179
- return Object.keys(this.children).length;
180
- }
181
- /** @docsNotRequired */
182
- toString() {
183
- return serializePaths(this);
184
- }
185
- }
186
- /**
187
- * @description
188
- *
189
- * Represents a single URL segment.
190
- *
191
- * A UrlSegment is a part of a URL between the two slashes. It contains a path and the matrix
192
- * parameters associated with the segment.
193
- *
194
- * @usageNotes
195
- * ### Example
196
- *
197
- * ```
198
- * @Component({templateUrl:'template.html'})
199
- * class MyComponent {
200
- * constructor(router: Router) {
201
- * const tree: UrlTree = router.parseUrl('/team;id=33');
202
- * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
203
- * const s: UrlSegment[] = g.segments;
204
- * s[0].path; // returns 'team'
205
- * s[0].parameters; // returns {id: 33}
206
- * }
207
- * }
208
- * ```
209
- *
210
- * @publicApi
211
- */
212
- export class UrlSegment {
213
- constructor(
214
- /** The path part of a URL segment */
215
- path,
216
- /** The matrix parameters associated with a segment */
217
- parameters) {
218
- this.path = path;
219
- this.parameters = parameters;
220
- }
221
- get parameterMap() {
222
- this._parameterMap ??= convertToParamMap(this.parameters);
223
- return this._parameterMap;
224
- }
225
- /** @docsNotRequired */
226
- toString() {
227
- return serializePath(this);
228
- }
229
- }
230
- export function equalSegments(as, bs) {
231
- return equalPath(as, bs) && as.every((a, i) => shallowEqual(a.parameters, bs[i].parameters));
232
- }
233
- export function equalPath(as, bs) {
234
- if (as.length !== bs.length)
235
- return false;
236
- return as.every((a, i) => a.path === bs[i].path);
237
- }
238
- export function mapChildrenIntoArray(segment, fn) {
239
- let res = [];
240
- Object.entries(segment.children).forEach(([childOutlet, child]) => {
241
- if (childOutlet === PRIMARY_OUTLET) {
242
- res = res.concat(fn(child, childOutlet));
243
- }
244
- });
245
- Object.entries(segment.children).forEach(([childOutlet, child]) => {
246
- if (childOutlet !== PRIMARY_OUTLET) {
247
- res = res.concat(fn(child, childOutlet));
248
- }
249
- });
250
- return res;
251
- }
252
- /**
253
- * @description
254
- *
255
- * Serializes and deserializes a URL string into a URL tree.
256
- *
257
- * The url serialization strategy is customizable. You can
258
- * make all URLs case insensitive by providing a custom UrlSerializer.
259
- *
260
- * See `DefaultUrlSerializer` for an example of a URL serializer.
261
- *
262
- * @publicApi
263
- */
264
- export class UrlSerializer {
265
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0-next.0", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
266
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.0-next.0", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() }); }
267
- }
268
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0-next.0", ngImport: i0, type: UrlSerializer, decorators: [{
269
- type: Injectable,
270
- args: [{ providedIn: 'root', useFactory: () => new DefaultUrlSerializer() }]
271
- }] });
272
- /**
273
- * @description
274
- *
275
- * A default implementation of the `UrlSerializer`.
276
- *
277
- * Example URLs:
278
- *
279
- * ```
280
- * /inbox/33(popup:compose)
281
- * /inbox/33;open=true/messages/44
282
- * ```
283
- *
284
- * DefaultUrlSerializer uses parentheses to serialize secondary segments (e.g., popup:compose), the
285
- * colon syntax to specify the outlet, and the ';parameter=value' syntax (e.g., open=true) to
286
- * specify route specific parameters.
287
- *
288
- * @publicApi
289
- */
290
- export class DefaultUrlSerializer {
291
- /** Parses a url into a `UrlTree` */
292
- parse(url) {
293
- const p = new UrlParser(url);
294
- return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
295
- }
296
- /** Converts a `UrlTree` into a url */
297
- serialize(tree) {
298
- const segment = `/${serializeSegment(tree.root, true)}`;
299
- const query = serializeQueryParams(tree.queryParams);
300
- const fragment = typeof tree.fragment === `string` ? `#${encodeUriFragment(tree.fragment)}` : '';
301
- return `${segment}${query}${fragment}`;
302
- }
303
- }
304
- const DEFAULT_SERIALIZER = new DefaultUrlSerializer();
305
- export function serializePaths(segment) {
306
- return segment.segments.map((p) => serializePath(p)).join('/');
307
- }
308
- function serializeSegment(segment, root) {
309
- if (!segment.hasChildren()) {
310
- return serializePaths(segment);
311
- }
312
- if (root) {
313
- const primary = segment.children[PRIMARY_OUTLET]
314
- ? serializeSegment(segment.children[PRIMARY_OUTLET], false)
315
- : '';
316
- const children = [];
317
- Object.entries(segment.children).forEach(([k, v]) => {
318
- if (k !== PRIMARY_OUTLET) {
319
- children.push(`${k}:${serializeSegment(v, false)}`);
320
- }
321
- });
322
- return children.length > 0 ? `${primary}(${children.join('//')})` : primary;
323
- }
324
- else {
325
- const children = mapChildrenIntoArray(segment, (v, k) => {
326
- if (k === PRIMARY_OUTLET) {
327
- return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
328
- }
329
- return [`${k}:${serializeSegment(v, false)}`];
330
- });
331
- // use no parenthesis if the only child is a primary outlet route
332
- if (Object.keys(segment.children).length === 1 && segment.children[PRIMARY_OUTLET] != null) {
333
- return `${serializePaths(segment)}/${children[0]}`;
334
- }
335
- return `${serializePaths(segment)}/(${children.join('//')})`;
336
- }
337
- }
338
- /**
339
- * Encodes a URI string with the default encoding. This function will only ever be called from
340
- * `encodeUriQuery` or `encodeUriSegment` as it's the base set of encodings to be used. We need
341
- * a custom encoding because encodeURIComponent is too aggressive and encodes stuff that doesn't
342
- * have to be encoded per https://url.spec.whatwg.org.
343
- */
344
- function encodeUriString(s) {
345
- return encodeURIComponent(s)
346
- .replace(/%40/g, '@')
347
- .replace(/%3A/gi, ':')
348
- .replace(/%24/g, '$')
349
- .replace(/%2C/gi, ',');
350
- }
351
- /**
352
- * This function should be used to encode both keys and values in a query string key/value. In
353
- * the following URL, you need to call encodeUriQuery on "k" and "v":
354
- *
355
- * http://www.site.org/html;mk=mv?k=v#f
356
- */
357
- export function encodeUriQuery(s) {
358
- return encodeUriString(s).replace(/%3B/gi, ';');
359
- }
360
- /**
361
- * This function should be used to encode a URL fragment. In the following URL, you need to call
362
- * encodeUriFragment on "f":
363
- *
364
- * http://www.site.org/html;mk=mv?k=v#f
365
- */
366
- export function encodeUriFragment(s) {
367
- return encodeURI(s);
368
- }
369
- /**
370
- * This function should be run on any URI segment as well as the key and value in a key/value
371
- * pair for matrix params. In the following URL, you need to call encodeUriSegment on "html",
372
- * "mk", and "mv":
373
- *
374
- * http://www.site.org/html;mk=mv?k=v#f
375
- */
376
- export function encodeUriSegment(s) {
377
- return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&');
378
- }
379
- export function decode(s) {
380
- return decodeURIComponent(s);
381
- }
382
- // Query keys/values should have the "+" replaced first, as "+" in a query string is " ".
383
- // decodeURIComponent function will not decode "+" as a space.
384
- export function decodeQuery(s) {
385
- return decode(s.replace(/\+/g, '%20'));
386
- }
387
- export function serializePath(path) {
388
- return `${encodeUriSegment(path.path)}${serializeMatrixParams(path.parameters)}`;
389
- }
390
- function serializeMatrixParams(params) {
391
- return Object.entries(params)
392
- .map(([key, value]) => `;${encodeUriSegment(key)}=${encodeUriSegment(value)}`)
393
- .join('');
394
- }
395
- function serializeQueryParams(params) {
396
- const strParams = Object.entries(params)
397
- .map(([name, value]) => {
398
- return Array.isArray(value)
399
- ? value.map((v) => `${encodeUriQuery(name)}=${encodeUriQuery(v)}`).join('&')
400
- : `${encodeUriQuery(name)}=${encodeUriQuery(value)}`;
401
- })
402
- .filter((s) => s);
403
- return strParams.length ? `?${strParams.join('&')}` : '';
404
- }
405
- const SEGMENT_RE = /^[^\/()?;#]+/;
406
- function matchSegments(str) {
407
- const match = str.match(SEGMENT_RE);
408
- return match ? match[0] : '';
409
- }
410
- const MATRIX_PARAM_SEGMENT_RE = /^[^\/()?;=#]+/;
411
- function matchMatrixKeySegments(str) {
412
- const match = str.match(MATRIX_PARAM_SEGMENT_RE);
413
- return match ? match[0] : '';
414
- }
415
- const QUERY_PARAM_RE = /^[^=?&#]+/;
416
- // Return the name of the query param at the start of the string or an empty string
417
- function matchQueryParams(str) {
418
- const match = str.match(QUERY_PARAM_RE);
419
- return match ? match[0] : '';
420
- }
421
- const QUERY_PARAM_VALUE_RE = /^[^&#]+/;
422
- // Return the value of the query param at the start of the string or an empty string
423
- function matchUrlQueryParamValue(str) {
424
- const match = str.match(QUERY_PARAM_VALUE_RE);
425
- return match ? match[0] : '';
426
- }
427
- class UrlParser {
428
- constructor(url) {
429
- this.url = url;
430
- this.remaining = url;
431
- }
432
- parseRootSegment() {
433
- this.consumeOptional('/');
434
- if (this.remaining === '' || this.peekStartsWith('?') || this.peekStartsWith('#')) {
435
- return new UrlSegmentGroup([], {});
436
- }
437
- // The root segment group never has segments
438
- return new UrlSegmentGroup([], this.parseChildren());
439
- }
440
- parseQueryParams() {
441
- const params = {};
442
- if (this.consumeOptional('?')) {
443
- do {
444
- this.parseQueryParam(params);
445
- } while (this.consumeOptional('&'));
446
- }
447
- return params;
448
- }
449
- parseFragment() {
450
- return this.consumeOptional('#') ? decodeURIComponent(this.remaining) : null;
451
- }
452
- parseChildren() {
453
- if (this.remaining === '') {
454
- return {};
455
- }
456
- this.consumeOptional('/');
457
- const segments = [];
458
- if (!this.peekStartsWith('(')) {
459
- segments.push(this.parseSegment());
460
- }
461
- while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) {
462
- this.capture('/');
463
- segments.push(this.parseSegment());
464
- }
465
- let children = {};
466
- if (this.peekStartsWith('/(')) {
467
- this.capture('/');
468
- children = this.parseParens(true);
469
- }
470
- let res = {};
471
- if (this.peekStartsWith('(')) {
472
- res = this.parseParens(false);
473
- }
474
- if (segments.length > 0 || Object.keys(children).length > 0) {
475
- res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children);
476
- }
477
- return res;
478
- }
479
- // parse a segment with its matrix parameters
480
- // ie `name;k1=v1;k2`
481
- parseSegment() {
482
- const path = matchSegments(this.remaining);
483
- if (path === '' && this.peekStartsWith(';')) {
484
- throw new RuntimeError(4009 /* RuntimeErrorCode.EMPTY_PATH_WITH_PARAMS */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
485
- `Empty path url segment cannot have parameters: '${this.remaining}'.`);
486
- }
487
- this.capture(path);
488
- return new UrlSegment(decode(path), this.parseMatrixParams());
489
- }
490
- parseMatrixParams() {
491
- const params = {};
492
- while (this.consumeOptional(';')) {
493
- this.parseParam(params);
494
- }
495
- return params;
496
- }
497
- parseParam(params) {
498
- const key = matchMatrixKeySegments(this.remaining);
499
- if (!key) {
500
- return;
501
- }
502
- this.capture(key);
503
- let value = '';
504
- if (this.consumeOptional('=')) {
505
- const valueMatch = matchSegments(this.remaining);
506
- if (valueMatch) {
507
- value = valueMatch;
508
- this.capture(value);
509
- }
510
- }
511
- params[decode(key)] = decode(value);
512
- }
513
- // Parse a single query parameter `name[=value]`
514
- parseQueryParam(params) {
515
- const key = matchQueryParams(this.remaining);
516
- if (!key) {
517
- return;
518
- }
519
- this.capture(key);
520
- let value = '';
521
- if (this.consumeOptional('=')) {
522
- const valueMatch = matchUrlQueryParamValue(this.remaining);
523
- if (valueMatch) {
524
- value = valueMatch;
525
- this.capture(value);
526
- }
527
- }
528
- const decodedKey = decodeQuery(key);
529
- const decodedVal = decodeQuery(value);
530
- if (params.hasOwnProperty(decodedKey)) {
531
- // Append to existing values
532
- let currentVal = params[decodedKey];
533
- if (!Array.isArray(currentVal)) {
534
- currentVal = [currentVal];
535
- params[decodedKey] = currentVal;
536
- }
537
- currentVal.push(decodedVal);
538
- }
539
- else {
540
- // Create a new value
541
- params[decodedKey] = decodedVal;
542
- }
543
- }
544
- // parse `(a/b//outlet_name:c/d)`
545
- parseParens(allowPrimary) {
546
- const segments = {};
547
- this.capture('(');
548
- while (!this.consumeOptional(')') && this.remaining.length > 0) {
549
- const path = matchSegments(this.remaining);
550
- const next = this.remaining[path.length];
551
- // if is is not one of these characters, then the segment was unescaped
552
- // or the group was not closed
553
- if (next !== '/' && next !== ')' && next !== ';') {
554
- throw new RuntimeError(4010 /* RuntimeErrorCode.UNPARSABLE_URL */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Cannot parse url '${this.url}'`);
555
- }
556
- let outletName = undefined;
557
- if (path.indexOf(':') > -1) {
558
- outletName = path.slice(0, path.indexOf(':'));
559
- this.capture(outletName);
560
- this.capture(':');
561
- }
562
- else if (allowPrimary) {
563
- outletName = PRIMARY_OUTLET;
564
- }
565
- const children = this.parseChildren();
566
- segments[outletName] =
567
- Object.keys(children).length === 1
568
- ? children[PRIMARY_OUTLET]
569
- : new UrlSegmentGroup([], children);
570
- this.consumeOptional('//');
571
- }
572
- return segments;
573
- }
574
- peekStartsWith(str) {
575
- return this.remaining.startsWith(str);
576
- }
577
- // Consumes the prefix when it is present and returns whether it has been consumed
578
- consumeOptional(str) {
579
- if (this.peekStartsWith(str)) {
580
- this.remaining = this.remaining.substring(str.length);
581
- return true;
582
- }
583
- return false;
584
- }
585
- capture(str) {
586
- if (!this.consumeOptional(str)) {
587
- throw new RuntimeError(4011 /* RuntimeErrorCode.UNEXPECTED_VALUE_IN_URL */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Expected "${str}".`);
588
- }
589
- }
590
- }
591
- export function createRoot(rootCandidate) {
592
- return rootCandidate.segments.length > 0
593
- ? new UrlSegmentGroup([], { [PRIMARY_OUTLET]: rootCandidate })
594
- : rootCandidate;
595
- }
596
- /**
597
- * Recursively
598
- * - merges primary segment children into their parents
599
- * - drops empty children (those which have no segments and no children themselves). This latter
600
- * prevents serializing a group into something like `/a(aux:)`, where `aux` is an empty child
601
- * segment.
602
- * - merges named outlets without a primary segment sibling into the children. This prevents
603
- * serializing a URL like `//(a:a)(b:b) instead of `/(a:a//b:b)` when the aux b route lives on the
604
- * root but the `a` route lives under an empty path primary route.
605
- */
606
- export function squashSegmentGroup(segmentGroup) {
607
- const newChildren = {};
608
- for (const [childOutlet, child] of Object.entries(segmentGroup.children)) {
609
- const childCandidate = squashSegmentGroup(child);
610
- // moves named children in an empty path primary child into this group
611
- if (childOutlet === PRIMARY_OUTLET &&
612
- childCandidate.segments.length === 0 &&
613
- childCandidate.hasChildren()) {
614
- for (const [grandChildOutlet, grandChild] of Object.entries(childCandidate.children)) {
615
- newChildren[grandChildOutlet] = grandChild;
616
- }
617
- } // don't add empty children
618
- else if (childCandidate.segments.length > 0 || childCandidate.hasChildren()) {
619
- newChildren[childOutlet] = childCandidate;
620
- }
621
- }
622
- const s = new UrlSegmentGroup(segmentGroup.segments, newChildren);
623
- return mergeTrivialChildren(s);
624
- }
625
- /**
626
- * When possible, merges the primary outlet child into the parent `UrlSegmentGroup`.
627
- *
628
- * When a segment group has only one child which is a primary outlet, merges that child into the
629
- * parent. That is, the child segment group's segments are merged into the `s` and the child's
630
- * children become the children of `s`. Think of this like a 'squash', merging the child segment
631
- * group into the parent.
632
- */
633
- function mergeTrivialChildren(s) {
634
- if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) {
635
- const c = s.children[PRIMARY_OUTLET];
636
- return new UrlSegmentGroup(s.segments.concat(c.segments), c.children);
637
- }
638
- return s;
639
- }
640
- export function isUrlTree(v) {
641
- return v instanceof UrlTree;
642
- }
643
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsX3RyZWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9yb3V0ZXIvc3JjL3VybF90cmVlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxVQUFVLEVBQUUsYUFBYSxJQUFJLFlBQVksRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUd4RSxPQUFPLEVBQUMsaUJBQWlCLEVBQW9CLGNBQWMsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUM3RSxPQUFPLEVBQUMsbUJBQW1CLEVBQUUsWUFBWSxFQUFDLE1BQU0sb0JBQW9CLENBQUM7O0FBMkRyRSxNQUFNLGNBQWMsR0FBeUQ7SUFDM0UsT0FBTyxFQUFFLGtCQUFrQjtJQUMzQixRQUFRLEVBQUUsb0JBQW9CO0NBQy9CLENBQUM7QUFDRixNQUFNLGVBQWUsR0FBOEM7SUFDakUsT0FBTyxFQUFFLFdBQVc7SUFDcEIsUUFBUSxFQUFFLGNBQWM7SUFDeEIsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUk7Q0FDdEIsQ0FBQztBQUVGLE1BQU0sVUFBVSxZQUFZLENBQzFCLFNBQWtCLEVBQ2xCLFNBQWtCLEVBQ2xCLE9BQTZCO0lBRTdCLE9BQU8sQ0FDTCxjQUFjLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsWUFBWSxDQUFDO1FBQ25GLGVBQWUsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUMsV0FBVyxDQUFDO1FBQ2xGLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sSUFBSSxTQUFTLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FDN0UsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxTQUFpQixFQUFFLFNB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Q0FBQyxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDbEUsT0FBTyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQyxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsb0JBQW9CLENBQUMsQ0FBa0I7SUFDOUMsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztRQUMzRCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3JDLE9BQU8sSUFBSSxlQUFlLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQsT0FBTyxDQUFDLENBQUM7QUFDWCxDQUFDO0FBRUQsTUFBTSxVQUFVLFNBQVMsQ0FBQyxDQUFNO0lBQzlCLE9BQU8sQ0FBQyxZQUFZLE9BQU8sQ0FBQztBQUM5QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7SW5qZWN0YWJsZSwgybVSdW50aW1lRXJyb3IgYXMgUnVudGltZUVycm9yfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtSdW50aW1lRXJyb3JDb2RlfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQge2NvbnZlcnRUb1BhcmFtTWFwLCBQYXJhbU1hcCwgUGFyYW1zLCBQUklNQVJZX09VVExFVH0gZnJvbSAnLi9zaGFyZWQnO1xuaW1wb3J0IHtlcXVhbEFycmF5c09yU3RyaW5nLCBzaGFsbG93RXF1YWx9IGZyb20gJy4vdXRpbHMvY29sbGVjdGlvbic7XG5cbi8qKlxuICogQSBzZXQgb2Ygb3B0aW9ucyB3aGljaCBzcGVjaWZ5IGhvdyB0byBkZXRlcm1pbmUgaWYgYSBgVXJsVHJlZWAgaXMgYWN0aXZlLCBnaXZlbiB0aGUgYFVybFRyZWVgXG4gKiBmb3IgdGhlIGN1cnJlbnQgcm91dGVyIHN0YXRlLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqIEBzZWUge0BsaW5rIFJvdXRlciNpc0FjdGl2ZX1cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJc0FjdGl2ZU1hdGNoT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBEZWZpbmVzIHRoZSBzdHJhdGVneSBmb3IgY29tcGFyaW5nIHRoZSBtYXRyaXggcGFyYW1ldGVycyBvZiB0d28gYFVybFRyZWVgcy5cbiAgICpcbiAgICogVGhlIG1hdHJpeCBwYXJhbWV0ZXIgbWF0Y2hpbmcgaXMgZGVwZW5kZW50IG9uIHRoZSBzdHJhdGVneSBmb3IgbWF0Y2hpbmcgdGhlXG4gICAqIHNlZ21lbnRzLiBUaGF0IGlzLCBpZiB0aGUgYHBhdGhzYCBvcHRpb24gaXMgc2V0IHRvIGAnc3Vic2V0J2AsIG9ubHlcbiAgICogdGhlIG1hdHJpeCBwYXJhbWV0ZXJzIG9mIHRoZSBtYXRjaGluZyBzZWdtZW50cyB3aWxsIGJlIGNvbXBhcmVkLlxuICAgKlxuICAgKiAtIGAnZXhhY3QnYDogUmVxdWlyZXMgdGhhdCBtYXRjaGluZyBzZWdtZW50cyBhbHNvIGhhdmUgZXhhY3QgbWF0cml4IHBhcmFtZXRlclxuICAgKiBtYXRjaGVzLlxuICAgKiAtIGAnc3Vic2V0J2A6IFRoZSBtYXRjaGluZyBzZWdtZW50cyBpbiB0aGUgcm91dGVyJ3MgYWN0aXZlIGBVcmxUcmVlYCBtYXkgY29udGFpblxuICAgKiBleHRyYSBtYXRyaXggcGFyYW1ldGVycywgYnV0IHRob3NlIHRoYXQgZXhpc3QgaW4gdGhlIGBVcmxUcmVlYCBpbiBxdWVzdGlvbiBtdXN0IG1hdGNoLlxuICAgKiAtIGAnaWdub3JlZCdgOiBXaGVuIGNvbXBhcmluZyBgVXJsVHJlZWBzLCBtYXRyaXggcGFyYW1zIHdpbGwgYmUgaWdub3JlZC5cbiAgICovXG4gIG1hdHJpeFBhcmFtczogJ2V4YWN0JyB8ICdzdWJzZXQnIHwgJ2lnbm9yZWQnO1xuICAvKipcbiAgICogRGVmaW5lcyB0aGUgc3RyYXRlZ3kgZm9yIGNvbXBhcmluZyB0aGUgcXVlcnkgcGFyYW1ldGVycyBvZiB0d28gYFVybFRyZWVgcy5cbiAgICpcbiAgICogLSBgJ2V4YWN0J2A6IHRoZSBxdWVyeSBwYXJhbWV0ZXJzIG11c3QgbWF0Y2ggZXhhY3RseS5cbiAgICogLSBgJ3N1YnNldCdgOiB0aGUgYWN0aXZlIGBVcmxUcmVlYCBtYXkgY29udGFpbiBleHRyYSBwYXJhbWV0ZXJzLFxuICAgKiBidXQgbXVzdCBtYXRjaCB0aGUga2V5IGFuZCB2YWx1ZSBvZiBhbnkgdGhhdCBleGlzdCBpbiB0aGUgYFVybFRyZWVgIGluIHF1ZXN0aW9uLlxuICAgKiAtIGAnaWdub3JlZCdgOiBXaGVuIGNvbXBhcmluZyBgVXJsVHJlZWBzLCBxdWVyeSBwYXJhbXMgd2lsbCBiZSBpZ25vcmVkLlxuICAgKi9cbiAgcXVlcnlQYXJhbXM6ICdleGFjdCcgfCAnc3Vic2V0JyB8ICdpZ25vcmVkJztcbiAgLyoqXG4gICAqIERlZmluZXMgdGhlIHN0cmF0ZWd5IGZvciBjb21wYXJpbmcgdGhlIGBVcmxTZWdtZW50YHMgb2YgdGhlIGBVcmxUcmVlYHMuXG4gICAqXG4gICAqIC0gYCdleGFjdCdgOiBhbGwgc2VnbWVudHMgaW4gZWFjaCBgVXJsVHJlZWAgbXVzdCBtYXRjaC5cbiAgICogLSBgJ3N1YnNldCdgOiBhIGBVcmxUcmVlYCB3aWxsIGJlIGRldGVybWluZWQgdG8gYmUgYWN0aXZlIGlmIGl0XG4gICAqIGlzIGEgc3VidHJlZSBvZiB0aGUgYWN0aXZlIHJvdXRlLiBUaGF0IGlzLCB0aGUgYWN0aXZlIHJvdXRlIG1heSBjb250YWluIGV4dHJhXG4gICAqIHNlZ21lbnRzLCBidXQgbXVzdCBhdCBsZWFzdCBoYXZlIGFsbCB0aGUgc2VnbWVudHMgb2YgdGhlIGBVcmxUcmVlYCBpbiBxdWVzdGlvbi5cbiAgICovXG4gIHBhdGhzOiAnZXhhY3QnIHwgJ3N1YnNldCc7XG4gIC8qKlxuICAgKiAtIGAnZXhhY3QnYDogaW5kaWNhdGVzIHRoYXQgdGhlIGBVcmxUcmVlYCBmcmFnbWVudHMgbXVzdCBiZSBlcXVhbC5cbiAgICogLSBgJ2lnbm9yZWQnYDogdGhlIGZyYWdtZW50cyB3aWxsIG5vdCBiZSBjb21wYXJlZCB3aGVuIGRldGVybWluaW5nIGlmIGFcbiAgICogYFVybFRyZWVgIGlzIGFjdGl2ZS5cbiAgICovXG4gIGZyYWdtZW50OiAnZXhhY3QnIHwgJ2lnbm9yZWQnO1xufVxuXG50eXBlIFBhcmFtTWF0Y2hPcHRpb25zID0gJ2V4YWN0JyB8ICdzdWJzZXQnIHwgJ2lnbm9yZWQnO1xuXG50eXBlIFBhdGhDb21wYXJlRm4gPSAoXG4gIGNvbnRhaW5lcjogVXJsU2VnbWVudEdyb3VwLFxuICBjb250YWluZWU6IFVybFNlZ21lbnRHcm91cCxcbiAgbWF0cml4UGFyYW1zOiBQYXJhbU1hdGNoT3B0aW9ucyxcbikgPT4gYm9vbGVhbjtcbnR5cGUgUGFyYW1Db21wYXJlRm4gPSAoY29udGFpbmVyOiBQYXJhbXMsIGNvbnRhaW5lZTogUGFyYW1zKSA9PiBib29sZWFuO1xuXG5jb25zdCBwYXRoQ29tcGFyZU1hcDogUmVjb3JkPElzQWN0aXZlTWF0Y2hPcHRpb25zWydwYXRocyddLCBQYXRoQ29tcGFyZUZuPiA9IHtcbiAgJ2V4YWN0JzogZXF1YWxTZWdtZW50R3JvdXBzLFxuICAnc3Vic2V0JzogY29udGFpbnNTZWdtZW50R3JvdXAsXG59O1xuY29uc3QgcGFyYW1Db21wYXJlTWFwOiBSZWNvcmQ8UGFyYW1NYXRjaE9wdGlvbnMsIFBhcmFtQ29tcGFyZUZuPiA9IHtcbiAgJ2V4YWN0JzogZXF1YWxQYXJhbXMsXG4gICdzdWJzZXQnOiBjb250YWluc1BhcmFtcyxcbiAgJ2lnbm9yZWQnOiAoKSA9PiB0cnVlLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5zVHJlZShcbiAgY29udGFpbmVyOiBVcmxUcmVlLFxuICBjb250YWluZWU6IFVybFRyZWUsXG4gIG9wdGlvbnM6IElzQWN0aXZlTWF0Y2hPcHRpb25zLFxuKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgcGF0aENvbXBhcmVNYXBbb3B0aW9ucy5wYXRoc10oY29udGFpbmVyLnJvb3QsIGNvbnRhaW5lZS5yb290LCBvcHRpb25zLm1hdHJpeFBhcmFtcykgJiZcbiAgICBwYXJhbUNvbXBhcmVNYXBbb3B0aW9ucy5xdWVyeVBhcmFtc10oY29udGFpbmVyLnF1ZXJ5UGFyYW1zLCBjb250YWluZWUucXVlcnlQYXJhbXMpICYmXG4gICAgIShvcHRpb25zLmZyYWdtZW50ID09PSAnZXhhY3QnICYmIGNvbnRhaW5lci5mcmFnbWVudCAhPT0gY29udGFpbmVlLmZyYWdtZW50KVxuICApO1xufVxuXG5mdW5jdGlvbiBlcXVhbFBhcmFtcyhjb250YWluZXI6IFBhcmFtcywgY29udGFpbmVlOiBQYXJhbXMpOiBib29sZWFuIHtcbiAgLy8gVE9ETzogVGhpcyBkb2VzIG5vdCBoYW5kbGUgYXJyYXkgcGFyYW1zIGNvcnJlY3RseS5cbiAgcmV0dXJuIHNoYWxsb3dFcXVhbChjb250YWluZXIsIGNvbnRhaW5lZSk7XG59XG5cbmZ1bmN0aW9uIGVxdWFsU2VnbWVudEdyb3VwcyhcbiAgY29udGFpbmVyOiBVcmxTZWdtZW50R3JvdXAsXG4gIGNvbnRhaW5lZTogVXJsU2VnbWVudEdyb3VwLFxuICBtYXRyaXhQYXJhbXM6IFBhcmFtTWF0Y2hPcHRpb25zLFxuKTogYm9vbGVhbiB7XG4gIGlmICghZXF1YWxQYXRoKGNvbnRhaW5lci5zZWdtZW50cywgY29udGFpbmVlLnNlZ21lbnRzKSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoIW1hdHJpeFBhcmFtc01hdGNoKGNvbnRhaW5lci5zZWdtZW50cywgY29udGFpbmVlLnNlZ21lbnRzLCBtYXRyaXhQYXJhbXMpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChjb250YWluZXIubnVtYmVyT2ZDaGlsZHJlbiAhPT0gY29udGFpbmVlLm51bWJlck9mQ2hpbGRyZW4pIHJldHVybiBmYWxzZTtcbiAgZm9yIChjb25zdCBjIGluIGNvbnRhaW5lZS5jaGlsZHJlbikge1xuICAgIGlmICghY29udGFpbmVyLmNoaWxkcmVuW2NdKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCFlcXVhbFNlZ21lbnRHcm91cHMoY29udGFpbmVyLmNoaWxkcmVuW2NdLCBjb250YWluZWUuY2hpbGRyZW5bY10sIG1hdHJpeFBhcmFtcykpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zUGFyYW1zKGNvbnRhaW5lcjogUGFyYW1zLCBjb250YWluZWU6IFBhcmFtcyk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIE9iamVjdC5rZXlzKGNvbnRhaW5lZSkubGVuZ3RoIDw9IE9iamVjdC5rZXlzKGNvbnRhaW5lcikubGVuZ3RoICYmXG4gICAgT2JqZWN0LmtleXMoY29udGFpbmVlKS5ldmVyeSgoa2V5KSA9PiBlcXVhbEFycmF5c09yU3RyaW5nKGNvbnRhaW5lcltrZXldLCBjb250YWluZWVba2V5XSkpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zU2VnbWVudEdyb3VwKFxuICBjb250YWluZXI6IFVybFNlZ21lbnRHcm91cCxcbiAgY29udGFpbmVlOiBVcmxTZWdtZW50R3JvdXAsXG4gIG1hdHJpeFBhcmFtczogUGFyYW1NYXRjaE9wdGlvbnMsXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIGNvbnRhaW5zU2VnbWVudEdyb3VwSGVscGVyKGNvbnRhaW5lciwgY29udGFpbmVlLCBjb250YWluZWUuc2VnbWVudHMsIG1hdHJpeFBhcmFtcyk7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zU2VnbWVudEdyb3VwSGVscGVyKFxuICBjb250YWluZXI6IFVybFNlZ21lbnRHcm91cCxcbiAgY29udGFpbmVlOiBVcmxTZWdtZW50R3JvdXAsXG4gIGNvbnRhaW5lZVBhdGhzOiBVcmxTZWdtZW50W10sXG4gIG1hdHJpeFBhcmFtczogUGFyYW1NYXRjaE9wdGlvbnMsXG4pOiBib29sZWFuIHtcbiAgaWYgKGNvbnRhaW5lci5zZWdtZW50cy5sZW5ndGggPiBjb250YWluZWVQYXRocy5sZW5ndGgpIHtcbiAgICBjb25zdCBjdXJyZW50ID0gY29udGFpbmVyLnNlZ21lbnRzLnNsaWNlKDAsIGNvbnRhaW5lZVBhdGhzLmxlbmd0aCk7XG4gICAgaWYgKCFlcXVhbFBhdGgoY3VycmVudCwgY29udGFpbmVlUGF0aHMpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGNvbnRhaW5lZS5oYXNDaGlsZHJlbigpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCFtYXRyaXhQYXJhbXNNYXRjaChjdXJyZW50LCBjb250YWluZWVQYXRocywgbWF0cml4UGFyYW1zKSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGNvbnRhaW5lci5zZWdtZW50cy5sZW5ndGggPT09IGNvbnRhaW5lZVBhdGhzLmxlbmd0aCkge1xuICAgIGlmICghZXF1YWxQYXRoKGNvbnRhaW5lci5zZWdtZW50cywgY29udGFpbmVlUGF0aHMpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCFtYXRyaXhQYXJhbXNNYXRjaChjb250YWluZXIuc2VnbWVudHMsIGNvbnRhaW5lZVBhdGhzLCBtYXRyaXhQYXJhbXMpKSByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChjb25zdCBjIGluIGNvbnRhaW5lZS5jaGlsZHJlbikge1xuICAgICAgaWYgKCFjb250YWluZXIuY2hpbGRyZW5bY10pIHJldHVybiBmYWxzZTtcbiAgICAgIGlmICghY29udGFpbnNTZWdtZW50R3JvdXAoY29udGFpbmVyLmNoaWxkcmVuW2NdLCBjb250YWluZWUuY2hpbGRyZW5bY10sIG1hdHJpeFBhcmFtcykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBjdXJyZW50ID0gY29udGFpbmVlUGF0aHMuc2xpY2UoMCwgY29udGFpbmVyLnNlZ21lbnRzLmxlbmd0aCk7XG4gICAgY29uc3QgbmV4dCA9IGNvbnRhaW5lZVBhdGhzLnNsaWNlKGNvbnRhaW5lci5zZWdtZW50cy5sZW5ndGgpO1xuICAgIGlmICghZXF1YWxQYXRoKGNvbnRhaW5lci5zZWdtZW50cywgY3VycmVudCkpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoIW1hdHJpeFBhcmFtc01hdGNoKGNvbnRhaW5lci5zZWdtZW50cywgY3VycmVudCwgbWF0cml4UGFyYW1zKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghY29udGFpbmVyLmNoaWxkcmVuW1BSSU1BUllfT1VUTEVUXSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBjb250YWluc1NlZ21lbnRHcm91cEhlbHBlcihcbiAgICAgIGNvbnRhaW5lci5jaGlsZHJlbltQUklNQVJZX09VVExFVF0sXG4gICAgICBjb250YWluZWUsXG4gICAgICBuZXh0LFxuICAgICAgbWF0cml4UGFyYW1zLFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF0cml4UGFyYW1zTWF0Y2goXG4gIGNvbnRhaW5lclBhdGhzOiBVcmxTZWdtZW50W10sXG4gIGNvbnRhaW5lZVBhdGhzOiBVcmxTZWdtZW50W10sXG4gIG9wdGlvbnM6IFBhcmFtTWF0Y2hPcHRpb25zLFxuKSB7XG4gIHJldHVybiBjb250YWluZWVQYXRocy5ldmVyeSgoY29udGFpbmVlU2VnbWVudCwgaSkgPT4ge1xuICAgIHJldHVybiBwYXJhbUNvbXBhcmVNYXBbb3B0aW9uc10oY29udGFpbmVyUGF0aHNbaV0ucGFyYW1ldGVycywgY29udGFpbmVlU2VnbWVudC5wYXJhbWV0ZXJzKTtcbiAgfSk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogUmVwcmVzZW50cyB0aGUgcGFyc2VkIFVSTC5cbiAqXG4gKiBTaW5jZSBhIHJvdXRlciBzdGF0ZSBpcyBhIHRyZWUsIGFuZCB0aGUgVVJMIGlzIG5vdGhpbmcgYnV0IGEgc2VyaWFsaXplZCBzdGF0ZSwgdGhlIFVSTCBpcyBhXG4gKiBzZXJpYWxpemVkIHRyZWUuXG4gKiBVcmxUcmVlIGlzIGEgZGF0YSBzdHJ1Y3R1cmUgdGhhdCBwcm92aWRlcyBhIGxvdCBvZiBhZmZvcmRhbmNlcyBpbiBkZWFsaW5nIHdpdGggVVJMc1xuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiAjIyMgRXhhbXBsZVxuICpcbiAqIGBgYFxuICogQENvbXBvbmVudCh7dGVtcGxhdGVVcmw6J3RlbXBsYXRlLmh0bWwnfSlcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgY29uc3RydWN0b3Iocm91dGVyOiBSb3V0ZXIpIHtcbiAqICAgICBjb25zdCB0cmVlOiBVcmxUcmVlID1cbiAqICAgICAgIHJvdXRlci5wYXJzZVVybCgnL3RlYW0vMzMvKHVzZXIvdmljdG9yLy9zdXBwb3J0OmhlbHApP2RlYnVnPXRydWUjZnJhZ21lbnQnKTtcbiAqICAgICBjb25zdCBmID0gdHJlZS5mcmFnbWVudDsgLy8gcmV0dXJuICdmcmFnbWVudCdcbiAqICAgICBjb25zdCBxID0gdHJlZS5xdWVyeVBhcmFtczsgLy8gcmV0dXJucyB7ZGVidWc6ICd0cnVlJ31cbiAqICAgICBjb25zdCBnOiBVcmxTZWdtZW50R3JvdXAgPSB0cmVlLnJvb3QuY2hpbGRyZW5bUFJJTUFSWV9PVVRMRVRdO1xuICogICAgIGNvbnN0IHM6IFVybFNlZ21lbnRbXSA9IGcuc2VnbWVudHM7IC8vIHJldHVybnMgMiBzZWdtZW50cyAndGVhbScgYW5kICczMydcbiAqICAgICBnLmNoaWxkcmVuW1BSSU1BUllfT1VUTEVUXS5zZWdtZW50czsgLy8gcmV0dXJucyAyIHNlZ21lbnRzICd1c2VyJyBhbmQgJ3ZpY3RvcidcbiAqICAgICBnLmNoaWxkcmVuWydzdXBwb3J0J10uc2VnbWVudHM7IC8vIHJldHVybiAxIHNlZ21lbnQgJ2hlbHAnXG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGNsYXNzIFVybFRyZWUge1xuICAvKiogQGludGVybmFsICovXG4gIF9xdWVyeVBhcmFtTWFwPzogUGFyYW1NYXA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgLyoqIFRoZSByb290IHNlZ21lbnQgZ3JvdXAgb2YgdGhlIFVSTCB0cmVlICovXG4gICAgcHVibGljIHJvb3Q6IFVybFNlZ21lbnRHcm91cCA9IG5ldyBVcmxTZWdtZW50R3JvdXAoW10sIHt9KSxcbiAgICAvKiogVGhlIHF1ZXJ5IHBhcmFtcyBvZiB0aGUgVVJMICovXG4gICAgcHVibGljIHF1ZXJ5UGFyYW1zOiBQYXJhbXMgPSB7fSxcbiAgICAvKiogVGhlIGZyYWdtZW50IG9mIHRoZSBVUkwgKi9cbiAgICBwdWJsaWMgZnJhZ21lbnQ6IHN0cmluZyB8IG51bGwgPSBudWxsLFxuICApIHtcbiAgICBpZiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSB7XG4gICAgICBpZiAocm9vdC5zZWdtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoXG4gICAgICAgICAgUnVudGltZUVycm9yQ29kZS5JTlZBTElEX1JPT1RfVVJMX1NFR01FTlQsXG4gICAgICAgICAgJ1RoZSByb290IGBVcmxTZWdtZW50R3JvdXBgIHNob3VsZCBub3QgY29udGFpbiBgc2VnbWVudHNgLiAnICtcbiAgICAgICAgICAgICdJbnN0ZWFkLCB0aGVzZSBzZWdtZW50cyBiZWxvbmcgaW4gdGhlIGBjaGlsZHJlbmAgc28gdGhleSBjYW4gYmUgYXNzb2NpYXRlZCB3aXRoIGEgbmFtZWQgb3V0bGV0LicsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IHF1ZXJ5UGFyYW1NYXAoKTogUGFyYW1NYXAge1xuICAgIHRoaXMuX3F1ZXJ5UGFyYW1NYXAgPz89IGNvbnZlcnRUb1BhcmFtTWFwKHRoaXMucXVlcnlQYXJhbXMpO1xuICAgIHJldHVybiB0aGlzLl9xdWVyeVBhcmFtTWFwO1xuICB9XG5cbiAgLyoqIEBkb2NzTm90UmVxdWlyZWQgKi9cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gREVGQVVMVF9TRVJJQUxJWkVSLnNlcmlhbGl6ZSh0aGlzKTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIFJlcHJlc2VudHMgdGhlIHBhcnNlZCBVUkwgc2VnbWVudCBncm91cC5cbiAqXG4gKiBTZWUgYFVybFRyZWVgIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGNsYXNzIFVybFNlZ21lbnRHcm91cCB7XG4gIC8qKiBUaGUgcGFyZW50IG5vZGUgaW4gdGhlIHVybCB0cmVlICovXG4gIHBhcmVudDogVXJsU2VnbWVudEdyb3VwIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgLyoqIFRoZSBVUkwgc2VnbWVudHMgb2YgdGhpcyBncm91cC4gU2VlIGBVcmxTZWdtZW50YCBmb3IgbW9yZSBpbmZvcm1hdGlvbiAqL1xuICAgIHB1YmxpYyBzZWdtZW50czogVXJsU2VnbWVudFtdLFxuICAgIC8qKiBUaGUgbGlzdCBvZiBjaGlsZHJlbiBvZiB0aGlzIGdyb3VwICovXG4gICAgcHVibGljIGNoaWxkcmVuOiB7W2tleTogc3RyaW5nXTogVXJsU2VnbWVudEdyb3VwfSxcbiAgKSB7XG4gICAgT2JqZWN0LnZhbHVlcyhjaGlsZHJlbikuZm9yRWFjaCgodikgPT4gKHYucGFyZW50ID0gdGhpcykpO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIHNlZ21lbnQgaGFzIGNoaWxkIHNlZ21lbnRzICovXG4gIGhhc0NoaWxkcmVuKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm51bWJlck9mQ2hpbGRyZW4gPiAwO1xuICB9XG5cbiAgLyoqIE51bWJlciBvZiBjaGlsZCBzZWdtZW50cyAqL1xuICBnZXQgbnVtYmVyT2ZDaGlsZHJlbigpOiBudW1iZXIge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmNoaWxkcmVuKS5sZW5ndGg7XG4gIH1cblxuICAvKiogQGRvY3NOb3RSZXF1aXJlZCAqL1xuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBzZXJpYWxpemVQYXRocyh0aGlzKTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIFJlcHJlc2VudHMgYSBzaW5nbGUgVVJMIHNlZ21lbnQuXG4gKlxuICogQSBVcmxTZWdtZW50IGlzIGEgcGFydCBvZiBhIFVSTCBiZXR3ZWVuIHRoZSB0d28gc2xhc2hlcy4gSXQgY29udGFpbnMgYSBwYXRoIGFuZCB0aGUgbWF0cml4XG4gKiBwYXJhbWV0ZXJzIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2VnbWVudC5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICrCoCMjIyBFeGFtcGxlXG4gKlxuICogYGBgXG4gKiBAQ29tcG9uZW50KHt0ZW1wbGF0ZVVybDondGVtcGxhdGUuaHRtbCd9KVxuICogY2xhc3MgTXlDb21wb25lbnQge1xuICogICBjb25zdHJ1Y3Rvcihyb3V0ZXI6IFJvdXRlcikge1xuICogICAgIGNvbnN0IHRyZWU6IFVybFRyZWUgPSByb3V0ZXIucGFyc2VVcmwoJy90ZWFtO2lkPTMzJyk7XG4gKiAgICAgY29uc3QgZzogVXJsU2VnbWVudEdyb3VwID0gdHJlZS5yb290LmNoaWxkcmVuW1BSSU1BUllfT1VUTEVUXTtcbiAqICAgICBjb25zdCBzOiBVcmxTZWdtZW50W10gPSBnLnNlZ21lbnRzO1xuICogICAgIHNbMF0ucGF0aDsgLy8gcmV0dXJucyAndGVhbSdcbiAqICAgICBzWzBdLnBhcmFtZXRlcnM7IC8vIHJldHVybnMge2lkOiAzM31cbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgY2xhc3MgVXJsU2VnbWVudCB7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX3BhcmFtZXRlck1hcD86IFBhcmFtTWFwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIC8qKiBUaGUgcGF0aCBwYXJ0IG9mIGEgVVJMIHNlZ21lbnQgKi9cbiAgICBwdWJsaWMgcGF0aDogc3RyaW5nLFxuXG4gICAgLyoqIFRoZSBtYXRyaXggcGFyYW1ldGVycyBhc3NvY2lhdGVkIHdpdGggYSBzZWdtZW50ICovXG4gICAgcHVibGljIHBhcmFtZXRlcnM6IHtbbmFtZTogc3RyaW5nXTogc3RyaW5nfSxcbiAgKSB7fVxuXG4gIGdldCBwYXJhbWV0ZXJNYXAoKTogUGFyYW1NYXAge1xuICAgIHRoaXMuX3BhcmFtZXRlck1hcCA/Pz0gY29udmVydFRvUGFyYW1NYXAodGhpcy5wYXJhbWV0ZXJzKTtcbiAgICByZXR1cm4gdGhpcy5fcGFyYW1ldGVyTWFwO1xuICB9XG5cbiAgLyoqIEBkb2NzTm90UmVxdWlyZWQgKi9cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gc2VyaWFsaXplUGF0aCh0aGlzKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxTZWdtZW50cyhhczogVXJsU2VnbWVudFtdLCBiczogVXJsU2VnbWVudFtdKTogYm9vbGVhbiB7XG4gIHJldHVybiBlcXVhbFBhdGgoYXMsIGJzKSAmJiBhcy5ldmVyeSgoYSwgaSkgPT4gc2hhbGxvd0VxdWFsKGEucGFyYW1ldGVycywgYnNbaV0ucGFyYW1ldGVycykpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxQYXRoKGFzOiBVcmxTZWdtZW50W10sIGJzOiBVcmxTZWdtZW50W10pOiBib29sZWFuIHtcbiAgaWYgKGFzLmxlbmd0aCAhPT0gYnMubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBhcy5ldmVyeSgoYSwgaSkgPT4gYS5wYXRoID09PSBic1tpXS5wYXRoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1hcENoaWxkcmVuSW50b0FycmF5PFQ+KFxuICBzZWdtZW50OiBVcmxTZWdtZW50R3JvdXAsXG4gIGZuOiAodjogVXJsU2VnbWVudEdyb3VwLCBrOiBzdHJpbmcpID0+IFRbXSxcbik6IFRbXSB7XG4gIGxldCByZXM6IFRbXSA9IFtdO1xuICBPYmplY3QuZW50cmllcyhzZWdtZW50LmNoaWxkcmVuKS5mb3JFYWNoKChbY2hpbGRPdXRsZXQsIGNoaWxkXSkgPT4ge1xuICAgIGlmIChjaGlsZE91dGxldCA9PT0gUFJJTUFSWV9PVVRMRVQpIHtcbiAgICAgIHJlcyA9IHJlcy5jb25jYXQoZm4oY2hpbGQsIGNoaWxkT3V0bGV0KSk7XG4gICAgfVxuICB9KTtcbiAgT2JqZWN0LmVudHJpZXMoc2VnbWVudC5jaGlsZHJlbikuZm9yRWFjaCgoW2NoaWxkT3V0bGV0LCBjaGlsZF0pID0+IHtcbiAgICBpZiAoY2hpbGRPdXRsZXQgIT09IFBSSU1BUllfT1VUTEVUKSB7XG4gICAgICByZXMgPSByZXMuY29uY2F0KGZuKGNoaWxkLCBjaGlsZE91dGxldCkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXM7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogU2VyaWFsaXplcyBhbmQgZGVzZXJpYWxpemVzIGEgVVJMIHN0cmluZyBpbnRvIGEgVVJMIHRyZWUuXG4gKlxuICogVGhlIHVybCBzZXJpYWxpemF0aW9uIHN0cmF0ZWd5IGlzIGN1c3RvbWl6YWJsZS4gWW91IGNhblxuICogbWFrZSBhbGwgVVJMcyBjYXNlIGluc2Vuc2l0aXZlIGJ5IHByb3ZpZGluZyBhIGN1c3RvbSBVcmxTZXJpYWxpemVyLlxuICpcbiAqIFNlZSBgRGVmYXVsdFVybFNlcmlhbGl6ZXJgIGZvciBhbiBleGFtcGxlIG9mIGEgVVJMIHNlcmlhbGl6ZXIuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnLCB1c2VGYWN0b3J5OiAoKSA9PiBuZXcgRGVmYXVsdFVybFNlcmlhbGl6ZXIoKX0pXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVXJsU2VyaWFsaXplciB7XG4gIC8qKiBQYXJzZSBhIHVybCBpbnRvIGEgYFVybFRyZWVgICovXG4gIGFic3RyYWN0IHBhcnNlKHVybDogc3RyaW5nKTogVXJsVHJlZTtcblxuICAvKiogQ29udmVydHMgYSBgVXJsVHJlZWAgaW50byBhIHVybCAqL1xuICBhYnN0cmFjdCBzZXJpYWxpemUodHJlZTogVXJsVHJlZSk6IHN0cmluZztcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiBBIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIGBVcmxTZXJpYWxpemVyYC5cbiAqXG4gKiBFeGFtcGxlIFVSTHM6XG4gKlxuICogYGBgXG4gKiAvaW5ib3gvMzMocG9wdXA6Y29tcG9zZSlcbiAqIC9pbmJveC8zMztvcGVuPXRydWUvbWVzc2FnZXMvNDRcbiAqIGBgYFxuICpcbiAqIERlZmF1bHRVcmxTZXJpYWxpemVyIHVzZXMgcGFyZW50aGVzZXMgdG8gc2VyaWFsaXplIHNlY29uZGFyeSBzZWdtZW50cyAoZS5nLiwgcG9wdXA6Y29tcG9zZSksIHRoZVxuICogY29sb24gc3ludGF4IHRvIHNwZWNpZnkgdGhlIG91dGxldCwgYW5kIHRoZSAnO3BhcmFtZXRlcj12YWx1ZScgc3ludGF4IChlLmcuLCBvcGVuPXRydWUpIHRvXG4gKiBzcGVjaWZ5IHJvdXRlIHNwZWNpZmljIHBhcmFtZXRlcnMuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgY2xhc3MgRGVmYXVsdFVybFNlcmlhbGl6ZXIgaW1wbGVtZW50cyBVcmxTZXJpYWxpemVyIHtcbiAgLyoqIFBhcnNlcyBhIHVybCBpbnRvIGEgYFVybFRyZWVgICovXG4gIHBhcnNlKHVybDogc3RyaW5nKTogVXJsVHJlZSB7XG4gICAgY29uc3QgcCA9IG5ldyBVcmxQYXJzZXIodXJsKTtcbiAgICByZXR1cm4gbmV3IFVybFRyZWUocC5wYXJzZVJvb3RTZWdtZW50KCksIHAucGFyc2VRdWVyeVBhcmFtcygpLCBwLnBhcnNlRnJhZ21lbnQoKSk7XG4gIH1cblxuICAvKiogQ29udmVydHMgYSBgVXJsVHJlZWAgaW50byBhIHVybCAqL1xuICBzZXJpYWxpemUodHJlZTogVXJsVHJlZSk6IHN0cmluZyB7XG4gICAgY29uc3Qgc2VnbWVudCA9IGAvJHtzZXJpYWxpemVTZWdtZW50KHRyZWUucm9vdCwgdHJ1ZSl9YDtcbiAgICBjb25zdCBxdWVyeSA9IHNlcmlhbGl6ZVF1ZXJ5UGFyYW1zKHRyZWUucXVlcnlQYXJhbXMpO1xuICAgIGNvbnN0IGZyYWdtZW50ID1cbiAgICAgIHR5cGVvZiB0cmVlLmZyYWdtZW50ID09PSBgc3RyaW5nYCA/IGAjJHtlbmNvZGVVcmlGcmFnbWVudCh0cmVlLmZyYWdtZW50KX1gIDogJyc7XG5cbiAgICByZXR1cm4gYCR7c2VnbWVudH0ke3F1ZXJ5fSR7ZnJhZ21lbnR9YDtcbiAgfVxufVxuXG5jb25zdCBERUZBVUxUX1NFUklBTElaRVIgPSBuZXcgRGVmYXVsdFVybFNlcmlhbGl6ZXIoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZVBhdGhzKHNlZ21lbnQ6IFVybFNlZ21lbnRHcm91cCk6IHN0cmluZyB7XG4gIHJldHVybiBzZWdtZW50LnNlZ21lbnRzLm1hcCgocCkgPT4gc2VyaWFsaXplUGF0aChwKSkuam9pbignLycpO1xufVxuXG5mdW5jdGlvbiBzZXJpYWxpemVTZWdtZW50KHNlZ21lbnQ6IFVybFNlZ21lbnRHcm91cCwgcm9vdDogYm9vbGVhbik6IHN0cmluZyB7XG4gIGlmICghc2VnbWVudC5oYXNDaGlsZHJlbigpKSB7XG4gICAgcmV0dXJuIHNlcmlhbGl6ZVBhdGhzKHNlZ21lbnQpO1xuICB9XG5cbiAgaWYgKHJvb3QpIHtcbiAgICBjb25zdCBwcmltYXJ5ID0gc2VnbWVudC5jaGlsZHJlbltQUklNQVJZX09VVExFVF1cbiAgICAgID8gc2VyaWFsaXplU2VnbWVudChzZWdtZW50LmNoaWxkcmVuW1BSSU1BUllfT1VUTEVUXSwgZmFsc2UpXG4gICAgICA6ICcnO1xuICAgIGNvbnN0IGNoaWxkcmVuOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgT2JqZWN0LmVudHJpZXMoc2VnbWVudC5jaGlsZHJlbikuZm9yRWFjaCgoW2ssIHZdKSA9PiB7XG4gICAgICBpZiAoayAhPT0gUFJJTUFSWV9PVVRMRVQpIHtcbiAgICAgICAgY2hpbGRyZW4ucHVzaChgJHtrfToke3NlcmlhbGl6ZVNlZ21lbnQodiwgZmFsc2UpfWApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNoaWxkcmVuLmxlbmd0aCA+IDAgPyBgJHtwcmltYXJ5fSgke2NoaWxkcmVuLmpvaW4oJy8vJyl9KWAgOiBwcmltYXJ5O1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGNoaWxkcmVuID0gbWFwQ2hpbGRyZW5JbnRvQXJyYXkoc2VnbWVudCwgKHY6IFVybFNlZ21lbnRHcm91cCwgazogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAoayA9PT0gUFJJTUFSWV9PVVRMRVQpIHtcbiAgICAgICAgcmV0dXJuIFtzZXJpYWxpemVTZWdtZW50KHNlZ21lbnQuY2hpbGRyZW5bUFJJTUFSWV9PVVRMRVRdLCBmYWxzZSldO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gW2Ake2t9OiR7c2VyaWFsaXplU2VnbWVudCh2LCBmYWxzZSl9YF07XG4gICAgfSk7XG5cbiAgICAvLyB1c2Ugbm8gcGFyZW50aGVzaXMgaWYgdGhlIG9ubHkgY2hpbGQgaXMgYSBwcmltYXJ5IG91dGxldCByb3V0ZVxuICAgIGlmIChPYmplY3Qua2V5cyhzZWdtZW50LmNoaWxkcmVuKS5sZW5ndGggPT09IDEgJiYgc2VnbWVudC5jaGlsZHJlbltQUklNQVJZX09VVExFVF0gIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGAke3NlcmlhbGl6ZVBhdGhzKHNlZ21lbnQpfS8ke2NoaWxkcmVuWzBdfWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIGAke3NlcmlhbGl6ZVBhdGhzKHNlZ21lbnQpfS8oJHtjaGlsZHJlbi5qb2luKCcvLycpfSlgO1xuICB9XG59XG5cbi8qKlxuICogRW5jb2RlcyBhIFVSSSBzdHJpbmcgd2l0aCB0aGUgZGVmYXVsdCBlbmNvZGluZy4gVGhpcyBmdW5jdGlvbiB3aWxsIG9ubHkgZXZlciBiZSBjYWxsZWQgZnJvbVxuICogYGVuY29kZVVyaVF1ZXJ5YCBvciBgZW5jb2RlVXJpU2VnbWVudGAgYXMgaXQncyB0aGUgYmFzZSBzZXQgb2YgZW5jb2RpbmdzIHRvIGJlIHVzZWQuIFdlIG5lZWRcbiAqIGEgY3VzdG9tIGVuY29kaW5nIGJlY2F1c2UgZW5jb2RlVVJJQ29tcG9uZW50IGlzIHRvbyBhZ2dyZXNzaXZlIGFuZCBlbmNvZGVzIHN0dWZmIHRoYXQgZG9lc24ndFxuICogaGF2ZSB0byBiZSBlbmNvZGVkIHBlciBodHRwczovL3VybC5zcGVjLndoYXR3Zy5vcmcuXG4gKi9cbmZ1bmN0aW9uIGVuY29kZVVyaVN0cmluZyhzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHMpXG4gICAgLnJlcGxhY2UoLyU0MC9nLCAnQCcpXG4gICAgLnJlcGxhY2UoLyUzQS9naSwgJzonKVxuICAgIC5yZXBsYWNlKC8lMjQvZywgJyQnKVxuICAgIC5yZXBsYWNlKC8lMkMvZ2ksICcsJyk7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgdXNlZCB0byBlbmNvZGUgYm90aCBrZXlzIGFuZCB2YWx1ZXMgaW4gYSBxdWVyeSBzdHJpbmcga2V5L3ZhbHVlLiBJblxuICogdGhlIGZvbGxvd2luZyBVUkwsIHlvdSBuZWVkIHRvIGNhbGwgZW5jb2RlVXJpUXVlcnkgb24gXCJrXCIgYW5kIFwidlwiOlxuICpcbiAqIGh0dHA6Ly93d3cuc2l0ZS5vcmcvaHRtbDttaz1tdj9rPXYjZlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlVXJpUXVlcnkoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGVuY29kZVVyaVN0cmluZyhzKS5yZXBsYWNlKC8lM0IvZ2ksICc7Jyk7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgdXNlZCB0byBlbmNvZGUgYSBVUkwgZnJhZ21lbnQuIEluIHRoZSBmb2xsb3dpbmcgVVJMLCB5b3UgbmVlZCB0byBjYWxsXG4gKiBlbmNvZGVVcmlGcmFnbWVudCBvbiBcImZcIjpcbiAqXG4gKiBodHRwOi8vd3d3LnNpdGUub3JnL2h0bWw7bWs9bXY/az12I2ZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuY29kZVVyaUZyYWdtZW50KHM6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBlbmNvZGVVUkkocyk7XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgcnVuIG9uIGFueSBVUkkgc2VnbWVudCBhcyB3ZWxsIGFzIHRoZSBrZXkgYW5kIHZhbHVlIGluIGEga2V5L3ZhbHVlXG4gKiBwYWlyIGZvciBtYXRyaXggcGFyYW1zLiBJbiB0aGUgZm9sbG93aW5nIFVSTCwgeW91IG5lZWQgdG8gY2FsbCBlbmNvZGVVcmlTZWdtZW50IG9uIFwiaHRtbFwiLFxuICogXCJta1wiLCBhbmQgXCJtdlwiOlxuICpcbiAqIGh0dHA6Ly93d3cuc2l0ZS5vcmcvaHRtbDttaz1tdj9rPXYjZlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlVXJpU2VnbWVudChzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gZW5jb2RlVXJpU3RyaW5nKHMpLnJlcGxhY2UoL1xcKC9nLCAnJTI4JykucmVwbGFjZSgvXFwpL2csICclMjknKS5yZXBsYWNlKC8lMjYvZ2ksICcmJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGUoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzKTtcbn1cblxuLy8gUXVlcnkga2V5cy92YWx1ZXMgc2hvdWxkIGhhdmUgdGhlIFwiK1wiIHJlcGxhY2VkIGZpcnN0LCBhcyBcIitcIiBpbiBhIHF1ZXJ5IHN0cmluZyBpcyBcIiBcIi5cbi8vIGRlY29kZVVSSUNvbXBvbmVudCBmdW5jdGlvbiB3aWxsIG5vdCBkZWNvZGUgXCIrXCIgYXMgYSBzcGFjZS5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVRdWVyeShzOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gZGVjb2RlKHMucmVwbGFjZSgvXFwrL2csICclMjAnKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVQYXRoKHBhdGg6IFVybFNlZ21lbnQpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7ZW5jb2RlVXJpU2VnbWVudChwYXRoLnBhdGgpfSR7c2VyaWFsaXplTWF0cml4UGFyYW1zKHBhdGgucGFyYW1ldGVycyl9YDtcbn1cblxuZnVuY3Rpb24gc2VyaWFsaXplTWF0cml4UGFyYW1zKHBhcmFtczoge1trZXk6IHN0cmluZ106IHN0cmluZ30pOiBzdHJpbmcge1xuICByZXR1cm4gT2JqZWN0LmVudHJpZXMocGFyYW1zKVxuICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYDske2VuY29kZVVyaVNlZ21lbnQoa2V5KX09JHtlbmNvZGVVcmlTZWdtZW50KHZhbHVlKX1gKVxuICAgIC5qb2luKCcnKTtcbn1cblxuZnVuY3Rpb24gc2VyaWFsaXplUXVlcnlQYXJhbXMocGFyYW1zOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHN0cmluZyB7XG4gIGNvbnN0IHN0clBhcmFtczogc3RyaW5nW10gPSBPYmplY3QuZW50cmllcyhwYXJhbXMpXG4gICAgLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4ge1xuICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpXG4gICAgICAgID8gdmFsdWUubWFwKCh2KSA9PiBgJHtlbmNvZGVVcmlRdWVyeShuYW1lKX09JHtlbmNvZGVVcmlRdWVyeSh2KX1gKS5qb2luKCcmJylcbiAgICAgICAgOiBgJHtlbmNvZGVVcmlRdWVyeShuYW1lKX09JHtlbmNvZGVVcmlRdWVyeSh2YWx1ZSl9YDtcbiAgICB9KVxuICAgIC5maWx0ZXIoKHMpID0+IHMpO1xuXG4gIHJldHVybiBzdHJQYXJhbXMubGVuZ3RoID8gYD8ke3N0clBhcmFtcy5qb2luKCcmJyl9YCA6ICcnO1xufVxuXG5jb25zdCBTRUdNRU5UX1JFID0gL15bXlxcLygpPzsjXSsvO1xuZnVuY3Rpb24gbWF0Y2hTZWdtZW50cyhzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IG1hdGNoID0gc3RyLm1hdGNoKFNFR01FTlRfUkUpO1xuICByZXR1cm4gbWF0Y2ggPyBtYXRjaFswXSA6ICcnO1xufVxuXG5jb25zdCBNQVRSSVhfUEFSQU1fU0VHTUVOVF9SRSA9IC9eW15cXC8oKT87PSNdKy87XG5mdW5jdGlvbiBtYXRjaE1hdHJpeEtleVNlZ21lbnRzKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbWF0Y2ggPSBzdHIubWF0Y2goTUFUUklYX1BBUkFNX1NFR01FTlRfUkUpO1xuICByZXR1cm4gbWF0Y2ggPyBtYXRjaFswXSA6ICcnO1xufVxuXG5jb25zdCBRVUVSWV9QQVJBTV9SRSA9IC9eW149PyYjXSsvO1xuLy8gUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBxdWVyeSBwYXJhbSBhdCB0aGUgc3RhcnQgb2YgdGhlIHN0cmluZyBvciBhbiBlbXB0eSBzdHJpbmdcbmZ1bmN0aW9uIG1hdGNoUXVlcnlQYXJhbXMoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBtYXRjaCA9IHN0ci5tYXRjaChRVUVSWV9QQVJBTV9SRSk7XG4gIHJldHVybiBtYXRjaCA/IG1hdGNoWzBdIDogJyc7XG59XG5cbmNvbnN0IFFVRVJZX1BBUkFNX1ZBTFVFX1JFID0gL15bXiYjXSsvO1xuLy8gUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgcXVlcnkgcGFyYW0gYXQgdGhlIHN0YXJ0IG9mIHRoZSBzdHJpbmcgb3IgYW4gZW1wdHkgc3RyaW5nXG5mdW5jdGlvbiBtYXRjaFVybFF1ZXJ5UGFyYW1WYWx1ZShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IG1hdGNoID0gc3RyLm1hdGNoKFFVRVJZX1BBUkFNX1ZBTFVFX1JFKTtcbiAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMF0gOiAnJztcbn1cblxuY2xhc3MgVXJsUGFyc2VyIHtcbiAgcHJpdmF0ZSByZW1haW5pbmc6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHVybDogc3RyaW5nKSB7XG4gICAgdGhpcy5yZW1haW5pbmcgPSB1cmw7XG4gIH1cblxuICBwYXJzZVJvb3RTZWdtZW50KCk6IFVybFNlZ21lbnRHcm91cCB7XG4gICAgdGhpcy5jb25zdW1lT3B0aW9uYWwoJy8nKTtcblxuICAgIGlmICh0aGlzLnJlbWFpbmluZyA9PT0gJycgfHwgdGhpcy5wZWVrU3RhcnRzV2l0aCgnPycpIHx8IHRoaXMucGVla1N0YXJ0c1dpdGgoJyMnKSkge1xuICAgICAgcmV0dXJuIG5ldyBVcmxTZWdtZW50R3JvdXAoW10sIHt9KTtcbiAgICB9XG5cbiAgICAvLyBUaGUgcm9vdCBzZWdtZW50IGdyb3VwIG5ldmVyIGhhcyBzZWdtZW50c1xuICAgIHJldHVybiBuZXcgVXJsU2VnbWVudEdyb3VwKFtdLCB0aGlzLnBhcnNlQ2hpbGRyZW4oKSk7XG4gIH1cblxuICBwYXJzZVF1ZXJ5UGFyYW1zKCk6IFBhcmFtcyB7XG4gICAgY29uc3QgcGFyYW1zOiBQYXJhbXMgPSB7fTtcbiAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWwoJz8nKSkge1xuICAgICAgZG8ge1xuICAgICAgICB0aGlzLnBhcnNlUXVlcnlQYXJhbShwYXJhbXMpO1xuICAgICAgfSB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWwoJyYnKSk7XG4gICAgfVxuICAgIHJldHVybiBwYXJhbXM7XG4gIH1cblxuICBwYXJzZUZyYWdtZW50KCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNvbnN1bWVPcHRpb25hbCgnIycpID8gZGVjb2RlVVJJQ29tcG9uZW50KHRoaXMucmVtYWluaW5nKSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQ2hpbGRyZW4oKToge1tvdXRsZXQ6IHN0cmluZ106IFVybFNlZ21lbnRHcm91cH0ge1xuICAgIGlmICh0aGlzLnJlbWFpbmluZyA9PT0gJycpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbnN1bWVPcHRpb25hbCgnLycpO1xuXG4gICAgY29uc3Qgc2VnbWVudHM6IFVybFNlZ21lbnRbXSA9IFtdO1xuICAgIGlmICghdGhpcy5wZWVrU3RhcnRzV2l0aCgnKCcpKSB7XG4gICAgICBzZWdtZW50cy5wdXNoKHRoaXMucGFyc2VTZWdtZW50KCkpO1xuICAgIH1cblxuICAgIHdoaWxlICh0aGlzLnBlZWtTdGFydHNXaXRoKCcvJykgJiYgIXRoaXMucGVla1N0YXJ0c1dpdGgoJy8vJykgJiYgIXRoaXMucGVla1N0YXJ0c1dpdGgoJy8oJykpIHtcbiAgICAgIHRoaXMuY2FwdHVyZSgnLycpO1xuICAgICAgc2VnbWVudHMucHVzaCh0aGlzLnBhcnNlU2VnbWVudCgpKTtcbiAgICB9XG5cbiAgICBsZXQgY2hpbGRyZW46IHtbb3V0bGV0OiBzdHJpbmddOiBVcmxTZWdtZW50R3JvdXB9ID0ge307XG4gICAgaWYgKHRoaXMucGVla1N0YXJ0c1dpdGgoJy8oJykpIHtcbiAgICAgIHRoaXMuY2FwdHVyZSgnLycpO1xuICAgICAgY2hpbGRyZW4gPSB0aGlzLnBhcnNlUGFyZW5zKHRydWUpO1xuICAgIH1cblxuICAgIGxldCByZXM6IHtbb3V0bGV0OiBzdHJpbmddOiBVcmxTZWdtZW50R3JvdXB9ID0ge307XG4gICAgaWYgKHRoaXMucGVla1N0YXJ0c1dpdGgoJygnKSkge1xuICAgICAgcmVzID0gdGhpcy5wYXJzZVBhcmVucyhmYWxzZSk7XG4gICAgfVxuXG4gICAgaWYgKHNlZ21lbnRzLmxlbmd0aCA+IDAgfHwgT2JqZWN0LmtleXMoY2hpbGRyZW4pLmxlbmd0aCA+IDApIHtcbiAgICAgIHJlc1tQUklNQVJZX09VVExFVF0gPSBuZXcgVXJsU2VnbWVudEdyb3VwKHNlZ21lbnRzLCBjaGlsZHJlbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8vIHBhcnNlIGEgc2VnbWVudCB3aXRoIGl0cyBtYXRyaXggcGFyYW1ldGVyc1xuICAvLyBpZSBgbmFtZTtrMT12MTtrMmBcbiAgcHJpdmF0ZSBwYXJzZVNlZ21lbnQoKTogVXJsU2VnbWVudCB7XG4gICAgY29uc3QgcGF0aCA9IG1hdGNoU2VnbWVudHModGhpcy5yZW1haW5pbmcpO1xuICAgIGlmIChwYXRoID09PSAnJyAmJiB0aGlzLnBlZWtTdGFydHNXaXRoKCc7JykpIHtcbiAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoXG4gICAgICAgIFJ1bnRpbWVFcnJvckNvZGUuRU1QVFlfUEFUSF9XSVRIX1BBUkFNUyxcbiAgICAgICAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSkgJiZcbiAgICAgICAgICBgRW1wdHkgcGF0aCB1cmwgc2VnbWVudCBjYW5ub3QgaGF2ZSBwYXJhbWV0ZXJzOiAnJHt0aGlzLnJlbWFpbmluZ30nLmAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuY2FwdHVyZShwYXRoKTtcbiAgICByZXR1cm4gbmV3IFVybFNlZ21lbnQoZGVjb2RlKHBhdGgpLCB0aGlzLnBhcnNlTWF0cml4UGFyYW1zKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZU1hdHJpeFBhcmFtcygpOiB7W2tleTogc3RyaW5nXTogc3RyaW5nfSB7XG4gICAgY29uc3QgcGFyYW1zOiB7W2tleTogc3RyaW5nXTogc3RyaW5nfSA9IHt9O1xuICAgIHdoaWxlICh0aGlzLmNvbnN1bWVPcHRpb25hbCgnOycpKSB7XG4gICAgICB0aGlzLnBhcnNlUGFyYW0ocGFyYW1zKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcmFtcztcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VQYXJhbShwYXJhbXM6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9KTogdm9pZCB7XG4gICAgY29uc3Qga2V5ID0gbWF0Y2hNYXRyaXhLZXlTZWdtZW50cyh0aGlzLnJlbWFpbmluZyk7XG4gICAgaWYgKCFrZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jYXB0dXJlKGtleSk7XG4gICAgbGV0IHZhbHVlOiBhbnkgPSAnJztcbiAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWwoJz0nKSkge1xuICAgICAgY29uc3QgdmFsdWVNYXRjaCA9IG1hdGNoU2VnbWVudHModGhpcy5yZW1haW5pbmcpO1xuICAgICAgaWYgKHZhbHVlTWF0Y2gpIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZU1hdGNoO1xuICAgICAgICB0aGlzLmNhcHR1cmUodmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHBhcmFtc1tkZWNvZGUoa2V5KV0gPSBkZWNvZGUodmFsdWUpO1xuICB9XG5cbiAgLy8gUGFyc2UgYSBzaW5nbGUgcXVlcnkgcGFyYW1ldGVyIGBuYW1lWz12YWx1ZV1gXG4gIHByaXZhdGUgcGFyc2VRdWVyeVBhcmFtKHBhcmFtczogUGFyYW1zKTogdm9pZCB7XG4gICAgY29uc3Qga2V5ID0gbWF0Y2hRdWVyeVBhcmFtcyh0aGlzLnJlbWFpbmluZyk7XG4gICAgaWYgKCFrZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jYXB0dXJlKGtleSk7XG4gICAgbGV0IHZhbHVlOiBhbnkgPSAnJztcbiAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWwoJz0nKSkge1xuICAgICAgY29uc3QgdmFsdWVNYXRjaCA9IG1hdGNoVXJsUXVlcnlQYXJhbVZhbHVlKHRoaXMucmVtYWluaW5nKTtcbiAgICAgIGlmICh2YWx1ZU1hdGNoKSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWVNYXRjaDtcbiAgICAgICAgdGhpcy5jYXB0dXJlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBkZWNvZGVkS2V5ID0gZGVjb2RlUXVlcnkoa2V5KTtcbiAgICBjb25zdCBkZWNvZGVkVmFsID0gZGVjb2RlUXVlcnkodmFsdWUpO1xuXG4gICAgaWYgKHBhcmFtcy5oYXNPd25Qcm9wZXJ0eShkZWNvZGVkS2V5KSkge1xuICAgICAgLy8gQXBwZW5kIHRvIGV4aXN0aW5nIHZhbHVlc1xuICAgICAgbGV0IGN1cnJlbnRWYWwgPSBwYXJhbXNbZGVjb2RlZEtleV07XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoY3VycmVudFZhbCkpIHtcbiAgICAgICAgY3VycmVudFZhbCA9IFtjdXJyZW50VmFsXTtcbiAgICAgICAgcGFyYW1zW2RlY29kZWRLZXldID0gY3VycmVudFZhbDtcbiAgICAgIH1cbiAgICAgIGN1cnJlbnRWYWwucHVzaChkZWNvZGVkVmFsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQ3JlYXRlIGEgbmV3IHZhbHVlXG4gICAgICBwYXJhbXNbZGVjb2RlZEtleV0gPSBkZWNvZGVkVmFsO1xuICAgIH1cbiAgfVxuXG4gIC8vIHBhcnNlIGAoYS9iLy9vdXRsZXRfbmFtZTpjL2QpYFxuICBwcml2YXRlIHBhcnNlUGFyZW5zKGFsbG93UHJpbWFyeTogYm9vbGVhbik6IHtbb3V0bGV0OiBzdHJpbmddOiBVcmxTZWdtZW50R3JvdXB9IHtcbiAgICBjb25zdCBzZWdtZW50czoge1trZXk6IHN0cmluZ106IFVybFNlZ21lbnRHcm91cH0gPSB7fTtcbiAgICB0aGlzLmNhcHR1cmUoJygnKTtcblxuICAgIHdoaWxlICghdGhpcy5jb25zdW1lT3B0aW9uYWwoJyknKSAmJiB0aGlzLnJlbWFpbmluZy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBwYXRoID0gbWF0Y2hTZWdtZW50cyh0aGlzLnJlbWFpbmluZyk7XG5cbiAgICAgIGNvbnN0IG5leHQgPSB0aGlzLnJlbWFpbmluZ1twYXRoLmxlbmd0aF07XG5cbiAgICAgIC8vIGlmIGlzIGlzIG5vdCBvbmUgb2YgdGhlc2UgY2hhcmFjdGVycywgdGhlbiB0aGUgc2VnbWVudCB3YXMgdW5lc2NhcGVkXG4gICAgICAvLyBvciB0aGUgZ3JvdXAgd2FzIG5vdCBjbG9zZWRcbiAgICAgIGlmIChuZXh0ICE9PSAnLycgJiYgbmV4dCAhPT0gJyknICYmIG5leHQgIT09ICc7Jykge1xuICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKFxuICAgICAgICAgIFJ1bnRpbWVFcnJvckNvZGUuVU5QQVJTQUJMRV9VUkwsXG4gICAgICAgICAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSkgJiYgYENhbm5vdCBwYXJzZSB1cmwgJyR7dGhpcy51cmx9J2AsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGxldCBvdXRsZXROYW1lOiBzdHJpbmcgPSB1bmRlZmluZWQhO1xuICAgICAgaWYgKHBhdGguaW5kZXhPZignOicpID4gLTEpIHtcbiAgICAgICAgb3V0bGV0TmFtZSA9IHBhdGguc2xpY2UoMCwgcGF0aC5pbmRleE9mKCc6JykpO1xuICAgICAgICB0aGlzLmNhcHR1cmUob3V0bGV0TmFtZSk7XG4gICAgICAgIHRoaXMuY2FwdHVyZSgnOicpO1xuICAgICAgfSBlbHNlIGlmIChhbGxvd1ByaW1hcnkpIHtcbiAgICAgICAgb3V0bGV0TmFtZSA9IFBSSU1BUllfT1VUTEVUO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMucGFyc2VDaGlsZHJlbigpO1xuICAgICAgc2VnbWVudHNbb3V0bGV0TmFtZV0gPVxuICAgICAgICBPYmplY3Qua2V5cyhjaGlsZHJlbikubGVuZ3RoID09PSAxXG4gICAgICAgICAgPyBjaGlsZHJlbltQUklNQVJZX09VVExFVF1cbiAgICAgICAgICA6IG5ldyBVcmxTZWdtZW50R3JvdXAoW10sIGNoaWxkcmVuKTtcbiAgICAgIHRoaXMuY29uc3VtZU9wdGlvbmFsKCcvLycpO1xuICAgIH1cblxuICAgIHJldHVybiBzZWdtZW50cztcbiAgfVxuXG4gIHByaXZhdGUgcGVla1N0YXJ0c1dpdGgoc3RyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZW1haW5pbmcuc3RhcnRzV2l0aChzdHIpO1xuICB9XG5cbiAgLy8gQ29uc3VtZXMgdGhlIHByZWZpeCB3aGVuIGl0IGlzIHByZXNlbnQgYW5kIHJldHVybnMgd2hldGhlciBpdCBoYXMgYmVlbiBjb25zdW1lZFxuICBwcml2YXRlIGNvbnN1bWVPcHRpb25hbChzdHI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLnBlZWtTdGFydHNXaXRoKHN0cikpIHtcbiAgICAgIHRoaXMucmVtYWluaW5nID0gdGhpcy5yZW1haW5pbmcuc3Vic3RyaW5nKHN0ci5sZW5ndGgpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgY2FwdHVyZShzdHI6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb25zdW1lT3B0aW9uYWwoc3RyKSkge1xuICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcihcbiAgICAgICAgUnVudGltZUVycm9yQ29kZS5VTkVYUEVDVEVEX1ZBTFVFX0lOX1VSTCxcbiAgICAgICAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSkgJiYgYEV4cGVjdGVkIFwiJHtzdHJ9XCIuYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSb290KHJvb3RDYW5kaWRhdGU6IFVybFNlZ21lbnRHcm91cCkge1xuICByZXR1cm4gcm9vdENhbmRpZGF0ZS5zZWdtZW50cy5sZW5ndGggPiAwXG4gICAgPyBuZXcgVXJsU2VnbWVudEdyb3VwKFtdLCB7W1BSSU1BUllfT1VUTEVUXTogcm9vdENhbmRpZGF0ZX0pXG4gICAgOiByb290Q2FuZGlkYXRlO1xufVxuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5XG4gKiAtIG1lcmdlcyBwcmltYXJ5IHNlZ21lbnQgY2hpbGRyZW4gaW50byB0aGVpciBwYXJlbnRzXG4gKiAtIGRyb3BzIGVtcHR5IGNoaWxkcmVuICh0aG9zZSB3aGljaCBoYXZlIG5vIHNlZ21lbnRzIGFuZCBubyBjaGlsZHJlbiB0aGVtc2VsdmVzKS4gVGhpcyBsYXR0ZXJcbiAqIHByZXZlbnRzIHNlcmlhbGl6aW5nIGEgZ3JvdXAgaW50byBzb21ldGhpbmcgbGlrZSBgL2EoYXV4OilgLCB3aGVyZSBgYXV4YCBpcyBhbiBlbXB0eSBjaGlsZFxuICogc2VnbWVudC5cbiAqIC0gbWVyZ2VzIG5hbWVkIG91dGxldHMgd2l0aG91dCBhIHByaW1hcnkgc2VnbWVudCBzaWJsaW5nIGludG8gdGhlIGNoaWxkcmVuLiBUaGlzIHByZXZlbnRzXG4gKiBzZXJpYWxpemluZyBhIFVSTCBsaWtlIGAvLyhhOmEpKGI6YikgaW5zdGVhZCBvZiBgLyhhOmEvL2I6YilgIHdoZW4gdGhlIGF1eCBiIHJvdXRlIGxpdmVzIG9uIHRoZVxuICogcm9vdCBidXQgdGhlIGBhYCByb3V0ZSBsaXZlcyB1bmRlciBhbiBlbXB0eSBwYXRoIHByaW1hcnkgcm91dGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcXVhc2hTZWdtZW50R3JvdXAoc2VnbWVudEdyb3VwOiBVcmxTZWdtZW50R3JvdXApOiBVcmxTZWdtZW50R3JvdXAge1xuICBjb25zdCBuZXdDaGlsZHJlbjogUmVjb3JkPHN0cmluZywgVXJsU2VnbWVudEdyb3VwPiA9IHt9O1xuICBmb3IgKGNvbnN0IFtjaGlsZE91dGxldCwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKHNlZ21lbnRHcm91cC5jaGlsZHJlbikpIHtcbiAgICBjb25zdCBjaGlsZENhbmRpZGF0ZSA9IHNxdWFzaFNlZ21lbnRHcm91cChjaGlsZCk7XG4gICAgLy8gbW92ZXMgbmFtZWQgY2hpbGRyZW4gaW4gYW4gZW1wdHkgcGF0aCBwcmltYXJ5IGNoaWxkIGludG8gdGhpcyBncm91cFxuICAgIGlmIChcbiAgICAgIGNoaWxkT3V0bGV0ID09PSBQUklNQVJZX09VVExFVCAmJlxuICAgICAgY2hpbGRDYW5kaWRhdGUuc2VnbWVudHMubGVuZ3RoID09PSAwICYmXG4gICAgICBjaGlsZENhbmRpZGF0ZS5oYXNDaGlsZHJlbigpXG4gICAgKSB7XG4gICAgICBmb3IgKGNvbnN0IFtncmFuZENoaWxkT3V0bGV0LCBncmFuZENoaWxkXSBvZiBPYmplY3QuZW50cmllcyhjaGlsZENhbmRpZGF0ZS5jaGlsZHJlbikpIHtcbiAgICAgICAgbmV3Q2hpbGRyZW5bZ3JhbmRDaGlsZE91dGxldF0gPSBncmFuZENoaWxkO1xuICAgICAgfVxuICAgIH0gLy8gZG9uJ3QgYWRkIGVtcHR5IGNoaWxkcmVuXG4gICAgZWxzZSBpZiAoY2hpbGRDYW5kaWRhdGUuc2VnbWVudHMubGVuZ3RoID4gMCB8fCBjaGlsZENhbmRpZGF0ZS5oYXNDaGlsZHJlbigpKSB7XG4gICAgICBuZXdDaGlsZHJlbltjaGlsZE91dGxldF0gPSBjaGlsZENhbmRpZGF0ZTtcbiAgICB9XG4gIH1cbiAgY29uc3QgcyA9IG5ldyBVcmxTZWdtZW50R3JvdXAoc2VnbWVudEdyb3VwLnNlZ21lbnRzLCBuZXdDaGlsZHJlbik7XG4gIHJldHVybiBtZXJnZVRyaXZpYWxDaGlsZHJlbihzKTtcbn1cblxuLyoqXG4gKiBXaGVuIHBvc3NpYmxlLCBtZXJnZXMgdGhlIHByaW1hcnkgb3V0bGV0IGNoaWxkIGludG8gdGhlIHBhcmVudCBgVXJsU2VnbWVudEdyb3VwYC5cbiAqXG4gKiBXaGVuIGEgc2VnbWVudCBncm91cCBoYXMgb25seSBvbmUgY2hpbGQgd2hpY2ggaXMgYSBwcmltYXJ5IG91dGxldCwgbWVyZ2VzIHRoYXQgY2hpbGQgaW50byB0aGVcbiAqIHBhcmVudC4gVGhhdCBpcywgdGhlIGNoaWxkIHNlZ21lbnQgZ3JvdXAncyBzZWdtZW50cyBhcmUgbWVyZ2VkIGludG8gdGhlIGBzYCBhbmQgdGhlIGNoaWxkJ3NcbiAqIGNoaWxkcmVuIGJlY29tZSB0aGUgY2hpbGRyZW4gb2YgYHNgLiBUaGluayBvZiB0aGlzIGxpa2UgYSAnc3F1YXNoJywgbWVyZ2luZyB0aGUgY2hpbGQgc2VnbWVudFxuICogZ3JvdXAgaW50byB0aGUgcGFyZW50LlxuICovXG5mdW5jdGlvbiBtZXJnZVRyaXZpYWxDaGlsZHJlbihzOiBVcmxTZWdtZW50R3JvdXApOiBVcmxTZWdtZW50R3JvdXAge1xuICBpZiAocy5udW1iZXJPZkNoaWxkcmVuID09PSAxICYmIHMuY2hpbGRyZW5bUFJJTUFSWV9PVVRMRVRdKSB7XG4gICAgY29uc3QgYyA9IHMuY2hpbGRyZW5bUFJJTUFSWV9PVVRMRVRdO1xuICAgIHJldHVybiBuZXcgVXJsU2VnbWVudEdyb3VwKHMuc2VnbWVudHMuY29uY2F0KGMuc2VnbWVudHMpLCBjLmNoaWxkcmVuKTtcbiAgfVxuXG4gIHJldHVybiBzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNVcmxUcmVlKHY6IGFueSk6IHYgaXMgVXJsVHJlZSB7XG4gIHJldHVybiB2IGluc3RhbmNlb2YgVXJsVHJlZTtcbn1cbiJdfQ==