@sumaris-net/ngx-components 18.5.13 → 18.6.0
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/doc/changelog.md +5 -0
- package/esm2022/public_api.mjs +10 -2
- package/esm2022/src/app/core/about/about.modal.mjs +5 -4
- package/esm2022/src/app/core/account/account.page.mjs +16 -15
- package/esm2022/src/app/core/home/home.mjs +5 -5
- package/esm2022/src/app/core/home/home.module.mjs +7 -3
- package/esm2022/src/app/core/services/account.service.mjs +1 -1
- package/esm2022/src/app/shared/file/url.utils.mjs +164 -0
- package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +40 -28
- package/esm2022/src/app/shared/markdown/markdown.component.mjs +259 -0
- package/esm2022/src/app/shared/markdown/markdown.directive.mjs +34 -0
- package/esm2022/src/app/shared/markdown/markdown.modal.mjs +75 -0
- package/esm2022/src/app/shared/markdown/markdown.module.mjs +88 -0
- package/esm2022/src/app/shared/markdown/markdown.service.mjs +202 -0
- package/esm2022/src/app/shared/markdown/markdown.utils.mjs +78 -0
- package/esm2022/src/app/shared/markdown/testing/markdown.test.mjs +45 -0
- package/esm2022/src/app/shared/markdown/testing/markdown.testing.module.mjs +29 -0
- package/esm2022/src/app/shared/material/material.animations.mjs +31 -1
- package/esm2022/src/app/shared/pipes/pipes.module.mjs +5 -2
- package/esm2022/src/app/shared/pipes/string.pipes.mjs +17 -1
- package/esm2022/src/app/shared/shared.module.mjs +11 -9
- package/esm2022/src/app/shared/shared.testing.module.mjs +13 -5
- package/fesm2022/sumaris-net.ngx-components.mjs +6656 -5759
- package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +2 -1
- package/public_api.d.ts +9 -1
- package/src/app/core/home/home.module.d.ts +2 -1
- package/src/app/shared/file/url.utils.d.ts +77 -0
- package/src/app/shared/image/gallery/image-gallery.component.d.ts +10 -1
- package/src/app/shared/inputs.d.ts +1 -1
- package/src/app/shared/markdown/markdown.component.d.ts +76 -0
- package/src/app/shared/markdown/markdown.directive.d.ts +13 -0
- package/src/app/shared/{help/help.modal.d.ts → markdown/markdown.modal.d.ts} +11 -12
- package/src/app/shared/markdown/markdown.module.d.ts +18 -0
- package/src/app/shared/markdown/markdown.service.d.ts +38 -0
- package/src/app/shared/markdown/markdown.utils.d.ts +25 -0
- package/src/app/shared/markdown/testing/markdown.test.d.ts +15 -0
- package/src/app/shared/markdown/testing/markdown.testing.module.d.ts +11 -0
- package/src/app/shared/material/material.animations.d.ts +1 -0
- package/src/app/shared/pipes/pipes.module.d.ts +1 -1
- package/src/app/shared/pipes/string.pipes.d.ts +5 -0
- package/src/app/shared/shared.module.d.ts +19 -19
- package/src/app/shared/shared.testing.module.d.ts +2 -1
- package/src/assets/manifest.json +1 -1
- package/esm2022/src/app/shared/help/help.modal.mjs +0 -86
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { isNilOrBlank } from '../functions';
|
|
2
|
+
export class UrlUtils {
|
|
3
|
+
/**
|
|
4
|
+
* Determines if a given URL is a relative URL.
|
|
5
|
+
*
|
|
6
|
+
* @param {string | null} href - The URL to check.
|
|
7
|
+
* @return {boolean} True if the URL is relative, false otherwise.
|
|
8
|
+
*/
|
|
9
|
+
static isRelativeUrl(href) {
|
|
10
|
+
if (!href)
|
|
11
|
+
return false;
|
|
12
|
+
return !href.startsWith('http:') && !href.startsWith('https:') && !href.startsWith('mailto:') && !href.startsWith('tel:');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Determines if a given URL is an internal URL.
|
|
16
|
+
*
|
|
17
|
+
* @param {string | null} href - The URL to be checked. Can be a string representing the URL or null.
|
|
18
|
+
* @return {boolean} Returns true if the URL is internal, otherwise false.
|
|
19
|
+
*/
|
|
20
|
+
static isInternalUrl(href) {
|
|
21
|
+
if (!href)
|
|
22
|
+
return false;
|
|
23
|
+
return href.startsWith(window.location.origin) || this.isRelativeUrl(href);
|
|
24
|
+
}
|
|
25
|
+
static isExternalUrl(href) {
|
|
26
|
+
if (!href)
|
|
27
|
+
return false;
|
|
28
|
+
return !this.isInternalUrl(href);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Removes the query string from the given URL, returning only the base URL.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} url - The URL from which the query string will be stripped.
|
|
34
|
+
* @return {string} The URL without the query string.
|
|
35
|
+
*/
|
|
36
|
+
static stripQuery(url) {
|
|
37
|
+
return /[^?]*/.exec(url)[0];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Removes the fragment and query components from a given URL string.
|
|
41
|
+
*
|
|
42
|
+
* @param {string} url - The URL string to process.
|
|
43
|
+
* @return {string} The URL without its fragment and query components.
|
|
44
|
+
*/
|
|
45
|
+
static stripFragmentAndQuery(url) {
|
|
46
|
+
if (!url)
|
|
47
|
+
return url;
|
|
48
|
+
return this.stripQuery(/[^#]*/.exec(url)[0]);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Extracts the fragment identifier from the given URL.
|
|
52
|
+
*
|
|
53
|
+
* @param {string} url - The URL from which to extract the fragment.
|
|
54
|
+
* @return {string} The fragment identifier of the URL, excluding the '#' symbol.
|
|
55
|
+
*/
|
|
56
|
+
static getFragment(url) {
|
|
57
|
+
if (isNilOrBlank(url))
|
|
58
|
+
return '';
|
|
59
|
+
const match = url.match(/#(.*)$/);
|
|
60
|
+
return match ? match[1] : '';
|
|
61
|
+
}
|
|
62
|
+
static resolveRelativeUrl(baseUrl, relativePath, opts) {
|
|
63
|
+
if (!baseUrl)
|
|
64
|
+
throw new Error("Missing 'baseUrl' argument");
|
|
65
|
+
if (!relativePath)
|
|
66
|
+
throw new Error("Missing 'relativePath' argument");
|
|
67
|
+
if (!this.isRelativeUrl(relativePath))
|
|
68
|
+
throw new Error("Should be a relative path");
|
|
69
|
+
// Detect absolute URL
|
|
70
|
+
if (relativePath.startsWith('/') || (opts?.absoluteByDefault && !relativePath.startsWith('.'))) {
|
|
71
|
+
baseUrl = this.getRootUrl(baseUrl);
|
|
72
|
+
}
|
|
73
|
+
return UrlUtils.normalizeUrl(UrlUtils.concat(baseUrl, relativePath));
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolves a given URL by normalizing its parts, removing unnecessary path segments like "." and "..".
|
|
77
|
+
*
|
|
78
|
+
* @param {string} url - The URL to be resolved. Must be a non-empty string.
|
|
79
|
+
* @return {string} The resolved and cleaned URL string.
|
|
80
|
+
* @throws {Error} If the provided URL is missing or undefined.
|
|
81
|
+
*/
|
|
82
|
+
static normalizeUrl(url) {
|
|
83
|
+
if (!url)
|
|
84
|
+
throw new Error("Missing 'url' argument");
|
|
85
|
+
return this.cleanUrl(url)
|
|
86
|
+
.split('/')
|
|
87
|
+
.reduce((res, part) => {
|
|
88
|
+
if (part === '.')
|
|
89
|
+
return res;
|
|
90
|
+
if (part === '..' && res.length > 0)
|
|
91
|
+
return res.slice(0, -1);
|
|
92
|
+
return res.concat(part);
|
|
93
|
+
}, [])
|
|
94
|
+
.join('/');
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Extracts and returns the root URL from the given complete URL string.
|
|
98
|
+
*
|
|
99
|
+
* @param {string} url - The complete URL string from which the root URL will be extracted.
|
|
100
|
+
* @return {string} The root URL including the protocol and host (and port if present).
|
|
101
|
+
* @throws {Error} Throws an error if the provided URL is missing or is in an invalid format.
|
|
102
|
+
*/
|
|
103
|
+
static getRootUrl(url) {
|
|
104
|
+
if (!url)
|
|
105
|
+
throw new Error("Missing 'url' argument");
|
|
106
|
+
let [protocol, path] = url.split('//', 2);
|
|
107
|
+
if (!protocol || isNilOrBlank(path))
|
|
108
|
+
throw new Error(`Invalid URL format: ${url}`);
|
|
109
|
+
const hostAndPort = path.split('/', 2)[0];
|
|
110
|
+
return `${protocol}//${hostAndPort}`;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Retrieves the parent URL or directory path from the provided URL.
|
|
114
|
+
* This method handles both relative and absolute URLs.
|
|
115
|
+
*
|
|
116
|
+
* @param {string} url - The URL from which to derive the parent path.
|
|
117
|
+
* Must be a valid URL or relative path.
|
|
118
|
+
* @return {string} The parent URL or directory path. Throws an error if the input is invalid.
|
|
119
|
+
*/
|
|
120
|
+
static getParent(url) {
|
|
121
|
+
if (!url)
|
|
122
|
+
throw new Error("Missing 'url' argument");
|
|
123
|
+
const cleanUrl = this.stripFragmentAndQuery(url);
|
|
124
|
+
if (cleanUrl.endsWith('/'))
|
|
125
|
+
return cleanUrl; // Skip if already a parent directory
|
|
126
|
+
const parentPath = cleanUrl + '/' + '..';
|
|
127
|
+
if (this.isRelativeUrl(url)) {
|
|
128
|
+
return this.resolveRelativeUrl(window.location.href, parentPath);
|
|
129
|
+
}
|
|
130
|
+
return this.normalizeUrl(parentPath);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Cleans the provided URL by encoding it safely and replacing specific patterns.
|
|
134
|
+
*
|
|
135
|
+
* @param {string} href - The URL string to be cleaned.
|
|
136
|
+
* @return {string|null} The cleaned and encoded URL string, or null if an error occurs.
|
|
137
|
+
*/
|
|
138
|
+
static cleanUrl(href) {
|
|
139
|
+
try {
|
|
140
|
+
href = encodeURI(href).replace(/%25/g, '%');
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
return href;
|
|
146
|
+
}
|
|
147
|
+
static addTrailingSlash(url) {
|
|
148
|
+
return url.endsWith('/') ? url : url + '/';
|
|
149
|
+
}
|
|
150
|
+
static addStartingSlash(url) {
|
|
151
|
+
return url.startsWith('/') ? url : '/' + url;
|
|
152
|
+
}
|
|
153
|
+
static removeStartingSlash(url) {
|
|
154
|
+
return url.startsWith('/') ? url.substring(1) : url;
|
|
155
|
+
}
|
|
156
|
+
static concat(basePath, relativePath) {
|
|
157
|
+
if (!basePath)
|
|
158
|
+
return relativePath;
|
|
159
|
+
if (!relativePath)
|
|
160
|
+
return basePath;
|
|
161
|
+
return this.addTrailingSlash(basePath) + this.removeStartingSlash(relativePath);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsLnV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zaGFyZWQvZmlsZS91cmwudXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU1QyxNQUFNLE9BQWdCLFFBQVE7SUFDNUI7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsYUFBYSxDQUFDLElBQW1CO1FBQ3RDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDeEIsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDNUgsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFtQjtRQUN0QyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUVELE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBbUI7UUFDdEMsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN4QixPQUFPLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQVc7UUFDM0IsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FB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QUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0lBQzdDLENBQUM7SUFFRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsR0FBVztRQUNqQyxPQUFPLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztJQUMvQyxDQUFDO0lBRUQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEdBQVc7UUFDcEMsT0FBTyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDdEQsQ0FBQztJQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBZ0IsRUFBRSxZQUFvQjtRQUNsRCxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU8sWUFBWSxDQUFDO1FBQ25DLElBQUksQ0FBQyxZQUFZO1lBQUUsT0FBTyxRQUFRLENBQUM7UUFDbkMsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ2xGLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzTmlsT3JCbGFuayB9IGZyb20gJy4uL2Z1bmN0aW9ucyc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBVcmxVdGlscyB7XG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGlmIGEgZ2l2ZW4gVVJMIGlzIGEgcmVsYXRpdmUgVVJMLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IGhyZWYgLSBUaGUgVVJMIHRvIGNoZWNrLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBVUkwgaXMgcmVsYXRpdmUsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIHN0YXRpYyBpc1JlbGF0aXZlVXJsKGhyZWY6IHN0cmluZyB8IG51bGwpOiBib29sZWFuIHtcbiAgICBpZiAoIWhyZWYpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gIWhyZWYuc3RhcnRzV2l0aCgnaHR0cDonKSAmJiAhaHJlZi5zdGFydHNXaXRoKCdodHRwczonKSAmJiAhaHJlZi5zdGFydHNXaXRoKCdtYWlsdG86JykgJiYgIWhyZWYuc3RhcnRzV2l0aCgndGVsOicpO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgYSBnaXZlbiBVUkwgaXMgYW4gaW50ZXJuYWwgVVJMLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IGhyZWYgLSBUaGUgVVJMIHRvIGJlIGNoZWNrZWQuIENhbiBiZSBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIFVSTCBvciBudWxsLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgdGhlIFVSTCBpcyBpbnRlcm5hbCwgb3RoZXJ3aXNlIGZhbHNlLlxuICAgKi9cbiAgc3RhdGljIGlzSW50ZXJuYWxVcmwoaHJlZjogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGlmICghaHJlZikgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBocmVmLnN0YXJ0c1dpdGgod2luZG93LmxvY2F0aW9uLm9yaWdpbikgfHwgdGhpcy5pc1JlbGF0aXZlVXJsKGhyZWYpO1xuICB9XG5cbiAgc3RhdGljIGlzRXh0ZXJuYWxVcmwoaHJlZjogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgIGlmICghaHJlZikgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiAhdGhpcy5pc0ludGVybmFsVXJsKGhyZWYpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIHF1ZXJ5IHN0cmluZyBmcm9tIHRoZSBnaXZlbiBVUkwsIHJldHVybmluZyBvbmx5IHRoZSBiYXNlIFVSTC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIFRoZSBVUkwgZnJvbSB3aGljaCB0aGUgcXVlcnkgc3RyaW5nIHdpbGwgYmUgc3RyaXBwZWQuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIFVSTCB3aXRob3V0IHRoZSBxdWVyeSBzdHJpbmcuXG4gICAqL1xuICBzdGF0aWMgc3RyaXBRdWVyeSh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIC9bXj9dKi8uZXhlYyh1cmwpWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGZyYWdtZW50IGFuZCBxdWVyeSBjb21wb25lbnRzIGZyb20gYSBnaXZlbiBVUkwgc3RyaW5nLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIC0gVGhlIFVSTCBzdHJpbmcgdG8gcHJvY2Vzcy5cbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVJMIHdpdGhvdXQgaXRzIGZyYWdtZW50IGFuZCBxdWVyeSBjb21wb25lbnRzLlxuICAgKi9cbiAgc3RhdGljIHN0cmlwRnJhZ21lbnRBbmRRdWVyeSh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF1cmwpIHJldHVybiB1cmw7XG4gICAgcmV0dXJuIHRoaXMuc3RyaXBRdWVyeSgvW14jXSovLmV4ZWModXJsKVswXSk7XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdHMgdGhlIGZyYWdtZW50IGlkZW50aWZpZXIgZnJvbSB0aGUgZ2l2ZW4gVVJMLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIC0gVGhlIFVSTCBmcm9tIHdoaWNoIHRvIGV4dHJhY3QgdGhlIGZyYWdtZW50LlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBmcmFnbWVudCBpZGVudGlmaWVyIG9mIHRoZSBVUkwsIGV4Y2x1ZGluZyB0aGUgJyMnIHN5bWJvbC5cbiAgICovXG4gIHN0YXRpYyBnZXRGcmFnbWVudCh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKGlzTmlsT3JCbGFuayh1cmwpKSByZXR1cm4gJyc7XG5cbiAgICBjb25zdCBtYXRjaCA9IHVybC5tYXRjaCgvIyguKikkLyk7XG4gICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0gOiAnJztcbiAgfVxuXG4gIHN0YXRpYyByZXNvbHZlUmVsYXRpdmVVcmwoYmFzZVVybDogc3RyaW5nLCByZWxhdGl2ZVBhdGg6IHN0cmluZywgb3B0cz86IHthYnNvbHV0ZUJ5RGVmYXVsdDogYm9vbGVhbn0pOiBzdHJpbmcge1xuICAgIGlmICghYmFzZVVybCkgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyAnYmFzZVVybCcgYXJndW1lbnRcIik7XG4gICAgaWYgKCFyZWxhdGl2ZVBhdGgpIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgJ3JlbGF0aXZlUGF0aCcgYXJndW1lbnRcIik7XG4gICAgaWYgKCF0aGlzLmlzUmVsYXRpdmVVcmwocmVsYXRpdmVQYXRoKSkgdGhyb3cgbmV3IEVycm9yKFwiU2hvdWxkIGJlIGEgcmVsYXRpdmUgcGF0aFwiKTtcblxuICAgIC8vIERldGVjdCBhYnNvbHV0ZSBVUkxcbiAgICBpZiAocmVsYXRpdmVQYXRoLnN0YXJ0c1dpdGgoJy8nKSB8fCAob3B0cz8uYWJzb2x1dGVCeURlZmF1bHQgJiYgIXJlbGF0aXZlUGF0aC5zdGFydHNXaXRoKCcuJykpKSB7XG4gICAgICBiYXNlVXJsID0gdGhpcy5nZXRSb290VXJsKGJhc2VVcmwpO1xuICAgIH1cblxuICAgIHJldHVybiBVcmxVdGlscy5ub3JtYWxpemVVcmwoVXJsVXRpbHMuY29uY2F0KGJhc2VVcmwsIHJlbGF0aXZlUGF0aCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIGEgZ2l2ZW4gVVJMIGJ5IG5vcm1hbGl6aW5nIGl0cyBwYXJ0cywgcmVtb3ZpbmcgdW5uZWNlc3NhcnkgcGF0aCBzZWdtZW50cyBsaWtlIFwiLlwiIGFuZCBcIi4uXCIuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIGJlIHJlc29sdmVkLiBNdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZy5cbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgcmVzb2x2ZWQgYW5kIGNsZWFuZWQgVVJMIHN0cmluZy5cbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwcm92aWRlZCBVUkwgaXMgbWlzc2luZyBvciB1bmRlZmluZWQuXG4gICAqL1xuICBzdGF0aWMgbm9ybWFsaXplVXJsKHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXVybCkgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyAndXJsJyBhcmd1bWVudFwiKTtcbiAgICByZXR1cm4gdGhpcy5jbGVhblVybCh1cmwpXG4gICAgICAuc3BsaXQoJy8nKVxuICAgICAgLnJlZHVjZSgocmVzLCBwYXJ0KSA9PiB7XG4gICAgICAgIGlmIChwYXJ0ID09PSAnLicpIHJldHVybiByZXM7XG4gICAgICAgIGlmIChwYXJ0ID09PSAnLi4nICYmIHJlcy5sZW5ndGggPiAwKSByZXR1cm4gcmVzLnNsaWNlKDAsIC0xKTtcbiAgICAgICAgcmV0dXJuIHJlcy5jb25jYXQocGFydCk7XG4gICAgICB9LCBbXSlcbiAgICAgIC5qb2luKCcvJyk7XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdHMgYW5kIHJldHVybnMgdGhlIHJvb3QgVVJMIGZyb20gdGhlIGdpdmVuIGNvbXBsZXRlIFVSTCBzdHJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgY29tcGxldGUgVVJMIHN0cmluZyBmcm9tIHdoaWNoIHRoZSByb290IFVSTCB3aWxsIGJlIGV4dHJhY3RlZC5cbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgcm9vdCBVUkwgaW5jbHVkaW5nIHRoZSBwcm90b2NvbCBhbmQgaG9zdCAoYW5kIHBvcnQgaWYgcHJlc2VudCkuXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBUaHJvd3MgYW4gZXJyb3IgaWYgdGhlIHByb3ZpZGVkIFVSTCBpcyBtaXNzaW5nIG9yIGlzIGluIGFuIGludmFsaWQgZm9ybWF0LlxuICAgKi9cbiAgc3RhdGljIGdldFJvb3RVcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghdXJsKSB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nICd1cmwnIGFyZ3VtZW50XCIpO1xuICAgIGxldCBbcHJvdG9jb2wsIHBhdGhdID0gdXJsLnNwbGl0KCcvLycsIDIpO1xuICAgIGlmICghcHJvdG9jb2wgfHwgaXNOaWxPckJsYW5rKHBhdGgpKSB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgVVJMIGZvcm1hdDogJHt1cmx9YCk7XG4gICAgY29uc3QgaG9zdEFuZFBvcnQgPSBwYXRoLnNwbGl0KCcvJywgMilbMF07XG4gICAgcmV0dXJuIGAke3Byb3RvY29sfS8vJHtob3N0QW5kUG9ydH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgcGFyZW50IFVSTCBvciBkaXJlY3RvcnkgcGF0aCBmcm9tIHRoZSBwcm92aWRlZCBVUkwuXG4gICAqIFRoaXMgbWV0aG9kIGhhbmRsZXMgYm90aCByZWxhdGl2ZSBhbmQgYWJzb2x1dGUgVVJMcy5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIFRoZSBVUkwgZnJvbSB3aGljaCB0byBkZXJpdmUgdGhlIHBhcmVudCBwYXRoLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgTXVzdCBiZSBhIHZhbGlkIFVSTCBvciByZWxhdGl2ZSBwYXRoLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYXJlbnQgVVJMIG9yIGRpcmVjdG9yeSBwYXRoLiBUaHJvd3MgYW4gZXJyb3IgaWYgdGhlIGlucHV0IGlzIGludmFsaWQuXG4gICAqL1xuICBzdGF0aWMgZ2V0UGFyZW50KHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXVybCkgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyAndXJsJyBhcmd1bWVudFwiKTtcbiAgICBjb25zdCBjbGVhblVybCA9IHRoaXMuc3RyaXBGcmFnbWVudEFuZFF1ZXJ5KHVybCk7XG4gICAgaWYgKGNsZWFuVXJsLmVuZHNXaXRoKCcvJykpIHJldHVybiBjbGVhblVybDsgLy8gU2tpcCBpZiBhbHJlYWR5IGEgcGFyZW50IGRpcmVjdG9yeVxuICAgIGNvbnN0IHBhcmVudFBhdGggPSBjbGVhblVybCArICcvJyArICcuLic7XG4gICAgaWYgKHRoaXMuaXNSZWxhdGl2ZVVybCh1cmwpKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXNvbHZlUmVsYXRpdmVVcmwod2luZG93LmxvY2F0aW9uLmhyZWYsIHBhcmVudFBhdGgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemVVcmwocGFyZW50UGF0aCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW5zIHRoZSBwcm92aWRlZCBVUkwgYnkgZW5jb2RpbmcgaXQgc2FmZWx5IGFuZCByZXBsYWNpbmcgc3BlY2lmaWMgcGF0dGVybnMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBocmVmIC0gVGhlIFVSTCBzdHJpbmcgdG8gYmUgY2xlYW5lZC5cbiAgICogQHJldHVybiB7c3RyaW5nfG51bGx9IFRoZSBjbGVhbmVkIGFuZCBlbmNvZGVkIFVSTCBzdHJpbmcsIG9yIG51bGwgaWYgYW4gZXJyb3Igb2NjdXJzLlxuICAgKi9cbiAgc3RhdGljIGNsZWFuVXJsKGhyZWY6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgdHJ5IHtcbiAgICAgIGhyZWYgPSBlbmNvZGVVUkkoaHJlZikucmVwbGFjZSgvJTI1L2csICclJyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBocmVmO1xuICB9XG5cbiAgc3RhdGljIGFkZFRyYWlsaW5nU2xhc2godXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB1cmwuZW5kc1dpdGgoJy8nKSA/IHVybCA6IHVybCArICcvJztcbiAgfVxuXG4gIHN0YXRpYyBhZGRTdGFydGluZ1NsYXNoKHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdXJsLnN0YXJ0c1dpdGgoJy8nKSA/IHVybCA6ICcvJyArIHVybDtcbiAgfVxuXG4gIHN0YXRpYyByZW1vdmVTdGFydGluZ1NsYXNoKHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdXJsLnN0YXJ0c1dpdGgoJy8nKSA/IHVybC5zdWJzdHJpbmcoMSkgOiB1cmw7XG4gIH1cblxuICBzdGF0aWMgY29uY2F0KGJhc2VQYXRoOiBzdHJpbmcsIHJlbGF0aXZlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIWJhc2VQYXRoKSByZXR1cm4gcmVsYXRpdmVQYXRoO1xuICAgIGlmICghcmVsYXRpdmVQYXRoKSByZXR1cm4gYmFzZVBhdGg7XG4gICAgcmV0dXJuIHRoaXMuYWRkVHJhaWxpbmdTbGFzaChiYXNlUGF0aCkgKyB0aGlzLnJlbW92ZVN0YXJ0aW5nU2xhc2gocmVsYXRpdmVQYXRoKTtcbiAgfVxufVxuIl19
|