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 | /**
|
---|
9 | * Create a {@link UrlResolver} with no package prefix.
|
---|
10 | */
|
---|
11 | export function createUrlResolverWithoutPackagePrefix() {
|
---|
12 | return new UrlResolver();
|
---|
13 | }
|
---|
14 | export function createOfflineCompileUrlResolver() {
|
---|
15 | return new UrlResolver('.');
|
---|
16 | }
|
---|
17 | export const UrlResolver = class UrlResolverImpl {
|
---|
18 | constructor(_packagePrefix = null) {
|
---|
19 | this._packagePrefix = _packagePrefix;
|
---|
20 | }
|
---|
21 | /**
|
---|
22 | * Resolves the `url` given the `baseUrl`:
|
---|
23 | * - when the `url` is null, the `baseUrl` is returned,
|
---|
24 | * - if `url` is relative ('path/to/here', './path/to/here'), the resolved url is a combination of
|
---|
25 | * `baseUrl` and `url`,
|
---|
26 | * - if `url` is absolute (it has a scheme: 'http://', 'https://' or start with '/'), the `url` is
|
---|
27 | * returned as is (ignoring the `baseUrl`)
|
---|
28 | */
|
---|
29 | resolve(baseUrl, url) {
|
---|
30 | let resolvedUrl = url;
|
---|
31 | if (baseUrl != null && baseUrl.length > 0) {
|
---|
32 | resolvedUrl = _resolveUrl(baseUrl, resolvedUrl);
|
---|
33 | }
|
---|
34 | const resolvedParts = _split(resolvedUrl);
|
---|
35 | let prefix = this._packagePrefix;
|
---|
36 | if (prefix != null && resolvedParts != null &&
|
---|
37 | resolvedParts[_ComponentIndex.Scheme] == 'package') {
|
---|
38 | let path = resolvedParts[_ComponentIndex.Path];
|
---|
39 | prefix = prefix.replace(/\/+$/, '');
|
---|
40 | path = path.replace(/^\/+/, '');
|
---|
41 | return `${prefix}/${path}`;
|
---|
42 | }
|
---|
43 | return resolvedUrl;
|
---|
44 | }
|
---|
45 | };
|
---|
46 | /**
|
---|
47 | * Extract the scheme of a URL.
|
---|
48 | */
|
---|
49 | export function getUrlScheme(url) {
|
---|
50 | const match = _split(url);
|
---|
51 | return (match && match[_ComponentIndex.Scheme]) || '';
|
---|
52 | }
|
---|
53 | // The code below is adapted from Traceur:
|
---|
54 | // https://github.com/google/traceur-compiler/blob/9511c1dafa972bf0de1202a8a863bad02f0f95a8/src/runtime/url.js
|
---|
55 | /**
|
---|
56 | * Builds a URI string from already-encoded parts.
|
---|
57 | *
|
---|
58 | * No encoding is performed. Any component may be omitted as either null or
|
---|
59 | * undefined.
|
---|
60 | *
|
---|
61 | * @param opt_scheme The scheme such as 'http'.
|
---|
62 | * @param opt_userInfo The user name before the '@'.
|
---|
63 | * @param opt_domain The domain such as 'www.google.com', already
|
---|
64 | * URI-encoded.
|
---|
65 | * @param opt_port The port number.
|
---|
66 | * @param opt_path The path, already URI-encoded. If it is not
|
---|
67 | * empty, it must begin with a slash.
|
---|
68 | * @param opt_queryData The URI-encoded query data.
|
---|
69 | * @param opt_fragment The URI-encoded fragment identifier.
|
---|
70 | * @return The fully combined URI.
|
---|
71 | */
|
---|
72 | function _buildFromEncodedParts(opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData, opt_fragment) {
|
---|
73 | const out = [];
|
---|
74 | if (opt_scheme != null) {
|
---|
75 | out.push(opt_scheme + ':');
|
---|
76 | }
|
---|
77 | if (opt_domain != null) {
|
---|
78 | out.push('//');
|
---|
79 | if (opt_userInfo != null) {
|
---|
80 | out.push(opt_userInfo + '@');
|
---|
81 | }
|
---|
82 | out.push(opt_domain);
|
---|
83 | if (opt_port != null) {
|
---|
84 | out.push(':' + opt_port);
|
---|
85 | }
|
---|
86 | }
|
---|
87 | if (opt_path != null) {
|
---|
88 | out.push(opt_path);
|
---|
89 | }
|
---|
90 | if (opt_queryData != null) {
|
---|
91 | out.push('?' + opt_queryData);
|
---|
92 | }
|
---|
93 | if (opt_fragment != null) {
|
---|
94 | out.push('#' + opt_fragment);
|
---|
95 | }
|
---|
96 | return out.join('');
|
---|
97 | }
|
---|
98 | /**
|
---|
99 | * A regular expression for breaking a URI into its component parts.
|
---|
100 | *
|
---|
101 | * {@link https://tools.ietf.org/html/rfc3986#appendix-B} says
|
---|
102 | * As the "first-match-wins" algorithm is identical to the "greedy"
|
---|
103 | * disambiguation method used by POSIX regular expressions, it is natural and
|
---|
104 | * commonplace to use a regular expression for parsing the potential five
|
---|
105 | * components of a URI reference.
|
---|
106 | *
|
---|
107 | * The following line is the regular expression for breaking-down a
|
---|
108 | * well-formed URI reference into its components.
|
---|
109 | *
|
---|
110 | * <pre>
|
---|
111 | * ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
|
---|
112 | * 12 3 4 5 6 7 8 9
|
---|
113 | * </pre>
|
---|
114 | *
|
---|
115 | * The numbers in the second line above are only to assist readability; they
|
---|
116 | * indicate the reference points for each subexpression (i.e., each paired
|
---|
117 | * parenthesis). We refer to the value matched for subexpression <n> as $<n>.
|
---|
118 | * For example, matching the above expression to
|
---|
119 | * <pre>
|
---|
120 | * http://www.ics.uci.edu/pub/ietf/uri/#Related
|
---|
121 | * </pre>
|
---|
122 | * results in the following subexpression matches:
|
---|
123 | * <pre>
|
---|
124 | * $1 = http:
|
---|
125 | * $2 = http
|
---|
126 | * $3 = //www.ics.uci.edu
|
---|
127 | * $4 = www.ics.uci.edu
|
---|
128 | * $5 = /pub/ietf/uri/
|
---|
129 | * $6 = <undefined>
|
---|
130 | * $7 = <undefined>
|
---|
131 | * $8 = #Related
|
---|
132 | * $9 = Related
|
---|
133 | * </pre>
|
---|
134 | * where <undefined> indicates that the component is not present, as is the
|
---|
135 | * case for the query component in the above example. Therefore, we can
|
---|
136 | * determine the value of the five components as
|
---|
137 | * <pre>
|
---|
138 | * scheme = $2
|
---|
139 | * authority = $4
|
---|
140 | * path = $5
|
---|
141 | * query = $7
|
---|
142 | * fragment = $9
|
---|
143 | * </pre>
|
---|
144 | *
|
---|
145 | * The regular expression has been modified slightly to expose the
|
---|
146 | * userInfo, domain, and port separately from the authority.
|
---|
147 | * The modified version yields
|
---|
148 | * <pre>
|
---|
149 | * $1 = http scheme
|
---|
150 | * $2 = <undefined> userInfo -\
|
---|
151 | * $3 = www.ics.uci.edu domain | authority
|
---|
152 | * $4 = <undefined> port -/
|
---|
153 | * $5 = /pub/ietf/uri/ path
|
---|
154 | * $6 = <undefined> query without ?
|
---|
155 | * $7 = Related fragment without #
|
---|
156 | * </pre>
|
---|
157 | * @internal
|
---|
158 | */
|
---|
159 | const _splitRe = new RegExp('^' +
|
---|
160 | '(?:' +
|
---|
161 | '([^:/?#.]+)' + // scheme - ignore special characters
|
---|
162 | // used by other URL parts such as :,
|
---|
163 | // ?, /, #, and .
|
---|
164 | ':)?' +
|
---|
165 | '(?://' +
|
---|
166 | '(?:([^/?#]*)@)?' + // userInfo
|
---|
167 | '([\\w\\d\\-\\u0100-\\uffff.%]*)' + // domain - restrict to letters,
|
---|
168 | // digits, dashes, dots, percent
|
---|
169 | // escapes, and unicode characters.
|
---|
170 | '(?::([0-9]+))?' + // port
|
---|
171 | ')?' +
|
---|
172 | '([^?#]+)?' + // path
|
---|
173 | '(?:\\?([^#]*))?' + // query
|
---|
174 | '(?:#(.*))?' + // fragment
|
---|
175 | '$');
|
---|
176 | /**
|
---|
177 | * The index of each URI component in the return value of goog.uri.utils.split.
|
---|
178 | * @enum {number}
|
---|
179 | */
|
---|
180 | var _ComponentIndex;
|
---|
181 | (function (_ComponentIndex) {
|
---|
182 | _ComponentIndex[_ComponentIndex["Scheme"] = 1] = "Scheme";
|
---|
183 | _ComponentIndex[_ComponentIndex["UserInfo"] = 2] = "UserInfo";
|
---|
184 | _ComponentIndex[_ComponentIndex["Domain"] = 3] = "Domain";
|
---|
185 | _ComponentIndex[_ComponentIndex["Port"] = 4] = "Port";
|
---|
186 | _ComponentIndex[_ComponentIndex["Path"] = 5] = "Path";
|
---|
187 | _ComponentIndex[_ComponentIndex["QueryData"] = 6] = "QueryData";
|
---|
188 | _ComponentIndex[_ComponentIndex["Fragment"] = 7] = "Fragment";
|
---|
189 | })(_ComponentIndex || (_ComponentIndex = {}));
|
---|
190 | /**
|
---|
191 | * Splits a URI into its component parts.
|
---|
192 | *
|
---|
193 | * Each component can be accessed via the component indices; for example:
|
---|
194 | * <pre>
|
---|
195 | * goog.uri.utils.split(someStr)[goog.uri.utils.CompontentIndex.QUERY_DATA];
|
---|
196 | * </pre>
|
---|
197 | *
|
---|
198 | * @param uri The URI string to examine.
|
---|
199 | * @return Each component still URI-encoded.
|
---|
200 | * Each component that is present will contain the encoded value, whereas
|
---|
201 | * components that are not present will be undefined or empty, depending
|
---|
202 | * on the browser's regular expression implementation. Never null, since
|
---|
203 | * arbitrary strings may still look like path names.
|
---|
204 | */
|
---|
205 | function _split(uri) {
|
---|
206 | return uri.match(_splitRe);
|
---|
207 | }
|
---|
208 | /**
|
---|
209 | * Removes dot segments in given path component, as described in
|
---|
210 | * RFC 3986, section 5.2.4.
|
---|
211 | *
|
---|
212 | * @param path A non-empty path component.
|
---|
213 | * @return Path component with removed dot segments.
|
---|
214 | */
|
---|
215 | function _removeDotSegments(path) {
|
---|
216 | if (path == '/')
|
---|
217 | return '/';
|
---|
218 | const leadingSlash = path[0] == '/' ? '/' : '';
|
---|
219 | const trailingSlash = path[path.length - 1] === '/' ? '/' : '';
|
---|
220 | const segments = path.split('/');
|
---|
221 | const out = [];
|
---|
222 | let up = 0;
|
---|
223 | for (let pos = 0; pos < segments.length; pos++) {
|
---|
224 | const segment = segments[pos];
|
---|
225 | switch (segment) {
|
---|
226 | case '':
|
---|
227 | case '.':
|
---|
228 | break;
|
---|
229 | case '..':
|
---|
230 | if (out.length > 0) {
|
---|
231 | out.pop();
|
---|
232 | }
|
---|
233 | else {
|
---|
234 | up++;
|
---|
235 | }
|
---|
236 | break;
|
---|
237 | default:
|
---|
238 | out.push(segment);
|
---|
239 | }
|
---|
240 | }
|
---|
241 | if (leadingSlash == '') {
|
---|
242 | while (up-- > 0) {
|
---|
243 | out.unshift('..');
|
---|
244 | }
|
---|
245 | if (out.length === 0)
|
---|
246 | out.push('.');
|
---|
247 | }
|
---|
248 | return leadingSlash + out.join('/') + trailingSlash;
|
---|
249 | }
|
---|
250 | /**
|
---|
251 | * Takes an array of the parts from split and canonicalizes the path part
|
---|
252 | * and then joins all the parts.
|
---|
253 | */
|
---|
254 | function _joinAndCanonicalizePath(parts) {
|
---|
255 | let path = parts[_ComponentIndex.Path];
|
---|
256 | path = path == null ? '' : _removeDotSegments(path);
|
---|
257 | parts[_ComponentIndex.Path] = path;
|
---|
258 | return _buildFromEncodedParts(parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo], parts[_ComponentIndex.Domain], parts[_ComponentIndex.Port], path, parts[_ComponentIndex.QueryData], parts[_ComponentIndex.Fragment]);
|
---|
259 | }
|
---|
260 | /**
|
---|
261 | * Resolves a URL.
|
---|
262 | * @param base The URL acting as the base URL.
|
---|
263 | * @param to The URL to resolve.
|
---|
264 | */
|
---|
265 | function _resolveUrl(base, url) {
|
---|
266 | const parts = _split(encodeURI(url));
|
---|
267 | const baseParts = _split(base);
|
---|
268 | if (parts[_ComponentIndex.Scheme] != null) {
|
---|
269 | return _joinAndCanonicalizePath(parts);
|
---|
270 | }
|
---|
271 | else {
|
---|
272 | parts[_ComponentIndex.Scheme] = baseParts[_ComponentIndex.Scheme];
|
---|
273 | }
|
---|
274 | for (let i = _ComponentIndex.Scheme; i <= _ComponentIndex.Port; i++) {
|
---|
275 | if (parts[i] == null) {
|
---|
276 | parts[i] = baseParts[i];
|
---|
277 | }
|
---|
278 | }
|
---|
279 | if (parts[_ComponentIndex.Path][0] == '/') {
|
---|
280 | return _joinAndCanonicalizePath(parts);
|
---|
281 | }
|
---|
282 | let path = baseParts[_ComponentIndex.Path];
|
---|
283 | if (path == null)
|
---|
284 | path = '/';
|
---|
285 | const index = path.lastIndexOf('/');
|
---|
286 | path = path.substring(0, index + 1) + parts[_ComponentIndex.Path];
|
---|
287 | parts[_ComponentIndex.Path] = path;
|
---|
288 | return _joinAndCanonicalizePath(parts);
|
---|
289 | }
|
---|
290 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsX3Jlc29sdmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3VybF9yZXNvbHZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSDs7R0FFRztBQUNILE1BQU0sVUFBVSxxQ0FBcUM7SUFDbkQsT0FBTyxJQUFJLFdBQVcsRUFBRSxDQUFDO0FBQzNCLENBQUM7QUFFRCxNQUFNLFVBQVUsK0JBQStCO0lBQzdDLE9BQU8sSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDOUIsQ0FBQztBQTBCRCxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQW9CLE1BQU0sZUFBZTtJQUMvRCxZQUFvQixpQkFBOEIsSUFBSTtRQUFsQyxtQkFBYyxHQUFkLGNBQWMsQ0FBb0I7SUFBRyxDQUFDO0lBRTFEOzs7Ozs7O09BT0c7SUFDSCxPQUFPLENBQUMsT0FBZSxFQUFFLEdBQVc7UUFDbEMsSUFBSSxXQUFXLEdBQUcsR0FBRyxDQUFDO1FBQ3RCLElBQUksT0FBTyxJQUFJLElBQUksSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUN6QyxXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQztTQUNqRDtRQUNELE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMxQyxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQ2pDLElBQUksTUFBTSxJQUFJLElBQUksSUFBSSxhQUFhLElBQUksSUFBSTtZQUN2QyxhQUFhLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLFNBQVMsRUFBRTtZQUN0RCxJQUFJLElBQUksR0FBRyxhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9DLE1BQU0sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFF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Ii8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG4vKipcbiAqIENyZWF0ZSBhIHtAbGluayBVcmxSZXNvbHZlcn0gd2l0aCBubyBwYWNrYWdlIHByZWZpeC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVVybFJlc29sdmVyV2l0aG91dFBhY2thZ2VQcmVmaXgoKTogVXJsUmVzb2x2ZXIge1xuICByZXR1cm4gbmV3IFVybFJlc29sdmVyKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPZmZsaW5lQ29tcGlsZVVybFJlc29sdmVyKCk6IFVybFJlc29sdmVyIHtcbiAgcmV0dXJuIG5ldyBVcmxSZXNvbHZlcignLicpO1xufVxuXG4vKipcbiAqIFVzZWQgYnkgdGhlIHtAbGluayBDb21waWxlcn0gd2hlbiByZXNvbHZpbmcgSFRNTCBhbmQgQ1NTIHRlbXBsYXRlIFVSTHMuXG4gKlxuICogVGhpcyBjbGFzcyBjYW4gYmUgb3ZlcnJpZGRlbiBieSB0aGUgYXBwbGljYXRpb24gZGV2ZWxvcGVyIHRvIGNyZWF0ZSBjdXN0b20gYmVoYXZpb3IuXG4gKlxuICogU2VlIHtAbGluayBDb21waWxlcn1cbiAqXG4gKiAjIyBFeGFtcGxlXG4gKlxuICogPGNvZGUtZXhhbXBsZSBwYXRoPVwiY29tcGlsZXIvdHMvdXJsX3Jlc29sdmVyL3VybF9yZXNvbHZlci50c1wiPjwvY29kZS1leGFtcGxlPlxuICpcbiAqIEBzZWN1cml0eSAgV2hlbiBjb21waWxpbmcgdGVtcGxhdGVzIGF0IHJ1bnRpbWUsIHlvdSBtdXN0XG4gKiBlbnN1cmUgdGhhdCB0aGUgZW50aXJlIHRlbXBsYXRlIGNvbWVzIGZyb20gYSB0cnVzdGVkIHNvdXJjZS5cbiAqIEF0dGFja2VyLWNvbnRyb2xsZWQgZGF0YSBpbnRyb2R1Y2VkIGJ5IGEgdGVtcGxhdGUgY291bGQgZXhwb3NlIHlvdXJcbiAqIGFwcGxpY2F0aW9uIHRvIFhTUyByaXNrcy4gRm9yIG1vcmUgZGV0YWlsLCBzZWUgdGhlIFtTZWN1cml0eSBHdWlkZV0oaHR0cHM6Ly9nLmNvL25nL3NlY3VyaXR5KS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVcmxSZXNvbHZlciB7XG4gIHJlc29sdmUoYmFzZVVybDogc3RyaW5nLCB1cmw6IHN0cmluZyk6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVcmxSZXNvbHZlckN0b3Ige1xuICBuZXcocGFja2FnZVByZWZpeD86IHN0cmluZ3xudWxsKTogVXJsUmVzb2x2ZXI7XG59XG5cbmV4cG9ydCBjb25zdCBVcmxSZXNvbHZlcjogVXJsUmVzb2x2ZXJDdG9yID0gY2xhc3MgVXJsUmVzb2x2ZXJJbXBsIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfcGFja2FnZVByZWZpeDogc3RyaW5nfG51bGwgPSBudWxsKSB7fVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgYHVybGAgZ2l2ZW4gdGhlIGBiYXNlVXJsYDpcbiAgICogLSB3aGVuIHRoZSBgdXJsYCBpcyBudWxsLCB0aGUgYGJhc2VVcmxgIGlzIHJldHVybmVkLFxuICAgKiAtIGlmIGB1cmxgIGlzIHJlbGF0aXZlICgncGF0aC90by9oZXJlJywgJy4vcGF0aC90by9oZXJlJyksIHRoZSByZXNvbHZlZCB1cmwgaXMgYSBjb21iaW5hdGlvbiBvZlxuICAgKiBgYmFzZVVybGAgYW5kIGB1cmxgLFxuICAgKiAtIGlmIGB1cmxgIGlzIGFic29sdXRlIChpdCBoYXMgYSBzY2hlbWU6ICdodHRwOi8vJywgJ2h0dHBzOi8vJyBvciBzdGFydCB3aXRoICcvJyksIHRoZSBgdXJsYCBpc1xuICAgKiByZXR1cm5lZCBhcyBpcyAoaWdub3JpbmcgdGhlIGBiYXNlVXJsYClcbiAgICovXG4gIHJlc29sdmUoYmFzZVVybDogc3RyaW5nLCB1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IHJlc29sdmVkVXJsID0gdXJsO1xuICAgIGlmIChiYXNlVXJsICE9IG51bGwgJiYgYmFzZVVybC5sZW5ndGggPiAwKSB7XG4gICAgICByZXNvbHZlZFVybCA9IF9yZXNvbHZlVXJsKGJhc2VVcmwsIHJlc29sdmVkVXJsKTtcbiAgICB9XG4gICAgY29uc3QgcmVzb2x2ZWRQYXJ0cyA9IF9zcGxpdChyZXNvbHZlZFVybCk7XG4gICAgbGV0IHByZWZpeCA9IHRoaXMuX3BhY2thZ2VQcmVmaXg7XG4gICAgaWYgKHByZWZpeCAhPSBudWxsICYmIHJlc29sdmVkUGFydHMgIT0gbnVsbCAmJlxuICAgICAgICByZXNvbHZlZFBhcnRzW19Db21wb25lbnRJbmRleC5TY2hlbWVdID09ICdwYWNrYWdlJykge1xuICAgICAgbGV0IHBhdGggPSByZXNvbHZlZFBhcnRzW19Db21wb25lbnRJbmRleC5QYXRoXTtcbiAgICAgIHByZWZpeCA9IHByZWZpeC5yZXBsYWNlKC9cXC8rJC8sICcnKTtcbiAgICAgIHBhdGggPSBwYXRoLnJlcGxhY2UoL15cXC8rLywgJycpO1xuICAgICAgcmV0dXJuIGAke3ByZWZpeH0vJHtwYXRofWA7XG4gICAgfVxuICAgIHJldHVybiByZXNvbHZlZFVybDtcbiAgfVxufTtcblxuLyoqXG4gKiBFeHRyYWN0IHRoZSBzY2hlbWUgb2YgYSBVUkwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRVcmxTY2hlbWUodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBtYXRjaCA9IF9zcGxpdCh1cmwpO1xuICByZXR1cm4gKG1hdGNoICYmIG1hdGNoW19Db21wb25lbnRJbmRleC5TY2hlbWVdKSB8fCAnJztcbn1cblxuLy8gVGhlIGNvZGUgYmVsb3cgaXMgYWRhcHRlZCBmcm9tIFRyYWNldXI6XG4vLyBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL3RyYWNldXItY29tcGlsZXIvYmxvYi85NTExYzFkYWZhOTcyYmYwZGUxMjAyYThhODYzYmFkMDJmMGY5NWE4L3NyYy9ydW50aW1lL3VybC5qc1xuXG4vKipcbiAqIEJ1aWxkcyBhIFVSSSBzdHJpbmcgZnJvbSBhbHJlYWR5LWVuY29kZWQgcGFydHMuXG4gKlxuICogTm8gZW5jb2RpbmcgaXMgcGVyZm9ybWVkLiAgQW55IGNvbXBvbmVudCBtYXkgYmUgb21pdHRlZCBhcyBlaXRoZXIgbnVsbCBvclxuICogdW5kZWZpbmVkLlxuICpcbiAqIEBwYXJhbSBvcHRfc2NoZW1lIFRoZSBzY2hlbWUgc3VjaCBhcyAnaHR0cCcuXG4gKiBAcGFyYW0gb3B0X3VzZXJJbmZvIFRoZSB1c2VyIG5hbWUgYmVmb3JlIHRoZSAnQCcuXG4gKiBAcGFyYW0gb3B0X2RvbWFpbiBUaGUgZG9tYWluIHN1Y2ggYXMgJ3d3dy5nb29nbGUuY29tJywgYWxyZWFkeVxuICogICAgIFVSSS1lbmNvZGVkLlxuICogQHBhcmFtIG9wdF9wb3J0IFRoZSBwb3J0IG51bWJlci5cbiAqIEBwYXJhbSBvcHRfcGF0aCBUaGUgcGF0aCwgYWxyZWFkeSBVUkktZW5jb2RlZC4gIElmIGl0IGlzIG5vdFxuICogICAgIGVtcHR5LCBpdCBtdXN0IGJlZ2luIHdpdGggYSBzbGFzaC5cbiAqIEBwYXJhbSBvcHRfcXVlcnlEYXRhIFRoZSBVUkktZW5jb2RlZCBxdWVyeSBkYXRhLlxuICogQHBhcmFtIG9wdF9mcmFnbWVudCBUaGUgVVJJLWVuY29kZWQgZnJhZ21lbnQgaWRlbnRpZmllci5cbiAqIEByZXR1cm4gVGhlIGZ1bGx5IGNvbWJpbmVkIFVSSS5cbiAqL1xuZnVuY3Rpb24gX2J1aWxkRnJvbUVuY29kZWRQYXJ0cyhcbiAgICBvcHRfc2NoZW1lPzogc3RyaW5nLCBvcHRfdXNlckluZm8/OiBzdHJpbmcsIG9wdF9kb21haW4/OiBzdHJpbmcsIG9wdF9wb3J0Pzogc3RyaW5nLFxuICAgIG9wdF9wYXRoPzogc3RyaW5nLCBvcHRfcXVlcnlEYXRhPzogc3RyaW5nLCBvcHRfZnJhZ21lbnQ/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBvdXQ6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKG9wdF9zY2hlbWUgIT0gbnVsbCkge1xuICAgIG91dC5wdXNoKG9wdF9zY2hlbWUgKyAnOicpO1xuICB9XG5cbiAgaWYgKG9wdF9kb21haW4gIT0gbnVsbCkge1xuICAgIG91dC5wdXNoKCcvLycpO1xuXG4gICAgaWYgKG9wdF91c2VySW5mbyAhPSBudWxsKSB7XG4gICAgICBvdXQucHVzaChvcHRfdXNlckluZm8gKyAnQCcpO1xuICAgIH1cblxuICAgIG91dC5wdXNoKG9wdF9kb21haW4pO1xuXG4gICAgaWYgKG9wdF9wb3J0ICE9IG51bGwpIHtcbiAgICAgIG91dC5wdXNoKCc6JyArIG9wdF9wb3J0KTtcbiAgICB9XG4gIH1cblxuICBpZiAob3B0X3BhdGggIT0gbnVsbCkge1xuICAgIG91dC5wdXNoKG9wdF9wYXRoKTtcbiAgfVxuXG4gIGlmIChvcHRfcXVlcnlEYXRhICE9IG51bGwpIHtcbiAgICBvdXQucHVzaCgnPycgKyBvcHRfcXVlcnlEYXRhKTtcbiAgfVxuXG4gIGlmIChvcHRfZnJhZ21lbnQgIT0gbnVsbCkge1xuICAgIG91dC5wdXNoKCcjJyArIG9wdF9mcmFnbWVudCk7XG4gIH1cblxuICByZXR1cm4gb3V0LmpvaW4oJycpO1xufVxuXG4vKipcbiAqIEEgcmVndWxhciBleHByZXNzaW9uIGZvciBicmVha2luZyBhIFVSSSBpbnRvIGl0cyBjb21wb25lbnQgcGFydHMuXG4gKlxuICoge0BsaW5rIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzOTg2I2FwcGVuZGl4LUJ9IHNheXNcbiAqIEFzIHRoZSBcImZpcnN0LW1hdGNoLXdpbnNcIiBhbGdvcml0aG0gaXMgaWRlbnRpY2FsIHRvIHRoZSBcImdyZWVkeVwiXG4gKiBkaXNhbWJpZ3VhdGlvbiBtZXRob2QgdXNlZCBieSBQT1NJWCByZWd1bGFyIGV4cHJlc3Npb25zLCBpdCBpcyBuYXR1cmFsIGFuZFxuICogY29tbW9ucGxhY2UgdG8gdXNlIGEgcmVndWxhciBleHByZXNzaW9uIGZvciBwYXJzaW5nIHRoZSBwb3RlbnRpYWwgZml2ZVxuICogY29tcG9uZW50cyBvZiBhIFVSSSByZWZlcmVuY2UuXG4gKlxuICogVGhlIGZvbGxvd2luZyBsaW5lIGlzIHRoZSByZWd1bGFyIGV4cHJlc3Npb24gZm9yIGJyZWFraW5nLWRvd24gYVxuICogd2VsbC1mb3JtZWQgVVJJIHJlZmVyZW5jZSBpbnRvIGl0cyBjb21wb25lbnRzLlxuICpcbiAqIDxwcmU+XG4gKiBeKChbXjovPyNdKyk6KT8oLy8oW14vPyNdKikpPyhbXj8jXSopKFxcPyhbXiNdKikpPygjKC4qKSk/XG4gKiAgMTIgICAgICAgICAgICAzICA0ICAgICAgICAgIDUgICAgICAgNiAgNyAgICAgICAgOCA5XG4gKiA8L3ByZT5cbiAqXG4gKiBUaGUgbnVtYmVycyBpbiB0aGUgc2Vjb25kIGxpbmUgYWJvdmUgYXJlIG9ubHkgdG8gYXNzaXN0IHJlYWRhYmlsaXR5OyB0aGV5XG4gKiBpbmRpY2F0ZSB0aGUgcmVmZXJlbmNlIHBvaW50cyBmb3IgZWFjaCBzdWJleHByZXNzaW9uIChpLmUuLCBlYWNoIHBhaXJlZFxuICogcGFyZW50aGVzaXMpLiBXZSByZWZlciB0byB0aGUgdmFsdWUgbWF0Y2hlZCBmb3Igc3ViZXhwcmVzc2lvbiA8bj4gYXMgJDxuPi5cbiAqIEZvciBleGFtcGxlLCBtYXRjaGluZyB0aGUgYWJvdmUgZXhwcmVzc2lvbiB0b1xuICogPHByZT5cbiAqICAgICBodHRwOi8vd3d3Lmljcy51Y2kuZWR1L3B1Yi9pZXRmL3VyaS8jUmVsYXRlZFxuICogPC9wcmU+XG4gKiByZXN1bHRzIGluIHRoZSBmb2xsb3dpbmcgc3ViZXhwcmVzc2lvbiBtYXRjaGVzOlxuICogPHByZT5cbiAqICAgICQxID0gaHR0cDpcbiAqICAgICQyID0gaHR0cFxuICogICAgJDMgPSAvL3d3dy5pY3MudWNpLmVkdVxuICogICAgJDQgPSB3d3cuaWNzLnVjaS5lZHVcbiAqICAgICQ1ID0gL3B1Yi9pZXRmL3VyaS9cbiAqICAgICQ2ID0gPHVuZGVmaW5lZD5cbiAqICAgICQ3ID0gPHVuZGVmaW5lZD5cbiAqICAgICQ4ID0gI1JlbGF0ZWRcbiAqICAgICQ5ID0gUmVsYXRlZFxuICogPC9wcmU+XG4gKiB3aGVyZSA8dW5kZWZpbmVkPiBpbmRpY2F0ZXMgdGhhdCB0aGUgY29tcG9uZW50IGlzIG5vdCBwcmVzZW50LCBhcyBpcyB0aGVcbiAqIGNhc2UgZm9yIHRoZSBxdWVyeSBjb21wb25lbnQgaW4gdGhlIGFib3ZlIGV4YW1wbGUuIFRoZXJlZm9yZSwgd2UgY2FuXG4gKiBkZXRlcm1pbmUgdGhlIHZhbHVlIG9mIHRoZSBmaXZlIGNvbXBvbmVudHMgYXNcbiAqIDxwcmU+XG4gKiAgICBzY2hlbWUgICAgPSAkMlxuICogICAgYXV0aG9yaXR5ID0gJDRcbiAqICAgIHBhdGggICAgICA9ICQ1XG4gKiAgICBxdWVyeSAgICAgPSAkN1xuICogICAgZnJhZ21lbnQgID0gJDlcbiAqIDwvcHJlPlxuICpcbiAqIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gaGFzIGJlZW4gbW9kaWZpZWQgc2xpZ2h0bHkgdG8gZXhwb3NlIHRoZVxuICogdXNlckluZm8sIGRvbWFpbiwgYW5kIHBvcnQgc2VwYXJhdGVseSBmcm9tIHRoZSBhdXRob3JpdHkuXG4gKiBUaGUgbW9kaWZpZWQgdmVyc2lvbiB5aWVsZHNcbiAqIDxwcmU+XG4gKiAgICAkMSA9IGh0dHAgICAgICAgICAgICAgIHNjaGVtZVxuICogICAgJDIgPSA8dW5kZWZpbmVkPiAgICAgICB1c2VySW5mbyAtXFxcbiAqICAgICQzID0gd3d3Lmljcy51Y2kuZWR1ICAgZG9tYWluICAgICB8IGF1dGhvcml0eVxuICogICAgJDQgPSA8dW5kZWZpbmVkPiAgICAgICBwb3J0ICAgICAtL1xuICogICAgJDUgPSAvcHViL2lldGYvdXJpLyAgICBwYXRoXG4gKiAgICAkNiA9IDx1bmRlZmluZWQ+ICAgICAgIHF1ZXJ5IHdpdGhvdXQgP1xuICogICAgJDcgPSBSZWxhdGVkICAgICAgICAgICBmcmFnbWVudCB3aXRob3V0ICNcbiAqIDwvcHJlPlxuICogQGludGVybmFsXG4gKi9cbmNvbnN0IF9zcGxpdFJlID0gbmV3IFJlZ0V4cChcbiAgICAnXicgK1xuICAgICcoPzonICtcbiAgICAnKFteOi8/Iy5dKyknICsgIC8vIHNjaGVtZSAtIGlnbm9yZSBzcGVjaWFsIGNoYXJhY3RlcnNcbiAgICAgICAgICAgICAgICAgICAgIC8vIHVzZWQgYnkgb3RoZXIgVVJMIHBhcnRzIHN1Y2ggYXMgOixcbiAgICAgICAgICAgICAgICAgICAgIC8vID8sIC8sICMsIGFuZCAuXG4gICAgJzopPycgK1xuICAgICcoPzovLycgK1xuICAgICcoPzooW14vPyNdKilAKT8nICsgICAgICAgICAgICAgICAgICAvLyB1c2VySW5mb1xuICAgICcoW1xcXFx3XFxcXGRcXFxcLVxcXFx1MDEwMC1cXFxcdWZmZmYuJV0qKScgKyAgLy8gZG9tYWluIC0gcmVzdHJpY3QgdG8gbGV0dGVycyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGlnaXRzLCBkYXNoZXMsIGRvdHMsIHBlcmNlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXNjYXBlcywgYW5kIHVuaWNvZGUgY2hhcmFjdGVycy5cbiAgICAnKD86OihbMC05XSspKT8nICsgICAgICAgICAgICAgICAgICAgLy8gcG9ydFxuICAgICcpPycgK1xuICAgICcoW14/I10rKT8nICsgICAgICAgIC8vIHBhdGhcbiAgICAnKD86XFxcXD8oW14jXSopKT8nICsgIC8vIHF1ZXJ5XG4gICAgJyg/OiMoLiopKT8nICsgICAgICAgLy8gZnJhZ21lbnRcbiAgICAnJCcpO1xuXG4vKipcbiAqIFRoZSBpbmRleCBvZiBlYWNoIFVSSSBjb21wb25lbnQgaW4gdGhlIHJldHVybiB2YWx1ZSBvZiBnb29nLnVyaS51dGlscy5zcGxpdC5cbiAqIEBlbnVtIHtudW1iZXJ9XG4gKi9cbmVudW0gX0NvbXBvbmVudEluZGV4IHtcbiAgU2NoZW1lID0gMSxcbiAgVXNlckluZm8sXG4gIERvbWFpbixcbiAgUG9ydCxcbiAgUGF0aCxcbiAgUXVlcnlEYXRhLFxuICBGcmFnbWVudFxufVxuXG4vKipcbiAqIFNwbGl0cyBhIFVSSSBpbnRvIGl0cyBjb21wb25lbnQgcGFydHMuXG4gKlxuICogRWFjaCBjb21wb25lbnQgY2FuIGJlIGFjY2Vzc2VkIHZpYSB0aGUgY29tcG9uZW50IGluZGljZXM7IGZvciBleGFtcGxlOlxuICogPHByZT5cbiAqIGdvb2cudXJpLnV0aWxzLnNwbGl0KHNvbWVTdHIpW2dvb2cudXJpLnV0aWxzLkNvbXBvbnRlbnRJbmRleC5RVUVSWV9EQVRBXTtcbiAqIDwvcHJlPlxuICpcbiAqIEBwYXJhbSB1cmkgVGhlIFVSSSBzdHJpbmcgdG8gZXhhbWluZS5cbiAqIEByZXR1cm4gRWFjaCBjb21wb25lbnQgc3RpbGwgVVJJLWVuY29kZWQuXG4gKiAgICAgRWFjaCBjb21wb25lbnQgdGhhdCBpcyBwcmVzZW50IHdpbGwgY29udGFpbiB0aGUgZW5jb2RlZCB2YWx1ZSwgd2hlcmVhc1xuICogICAgIGNvbXBvbmVudHMgdGhhdCBhcmUgbm90IHByZXNlbnQgd2lsbCBiZSB1bmRlZmluZWQgb3IgZW1wdHksIGRlcGVuZGluZ1xuICogICAgIG9uIHRoZSBicm93c2VyJ3MgcmVndWxhciBleHByZXNzaW9uIGltcGxlbWVudGF0aW9uLiAgTmV2ZXIgbnVsbCwgc2luY2VcbiAqICAgICBhcmJpdHJhcnkgc3RyaW5ncyBtYXkgc3RpbGwgbG9vayBsaWtlIHBhdGggbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIF9zcGxpdCh1cmk6IHN0cmluZyk6IEFycmF5PHN0cmluZ3xhbnk+IHtcbiAgcmV0dXJuIHVyaS5tYXRjaChfc3BsaXRSZSkhO1xufVxuXG4vKipcbiAqIFJlbW92ZXMgZG90IHNlZ21lbnRzIGluIGdpdmVuIHBhdGggY29tcG9uZW50LCBhcyBkZXNjcmliZWQgaW5cbiAqIFJGQyAzOTg2LCBzZWN0aW9uIDUuMi40LlxuICpcbiAqIEBwYXJhbSBwYXRoIEEgbm9uLWVtcHR5IHBhdGggY29tcG9uZW50LlxuICogQHJldHVybiBQYXRoIGNvbXBvbmVudCB3aXRoIHJlbW92ZWQgZG90IHNlZ21lbnRzLlxuICovXG5mdW5jdGlvbiBfcmVtb3ZlRG90U2VnbWVudHMocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKHBhdGggPT0gJy8nKSByZXR1cm4gJy8nO1xuXG4gIGNvbnN0IGxlYWRpbmdTbGFzaCA9IHBhdGhbMF0gPT0gJy8nID8gJy8nIDogJyc7XG4gIGNvbnN0IHRyYWlsaW5nU2xhc2ggPSBwYXRoW3BhdGgubGVuZ3RoIC0gMV0gPT09ICcvJyA/ICcvJyA6ICcnO1xuICBjb25zdCBzZWdtZW50cyA9IHBhdGguc3BsaXQoJy8nKTtcblxuICBjb25zdCBvdXQ6IHN0cmluZ1tdID0gW107XG4gIGxldCB1cCA9IDA7XG4gIGZvciAobGV0IHBvcyA9IDA7IHBvcyA8IHNlZ21lbnRzLmxlbmd0aDsgcG9zKyspIHtcbiAgICBjb25zdCBzZWdtZW50ID0gc2VnbWVudHNbcG9zXTtcbiAgICBzd2l0Y2ggKHNlZ21lbnQpIHtcbiAgICAgIGNhc2UgJyc6XG4gICAgICBjYXNlICcuJzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICcuLic6XG4gICAgICAgIGlmIChvdXQubGVuZ3RoID4gMCkge1xuICAgICAgICAgIG91dC5wb3AoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB1cCsrO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgb3V0LnB1c2goc2VnbWVudCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGxlYWRpbmdTbGFzaCA9PSAnJykge1xuICAgIHdoaWxlICh1cC0tID4gMCkge1xuICAgICAgb3V0LnVuc2hpZnQoJy4uJyk7XG4gICAgfVxuXG4gICAgaWYgKG91dC5sZW5ndGggPT09IDApIG91dC5wdXNoKCcuJyk7XG4gIH1cblxuICByZXR1cm4gbGVhZGluZ1NsYXNoICsgb3V0LmpvaW4oJy8nKSArIHRyYWlsaW5nU2xhc2g7XG59XG5cbi8qKlxuICogVGFrZXMgYW4gYXJyYXkgb2YgdGhlIHBhcnRzIGZyb20gc3BsaXQgYW5kIGNhbm9uaWNhbGl6ZXMgdGhlIHBhdGggcGFydFxuICogYW5kIHRoZW4gam9pbnMgYWxsIHRoZSBwYXJ0cy5cbiAqL1xuZnVuY3Rpb24gX2pvaW5BbmRDYW5vbmljYWxpemVQYXRoKHBhcnRzOiBhbnlbXSk6IHN0cmluZyB7XG4gIGxldCBwYXRoID0gcGFydHNbX0NvbXBvbmVudEluZGV4LlBhdGhdO1xuICBwYXRoID0gcGF0aCA9PSBudWxsID8gJycgOiBfcmVtb3ZlRG90U2VnbWVudHMocGF0aCk7XG4gIHBhcnRzW19Db21wb25lbnRJbmRleC5QYXRoXSA9IHBhdGg7XG5cbiAgcmV0dXJuIF9idWlsZEZyb21FbmNvZGVkUGFydHMoXG4gICAgICBwYXJ0c1tfQ29tcG9uZW50SW5kZXguU2NoZW1lXSwgcGFydHNbX0NvbXBvbmVudEluZGV4LlVzZXJJbmZvXSwgcGFydHNbX0NvbXBvbmVudEluZGV4LkRvbWFpbl0sXG4gICAgICBwYXJ0c1tfQ29tcG9uZW50SW5kZXguUG9ydF0sIHBhdGgsIHBhcnRzW19Db21wb25lbnRJbmRleC5RdWVyeURhdGFdLFxuICAgICAgcGFydHNbX0NvbXBvbmVudEluZGV4LkZyYWdtZW50XSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgYSBVUkwuXG4gKiBAcGFyYW0gYmFzZSBUaGUgVVJMIGFjdGluZyBhcyB0aGUgYmFzZSBVUkwuXG4gKiBAcGFyYW0gdG8gVGhlIFVSTCB0byByZXNvbHZlLlxuICovXG5mdW5jdGlvbiBfcmVzb2x2ZVVybChiYXNlOiBzdHJpbmcsIHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcGFydHMgPSBfc3BsaXQoZW5jb2RlVVJJKHVybCkpO1xuICBjb25zdCBiYXNlUGFydHMgPSBfc3BsaXQoYmFzZSk7XG5cbiAgaWYgKHBhcnRzW19Db21wb25lbnRJbmRleC5TY2hlbWVdICE9IG51bGwpIHtcbiAgICByZXR1cm4gX2pvaW5BbmRDYW5vbmljYWxpemVQYXRoKHBhcnRzKTtcbiAgfSBlbHNlIHtcbiAgICBwYXJ0c1tfQ29tcG9uZW50SW5kZXguU2NoZW1lXSA9IGJhc2VQYXJ0c1tfQ29tcG9uZW50SW5kZXguU2NoZW1lXTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSBfQ29tcG9uZW50SW5kZXguU2NoZW1lOyBpIDw9IF9Db21wb25lbnRJbmRleC5Qb3J0OyBpKyspIHtcbiAgICBpZiAocGFydHNbaV0gPT0gbnVsbCkge1xuICAgICAgcGFydHNbaV0gPSBiYXNlUGFydHNbaV07XG4gICAgfVxuICB9XG5cbiAgaWYgKHBhcnRzW19Db21wb25lbnRJbmRleC5QYXRoXVswXSA9PSAnLycpIHtcbiAgICByZXR1cm4gX2pvaW5BbmRDYW5vbmljYWxpemVQYXRoKHBhcnRzKTtcbiAgfVxuXG4gIGxldCBwYXRoID0gYmFzZVBhcnRzW19Db21wb25lbnRJbmRleC5QYXRoXTtcbiAgaWYgKHBhdGggPT0gbnVsbCkgcGF0aCA9ICcvJztcbiAgY29uc3QgaW5kZXggPSBwYXRoLmxhc3RJbmRleE9mKCcvJyk7XG4gIHBhdGggPSBwYXRoLnN1YnN0cmluZygwLCBpbmRleCArIDEpICsgcGFydHNbX0NvbXBvbmVudEluZGV4LlBhdGhdO1xuICBwYXJ0c1tfQ29tcG9uZW50SW5kZXguUGF0aF0gPSBwYXRoO1xuICByZXR1cm4gX2pvaW5BbmRDYW5vbmljYWxpemVQYXRoKHBhcnRzKTtcbn1cbiJdfQ== |
---|