@gnwebsoft/ui 4.1.2 → 4.2.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.
Files changed (57) hide show
  1. package/dist/{chunk-KSJAR3NE.cjs → chunk-7AOABVLH.cjs} +137 -79
  2. package/dist/chunk-EQQROKNQ.js +3015 -0
  3. package/dist/chunk-FMN47XRJ.cjs +1 -1
  4. package/dist/{chunk-73DUUDND.cjs → chunk-JCF64O7K.cjs} +38 -11
  5. package/dist/chunk-QYHJIPSZ.cjs +1 -1
  6. package/dist/chunk-VDANRHRZ.js +568 -0
  7. package/dist/chunk-ZZDLWPNL.cjs +1 -1
  8. package/dist/core/index.cjs +1 -1
  9. package/dist/hooks/index.cjs +1 -1
  10. package/dist/index.cjs +16 -4
  11. package/dist/index.js +14 -2
  12. package/dist/types/index.cjs +1 -1
  13. package/dist/utils/fileUtils.d.ts +13 -0
  14. package/dist/utils/fileUtils.d.ts.map +1 -0
  15. package/dist/utils/index.cjs +15 -3
  16. package/dist/utils/index.d.ts +1 -0
  17. package/dist/utils/index.d.ts.map +1 -1
  18. package/dist/utils/index.js +13 -1
  19. package/dist/utils/schemaTools.d.ts.map +1 -1
  20. package/dist/wrappers/AsyncMultiSelect/AsyncMultiSelect.d.ts.map +1 -1
  21. package/dist/wrappers/AsyncMultiSelect/types.d.ts +0 -2
  22. package/dist/wrappers/AsyncMultiSelect/types.d.ts.map +1 -1
  23. package/dist/wrappers/AsyncSelect/index.d.ts.map +1 -1
  24. package/dist/wrappers/AsyncSelect/types.d.ts +0 -2
  25. package/dist/wrappers/AsyncSelect/types.d.ts.map +1 -1
  26. package/dist/wrappers/DatePickerElement/DatePickerElementCore.d.ts.map +1 -1
  27. package/dist/wrappers/DatePickerElement/types.d.ts +9 -18
  28. package/dist/wrappers/DatePickerElement/types.d.ts.map +1 -1
  29. package/dist/wrappers/DateTimePickerElement/DateTimePickerElement.d.ts +0 -2
  30. package/dist/wrappers/DateTimePickerElement/DateTimePickerElement.d.ts.map +1 -1
  31. package/dist/wrappers/FileUploadElement/FileUploadElement.d.ts +2 -0
  32. package/dist/wrappers/FileUploadElement/FileUploadElement.d.ts.map +1 -1
  33. package/dist/wrappers/NumberFieldElement/NumberFieldElement.d.ts +0 -2
  34. package/dist/wrappers/NumberFieldElement/NumberFieldElement.d.ts.map +1 -1
  35. package/dist/wrappers/PasswordElement/PasswordElement.d.ts +0 -2
  36. package/dist/wrappers/PasswordElement/PasswordElement.d.ts.map +1 -1
  37. package/dist/wrappers/PhoneNumberElement/PhoneNumberElement.d.ts +1 -3
  38. package/dist/wrappers/PhoneNumberElement/PhoneNumberElement.d.ts.map +1 -1
  39. package/dist/wrappers/SelectCascadeElement/SelectCascadeElement.d.ts +0 -2
  40. package/dist/wrappers/SelectCascadeElement/SelectCascadeElement.d.ts.map +1 -1
  41. package/dist/wrappers/SelectElement/SelectElement.d.ts +0 -2
  42. package/dist/wrappers/SelectElement/SelectElement.d.ts.map +1 -1
  43. package/dist/wrappers/SelectMultiElement/SelectMultiElement.d.ts +0 -2
  44. package/dist/wrappers/SelectMultiElement/SelectMultiElement.d.ts.map +1 -1
  45. package/dist/wrappers/TextFieldElement/TextFieldElement.d.ts +0 -2
  46. package/dist/wrappers/TextFieldElement/TextFieldElement.d.ts.map +1 -1
  47. package/dist/wrappers/TimePickerElement/TimePickerElement.d.ts +0 -2
  48. package/dist/wrappers/TimePickerElement/TimePickerElement.d.ts.map +1 -1
  49. package/dist/wrappers/index.cjs +4 -4
  50. package/dist/wrappers/index.js +2 -2
  51. package/package.json +1 -1
  52. package/dist/chunk-AHYFDQIK.js +0 -2957
  53. package/dist/chunk-N37HXJT5.js +0 -541
  54. package/dist/core/components/FieldTooltip/FieldTooltip.d.ts +0 -15
  55. package/dist/core/components/FieldTooltip/FieldTooltip.d.ts.map +0 -1
  56. package/dist/core/components/FieldTooltip/index.d.ts +0 -2
  57. package/dist/core/components/FieldTooltip/index.d.ts.map +0 -1
