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 { ReplaySubject } from 'rxjs';
|
---|
9 | import { deepEqual, isAnchor, isPromise } from './utils';
|
---|
10 | const PATH_MATCH = /^([^?#]*)(\?([^#]*))?(#(.*))?$/;
|
---|
11 | const DOUBLE_SLASH_REGEX = /^\s*[\\/]{2,}/;
|
---|
12 | const IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i;
|
---|
13 | const DEFAULT_PORTS = {
|
---|
14 | 'http:': 80,
|
---|
15 | 'https:': 443,
|
---|
16 | 'ftp:': 21
|
---|
17 | };
|
---|
18 | /**
|
---|
19 | * Location service that provides a drop-in replacement for the $location service
|
---|
20 | * provided in AngularJS.
|
---|
21 | *
|
---|
22 | * @see [Using the Angular Unified Location Service](guide/upgrade#using-the-unified-angular-location-service)
|
---|
23 | *
|
---|
24 | * @publicApi
|
---|
25 | */
|
---|
26 | export class $locationShim {
|
---|
27 | constructor($injector, location, platformLocation, urlCodec, locationStrategy) {
|
---|
28 | this.location = location;
|
---|
29 | this.platformLocation = platformLocation;
|
---|
30 | this.urlCodec = urlCodec;
|
---|
31 | this.locationStrategy = locationStrategy;
|
---|
32 | this.initalizing = true;
|
---|
33 | this.updateBrowser = false;
|
---|
34 | this.$$absUrl = '';
|
---|
35 | this.$$url = '';
|
---|
36 | this.$$host = '';
|
---|
37 | this.$$replace = false;
|
---|
38 | this.$$path = '';
|
---|
39 | this.$$search = '';
|
---|
40 | this.$$hash = '';
|
---|
41 | this.$$changeListeners = [];
|
---|
42 | this.cachedState = null;
|
---|
43 | this.urlChanges = new ReplaySubject(1);
|
---|
44 | this.lastBrowserUrl = '';
|
---|
45 | // This variable should be used *only* inside the cacheState function.
|
---|
46 | this.lastCachedState = null;
|
---|
47 | const initialUrl = this.browserUrl();
|
---|
48 | let parsedUrl = this.urlCodec.parse(initialUrl);
|
---|
49 | if (typeof parsedUrl === 'string') {
|
---|
50 | throw 'Invalid URL';
|
---|
51 | }
|
---|
52 | this.$$protocol = parsedUrl.protocol;
|
---|
53 | this.$$host = parsedUrl.hostname;
|
---|
54 | this.$$port = parseInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null;
|
---|
55 | this.$$parseLinkUrl(initialUrl, initialUrl);
|
---|
56 | this.cacheState();
|
---|
57 | this.$$state = this.browserState();
|
---|
58 | this.location.onUrlChange((newUrl, newState) => {
|
---|
59 | this.urlChanges.next({ newUrl, newState });
|
---|
60 | });
|
---|
61 | if (isPromise($injector)) {
|
---|
62 | $injector.then($i => this.initialize($i));
|
---|
63 | }
|
---|
64 | else {
|
---|
65 | this.initialize($injector);
|
---|
66 | }
|
---|
67 | }
|
---|
68 | initialize($injector) {
|
---|
69 | const $rootScope = $injector.get('$rootScope');
|
---|
70 | const $rootElement = $injector.get('$rootElement');
|
---|
71 | $rootElement.on('click', (event) => {
|
---|
72 | if (event.ctrlKey || event.metaKey || event.shiftKey || event.which === 2 ||
|
---|
73 | event.button === 2) {
|
---|
74 | return;
|
---|
75 | }
|
---|
76 | let elm = event.target;
|
---|
77 | // traverse the DOM up to find first A tag
|
---|
78 | while (elm && elm.nodeName.toLowerCase() !== 'a') {
|
---|
79 | // ignore rewriting if no A tag (reached root element, or no parent - removed from document)
|
---|
80 | if (elm === $rootElement[0] || !(elm = elm.parentNode)) {
|
---|
81 | return;
|
---|
82 | }
|
---|
83 | }
|
---|
84 | if (!isAnchor(elm)) {
|
---|
85 | return;
|
---|
86 | }
|
---|
87 | const absHref = elm.href;
|
---|
88 | const relHref = elm.getAttribute('href');
|
---|
89 | // Ignore when url is started with javascript: or mailto:
|
---|
90 | if (IGNORE_URI_REGEXP.test(absHref)) {
|
---|
91 | return;
|
---|
92 | }
|
---|
93 | if (absHref && !elm.getAttribute('target') && !event.isDefaultPrevented()) {
|
---|
94 | if (this.$$parseLinkUrl(absHref, relHref)) {
|
---|
95 | // We do a preventDefault for all urls that are part of the AngularJS application,
|
---|
96 | // in html5mode and also without, so that we are able to abort navigation without
|
---|
97 | // getting double entries in the location history.
|
---|
98 | event.preventDefault();
|
---|
99 | // update location manually
|
---|
100 | if (this.absUrl() !== this.browserUrl()) {
|
---|
101 | $rootScope.$apply();
|
---|
102 | }
|
---|
103 | }
|
---|
104 | }
|
---|
105 | });
|
---|
106 | this.urlChanges.subscribe(({ newUrl, newState }) => {
|
---|
107 | const oldUrl = this.absUrl();
|
---|
108 | const oldState = this.$$state;
|
---|
109 | this.$$parse(newUrl);
|
---|
110 | newUrl = this.absUrl();
|
---|
111 | this.$$state = newState;
|
---|
112 | const defaultPrevented = $rootScope.$broadcast('$locationChangeStart', newUrl, oldUrl, newState, oldState)
|
---|
113 | .defaultPrevented;
|
---|
114 | // if the location was changed by a `$locationChangeStart` handler then stop
|
---|
115 | // processing this location change
|
---|
116 | if (this.absUrl() !== newUrl)
|
---|
117 | return;
|
---|
118 | // If default was prevented, set back to old state. This is the state that was locally
|
---|
119 | // cached in the $location service.
|
---|
120 | if (defaultPrevented) {
|
---|
121 | this.$$parse(oldUrl);
|
---|
122 | this.state(oldState);
|
---|
123 | this.setBrowserUrlWithFallback(oldUrl, false, oldState);
|
---|
124 | this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);
|
---|
125 | }
|
---|
126 | else {
|
---|
127 | this.initalizing = false;
|
---|
128 | $rootScope.$broadcast('$locationChangeSuccess', newUrl, oldUrl, newState, oldState);
|
---|
129 | this.resetBrowserUpdate();
|
---|
130 | }
|
---|
131 | if (!$rootScope.$$phase) {
|
---|
132 | $rootScope.$digest();
|
---|
133 | }
|
---|
134 | });
|
---|
135 | // update browser
|
---|
136 | $rootScope.$watch(() => {
|
---|
137 | if (this.initalizing || this.updateBrowser) {
|
---|
138 | this.updateBrowser = false;
|
---|
139 | const oldUrl = this.browserUrl();
|
---|
140 | const newUrl = this.absUrl();
|
---|
141 | const oldState = this.browserState();
|
---|
142 | let currentReplace = this.$$replace;
|
---|
143 | const urlOrStateChanged = !this.urlCodec.areEqual(oldUrl, newUrl) || oldState !== this.$$state;
|
---|
144 | // Fire location changes one time to on initialization. This must be done on the
|
---|
145 | // next tick (thus inside $evalAsync()) in order for listeners to be registered
|
---|
146 | // before the event fires. Mimicing behavior from $locationWatch:
|
---|
147 | // https://github.com/angular/angular.js/blob/master/src/ng/location.js#L983
|
---|
148 | if (this.initalizing || urlOrStateChanged) {
|
---|
149 | this.initalizing = false;
|
---|
150 | $rootScope.$evalAsync(() => {
|
---|
151 | // Get the new URL again since it could have changed due to async update
|
---|
152 | const newUrl = this.absUrl();
|
---|
153 | const defaultPrevented = $rootScope
|
---|
154 | .$broadcast('$locationChangeStart', newUrl, oldUrl, this.$$state, oldState)
|
---|
155 | .defaultPrevented;
|
---|
156 | // if the location was changed by a `$locationChangeStart` handler then stop
|
---|
157 | // processing this location change
|
---|
158 | if (this.absUrl() !== newUrl)
|
---|
159 | return;
|
---|
160 | if (defaultPrevented) {
|
---|
161 | this.$$parse(oldUrl);
|
---|
162 | this.$$state = oldState;
|
---|
163 | }
|
---|
164 | else {
|
---|
165 | // This block doesn't run when initalizing because it's going to perform the update to
|
---|
166 | // the URL which shouldn't be needed when initalizing.
|
---|
167 | if (urlOrStateChanged) {
|
---|
168 | this.setBrowserUrlWithFallback(newUrl, currentReplace, oldState === this.$$state ? null : this.$$state);
|
---|
169 | this.$$replace = false;
|
---|
170 | }
|
---|
171 | $rootScope.$broadcast('$locationChangeSuccess', newUrl, oldUrl, this.$$state, oldState);
|
---|
172 | if (urlOrStateChanged) {
|
---|
173 | this.$$notifyChangeListeners(this.url(), this.$$state, oldUrl, oldState);
|
---|
174 | }
|
---|
175 | }
|
---|
176 | });
|
---|
177 | }
|
---|
178 | }
|
---|
179 | this.$$replace = false;
|
---|
180 | });
|
---|
181 | }
|
---|
182 | resetBrowserUpdate() {
|
---|
183 | this.$$replace = false;
|
---|
184 | this.$$state = this.browserState();
|
---|
185 | this.updateBrowser = false;
|
---|
186 | this.lastBrowserUrl = this.browserUrl();
|
---|
187 | }
|
---|
188 | browserUrl(url, replace, state) {
|
---|
189 | // In modern browsers `history.state` is `null` by default; treating it separately
|
---|
190 | // from `undefined` would cause `$browser.url('/foo')` to change `history.state`
|
---|
191 | // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.
|
---|
192 | if (typeof state === 'undefined') {
|
---|
193 | state = null;
|
---|
194 | }
|
---|
195 | // setter
|
---|
196 | if (url) {
|
---|
197 | let sameState = this.lastHistoryState === state;
|
---|
198 | // Normalize the inputted URL
|
---|
199 | url = this.urlCodec.parse(url).href;
|
---|
200 | // Don't change anything if previous and current URLs and states match.
|
---|
201 | if (this.lastBrowserUrl === url && sameState) {
|
---|
202 | return this;
|
---|
203 | }
|
---|
204 | this.lastBrowserUrl = url;
|
---|
205 | this.lastHistoryState = state;
|
---|
206 | // Remove server base from URL as the Angular APIs for updating URL require
|
---|
207 | // it to be the path+.
|
---|
208 | url = this.stripBaseUrl(this.getServerBase(), url) || url;
|
---|
209 | // Set the URL
|
---|
210 | if (replace) {
|
---|
211 | this.locationStrategy.replaceState(state, '', url, '');
|
---|
212 | }
|
---|
213 | else {
|
---|
214 | this.locationStrategy.pushState(state, '', url, '');
|
---|
215 | }
|
---|
216 | this.cacheState();
|
---|
217 | return this;
|
---|
218 | // getter
|
---|
219 | }
|
---|
220 | else {
|
---|
221 | return this.platformLocation.href;
|
---|
222 | }
|
---|
223 | }
|
---|
224 | cacheState() {
|
---|
225 | // This should be the only place in $browser where `history.state` is read.
|
---|
226 | this.cachedState = this.platformLocation.getState();
|
---|
227 | if (typeof this.cachedState === 'undefined') {
|
---|
228 | this.cachedState = null;
|
---|
229 | }
|
---|
230 | // Prevent callbacks fo fire twice if both hashchange & popstate were fired.
|
---|
231 | if (deepEqual(this.cachedState, this.lastCachedState)) {
|
---|
232 | this.cachedState = this.lastCachedState;
|
---|
233 | }
|
---|
234 | this.lastCachedState = this.cachedState;
|
---|
235 | this.lastHistoryState = this.cachedState;
|
---|
236 | }
|
---|
237 | /**
|
---|
238 | * This function emulates the $browser.state() function from AngularJS. It will cause
|
---|
239 | * history.state to be cached unless changed with deep equality check.
|
---|
240 | */
|
---|
241 | browserState() {
|
---|
242 | return this.cachedState;
|
---|
243 | }
|
---|
244 | stripBaseUrl(base, url) {
|
---|
245 | if (url.startsWith(base)) {
|
---|
246 | return url.substr(base.length);
|
---|
247 | }
|
---|
248 | return undefined;
|
---|
249 | }
|
---|
250 | getServerBase() {
|
---|
251 | const { protocol, hostname, port } = this.platformLocation;
|
---|
252 | const baseHref = this.locationStrategy.getBaseHref();
|
---|
253 | let url = `${protocol}//${hostname}${port ? ':' + port : ''}${baseHref || '/'}`;
|
---|
254 | return url.endsWith('/') ? url : url + '/';
|
---|
255 | }
|
---|
256 | parseAppUrl(url) {
|
---|
257 | if (DOUBLE_SLASH_REGEX.test(url)) {
|
---|
258 | throw new Error(`Bad Path - URL cannot start with double slashes: ${url}`);
|
---|
259 | }
|
---|
260 | let prefixed = (url.charAt(0) !== '/');
|
---|
261 | if (prefixed) {
|
---|
262 | url = '/' + url;
|
---|
263 | }
|
---|
264 | let match = this.urlCodec.parse(url, this.getServerBase());
|
---|
265 | if (typeof match === 'string') {
|
---|
266 | throw new Error(`Bad URL - Cannot parse URL: ${url}`);
|
---|
267 | }
|
---|
268 | let path = prefixed && match.pathname.charAt(0) === '/' ? match.pathname.substring(1) : match.pathname;
|
---|
269 | this.$$path = this.urlCodec.decodePath(path);
|
---|
270 | this.$$search = this.urlCodec.decodeSearch(match.search);
|
---|
271 | this.$$hash = this.urlCodec.decodeHash(match.hash);
|
---|
272 | // make sure path starts with '/';
|
---|
273 | if (this.$$path && this.$$path.charAt(0) !== '/') {
|
---|
274 | this.$$path = '/' + this.$$path;
|
---|
275 | }
|
---|
276 | }
|
---|
277 | /**
|
---|
278 | * Registers listeners for URL changes. This API is used to catch updates performed by the
|
---|
279 | * AngularJS framework. These changes are a subset of the `$locationChangeStart` and
|
---|
280 | * `$locationChangeSuccess` events which fire when AngularJS updates its internally-referenced
|
---|
281 | * version of the browser URL.
|
---|
282 | *
|
---|
283 | * It's possible for `$locationChange` events to happen, but for the browser URL
|
---|
284 | * (window.location) to remain unchanged. This `onChange` callback will fire only when AngularJS
|
---|
285 | * actually updates the browser URL (window.location).
|
---|
286 | *
|
---|
287 | * @param fn The callback function that is triggered for the listener when the URL changes.
|
---|
288 | * @param err The callback function that is triggered when an error occurs.
|
---|
289 | */
|
---|
290 | onChange(fn, err = (e) => { }) {
|
---|
291 | this.$$changeListeners.push([fn, err]);
|
---|
292 | }
|
---|
293 | /** @internal */
|
---|
294 | $$notifyChangeListeners(url = '', state, oldUrl = '', oldState) {
|
---|
295 | this.$$changeListeners.forEach(([fn, err]) => {
|
---|
296 | try {
|
---|
297 | fn(url, state, oldUrl, oldState);
|
---|
298 | }
|
---|
299 | catch (e) {
|
---|
300 | err(e);
|
---|
301 | }
|
---|
302 | });
|
---|
303 | }
|
---|
304 | /**
|
---|
305 | * Parses the provided URL, and sets the current URL to the parsed result.
|
---|
306 | *
|
---|
307 | * @param url The URL string.
|
---|
308 | */
|
---|
309 | $$parse(url) {
|
---|
310 | let pathUrl;
|
---|
311 | if (url.startsWith('/')) {
|
---|
312 | pathUrl = url;
|
---|
313 | }
|
---|
314 | else {
|
---|
315 | // Remove protocol & hostname if URL starts with it
|
---|
316 | pathUrl = this.stripBaseUrl(this.getServerBase(), url);
|
---|
317 | }
|
---|
318 | if (typeof pathUrl === 'undefined') {
|
---|
319 | throw new Error(`Invalid url "${url}", missing path prefix "${this.getServerBase()}".`);
|
---|
320 | }
|
---|
321 | this.parseAppUrl(pathUrl);
|
---|
322 | if (!this.$$path) {
|
---|
323 | this.$$path = '/';
|
---|
324 | }
|
---|
325 | this.composeUrls();
|
---|
326 | }
|
---|
327 | /**
|
---|
328 | * Parses the provided URL and its relative URL.
|
---|
329 | *
|
---|
330 | * @param url The full URL string.
|
---|
331 | * @param relHref A URL string relative to the full URL string.
|
---|
332 | */
|
---|
333 | $$parseLinkUrl(url, relHref) {
|
---|
334 | // When relHref is passed, it should be a hash and is handled separately
|
---|
335 | if (relHref && relHref[0] === '#') {
|
---|
336 | this.hash(relHref.slice(1));
|
---|
337 | return true;
|
---|
338 | }
|
---|
339 | let rewrittenUrl;
|
---|
340 | let appUrl = this.stripBaseUrl(this.getServerBase(), url);
|
---|
341 | if (typeof appUrl !== 'undefined') {
|
---|
342 | rewrittenUrl = this.getServerBase() + appUrl;
|
---|
343 | }
|
---|
344 | else if (this.getServerBase() === url + '/') {
|
---|
345 | rewrittenUrl = this.getServerBase();
|
---|
346 | }
|
---|
347 | // Set the URL
|
---|
348 | if (rewrittenUrl) {
|
---|
349 | this.$$parse(rewrittenUrl);
|
---|
350 | }
|
---|
351 | return !!rewrittenUrl;
|
---|
352 | }
|
---|
353 | setBrowserUrlWithFallback(url, replace, state) {
|
---|
354 | const oldUrl = this.url();
|
---|
355 | const oldState = this.$$state;
|
---|
356 | try {
|
---|
357 | this.browserUrl(url, replace, state);
|
---|
358 | // Make sure $location.state() returns referentially identical (not just deeply equal)
|
---|
359 | // state object; this makes possible quick checking if the state changed in the digest
|
---|
360 | // loop. Checking deep equality would be too expensive.
|
---|
361 | this.$$state = this.browserState();
|
---|
362 | }
|
---|
363 | catch (e) {
|
---|
364 | // Restore old values if pushState fails
|
---|
365 | this.url(oldUrl);
|
---|
366 | this.$$state = oldState;
|
---|
367 | throw e;
|
---|
368 | }
|
---|
369 | }
|
---|
370 | composeUrls() {
|
---|
371 | this.$$url = this.urlCodec.normalize(this.$$path, this.$$search, this.$$hash);
|
---|
372 | this.$$absUrl = this.getServerBase() + this.$$url.substr(1); // remove '/' from front of URL
|
---|
373 | this.updateBrowser = true;
|
---|
374 | }
|
---|
375 | /**
|
---|
376 | * Retrieves the full URL representation with all segments encoded according to
|
---|
377 | * rules specified in
|
---|
378 | * [RFC 3986](https://tools.ietf.org/html/rfc3986).
|
---|
379 | *
|
---|
380 | *
|
---|
381 | * ```js
|
---|
382 | * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
|
---|
383 | * let absUrl = $location.absUrl();
|
---|
384 | * // => "http://example.com/#/some/path?foo=bar&baz=xoxo"
|
---|
385 | * ```
|
---|
386 | */
|
---|
387 | absUrl() {
|
---|
388 | return this.$$absUrl;
|
---|
389 | }
|
---|
390 | url(url) {
|
---|
391 | if (typeof url === 'string') {
|
---|
392 | if (!url.length) {
|
---|
393 | url = '/';
|
---|
394 | }
|
---|
395 | const match = PATH_MATCH.exec(url);
|
---|
396 | if (!match)
|
---|
397 | return this;
|
---|
398 | if (match[1] || url === '')
|
---|
399 | this.path(this.urlCodec.decodePath(match[1]));
|
---|
400 | if (match[2] || match[1] || url === '')
|
---|
401 | this.search(match[3] || '');
|
---|
402 | this.hash(match[5] || '');
|
---|
403 | // Chainable method
|
---|
404 | return this;
|
---|
405 | }
|
---|
406 | return this.$$url;
|
---|
407 | }
|
---|
408 | /**
|
---|
409 | * Retrieves the protocol of the current URL.
|
---|
410 | *
|
---|
411 | * ```js
|
---|
412 | * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
|
---|
413 | * let protocol = $location.protocol();
|
---|
414 | * // => "http"
|
---|
415 | * ```
|
---|
416 | */
|
---|
417 | protocol() {
|
---|
418 | return this.$$protocol;
|
---|
419 | }
|
---|
420 | /**
|
---|
421 | * Retrieves the protocol of the current URL.
|
---|
422 | *
|
---|
423 | * In contrast to the non-AngularJS version `location.host` which returns `hostname:port`, this
|
---|
424 | * returns the `hostname` portion only.
|
---|
425 | *
|
---|
426 | *
|
---|
427 | * ```js
|
---|
428 | * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
|
---|
429 | * let host = $location.host();
|
---|
430 | * // => "example.com"
|
---|
431 | *
|
---|
432 | * // given URL http://user:password@example.com:8080/#/some/path?foo=bar&baz=xoxo
|
---|
433 | * host = $location.host();
|
---|
434 | * // => "example.com"
|
---|
435 | * host = location.host;
|
---|
436 | * // => "example.com:8080"
|
---|
437 | * ```
|
---|
438 | */
|
---|
439 | host() {
|
---|
440 | return this.$$host;
|
---|
441 | }
|
---|
442 | /**
|
---|
443 | * Retrieves the port of the current URL.
|
---|
444 | *
|
---|
445 | * ```js
|
---|
446 | * // given URL http://example.com/#/some/path?foo=bar&baz=xoxo
|
---|
447 | * let port = $location.port();
|
---|
448 | * // => 80
|
---|
449 | * ```
|
---|
450 | */
|
---|
451 | port() {
|
---|
452 | return this.$$port;
|
---|
453 | }
|
---|
454 | path(path) {
|
---|
455 | if (typeof path === 'undefined') {
|
---|
456 | return this.$$path;
|
---|
457 | }
|
---|
458 | // null path converts to empty string. Prepend with "/" if needed.
|
---|
459 | path = path !== null ? path.toString() : '';
|
---|
460 | path = path.charAt(0) === '/' ? path : '/' + path;
|
---|
461 | this.$$path = path;
|
---|
462 | this.composeUrls();
|
---|
463 | return this;
|
---|
464 | }
|
---|
465 | search(search, paramValue) {
|
---|
466 | switch (arguments.length) {
|
---|
467 | case 0:
|
---|
468 | return this.$$search;
|
---|
469 | case 1:
|
---|
470 | if (typeof search === 'string' || typeof search === 'number') {
|
---|
471 | this.$$search = this.urlCodec.decodeSearch(search.toString());
|
---|
472 | }
|
---|
473 | else if (typeof search === 'object' && search !== null) {
|
---|
474 | // Copy the object so it's never mutated
|
---|
475 | search = Object.assign({}, search);
|
---|
476 | // remove object undefined or null properties
|
---|
477 | for (const key in search) {
|
---|
478 | if (search[key] == null)
|
---|
479 | delete search[key];
|
---|
480 | }
|
---|
481 | this.$$search = search;
|
---|
482 | }
|
---|
483 | else {
|
---|
484 | throw new Error('LocationProvider.search(): First argument must be a string or an object.');
|
---|
485 | }
|
---|
486 | break;
|
---|
487 | default:
|
---|
488 | if (typeof search === 'string') {
|
---|
489 | const currentSearch = this.search();
|
---|
490 | if (typeof paramValue === 'undefined' || paramValue === null) {
|
---|
491 | delete currentSearch[search];
|
---|
492 | return this.search(currentSearch);
|
---|
493 | }
|
---|
494 | else {
|
---|
495 | currentSearch[search] = paramValue;
|
---|
496 | return this.search(currentSearch);
|
---|
497 | }
|
---|
498 | }
|
---|
499 | }
|
---|
500 | this.composeUrls();
|
---|
501 | return this;
|
---|
502 | }
|
---|
503 | hash(hash) {
|
---|
504 | if (typeof hash === 'undefined') {
|
---|
505 | return this.$$hash;
|
---|
506 | }
|
---|
507 | this.$$hash = hash !== null ? hash.toString() : '';
|
---|
508 | this.composeUrls();
|
---|
509 | return this;
|
---|
510 | }
|
---|
511 | /**
|
---|
512 | * Changes to `$location` during the current `$digest` will replace the current
|
---|
513 | * history record, instead of adding a new one.
|
---|
514 | */
|
---|
515 | replace() {
|
---|
516 | this.$$replace = true;
|
---|
517 | return this;
|
---|
518 | }
|
---|
519 | state(state) {
|
---|
520 | if (typeof state === 'undefined') {
|
---|
521 | return this.$$state;
|
---|
522 | }
|
---|
523 | this.$$state = state;
|
---|
524 | return this;
|
---|
525 | }
|
---|
526 | }
|
---|
527 | /**
|
---|
528 | * The factory function used to create an instance of the `$locationShim` in Angular,
|
---|
529 | * and provides an API-compatiable `$locationProvider` for AngularJS.
|
---|
530 | *
|
---|
531 | * @publicApi
|
---|
532 | */
|
---|
533 | export class $locationShimProvider {
|
---|
534 | constructor(ngUpgrade, location, platformLocation, urlCodec, locationStrategy) {
|
---|
535 | this.ngUpgrade = ngUpgrade;
|
---|
536 | this.location = location;
|
---|
537 | this.platformLocation = platformLocation;
|
---|
538 | this.urlCodec = urlCodec;
|
---|
539 | this.locationStrategy = locationStrategy;
|
---|
540 | }
|
---|
541 | /**
|
---|
542 | * Factory method that returns an instance of the $locationShim
|
---|
543 | */
|
---|
544 | $get() {
|
---|
545 | return new $locationShim(this.ngUpgrade.$injector, this.location, this.platformLocation, this.urlCodec, this.locationStrategy);
|
---|
546 | }
|
---|
547 | /**
|
---|
548 | * Stub method used to keep API compatible with AngularJS. This setting is configured through
|
---|
549 | * the LocationUpgradeModule's `config` method in your Angular app.
|
---|
550 | */
|
---|
551 | hashPrefix(prefix) {
|
---|
552 | throw new Error('Configure LocationUpgrade through LocationUpgradeModule.config method.');
|
---|
553 | }
|
---|
554 | /**
|
---|
555 | * Stub method used to keep API compatible with AngularJS. This setting is configured through
|
---|
556 | * the LocationUpgradeModule's `config` method in your Angular app.
|
---|
557 | */
|
---|
558 | html5Mode(mode) {
|
---|
559 | throw new Error('Configure LocationUpgrade through LocationUpgradeModule.config method.');
|
---|
560 | }
|
---|
561 | }
|
---|
562 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYXRpb25fc2hpbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbW1vbi91cGdyYWRlL3NyYy9sb2NhdGlvbl9zaGltLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUlILE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFHbkMsT0FBTyxFQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBRXZELE1BQU0sVUFBVSxHQUFHLGdDQUFnQyxDQUFDO0FBQ3BELE1BQU0sa0JBQWtCLEdBQUcsZUFBZSxDQUFDO0FBQzNDLE1BQU0saUJBQWlCLEdBQUcsMkJBQTJCLENBQUM7QUFDdEQsTUFBTSxhQUFhLEdBQTRCO0lBQzdDLE9BQU8sRUFBRSxFQUFFO0lBQ1gsUUFBUSxFQUFFLEdBQUc7SUFDYixNQUFNLEVBQUUsRUFBRTtDQUNYLENBQUM7QUFFRjs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLGFBQWE7SUF1QnhCLFlBQ0ksU0FBYyxFQUFVLFFBQWtCLEVBQVUsZ0JBQWtDLEVBQzlFLFFBQWtCLEVBQVUsZ0JBQWtDO1FBRDlDLGFBQVEsR0FBUixRQUFRLENBQVU7UUFBVSxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQzlFLGFBQVEsR0FBUixRQUFRLENBQVU7UUFBVSxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBeEJsRSxnQkFBVyxHQUFHLElBQUksQ0FBQztRQUNuQixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUN0QixhQUFRLEdBQVcsRUFBRSxDQUFDO1FBQ3RCLFVBQUssR0FBVyxFQUFFLENBQUM7UUFFbkIsV0FBTSxHQUFXLEVBQUUsQ0FBQztRQUVwQixjQUFTLEdBQVksS0FBSyxDQUFDO1FBQzNCLFdBQU0sR0FBVyxFQUFFLENBQUM7UUFDcEIsYUFBUSxHQUFRLEVBQUUsQ0FBQztRQUNuQixX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Q0YsT0FBTyxJQUFJLGFBQWEsQ0FDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFDN0UsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVEOzs7T0FHRztJQUNILFVBQVUsQ0FBQyxNQUFlO1FBQ3hCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0VBQXdFLENBQUMsQ0FBQztJQUM1RixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsU0FBUyxDQUFDLElBQVU7UUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3RUFBd0UsQ0FBQyxDQUFDO0lBQzVGLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0xvY2F0aW9uLCBMb2NhdGlvblN0cmF0ZWd5LCBQbGF0Zm9ybUxvY2F0aW9ufSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtVcGdyYWRlTW9kdWxlfSBmcm9tICdAYW5ndWxhci91cGdyYWRlL3N0YXRpYyc7XG5pbXBvcnQge1JlcGxheVN1YmplY3R9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge1VybENvZGVjfSBmcm9tICcuL3BhcmFtcyc7XG5pbXBvcnQge2RlZXBFcXVhbCwgaXNBbmNob3IsIGlzUHJvbWlzZX0gZnJvbSAnLi91dGlscyc7XG5cbmNvbnN0IFBBVEhfTUFUQ0ggPSAvXihbXj8jXSopKFxcPyhbXiNdKikpPygjKC4qKSk/JC87XG5jb25zdCBET1VCTEVfU0xBU0hfUkVHRVggPSAvXlxccypbXFxcXC9dezIsfS87XG5jb25zdCBJR05PUkVfVVJJX1JFR0VYUCA9IC9eXFxzKihqYXZhc2NyaXB0fG1haWx0byk6L2k7XG5jb25zdCBERUZBVUxUX1BPUlRTOiB7W2tleTogc3RyaW5nXTogbnVtYmVyfSA9IHtcbiAgJ2h0dHA6JzogODAsXG4gICdodHRwczonOiA0NDMsXG4gICdmdHA6JzogMjFcbn07XG5cbi8qKlxuICogTG9jYXRpb24gc2VydmljZSB0aGF0IHByb3ZpZGVzIGEgZHJvcC1pbiByZXBsYWNlbWVudCBmb3IgdGhlICRsb2NhdGlvbiBzZXJ2aWNlXG4gKiBwcm92aWRlZCBpbiBBbmd1bGFySlMuXG4gKlxuICogQHNlZSBbVXNpbmcgdGhlIEFuZ3VsYXIgVW5pZmllZCBMb2NhdGlvbiBTZXJ2aWNlXShndWlkZS91cGdyYWRlI3VzaW5nLXRoZS11bmlmaWVkLWFuZ3VsYXItbG9jYXRpb24tc2VydmljZSlcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmV4cG9ydCBjbGFzcyAkbG9jYXRpb25TaGltIHtcbiAgcHJpdmF0ZSBpbml0YWxpemluZyA9IHRydWU7XG4gIHByaXZhdGUgdXBkYXRlQnJvd3NlciA9IGZhbHNlO1xuICBwcml2YXRlICQkYWJzVXJsOiBzdHJpbmcgPSAnJztcbiAgcHJpdmF0ZSAkJHVybDogc3RyaW5nID0gJyc7XG4gIHByaXZhdGUgJCRwcm90b2NvbDogc3RyaW5nO1xuICBwcml2YXRlICQkaG9zdDogc3RyaW5nID0gJyc7XG4gIHByaXZhdGUgJCRwb3J0OiBudW1iZXJ8bnVsbDtcbiAgcHJpdmF0ZSAkJHJlcGxhY2U6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSAkJHBhdGg6IHN0cmluZyA9ICcnO1xuICBwcml2YXRlICQkc2VhcmNoOiBhbnkgPSAnJztcbiAgcHJpdmF0ZSAkJGhhc2g6IHN0cmluZyA9ICcnO1xuICBwcml2YXRlICQkc3RhdGU6IHVua25vd247XG4gIHByaXZhdGUgJCRjaGFuZ2VMaXN0ZW5lcnM6IFtcbiAgICAoKHVybDogc3RyaW5nLCBzdGF0ZTogdW5rbm93biwgb2xkVXJsOiBzdHJpbmcsIG9sZFN0YXRlOiB1bmtub3duLCBlcnI/OiAoZTogRXJyb3IpID0+IHZvaWQpID0+XG4gICAgICAgICB2b2lkKSxcbiAgICAoZTogRXJyb3IpID0+IHZvaWRcbiAgXVtdID0gW107XG5cbiAgcHJpdmF0ZSBjYWNoZWRTdGF0ZTogdW5rbm93biA9IG51bGw7XG5cbiAgcHJpdmF0ZSB1cmxDaGFuZ2VzID0gbmV3IFJlcGxheVN1YmplY3Q8e25ld1VybDogc3RyaW5nLCBuZXdTdGF0ZTogdW5rbm93bn0+KDEpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgJGluamVjdG9yOiBhbnksIHByaXZhdGUgbG9jYXRpb246IExvY2F0aW9uLCBwcml2YXRlIHBsYXRmb3JtTG9jYXRpb246IFBsYXRmb3JtTG9jYXRpb24sXG4gICAgICBwcml2YXRlIHVybENvZGVjOiBVcmxDb2RlYywgcHJpdmF0ZSBsb2NhdGlvblN0cmF0ZWd5OiBMb2NhdGlvblN0cmF0ZWd5KSB7XG4gICAgY29uc3QgaW5pdGlhbFVybCA9IHRoaXMuYnJvd3NlclVybCgpO1xuXG4gICAgbGV0IHBhcnNlZFVybCA9IHRoaXMudXJsQ29kZWMucGFyc2UoaW5pdGlhbFVybCk7XG5cbiAgICBpZiAodHlwZW9mIHBhcnNlZFVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93ICdJbnZhbGlkIFVSTCc7XG4gICAgfVxuXG4gICAgdGhpcy4kJHByb3RvY29sID0gcGFyc2VkVXJsLnByb3RvY29sO1xuICAgIHRoaXMuJCRob3N0ID0gcGFyc2VkVXJsLmhvc3RuYW1lO1xuICAgIHRoaXMuJCRwb3J0ID0gcGFyc2VJbnQocGFyc2VkVXJsLnBvcnQpIHx8IERFRkFVTFRfUE9SVFNbcGFyc2VkVXJsLnByb3RvY29sXSB8fCBudWxsO1xuXG4gICAgdGhpcy4kJHBhcnNlTGlua1VybChpbml0aWFsVXJsLCBpbml0aWFsVXJsKTtcbiAgICB0aGlzLmNhY2hlU3RhdGUoKTtcbiAgICB0aGlzLiQkc3RhdGUgPSB0aGlzLmJyb3dzZXJTdGF0ZSgpO1xuXG4gICAgdGhpcy5sb2NhdGlvbi5vblVybENoYW5nZSgobmV3VXJsLCBuZXdTdGF0ZSkgPT4ge1xuICAgICAgdGhpcy51cmxDaGFuZ2VzLm5leHQoe25ld1VybCwgbmV3U3RhdGV9KTtcbiAgICB9KTtcblxuICAgIGlmIChpc1Byb21pc2UoJGluamVjdG9yKSkge1xuICAgICAgJGluamVjdG9yLnRoZW4oJGkgPT4gdGhpcy5pbml0aWFsaXplKCRpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZSgkaW5qZWN0b3IpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZSgkaW5qZWN0b3I6IGFueSkge1xuICAgIGNvbnN0ICRyb290U2NvcGUgPSAkaW5qZWN0b3IuZ2V0KCckcm9vdFNjb3BlJyk7XG4gICAgY29uc3QgJHJvb3RFbGVtZW50ID0gJGluamVjdG9yLmdldCgnJHJvb3RFbGVtZW50Jyk7XG5cbiAgICAkcm9vdEVsZW1lbnQub24oJ2NsaWNrJywgKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgIGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuc2hpZnRLZXkgfHwgZXZlbnQud2hpY2ggPT09IDIgfHxcbiAgICAgICAgICBldmVudC5idXR0b24gPT09IDIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBsZXQgZWxtOiAoTm9kZSZQYXJlbnROb2RlKXxudWxsID0gZXZlbnQudGFyZ2V0O1xuXG4gICAgICAvLyB0cmF2ZXJzZSB0aGUgRE9NIHVwIHRvIGZpbmQgZmlyc3QgQSB0YWdcbiAgICAgIHdoaWxlIChlbG0gJiYgZWxtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09ICdhJykge1xuICAgICAgICAvLyBpZ25vcmUgcmV3cml0aW5nIGlmIG5vIEEgdGFnIChyZWFjaGVkIHJvb3QgZWxlbWVudCwgb3Igbm8gcGFyZW50IC0gcmVtb3ZlZCBmcm9tIGRvY3VtZW50KVxuICAgICAgICBpZiAoZWxtID09PSAkcm9vdEVsZW1lbnRbMF0gfHwgIShlbG0gPSBlbG0ucGFyZW50Tm9kZSkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFpc0FuY2hvcihlbG0pKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYWJzSHJlZiA9IGVsbS5ocmVmO1xuICAgICAgY29uc3QgcmVsSHJlZiA9IGVsbS5nZXRBdHRyaWJ1dGUoJ2hyZWYnKTtcblxuICAgICAgLy8gSWdub3JlIHdoZW4gdXJsIGlzIHN0YXJ0ZWQgd2l0aCBqYXZhc2NyaXB0OiBvciBtYWlsdG86XG4gICAgICBpZiAoSUdOT1JFX1VSSV9SRUdFWFAudGVzdChhYnNIcmVmKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChhYnNIcmVmICYmICFlbG0uZ2V0QXR0cmlidXRlKCd0YXJnZXQnKSAmJiAhZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpIHtcbiAgICAgICAgaWYgKHRoaXMuJCRwYXJzZUxpbmtVcmwoYWJzSHJlZiwgcmVsSHJlZikpIHtcbiAgICAgICAgICAvLyBXZSBkbyBhIHByZXZlbnREZWZhdWx0IGZvciBhbGwgdXJscyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBBbmd1bGFySlMgYXBwbGljYXRpb24sXG4gICAgICAgICAgLy8gaW4gaHRtbDVtb2RlIGFuZCBhbHNvIHdpdGhvdXQsIHNvIHRoYXQgd2UgYXJlIGFibGUgdG8gYWJvcnQgbmF2aWdhdGlvbiB3aXRob3V0XG4gICAgICAgICAgLy8gZ2V0dGluZyBkb3VibGUgZW50cmllcyBpbiB0aGUgbG9jYXRpb24gaGlzdG9yeS5cbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIC8vIHVwZGF0ZSBsb2NhdGlvbiBtYW51YWxseVxuICAgICAgICAgIGlmICh0aGlzLmFic1VybCgpICE9PSB0aGlzLmJyb3dzZXJVcmwoKSkge1xuICAgICAgICAgICAgJHJvb3RTY29wZS4kYXBwbHkoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMudXJsQ2hhbmdlcy5zdWJzY3JpYmUoKHtuZXdVcmwsIG5ld1N0YXRlfSkgPT4ge1xuICAgICAgY29uc3Qgb2xkVXJsID0gdGhpcy5hYnNVcmwoKTtcbiAgICAgIGNvbnN0IG9sZFN0YXRlID0gdGhpcy4kJHN0YXRlO1xuICAgICAgdGhpcy4kJHBhcnNlKG5ld1VybCk7XG4gICAgICBuZXdVcmwgPSB0aGlzLmFic1VybCgpO1xuICAgICAgdGhpcy4kJHN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBjb25zdCBkZWZhdWx0UHJldmVudGVkID1cbiAgICAgICAgICAkcm9vdFNjb3BlLiRicm9hZGNhc3QoJyRsb2NhdGlvbkNoYW5nZVN0YXJ0JywgbmV3VXJsLCBvbGRVcmwsIG5ld1N0YXRlLCBvbGRTdGF0ZSlcbiAgICAgICAgICAgICAgLmRlZmF1bHRQcmV2ZW50ZWQ7XG5cbiAgICAgIC8vIGlmIHRoZSBsb2NhdGlvbiB3YXMgY2hhbmdlZCBieSBhIGAkbG9jYXRpb25DaGFuZ2VTdGFydGAgaGFuZGxlciB0aGVuIHN0b3BcbiAgICAgIC8vIHByb2Nlc3NpbmcgdGhpcyBsb2NhdGlvbiBjaGFuZ2VcbiAgICAgIGlmICh0aGlzLmFic1VybCgpICE9PSBuZXdVcmwpIHJldHVybjtcblxuICAgICAgLy8gSWYgZGVmYXVsdCB3YXMgcHJldmVudGVkLCBzZXQgYmFjayB0byBvbGQgc3RhdGUuIFRoaXMgaXMgdGhlIHN0YXRlIHRoYXQgd2FzIGxvY2FsbHlcbiAgICAgIC8vIGNhY2hlZCBpbiB0aGUgJGxvY2F0aW9uIHNlcnZpY2UuXG4gICAgICBpZiAoZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICB0aGlzLiQkcGFyc2Uob2xkVXJsKTtcbiAgICAgICAgdGhpcy5zdGF0ZShvbGRTdGF0ZSk7XG4gICAgICAgIHRoaXMuc2V0QnJvd3NlclVybFdpdGhGYWxsYmFjayhvbGRVcmwsIGZhbHNlLCBvbGRTdGF0ZSk7XG4gICAgICAgIHRoaXMuJCRub3RpZnlDaGFuZ2VMaXN0ZW5lcnModGhpcy51cmwoKSwgdGhpcy4kJHN0YXRlLCBvbGRVcmwsIG9sZFN0YXRlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaW5pdGFsaXppbmcgPSBmYWxzZTtcbiAgICAgICAgJHJvb3RTY29wZS4kYnJvYWRjYXN0KCckbG9jYXRpb25DaGFuZ2VTdWNjZXNzJywgbmV3VXJsLCBvbGRVcmwsIG5ld1N0YXRlLCBvbGRTdGF0ZSk7XG4gICAgICAgIHRoaXMucmVzZXRCcm93c2VyVXBkYXRlKCk7XG4gICAgICB9XG4gICAgICBpZiAoISRyb290U2NvcGUuJCRwaGFzZSkge1xuICAgICAgICAkcm9vdFNjb3BlLiRkaWdlc3QoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIHVwZGF0ZSBicm93c2VyXG4gICAgJHJvb3RTY29wZS4kd2F0Y2goKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaW5pdGFsaXppbmcgfHwgdGhpcy51cGRhdGVCcm93c2VyKSB7XG4gICAgICAgIHRoaXMudXBkYXRlQnJvd3NlciA9IGZhbHNlO1xuXG4gICAgICAgIGNvbnN0IG9sZFVybCA9IHRoaXMuYnJvd3NlclVybCgpO1xuICAgICAgICBjb25zdCBuZXdVcmwgPSB0aGlzLmFic1VybCgpO1xuICAgICAgICBjb25zdCBvbGRTdGF0ZSA9IHRoaXMuYnJvd3NlclN0YXRlKCk7XG4gICAgICAgIGxldCBjdXJyZW50UmVwbGFjZSA9IHRoaXMuJCRyZXBsYWNlO1xuXG4gICAgICAgIGNvbnN0IHVybE9yU3RhdGVDaGFuZ2VkID1cbiAgICAgICAgICAgICF0aGlzLnVybENvZGVjLmFyZUVxdWFsKG9sZFVybCwgbmV3VXJsKSB8fCBvbGRTdGF0ZSAhPT0gdGhpcy4kJHN0YXRlO1xuXG4gICAgICAgIC8vIEZpcmUgbG9jYXRpb24gY2hhbmdlcyBvbmUgdGltZSB0byBvbiBpbml0aWFsaXphdGlvbi4gVGhpcyBtdXN0IGJlIGRvbmUgb24gdGhlXG4gICAgICAgIC8vIG5leHQgdGljayAodGh1cyBpbnNpZGUgJGV2YWxBc3luYygpKSBpbiBvcmRlciBmb3IgbGlzdGVuZXJzIHRvIGJlIHJlZ2lzdGVyZWRcbiAgICAgICAgLy8gYmVmb3JlIHRoZSBldmVudCBmaXJlcy4gTWltaWNpbmcgYmVoYXZpb3IgZnJvbSAkbG9jYXRpb25XYXRjaDpcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci5qcy9ibG9iL21hc3Rlci9zcmMvbmcvbG9jYXRpb24uanMjTDk4M1xuICAgICAgICBpZiAodGhpcy5pbml0YWxpemluZyB8fCB1cmxPclN0YXRlQ2hhbmdlZCkge1xuICAgICAgICAgIHRoaXMuaW5pdGFsaXppbmcgPSBmYWxzZTtcblxuICAgICAgICAgICRyb290U2NvcGUuJGV2YWxBc3luYygoKSA9PiB7XG4gICAgICAgICAgICAvLyBHZXQgdGhlIG5ldyBVUkwgYWdhaW4gc2luY2UgaXQgY291bGQgaGF2ZSBjaGFuZ2VkIGR1ZSB0byBhc3luYyB1cGRhdGVcbiAgICAgICAgICAgIGNvbnN0IG5ld1VybCA9IHRoaXMuYWJzVXJsKCk7XG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0UHJldmVudGVkID1cbiAgICAgICAgICAgICAgICAkcm9vdFNjb3BlXG4gICAgICAgICAgICAgICAgICAgIC4kYnJvYWRjYXN0KCckbG9jYXRpb25DaGFuZ2VTdGFydCcsIG5ld1VybCwgb2xkVXJsLCB0aGlzLiQkc3RhdGUsIG9sZFN0YXRlKVxuICAgICAgICAgICAgICAgICAgICAuZGVmYXVsdFByZXZlbnRlZDtcblxuICAgICAgICAgICAgLy8gaWYgdGhlIGxvY2F0aW9uIHdhcyBjaGFuZ2VkIGJ5IGEgYCRsb2NhdGlvbkNoYW5nZVN0YXJ0YCBoYW5kbGVyIHRoZW4gc3RvcFxuICAgICAgICAgICAgLy8gcHJvY2Vzc2luZyB0aGlzIGxvY2F0aW9uIGNoYW5nZVxuICAgICAgICAgICAgaWYgKHRoaXMuYWJzVXJsKCkgIT09IG5ld1VybCkgcmV0dXJuO1xuXG4gICAgICAgICAgICBpZiAoZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICAgICAgICB0aGlzLiQkcGFyc2Uob2xkVXJsKTtcbiAgICAgICAgICAgICAgdGhpcy4kJHN0YXRlID0gb2xkU3RhdGU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBUaGlzIGJsb2NrIGRvZXNuJ3QgcnVuIHdoZW4gaW5pdGFsaXppbmcgYmVjYXVzZSBpdCdzIGdvaW5nIHRvIHBlcmZvcm0gdGhlIHVwZGF0ZSB0b1xuICAgICAgICAgICAgICAvLyB0aGUgVVJMIHdoaWNoIHNob3VsZG4ndCBiZSBuZWVkZWQgd2hlbiBpbml0YWxpemluZy5cbiAgICAgICAgICAgICAgaWYgKHVybE9yU3RhdGVDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRCcm93c2VyVXJsV2l0aEZhbGxiYWNrKFxuICAgICAgICAgICAgICAgICAgICBuZXdVcmwsIGN1cnJlbnRSZXBsYWNlLCBvbGRTdGF0ZSA9PT0gdGhpcy4kJHN0YXRlID8gbnVsbCA6IHRoaXMuJCRzdGF0ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy4kJHJlcGxhY2UgPSBmYWxzZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAkcm9vdFNjb3BlLiRicm9hZGNhc3QoXG4gICAgICAgICAgICAgICAgICAnJGxvY2F0aW9uQ2hhbmdlU3VjY2VzcycsIG5ld1VybCwgb2xkVXJsLCB0aGlzLiQkc3RhdGUsIG9sZFN0YXRlKTtcbiAgICAgICAgICAgICAgaWYgKHVybE9yU3RhdGVDaGFuZ2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kJG5vdGlmeUNoYW5nZUxpc3RlbmVycyh0aGlzLnVybCgpLCB0aGlzLiQkc3RhdGUsIG9sZFVybCwgb2xkU3RhdGUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuJCRyZXBsYWNlID0gZmFsc2U7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlc2V0QnJvd3NlclVwZGF0ZSgpIHtcbiAgICB0aGlzLiQkcmVwbGFjZSA9IGZhbHNlO1xuICAgIHRoaXMuJCRzdGF0ZSA9IHRoaXMuYnJvd3NlclN0YXRlKCk7XG4gICAgdGhpcy51cGRhdGVCcm93c2VyID0gZmFsc2U7XG4gICAgdGhpcy5sYXN0QnJvd3NlclVybCA9IHRoaXMuYnJvd3NlclVybCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBsYXN0SGlzdG9yeVN0YXRlOiB1bmtub3duO1xuICBwcml2YXRlIGxhc3RCcm93c2VyVXJsOiBzdHJpbmcgPSAnJztcbiAgcHJpdmF0ZSBicm93c2VyVXJsKCk6IHN0cmluZztcbiAgcHJpdmF0ZSBicm93c2VyVXJsKHVybDogc3RyaW5nLCByZXBsYWNlPzogYm9vbGVhbiwgc3RhdGU/OiB1bmtub3duKTogdGhpcztcbiAgcHJpdmF0ZSBicm93c2VyVXJsKHVybD86IHN0cmluZywgcmVwbGFjZT86IGJvb2xlYW4sIHN0YXRlPzogdW5rbm93bikge1xuICAgIC8vIEluIG1vZGVybiBicm93c2VycyBgaGlzdG9yeS5zdGF0ZWAgaXMgYG51bGxgIGJ5IGRlZmF1bHQ7IHRyZWF0aW5nIGl0IHNlcGFyYXRlbHlcbiAgICAvLyBmcm9tIGB1bmRlZmluZWRgIHdvdWxkIGNhdXNlIGAkYnJvd3Nlci51cmwoJy9mb28nKWAgdG8gY2hhbmdlIGBoaXN0b3J5LnN0YXRlYFxuICAgIC8vIHRvIHVuZGVmaW5lZCB2aWEgYHB1c2hTdGF0ZWAuIEluc3RlYWQsIGxldCdzIGNoYW5nZSBgdW5kZWZpbmVkYCB0byBgbnVsbGAgaGVyZS5cbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgc3RhdGUgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIHNldHRlclxuICAgIGlmICh1cmwpIHtcbiAgICAgIGxldCBzYW1lU3RhdGUgPSB0aGlzLmxhc3RIaXN0b3J5U3RhdGUgPT09IHN0YXRlO1xuXG4gICAgICAvLyBOb3JtYWxpemUgdGhlIGlucHV0dGVkIFVSTFxuICAgICAgdXJsID0gdGhpcy51cmxDb2RlYy5wYXJzZSh1cmwpLmhyZWY7XG5cbiAgICAgIC8vIERvbid0IGNoYW5nZSBhbnl0aGluZyBpZiBwcmV2aW91cyBhbmQgY3VycmVudCBVUkxzIGFuZCBzdGF0ZXMgbWF0Y2guXG4gICAgICBpZiAodGhpcy5sYXN0QnJvd3NlclVybCA9PT0gdXJsICYmIHNhbWVTdGF0ZSkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHRoaXMubGFzdEJyb3dzZXJVcmwgPSB1cmw7XG4gICAgICB0aGlzLmxhc3RIaXN0b3J5U3RhdGUgPSBzdGF0ZTtcblxuICAgICAgLy8gUmVtb3ZlIHNlcnZlciBiYXNlIGZyb20gVVJMIGFzIHRoZSBBbmd1bGFyIEFQSXMgZm9yIHVwZGF0aW5nIFVSTCByZXF1aXJlXG4gICAgICAvLyBpdCB0byBiZSB0aGUgcGF0aCsuXG4gICAgICB1cmwgPSB0aGlzLnN0cmlwQmFzZVVybCh0aGlzLmdldFNlcnZlckJhc2UoKSwgdXJsKSB8fCB1cmw7XG5cbiAgICAgIC8vIFNldCB0aGUgVVJMXG4gICAgICBpZiAocmVwbGFjZSkge1xuICAgICAgICB0aGlzLmxvY2F0aW9uU3RyYXRlZ3kucmVwbGFjZVN0YXRlKHN0YXRlLCAnJywgdXJsLCAnJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxvY2F0aW9uU3RyYXRlZ3kucHVzaFN0YXRlKHN0YXRlLCAnJywgdXJsLCAnJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2FjaGVTdGF0ZSgpO1xuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICAgIC8vIGdldHRlclxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5wbGF0Zm9ybUxvY2F0aW9uLmhyZWY7XG4gICAgfVxuICB9XG5cbiAgLy8gVGhpcyB2YXJpYWJsZSBzaG91bGQgYmUgdXNlZCAqb25seSogaW5zaWRlIHRoZSBjYWNoZVN0YXRlIGZ1bmN0aW9uLlxuICBwcml2YXRlIGxhc3RDYWNoZWRTdGF0ZTogdW5rbm93biA9IG51bGw7XG4gIHByaXZhdGUgY2FjaGVTdGF0ZSgpIHtcbiAgICAvLyBUaGlzIHNob3VsZCBiZSB0aGUgb25seSBwbGFjZSBpbiAkYnJvd3NlciB3aGVyZSBgaGlzdG9yeS5zdGF0ZWAgaXMgcmVhZC5cbiAgICB0aGlzLmNhY2hlZFN0YXRlID0gdGhpcy5wbGF0Zm9ybUxvY2F0aW9uLmdldFN0YXRlKCk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmNhY2hlZFN0YXRlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5jYWNoZWRTdGF0ZSA9IG51bGw7XG4gICAgfVxuXG4gICAgLy8gUHJldmVudCBjYWxsYmFja3MgZm8gZmlyZSB0d2ljZSBpZiBib3RoIGhhc2hjaGFuZ2UgJiBwb3BzdGF0ZSB3ZXJlIGZpcmVkLlxuICAgIGlmIChkZWVwRXF1YWwodGhpcy5jYWNoZWRTdGF0ZSwgdGhpcy5sYXN0Q2FjaGVkU3RhdGUpKSB7XG4gICAgICB0aGlzLmNhY2hlZFN0YXRlID0gdGhpcy5sYXN0Q2FjaGVkU3RhdGU7XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0Q2FjaGVkU3RhdGUgPSB0aGlzLmNhY2hlZFN0YXRlO1xuICAgIHRoaXMubGFzdEhpc3RvcnlTdGF0ZSA9IHRoaXMuY2FjaGVkU3RhdGU7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBlbXVsYXRlcyB0aGUgJGJyb3dzZXIuc3RhdGUoKSBmdW5jdGlvbiBmcm9tIEFuZ3VsYXJKUy4gSXQgd2lsbCBjYXVzZVxuICAgKiBoaXN0b3J5LnN0YXRlIHRvIGJlIGNhY2hlZCB1bmxlc3MgY2hhbmdlZCB3aXRoIGRlZXAgZXF1YWxpdHkgY2hlY2suXG4gICAqL1xuICBwcml2YXRlIGJyb3dzZXJTdGF0ZSgpOiB1bmtub3duIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZWRTdGF0ZTtcbiAgfVxuXG4gIHByaXZhdGUgc3RyaXBCYXNlVXJsKGJhc2U6IHN0cmluZywgdXJsOiBzdHJpbmcpIHtcbiAgICBpZiAodXJsLnN0YXJ0c1dpdGgoYmFzZSkpIHtcbiAgICAgIHJldHVybiB1cmwuc3Vic3RyKGJhc2UubGVuZ3RoKTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2VydmVyQmFzZSgpIHtcbiAgICBjb25zdCB7cHJvdG9jb2wsIGhvc3RuYW1lLCBwb3J0fSA9IHRoaXMucGxhdGZvcm1Mb2NhdGlvbjtcbiAgICBjb25zdCBiYXNlSHJlZiA9IHRoaXMubG9jYXRpb25TdHJhdGVneS5nZXRCYXNlSHJlZigpO1xuICAgIGxldCB1cmwgPSBgJHtwcm90b2NvbH0vLyR7aG9zdG5hbWV9JHtwb3J0ID8gJzonICsgcG9ydCA6ICcnfSR7YmFzZUhyZWYgfHwgJy8nfWA7XG4gICAgcmV0dXJuIHVybC5lbmRzV2l0aCgnLycpID8gdXJsIDogdXJsICsgJy8nO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUFwcFVybCh1cmw6IHN0cmluZykge1xuICAgIGlmIChET1VCTEVfU0xBU0hfUkVHRVgudGVzdCh1cmwpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEJhZCBQYXRoIC0gVVJMIGNhbm5vdCBzdGFydCB3aXRoIGRvdWJsZSBzbGFzaGVzOiAke3VybH1gKTtcbiAgICB9XG5cbiAgICBsZXQgcHJlZml4ZWQgPSAodXJsLmNoYXJBdCgwKSAhPT0gJy8nKTtcbiAgICBpZiAocHJlZml4ZWQpIHtcbiAgICAgIHVybCA9ICcvJyArIHVybDtcbiAgICB9XG4gICAgbGV0IG1hdGNoID0gdGhpcy51cmxDb2RlYy5wYXJzZSh1cmwsIHRoaXMuZ2V0U2VydmVyQmFzZSgpKTtcbiAgICBpZiAodHlwZW9mIG1hdGNoID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBCYWQgVVJMIC0gQ2Fubm90IHBhcnNlIFVSTDogJHt1cmx9YCk7XG4gICAgfVxuICAgIGxldCBwYXRoID1cbiAgICAgICAgcHJlZml4ZWQgJiYgbWF0Y2gucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycgPyBtYXRjaC5wYXRobmFtZS5zdWJzdHJpbmcoMSkgOiBtYXRjaC5wYXRobmFtZTtcbiAgICB0aGlzLiQkcGF0aCA9IHRoaXMudXJsQ29kZWMuZGVjb2RlUGF0aChwYXRoKTtcbiAgICB0aGlzLiQkc2VhcmNoID0gdGhpcy51cmxDb2RlYy5kZWNvZGVTZWFyY2gobWF0Y2guc2VhcmNoKTtcbiAgICB0aGlzLiQkaGFzaCA9IHRoaXMudXJsQ29kZWMuZGVjb2RlSGFzaChtYXRjaC5oYXNoKTtcblxuICAgIC8vIG1ha2Ugc3VyZSBwYXRoIHN0YXJ0cyB3aXRoICcvJztcbiAgICBpZiAodGhpcy4kJHBhdGggJiYgdGhpcy4kJHBhdGguY2hhckF0KDApICE9PSAnLycpIHtcbiAgICAgIHRoaXMuJCRwYXRoID0gJy8nICsgdGhpcy4kJHBhdGg7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBsaXN0ZW5lcnMgZm9yIFVSTCBjaGFuZ2VzLiBUaGlzIEFQSSBpcyB1c2VkIHRvIGNhdGNoIHVwZGF0ZXMgcGVyZm9ybWVkIGJ5IHRoZVxuICAgKiBBbmd1bGFySlMgZnJhbWV3b3JrLiBUaGVzZSBjaGFuZ2VzIGFyZSBhIHN1YnNldCBvZiB0aGUgYCRsb2NhdGlvbkNoYW5nZVN0YXJ0YCBhbmRcbiAgICogYCRsb2NhdGlvbkNoYW5nZVN1Y2Nlc3NgIGV2ZW50cyB3aGljaCBmaXJlIHdoZW4gQW5ndWxhckpTIHVwZGF0ZXMgaXRzIGludGVybmFsbHktcmVmZXJlbmNlZFxuICAgKiB2ZXJzaW9uIG9mIHRoZSBicm93c2VyIFVSTC5cbiAgICpcbiAgICogSXQncyBwb3NzaWJsZSBmb3IgYCRsb2NhdGlvbkNoYW5nZWAgZXZlbnRzIHRvIGhhcHBlbiwgYnV0IGZvciB0aGUgYnJvd3NlciBVUkxcbiAgICogKHdpbmRvdy5sb2NhdGlvbikgdG8gcmVtYWluIHVuY2hhbmdlZC4gVGhpcyBgb25DaGFuZ2VgIGNhbGxiYWNrIHdpbGwgZmlyZSBvbmx5IHdoZW4gQW5ndWxhckpTXG4gICAqIGFjdHVhbGx5IHVwZGF0ZXMgdGhlIGJyb3dzZXIgVVJMICh3aW5kb3cubG9jYXRpb24pLlxuICAgKlxuICAgKiBAcGFyYW0gZm4gVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgaXMgdHJpZ2dlcmVkIGZvciB0aGUgbGlzdGVuZXIgd2hlbiB0aGUgVVJMIGNoYW5nZXMuXG4gICAqIEBwYXJhbSBlcnIgVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgaXMgdHJpZ2dlcmVkIHdoZW4gYW4gZXJyb3Igb2NjdXJzLlxuICAgKi9cbiAgb25DaGFuZ2UoXG4gICAgICBmbjogKHVybDogc3RyaW5nLCBzdGF0ZTogdW5rbm93biwgb2xkVXJsOiBzdHJpbmcsIG9sZFN0YXRlOiB1bmtub3duKSA9PiB2b2lkLFxuICAgICAgZXJyOiAoZTogRXJyb3IpID0+IHZvaWQgPSAoZTogRXJyb3IpID0+IHt9KSB7XG4gICAgdGhpcy4kJGNoYW5nZUxpc3RlbmVycy5wdXNoKFtmbiwgZXJyXSk7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gICQkbm90aWZ5Q2hhbmdlTGlzdGVuZXJzKFxuICAgICAgdXJsOiBzdHJpbmcgPSAnJywgc3RhdGU6IHVua25vd24sIG9sZFVybDogc3RyaW5nID0gJycsIG9sZFN0YXRlOiB1bmtub3duKSB7XG4gICAgdGhpcy4kJGNoYW5nZUxpc3RlbmVycy5mb3JFYWNoKChbZm4sIGVycl0pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZuKHVybCwgc3RhdGUsIG9sZFVybCwgb2xkU3RhdGUpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlcnIoZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIHRoZSBwcm92aWRlZCBVUkwsIGFuZCBzZXRzIHRoZSBjdXJyZW50IFVSTCB0byB0aGUgcGFyc2VkIHJlc3VsdC5cbiAgICpcbiAgICogQHBhcmFtIHVybCBUaGUgVVJMIHN0cmluZy5cbiAgICovXG4gICQkcGFyc2UodXJsOiBzdHJpbmcpIHtcbiAgICBsZXQgcGF0aFVybDogc3RyaW5nfHVuZGVmaW5lZDtcbiAgICBpZiAodXJsLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgICAgcGF0aFVybCA9IHVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmVtb3ZlIHByb3RvY29sICYgaG9zdG5hbWUgaWYgVVJMIHN0YXJ0cyB3aXRoIGl0XG4gICAgICBwYXRoVXJsID0gdGhpcy5zdHJpcEJhc2VVcmwodGhpcy5nZXRTZXJ2ZXJCYXNlKCksIHVybCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcGF0aFVybCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB1cmwgXCIke3VybH1cIiwgbWlzc2luZyBwYXRoIHByZWZpeCBcIiR7dGhpcy5nZXRTZXJ2ZXJCYXNlKCl9XCIuYCk7XG4gICAgfVxuXG4gICAgdGhpcy5wYXJzZUFwcFVybChwYXRoVXJsKTtcblxuICAgIGlmICghdGhpcy4kJHBhdGgpIHtcbiAgICAgIHRoaXMuJCRwYXRoID0gJy8nO1xuICAgIH1cbiAgICB0aGlzLmNvbXBvc2VVcmxzKCk7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIHRoZSBwcm92aWRlZCBVUkwgYW5kIGl0cyByZWxhdGl2ZSBVUkwuXG4gICAqXG4gICAqIEBwYXJhbSB1cmwgVGhlIGZ1bGwgVVJMIHN0cmluZy5cbiAgICogQHBhcmFtIHJlbEhyZWYgQSBVUkwgc3RyaW5nIHJlbGF0aXZlIHRvIHRoZSBmdWxsIFVSTCBzdHJpbmcuXG4gICAqL1xuICAkJHBhcnNlTGlua1VybCh1cmw6IHN0cmluZywgcmVsSHJlZj86IHN0cmluZ3xudWxsKTogYm9vbGVhbiB7XG4gICAgLy8gV2hlbiByZWxIcmVmIGlzIHBhc3NlZCwgaXQgc2hvdWxkIGJlIGEgaGFzaCBhbmQgaXMgaGFuZGxlZCBzZXBhcmF0ZWx5XG4gICAgaWYgKHJlbEhyZWYgJiYgcmVsSHJlZlswXSA9PT0gJyMnKSB7XG4gICAgICB0aGlzLmhhc2gocmVsSHJlZi5zbGljZSgxKSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IHJld3JpdHRlblVybDtcbiAgICBsZXQgYXBwVXJsID0gdGhpcy5zdHJpcEJhc2VVcmwodGhpcy5nZXRTZXJ2ZXJCYXNlKCksIHVybCk7XG4gICAgaWYgKHR5cGVvZiBhcHBVcmwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXdyaXR0ZW5VcmwgPSB0aGlzLmdldFNlcnZlckJhc2UoKSArIGFwcFVybDtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZ2V0U2VydmVyQmFzZSgpID09PSB1cmwgKyAnLycpIHtcbiAgICAgIHJld3JpdHRlblVybCA9IHRoaXMuZ2V0U2VydmVyQmFzZSgpO1xuICAgIH1cbiAgICAvLyBTZXQgdGhlIFVSTFxuICAgIGlmIChyZXdyaXR0ZW5VcmwpIHtcbiAgICAgIHRoaXMuJCRwYXJzZShyZXdyaXR0ZW5VcmwpO1xuICAgIH1cbiAgICByZXR1cm4gISFyZXdyaXR0ZW5Vcmw7XG4gIH1cblxuICBwcml2YXRlIHNldEJyb3dzZXJVcmxXaXRoRmFsbGJhY2sodXJsOiBzdHJpbmcsIHJlcGxhY2U6IGJvb2xlYW4sIHN0YXRlOiB1bmtub3duKSB7XG4gICAgY29uc3Qgb2xkVXJsID0gdGhpcy51cmwoKTtcbiAgICBjb25zdCBvbGRTdGF0ZSA9IHRoaXMuJCRzdGF0ZTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5icm93c2VyVXJsKHVybCwgcmVwbGFjZSwgc3RhdGUpO1xuXG4gICAgICAvLyBNYWtlIHN1cmUgJGxvY2F0aW9uLnN0YXRlKCkgcmV0dXJucyByZWZlcmVudGlhbGx5IGlkZW50aWNhbCAobm90IGp1c3QgZGVlcGx5IGVxdWFsKVxuICAgICAgLy8gc3RhdGUgb2JqZWN0OyB0aGlzIG1ha2VzIHBvc3NpYmxlIHF1aWNrIGNoZWNraW5nIGlmIHRoZSBzdGF0ZSBjaGFuZ2VkIGluIHRoZSBkaWdlc3RcbiAgICAgIC8vIGxvb3AuIENoZWNraW5nIGRlZXAgZXF1YWxpdHkgd291bGQgYmUgdG9vIGV4cGVuc2l2ZS5cbiAgICAgIHRoaXMuJCRzdGF0ZSA9IHRoaXMuYnJvd3NlclN0YXRlKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gUmVzdG9yZSBvbGQgdmFsdWVzIGlmIHB1c2hTdGF0ZSBmYWlsc1xuICAgICAgdGhpcy51cmwob2xkVXJsKTtcbiAgICAgIHRoaXMuJCRzdGF0ZSA9IG9sZFN0YXRlO1xuXG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29tcG9zZVVybHMoKSB7XG4gICAgdGhpcy4kJHVybCA9IHRoaXMudXJsQ29kZWMubm9ybWFsaXplKHRoaXMuJCRwYXRoLCB0aGlzLiQkc2VhcmNoLCB0aGlzLiQkaGFzaCk7XG4gICAgdGhpcy4kJGFic1VybCA9IHRoaXMuZ2V0U2VydmVyQmFzZSgpICsgdGhpcy4kJHVybC5zdWJzdHIoMSk7ICAvLyByZW1vdmUgJy8nIGZyb20gZnJvbnQgb2YgVVJMXG4gICAgdGhpcy51cGRhdGVCcm93c2VyID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIGZ1bGwgVVJMIHJlcHJlc2VudGF0aW9uIHdpdGggYWxsIHNlZ21lbnRzIGVuY29kZWQgYWNjb3JkaW5nIHRvXG4gICAqIHJ1bGVzIHNwZWNpZmllZCBpblxuICAgKiBbUkZDIDM5ODZdKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzOTg2KS5cbiAgICpcbiAgICpcbiAgICogYGBganNcbiAgICogLy8gZ2l2ZW4gVVJMIGh0dHA6Ly9leGFtcGxlLmNvbS8jL3NvbWUvcGF0aD9mb289YmFyJmJhej14b3hvXG4gICAqIGxldCBhYnNVcmwgPSAkbG9jYXRpb24uYWJzVXJsKCk7XG4gICAqIC8vID0+IFwiaHR0cDovL2V4YW1wbGUuY29tLyMvc29tZS9wYXRoP2Zvbz1iYXImYmF6PXhveG9cIlxuICAgKiBgYGBcbiAgICovXG4gIGFic1VybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLiQkYWJzVXJsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgY3VycmVudCBVUkwsIG9yIHNldHMgYSBuZXcgVVJMLiBXaGVuIHNldHRpbmcgYSBVUkwsXG4gICAqIGNoYW5nZXMgdGhlIHBhdGgsIHNlYXJjaCwgYW5kIGhhc2gsIGFuZCByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIGl0cyBvd24gaW5zdGFuY2UuXG4gICAqXG4gICAqIGBgYGpzXG4gICAqIC8vIGdpdmVuIFVSTCBodHRwOi8vZXhhbXBsZS5jb20vIy9zb21lL3BhdGg/Zm9vPWJhciZiYXo9eG94b1xuICAgKiBsZXQgdXJsID0gJGxvY2F0aW9uLnVybCgpO1xuICAgKiAvLyA9PiBcIi9zb21lL3BhdGg/Zm9vPWJhciZiYXo9eG94b1wiXG4gICAqIGBgYFxuICAgKi9cbiAgdXJsKCk6IHN0cmluZztcbiAgdXJsKHVybDogc3RyaW5nKTogdGhpcztcbiAgdXJsKHVybD86IHN0cmluZyk6IHN0cmluZ3x0aGlzIHtcbiAgICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmICghdXJsLmxlbmd0aCkge1xuICAgICAgICB1cmwgPSAnLyc7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1hdGNoID0gUEFUSF9NQVRDSC5leGVjKHVybCk7XG4gICAgICBpZiAoIW1hdGNoKSByZXR1cm4gdGhpcztcbiAgICAgIGlmIChtYXRjaFsxXSB8fCB1cmwgPT09ICcnKSB0aGlzLnBhdGgodGhpcy51cmxDb2RlYy5kZWNvZGVQYXRoKG1hdGNoWzFdKSk7XG4gICAgICBpZiAobWF0Y2hbMl0gfHwgbWF0Y2hbMV0gfHwgdXJsID09PSAnJykgdGhpcy5zZWFyY2gobWF0Y2hbM10gfHwgJycpO1xuICAgICAgdGhpcy5oYXNoKG1hdGNoWzVdIHx8ICcnKTtcblxuICAgICAgLy8gQ2hhaW5hYmxlIG1ldGhvZFxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuJCR1cmw7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSBwcm90b2NvbCBvZiB0aGUgY3VycmVudCBVUkwuXG4gICAqXG4gICAqIGBgYGpzXG4gICAqIC8vIGdpdmVuIFVSTCBodHRwOi8vZXhhbXBsZS5jb20vIy9zb21lL3BhdGg/Zm9vPWJhciZiYXo9eG94b1xuICAgKiBsZXQgcHJvdG9jb2wgPSAkbG9jYXRpb24ucHJvdG9jb2woKTtcbiAgICogLy8gPT4gXCJodHRwXCJcbiAgICogYGBgXG4gICAqL1xuICBwcm90b2NvbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLiQkcHJvdG9jb2w7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSBwcm90b2NvbCBvZiB0aGUgY3VycmVudCBVUkwuXG4gICAqXG4gICAqIEluIGNvbnRyYXN0IHRvIHRoZSBub24tQW5ndWxhckpTIHZlcnNpb24gYGxvY2F0aW9uLmhvc3RgIHdoaWNoIHJldHVybnMgYGhvc3RuYW1lOnBvcnRgLCB0aGlzXG4gICAqIHJldHVybnMgdGhlIGBob3N0bmFtZWAgcG9ydGlvbiBvbmx5LlxuICAgKlxuICAgKlxuICAgKiBgYGBqc1xuICAgKiAvLyBnaXZlbiBVUkwgaHR0cDovL2V4YW1wbGUuY29tLyMvc29tZS9wYXRoP2Zvbz1iYXImYmF6PXhveG9cbiAgICogbGV0IGhvc3QgPSAkbG9jYXRpb24uaG9zdCgpO1xuICAgKiAvLyA9PiBcImV4YW1wbGUuY29tXCJcbiAgICpcbiAgICogLy8gZ2l2ZW4gVVJMIGh0dHA6Ly91c2VyOnBhc3N3b3JkQGV4YW1wbGUuY29tOjgwODAvIy9zb21lL3BhdGg/Zm9vPWJhciZiYXo9eG94b1xuICAgKiBob3N0ID0gJGxvY2F0aW9uLmhvc3QoKTtcbiAgICogLy8gPT4gXCJleGFtcGxlLmNvbVwiXG4gICAqIGhvc3QgPSBsb2NhdGlvbi5ob3N0O1xuICAgKiAvLyA9PiBcImV4YW1wbGUuY29tOjgwODBcIlxuICAgKiBgYGBcbiAgICovXG4gIGhvc3QoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy4kJGhvc3Q7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSBwb3J0IG9mIHRoZSBjdXJyZW50IFVSTC5cbiAgICpcbiAgICogYGBganNcbiAgICogLy8gZ2l2ZW4gVVJMIGh0dHA6Ly9leGFtcGxlLmNvbS8jL3NvbWUvcGF0aD9mb289YmFyJmJhej14b3hvXG4gICAqIGxldCBwb3J0ID0gJGxvY2F0aW9uLnBvcnQoKTtcbiAgICogLy8gPT4gODBcbiAgICogYGBgXG4gICAqL1xuICBwb3J0KCk6IG51bWJlcnxudWxsIHtcbiAgICByZXR1cm4gdGhpcy4kJHBvcnQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSBwYXRoIG9mIHRoZSBjdXJyZW50IFVSTCwgb3IgY2hhbmdlcyB0aGUgcGF0aCBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byBpdHMgb3duXG4gICAqIGluc3RhbmNlLlxuICAgKlxuICAgKiBQYXRocyBzaG91bGQgYWx3YXlzIGJlZ2luIHdpdGggZm9yd2FyZCBzbGFzaCAoLykuIFRoaXMgbWV0aG9kIGFkZHMgdGhlIGZvcndhcmQgc2xhc2hcbiAgICogaWYgaXQgaXMgbWlzc2luZy5cbiAgICpcbiAgICogYGBganNcbiAgICogLy8gZ2l2ZW4gVVJMIGh0dHA6Ly9leGFtcGxlLmNvbS8jL3NvbWUvcGF0aD9mb289YmFyJmJhej14b3hvXG4gICAqIGxldCBwYXRoID0gJGxvY2F0aW9uLnBhdGgoKTtcbiAgICogLy8gPT4gXCIvc29tZS9wYXRoXCJcbiAgICogYGBgXG4gICAqL1xuICBwYXRoKCk6IHN0cmluZztcbiAgcGF0aChwYXRoOiBzdHJpbmd8bnVtYmVyfG51bGwpOiB0aGlzO1xuICBwYXRoKHBhdGg/OiBzdHJpbmd8bnVtYmVyfG51bGwpOiBzdHJpbmd8dGhpcyB7XG4gICAgaWYgKHR5cGVvZiBwYXRoID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIHRoaXMuJCRwYXRoO1xuICAgIH1cblxuICAgIC8vIG51bGwgcGF0aCBjb252ZXJ0cyB0byBlbXB0eSBzdHJpbmcuIFByZXBlbmQgd2l0aCBcIi9cIiBpZiBuZWVkZWQuXG4gICAgcGF0aCA9IHBhdGggIT09IG51bGwgPyBwYXRoLnRvU3RyaW5nKCkgOiAnJztcbiAgICBwYXRoID0gcGF0aC5jaGFyQXQoMCkgPT09ICcvJyA/IHBhdGggOiAnLycgKyBwYXRoO1xuXG4gICAgdGhpcy4kJHBhdGggPSBwYXRoO1xuXG4gICAgdGhpcy5jb21wb3NlVXJscygpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhIG1hcCBvZiB0aGUgc2VhcmNoIHBhcmFtZXRlcnMgb2YgdGhlIGN1cnJlbnQgVVJMLCBvciBjaGFuZ2VzIGEgc2VhcmNoXG4gICAqIHBhcnQgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG8gaXRzIG93biBpbnN0YW5jZS5cbiAgICpcbiAgICpcbiAgICogYGBganNcbiAgICogLy8gZ2l2ZW4gVVJMIGh0dHA6Ly9leGFtcGxlLmNvbS8jL3NvbWUvcGF0aD9mb289YmFyJmJhej14b3hvXG4gICAqIGxldCBzZWFyY2hPYmplY3QgPSAkbG9jYXRpb24uc2VhcmNoKCk7XG4gICAqIC8vID0+IHtmb286ICdiYXInLCBiYXo6ICd4b3hvJ31cbiAgICpcbiAgICogLy8gc2V0IGZvbyB0byAneWlwZWUnXG4gICAqICRsb2NhdGlvbi5zZWFyY2goJ2ZvbycsICd5aXBlZScpO1xuICAgKiAvLyAkbG9jYXRpb24uc2VhcmNoKCkgPT4ge2ZvbzogJ3lpcGVlJywgYmF6OiAneG94byd9XG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ3xPYmplY3QuPHN0cmluZz58T2JqZWN0LjxBcnJheS48c3RyaW5nPj59IHNlYXJjaCBOZXcgc2VhcmNoIHBhcmFtcyAtIHN0cmluZyBvclxuICAgKiBoYXNoIG9iamVjdC5cbiAgICpcbiAgICogV2hlbiBjYWxsZWQgd2l0aCBhIHNpbmdsZSBhcmd1bWVudCB0aGUgbWV0aG9kIGFjdHMgYXMgYSBzZXR0ZXIsIHNldHRpbmcgdGhlIGBzZWFyY2hgIGNvbXBvbmVudFxuICAgKiBvZiBgJGxvY2F0aW9uYCB0byB0aGUgc3BlY2lmaWVkIHZhbHVlLlxuICAgKlxuICAgKiBJZiB0aGUgYXJndW1lbnQgaXMgYSBoYXNoIG9iamVjdCBjb250YWluaW5nIGFuIGFycmF5IG9mIHZhbHVlcywgdGhlc2UgdmFsdWVzIHdpbGwgYmUgZW5jb2RlZFxuICAgKiBhcyBkdXBsaWNhdGUgc2VhcmNoIHBhcmFtZXRlcnMgaW4gdGhlIFVSTC5cbiAgICpcbiAgICogQHBhcmFtIHsoc3RyaW5nfE51bWJlcnxBcnJheTxzdHJpbmc+fGJvb2xlYW4pPX0gcGFyYW1WYWx1ZSBJZiBgc2VhcmNoYCBpcyBhIHN0cmluZyBvciBudW1iZXIsXG4gICAqICAgICB0aGVuIGBwYXJhbVZhbHVlYFxuICAgKiB3aWxsIG92ZXJyaWRlIG9ubHkgYSBzaW5nbGUgc2VhcmNoIHByb3BlcnR5LlxuICAgKlxuICAgKiBJZiBgcGFyYW1WYWx1ZWAgaXMgYW4gYXJyYXksIGl0IHdpbGwgb3ZlcnJpZGUgdGhlIHByb3BlcnR5IG9mIHRoZSBgc2VhcmNoYCBjb21wb25lbnQgb2ZcbiAgICogYCRsb2NhdGlvbmAgc3BlY2lmaWVkIHZpYSB0aGUgZmlyc3QgYXJndW1lbnQuXG4gICAqXG4gICAqIElmIGBwYXJhbVZhbHVlYCBpcyBgbnVsbGAsIHRoZSBwcm9wZXJ0eSBzcGVjaWZpZWQgdmlhIHRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGJlIGRlbGV0ZWQuXG4gICAqXG4gICAqIElmIGBwYXJhbVZhbHVlYCBpcyBgdHJ1ZWAsIHRoZSBwcm9wZXJ0eSBzcGVjaWZpZWQgdmlhIHRoZSBmaXJzdCBhcmd1bWVudCB3aWxsIGJlIGFkZGVkIHdpdGggbm9cbiAgICogdmFsdWUgbm9yIHRyYWlsaW5nIGVxdWFsIHNpZ24uXG4gICAqXG4gICAqIEByZXR1cm4ge09iamVjdH0gVGhlIHBhcnNlZCBgc2VhcmNoYCBvYmplY3Qgb2YgdGhlIGN1cnJlbnQgVVJMLCBvciB0aGUgY2hhbmdlZCBgc2VhcmNoYCBvYmplY3QuXG4gICAqL1xuICBzZWFyY2goKToge1trZXk6IHN0cmluZ106IHVua25vd259O1xuICBzZWFyY2goc2VhcmNoOiBzdHJpbmd8bnVtYmVyfHtba2V5OiBzdHJpbmddOiB1bmtub3dufSk6IHRoaXM7XG4gIHNlYXJjaChcbiAgICAgIHNlYXJjaDogc3RyaW5nfG51bWJlcnx7W2tleTogc3RyaW5nXTogdW5rbm93bn0sXG4gICAgICBwYXJhbVZhbHVlOiBudWxsfHVuZGVmaW5lZHxzdHJpbmd8bnVtYmVyfGJvb2xlYW58c3RyaW5nW10pOiB0aGlzO1xuICBzZWFyY2goXG4gICAgICBzZWFyY2g/OiBzdHJpbmd8bnVtYmVyfHtba2V5OiBzdHJpbmddOiB1bmtub3dufSxcbiAgICAgIHBhcmFtVmFsdWU/OiBudWxsfHVuZGVmaW5lZHxzdHJpbmd8bnVtYmVyfGJvb2xlYW58c3RyaW5nW10pOiB7W2tleTogc3RyaW5nXTogdW5rbm93bn18dGhpcyB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLiQkc2VhcmNoO1xuICAgICAgY2FzZSAxOlxuICAgICAgICBpZiAodHlwZW9mIHNlYXJjaCA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHNlYXJjaCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICB0aGlzLiQkc2VhcmNoID0gdGhpcy51cmxDb2RlYy5kZWNvZGVTZWFyY2goc2VhcmNoLnRvU3RyaW5nKCkpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZWFyY2ggPT09ICdvYmplY3QnICYmIHNlYXJjaCAhPT0gbnVsbCkge1xuICAgICAgICAgIC8vIENvcHkgdGhlIG9iamVjdCBzbyBpdCdzIG5ldmVyIG11dGF0ZWRcbiAgICAgICAgICBzZWFyY2ggPSB7Li4uc2VhcmNofTtcbiAgICAgICAgICAvLyByZW1vdmUgb2JqZWN0IHVuZGVmaW5lZCBvciBudWxsIHByb3BlcnRpZXNcbiAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzZWFyY2gpIHtcbiAgICAgICAgICAgIGlmIChzZWFyY2hba2V5XSA9PSBudWxsKSBkZWxldGUgc2VhcmNoW2tleV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy4kJHNlYXJjaCA9IHNlYXJjaDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICdMb2NhdGlvblByb3ZpZGVyLnNlYXJjaCgpOiBGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nIG9yIGFuIG9iamVjdC4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmICh0eXBlb2Ygc2VhcmNoID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTZWFyY2ggPSB0aGlzLnNlYXJjaCgpO1xuICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1WYWx1ZSA9PT0gJ3VuZGVmaW5lZCcgfHwgcGFyYW1WYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZGVsZXRlIGN1cnJlbnRTZWFyY2hbc2VhcmNoXTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNlYXJjaChjdXJyZW50U2VhcmNoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3VycmVudFNlYXJjaFtzZWFyY2hdID0gcGFyYW1WYWx1ZTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNlYXJjaChjdXJyZW50U2VhcmNoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jb21wb3NlVXJscygpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgY3VycmVudCBoYXNoIGZyYWdtZW50LCBvciBjaGFuZ2VzIHRoZSBoYXNoIGZyYWdtZW50IGFuZCByZXR1cm5zIGEgcmVmZXJlbmNlIHRvXG4gICAqIGl0cyBvd24gaW5zdGFuY2UuXG4gICAqXG4gICAqIGBgYGpzXG4gICAqIC8vIGdpdmVuIFVSTCBodHRwOi8vZXhhbXBsZS5jb20vIy9zb21lL3BhdGg/Zm9vPWJhciZiYXo9eG94byNoYXNoVmFsdWVcbiAgICogbGV0IGhhc2ggPSAkbG9jYXRpb24uaGFzaCgpO1xuICAgKiAvLyA9PiBcImhhc2hWYWx1ZVwiXG4gICAqIGBgYFxuICAgKi9cbiAgaGFzaCgpOiBzdHJpbmc7XG4gIGhhc2goaGFzaDogc3RyaW5nfG51bWJlcnxudWxsKTogdGhpcztcbiAgaGFzaChoYXNoPzogc3RyaW5nfG51bWJlcnxudWxsKTogc3RyaW5nfHRoaXMge1xuICAgIGlmICh0eXBlb2YgaGFzaCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiB0aGlzLiQkaGFzaDtcbiAgICB9XG5cbiAgICB0aGlzLiQkaGFzaCA9IGhhc2ggIT09IG51bGwgPyBoYXNoLnRvU3RyaW5nKCkgOiAnJztcblxuICAgIHRoaXMuY29tcG9zZVVybHMoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGFuZ2VzIHRvIGAkbG9jYXRpb25gIGR1cmluZyB0aGUgY3VycmVudCBgJGRpZ2VzdGAgd2lsbCByZXBsYWNlIHRoZSBjdXJyZW50XG4gICAqIGhpc3RvcnkgcmVjb3JkLCBpbnN0ZWFkIG9mIGFkZGluZyBhIG5ldyBvbmUuXG4gICAqL1xuICByZXBsYWNlKCk6IHRoaXMge1xuICAgIHRoaXMuJCRyZXBsYWNlID0gdHJ1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIGhpc3Rvcnkgc3RhdGUgb2JqZWN0IHdoZW4gY2FsbGVkIHdpdGhvdXQgYW55IHBhcmFtZXRlci5cbiAgICpcbiAgICogQ2hhbmdlIHRoZSBoaXN0b3J5IHN0YXRlIG9iamVjdCB3aGVuIGNhbGxlZCB3aXRoIG9uZSBwYXJhbWV0ZXIgYW5kIHJldHVybiBgJGxvY2F0aW9uYC5cbiAgICogVGhlIHN0YXRlIG9iamVjdCBpcyBsYXRlciBwYXNzZWQgdG8gYHB1c2hTdGF0ZWAgb3IgYHJlcGxhY2VTdGF0ZWAuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGlzIHN1cHBvcnRlZCBvbmx5IGluIEhUTUw1IG1vZGUgYW5kIG9ubHkgaW4gYnJvd3NlcnMgc3VwcG9ydGluZ1xuICAgKiB0aGUgSFRNTDUgSGlzdG9yeSBBUEkgbWV0aG9kcyBzdWNoIGFzIGBwdXNoU3RhdGVgIGFuZCBgcmVwbGFjZVN0YXRlYC4gSWYgeW91IG5lZWQgdG8gc3VwcG9ydFxuICAgKiBvbGRlciBicm93c2VycyAobGlrZSBBbmRyb2lkIDwgNC4wKSwgZG9uJ3QgdXNlIHRoaXMgbWV0aG9kLlxuICAgKlxuICAgKi9cbiAgc3RhdGUoKTogdW5rbm93bjtcbiAgc3RhdGUoc3RhdGU6IHVua25vd24pOiB0aGlzO1xuICBzdGF0ZShzdGF0ZT86IHVua25vd24pOiB1bmtub3dufHRoaXMge1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gdGhpcy4kJHN0YXRlO1xuICAgIH1cblxuICAgIHRoaXMuJCRzdGF0ZSA9IHN0YXRlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbi8qKlxuICogVGhlIGZhY3RvcnkgZnVuY3Rpb24gdXNlZCB0byBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhlIGAkbG9jYXRpb25TaGltYCBpbiBBbmd1bGFyLFxuICogYW5kIHByb3ZpZGVzIGFuIEFQSS1jb21wYXRpYWJsZSBgJGxvY2F0aW9uUHJvdmlkZXJgIGZvciBBbmd1bGFySlMuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgY2xhc3MgJGxvY2F0aW9uU2hpbVByb3ZpZGVyIHtcbiAgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIG5nVXBncmFkZTogVXBncmFkZU1vZHVsZSwgcHJpdmF0ZSBsb2NhdGlvbjogTG9jYXRpb24sXG4gICAgICBwcml2YXRlIHBsYXRmb3JtTG9jYXRpb246IFBsYXRmb3JtTG9jYXRpb24sIHByaXZhdGUgdXJsQ29kZWM6IFVybENvZGVjLFxuICAgICAgcHJpdmF0ZSBsb2NhdGlvblN0cmF0ZWd5OiBMb2NhdGlvblN0cmF0ZWd5KSB7fVxuXG4gIC8qKlxuICAgKiBGYWN0b3J5IG1ldGhvZCB0aGF0IHJldHVybnMgYW4gaW5zdGFuY2Ugb2YgdGhlICRsb2NhdGlvblNoaW1cbiAgICovXG4gICRnZXQoKSB7XG4gICAgcmV0dXJuIG5ldyAkbG9jYXRpb25TaGltKFxuICAgICAgICB0aGlzLm5nVXBncmFkZS4kaW5qZWN0b3IsIHRoaXMubG9jYXRpb24sIHRoaXMucGxhdGZvcm1Mb2NhdGlvbiwgdGhpcy51cmxDb2RlYyxcbiAgICAgICAgdGhpcy5sb2NhdGlvblN0cmF0ZWd5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdHViIG1ldGhvZCB1c2VkIHRvIGtlZXAgQVBJIGNvbXBhdGlibGUgd2l0aCBBbmd1bGFySlMuIFRoaXMgc2V0dGluZyBpcyBjb25maWd1cmVkIHRocm91Z2hcbiAgICogdGhlIExvY2F0aW9uVXBncmFkZU1vZHVsZSdzIGBjb25maWdgIG1ldGhvZCBpbiB5b3VyIEFuZ3VsYXIgYXBwLlxuICAgKi9cbiAgaGFzaFByZWZpeChwcmVmaXg/OiBzdHJpbmcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbmZpZ3VyZSBMb2NhdGlvblVwZ3JhZGUgdGhyb3VnaCBMb2NhdGlvblVwZ3JhZGVNb2R1bGUuY29uZmlnIG1ldGhvZC4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdHViIG1ldGhvZCB1c2VkIHRvIGtlZXAgQVBJIGNvbXBhdGlibGUgd2l0aCBBbmd1bGFySlMuIFRoaXMgc2V0dGluZyBpcyBjb25maWd1cmVkIHRocm91Z2hcbiAgICogdGhlIExvY2F0aW9uVXBncmFkZU1vZHVsZSdzIGBjb25maWdgIG1ldGhvZCBpbiB5b3VyIEFuZ3VsYXIgYXBwLlxuICAgKi9cbiAgaHRtbDVNb2RlKG1vZGU/OiBhbnkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbmZpZ3VyZSBMb2NhdGlvblVwZ3JhZGUgdGhyb3VnaCBMb2NhdGlvblVwZ3JhZGVNb2R1bGUuY29uZmlnIG1ldGhvZC4nKTtcbiAgfVxufVxuIl19 |
---|