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