@@ -0,0 +1,568 @@
1
+ // src/utils/fileUtils.ts
2
+ var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp"];
3
+ var DOCUMENT_EXTENSIONS = [".pdf", ".doc", ".docx", ".xls", ".xlsx", ".txt"];
4
+ var ALL_FILE_EXTENSIONS = [...IMAGE_EXTENSIONS, ...DOCUMENT_EXTENSIONS];
5
+ var IMAGE_EXT_SET = new Set(IMAGE_EXTENSIONS);
6
+ function isImageFile(file) {
7
+ if (file.type.startsWith("image/")) return true;
8
+ const ext = "." + file.name.split(".").pop()?.toLowerCase();
9
+ return IMAGE_EXT_SET.has(ext);
10
+ }
11
+ function isImageMimeType(mimeType) {
12
+ return mimeType.startsWith("image/");
13
+ }
14
+ function formatFileSize(bytes) {
15
+ if (bytes === 0) return "0 B";
16
+ const k = 1024;
17
+ const units = ["B", "KB", "MB", "GB"];
18
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
19
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${units[i]}`;
20
+ }
21
+
22
+ // src/utils/flattenObjectKeys.ts
23
+ var isNested = (obj) => typeof obj === "object" && obj !== null && !Array.isArray(obj);
24
+ var isArray = (obj) => Array.isArray(obj);
25
+ var flattenObjectKeys = (obj, prefix = "") => {
26
+ if (!isNested(obj)) {
27
+ return {
28
+ [prefix]: obj
29
+ };
30
+ }
31
+ return Object.keys(obj).reduce((acc, key) => {
32
+ const currentPrefix = prefix.length ? `${prefix}.` : "";
33
+ if (isNested(obj[key]) && Object.keys(obj[key]).length) {
34
+ if (isArray(obj[key]) && obj[key].length) {
35
+ obj[key].forEach((item, index) => {
36
+ Object.assign(
37
+ acc,
38
+ flattenObjectKeys(item, `${currentPrefix + key}.${index}`)
39
+ );
40
+ });
41
+ } else {
42
+ Object.assign(acc, flattenObjectKeys(obj[key], currentPrefix + key));
43
+ }
44
+ acc[currentPrefix + key] = obj[key];
45
+ } else {
46
+ acc[currentPrefix + key] = obj[key];
47
+ }
48
+ return acc;
49
+ }, {});
50
+ };
51
+
52
+ // src/utils/getTimezone.ts
53
+ function getTimezone(adapter, value) {
54
+ return value == null || !adapter.utils.isValid(value) ? null : adapter.utils.getTimezone(value);
55
+ }
56
+
57
+ // src/utils/handleServerErrors.ts
58
+ var handleServerErrors = function handleServerErrors2(args) {
59
+ const { errors, setError } = args;
60
+ for (const key in errors) {
61
+ const isKeyInVariables = Object.keys(flattenObjectKeys(errors)).includes(
62
+ key
63
+ );
64
+ if (!isKeyInVariables) {
65
+ continue;
66
+ }
67
+ const fieldError = errors[key];
68
+ let errorMessage = "";
69
+ if (Array.isArray(fieldError)) {
70
+ errorMessage = fieldError.join(" ");
71
+ }
72
+ if (typeof fieldError === "string") {
73
+ errorMessage = fieldError;
74
+ }
75
+ if (typeof fieldError === "boolean" && fieldError) {
76
+ errorMessage = "Field is not valid.";
77
+ }
78
+ setError(key, {
79
+ message: errorMessage
80
+ });
81
+ }
82
+ };
83
+
84
+ // src/utils/propertyExists.ts
85
+ function propertyExists(obj, prop) {
86
+ return typeof obj === "object" && obj !== null && Object.prototype.hasOwnProperty.call(obj, prop);
87
+ }
88
+
89
+ // src/utils/readValueAsDate.ts
90
+ function readValueAsDate(adapter, value) {
91
+ if (typeof value === "string") {
92
+ if (value === "") {
93
+ return null;
94
+ }
95
+ return adapter.utils.date(value);
96
+ }
97
+ return value;
98
+ }
99
+
100
+ // src/utils/removeLeadingTrailingSlashes.ts
101
+ var removeLeadingTrailingSlashes = (route) => {
102
+ return route.replace(/^\/|\/$/g, "");
103
+ };
104
+
105
+ // src/utils/schemaTools.ts
106
+ import dayjs from "dayjs";
107
+ import { z } from "zod";
108
+ function isValidLuhn(value) {
109
+ if (!value || value.trim() === "") {
110
+ return false;
111
+ }
112
+ const number = value.replace(/[\s-]/g, "");
113
+ if (!/^\d+$/.test(number)) {
114
+ return false;
115
+ }
116
+ if (number.length < 13 || number.length > 19) {
117
+ return false;
118
+ }
119
+ let sum = 0;
120
+ let alternate = false;
121
+ for (let i = number.length - 1; i >= 0; i--) {
122
+ let digit = parseInt(number.charAt(i), 10);
123
+ if (alternate) {
124
+ digit *= 2;
125
+ if (digit > 9) {
126
+ digit -= 9;
127
+ }
128
+ }
129
+ sum += digit;
130
+ alternate = !alternate;
131
+ }
132
+ return sum % 10 === 0;
133
+ }
134
+ var schemaTools = {
135
+ // Date validations
136
+ date: ({ message } = {}) => z.coerce.string().transform((c) => c === "null" || c === "undefined" ? null : c).refine((c) => !!c, { message: message || "Date is required" }).refine((c) => c ? dayjs(c).isValid() : true, {
137
+ message: message || "Invalid date"
138
+ }),
139
+ nullableDate: ({ message } = {}) => z.coerce.string().transform((c) => c === "null" ? null : c).transform((c) => c === "undefined" ? null : c).refine((c) => !c && c !== null ? dayjs(c).isValid() : true, {
140
+ message: message || "Invalid date"
141
+ }),
142
+ pastDate: ({ message } = {}) => z.coerce.date().refine((date) => date < /* @__PURE__ */ new Date(), {
143
+ message: message || "Must be a past date"
144
+ }),
145
+ futureDate: ({ message } = {}) => z.coerce.date().refine((date) => date > /* @__PURE__ */ new Date(), {
146
+ message: message || "Must be a future date"
147
+ }),
148
+ todayOrFutureDate: ({ message } = {}) => z.coerce.date().refine(
149
+ (date) => {
150
+ const today = /* @__PURE__ */ new Date();
151
+ today.setHours(0, 0, 0, 0);
152
+ return date.setHours(0, 0, 0, 0) >= today.getTime();
153
+ },
154
+ { message: message || "Must be today or a future date" }
155
+ ),
156
+ todayOrPastDate: ({ message } = {}) => z.coerce.date().refine(
157
+ (date) => {
158
+ const today = /* @__PURE__ */ new Date();
159
+ today.setHours(0, 0, 0, 0);
160
+ return date.setHours(0, 0, 0, 0) <= today.getTime();
161
+ },
162
+ { message: message || "Must be today or a past date" }
163
+ ),
164
+ adult: ({ message } = {}) => z.coerce.date().refine(
165
+ (date) => {
166
+ const eighteenYearsAgo = /* @__PURE__ */ new Date();
167
+ eighteenYearsAgo.setFullYear(eighteenYearsAgo.getFullYear() - 18);
168
+ eighteenYearsAgo.setHours(0, 0, 0, 0);
169
+ const dob = new Date(date);
170
+ dob.setHours(0, 0, 0, 0);
171
+ return dob <= eighteenYearsAgo;
172
+ },
173
+ { message: message || "Must be at least 18 years old" }
174
+ ),
175
+ minimumAge: ({
176
+ message,
177
+ minimumAge
178
+ } = {}) => z.coerce.date().refine(
179
+ (date) => {
180
+ if (typeof minimumAge !== "number") return false;
181
+ const minYearsAgo = /* @__PURE__ */ new Date();
182
+ minYearsAgo.setFullYear(minYearsAgo.getFullYear() - minimumAge);
183
+ minYearsAgo.setHours(0, 0, 0, 0);
184
+ const dob = new Date(date);
185
+ dob.setHours(0, 0, 0, 0);
186
+ return dob <= minYearsAgo;
187
+ },
188
+ {
189
+ message: message || `Must be at least ${minimumAge ?? "the required"} years old`
190
+ }
191
+ ),
192
+ withinDays: ({ message, days } = {}) => z.coerce.date().refine(
193
+ (date) => {
194
+ const today = /* @__PURE__ */ new Date();
195
+ today.setHours(0, 0, 0, 0);
196
+ const inputDate = new Date(date);
197
+ inputDate.setHours(0, 0, 0, 0);
198
+ const diffTime = Math.abs(inputDate.getTime() - today.getTime());
199
+ const diffDays = Math.ceil(diffTime / (1e3 * 60 * 60 * 24));
200
+ return typeof days === "number" ? diffDays <= days : false;
201
+ },
202
+ { message: message || `Must be within ${days} days of today` }
203
+ ),
204
+ weekday: ({ message } = {}) => z.coerce.date().refine(
205
+ (date) => {
206
+ const day = date.getDay();
207
+ return day !== 0 && day !== 6;
208
+ },
209
+ { message: message || "Must be a weekday" }
210
+ ),
211
+ dateRange: ({ message } = {}) => z.object({
212
+ start: z.coerce.date(),
213
+ end: z.coerce.date()
214
+ }).refine((data) => data.start <= data.end, {
215
+ message: message || "Start date must be before or equal to end date"
216
+ }),
217
+ time: ({ message } = {}) => z.coerce.date().transform((c) => c === null || c === void 0 ? null : c).refine((c) => !!c, { message: message || "Time is required" }).refine((c) => c ? dayjs(c).isValid() : true, {
218
+ message: message || "Invalid time"
219
+ }),
220
+ dateTime: ({ message } = {}) => z.coerce.date().transform((c) => c === null || c === void 0 ? null : c).refine((c) => !!c, { message: message || "Date and Time is required" }).refine((c) => c ? dayjs(c).isValid() : true, {
221
+ message: message || "Invalid Date and Time"
222
+ }),
223
+ // String validations
224
+ requiredString: ({
225
+ message,
226
+ min,
227
+ max
228
+ } = {}) => z.string().trim().min(
229
+ min || 1,
230
+ message || `String must be at least ${min || 1} characters`
231
+ ).max(
232
+ max || 255,
233
+ message || `String must be at most ${max || 255} characters`
234
+ ),
235
+ email: ({ message } = {}) => z.string().email(message || "Invalid email address").max(254, "Email must be at most 254 characters"),
236
+ url: ({ message } = {}) => z.string().url(message || "Invalid URL format"),
237
+ phone: ({ message } = {}) => z.string().regex(/^[+]?[1-9][\d]{0,15}$/, message || "Invalid phone number format"),
238
+ creditCard: ({ message } = {}) => z.string().refine((value) => isValidLuhn(value), {
239
+ message: message || "Must be a valid credit card number"
240
+ }),
241
+ indianMobile: ({ message } = {}) => z.string().regex(/^[6-9]\d{9}$/, message || "Must be a valid Indian mobile number"),
242
+ internationalPhone: ({ message } = {}) => z.string().regex(
243
+ /^\+?[1-9]\d{6,14}$/,
244
+ message || "Must be a valid international phone number"
245
+ ),
246
+ alphabetic: ({ message } = {}) => z.string().regex(
247
+ /^[A-Za-z, ]+$/,
248
+ message || "Must contain only letters, commas, and spaces"
249
+ ),
250
+ guid: ({ message } = {}) => z.string().uuid(message || "Must be a valid GUID"),
251
+ nonEmptyOrWhitespace: ({ message } = {}) => z.string().trim().min(1, message || "Must not be empty or whitespace"),
252
+ username: ({ message } = {}) => z.string().regex(
253
+ /^[a-zA-Z][a-zA-Z0-9_]{2,29}$/,
254
+ message || "Must be 3-30 characters, start with a letter, and contain only letters, numbers, and underscores"
255
+ ),
256
+ exactLength: ({
257
+ message,
258
+ length
259
+ } = {}) => {
260
+ if (typeof length !== "number") {
261
+ throw new Error("Length must be provided for exactLength validator");
262
+ }
263
+ return z.string().length(length, message || `Must be exactly ${length} characters`);
264
+ },
265
+ minWords: ({
266
+ message,
267
+ minWords
268
+ } = {}) => z.string().refine(
269
+ (value) => {
270
+ if (!value) return true;
271
+ const words = value.split(/[\s\t\n\r]+/).filter(Boolean);
272
+ return words.length >= (typeof minWords === "number" ? minWords : 0);
273
+ },
274
+ { message: message || `Must have at least ${minWords} word(s)` }
275
+ ),
276
+ maxWords: ({
277
+ message,
278
+ maxWords
279
+ } = {}) => z.string().refine(
280
+ (value) => {
281
+ if (!value) return true;
282
+ const words = value.split(/[\s\t\n\r]+/).filter(Boolean);
283
+ return words.length <= (typeof maxWords === "number" ? maxWords : 0);
284
+ },
285
+ { message: message || `Must have at most ${maxWords} word(s)` }
286
+ ),
287
+ strongPassword: ({ message } = {}) => z.string().regex(
288
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,
289
+ message || "Must be at least 8 characters and contain uppercase, lowercase, number, and special character"
290
+ ),
291
+ noHtml: ({ message } = {}) => z.string().refine(
292
+ (value) => !value || !/<[^>]*>/.test(value),
293
+ message || "Must not contain HTML tags"
294
+ ),
295
+ noScriptInjection: ({ message } = {}) => z.string().refine(
296
+ (value) => !value || !/<script|javascript:|on\w+\s*=/i.test(value),
297
+ message || "Contains potentially unsafe content"
298
+ ),
299
+ noSqlInjection: ({ message } = {}) => z.string().refine(
300
+ (value) => !value || !/('|--|;|\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER|CREATE|EXEC|EXECUTE)\b)/i.test(
301
+ value
302
+ ),
303
+ message || "Contains potentially unsafe content"
304
+ ),
305
+ indianPinCode: ({ message } = {}) => z.string().regex(/^[1-9][0-9]{5}$/, message || "Must be a valid 6-digit PIN code"),
306
+ usZipCode: ({ message } = {}) => z.string().regex(/^\d{5}(-\d{4})?$/, message || "Must be a valid US ZIP code"),
307
+ ukPostalCode: ({ message } = {}) => z.string().regex(
308
+ /^[A-Z]{1,2}[0-9][0-9A-Z]?\s?[0-9][A-Z]{2}$/i,
309
+ message || "Must be a valid UK postal code"
310
+ ),
311
+ ipv4: ({ message } = {}) => z.string().regex(
312
+ /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
313
+ message || "Must be a valid IPv4 address"
314
+ ),
315
+ ipv6: ({ message } = {}) => z.string().regex(
316
+ /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^::$|^::1$|^([0-9a-fA-F]{1,4}:){1,7}:$/,
317
+ message || "Must be a valid IPv6 address"
318
+ ),
319
+ macAddress: ({ message } = {}) => z.string().regex(
320
+ /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/,
321
+ message || "Must be a valid MAC address"
322
+ ),
323
+ allowedFileExtension: ({
324
+ message,
325
+ allowedExtensions
326
+ } = {}) => z.string().refine(
327
+ (fileName) => {
328
+ if (!fileName) return true;
329
+ const extension = fileName.split(".").pop()?.toLowerCase();
330
+ const lowerAllowed = allowedExtensions?.map(
331
+ (ext) => ext.toLowerCase().startsWith(".") ? ext.toLowerCase() : `.${ext.toLowerCase()}`
332
+ );
333
+ return extension && lowerAllowed?.includes(`.${extension}`);
334
+ },
335
+ {
336
+ message: message || `Must have one of the following extensions: ${allowedExtensions?.join(", ")}`
337
+ }
338
+ ),
339
+ validImageExtension: ({ message } = {}) => schemaTools.allowedFileExtension({
340
+ allowedExtensions: [...IMAGE_EXTENSIONS],
341
+ message: message || `Must have a valid image extension (${IMAGE_EXTENSIONS.join(", ")})`
342
+ }),
343
+ validDocumentExtension: ({ message } = {}) => schemaTools.allowedFileExtension({
344
+ allowedExtensions: [...DOCUMENT_EXTENSIONS],
345
+ message: message || `Must have a valid document extension (${DOCUMENT_EXTENSIONS.join(", ")})`
346
+ }),
347
+ panCard: ({ message } = {}) => z.string().regex(
348
+ /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/,
349
+ message || "Must be a valid PAN card number"
350
+ ),
351
+ aadhaar: ({ message } = {}) => z.string().regex(
352
+ /^[2-9]{1}[0-9]{11}$/,
353
+ message || "Must be a valid Aadhaar number"
354
+ ),
355
+ gstin: ({ message } = {}) => z.string().regex(
356
+ /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/,
357
+ message || "Must be a valid GSTIN"
358
+ ),
359
+ ifsc: ({ message } = {}) => z.string().regex(/^[A-Z]{4}0[A-Z0-9]{6}$/, message || "Must be a valid IFSC code"),
360
+ alphanumeric: ({ message } = {}) => z.string().regex(
361
+ /^[a-zA-Z0-9]+$/,
362
+ message || "Only letters and numbers are allowed"
363
+ ),
364
+ slug: ({ message } = {}) => z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, message || "Invalid slug format"),
365
+ // Number validations
366
+ positiveNumber: ({
367
+ message,
368
+ min,
369
+ max
370
+ } = {}) => z.number().positive(message || "Number must be positive").min(min || 0.01, `Number must be at least ${min || 0.01}`).max(
371
+ max || Number.MAX_SAFE_INTEGER,
372
+ `Number must be at most ${max || Number.MAX_SAFE_INTEGER}`
373
+ ),
374
+ maxDecimalPlaces: ({
375
+ message,
376
+ maxPlaces
377
+ } = {}) => z.number().refine(
378
+ (value) => {
379
+ if (value === null || value === void 0) return true;
380
+ const decimalPart = value.toString().split(".")[1];
381
+ return !decimalPart || decimalPart.length <= (typeof maxPlaces === "number" ? maxPlaces : 0);
382
+ },
383
+ { message: message || `Must have at most ${maxPlaces} decimal places` }
384
+ ),
385
+ currency: ({ message } = {}) => z.number().min(0, message || "Must be a valid currency amount (positive)").refine(
386
+ (value) => {
387
+ if (value === null || value === void 0) return true;
388
+ const decimalPart = value.toString().split(".")[1];
389
+ return !decimalPart || decimalPart.length <= 2;
390
+ },
391
+ {
392
+ message: message || "Must be a valid currency amount (max 2 decimal places)"
393
+ }
394
+ ),
395
+ validAge: ({ message } = {}) => z.number().int("Must be an integer").min(0, message || "Must be a valid age (between 0 and 150)").max(150, message || "Must be a valid age (between 0 and 150)"),
396
+ nonNegativeNumber: ({
397
+ message,
398
+ max
399
+ } = {}) => z.number().min(0, message || "Number must be non-negative").max(
400
+ max || Number.MAX_SAFE_INTEGER,
401
+ `Number must be at most ${max || Number.MAX_SAFE_INTEGER}`
402
+ ),
403
+ integer: ({
404
+ message,
405
+ min,
406
+ max
407
+ } = {}) => z.number().int(message || "Must be an integer").min(
408
+ min || Number.MIN_SAFE_INTEGER,
409
+ `Number must be at least ${min || Number.MIN_SAFE_INTEGER}`
410
+ ).max(
411
+ max || Number.MAX_SAFE_INTEGER,
412
+ `Number must be at most ${max || Number.MAX_SAFE_INTEGER}`
413
+ ),
414
+ percentage: ({ message } = {}) => z.number().min(0, message || "Percentage must be between 0 and 100").max(100, message || "Percentage must be between 0 and 100"),
415
+ // Array validations
416
+ nonEmptyArray: (schema, { message } = {}) => z.array(schema).min(1, message || "At least one item is required"),
417
+ uniqueArray: (schema, { message } = {}) => z.array(schema).refine((items) => new Set(items).size === items.length, {
418
+ message: message || "All items must be unique"
419
+ }),
420
+ noNullArrayItems: (schema, { message } = {}) => z.array(schema.nullable()).refine((items) => items.every((item) => item !== null), {
421
+ message: message || "Must not contain null items"
422
+ }),
423
+ // Boolean validations
424
+ requiredBoolean: ({ message } = {}) => z.boolean({
425
+ message: message || "This field is required"
426
+ }),
427
+ // Object validations
428
+ nonEmptyObject: (schema, { message } = {}) => schema.refine((obj) => Object.keys(obj).length > 0, {
429
+ message: message || "Object cannot be empty"
430
+ }),
431
+ // File validations
432
+ requiredFile: ({ message } = {}) => z.instanceof(File, { message: message || "File is required" }).refine((file) => file.size > 0, {
433
+ message: message || "File cannot be empty"
434
+ }),
435
+ fileSize: ({ maxSize, message }) => z.instanceof(File).refine((file) => file.size <= maxSize, {
436
+ message: message || `File size must be less than ${Math.round(maxSize / 1024 / 1024)}MB`
437
+ }),
438
+ fileType: ({
439
+ allowedTypes,
440
+ message
441
+ }) => z.instanceof(File).refine((file) => allowedTypes.includes(file.type), {
442
+ message: message || `File type must be one of: ${allowedTypes.join(", ")}`
443
+ }),
444
+ // Custom validators
445
+ conditional: (condition, trueSchema, falseSchema) => z.union([trueSchema, falseSchema]).superRefine((data, ctx) => {
446
+ const shouldUseTrue = condition(data);
447
+ const schema = shouldUseTrue ? trueSchema : falseSchema;
448
+ const result = schema.safeParse(data);
449
+ if (!result.success) {
450
+ ctx.addIssue({
451
+ code: z.ZodIssueCode.custom,
452
+ message: result.error.message
453
+ });
454
+ }
455
+ }),
456
+ transform: {
457
+ toLowerCase: z.string().transform((val) => val.toLowerCase()),
458
+ toUpperCase: z.string().transform((val) => val.toUpperCase()),
459
+ trim: z.string().transform((val) => val.trim()),
460
+ toNumber: z.string().transform((val) => Number(val)),
461
+ toBoolean: z.string().transform((val) => val === "true"),
462
+ parseJson: (schema) => z.string().transform((val, ctx) => {
463
+ try {
464
+ const parsed = JSON.parse(val);
465
+ const result = schema.safeParse(parsed);
466
+ if (result.success) return result.data;
467
+ ctx.addIssue({
468
+ code: z.ZodIssueCode.custom,
469
+ message: result.error.message
470
+ });
471
+ return z.NEVER;
472
+ } catch {
473
+ ctx.addIssue({
474
+ code: z.ZodIssueCode.custom,
475
+ message: "Invalid JSON"
476
+ });
477
+ return z.NEVER;
478
+ }
479
+ })
480
+ }
481
+ };
482
+
483
+ // src/utils/typeGuards.ts
484
+ function isRecord(value) {
485
+ return typeof value === "object" && value !== null && !Array.isArray(value);
486
+ }
487
+ function hasProperty(obj, key) {
488
+ return isRecord(obj) && key in obj;
489
+ }
490
+ function isNonEmptyString(value) {
491
+ return typeof value === "string" && value.length > 0;
492
+ }
493
+ function isArray2(value) {
494
+ return Array.isArray(value);
495
+ }
496
+ function isNonEmptyArray(value) {
497
+ return Array.isArray(value) && value.length > 0;
498
+ }
499
+ function isFunction(value) {
500
+ return typeof value === "function";
501
+ }
502
+ function isString(value) {
503
+ return typeof value === "string";
504
+ }
505
+ function isNumber(value) {
506
+ return typeof value === "number" && !isNaN(value);
507
+ }
508
+ function isBoolean(value) {
509
+ return typeof value === "boolean";
510
+ }
511
+ function isNull(value) {
512
+ return value === null;
513
+ }
514
+ function isUndefined(value) {
515
+ return value === void 0;
516
+ }
517
+ function isNullish(value) {
518
+ return value === null || value === void 0;
519
+ }
520
+ function isDefined(value) {
521
+ return value !== null && value !== void 0;
522
+ }
523
+ function isDate(value) {
524
+ return value instanceof Date && !isNaN(value.getTime());
525
+ }
526
+ function isPromise(value) {
527
+ return value instanceof Promise || isRecord(value) && typeof value.then === "function";
528
+ }
529
+ function isError(error) {
530
+ return error instanceof Error;
531
+ }
532
+ function matches(value, validator) {
533
+ return validator(value);
534
+ }
535
+
536
+ export {
537
+ IMAGE_EXTENSIONS,
538
+ DOCUMENT_EXTENSIONS,
539
+ ALL_FILE_EXTENSIONS,
540
+ isImageFile,
541
+ isImageMimeType,
542
+ formatFileSize,
543
+ flattenObjectKeys,
544
+ getTimezone,
545
+ handleServerErrors,
546
+ propertyExists,
547
+ readValueAsDate,
548
+ removeLeadingTrailingSlashes,
549
+ schemaTools,
550
+ isRecord,
551
+ hasProperty,
552
+ isNonEmptyString,
553
+ isArray2 as isArray,
554
+ isNonEmptyArray,
555
+ isFunction,
556
+ isString,
557
+ isNumber,
558
+ isBoolean,
559
+ isNull,
560
+ isUndefined,
561
+ isNullish,
562
+ isDefined,
563
+ isDate,
564
+ isPromise,
565
+ isError,
566
+ matches
567
+ };
568
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3V0aWxzL2ZpbGVVdGlscy50cyIsICIuLi9zcmMvdXRpbHMvZmxhdHRlbk9iamVjdEtleXMudHMiLCAiLi4vc3JjL3V0aWxzL2dldFRpbWV6b25lLnRzIiwgIi4uL3NyYy91dGlscy9oYW5kbGVTZXJ2ZXJFcnJvcnMudHMiLCAiLi4vc3JjL3V0aWxzL3Byb3BlcnR5RXhpc3RzLnRzIiwgIi4uL3NyYy91dGlscy9yZWFkVmFsdWVBc0RhdGUudHMiLCAiLi4vc3JjL3V0aWxzL3JlbW92ZUxlYWRpbmdUcmFpbGluZ1NsYXNoZXMudHMiLCAiLi4vc3JjL3V0aWxzL3NjaGVtYVRvb2xzLnRzIiwgIi4uL3NyYy91dGlscy90eXBlR3VhcmRzLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKiogQ2Fub25pY2FsIGltYWdlIGV4dGVuc2lvbnMgXHUyMDE0IG1hdGNoZXMgYmFja2VuZCBhcHBzZXR0aW5ncy5qc29uIEltYWdlcy5GaWxlVHlwZXMgKi9cbmV4cG9ydCBjb25zdCBJTUFHRV9FWFRFTlNJT05TID0gWycuanBnJywgJy5qcGVnJywgJy5wbmcnLCAnLmdpZicsICcud2VicCddIGFzIGNvbnN0O1xuXG4vKiogQ2Fub25pY2FsIGRvY3VtZW50IGV4dGVuc2lvbnMgXHUyMDE0IG1hdGNoZXMgYmFja2VuZCBhcHBzZXR0aW5ncy5qc29uIERvY3VtZW50cy5GaWxlVHlwZXMgKi9cbmV4cG9ydCBjb25zdCBET0NVTUVOVF9FWFRFTlNJT05TID0gWycucGRmJywgJy5kb2MnLCAnLmRvY3gnLCAnLnhscycsICcueGxzeCcsICcudHh0J10gYXMgY29uc3Q7XG5cbi8qKiBBbGwgYWxsb3dlZCBmaWxlIGV4dGVuc2lvbnMgKGltYWdlICsgZG9jdW1lbnQpICovXG5leHBvcnQgY29uc3QgQUxMX0ZJTEVfRVhURU5TSU9OUzogc3RyaW5nW10gPSBbLi4uSU1BR0VfRVhURU5TSU9OUywgLi4uRE9DVU1FTlRfRVhURU5TSU9OU107XG5cbmNvbnN0IElNQUdFX0VYVF9TRVQgPSBuZXcgU2V0PHN0cmluZz4oSU1BR0VfRVhURU5TSU9OUyk7XG5cbi8qKiBDaGVjayBpZiBhIEZpbGUgb2JqZWN0IGlzIGFuIGltYWdlIChNSU1FIHR5cGUgY2hlY2ssIGV4dGVuc2lvbiBmYWxsYmFjaykgKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0ltYWdlRmlsZShmaWxlOiBGaWxlKTogYm9vbGVhbiB7XG4gIGlmIChmaWxlLnR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJykpIHJldHVybiB0cnVlO1xuICBjb25zdCBleHQgPSAnLicgKyBmaWxlLm5hbWUuc3BsaXQoJy4nKS5wb3AoKT8udG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIElNQUdFX0VYVF9TRVQuaGFzKGV4dCk7XG59XG5cbi8qKiBDaGVjayBpZiBhIE1JTUUgdHlwZSBzdHJpbmcgaXMgYW4gaW1hZ2UgdHlwZSAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzSW1hZ2VNaW1lVHlwZShtaW1lVHlwZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBtaW1lVHlwZS5zdGFydHNXaXRoKCdpbWFnZS8nKTtcbn1cblxuLyoqIEZvcm1hdCBieXRlIGNvdW50IHRvIGh1bWFuLXJlYWRhYmxlIHN0cmluZyAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEZpbGVTaXplKGJ5dGVzOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAoYnl0ZXMgPT09IDApIHJldHVybiAnMCBCJztcbiAgY29uc3QgayA9IDEwMjQ7XG4gIGNvbnN0IHVuaXRzID0gWydCJywgJ0tCJywgJ01CJywgJ0dCJ107XG4gIGNvbnN0IGkgPSBNYXRoLmZsb29yKE1hdGgubG9nKGJ5dGVzKSAvIE1hdGgubG9nKGspKTtcbiAgcmV0dXJuIGAke3BhcnNlRmxvYXQoKGJ5dGVzIC8gTWF0aC5wb3coaywgaSkpLnRvRml4ZWQoMSkpfSAke3VuaXRzW2ldfWA7XG59XG4iLCAiLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhIG5lc3RlZCBvYmplY3QgKG5vdCBudWxsIGFuZCBub3QgYW4gYXJyYXkpLlxuICpcbiAqIEBwYXJhbSBvYmogLSBUaGUgdmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgbmVzdGVkIG9iamVjdFxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5jb25zdCBpc05lc3RlZCA9IChvYmo6IHVua25vd24pOiBvYmogaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPT4gXG4gIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgJiYgb2JqICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KG9iaik7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgYW4gYXJyYXkuXG4gKlxuICogQHBhcmFtIG9iaiAtIFRoZSB2YWx1ZSB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYW4gYXJyYXlcbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY29uc3QgaXNBcnJheSA9IChvYmo6IHVua25vd24pOiBvYmogaXMgdW5rbm93bltdID0+IEFycmF5LmlzQXJyYXkob2JqKTtcblxuLyoqXG4gKiBSZWN1cnNpdmVseSBmbGF0dGVucyBhbiBvYmplY3QgaW50byBhIGZsYXQgc3RydWN0dXJlIHdpdGggZG90LW5vdGF0aW9uIGtleXMuXG4gKlxuICogVGhpcyB1dGlsaXR5IGZ1bmN0aW9uIHRha2VzIGEgbmVzdGVkIG9iamVjdCBhbmQgY29udmVydHMgaXQgaW50byBhIGZsYXQgb2JqZWN0XG4gKiB3aGVyZSBuZXN0ZWQgcHJvcGVydGllcyBhcmUgcmVwcmVzZW50ZWQgdXNpbmcgZG90IG5vdGF0aW9uLiBJdCBoYW5kbGVzIGJvdGhcbiAqIG5lc3RlZCBvYmplY3RzIGFuZCBhcnJheXMsIHByZXNlcnZpbmcgYWxsIGxldmVscyBvZiB0aGUgb3JpZ2luYWwgc3RydWN0dXJlXG4gKiBhcyBzZXBhcmF0ZSBrZXlzIGluIHRoZSByZXN1bHQuXG4gKlxuICogQGV4YW1wbGVcbiAqIEJhc2ljIG9iamVjdCBmbGF0dGVuaW5nOlxuICogYGBgdHN4XG4gKiBjb25zdCBuZXN0ZWQgPSB7XG4gKiAgIHVzZXI6IHtcbiAqICAgICBuYW1lOiAnSm9obicsXG4gKiAgICAgYWRkcmVzczoge1xuICogICAgICAgY2l0eTogJ05ldyBZb3JrJyxcbiAqICAgICAgIHppcDogJzEwMDAxJ1xuICogICAgIH1cbiAqICAgfVxuICogfTtcbiAqXG4gKiBjb25zdCBmbGF0dGVuZWQgPSBmbGF0dGVuT2JqZWN0S2V5cyhuZXN0ZWQpO1xuICogLy8gUmVzdWx0OlxuICogLy8ge1xuICogLy8gICAndXNlcic6IHsgbmFtZTogJ0pvaG4nLCBhZGRyZXNzOiB7IGNpdHk6ICdOZXcgWW9yaycsIHppcDogJzEwMDAxJyB9IH0sXG4gKiAvLyAgICd1c2VyLm5hbWUnOiAnSm9obicsXG4gKiAvLyAgICd1c2VyLmFkZHJlc3MnOiB7IGNpdHk6ICdOZXcgWW9yaycsIHppcDogJzEwMDAxJyB9LFxuICogLy8gICAndXNlci5hZGRyZXNzLmNpdHknOiAnTmV3IFlvcmsnLFxuICogLy8gICAndXNlci5hZGRyZXNzLnppcCc6ICcxMDAwMSdcbiAqIC8vIH1cbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlXG4gKiBBcnJheSBoYW5kbGluZzpcbiAqIGBgYHRzeFxuICogY29uc3Qgd2l0aEFycmF5cyA9IHtcbiAqICAgaXRlbXM6IFtcbiAqICAgICB7IGlkOiAxLCBuYW1lOiAnSXRlbSAxJyB9LFxuICogICAgIHsgaWQ6IDIsIG5hbWU6ICdJdGVtIDInIH1cbiAqICAgXVxuICogfTtcbiAqXG4gKiBjb25zdCBmbGF0dGVuZWQgPSBmbGF0dGVuT2JqZWN0S2V5cyh3aXRoQXJyYXlzKTtcbiAqIC8vIFJlc3VsdCBpbmNsdWRlczpcbiAqIC8vIHtcbiAqIC8vICAgJ2l0ZW1zJzogWy4uLl0sXG4gKiAvLyAgICdpdGVtcy4wJzogeyBpZDogMSwgbmFtZTogJ0l0ZW0gMScgfSxcbiAqIC8vICAgJ2l0ZW1zLjAuaWQnOiAxLFxuICogLy8gICAnaXRlbXMuMC5uYW1lJzogJ0l0ZW0gMScsXG4gKiAvLyAgICdpdGVtcy4xJzogeyBpZDogMiwgbmFtZTogJ0l0ZW0gMicgfSxcbiAqIC8vICAgJ2l0ZW1zLjEuaWQnOiAyLFxuICogLy8gICAnaXRlbXMuMS5uYW1lJzogJ0l0ZW0gMidcbiAqIC8vIH1cbiAqIGBgYFxuICpcbiAqIEBwYXJhbSBvYmogLSBUaGUgb2JqZWN0IHRvIGZsYXR0ZW5cbiAqIEBwYXJhbSBwcmVmaXggLSBJbnRlcm5hbCBwYXJhbWV0ZXIgZm9yIGJ1aWxkaW5nIGtleSBwYXRocyAodXNlZCBpbiByZWN1cnNpb24pXG4gKiBAcmV0dXJucyBBIGZsYXQgb2JqZWN0IHdpdGggZG90LW5vdGF0aW9uIGtleXMgcmVwcmVzZW50aW5nIHRoZSBvcmlnaW5hbCBzdHJ1Y3R1cmVcbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBmbGF0dGVuT2JqZWN0S2V5cyA9IChvYmo6IHVua25vd24sIHByZWZpeCA9IFwiXCIpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9PiB7XG4gIGlmICghaXNOZXN0ZWQob2JqKSkge1xuICAgIHJldHVybiB7XG4gICAgICBbcHJlZml4XTogb2JqLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmtleXMob2JqKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgY29uc3QgY3VycmVudFByZWZpeCA9IHByZWZpeC5sZW5ndGggPyBgJHtwcmVmaXh9LmAgOiBcIlwiO1xuXG4gICAgaWYgKGlzTmVzdGVkKG9ialtrZXldKSAmJiBPYmplY3Qua2V5cyhvYmpba2V5XSkubGVuZ3RoKSB7XG4gICAgICBpZiAoaXNBcnJheShvYmpba2V5XSkgJiYgb2JqW2tleV0ubGVuZ3RoKSB7XG4gICAgICAgIG9ialtrZXldLmZvckVhY2goKGl0ZW0sIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICBPYmplY3QuYXNzaWduKFxuICAgICAgICAgICAgYWNjLFxuICAgICAgICAgICAgZmxhdHRlbk9iamVjdEtleXMoaXRlbSwgYCR7Y3VycmVudFByZWZpeCArIGtleX0uJHtpbmRleH1gKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihhY2MsIGZsYXR0ZW5PYmplY3RLZXlzKG9ialtrZXldLCBjdXJyZW50UHJlZml4ICsga2V5KSk7XG4gICAgICB9XG5cbiAgICAgIC8vIEV2ZW4gaWYgaXQncyBhIG5lc3RlZCBvYmplY3QsIGl0IHNob3VsZCBiZSB0cmVhdGVkIGFzIGEga2V5IGFzIHdlbGxcbiAgICAgIGFjY1tjdXJyZW50UHJlZml4ICsga2V5XSA9IG9ialtrZXldO1xuICAgIH0gZWxzZSB7XG4gICAgICBhY2NbY3VycmVudFByZWZpeCArIGtleV0gPSBvYmpba2V5XTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWNjO1xuICB9LCB7fSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik7XG59O1xuIiwgImltcG9ydCB0eXBlIHsgUGlja2VyVmFsaWREYXRlIH0gZnJvbSBcIkBtdWkveC1kYXRlLXBpY2tlcnNcIjtcbmltcG9ydCB0eXBlIHsgdXNlTG9jYWxpemF0aW9uQ29udGV4dCB9IGZyb20gXCJAbXVpL3gtZGF0ZS1waWNrZXJzL2ludGVybmFsc1wiO1xuaW1wb3J0IHR5cGUgeyBEYXlqcyB9IGZyb20gXCJkYXlqc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGltZXpvbmU8VERhdGUgZXh0ZW5kcyBQaWNrZXJWYWxpZERhdGU+KFxuICBhZGFwdGVyOiBSZXR1cm5UeXBlPHR5cGVvZiB1c2VMb2NhbGl6YXRpb25Db250ZXh0PixcbiAgdmFsdWU6IFREYXRlXG4pOiBzdHJpbmcgfCBudWxsIHtcbiAgcmV0dXJuIHZhbHVlID09IG51bGwgfHwgIWFkYXB0ZXIudXRpbHMuaXNWYWxpZCh2YWx1ZSBhcyB1bmtub3duIGFzIERheWpzKVxuICAgID8gbnVsbFxuICAgIDogYWRhcHRlci51dGlscy5nZXRUaW1lem9uZSh2YWx1ZSBhcyB1bmtub3duIGFzIERheWpzKTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEZpZWxkVmFsdWVzLCBQYXRoLCBVc2VGb3JtU2V0RXJyb3IgfSBmcm9tICdyZWFjdC1ob29rLWZvcm0nO1xuXG5pbXBvcnQgeyBmbGF0dGVuT2JqZWN0S2V5cyB9IGZyb20gJy4vZmxhdHRlbk9iamVjdEtleXMnO1xuXG5pbXBvcnQgdHlwZSB7IFZhbGlkYXRpb25FcnJvcnMgfSBmcm9tICdAL2NvcmUnO1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIGhhbmRsZVNlcnZlckVycm9ycyBmdW5jdGlvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVEZpZWxkVmFsdWVzIC0gVGhlIGZvcm0gdmFsdWVzIHR5cGVcbiAqXG4gKiBAcHVibGljXG4gKi9cbmludGVyZmFjZSBIYW5kbGVTZXJ2ZXJFcnJvcnNUeXBlPFxuICBURmllbGRWYWx1ZXMgZXh0ZW5kcyBGaWVsZFZhbHVlcyA9IEZpZWxkVmFsdWVzLFxuPiB7XG4gIC8qKlxuICAgKiBTZXJ2ZXIgdmFsaWRhdGlvbiBlcnJvcnMgb2JqZWN0IGNvbnRhaW5pbmcgZmllbGQtc3BlY2lmaWMgZXJyb3IgbWVzc2FnZXNcbiAgICogQGV4YW1wbGUgeyBlbWFpbDogJ0VtYWlsIGlzIGFscmVhZHkgdGFrZW4nLCBwYXNzd29yZDogWydUb28gc2hvcnQnLCAnTXVzdCBjb250YWluIG51bWJlcnMnXSB9XG4gICAqL1xuICBlcnJvcnM/OiBWYWxpZGF0aW9uRXJyb3JzO1xuICAvKipcbiAgICogVGhlIHNldEVycm9yIGZ1bmN0aW9uIGZyb20gcmVhY3QtaG9vay1mb3JtIGZvciBzZXR0aW5nIGZpZWxkIGVycm9yc1xuICAgKi9cbiAgc2V0RXJyb3I6IFVzZUZvcm1TZXRFcnJvcjxURmllbGRWYWx1ZXM+O1xufVxuXG4vKipcbiAqIFByb2Nlc3NlcyBzZXJ2ZXIgdmFsaWRhdGlvbiBlcnJvcnMgYW5kIGFwcGxpZXMgdGhlbSB0byByZWFjdC1ob29rLWZvcm0gZmllbGRzLlxuICpcbiAqIFRoaXMgdXRpbGl0eSBmdW5jdGlvbiB0YWtlcyB2YWxpZGF0aW9uIGVycm9ycyBmcm9tIGEgc2VydmVyIHJlc3BvbnNlIGFuZCBhdXRvbWF0aWNhbGx5XG4gKiBhcHBsaWVzIHRoZW0gdG8gdGhlIGNvcnJlc3BvbmRpbmcgZm9ybSBmaWVsZHMgdXNpbmcgcmVhY3QtaG9vay1mb3JtJ3Mgc2V0RXJyb3IgZnVuY3Rpb24uXG4gKiBJdCBzdXBwb3J0cyB2YXJpb3VzIGVycm9yIGZvcm1hdHMgaW5jbHVkaW5nIHN0cmluZ3MsIGFycmF5cyBvZiBzdHJpbmdzLCBhbmQgYm9vbGVhbiBmbGFncy5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gdXNlcyBvYmplY3QgZmxhdHRlbmluZyB0byBoYW5kbGUgbmVzdGVkIGVycm9yIHN0cnVjdHVyZXMgYW5kIGVuc3VyZXNcbiAqIHRoYXQgb25seSB2YWxpZCBmaWVsZCBwYXRocyBhcmUgcHJvY2Vzc2VkLlxuICpcbiAqIEBleGFtcGxlXG4gKiBCYXNpYyB1c2FnZSB3aXRoIHNlcnZlciByZXNwb25zZTpcbiAqIGBgYHRzeFxuICogY29uc3QgeyBzZXRFcnJvciB9ID0gdXNlRm9ybSgpO1xuICpcbiAqIHRyeSB7XG4gKiAgIGF3YWl0IHN1Ym1pdEZvcm0oZGF0YSk7XG4gKiB9IGNhdGNoIChlcnJvcikge1xuICogICBoYW5kbGVTZXJ2ZXJFcnJvcnMoe1xuICogICAgIGVycm9yczogZXJyb3IucmVzcG9uc2UuZGF0YS5lcnJvcnMsXG4gKiAgICAgc2V0RXJyb3JcbiAqICAgfSk7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZVxuICogV2l0aCBkaWZmZXJlbnQgZXJyb3IgZm9ybWF0czpcbiAqIGBgYHRzeFxuICogY29uc3Qgc2VydmVyRXJyb3JzID0ge1xuICogICBlbWFpbDogJ0VtYWlsIGlzIGFscmVhZHkgdGFrZW4nLFxuICogICBwYXNzd29yZDogWydUb28gc2hvcnQnLCAnTXVzdCBjb250YWluIG51bWJlcnMnXSxcbiAqICAgdGVybXM6IHRydWUgLy8gQm9vbGVhbiBmbGFnIGluZGljYXRpbmcgaW52YWxpZFxuICogfTtcbiAqXG4gKiBoYW5kbGVTZXJ2ZXJFcnJvcnMoeyBlcnJvcnM6IHNlcnZlckVycm9ycywgc2V0RXJyb3IgfSk7XG4gKiAvLyBSZXN1bHRzIGluOlxuICogLy8gLSBlbWFpbCBmaWVsZCBzaG93czogXCJFbWFpbCBpcyBhbHJlYWR5IHRha2VuXCJcbiAqIC8vIC0gcGFzc3dvcmQgZmllbGQgc2hvd3M6IFwiVG9vIHNob3J0IE11c3QgY29udGFpbiBudW1iZXJzXCJcbiAqIC8vIC0gdGVybXMgZmllbGQgc2hvd3M6IFwiRmllbGQgaXMgbm90IHZhbGlkLlwiXG4gKiBgYGBcbiAqXG4gKiBAdGVtcGxhdGUgVEZpZWxkVmFsdWVzIC0gVGhlIGZvcm0gdmFsdWVzIHR5cGVcbiAqXG4gKiBAcGFyYW0gYXJncyAtIENvbmZpZ3VyYXRpb24gb2JqZWN0IGNvbnRhaW5pbmcgZXJyb3JzIGFuZCBzZXRFcnJvciBmdW5jdGlvblxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IGhhbmRsZVNlcnZlckVycm9ycyA9IGZ1bmN0aW9uIGhhbmRsZVNlcnZlckVycm9yczxcbiAgVEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXMgPSBGaWVsZFZhbHVlcyxcbj4oYXJnczogSGFuZGxlU2VydmVyRXJyb3JzVHlwZTxURmllbGRWYWx1ZXM+KSB7XG4gIGNvbnN0IHsgZXJyb3JzLCBzZXRFcnJvciB9ID0gYXJncztcblxuICBmb3IgKGNvbnN0IGtleSBpbiBlcnJvcnMpIHtcbiAgICBjb25zdCBpc0tleUluVmFyaWFibGVzID0gT2JqZWN0LmtleXMoZmxhdHRlbk9iamVjdEtleXMoZXJyb3JzKSkuaW5jbHVkZXMoXG4gICAgICBrZXlcbiAgICApO1xuXG4gICAgaWYgKCFpc0tleUluVmFyaWFibGVzKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWVsZEVycm9yID0gZXJyb3JzW2tleV07XG5cbiAgICBsZXQgZXJyb3JNZXNzYWdlID0gJyc7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZEVycm9yKSkge1xuICAgICAgZXJyb3JNZXNzYWdlID0gZmllbGRFcnJvci5qb2luKCcgJyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBmaWVsZEVycm9yID09PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3JNZXNzYWdlID0gZmllbGRFcnJvcjtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGZpZWxkRXJyb3IgPT09ICdib29sZWFuJyAmJiBmaWVsZEVycm9yKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgPSAnRmllbGQgaXMgbm90IHZhbGlkLic7XG4gICAgfVxuXG4gICAgc2V0RXJyb3Ioa2V5IGFzIFBhdGg8VEZpZWxkVmFsdWVzPiwge1xuICAgICAgbWVzc2FnZTogZXJyb3JNZXNzYWdlLFxuICAgIH0pO1xuICB9XG59O1xuIiwgIi8qKlxuICogVHlwZS1zYWZlIHByb3BlcnR5IGV4aXN0ZW5jZSBjaGVja2VyIHRoYXQgYWN0cyBhcyBhIHR5cGUgZ3VhcmQuXG4gKlxuICogQ2hlY2tzIGlmIGEgZ2l2ZW4gcHJvcGVydHkgZXhpc3RzIG9uIGFuIG9iamVjdCBhbmQgbmFycm93cyB0aGUgVHlwZVNjcmlwdCB0eXBlXG4gKiB0byBpbmNsdWRlIHRoYXQgcHJvcGVydHkuIFRoaXMgaXMgdXNlZnVsIGZvciBzYWZlbHkgYWNjZXNzaW5nIHByb3BlcnRpZXMgb25cbiAqIG9iamVjdHMgb2YgdW5rbm93biBzdHJ1Y3R1cmUgd2hpbGUgbWFpbnRhaW5pbmcgdHlwZSBzYWZldHkuXG4gKlxuICogQHRlbXBsYXRlIFggLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0IGJlaW5nIGNoZWNrZWRcbiAqIEB0ZW1wbGF0ZSBZIC0gVGhlIHR5cGUgb2YgdGhlIHByb3BlcnR5IGtleSAoZXh0ZW5kcyBQcm9wZXJ0eUtleSlcbiAqXG4gKiBAcGFyYW0gb2JqIC0gVGhlIG9iamVjdCB0byBjaGVjayBmb3IgdGhlIHByb3BlcnR5XG4gKiBAcGFyYW0gcHJvcCAtIFRoZSBwcm9wZXJ0eSBrZXkgdG8gY2hlY2sgZm9yIGV4aXN0ZW5jZVxuICpcbiAqIEByZXR1cm5zIEEgdHlwZSBwcmVkaWNhdGUgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBwcm9wZXJ0eSBleGlzdHMgb24gdGhlIG9iamVjdC5cbiAqICAgICAgICAgIElmIHRydWUsIHRoZSBvYmplY3QgdHlwZSBpcyBuYXJyb3dlZCB0byBpbmNsdWRlIHRoZSBzcGVjaWZpZWQgcHJvcGVydHkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGRhdGE6IHVua25vd24gPSB7IG5hbWU6IFwiSm9oblwiLCBhZ2U6IDMwIH07XG4gKlxuICogaWYgKHByb3BlcnR5RXhpc3RzKGRhdGEsIFwibmFtZVwiKSkge1xuICogICAvLyBUeXBlU2NyaXB0IG5vdyBrbm93cyBkYXRhIGhhcyBhICduYW1lJyBwcm9wZXJ0eVxuICogICBjb25zb2xlLmxvZyhkYXRhLm5hbWUpOyAvLyBUeXBlLXNhZmUgYWNjZXNzXG4gKiB9XG4gKlxuICogLy8gQ2hlY2sgZm9yIG5lc3RlZCBwcm9wZXJ0eSBleGlzdGVuY2VcbiAqIGlmIChwcm9wZXJ0eUV4aXN0cyhvYmosIFwidXNlclwiKSAmJiBwcm9wZXJ0eUV4aXN0cyhvYmoudXNlciwgXCJpZFwiKSkge1xuICogICBjb25zb2xlLmxvZyhvYmoudXNlci5pZCk7IC8vIFNhZmUgbmVzdGVkIGFjY2Vzc1xuICogfVxuICogYGBgXG4gKlxuICogQHNpbmNlIDIuMTguNDVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb3BlcnR5RXhpc3RzPFgsIFkgZXh0ZW5kcyBQcm9wZXJ0eUtleT4oXG4gIG9iajogWCxcbiAgcHJvcDogWVxuKTogb2JqIGlzIFggJiBSZWNvcmQ8WSwgdW5rbm93bj4ge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmXG4gICAgb2JqICE9PSBudWxsICYmXG4gICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcClcbiAgKTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7IFBpY2tlclZhbGlkRGF0ZSB9IGZyb20gXCJAbXVpL3gtZGF0ZS1waWNrZXJzXCI7XG5pbXBvcnQgdHlwZSB7IHVzZUxvY2FsaXphdGlvbkNvbnRleHQgfSBmcm9tIFwiQG11aS94LWRhdGUtcGlja2Vycy9pbnRlcm5hbHNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlYWRWYWx1ZUFzRGF0ZTxURGF0ZSBleHRlbmRzIFBpY2tlclZhbGlkRGF0ZT4oXG4gIGFkYXB0ZXI6IFJldHVyblR5cGU8dHlwZW9mIHVzZUxvY2FsaXphdGlvbkNvbnRleHQ+LFxuICB2YWx1ZTogc3RyaW5nIHwgbnVsbCB8IFREYXRlXG4pOiBURGF0ZSB8IG51bGwge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgaWYgKHZhbHVlID09PSBcIlwiKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gYWRhcHRlci51dGlscy5kYXRlKHZhbHVlKSBhcyBURGF0ZTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZTtcbn1cbiIsICJleHBvcnQgY29uc3QgcmVtb3ZlTGVhZGluZ1RyYWlsaW5nU2xhc2hlcyA9IChyb3V0ZTogc3RyaW5nKSA9PiB7XG4gIHJldHVybiByb3V0ZS5yZXBsYWNlKC9eXFwvfFxcLyQvZywgXCJcIik7XG59O1xuIiwgImltcG9ydCBkYXlqcyBmcm9tICdkYXlqcyc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcbmltcG9ydCB7IElNQUdFX0VYVEVOU0lPTlMsIERPQ1VNRU5UX0VYVEVOU0lPTlMgfSBmcm9tICcuL2ZpbGVVdGlscyc7XG5cbi8vIEhlbHBlciBmdW5jdGlvbiBmb3IgTHVobiBhbGdvcml0aG0gdmFsaWRhdGlvblxuZnVuY3Rpb24gaXNWYWxpZEx1aG4odmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBpZiAoIXZhbHVlIHx8IHZhbHVlLnRyaW0oKSA9PT0gJycpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBudW1iZXIgPSB2YWx1ZS5yZXBsYWNlKC9bXFxzLV0vZywgJycpO1xuXG4gIGlmICghL15cXGQrJC8udGVzdChudW1iZXIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKG51bWJlci5sZW5ndGggPCAxMyB8fCBudW1iZXIubGVuZ3RoID4gMTkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBsZXQgc3VtID0gMDtcbiAgbGV0IGFsdGVybmF0ZSA9IGZhbHNlO1xuXG4gIGZvciAobGV0IGkgPSBudW1iZXIubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBsZXQgZGlnaXQgPSBwYXJzZUludChudW1iZXIuY2hhckF0KGkpLCAxMCk7XG5cbiAgICBpZiAoYWx0ZXJuYXRlKSB7XG4gICAgICBkaWdpdCAqPSAyO1xuICAgICAgaWYgKGRpZ2l0ID4gOSkge1xuICAgICAgICBkaWdpdCAtPSA5O1xuICAgICAgfVxuICAgIH1cblxuICAgIHN1bSArPSBkaWdpdDtcbiAgICBhbHRlcm5hdGUgPSAhYWx0ZXJuYXRlO1xuICB9XG5cbiAgcmV0dXJuIHN1bSAlIDEwID09PSAwO1xufVxuXG5leHBvcnQgY29uc3Qgc2NoZW1hVG9vbHMgPSB7XG4gIC8vIERhdGUgdmFsaWRhdGlvbnNcbiAgZGF0ZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHouY29lcmNlXG4gICAgICAuc3RyaW5nKClcbiAgICAgIC50cmFuc2Zvcm0oYyA9PiAoYyA9PT0gJ251bGwnIHx8IGMgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IGMpKVxuICAgICAgLnJlZmluZShjID0+ICEhYywgeyBtZXNzYWdlOiBtZXNzYWdlIHx8ICdEYXRlIGlzIHJlcXVpcmVkJyB9KVxuICAgICAgLnJlZmluZShjID0+IChjID8gZGF5anMoYykuaXNWYWxpZCgpIDogdHJ1ZSksIHtcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSB8fCAnSW52YWxpZCBkYXRlJyxcbiAgICAgIH0pLFxuXG4gIG51bGxhYmxlRGF0ZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHouY29lcmNlXG4gICAgICAuc3RyaW5nKClcbiAgICAgIC50cmFuc2Zvcm0oYyA9PiAoYyA9PT0gJ251bGwnID8gbnVsbCA6IGMpKVxuICAgICAgLnRyYW5zZm9ybShjID0+IChjID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiBjKSlcbiAgICAgIC5yZWZpbmUoYyA9PiAoIWMgJiYgYyAhPT0gbnVsbCA/IGRheWpzKGMpLmlzVmFsaWQoKSA6IHRydWUpLCB7XG4gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UgfHwgJ0ludmFsaWQgZGF0ZScsXG4gICAgICB9KSxcblxuICBwYXN0RGF0ZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHouY29lcmNlLmRhdGUoKS5yZWZpbmUoZGF0ZSA9PiBkYXRlIDwgbmV3IERhdGUoKSwge1xuICAgICAgbWVzc2FnZTogbWVzc2FnZSB8fCAnTXVzdCBiZSBhIHBhc3QgZGF0ZScsXG4gICAgfSksXG5cbiAgZnV0dXJlRGF0ZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHouY29lcmNlLmRhdGUoKS5yZWZpbmUoZGF0ZSA9PiBkYXRlID4gbmV3IERhdGUoKSwge1xuICAgICAgbWVzc2FnZTogbWVzc2FnZSB8fCAnTXVzdCBiZSBhIGZ1dHVyZSBkYXRlJyxcbiAgICB9KSxcblxuICB0b2RheU9yRnV0dXJlRGF0ZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHouY29lcmNlLmRhdGUoKS5yZWZpbmUoXG4gICAgICBkYXRlID0+IHtcbiAgICAgICAgY29uc3QgdG9kYXkgPSBuZXcgRGF0ZSgpO1xuXG4gICAgICAgIHRvZGF5LnNldEhvdXJzKDAsIDAsIDAsIDApO1xuXG4gICAgICAgIHJldHVybiBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApID49IHRvZGF5LmdldFRpbWUoKTtcbiAgICAgIH0sXG4gICAgICB7IG1lc3NhZ2U6IG1lc3NhZ2UgfHwgJ011c3QgYmUgdG9kYXkgb3IgYSBmdXR1cmUgZGF0ZScgfVxuICAgICksXG5cbiAgdG9kYXlPclBhc3REYXRlOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgei5jb2VyY2UuZGF0ZSgpLnJlZmluZShcbiAgICAgIGRhdGUgPT4ge1xuICAgICAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XG5cbiAgICAgICAgdG9kYXkuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG5cbiAgICAgICAgcmV0dXJuIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCkgPD0gdG9kYXkuZ2V0VGltZSgpO1xuICAgICAgfSxcbiAgICAgIHsgbWVzc2FnZTogbWVzc2FnZSB8fCAnTXVzdCBiZSB0b2RheSBvciBhIHBhc3QgZGF0ZScgfVxuICAgICksXG5cbiAgYWR1bHQ6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6LmNvZXJjZS5kYXRlKCkucmVmaW5lKFxuICAgICAgZGF0ZSA9PiB7XG4gICAgICAgIGNvbnN0IGVpZ2h0ZWVuWWVhcnNBZ28gPSBuZXcgRGF0ZSgpO1xuXG4gICAgICAgIGVpZ2h0ZWVuWWVhcnNBZ28uc2V0RnVsbFllYXIoZWlnaHRlZW5ZZWFyc0Fnby5nZXRGdWxsWWVhcigpIC0gMTgpO1xuICAgICAgICBlaWdodGVlblllYXJzQWdvLnNldEhvdXJzKDAsIDAsIDAsIDApOyAvLyBOb3JtYWxpemUgdG8gc3RhcnQgb2YgZGF5XG4gICAgICAgIGNvbnN0IGRvYiA9IG5ldyBEYXRlKGRhdGUpO1xuXG4gICAgICAgIGRvYi5zZXRIb3VycygwLCAwLCAwLCAwKTsgLy8gTm9ybWFsaXplIHRvIHN0YXJ0IG9mIGRheVxuXG4gICAgICAgIHJldHVybiBkb2IgPD0gZWlnaHRlZW5ZZWFyc0FnbztcbiAgICAgIH0sXG4gICAgICB7IG1lc3NhZ2U6IG1lc3NhZ2UgfHwgJ011c3QgYmUgYXQgbGVhc3QgMTggeWVhcnMgb2xkJyB9XG4gICAgKSxcblxuICBtaW5pbXVtQWdlOiAoe1xuICAgIG1lc3NhZ2UsXG4gICAgbWluaW11bUFnZSxcbiAgfTogeyBtZXNzYWdlPzogc3RyaW5nOyBtaW5pbXVtQWdlPzogbnVtYmVyIH0gPSB7fSkgPT5cbiAgICB6LmNvZXJjZS5kYXRlKCkucmVmaW5lKFxuICAgICAgZGF0ZSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgbWluaW11bUFnZSAhPT0gJ251bWJlcicpIHJldHVybiBmYWxzZTtcbiAgICAgICAgY29uc3QgbWluWWVhcnNBZ28gPSBuZXcgRGF0ZSgpO1xuXG4gICAgICAgIG1pblllYXJzQWdvLnNldEZ1bGxZZWFyKG1pblllYXJzQWdvLmdldEZ1bGxZZWFyKCkgLSBtaW5pbXVtQWdlKTtcbiAgICAgICAgbWluWWVhcnNBZ28uc2V0SG91cnMoMCwgMCwgMCwgMCk7IC8vIE5vcm1hbGl6ZSB0byBzdGFydCBvZiBkYXlcbiAgICAgICAgY29uc3QgZG9iID0gbmV3IERhdGUoZGF0ZSk7XG5cbiAgICAgICAgZG9iLnNldEhvdXJzKDAsIDAsIDAsIDApOyAvLyBOb3JtYWxpemUgdG8gc3RhcnQgb2YgZGF5XG5cbiAgICAgICAgcmV0dXJuIGRvYiA8PSBtaW5ZZWFyc0FnbztcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgbWVzc2FnZSB8fFxuICAgICAgICAgIGBNdXN0IGJlIGF0IGxlYXN0ICR7bWluaW11bUFnZSA/PyAndGhlIHJlcXVpcmVkJ30geWVhcnMgb2xkYCxcbiAgICAgIH1cbiAgICApLFxuXG4gIHdpdGhpbkRheXM6ICh7IG1lc3NhZ2UsIGRheXMgfTogeyBtZXNzYWdlPzogc3RyaW5nOyBkYXlzPzogbnVtYmVyIH0gPSB7fSkgPT5cbiAgICB6LmNvZXJjZS5kYXRlKCkucmVmaW5lKFxuICAgICAgZGF0ZSA9PiB7XG4gICAgICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcblxuICAgICAgICB0b2RheS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgICAgICAgY29uc3QgaW5wdXREYXRlID0gbmV3IERhdGUoZGF0ZSk7XG5cbiAgICAgICAgaW5wdXREYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xuXG4gICAgICAgIGNvbnN0IGRpZmZUaW1lID0gTWF0aC5hYnMoaW5wdXREYXRlLmdldFRpbWUoKSAtIHRvZGF5LmdldFRpbWUoKSk7XG4gICAgICAgIGNvbnN0IGRpZmZEYXlzID0gTWF0aC5jZWlsKGRpZmZUaW1lIC8gKDEwMDAgKiA2MCAqIDYwICogMjQpKTsgLy8gQ29udmVydCBtaWxsaXNlY29uZHMgdG8gZGF5c1xuXG4gICAgICAgIHJldHVybiB0eXBlb2YgZGF5cyA9PT0gJ251bWJlcicgPyBkaWZmRGF5cyA8PSBkYXlzIDogZmFsc2U7XG4gICAgICB9LFxuICAgICAgeyBtZXNzYWdlOiBtZXNzYWdlIHx8IGBNdXN0IGJlIHdpdGhpbiAke2RheXN9IGRheXMgb2YgdG9kYXlgIH1cbiAgICApLFxuXG4gIHdlZWtkYXk6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6LmNvZXJjZS5kYXRlKCkucmVmaW5lKFxuICAgICAgZGF0ZSA9PiB7XG4gICAgICAgIGNvbnN0IGRheSA9IGRhdGUuZ2V0RGF5KCk7IC8vIDAgPSBTdW5kYXksIDEgPSBNb25kYXksIC4uLiwgNiA9IFNhdHVyZGF5XG5cbiAgICAgICAgcmV0dXJuIGRheSAhPT0gMCAmJiBkYXkgIT09IDY7XG4gICAgICB9LFxuICAgICAgeyBtZXNzYWdlOiBtZXNzYWdlIHx8ICdNdXN0IGJlIGEgd2Vla2RheScgfVxuICAgICksXG5cbiAgZGF0ZVJhbmdlOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLm9iamVjdCh7XG4gICAgICAgIHN0YXJ0OiB6LmNvZXJjZS5kYXRlKCksXG4gICAgICAgIGVuZDogei5jb2VyY2UuZGF0ZSgpLFxuICAgICAgfSlcbiAgICAgIC5yZWZpbmUoZGF0YSA9PiBkYXRhLnN0YXJ0IDw9IGRhdGEuZW5kLCB7XG4gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UgfHwgJ1N0YXJ0IGRhdGUgbXVzdCBiZSBiZWZvcmUgb3IgZXF1YWwgdG8gZW5kIGRhdGUnLFxuICAgICAgfSksXG5cbiAgdGltZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHouY29lcmNlXG4gICAgICAuZGF0ZSgpXG4gICAgICAudHJhbnNmb3JtKGMgPT4gKGMgPT09IG51bGwgfHwgYyA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGMpKVxuICAgICAgLnJlZmluZShjID0+ICEhYywgeyBtZXNzYWdlOiBtZXNzYWdlIHx8ICdUaW1lIGlzIHJlcXVpcmVkJyB9KVxuICAgICAgLnJlZmluZShjID0+IChjID8gZGF5anMoYykuaXNWYWxpZCgpIDogdHJ1ZSksIHtcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSB8fCAnSW52YWxpZCB0aW1lJyxcbiAgICAgIH0pLFxuXG4gIGRhdGVUaW1lOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgei5jb2VyY2VcbiAgICAgIC5kYXRlKClcbiAgICAgIC50cmFuc2Zvcm0oYyA9PiAoYyA9PT0gbnVsbCB8fCBjID09PSB1bmRlZmluZWQgPyBudWxsIDogYykpXG4gICAgICAucmVmaW5lKGMgPT4gISFjLCB7IG1lc3NhZ2U6IG1lc3NhZ2UgfHwgJ0RhdGUgYW5kIFRpbWUgaXMgcmVxdWlyZWQnIH0pXG4gICAgICAucmVmaW5lKGMgPT4gKGMgPyBkYXlqcyhjKS5pc1ZhbGlkKCkgOiB0cnVlKSwge1xuICAgICAgICBtZXNzYWdlOiBtZXNzYWdlIHx8ICdJbnZhbGlkIERhdGUgYW5kIFRpbWUnLFxuICAgICAgfSksXG5cbiAgLy8gU3RyaW5nIHZhbGlkYXRpb25zXG4gIHJlcXVpcmVkU3RyaW5nOiAoe1xuICAgIG1lc3NhZ2UsXG4gICAgbWluLFxuICAgIG1heCxcbiAgfTogeyBtZXNzYWdlPzogc3RyaW5nOyBtaW4/OiBudW1iZXI7IG1heD86IG51bWJlciB9ID0ge30pID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAudHJpbSgpXG4gICAgICAubWluKFxuICAgICAgICBtaW4gfHwgMSxcbiAgICAgICAgbWVzc2FnZSB8fCBgU3RyaW5nIG11c3QgYmUgYXQgbGVhc3QgJHttaW4gfHwgMX0gY2hhcmFjdGVyc2BcbiAgICAgIClcbiAgICAgIC5tYXgoXG4gICAgICAgIG1heCB8fCAyNTUsXG4gICAgICAgIG1lc3NhZ2UgfHwgYFN0cmluZyBtdXN0IGJlIGF0IG1vc3QgJHttYXggfHwgMjU1fSBjaGFyYWN0ZXJzYFxuICAgICAgKSxcblxuICBlbWFpbDogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLmVtYWlsKG1lc3NhZ2UgfHwgJ0ludmFsaWQgZW1haWwgYWRkcmVzcycpXG4gICAgICAubWF4KDI1NCwgJ0VtYWlsIG11c3QgYmUgYXQgbW9zdCAyNTQgY2hhcmFjdGVycycpLFxuXG4gIHVybDogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHouc3RyaW5nKCkudXJsKG1lc3NhZ2UgfHwgJ0ludmFsaWQgVVJMIGZvcm1hdCcpLFxuXG4gIHBob25lOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAucmVnZXgoL15bK10/WzEtOV1bXFxkXXswLDE1fSQvLCBtZXNzYWdlIHx8ICdJbnZhbGlkIHBob25lIG51bWJlciBmb3JtYXQnKSxcblxuICBjcmVkaXRDYXJkOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgei5zdHJpbmcoKS5yZWZpbmUodmFsdWUgPT4gaXNWYWxpZEx1aG4odmFsdWUpLCB7XG4gICAgICBtZXNzYWdlOiBtZXNzYWdlIHx8ICdNdXN0IGJlIGEgdmFsaWQgY3JlZGl0IGNhcmQgbnVtYmVyJyxcbiAgICB9KSxcblxuICBpbmRpYW5Nb2JpbGU6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5yZWdleCgvXls2LTldXFxkezl9JC8sIG1lc3NhZ2UgfHwgJ011c3QgYmUgYSB2YWxpZCBJbmRpYW4gbW9iaWxlIG51bWJlcicpLFxuXG4gIGludGVybmF0aW9uYWxQaG9uZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLnJlZ2V4KFxuICAgICAgICAvXlxcKz9bMS05XVxcZHs2LDE0fSQvLFxuICAgICAgICBtZXNzYWdlIHx8ICdNdXN0IGJlIGEgdmFsaWQgaW50ZXJuYXRpb25hbCBwaG9uZSBudW1iZXInXG4gICAgICApLFxuXG4gIGFscGhhYmV0aWM6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5yZWdleChcbiAgICAgICAgL15bQS1aYS16LCBdKyQvLFxuICAgICAgICBtZXNzYWdlIHx8ICdNdXN0IGNvbnRhaW4gb25seSBsZXR0ZXJzLCBjb21tYXMsIGFuZCBzcGFjZXMnXG4gICAgICApLFxuXG4gIGd1aWQ6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6LnN0cmluZygpLnV1aWQobWVzc2FnZSB8fCAnTXVzdCBiZSBhIHZhbGlkIEdVSUQnKSxcblxuICBub25FbXB0eU9yV2hpdGVzcGFjZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLnRyaW0oKVxuICAgICAgLm1pbigxLCBtZXNzYWdlIHx8ICdNdXN0IG5vdCBiZSBlbXB0eSBvciB3aGl0ZXNwYWNlJyksXG5cbiAgdXNlcm5hbWU6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5yZWdleChcbiAgICAgICAgL15bYS16QS1aXVthLXpBLVowLTlfXXsyLDI5fSQvLFxuICAgICAgICBtZXNzYWdlIHx8XG4gICAgICAgICAgJ011c3QgYmUgMy0zMCBjaGFyYWN0ZXJzLCBzdGFydCB3aXRoIGEgbGV0dGVyLCBhbmQgY29udGFpbiBvbmx5IGxldHRlcnMsIG51bWJlcnMsIGFuZCB1bmRlcnNjb3JlcydcbiAgICAgICksXG5cbiAgZXhhY3RMZW5ndGg6ICh7XG4gICAgbWVzc2FnZSxcbiAgICBsZW5ndGgsXG4gIH06IHsgbWVzc2FnZT86IHN0cmluZzsgbGVuZ3RoPzogbnVtYmVyIH0gPSB7fSkgPT4ge1xuICAgIGlmICh0eXBlb2YgbGVuZ3RoICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdMZW5ndGggbXVzdCBiZSBwcm92aWRlZCBmb3IgZXhhY3RMZW5ndGggdmFsaWRhdG9yJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLmxlbmd0aChsZW5ndGgsIG1lc3NhZ2UgfHwgYE11c3QgYmUgZXhhY3RseSAke2xlbmd0aH0gY2hhcmFjdGVyc2ApO1xuICB9LFxuXG4gIG1pbldvcmRzOiAoe1xuICAgIG1lc3NhZ2UsXG4gICAgbWluV29yZHMsXG4gIH06IHsgbWVzc2FnZT86IHN0cmluZzsgbWluV29yZHM/OiBudW1iZXIgfSA9IHt9KSA9PlxuICAgIHouc3RyaW5nKCkucmVmaW5lKFxuICAgICAgdmFsdWUgPT4ge1xuICAgICAgICBpZiAoIXZhbHVlKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY29uc3Qgd29yZHMgPSB2YWx1ZS5zcGxpdCgvW1xcc1xcdFxcblxccl0rLykuZmlsdGVyKEJvb2xlYW4pO1xuXG4gICAgICAgIHJldHVybiB3b3Jkcy5sZW5ndGggPj0gKHR5cGVvZiBtaW5Xb3JkcyA9PT0gJ251bWJlcicgPyBtaW5Xb3JkcyA6IDApO1xuICAgICAgfSxcbiAgICAgIHsgbWVzc2FnZTogbWVzc2FnZSB8fCBgTXVzdCBoYXZlIGF0IGxlYXN0ICR7bWluV29yZHN9IHdvcmQocylgIH1cbiAgICApLFxuXG4gIG1heFdvcmRzOiAoe1xuICAgIG1lc3NhZ2UsXG4gICAgbWF4V29yZHMsXG4gIH06IHsgbWVzc2FnZT86IHN0cmluZzsgbWF4V29yZHM/OiBudW1iZXIgfSA9IHt9KSA9PlxuICAgIHouc3RyaW5nKCkucmVmaW5lKFxuICAgICAgdmFsdWUgPT4ge1xuICAgICAgICBpZiAoIXZhbHVlKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY29uc3Qgd29yZHMgPSB2YWx1ZS5zcGxpdCgvW1xcc1xcdFxcblxccl0rLykuZmlsdGVyKEJvb2xlYW4pO1xuXG4gICAgICAgIHJldHVybiB3b3Jkcy5sZW5ndGggPD0gKHR5cGVvZiBtYXhXb3JkcyA9PT0gJ251bWJlcicgPyBtYXhXb3JkcyA6IDApO1xuICAgICAgfSxcbiAgICAgIHsgbWVzc2FnZTogbWVzc2FnZSB8fCBgTXVzdCBoYXZlIGF0IG1vc3QgJHttYXhXb3Jkc30gd29yZChzKWAgfVxuICAgICksXG5cbiAgc3Ryb25nUGFzc3dvcmQ6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5yZWdleChcbiAgICAgICAgL14oPz0uKlthLXpdKSg/PS4qW0EtWl0pKD89LipcXGQpKD89LipbQCQhJSo/Jl0pW0EtWmEtelxcZEAkISUqPyZdezgsfSQvLFxuICAgICAgICBtZXNzYWdlIHx8XG4gICAgICAgICAgJ011c3QgYmUgYXQgbGVhc3QgOCBjaGFyYWN0ZXJzIGFuZCBjb250YWluIHVwcGVyY2FzZSwgbG93ZXJjYXNlLCBudW1iZXIsIGFuZCBzcGVjaWFsIGNoYXJhY3RlcidcbiAgICAgICksXG5cbiAgbm9IdG1sOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAucmVmaW5lKFxuICAgICAgICB2YWx1ZSA9PiAhdmFsdWUgfHwgIS88W14+XSo+Ly50ZXN0KHZhbHVlKSxcbiAgICAgICAgbWVzc2FnZSB8fCAnTXVzdCBub3QgY29udGFpbiBIVE1MIHRhZ3MnXG4gICAgICApLFxuXG4gIG5vU2NyaXB0SW5qZWN0aW9uOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAucmVmaW5lKFxuICAgICAgICB2YWx1ZSA9PiAhdmFsdWUgfHwgIS88c2NyaXB0fGphdmFzY3JpcHQ6fG9uXFx3K1xccyo9L2kudGVzdCh2YWx1ZSksXG4gICAgICAgIG1lc3NhZ2UgfHwgJ0NvbnRhaW5zIHBvdGVudGlhbGx5IHVuc2FmZSBjb250ZW50J1xuICAgICAgKSxcblxuICBub1NxbEluamVjdGlvbjogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLnJlZmluZShcbiAgICAgICAgdmFsdWUgPT5cbiAgICAgICAgICAhdmFsdWUgfHxcbiAgICAgICAgICAhLygnfC0tfDt8XFxiKFNFTEVDVHxJTlNFUlR8VVBEQVRFfERFTEVURXxEUk9QfFVOSU9OfEFMVEVSfENSRUFURXxFWEVDfEVYRUNVVEUpXFxiKS9pLnRlc3QoXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICksXG4gICAgICAgIG1lc3NhZ2UgfHwgJ0NvbnRhaW5zIHBvdGVudGlhbGx5IHVuc2FmZSBjb250ZW50J1xuICAgICAgKSxcblxuICBpbmRpYW5QaW5Db2RlOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAucmVnZXgoL15bMS05XVswLTldezV9JC8sIG1lc3NhZ2UgfHwgJ011c3QgYmUgYSB2YWxpZCA2LWRpZ2l0IFBJTiBjb2RlJyksXG5cbiAgdXNaaXBDb2RlOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAucmVnZXgoL15cXGR7NX0oLVxcZHs0fSk/JC8sIG1lc3NhZ2UgfHwgJ011c3QgYmUgYSB2YWxpZCBVUyBaSVAgY29kZScpLFxuXG4gIHVrUG9zdGFsQ29kZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLnJlZ2V4KFxuICAgICAgICAvXltBLVpdezEsMn1bMC05XVswLTlBLVpdP1xccz9bMC05XVtBLVpdezJ9JC9pLFxuICAgICAgICBtZXNzYWdlIHx8ICdNdXN0IGJlIGEgdmFsaWQgVUsgcG9zdGFsIGNvZGUnXG4gICAgICApLFxuXG4gIGlwdjQ6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5yZWdleChcbiAgICAgICAgL14oKDI1WzAtNV18MlswLTRdWzAtOV18WzAxXT9bMC05XVswLTldPylcXC4pezN9KDI1WzAtNV18MlswLTRdWzAtOV18WzAxXT9bMC05XVswLTldPykkLyxcbiAgICAgICAgbWVzc2FnZSB8fCAnTXVzdCBiZSBhIHZhbGlkIElQdjQgYWRkcmVzcydcbiAgICAgICksXG5cbiAgaXB2NjogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHpcbiAgICAgIC5zdHJpbmcoKVxuICAgICAgLnJlZ2V4KFxuICAgICAgICAvXihbMC05YS1mQS1GXXsxLDR9Oil7N31bMC05YS1mQS1GXXsxLDR9JHxeOjokfF46OjEkfF4oWzAtOWEtZkEtRl17MSw0fTopezEsN306JC8sXG4gICAgICAgIG1lc3NhZ2UgfHwgJ011c3QgYmUgYSB2YWxpZCBJUHY2IGFkZHJlc3MnXG4gICAgICApLFxuXG4gIG1hY0FkZHJlc3M6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5yZWdleChcbiAgICAgICAgL14oWzAtOUEtRmEtZl17Mn1bOi1dKXs1fShbMC05QS1GYS1mXXsyfSkkLyxcbiAgICAgICAgbWVzc2FnZSB8fCAnTXVzdCBiZSBhIHZhbGlkIE1BQyBhZGRyZXNzJ1xuICAgICAgKSxcblxuICBhbGxvd2VkRmlsZUV4dGVuc2lvbjogKHtcbiAgICBtZXNzYWdlLFxuICAgIGFsbG93ZWRFeHRlbnNpb25zLFxuICB9OiB7IG1lc3NhZ2U/OiBzdHJpbmc7IGFsbG93ZWRFeHRlbnNpb25zPzogc3RyaW5nW10gfSA9IHt9KSA9PlxuICAgIHouc3RyaW5nKCkucmVmaW5lKFxuICAgICAgZmlsZU5hbWUgPT4ge1xuICAgICAgICBpZiAoIWZpbGVOYW1lKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZmlsZU5hbWUuc3BsaXQoJy4nKS5wb3AoKT8udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgY29uc3QgbG93ZXJBbGxvd2VkID0gYWxsb3dlZEV4dGVuc2lvbnM/Lm1hcChleHQgPT5cbiAgICAgICAgICBleHQudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKCcuJylcbiAgICAgICAgICAgID8gZXh0LnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgIDogYC4ke2V4dC50b0xvd2VyQ2FzZSgpfWBcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gZXh0ZW5zaW9uICYmIGxvd2VyQWxsb3dlZD8uaW5jbHVkZXMoYC4ke2V4dGVuc2lvbn1gKTtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgbWVzc2FnZSB8fFxuICAgICAgICAgIGBNdXN0IGhhdmUgb25lIG9mIHRoZSBmb2xsb3dpbmcgZXh0ZW5zaW9uczogJHthbGxvd2VkRXh0ZW5zaW9ucz8uam9pbignLCAnKX1gLFxuICAgICAgfVxuICAgICksXG5cbiAgdmFsaWRJbWFnZUV4dGVuc2lvbjogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHNjaGVtYVRvb2xzLmFsbG93ZWRGaWxlRXh0ZW5zaW9uKHtcbiAgICAgIGFsbG93ZWRFeHRlbnNpb25zOiBbLi4uSU1BR0VfRVhURU5TSU9OU10sXG4gICAgICBtZXNzYWdlOlxuICAgICAgICBtZXNzYWdlIHx8XG4gICAgICAgIGBNdXN0IGhhdmUgYSB2YWxpZCBpbWFnZSBleHRlbnNpb24gKCR7SU1BR0VfRVhURU5TSU9OUy5qb2luKCcsICcpfSlgLFxuICAgIH0pLFxuXG4gIHZhbGlkRG9jdW1lbnRFeHRlbnNpb246ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICBzY2hlbWFUb29scy5hbGxvd2VkRmlsZUV4dGVuc2lvbih7XG4gICAgICBhbGxvd2VkRXh0ZW5zaW9uczogWy4uLkRPQ1VNRU5UX0VYVEVOU0lPTlNdLFxuICAgICAgbWVzc2FnZTpcbiAgICAgICAgbWVzc2FnZSB8fFxuICAgICAgICBgTXVzdCBoYXZlIGEgdmFsaWQgZG9jdW1lbnQgZXh0ZW5zaW9uICgke0RPQ1VNRU5UX0VYVEVOU0lPTlMuam9pbignLCAnKX0pYCxcbiAgICB9KSxcblxuICBwYW5DYXJkOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAucmVnZXgoXG4gICAgICAgIC9eW0EtWl17NX1bMC05XXs0fVtBLVpdezF9JC8sXG4gICAgICAgIG1lc3NhZ2UgfHwgJ011c3QgYmUgYSB2YWxpZCBQQU4gY2FyZCBudW1iZXInXG4gICAgICApLFxuXG4gIGFhZGhhYXI6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5yZWdleChcbiAgICAgICAgL15bMi05XXsxfVswLTldezExfSQvLFxuICAgICAgICBtZXNzYWdlIHx8ICdNdXN0IGJlIGEgdmFsaWQgQWFkaGFhciBudW1iZXInXG4gICAgICApLFxuXG4gIGdzdGluOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAucmVnZXgoXG4gICAgICAgIC9eWzAtOV17Mn1bQS1aXXs1fVswLTldezR9W0EtWl17MX1bMS05QS1aXXsxfVpbMC05QS1aXXsxfSQvLFxuICAgICAgICBtZXNzYWdlIHx8ICdNdXN0IGJlIGEgdmFsaWQgR1NUSU4nXG4gICAgICApLFxuXG4gIGlmc2M6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5yZWdleCgvXltBLVpdezR9MFtBLVowLTldezZ9JC8sIG1lc3NhZ2UgfHwgJ011c3QgYmUgYSB2YWxpZCBJRlNDIGNvZGUnKSxcblxuICBhbHBoYW51bWVyaWM6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAuc3RyaW5nKClcbiAgICAgIC5yZWdleChcbiAgICAgICAgL15bYS16QS1aMC05XSskLyxcbiAgICAgICAgbWVzc2FnZSB8fCAnT25seSBsZXR0ZXJzIGFuZCBudW1iZXJzIGFyZSBhbGxvd2VkJ1xuICAgICAgKSxcblxuICBzbHVnOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLnN0cmluZygpXG4gICAgICAucmVnZXgoL15bYS16MC05XSsoPzotW2EtejAtOV0rKSokLywgbWVzc2FnZSB8fCAnSW52YWxpZCBzbHVnIGZvcm1hdCcpLFxuXG4gIC8vIE51bWJlciB2YWxpZGF0aW9uc1xuICBwb3NpdGl2ZU51bWJlcjogKHtcbiAgICBtZXNzYWdlLFxuICAgIG1pbixcbiAgICBtYXgsXG4gIH06IHsgbWVzc2FnZT86IHN0cmluZzsgbWluPzogbnVtYmVyOyBtYXg/OiBudW1iZXIgfSA9IHt9KSA9PlxuICAgIHpcbiAgICAgIC5udW1iZXIoKVxuICAgICAgLnBvc2l0aXZlKG1lc3NhZ2UgfHwgJ051bWJlciBtdXN0IGJlIHBvc2l0aXZlJylcbiAgICAgIC5taW4obWluIHx8IDAuMDEsIGBOdW1iZXIgbXVzdCBiZSBhdCBsZWFzdCAke21pbiB8fCAwLjAxfWApXG4gICAgICAubWF4KFxuICAgICAgICBtYXggfHwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIsXG4gICAgICAgIGBOdW1iZXIgbXVzdCBiZSBhdCBtb3N0ICR7bWF4IHx8IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSfWBcbiAgICAgICksXG5cbiAgbWF4RGVjaW1hbFBsYWNlczogKHtcbiAgICBtZXNzYWdlLFxuICAgIG1heFBsYWNlcyxcbiAgfTogeyBtZXNzYWdlPzogc3RyaW5nOyBtYXhQbGFjZXM/OiBudW1iZXIgfSA9IHt9KSA9PlxuICAgIHoubnVtYmVyKCkucmVmaW5lKFxuICAgICAgdmFsdWUgPT4ge1xuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRydWU7XG4gICAgICAgIGNvbnN0IGRlY2ltYWxQYXJ0ID0gdmFsdWUudG9TdHJpbmcoKS5zcGxpdCgnLicpWzFdO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgIWRlY2ltYWxQYXJ0IHx8XG4gICAgICAgICAgZGVjaW1hbFBhcnQubGVuZ3RoIDw9ICh0eXBlb2YgbWF4UGxhY2VzID09PSAnbnVtYmVyJyA/IG1heFBsYWNlcyA6IDApXG4gICAgICAgICk7XG4gICAgICB9LFxuICAgICAgeyBtZXNzYWdlOiBtZXNzYWdlIHx8IGBNdXN0IGhhdmUgYXQgbW9zdCAke21heFBsYWNlc30gZGVjaW1hbCBwbGFjZXNgIH1cbiAgICApLFxuXG4gIGN1cnJlbmN5OiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLm51bWJlcigpXG4gICAgICAubWluKDAsIG1lc3NhZ2UgfHwgJ011c3QgYmUgYSB2YWxpZCBjdXJyZW5jeSBhbW91bnQgKHBvc2l0aXZlKScpXG4gICAgICAucmVmaW5lKFxuICAgICAgICB2YWx1ZSA9PiB7XG4gICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiB0cnVlO1xuICAgICAgICAgIGNvbnN0IGRlY2ltYWxQYXJ0ID0gdmFsdWUudG9TdHJpbmcoKS5zcGxpdCgnLicpWzFdO1xuXG4gICAgICAgICAgcmV0dXJuICFkZWNpbWFsUGFydCB8fCBkZWNpbWFsUGFydC5sZW5ndGggPD0gMjtcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgICBtZXNzYWdlIHx8ICdNdXN0IGJlIGEgdmFsaWQgY3VycmVuY3kgYW1vdW50IChtYXggMiBkZWNpbWFsIHBsYWNlcyknLFxuICAgICAgICB9XG4gICAgICApLFxuXG4gIHZhbGlkQWdlOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgelxuICAgICAgLm51bWJlcigpXG4gICAgICAuaW50KCdNdXN0IGJlIGFuIGludGVnZXInKVxuICAgICAgLm1pbigwLCBtZXNzYWdlIHx8ICdNdXN0IGJlIGEgdmFsaWQgYWdlIChiZXR3ZWVuIDAgYW5kIDE1MCknKVxuICAgICAgLm1heCgxNTAsIG1lc3NhZ2UgfHwgJ011c3QgYmUgYSB2YWxpZCBhZ2UgKGJldHdlZW4gMCBhbmQgMTUwKScpLFxuXG4gIG5vbk5lZ2F0aXZlTnVtYmVyOiAoe1xuICAgIG1lc3NhZ2UsXG4gICAgbWF4LFxuICB9OiB7IG1lc3NhZ2U/OiBzdHJpbmc7IG1heD86IG51bWJlciB9ID0ge30pID0+XG4gICAgelxuICAgICAgLm51bWJlcigpXG4gICAgICAubWluKDAsIG1lc3NhZ2UgfHwgJ051bWJlciBtdXN0IGJlIG5vbi1uZWdhdGl2ZScpXG4gICAgICAubWF4KFxuICAgICAgICBtYXggfHwgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIsXG4gICAgICAgIGBOdW1iZXIgbXVzdCBiZSBhdCBtb3N0ICR7bWF4IHx8IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSfWBcbiAgICAgICksXG5cbiAgaW50ZWdlcjogKHtcbiAgICBtZXNzYWdlLFxuICAgIG1pbixcbiAgICBtYXgsXG4gIH06IHsgbWVzc2FnZT86IHN0cmluZzsgbWluPzogbnVtYmVyOyBtYXg/OiBudW1iZXIgfSA9IHt9KSA9PlxuICAgIHpcbiAgICAgIC5udW1iZXIoKVxuICAgICAgLmludChtZXNzYWdlIHx8ICdNdXN0IGJlIGFuIGludGVnZXInKVxuICAgICAgLm1pbihcbiAgICAgICAgbWluIHx8IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSLFxuICAgICAgICBgTnVtYmVyIG11c3QgYmUgYXQgbGVhc3QgJHttaW4gfHwgTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVJ9YFxuICAgICAgKVxuICAgICAgLm1heChcbiAgICAgICAgbWF4IHx8IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSLFxuICAgICAgICBgTnVtYmVyIG11c3QgYmUgYXQgbW9zdCAke21heCB8fCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUn1gXG4gICAgICApLFxuXG4gIHBlcmNlbnRhZ2U6ICh7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fSkgPT5cbiAgICB6XG4gICAgICAubnVtYmVyKClcbiAgICAgIC5taW4oMCwgbWVzc2FnZSB8fCAnUGVyY2VudGFnZSBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMTAwJylcbiAgICAgIC5tYXgoMTAwLCBtZXNzYWdlIHx8ICdQZXJjZW50YWdlIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxMDAnKSxcblxuICAvLyBBcnJheSB2YWxpZGF0aW9uc1xuICBub25FbXB0eUFycmF5OiA8VD4oXG4gICAgc2NoZW1hOiB6LlpvZFNjaGVtYTxUPixcbiAgICB7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fVxuICApID0+IHouYXJyYXkoc2NoZW1hKS5taW4oMSwgbWVzc2FnZSB8fCAnQXQgbGVhc3Qgb25lIGl0ZW0gaXMgcmVxdWlyZWQnKSxcblxuICB1bmlxdWVBcnJheTogPFQ+KFxuICAgIHNjaGVtYTogei5ab2RTY2hlbWE8VD4sXG4gICAgeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge31cbiAgKSA9PlxuICAgIHouYXJyYXkoc2NoZW1hKS5yZWZpbmUoaXRlbXMgPT4gbmV3IFNldChpdGVtcykuc2l6ZSA9PT0gaXRlbXMubGVuZ3RoLCB7XG4gICAgICBtZXNzYWdlOiBtZXNzYWdlIHx8ICdBbGwgaXRlbXMgbXVzdCBiZSB1bmlxdWUnLFxuICAgIH0pLFxuXG4gIG5vTnVsbEFycmF5SXRlbXM6IDxUPihcbiAgICBzY2hlbWE6IHouWm9kU2NoZW1hPFQ+LFxuICAgIHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9XG4gICkgPT5cbiAgICB6XG4gICAgICAuYXJyYXkoc2NoZW1hLm51bGxhYmxlKCkpXG4gICAgICAucmVmaW5lKGl0ZW1zID0+IGl0ZW1zLmV2ZXJ5KGl0ZW0gPT4gaXRlbSAhPT0gbnVsbCksIHtcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSB8fCAnTXVzdCBub3QgY29udGFpbiBudWxsIGl0ZW1zJyxcbiAgICAgIH0pLFxuXG4gIC8vIEJvb2xlYW4gdmFsaWRhdGlvbnNcbiAgcmVxdWlyZWRCb29sZWFuOiAoeyBtZXNzYWdlIH06IHsgbWVzc2FnZT86IHN0cmluZyB9ID0ge30pID0+XG4gICAgei5ib29sZWFuKHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UgfHwgJ1RoaXMgZmllbGQgaXMgcmVxdWlyZWQnLFxuICAgIH0pLFxuXG4gIC8vIE9iamVjdCB2YWxpZGF0aW9uc1xuICBub25FbXB0eU9iamVjdDogPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gICAgc2NoZW1hOiB6LlpvZFNjaGVtYTxUPixcbiAgICB7IG1lc3NhZ2UgfTogeyBtZXNzYWdlPzogc3RyaW5nIH0gPSB7fVxuICApID0+XG4gICAgc2NoZW1hLnJlZmluZShvYmogPT4gT2JqZWN0LmtleXMob2JqKS5sZW5ndGggPiAwLCB7XG4gICAgICBtZXNzYWdlOiBtZXNzYWdlIHx8ICdPYmplY3QgY2Fubm90IGJlIGVtcHR5JyxcbiAgICB9KSxcblxuICAvLyBGaWxlIHZhbGlkYXRpb25zXG4gIHJlcXVpcmVkRmlsZTogKHsgbWVzc2FnZSB9OiB7IG1lc3NhZ2U/OiBzdHJpbmcgfSA9IHt9KSA9PlxuICAgIHpcbiAgICAgIC5pbnN0YW5jZW9mKEZpbGUsIHsgbWVzc2FnZTogbWVzc2FnZSB8fCAnRmlsZSBpcyByZXF1aXJlZCcgfSlcbiAgICAgIC5yZWZpbmUoZmlsZSA9PiBmaWxlLnNpemUgPiAwLCB7XG4gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UgfHwgJ0ZpbGUgY2Fubm90IGJlIGVtcHR5JyxcbiAgICAgIH0pLFxuXG4gIGZpbGVTaXplOiAoeyBtYXhTaXplLCBtZXNzYWdlIH06IHsgbWF4U2l6ZTogbnVtYmVyOyBtZXNzYWdlPzogc3RyaW5nIH0pID0+XG4gICAgei5pbnN0YW5jZW9mKEZpbGUpLnJlZmluZShmaWxlID0+IGZpbGUuc2l6ZSA8PSBtYXhTaXplLCB7XG4gICAgICBtZXNzYWdlOlxuICAgICAgICBtZXNzYWdlIHx8XG4gICAgICAgIGBGaWxlIHNpemUgbXVzdCBiZSBsZXNzIHRoYW4gJHtNYXRoLnJvdW5kKG1heFNpemUgLyAxMDI0IC8gMTAyNCl9TUJgLFxuICAgIH0pLFxuXG4gIGZpbGVUeXBlOiAoe1xuICAgIGFsbG93ZWRUeXBlcyxcbiAgICBtZXNzYWdlLFxuICB9OiB7XG4gICAgYWxsb3dlZFR5cGVzOiBzdHJpbmdbXTtcbiAgICBtZXNzYWdlPzogc3RyaW5nO1xuICB9KSA9PlxuICAgIHouaW5zdGFuY2VvZihGaWxlKS5yZWZpbmUoZmlsZSA9PiBhbGxvd2VkVHlwZXMuaW5jbHVkZXMoZmlsZS50eXBlKSwge1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgbWVzc2FnZSB8fCBgRmlsZSB0eXBlIG11c3QgYmUgb25lIG9mOiAke2FsbG93ZWRUeXBlcy5qb2luKCcsICcpfWAsXG4gICAgfSksXG5cbiAgLy8gQ3VzdG9tIHZhbGlkYXRvcnNcbiAgY29uZGl0aW9uYWw6IDxULCBVPihcbiAgICBjb25kaXRpb246IChkYXRhOiBUKSA9PiBib29sZWFuLFxuICAgIHRydWVTY2hlbWE6IHouWm9kU2NoZW1hPFU+LFxuICAgIGZhbHNlU2NoZW1hOiB6LlpvZFNjaGVtYTxVPlxuICApID0+XG4gICAgei51bmlvbihbdHJ1ZVNjaGVtYSwgZmFsc2VTY2hlbWFdKS5zdXBlclJlZmluZSgoZGF0YSwgY3R4KSA9PiB7XG4gICAgICBjb25zdCBzaG91bGRVc2VUcnVlID0gY29uZGl0aW9uKGRhdGEgYXMgdW5rbm93biBhcyBUKTtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IHNob3VsZFVzZVRydWUgPyB0cnVlU2NoZW1hIDogZmFsc2VTY2hlbWE7XG4gICAgICBjb25zdCByZXN1bHQgPSBzY2hlbWEuc2FmZVBhcnNlKGRhdGEpO1xuXG4gICAgICBpZiAoIXJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIGN0eC5hZGRJc3N1ZSh7XG4gICAgICAgICAgY29kZTogei5ab2RJc3N1ZUNvZGUuY3VzdG9tLFxuICAgICAgICAgIG1lc3NhZ2U6IHJlc3VsdC5lcnJvci5tZXNzYWdlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KSxcblxuICB0cmFuc2Zvcm06IHtcbiAgICB0b0xvd2VyQ2FzZTogei5zdHJpbmcoKS50cmFuc2Zvcm0odmFsID0+IHZhbC50b0xvd2VyQ2FzZSgpKSxcbiAgICB0b1VwcGVyQ2FzZTogei5zdHJpbmcoKS50cmFuc2Zvcm0odmFsID0+IHZhbC50b1VwcGVyQ2FzZSgpKSxcbiAgICB0cmltOiB6LnN0cmluZygpLnRyYW5zZm9ybSh2YWwgPT4gdmFsLnRyaW0oKSksXG4gICAgdG9OdW1iZXI6IHouc3RyaW5nKCkudHJhbnNmb3JtKHZhbCA9PiBOdW1iZXIodmFsKSksXG4gICAgdG9Cb29sZWFuOiB6LnN0cmluZygpLnRyYW5zZm9ybSh2YWwgPT4gdmFsID09PSAndHJ1ZScpLFxuICAgIHBhcnNlSnNvbjogPFQ+KHNjaGVtYTogei5ab2RTY2hlbWE8VD4pID0+XG4gICAgICB6LnN0cmluZygpLnRyYW5zZm9ybSgodmFsLCBjdHgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKHZhbCk7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gc2NoZW1hLnNhZmVQYXJzZShwYXJzZWQpO1xuXG4gICAgICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKSByZXR1cm4gcmVzdWx0LmRhdGE7XG5cbiAgICAgICAgICBjdHguYWRkSXNzdWUoe1xuICAgICAgICAgICAgY29kZTogei5ab2RJc3N1ZUNvZGUuY3VzdG9tLFxuICAgICAgICAgICAgbWVzc2FnZTogcmVzdWx0LmVycm9yLm1lc3NhZ2UsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXR1cm4gei5ORVZFUjtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgY3R4LmFkZElzc3VlKHtcbiAgICAgICAgICAgIGNvZGU6IHouWm9kSXNzdWVDb2RlLmN1c3RvbSxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIEpTT04nLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIHouTkVWRVI7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICB9LFxufTtcbiIsICIvKipcbiAqIFR5cGUgZ3VhcmQgdXRpbGl0aWVzIGZvciBydW50aW1lIHR5cGUgY2hlY2tpbmdcbiAqIFxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgYSBub24tbnVsbCBvYmplY3QgKGV4Y2x1ZGluZyBhcnJheXMpXG4gKiBcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYSBwbGFpbiBvYmplY3RcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGlmIChpc1JlY29yZCh2YWx1ZSkpIHtcbiAqICAgLy8gdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAqICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAqIH1cbiAqIGBgYFxuICogXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1JlY29yZCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYW4gb2JqZWN0IGhhcyBhIHNwZWNpZmljIHByb3BlcnR5XG4gKiBcbiAqIEBwYXJhbSBvYmogLSBUaGUgb2JqZWN0IHRvIGNoZWNrXG4gKiBAcGFyYW0ga2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byBsb29rIGZvclxuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgb2JqZWN0IGhhcyB0aGUgcHJvcGVydHlcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGlmIChoYXNQcm9wZXJ0eShvYmosICduYW1lJykpIHtcbiAqICAgLy8gb2JqIGlzIFJlY29yZDwnbmFtZScsIHVua25vd24+XG4gKiAgIGNvbnNvbGUubG9nKG9iai5uYW1lKTtcbiAqIH1cbiAqIGBgYFxuICogXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNQcm9wZXJ0eTxLIGV4dGVuZHMgUHJvcGVydHlLZXk+KFxuICBvYmo6IHVua25vd24sXG4gIGtleTogS1xuKTogb2JqIGlzIFJlY29yZDxLLCB1bmtub3duPiB7XG4gIHJldHVybiBpc1JlY29yZChvYmopICYmIGtleSBpbiBvYmo7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgbm9uLWVtcHR5IHN0cmluZ1xuICogXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgbm9uLWVtcHR5IHN0cmluZ1xuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaWYgKGlzTm9uRW1wdHlTdHJpbmcodmFsdWUpKSB7XG4gKiAgIC8vIHZhbHVlIGlzIHN0cmluZyB3aXRoIGxlbmd0aCA+IDBcbiAqICAgY29uc29sZS5sb2codmFsdWUudG9VcHBlckNhc2UoKSk7XG4gKiB9XG4gKiBgYGBcbiAqIFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOb25FbXB0eVN0cmluZyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlLmxlbmd0aCA+IDA7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgdmFsaWQgYXJyYXlcbiAqIFxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBhbiBhcnJheVxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gKiAgIC8vIHZhbHVlIGlzIHVua25vd25bXVxuICogICB2YWx1ZS5mb3JFYWNoKGl0ZW0gPT4gY29uc29sZS5sb2coaXRlbSkpO1xuICogfVxuICogYGBgXG4gKiBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXJyYXk8VCA9IHVua25vd24+KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgVFtdIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhIG5vbi1lbXB0eSBhcnJheVxuICogXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgbm9uLWVtcHR5IGFycmF5XG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpZiAoaXNOb25FbXB0eUFycmF5KGl0ZW1zKSkge1xuICogICAvLyBpdGVtcyBpcyBbVCwgLi4uVFtdXSAtIGd1YXJhbnRlZWQgdG8gaGF2ZSBhdCBsZWFzdCBvbmUgZWxlbWVudFxuICogICBjb25zdCBmaXJzdCA9IGl0ZW1zWzBdOyAgLy8gU2FmZSBhY2Nlc3NcbiAqIH1cbiAqIGBgYFxuICogXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05vbkVtcHR5QXJyYXk8VD4odmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBbVCwgLi4uVFtdXSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPiAwO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhIGZ1bmN0aW9uXG4gKiBcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYSBmdW5jdGlvblxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaWYgKGlzRnVuY3Rpb24oY2FsbGJhY2spKSB7XG4gKiAgIC8vIGNhbGxiYWNrIGlzICguLi5hcmdzOiB1bmtub3duW10pID0+IHVua25vd25cbiAqICAgY2FsbGJhY2soKTtcbiAqIH1cbiAqIGBgYFxuICogXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Z1bmN0aW9uKFxuICB2YWx1ZTogdW5rbm93blxuKTogdmFsdWUgaXMgKC4uLmFyZ3M6IHJlYWRvbmx5IHVua25vd25bXSkgPT4gdW5rbm93biB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbic7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgc3RyaW5nXG4gKiBcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYSBzdHJpbmcgKGluY2x1ZGluZyBlbXB0eSBzdHJpbmcpXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gKiAgIC8vIHZhbHVlIGlzIHN0cmluZ1xuICogICBjb25zb2xlLmxvZyh2YWx1ZS5sZW5ndGgpO1xuICogfVxuICogYGBgXG4gKiBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgc3RyaW5nIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZyc7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgbnVtYmVyIChleGNsdWRpbmcgTmFOKVxuICogXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgdmFsaWQgbnVtYmVyXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpZiAoaXNOdW1iZXIodmFsdWUpKSB7XG4gKiAgIC8vIHZhbHVlIGlzIG51bWJlciAobm90IE5hTilcbiAqICAgY29uc3QgZG91YmxlZCA9IHZhbHVlICogMjtcbiAqIH1cbiAqIGBgYFxuICogXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmICFpc05hTih2YWx1ZSk7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGEgYm9vbGVhblxuICogXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHZhbHVlIGlzIGEgYm9vbGVhblxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaWYgKGlzQm9vbGVhbih2YWx1ZSkpIHtcbiAqICAgLy8gdmFsdWUgaXMgYm9vbGVhblxuICogICBjb25zb2xlLmxvZyghdmFsdWUpO1xuICogfVxuICogYGBgXG4gKiBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQm9vbGVhbih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIGJvb2xlYW4ge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbic7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIG51bGxcbiAqIFxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBudWxsXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpZiAoaXNOdWxsKHZhbHVlKSkge1xuICogICAvLyB2YWx1ZSBpcyBudWxsXG4gKiAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gKiB9XG4gKiBgYGBcbiAqIFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOdWxsKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgbnVsbCB7XG4gIHJldHVybiB2YWx1ZSA9PT0gbnVsbDtcbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmFsdWUgaXMgdW5kZWZpbmVkXG4gKiBcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgdW5kZWZpbmVkXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpZiAoaXNVbmRlZmluZWQodmFsdWUpKSB7XG4gKiAgIC8vIHZhbHVlIGlzIHVuZGVmaW5lZFxuICogICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICogfVxuICogYGBgXG4gKiBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIG51bGwgb3IgdW5kZWZpbmVkXG4gKiBcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgbnVsbGlzaFxuICogXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaWYgKGlzTnVsbGlzaCh2YWx1ZSkpIHtcbiAqICAgLy8gdmFsdWUgaXMgbnVsbCB8IHVuZGVmaW5lZFxuICogICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICogfVxuICogXG4gKiBpZiAoIWlzTnVsbGlzaCh2YWx1ZSkpIHtcbiAqICAgLy8gdmFsdWUgaXMgTm9uTnVsbGFibGU8dHlwZW9mIHZhbHVlPlxuICogICBjb25zb2xlLmxvZyh2YWx1ZSk7XG4gKiB9XG4gKiBgYGBcbiAqIFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOdWxsaXNoKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgbnVsbCB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBkZWZpbmVkIChub3QgbnVsbCBvciB1bmRlZmluZWQpXG4gKiBcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgbm90IG51bGwgb3IgdW5kZWZpbmVkXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBmaWx0ZXJlZCA9IGl0ZW1zLmZpbHRlcihpc0RlZmluZWQpO1xuICogLy8gZmlsdGVyZWQgaGFzIHR5cGU6IE5vbk51bGxhYmxlPFQ+W11cbiAqIGBgYFxuICogXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RlZmluZWQ8VD4odmFsdWU6IFQpOiB2YWx1ZSBpcyBOb25OdWxsYWJsZTxUPiB7XG4gIHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhIERhdGUgb2JqZWN0XG4gKiBcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYSBEYXRlXG4gKiBcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICogICAvLyB2YWx1ZSBpcyBEYXRlXG4gKiAgIGNvbnNvbGUubG9nKHZhbHVlLnRvSVNPU3RyaW5nKCkpO1xuICogfVxuICogYGBgXG4gKiBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGF0ZSh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIERhdGUge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBEYXRlICYmICFpc05hTih2YWx1ZS5nZXRUaW1lKCkpO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhIFByb21pc2VcbiAqIFxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBhIFByb21pc2VcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gKiAgIC8vIHZhbHVlIGlzIFByb21pc2U8dW5rbm93bj5cbiAqICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmFsdWU7XG4gKiB9XG4gKiBgYGBcbiAqIFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQcm9taXNlKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUHJvbWlzZTx1bmtub3duPiB7XG4gIHJldHVybiAoXG4gICAgdmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlIHx8XG4gICAgKGlzUmVjb3JkKHZhbHVlKSAmJlxuICAgICAgdHlwZW9mICh2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikudGhlbiA9PT0gJ2Z1bmN0aW9uJylcbiAgKTtcbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGFuIGVycm9yIGlzIGFuIEVycm9yIGluc3RhbmNlXG4gKiBcbiAqIEBwYXJhbSBlcnJvciAtIFRoZSBlcnJvciB0byBjaGVja1xuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgZXJyb3IgaXMgYW4gRXJyb3IgaW5zdGFuY2VcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHRyeSB7XG4gKiAgIC8vIC4uLlxuICogfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgaWYgKGlzRXJyb3IoZXJyb3IpKSB7XG4gKiAgICAgLy8gZXJyb3IgaXMgRXJyb3JcbiAqICAgICBjb25zb2xlLmVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqIFxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFcnJvcihlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIEVycm9yIHtcbiAgcmV0dXJuIGVycm9yIGluc3RhbmNlb2YgRXJyb3I7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIG1hdGNoZXMgYSBzcGVjaWZpYyB0eXBlIHVzaW5nIGEgdmFsaWRhdG9yIGZ1bmN0aW9uXG4gKiBcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjaGVja1xuICogQHBhcmFtIHZhbGlkYXRvciAtIEZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0cnVlIGlmIHZhbHVlIG1hdGNoZXMgdGhlIHR5cGVcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHZhbHVlIG1hdGNoZXMgdGhlIHR5cGVcbiAqIFxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGludGVyZmFjZSBVc2VyIHtcbiAqICAgaWQ6IHN0cmluZztcbiAqICAgbmFtZTogc3RyaW5nO1xuICogfVxuICogXG4gKiBjb25zdCBpc1VzZXIgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBVc2VyID0+XG4gKiAgIGlzUmVjb3JkKHZhbHVlKSAmJlxuICogICBoYXNQcm9wZXJ0eSh2YWx1ZSwgJ2lkJykgJiZcbiAqICAgaGFzUHJvcGVydHkodmFsdWUsICduYW1lJykgJiZcbiAqICAgaXNTdHJpbmcodmFsdWUuaWQpICYmXG4gKiAgIGlzU3RyaW5nKHZhbHVlLm5hbWUpO1xuICogXG4gKiBpZiAoaXNVc2VyKGRhdGEpKSB7XG4gKiAgIC8vIGRhdGEgaXMgVXNlclxuICogICBjb25zb2xlLmxvZyhkYXRhLm5hbWUpO1xuICogfVxuICogYGBgXG4gKiBcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoZXM8VD4oXG4gIHZhbHVlOiB1bmtub3duLFxuICB2YWxpZGF0b3I6ICh2YWx1ZTogdW5rbm93bikgPT4gdmFsdWUgaXMgVFxuKTogdmFsdWUgaXMgVCB7XG4gIHJldHVybiB2YWxpZGF0b3IodmFsdWUpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUNPLElBQU0sbUJBQW1CLENBQUMsUUFBUSxTQUFTLFFBQVEsUUFBUSxPQUFPO0FBR2xFLElBQU0sc0JBQXNCLENBQUMsUUFBUSxRQUFRLFNBQVMsUUFBUSxTQUFTLE1BQU07QUFHN0UsSUFBTSxzQkFBZ0MsQ0FBQyxHQUFHLGtCQUFrQixHQUFHLG1CQUFtQjtBQUV6RixJQUFNLGdCQUFnQixJQUFJLElBQVksZ0JBQWdCO0FBRy9DLFNBQVMsWUFBWSxNQUFxQjtBQUMvQyxNQUFJLEtBQUssS0FBSyxXQUFXLFFBQVEsRUFBRyxRQUFPO0FBQzNDLFFBQU0sTUFBTSxNQUFNLEtBQUssS0FBSyxNQUFNLEdBQUcsRUFBRSxJQUFJLEdBQUcsWUFBWTtBQUMxRCxTQUFPLGNBQWMsSUFBSSxHQUFHO0FBQzlCO0FBR08sU0FBUyxnQkFBZ0IsVUFBMkI7QUFDekQsU0FBTyxTQUFTLFdBQVcsUUFBUTtBQUNyQztBQUdPLFNBQVMsZUFBZSxPQUF1QjtBQUNwRCxNQUFJLFVBQVUsRUFBRyxRQUFPO0FBQ3hCLFFBQU0sSUFBSTtBQUNWLFFBQU0sUUFBUSxDQUFDLEtBQUssTUFBTSxNQUFNLElBQUk7QUFDcEMsUUFBTSxJQUFJLEtBQUssTUFBTSxLQUFLLElBQUksS0FBSyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUM7QUFDbEQsU0FBTyxHQUFHLFlBQVksUUFBUSxLQUFLLElBQUksR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FB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WCxNQUFNLEVBQUUsYUFBYTtBQUFBLFVBQ3JCLFNBQVM7QUFBQSxRQUNYLENBQUM7QUFFRCxlQUFPLEVBQUU7QUFBQSxNQUNYO0FBQUEsSUFDRixDQUFDO0FBQUEsRUFDTDtBQUNGOzs7QUMzb0JPLFNBQVMsU0FBUyxPQUFrRDtBQUN6RSxTQUFPLE9BQU8sVUFBVSxZQUFZLFVBQVUsUUFBUSxDQUFDLE1BQU0sUUFBUSxLQUFLO0FBQzVFO0FBbUJPLFNBQVMsWUFDZCxLQUNBLEtBQzJCO0FBQzNCLFNBQU8sU0FBUyxHQUFHLEtBQUssT0FBTztBQUNqQztBQWtCTyxTQUFTLGlCQUFpQixPQUFpQztBQUNoRSxTQUFPLE9BQU8sVUFBVSxZQUFZLE1BQU0sU0FBUztBQUNyRDtBQWtCTyxTQUFTQyxTQUFxQixPQUE4QjtBQUNqRSxTQUFPLE1BQU0sUUFBUSxLQUFLO0FBQzVCO0FBa0JPLFNBQVMsZ0JBQW1CLE9BQXNDO0FBQ3ZFLFNBQU8sTUFBTSxRQUFRLEtBQUssS0FBSyxNQUFNLFNBQVM7QUFDaEQ7QUFrQk8sU0FBUyxXQUNkLE9BQ21EO0FBQ25ELFNBQU8sT0FBTyxVQUFVO0FBQzFCO0FBa0JPLFNBQVMsU0FBUyxPQUFpQztBQUN4RCxTQUFPLE9BQU8sVUFBVTtBQUMxQjtBQWtCTyxTQUFTLFNBQVMsT0FBaUM7QUFDeEQsU0FBTyxPQUFPLFVBQVUsWUFBWSxDQUFDLE1BQU0sS0FBSztBQUNsRDtBQWtCTyxTQUFTLFVBQVUsT0FBa0M7QUFDMUQsU0FBTyxPQUFPLFVBQVU7QUFDMUI7QUFrQk8sU0FBUyxPQUFPLE9BQStCO0FBQ3BELFNBQU8sVUFBVTtBQUNuQjtBQWtCTyxTQUFTLFlBQVksT0FBb0M7QUFDOUQsU0FBTyxVQUFVO0FBQ25CO0FBdUJPLFNBQVMsVUFBVSxPQUEyQztBQUNuRSxTQUFPLFVBQVUsUUFBUSxVQUFVO0FBQ3JDO0FBZ0JPLFNBQVMsVUFBYSxPQUFtQztBQUM5RCxTQUFPLFVBQVUsUUFBUSxVQUFVO0FBQ3JDO0FBa0JPLFNBQVMsT0FBTyxPQUErQjtBQUNwRCxTQUFPLGlCQUFpQixRQUFRLENBQUMsTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUN4RDtBQWtCTyxTQUFTLFVBQVUsT0FBMkM7QUFDbkUsU0FDRSxpQkFBaUIsV0FDaEIsU0FBUyxLQUFLLEtBQ2IsT0FBUSxNQUFrQyxTQUFTO0FBRXpEO0FBc0JPLFNBQVMsUUFBUSxPQUFnQztBQUN0RCxTQUFPLGlCQUFpQjtBQUMxQjtBQStCTyxTQUFTLFFBQ2QsT0FDQSxXQUNZO0FBQ1osU0FBTyxVQUFVLEtBQUs7QUFDeEI7IiwKICAibmFtZXMiOiBbImhhbmRsZVNlcnZlckVycm9ycyIsICJpc0FycmF5Il0KfQo=