@sambath999/localize-token 12.3.1 → 12.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/sambath999-localize-token.umd.js +509 -169
- package/bundles/sambath999-localize-token.umd.js.map +1 -1
- package/esm2015/localize-logindlg/localize-logindlg.component.js +60 -26
- package/esm2015/localize-logindlg/localize-logindlg.service.js +34 -7
- package/esm2015/localize-token/helpers/interfaces.js +12 -0
- package/esm2015/localize-token/helpers/loccalize.api.helper.js +270 -0
- package/esm2015/localize-token/localize.api.service.js +127 -89
- package/esm2015/localize-token/localize.token.service.js +3 -1
- package/esm2015/localize-token/public-api.js +3 -1
- package/fesm2015/sambath999-localize-token.js +493 -117
- package/fesm2015/sambath999-localize-token.js.map +1 -1
- package/localize-logindlg/localize-logindlg.component.d.ts +6 -1
- package/localize-logindlg/localize-logindlg.service.d.ts +44 -0
- package/localize-token/helpers/interfaces.d.ts +93 -0
- package/localize-token/helpers/loccalize.api.helper.d.ts +34 -0
- package/localize-token/localize.api.service.d.ts +24 -45
- package/localize-token/localize.token.service.d.ts +1 -1
- package/localize-token/public-api.d.ts +2 -0
- package/package.json +1 -1
- package/sambath999-localize-token.metadata.json +1 -1
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { HttpErrorResponse } from "@angular/common/http";
|
|
3
|
+
import { takeUntil, catchError, throwError } from "rxjs";
|
|
4
|
+
import { LocalizeToken, waitFor } from "../localize.token";
|
|
5
|
+
class LocalizeApiHelper {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.defaultRetryOptions = {
|
|
8
|
+
connectionError: {
|
|
9
|
+
message: 'Connection error occurred. Please wait',
|
|
10
|
+
blockScreen: true,
|
|
11
|
+
blockScreenZIndex: 10000
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
performRetry(options) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
let attempts = 0;
|
|
18
|
+
let lastError;
|
|
19
|
+
let consoleCount = 0;
|
|
20
|
+
// Merge default retry options with provided options
|
|
21
|
+
options = Object.assign(Object.assign({}, this.defaultRetryOptions), options);
|
|
22
|
+
let styleElement;
|
|
23
|
+
while (attempts < options.maxRetries()) {
|
|
24
|
+
try {
|
|
25
|
+
const result = yield options.callback();
|
|
26
|
+
this.removeBlocker(styleElement);
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
lastError = error;
|
|
31
|
+
if (consoleCount >= 7) {
|
|
32
|
+
console.clear();
|
|
33
|
+
consoleCount = 0;
|
|
34
|
+
}
|
|
35
|
+
if (options.retryUnless && !options.retryUnless(error))
|
|
36
|
+
throw error; // If the error should not be retried, rethrow it
|
|
37
|
+
// Handle connection error
|
|
38
|
+
styleElement = yield this.onConnectionError(options, error);
|
|
39
|
+
if (options.onError)
|
|
40
|
+
yield this.invokeHook(options.onError.bind(this, error));
|
|
41
|
+
if (attempts >= options.maxRetries() - 1)
|
|
42
|
+
throw error;
|
|
43
|
+
attempts++;
|
|
44
|
+
consoleCount++;
|
|
45
|
+
console.warn(`Attempt ${attempts} failed. Retrying...`, error);
|
|
46
|
+
yield waitFor(options.delay);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
console.warn(`Failed after ${options.maxRetries} attempts`);
|
|
50
|
+
throw lastError;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
performRequestWithRetry(options, config, performRequest) {
|
|
54
|
+
var _a, _b, _c, _d;
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const retryUnless = ((_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.retryFunction)
|
|
57
|
+
|| this.isConnectionError;
|
|
58
|
+
return yield this.performRetry({
|
|
59
|
+
connectionError: (_b = config.retryOptions) === null || _b === void 0 ? void 0 : _b.onConnectionError,
|
|
60
|
+
maxRetries: () => { var _a, _b; return (_b = (_a = config.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== null && _b !== void 0 ? _b : 1000; },
|
|
61
|
+
delay: (_d = (_c = config.retryOptions) === null || _c === void 0 ? void 0 : _c.delay) !== null && _d !== void 0 ? _d : 500,
|
|
62
|
+
callback: () => performRequest(options),
|
|
63
|
+
retryUnless: retryUnless,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
buildUrl(baseUrl, path) {
|
|
68
|
+
const normalizedUrl = `${baseUrl.trim().replace(/\/?$/, '/')}${path.trim().replace(/^\//, '')}`;
|
|
69
|
+
return normalizedUrl.endsWith('/')
|
|
70
|
+
? normalizedUrl.slice(0, -1)
|
|
71
|
+
: normalizedUrl;
|
|
72
|
+
}
|
|
73
|
+
normalizeError(error) {
|
|
74
|
+
var _a, _b, _c;
|
|
75
|
+
return {
|
|
76
|
+
code: ((_a = error.error) === null || _a === void 0 ? void 0 : _a.code) || `HTTP_${error.status}`,
|
|
77
|
+
message: ((_b = error.error) === null || _b === void 0 ? void 0 : _b.message) || error.message,
|
|
78
|
+
details: (_c = error.error) === null || _c === void 0 ? void 0 : _c.details,
|
|
79
|
+
status: error.status
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
invokeHook(callback) {
|
|
83
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
+
if (!callback)
|
|
85
|
+
return;
|
|
86
|
+
const result = callback();
|
|
87
|
+
if (result instanceof Promise) {
|
|
88
|
+
yield result;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
createRequest(instance, method, url, body, options) {
|
|
93
|
+
const request$ = instance.client.request(method, url, Object.assign(Object.assign({}, options), { body, observe: 'response' })).pipe(takeUntil(instance.destroy$()), catchError((error) => {
|
|
94
|
+
// Convert to a non-observable error to handle in the promise
|
|
95
|
+
return throwError(() => this.normalizeError(error));
|
|
96
|
+
}));
|
|
97
|
+
return request$;
|
|
98
|
+
}
|
|
99
|
+
defaultRetryFunction(error) {
|
|
100
|
+
// Don't retry for other errors (like 400, 401, 403, etc.)
|
|
101
|
+
if (!this.isConnectionError(error))
|
|
102
|
+
throw error;
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
isConnectionError(error) {
|
|
106
|
+
const isNetworkError = error.status === 0;
|
|
107
|
+
const isServerError = error.status >= 1000 && error.status < 600;
|
|
108
|
+
return isNetworkError || isServerError;
|
|
109
|
+
}
|
|
110
|
+
onConnectionError(options, error) {
|
|
111
|
+
var _a;
|
|
112
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
if (!options.connectionError)
|
|
114
|
+
return;
|
|
115
|
+
let styleElement;
|
|
116
|
+
if (this.isConnectionError(error)) {
|
|
117
|
+
styleElement = this.screenBlocker(options, error, true);
|
|
118
|
+
yield this.invokeHook((_a = options.connectionError.callback) === null || _a === void 0 ? void 0 : _a.bind(this, error));
|
|
119
|
+
return styleElement;
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
this.screenBlocker(options, error, false);
|
|
123
|
+
styleElement === null || styleElement === void 0 ? void 0 : styleElement.remove();
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
validateConfig(config) {
|
|
128
|
+
var _a;
|
|
129
|
+
if (LocalizeToken.config.needTenant && !((_a = config.tenantTokenName) === null || _a === void 0 ? void 0 : _a.trim().length)) {
|
|
130
|
+
throw Error('Tenant token is required but tenantTokenName is not configured');
|
|
131
|
+
}
|
|
132
|
+
if (!LocalizeToken.config.revokeTokenUrl.trim().length) {
|
|
133
|
+
throw Error('Revoke token URL is not configured - token refresh will not work');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
screenBlocker(optons, error, add = true) {
|
|
137
|
+
var _a, _b, _c, _d;
|
|
138
|
+
if (!((_a = optons.connectionError) === null || _a === void 0 ? void 0 : _a.blockScreen))
|
|
139
|
+
return;
|
|
140
|
+
if (error instanceof HttpErrorResponse)
|
|
141
|
+
error = this.normalizeError(error);
|
|
142
|
+
const message = ((_b = optons.connectionError) === null || _b === void 0 ? void 0 : _b.message)
|
|
143
|
+
|| 'Connection error occurred. Please wait';
|
|
144
|
+
const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || 'An error occurred';
|
|
145
|
+
const suggestinMessage = ((_c = optons.connectionError) === null || _c === void 0 ? void 0 : _c.suggestionMessage)
|
|
146
|
+
|| 'Please check your internet connection or the server status.';
|
|
147
|
+
const zIndex = ((_d = optons.connectionError) === null || _d === void 0 ? void 0 : _d.blockScreenZIndex) || 10000;
|
|
148
|
+
const body = document.body;
|
|
149
|
+
const blcokerHtml = `
|
|
150
|
+
<div class="lze-blocker">
|
|
151
|
+
<div class="lze-blocker__message">
|
|
152
|
+
${message}
|
|
153
|
+
<span class="lze-blocker__dotting">
|
|
154
|
+
<span class="lze-blocker__dot"></span>
|
|
155
|
+
<span class="lze-blocker__dot"></span>
|
|
156
|
+
<span class="lze-blocker__dot"></span>
|
|
157
|
+
</span>
|
|
158
|
+
</div>
|
|
159
|
+
<div class="lze-blocker__error">${errorMessage}</div>
|
|
160
|
+
<div class="lze-blocker__error_suggestion">${suggestinMessage}</div>
|
|
161
|
+
<div class="lze-blocker__spinner"></div>
|
|
162
|
+
</div>
|
|
163
|
+
`;
|
|
164
|
+
const style = `
|
|
165
|
+
.lze-blocker {
|
|
166
|
+
position: fixed;
|
|
167
|
+
top: 0;
|
|
168
|
+
left: 0;
|
|
169
|
+
width: 100%;
|
|
170
|
+
height: 100%;
|
|
171
|
+
background: rgba(0, 0, 0, 0.8);
|
|
172
|
+
z-index: ${zIndex};
|
|
173
|
+
display: flex;
|
|
174
|
+
align-items: center;
|
|
175
|
+
justify-content: center;
|
|
176
|
+
flex-direction: column;
|
|
177
|
+
color: #fff;
|
|
178
|
+
font-family: Arial, sans-serif;
|
|
179
|
+
text-align: center;
|
|
180
|
+
padding: 20px;
|
|
181
|
+
box-sizing: border-box;
|
|
182
|
+
overflow: hidden;
|
|
183
|
+
user-select: none;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.lze-blocker__spinner {
|
|
187
|
+
border: 4px solid rgba(255, 255, 255, 0.1);
|
|
188
|
+
border-top: 4px solid #fff;
|
|
189
|
+
border-radius: 50%;
|
|
190
|
+
width: 50px;
|
|
191
|
+
height: 50px;
|
|
192
|
+
animation: spin 1s linear infinite;
|
|
193
|
+
margin-top: 20px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.lze-blocker__message {
|
|
197
|
+
color: #fff;
|
|
198
|
+
font-size: 18px;
|
|
199
|
+
margin-bottom: 10px;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.lze-blocker__dotting {
|
|
203
|
+
display: inline-block;
|
|
204
|
+
vertical-align: middle;
|
|
205
|
+
}
|
|
206
|
+
.lze-blocker__dot {
|
|
207
|
+
display: inline-block;
|
|
208
|
+
width: 7px;
|
|
209
|
+
height: 7px;
|
|
210
|
+
background-color: #ffffff;
|
|
211
|
+
border-radius: 50%;
|
|
212
|
+
margin-left: 3px;
|
|
213
|
+
opacity: 0.3;
|
|
214
|
+
animation: dotting 1s infinite;
|
|
215
|
+
}
|
|
216
|
+
.lze-blocker__dot:nth-child(1) {
|
|
217
|
+
animation-delay: 0s;
|
|
218
|
+
opacity: 1;
|
|
219
|
+
}
|
|
220
|
+
.lze-blocker__dot:nth-child(2) {
|
|
221
|
+
animation-delay: 0.2s;
|
|
222
|
+
}
|
|
223
|
+
.lze-blocker__dot:nth-child(3) {
|
|
224
|
+
animation-delay: 0.4s;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
@keyframes dotting {
|
|
228
|
+
0%, 80%, 100% { opacity: 0.3; }
|
|
229
|
+
40% { opacity: 1; }
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.lze-blocker__error {
|
|
233
|
+
color: #f00;
|
|
234
|
+
font-size: 14px;
|
|
235
|
+
margin-bottom: 10px;
|
|
236
|
+
text-shadow: 0 0 1px #ff5f5f;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.lze-blocker__error_suggestion {
|
|
240
|
+
color: #ccc;
|
|
241
|
+
font-size: 14px;
|
|
242
|
+
margin-top: 10px;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
@keyframes spin {
|
|
246
|
+
0% { transform: rotate(0deg); }
|
|
247
|
+
100% { transform: rotate(360deg); }
|
|
248
|
+
}
|
|
249
|
+
`;
|
|
250
|
+
const styleElement = document.createElement('style');
|
|
251
|
+
if (add) {
|
|
252
|
+
if (!document.querySelector('.lze-blocker')) {
|
|
253
|
+
styleElement.innerHTML = style;
|
|
254
|
+
document.head.appendChild(styleElement);
|
|
255
|
+
body.insertAdjacentHTML('beforeend', blcokerHtml);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
this.removeBlocker(styleElement);
|
|
260
|
+
}
|
|
261
|
+
return styleElement;
|
|
262
|
+
}
|
|
263
|
+
removeBlocker(styleElement) {
|
|
264
|
+
const blocker = document.querySelector('.lze-blocker');
|
|
265
|
+
blocker === null || blocker === void 0 ? void 0 : blocker.remove();
|
|
266
|
+
styleElement === null || styleElement === void 0 ? void 0 : styleElement.remove();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
export const ApiHelper = new LocalizeApiHelper();
|
|
270
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jY2FsaXplLmFwaS5oZWxwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbG9jYWxpemUtdG9rZW4vaGVscGVycy9sb2NjYWxpemUuYXBpLmhlbHBlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFjLGlCQUFpQixFQUFlLE1BQU0sc0JBQXNCLENBQUM7QUFFbEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFXLE1BQU0sTUFBTSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFnQjNELE1BQU0saUJBQWlCO0lBQXZCO1FBRWEsd0JBQW1CLEdBQTJCO1lBQ25ELGVBQWUsRUFBRTtnQkFDYixPQUFPLEVBQUUsd0NBQXdDO2dCQUNqRCxXQUFXLEVBQUUsSUFBSTtnQkFDakIsaUJBQWlCLEVBQUUsS0FBSzthQUMzQjtTQUNKLENBQUM7SUE2U04sQ0FBQztJQTNTUyxZQUFZLENBQVUsT0FBc0I7O1lBQzlDLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztZQUNqQixJQUFJLFNBQWMsQ0FBQztZQUNuQixJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7WUFFckIsb0RBQW9EO1lBQ3BELE9BQU8sbUNBQVEsSUFBSSxDQUFDLG1CQUFtQixHQUFLLE9BQU8sQ0FBRSxDQUFBO1lBRXJELElBQUksWUFBMEMsQ0FBQztZQUUvQyxPQUFPLFFBQVEsR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUU7Z0JBQ3BDLElBQUk7b0JBQ0EsTUFBTSxNQUFNLEdBQUcsTUFBTSxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ3hDLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ2pDLE9BQU8sTUFBTSxDQUFDO2lCQUVqQjtnQkFBQyxPQUFPLEtBQVUsRUFBRTtvQkFDakIsU0FBUyxHQUFHLEtBQUssQ0FBQztv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RUFBRSxXQUFXLENBQUMsQ0FBQzthQUNyRDtTQUNKO2FBQU07WUFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQ3BDO1FBRUQsT0FBTyxZQUFZLENBQUM7SUFDeEIsQ0FBQztJQUVPLGFBQWEsQ0FBQyxZQUEwQztRQUM1RCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3ZELE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxNQUFNLEVBQUUsQ0FBQztRQUNsQixZQUFZLGFBQVosWUFBWSx1QkFBWixZQUFZLENBQUUsTUFBTSxFQUFFLENBQUM7SUFDM0IsQ0FBQztDQUNKO0FBRUQsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLElBQUksaUJBQWlCLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlLCBIdHRwSGVhZGVycyB9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xyXG5pbXBvcnQgeyBJQXBpT3B0aW9ucywgSUxvY2FsaXplQXBpQ29uZmlncywgSU5vcm1hbGl6ZWRFcnJvciwgSU9uQ29ubmVjdGlvbkVycm9yIH0gZnJvbSBcIi4vaW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgeyB0YWtlVW50aWwsIGNhdGNoRXJyb3IsIHRocm93RXJyb3IsIFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyBMb2NhbGl6ZVRva2VuLCB3YWl0Rm9yIH0gZnJvbSBcIi4uL2xvY2FsaXplLnRva2VuXCI7XHJcblxyXG5pbnRlcmZhY2UgSVJlcXVlc3RJbnN0YW5jZSB7XHJcbiAgICBjbGllbnQ6IEh0dHBDbGllbnQ7XHJcbiAgICBkZXN0cm95JDogKCkgPT4gU3ViamVjdDx2b2lkPjtcclxufVxyXG5cclxuaW50ZXJmYWNlIElSZXRyeU9wdGlvbnMge1xyXG4gICAgbWF4UmV0cmllczogKCkgPT4gbnVtYmVyO1xyXG4gICAgZGVsYXk6IG51bWJlcjtcclxuICAgIGNhbGxiYWNrOiAoKSA9PiBQcm9taXNlPGFueT4gfCBhbnk7XHJcbiAgICByZXRyeVVubGVzcz86IChlcnJvcjogYW55KSA9PiBib29sZWFuO1xyXG4gICAgb25FcnJvcj86IChlcnJvcjogYW55KSA9PiBQcm9taXNlPHZvaWQ+IHwgYW55O1xyXG4gICAgY29ubmVjdGlvbkVycm9yPzogSU9uQ29ubmVjdGlvbkVycm9yXHJcbn1cclxuXHJcbmNsYXNzIExvY2FsaXplQXBpSGVscGVyIHtcclxuXHJcbiAgICByZWFkb25seSBkZWZhdWx0UmV0cnlPcHRpb25zOiBQYXJ0aWFsPElSZXRyeU9wdGlvbnM+ID0ge1xyXG4gICAgICAgIGNvbm5lY3Rpb25FcnJvcjoge1xyXG4gICAgICAgICAgICBtZXNzYWdlOiAnQ29ubmVjdGlvbiBlcnJvciBvY2N1cnJlZC4gUGxlYXNlIHdhaXQnLFxyXG4gICAgICAgICAgICBibG9ja1NjcmVlbjogdHJ1ZSxcclxuICAgICAgICAgICAgYmxvY2tTY3JlZW5aSW5kZXg6IDEwMDAwXHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBhc3luYyBwZXJmb3JtUmV0cnk8VCA9IGFueT4ob3B0aW9uczogSVJldHJ5T3B0aW9ucyk6IFByb21pc2U8VD4ge1xyXG4gICAgICAgIGxldCBhdHRlbXB0cyA9IDA7XHJcbiAgICAgICAgbGV0IGxhc3RFcnJvcjogYW55O1xyXG4gICAgICAgIGxldCBjb25zb2xlQ291bnQgPSAwO1xyXG5cclxuICAgICAgICAvLyBNZXJnZSBkZWZhdWx0IHJldHJ5IG9wdGlvbnMgd2l0aCBwcm92aWRlZCBvcHRpb25zXHJcbiAgICAgICAgb3B0aW9ucyA9IHsgLi4udGhpcy5kZWZhdWx0UmV0cnlPcHRpb25zLCAuLi5vcHRpb25zIH1cclxuXHJcbiAgICAgICAgbGV0IHN0eWxlRWxlbWVudDogSFRNTFN0eWxlRWxlbWVudCB8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgd2hpbGUgKGF0dGVtcHRzIDwgb3B0aW9ucy5tYXhSZXRyaWVzKCkpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9wdGlvbnMuY2FsbGJhY2soKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlQmxvY2tlcihzdHlsZUVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuXHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcclxuICAgICAgICAgICAgICAgIGxhc3RFcnJvciA9IGVycm9yO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChjb25zb2xlQ291bnQgPj0gNykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuY2xlYXIoKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlQ291bnQgPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnJldHJ5VW5sZXNzICYmICFvcHRpb25zLnJldHJ5VW5sZXNzKGVycm9yKSlcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjsgLy8gSWYgdGhlIGVycm9yIHNob3VsZCBub3QgYmUgcmV0cmllZCwgcmV0aHJvdyBpdFxyXG5cclxuICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBjb25uZWN0aW9uIGVycm9yXHJcbiAgICAgICAgICAgICAgICBzdHlsZUVsZW1lbnQgPSBhd2FpdCB0aGlzLm9uQ29ubmVjdGlvbkVycm9yKG9wdGlvbnMsIGVycm9yKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5vbkVycm9yKVxyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaW52b2tlSG9vayhvcHRpb25zLm9uRXJyb3IuYmluZCh0aGlzLCBlcnJvcikpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChhdHRlbXB0cyA+PSBvcHRpb25zLm1heFJldHJpZXMoKSAtIDEpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XHJcblxyXG4gICAgICAgICAgICAgICAgYXR0ZW1wdHMrKztcclxuICAgICAgICAgICAgICAgIGNvbnNvbGVDb3VudCsrO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBBdHRlbXB0ICR7YXR0ZW1wdHN9IGZhaWxlZC4gUmV0cnlpbmcuLi5gLCBlcnJvcik7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCB3YWl0Rm9yKG9wdGlvbnMuZGVsYXkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zb2xlLndhcm4oYEZhaWxlZCBhZnRlciAke29wdGlvbnMubWF4UmV0cmllc30gYXR0ZW1wdHNgKTtcclxuICAgICAgICB0aHJvdyBsYXN0RXJyb3I7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgcGVyZm9ybVJlcXVlc3RXaXRoUmV0cnk8VCA9IGFueT4oXHJcbiAgICAgICAgb3B0aW9uczogSUFwaU9wdGlvbnMsXHJcbiAgICAgICAgY29uZmlnOiBJTG9jYWxpemVBcGlDb25maWdzLFxyXG4gICAgICAgIHBlcmZvcm1SZXF1ZXN0OiA8VCA9IGFueT4ob3B0aW9uczogSUFwaU9wdGlvbnMpID0+IFByb21pc2U8VD5cclxuICAgICk6IFByb21pc2U8VD4ge1xyXG5cclxuICAgICAgICBjb25zdCByZXRyeVVubGVzcyA9IGNvbmZpZy5yZXRyeU9wdGlvbnM/LnJldHJ5RnVuY3Rpb25cclxuICAgICAgICAgICAgfHwgdGhpcy5pc0Nvbm5lY3Rpb25FcnJvcjtcclxuXHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucGVyZm9ybVJldHJ5KHtcclxuICAgICAgICAgICAgY29ubmVjdGlvbkVycm9yOiBjb25maWcucmV0cnlPcHRpb25zPy5vbkNvbm5lY3Rpb25FcnJvcixcclxuICAgICAgICAgICAgbWF4UmV0cmllczogKCkgPT4gY29uZmlnLnJldHJ5T3B0aW9ucz8ubWF4UmV0cmllcyA/PyAxMDAwLFxyXG4gICAgICAgICAgICBkZWxheTogY29uZmlnLnJldHJ5T3B0aW9ucz8uZGVsYXkgPz8gNTAwLFxyXG4gICAgICAgICAgICBjYWxsYmFjazogKCkgPT4gcGVyZm9ybVJlcXVlc3Q8VD4ob3B0aW9ucyksXHJcbiAgICAgICAgICAgIHJldHJ5VW5sZXNzOiByZXRyeVVubGVzcyxcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIGJ1aWxkVXJsKGJhc2VVcmw6IHN0cmluZywgcGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBub3JtYWxpemVkVXJsID0gYCR7YmFzZVVybC50cmltKCkucmVwbGFjZSgvXFwvPyQvLCAnLycpfSR7cGF0aC50cmltKCkucmVwbGFjZSgvXlxcLy8sICcnKX1gO1xyXG4gICAgICAgIHJldHVybiBub3JtYWxpemVkVXJsLmVuZHNXaXRoKCcvJylcclxuICAgICAgICAgICAgPyBub3JtYWxpemVkVXJsLnNsaWNlKDAsIC0xKVxyXG4gICAgICAgICAgICA6IG5vcm1hbGl6ZWRVcmw7XHJcbiAgICB9XHJcblxyXG4gICAgbm9ybWFsaXplRXJyb3IoZXJyb3I6IEh0dHBFcnJvclJlc3BvbnNlKTogSU5vcm1hbGl6ZWRFcnJvciB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgY29kZTogZXJyb3IuZXJyb3I/LmNvZGUgfHwgYEhUVFBfJHtlcnJvci5zdGF0dXN9YCxcclxuICAgICAgICAgICAgbWVzc2FnZTogZXJyb3IuZXJyb3I/Lm1lc3NhZ2UgfHwgZXJyb3IubWVzc2FnZSxcclxuICAgICAgICAgICAgZGV0YWlsczogZXJyb3IuZXJyb3I/LmRldGFpbHMsXHJcbiAgICAgICAgICAgIHN0YXR1czogZXJyb3Iuc3RhdHVzXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBpbnZva2VIb29rKGNhbGxiYWNrPzogKCkgPT4gUHJvbWlzZTxhbnk+IHwgYW55KTogUHJvbWlzZTxhbnk+IHtcclxuICAgICAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XHJcblxyXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGNhbGxiYWNrKCk7XHJcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcclxuICAgICAgICAgICAgYXdhaXQgcmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjcmVhdGVSZXF1ZXN0PFQgPSBhbnk+KFxyXG4gICAgICAgIGluc3RhbmNlOiBSZXF1aXJlZDxJUmVxdWVzdEluc3RhbmNlPixcclxuICAgICAgICBtZXRob2Q6IHN0cmluZyxcclxuICAgICAgICB1cmw6IHN0cmluZyxcclxuICAgICAgICBib2R5OiBhbnksXHJcbiAgICAgICAgb3B0aW9uczogeyBoZWFkZXJzOiBIdHRwSGVhZGVycyB9XHJcbiAgICApIHtcclxuICAgICAgICBjb25zdCByZXF1ZXN0JCA9IGluc3RhbmNlLmNsaWVudC5yZXF1ZXN0PFQ+KG1ldGhvZCwgdXJsLCB7XHJcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXHJcbiAgICAgICAgICAgIGJvZHksXHJcbiAgICAgICAgICAgIG9ic2VydmU6ICdyZXNwb25zZScsXHJcbiAgICAgICAgfSkucGlwZShcclxuICAgICAgICAgICAgdGFrZVVudGlsKGluc3RhbmNlLmRlc3Ryb3kkKCkpLFxyXG4gICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcjogSHR0cEVycm9yUmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIENvbnZlcnQgdG8gYSBub24tb2JzZXJ2YWJsZSBlcnJvciB0byBoYW5kbGUgaW4gdGhlIHByb21pc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IHRoaXMubm9ybWFsaXplRXJyb3IoZXJyb3IpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICByZXR1cm4gcmVxdWVzdCQ7XHJcbiAgICB9XHJcblxyXG4gICAgZGVmYXVsdFJldHJ5RnVuY3Rpb24oZXJyb3I6IElOb3JtYWxpemVkRXJyb3IpOiBib29sZWFuIHtcclxuXHJcbiAgICAgICAgLy8gRG9uJ3QgcmV0cnkgZm9yIG90aGVyIGVycm9ycyAobGlrZSA0MDAsIDQwMSwgNDAzLCBldGMuKVxyXG4gICAgICAgIGlmICghdGhpcy5pc0Nvbm5lY3Rpb25FcnJvcihlcnJvcikpXHJcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xyXG5cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBpc0Nvbm5lY3Rpb25FcnJvcihlcnJvcjogSU5vcm1hbGl6ZWRFcnJvcik6IGJvb2xlYW4ge1xyXG4gICAgICAgIGNvbnN0IGlzTmV0d29ya0Vycm9yID0gZXJyb3Iuc3RhdHVzID09PSAwO1xyXG4gICAgICAgIGNvbnN0IGlzU2VydmVyRXJyb3IgPSBlcnJvci5zdGF0dXMgPj0gMTAwMCAmJiBlcnJvci5zdGF0dXMgPCA2MDA7XHJcbiAgICAgICAgcmV0dXJuIGlzTmV0d29ya0Vycm9yIHx8IGlzU2VydmVyRXJyb3I7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgb25Db25uZWN0aW9uRXJyb3IoXHJcbiAgICAgICAgb3B0aW9uczogSVJldHJ5T3B0aW9ucyxcclxuICAgICAgICBlcnJvcjogYW55XHJcbiAgICApOiBQcm9taXNlPFByb21pc2U8dm9pZD4gfCBhbnk+IHtcclxuXHJcbiAgICAgICAgaWYgKCFvcHRpb25zLmNvbm5lY3Rpb25FcnJvcilcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBsZXQgc3R5bGVFbGVtZW50OiBIVE1MU3R5bGVFbGVtZW50IHwgdW5kZWZpbmVkO1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ29ubmVjdGlvbkVycm9yKGVycm9yKSkge1xyXG5cclxuICAgICAgICAgICAgc3R5bGVFbGVtZW50ID0gdGhpcy5zY3JlZW5CbG9ja2VyKG9wdGlvbnMsIGVycm9yLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuaW52b2tlSG9vayhvcHRpb25zLmNvbm5lY3Rpb25FcnJvci5jYWxsYmFjaz8uYmluZCh0aGlzLCBlcnJvcikpO1xyXG4gICAgICAgICAgICByZXR1cm4gc3R5bGVFbGVtZW50O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2NyZWVuQmxvY2tlcihvcHRpb25zLCBlcnJvciwgZmFsc2UpO1xyXG4gICAgICAgICAgICBzdHlsZUVsZW1lbnQ/LnJlbW92ZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZUNvbmZpZyhjb25maWc6IElMb2NhbGl6ZUFwaUNvbmZpZ3MpOiB2b2lkIHtcclxuICAgICAgICBpZiAoTG9jYWxpemVUb2tlbi5jb25maWcubmVlZFRlbmFudCAmJiAhY29uZmlnLnRlbmFudFRva2VuTmFtZT8udHJpbSgpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcignVGVuYW50IHRva2VuIGlzIHJlcXVpcmVkIGJ1dCB0ZW5hbnRUb2tlbk5hbWUgaXMgbm90IGNvbmZpZ3VyZWQnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghTG9jYWxpemVUb2tlbi5jb25maWcucmV2b2tlVG9rZW5VcmwudHJpbSgpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcignUmV2b2tlIHRva2VuIFVSTCBpcyBub3QgY29uZmlndXJlZCAtIHRva2VuIHJlZnJlc2ggd2lsbCBub3Qgd29yaycpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzY3JlZW5CbG9ja2VyKG9wdG9uczogSVJldHJ5T3B0aW9ucyxcclxuICAgICAgICBlcnJvcj86IGFueSxcclxuICAgICAgICBhZGQ6IGJvb2xlYW4gPSB0cnVlKTogSFRNTFN0eWxlRWxlbWVudCB8IHVuZGVmaW5lZCB7XHJcblxyXG4gICAgICAgIGlmICghb3B0b25zLmNvbm5lY3Rpb25FcnJvcj8uYmxvY2tTY3JlZW4pXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgSHR0cEVycm9yUmVzcG9uc2UpXHJcbiAgICAgICAgICAgIGVycm9yID0gdGhpcy5ub3JtYWxpemVFcnJvcihlcnJvcik7XHJcblxyXG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBvcHRvbnMuY29ubmVjdGlvbkVycm9yPy5tZXNzYWdlXHJcbiAgICAgICAgICAgIHx8ICdDb25uZWN0aW9uIGVycm9yIG9jY3VycmVkLiBQbGVhc2Ugd2FpdCc7XHJcbiAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3I/Lm1lc3NhZ2UgfHwgJ0FuIGVycm9yIG9jY3VycmVkJztcclxuICAgICAgICBjb25zdCBzdWdnZXN0aW5NZXNzYWdlID0gb3B0b25zLmNvbm5lY3Rpb25FcnJvcj8uc3VnZ2VzdGlvbk1lc3NhZ2VcclxuICAgICAgICAgICAgfHwgJ1BsZWFzZSBjaGVjayB5b3VyIGludGVybmV0IGNvbm5lY3Rpb24gb3IgdGhlIHNlcnZlciBzdGF0dXMuJztcclxuXHJcbiAgICAgICAgY29uc3QgekluZGV4ID0gb3B0b25zLmNvbm5lY3Rpb25FcnJvcj8uYmxvY2tTY3JlZW5aSW5kZXggfHwgMTAwMDA7XHJcblxyXG4gICAgICAgIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5ib2R5O1xyXG4gICAgICAgIGNvbnN0IGJsY29rZXJIdG1sID0gYFxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJsemUtYmxvY2tlclwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibHplLWJsb2NrZXJfX21lc3NhZ2VcIj5cclxuICAgICAgICAgICAgICAgICR7bWVzc2FnZX1cclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibHplLWJsb2NrZXJfX2RvdHRpbmdcIj5cclxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImx6ZS1ibG9ja2VyX19kb3RcIj48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsemUtYmxvY2tlcl9fZG90XCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibHplLWJsb2NrZXJfX2RvdFwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsemUtYmxvY2tlcl9fZXJyb3JcIj4ke2Vycm9yTWVzc2FnZX08L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImx6ZS1ibG9ja2VyX19lcnJvcl9zdWdnZXN0aW9uXCI+JHtzdWdnZXN0aW5NZXNzYWdlfTwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibHplLWJsb2NrZXJfX3NwaW5uZXJcIj48L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICBgO1xyXG4gICAgICAgIGNvbnN0IHN0eWxlID0gYFxyXG4gICAgICAgIC5semUtYmxvY2tlciB7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uOiBmaXhlZDtcclxuICAgICAgICAgICAgdG9wOiAwO1xyXG4gICAgICAgICAgICBsZWZ0OiAwO1xyXG4gICAgICAgICAgICB3aWR0aDogMTAwJTtcclxuICAgICAgICAgICAgaGVpZ2h0OiAxMDAlO1xyXG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsIDAsIDAsIDAuOCk7XHJcbiAgICAgICAgICAgIHotaW5kZXg6ICR7ekluZGV4fTtcclxuICAgICAgICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcclxuICAgICAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XHJcbiAgICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XHJcbiAgICAgICAgICAgIGNvbG9yOiAjZmZmO1xyXG4gICAgICAgICAgICBmb250LWZhbWlseTogQXJpYWwsIHNhbnMtc2VyaWY7XHJcbiAgICAgICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcclxuICAgICAgICAgICAgcGFkZGluZzogMjBweDtcclxuICAgICAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcclxuICAgICAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcclxuICAgICAgICAgICAgdXNlci1zZWxlY3Q6IG5vbmU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIC5semUtYmxvY2tlcl9fc3Bpbm5lciB7XHJcbiAgICAgICAgICAgIGJvcmRlcjogNHB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xKTtcclxuICAgICAgICAgICAgYm9yZGVyLXRvcDogNHB4IHNvbGlkICNmZmY7XHJcbiAgICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcclxuICAgICAgICAgICAgd2lkdGg6IDUwcHg7XHJcbiAgICAgICAgICAgIGhlaWdodDogNTBweDtcclxuICAgICAgICAgICAgYW5pbWF0aW9uOiBzcGluIDFzIGxpbmVhciBpbmZpbml0ZTtcclxuICAgICAgICAgICAgbWFyZ2luLXRvcDogMjBweDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC5semUtYmxvY2tlcl9fbWVzc2FnZSB7XHJcbiAgICAgICAgICAgIGNvbG9yOiAjZmZmO1xyXG4gICAgICAgICAgICBmb250LXNpemU6IDE4cHg7XHJcbiAgICAgICAgICAgIG1hcmdpbi1ib3R0b206IDEwcHg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAubHplLWJsb2NrZXJfX2RvdHRpbmcge1xyXG4gICAgICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XHJcbiAgICAgICAgICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC5semUtYmxvY2tlcl9fZG90IHtcclxuICAgICAgICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xyXG4gICAgICAgICAgICB3aWR0aDogN3B4O1xyXG4gICAgICAgICAgICBoZWlnaHQ6IDdweDtcclxuICAgICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZmZmZjtcclxuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogNTAlO1xyXG4gICAgICAgICAgICBtYXJnaW4tbGVmdDogM3B4O1xyXG4gICAgICAgICAgICBvcGFjaXR5OiAwLjM7XHJcbiAgICAgICAgICAgIGFuaW1hdGlvbjogZG90dGluZyAxcyBpbmZpbml0ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLmx6ZS1ibG9ja2VyX19kb3Q6bnRoLWNoaWxkKDEpIHtcclxuICAgICAgICAgICAgYW5pbWF0aW9uLWRlbGF5OiAwcztcclxuICAgICAgICAgICAgb3BhY2l0eTogMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLmx6ZS1ibG9ja2VyX19kb3Q6bnRoLWNoaWxkKDIpIHtcclxuICAgICAgICAgICAgYW5pbWF0aW9uLWRlbGF5OiAwLjJzO1xyXG4gICAgICAgIH1cclxuICAgICAgICAubHplLWJsb2NrZXJfX2RvdDpudGgtY2hpbGQoMykge1xyXG4gICAgICAgICAgICBhbmltYXRpb24tZGVsYXk6IDAuNHM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBAa2V5ZnJhbWVzIGRvdHRpbmcge1xyXG4gICAgICAgICAgICAwJSwgODAlLCAxMDAlIHsgb3BhY2l0eTogMC4zOyB9XHJcbiAgICAgICAgICAgIDQwJSB7IG9wYWNpdHk6IDE7IH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC5semUtYmxvY2tlcl9fZXJyb3Ige1xyXG4gICAgICAgICAgICBjb2xvcjogI2YwMDtcclxuICAgICAgICAgICAgZm9udC1zaXplOiAxNHB4O1xyXG4gICAgICAgICAgICBtYXJnaW4tYm90dG9tOiAxMHB4O1xyXG4gICAgICAgICAgICB0ZXh0LXNoYWRvdzogMCAwIDFweCAjZmY1ZjVmO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLmx6ZS1ibG9ja2VyX19lcnJvcl9zdWdnZXN0aW9uIHtcclxuICAgICAgICAgICAgY29sb3I6ICNjY2M7XHJcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogMTRweDtcclxuICAgICAgICAgICAgbWFyZ2luLXRvcDogMTBweDtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgQGtleWZyYW1lcyBzcGluIHtcclxuICAgICAgICAgICAgMCUgeyB0cmFuc2Zvcm06IHJvdGF0ZSgwZGVnKTsgfVxyXG4gICAgICAgICAgICAxMDAlIHsgdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTsgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBgO1xyXG5cclxuICAgICAgICBjb25zdCBzdHlsZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xyXG5cclxuICAgICAgICBpZiAoYWRkKSB7XHJcbiAgICAgICAgICAgIGlmICghZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmx6ZS1ibG9ja2VyJykpIHtcclxuICAgICAgICAgICAgICAgIHN0eWxlRWxlbWVudC5pbm5lckhUTUwgPSBzdHlsZTtcclxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIGJvZHkuaW5zZXJ0QWRqYWNlbnRIVE1MKCdiZWZvcmVlbmQnLCBibGNva2VySHRtbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnJlbW92ZUJsb2NrZXIoc3R5bGVFbGVtZW50KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBzdHlsZUVsZW1lbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZW1vdmVCbG9ja2VyKHN0eWxlRWxlbWVudDogSFRNTFN0eWxlRWxlbWVudCB8IHVuZGVmaW5lZCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGJsb2NrZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubHplLWJsb2NrZXInKTtcclxuICAgICAgICBibG9ja2VyPy5yZW1vdmUoKTtcclxuICAgICAgICBzdHlsZUVsZW1lbnQ/LnJlbW92ZSgpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgQXBpSGVscGVyID0gbmV3IExvY2FsaXplQXBpSGVscGVyKCk7Il19
|