@f-o-t/pdf 0.1.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.
@@ -0,0 +1,572 @@
1
+ import {
2
+ createArray,
3
+ createDictionary,
4
+ createName,
5
+ createRef,
6
+ createStream
7
+ } from "./chunk-6dengthp.js";
8
+
9
+ // src/parsing/lexer.ts
10
+ var TokenType;
11
+ ((TokenType2) => {
12
+ TokenType2["NUMBER"] = "NUMBER";
13
+ TokenType2["STRING"] = "STRING";
14
+ TokenType2["NAME"] = "NAME";
15
+ TokenType2["BOOLEAN"] = "BOOLEAN";
16
+ TokenType2["NULL"] = "NULL";
17
+ TokenType2["ARRAY_START"] = "ARRAY_START";
18
+ TokenType2["ARRAY_END"] = "ARRAY_END";
19
+ TokenType2["DICT_START"] = "DICT_START";
20
+ TokenType2["DICT_END"] = "DICT_END";
21
+ TokenType2["OBJ"] = "OBJ";
22
+ TokenType2["ENDOBJ"] = "ENDOBJ";
23
+ TokenType2["STREAM"] = "STREAM";
24
+ TokenType2["ENDSTREAM"] = "ENDSTREAM";
25
+ TokenType2["XREF"] = "XREF";
26
+ TokenType2["TRAILER"] = "TRAILER";
27
+ TokenType2["STARTXREF"] = "STARTXREF";
28
+ TokenType2["R"] = "R";
29
+ TokenType2["EOF"] = "EOF";
30
+ })(TokenType ||= {});
31
+
32
+ class PDFLexer {
33
+ data;
34
+ position = 0;
35
+ constructor(data) {
36
+ this.data = data;
37
+ }
38
+ nextToken() {
39
+ this.skipWhitespace();
40
+ if (this.position >= this.data.length) {
41
+ return { type: "EOF" /* EOF */, value: null, position: this.position };
42
+ }
43
+ const char = String.fromCharCode(this.data[this.position]);
44
+ if (char === "[") {
45
+ this.position++;
46
+ return { type: "ARRAY_START" /* ARRAY_START */, value: "[", position: this.position - 1 };
47
+ }
48
+ if (char === "]") {
49
+ this.position++;
50
+ return { type: "ARRAY_END" /* ARRAY_END */, value: "]", position: this.position - 1 };
51
+ }
52
+ if (char === "<" && this.peek() === "<") {
53
+ this.position += 2;
54
+ return { type: "DICT_START" /* DICT_START */, value: "<<", position: this.position - 2 };
55
+ }
56
+ if (char === ">" && this.peek() === ">") {
57
+ this.position += 2;
58
+ return { type: "DICT_END" /* DICT_END */, value: ">>", position: this.position - 2 };
59
+ }
60
+ if (char === "/") {
61
+ return this.readName();
62
+ }
63
+ if (char === "(") {
64
+ return this.readString();
65
+ }
66
+ if (char === "-" || char === "+" || char === "." || char >= "0" && char <= "9") {
67
+ return this.readNumber();
68
+ }
69
+ return this.readKeyword();
70
+ }
71
+ peek() {
72
+ if (this.position + 1 >= this.data.length)
73
+ return "";
74
+ return String.fromCharCode(this.data[this.position + 1]);
75
+ }
76
+ skipWhitespace() {
77
+ while (this.position < this.data.length) {
78
+ const char = this.data[this.position];
79
+ if (char === 32 || char === 9 || char === 10 || char === 13 || char === 0) {
80
+ this.position++;
81
+ continue;
82
+ }
83
+ if (char === 37) {
84
+ while (this.position < this.data.length && this.data[this.position] !== 10 && this.data[this.position] !== 13) {
85
+ this.position++;
86
+ }
87
+ continue;
88
+ }
89
+ break;
90
+ }
91
+ }
92
+ readName() {
93
+ const start = this.position;
94
+ this.position++;
95
+ let value = "";
96
+ while (this.position < this.data.length) {
97
+ const char = String.fromCharCode(this.data[this.position]);
98
+ if (this.isDelimiter(char) || this.isWhitespace(this.data[this.position])) {
99
+ break;
100
+ }
101
+ value += char;
102
+ this.position++;
103
+ }
104
+ return { type: "NAME" /* NAME */, value, position: start };
105
+ }
106
+ readString() {
107
+ const start = this.position;
108
+ this.position++;
109
+ let value = "";
110
+ let depth = 1;
111
+ while (this.position < this.data.length && depth > 0) {
112
+ const char = String.fromCharCode(this.data[this.position]);
113
+ if (char === "\\") {
114
+ this.position++;
115
+ if (this.position < this.data.length) {
116
+ const escaped = String.fromCharCode(this.data[this.position]);
117
+ value += escaped === "n" ? `
118
+ ` : escaped === "r" ? "\r" : escaped === "t" ? "\t" : escaped;
119
+ }
120
+ } else if (char === "(") {
121
+ depth++;
122
+ value += char;
123
+ } else if (char === ")") {
124
+ depth--;
125
+ if (depth > 0)
126
+ value += char;
127
+ } else {
128
+ value += char;
129
+ }
130
+ this.position++;
131
+ }
132
+ return { type: "STRING" /* STRING */, value, position: start };
133
+ }
134
+ readNumber() {
135
+ const start = this.position;
136
+ let value = "";
137
+ while (this.position < this.data.length) {
138
+ const char = String.fromCharCode(this.data[this.position]);
139
+ if (char === "-" || char === "+" || char === "." || char >= "0" && char <= "9") {
140
+ value += char;
141
+ this.position++;
142
+ } else {
143
+ break;
144
+ }
145
+ }
146
+ return { type: "NUMBER" /* NUMBER */, value: value.includes(".") ? parseFloat(value) : parseInt(value, 10), position: start };
147
+ }
148
+ readKeyword() {
149
+ const start = this.position;
150
+ let value = "";
151
+ while (this.position < this.data.length) {
152
+ const char = String.fromCharCode(this.data[this.position]);
153
+ if (this.isDelimiter(char) || this.isWhitespace(this.data[this.position])) {
154
+ break;
155
+ }
156
+ value += char;
157
+ this.position++;
158
+ }
159
+ const upper = value.toUpperCase();
160
+ if (upper === "OBJ")
161
+ return { type: "OBJ" /* OBJ */, value, position: start };
162
+ if (upper === "ENDOBJ")
163
+ return { type: "ENDOBJ" /* ENDOBJ */, value, position: start };
164
+ if (upper === "STREAM")
165
+ return { type: "STREAM" /* STREAM */, value, position: start };
166
+ if (upper === "ENDSTREAM")
167
+ return { type: "ENDSTREAM" /* ENDSTREAM */, value, position: start };
168
+ if (upper === "XREF")
169
+ return { type: "XREF" /* XREF */, value, position: start };
170
+ if (upper === "TRAILER")
171
+ return { type: "TRAILER" /* TRAILER */, value, position: start };
172
+ if (upper === "STARTXREF")
173
+ return { type: "STARTXREF" /* STARTXREF */, value, position: start };
174
+ if (upper === "R")
175
+ return { type: "R" /* R */, value, position: start };
176
+ if (upper === "TRUE")
177
+ return { type: "BOOLEAN" /* BOOLEAN */, value: true, position: start };
178
+ if (upper === "FALSE")
179
+ return { type: "BOOLEAN" /* BOOLEAN */, value: false, position: start };
180
+ if (upper === "NULL")
181
+ return { type: "NULL" /* NULL */, value: null, position: start };
182
+ return { type: "NAME" /* NAME */, value, position: start };
183
+ }
184
+ isDelimiter(char) {
185
+ return ["(", ")", "<", ">", "[", "]", "{", "}", "/", "%"].includes(char);
186
+ }
187
+ isWhitespace(byte) {
188
+ return byte === 32 || byte === 9 || byte === 10 || byte === 13 || byte === 0;
189
+ }
190
+ }
191
+ // src/parsing/parser.ts
192
+ class PDFParser {
193
+ lexer;
194
+ currentToken;
195
+ nextToken = null;
196
+ data;
197
+ constructor(data) {
198
+ this.data = data;
199
+ this.lexer = new PDFLexer(data);
200
+ this.currentToken = this.lexer.nextToken();
201
+ }
202
+ parseValue() {
203
+ switch (this.currentToken.type) {
204
+ case "NUMBER" /* NUMBER */:
205
+ return this.parseNumberOrRef();
206
+ case "STRING" /* STRING */:
207
+ return this.parseString();
208
+ case "NAME" /* NAME */:
209
+ return this.parseName();
210
+ case "BOOLEAN" /* BOOLEAN */:
211
+ return this.parseBoolean();
212
+ case "NULL" /* NULL */:
213
+ return this.parseNull();
214
+ case "ARRAY_START" /* ARRAY_START */:
215
+ return this.parseArray();
216
+ case "DICT_START" /* DICT_START */:
217
+ return this.parseDictionary();
218
+ default:
219
+ throw new Error(`Unexpected token: ${this.currentToken.type}`);
220
+ }
221
+ }
222
+ parseNumberOrRef() {
223
+ const first = this.currentToken.value;
224
+ this.advance();
225
+ if (this.currentToken.type === "NUMBER" /* NUMBER */) {
226
+ const second = this.currentToken.value;
227
+ this.advance();
228
+ if (this.currentToken.type === "R" /* R */) {
229
+ this.advance();
230
+ return createRef(first, second);
231
+ }
232
+ const thirdToken = this.currentToken;
233
+ this.currentToken = { type: "NUMBER" /* NUMBER */, value: second, position: 0 };
234
+ this.nextToken = thirdToken;
235
+ return first;
236
+ }
237
+ return first;
238
+ }
239
+ parseString() {
240
+ const value = this.currentToken.value;
241
+ this.advance();
242
+ return value;
243
+ }
244
+ parseName() {
245
+ const value = this.currentToken.value;
246
+ this.advance();
247
+ return createName(value);
248
+ }
249
+ parseBoolean() {
250
+ const value = this.currentToken.value;
251
+ this.advance();
252
+ return value;
253
+ }
254
+ parseNull() {
255
+ this.advance();
256
+ return null;
257
+ }
258
+ parseArray() {
259
+ this.advance();
260
+ const values = [];
261
+ while (this.currentToken.type !== "ARRAY_END" /* ARRAY_END */) {
262
+ if (this.currentToken.type === "EOF" /* EOF */) {
263
+ throw new Error("Unexpected EOF in array");
264
+ }
265
+ values.push(this.parseValue());
266
+ }
267
+ this.advance();
268
+ return createArray(values);
269
+ }
270
+ parseDictionary() {
271
+ this.advance();
272
+ const entries = {};
273
+ while (this.currentToken.type !== "DICT_END" /* DICT_END */) {
274
+ if (this.currentToken.type === "EOF" /* EOF */) {
275
+ throw new Error("Unexpected EOF in dictionary");
276
+ }
277
+ if (this.currentToken.type !== "NAME" /* NAME */) {
278
+ throw new Error(`Expected name in dictionary, got ${this.currentToken.type}`);
279
+ }
280
+ const key = this.currentToken.value;
281
+ this.advance();
282
+ const value = this.parseValue();
283
+ entries[key] = value;
284
+ }
285
+ this.advance();
286
+ return createDictionary(entries);
287
+ }
288
+ parseIndirectObject() {
289
+ if (this.currentToken.type !== "NUMBER" /* NUMBER */) {
290
+ throw new Error("Expected object number");
291
+ }
292
+ const objectNumber = this.currentToken.value;
293
+ this.advance();
294
+ if (this.currentToken.type !== "NUMBER" /* NUMBER */) {
295
+ throw new Error("Expected generation number");
296
+ }
297
+ const generation = this.currentToken.value;
298
+ this.advance();
299
+ if (this.currentToken.type !== "OBJ" /* OBJ */) {
300
+ throw new Error("Expected 'obj' keyword");
301
+ }
302
+ this.advance();
303
+ let value = this.parseValue();
304
+ if (this.currentToken.type === "STREAM" /* STREAM */) {
305
+ value = this.parseStream(value);
306
+ }
307
+ if (this.currentToken.type !== "ENDOBJ" /* ENDOBJ */) {
308
+ throw new Error("Expected 'endobj' keyword");
309
+ }
310
+ this.advance();
311
+ return {
312
+ ref: createRef(objectNumber, generation),
313
+ value
314
+ };
315
+ }
316
+ parseStream(dictionary) {
317
+ const streamKeywordPos = this.currentToken.position;
318
+ this.advance();
319
+ let streamDataStart = streamKeywordPos + 6;
320
+ while (streamDataStart < this.data.length) {
321
+ const byte = this.data[streamDataStart];
322
+ if (byte === 13 || byte === 10) {
323
+ streamDataStart++;
324
+ if (byte === 13 && this.data[streamDataStart] === 10) {
325
+ streamDataStart++;
326
+ }
327
+ break;
328
+ }
329
+ streamDataStart++;
330
+ }
331
+ const length = dictionary.Length;
332
+ if (typeof length !== "number") {
333
+ throw new Error("Stream dictionary missing Length");
334
+ }
335
+ const data = this.data.slice(streamDataStart, streamDataStart + length);
336
+ while (this.currentToken.type !== "ENDSTREAM" /* ENDSTREAM */ && this.currentToken.type !== "EOF" /* EOF */) {
337
+ this.advance();
338
+ }
339
+ if (this.currentToken.type !== "ENDSTREAM" /* ENDSTREAM */) {
340
+ throw new Error("Expected 'endstream' keyword");
341
+ }
342
+ this.advance();
343
+ return createStream(data, dictionary);
344
+ }
345
+ advance() {
346
+ if (this.nextToken !== null) {
347
+ this.currentToken = this.nextToken;
348
+ this.nextToken = null;
349
+ } else {
350
+ this.currentToken = this.lexer.nextToken();
351
+ }
352
+ }
353
+ hasMore() {
354
+ return this.currentToken.type !== "EOF" /* EOF */;
355
+ }
356
+ }
357
+ // src/errors.ts
358
+ class PDFError extends Error {
359
+ constructor(message) {
360
+ super(message);
361
+ this.name = "PDFError";
362
+ if (Error.captureStackTrace) {
363
+ Error.captureStackTrace(this, this.constructor);
364
+ }
365
+ }
366
+ }
367
+
368
+ class PDFParseError extends PDFError {
369
+ offset;
370
+ constructor(message, offset) {
371
+ super(message);
372
+ this.offset = offset;
373
+ this.name = "PDFParseError";
374
+ }
375
+ }
376
+
377
+ class PDFGenerationError extends PDFError {
378
+ constructor(message) {
379
+ super(message);
380
+ this.name = "PDFGenerationError";
381
+ }
382
+ }
383
+
384
+ class InvalidPDFObjectError extends PDFError {
385
+ objectType;
386
+ constructor(objectType, reason) {
387
+ super(`Invalid ${objectType}: ${reason}`);
388
+ this.objectType = objectType;
389
+ this.name = "InvalidPDFObjectError";
390
+ }
391
+ }
392
+
393
+ class FontNotFoundError extends PDFError {
394
+ fontName;
395
+ constructor(fontName) {
396
+ super(`Font not found: ${fontName}`);
397
+ this.fontName = fontName;
398
+ this.name = "FontNotFoundError";
399
+ }
400
+ }
401
+
402
+ class InvalidImageError extends PDFError {
403
+ constructor(reason) {
404
+ super(`Invalid image: ${reason}`);
405
+ this.name = "InvalidImageError";
406
+ }
407
+ }
408
+
409
+ class PDFSignatureError extends PDFError {
410
+ constructor(reason) {
411
+ super(`PDF signature error: ${reason}`);
412
+ this.name = "PDFSignatureError";
413
+ }
414
+ }
415
+
416
+ class PDFEncryptionError extends PDFError {
417
+ constructor(reason) {
418
+ super(`PDF encryption error: ${reason}`);
419
+ this.name = "PDFEncryptionError";
420
+ }
421
+ }
422
+
423
+ class NotImplementedError extends PDFError {
424
+ constructor(feature) {
425
+ super(`Feature not yet implemented: ${feature}`);
426
+ this.name = "NotImplementedError";
427
+ }
428
+ }
429
+
430
+ // src/parsing/reader.ts
431
+ class PDFReader {
432
+ data;
433
+ objects = new Map;
434
+ constructor(data) {
435
+ this.data = data;
436
+ }
437
+ parse() {
438
+ const xrefOffset = this.findStartXRef();
439
+ const xrefTable = this.parseXRefTable(xrefOffset);
440
+ const trailer = this.parseTrailer(xrefOffset);
441
+ const catalogRef = trailer.Root;
442
+ this.readObjects(xrefTable);
443
+ const version = this.parseVersion();
444
+ const pages = this.parsePages(catalogRef);
445
+ return {
446
+ version,
447
+ catalog: catalogRef,
448
+ pages,
449
+ objects: this.objects
450
+ };
451
+ }
452
+ findStartXRef() {
453
+ const decoder = new TextDecoder;
454
+ const content = decoder.decode(this.data);
455
+ const match = content.match(/startxref\s+(\d+)/);
456
+ if (!match) {
457
+ throw new PDFParseError("Could not find startxref");
458
+ }
459
+ return parseInt(match[1], 10);
460
+ }
461
+ parseXRefTable(offset) {
462
+ const decoder = new TextDecoder;
463
+ const content = decoder.decode(this.data.slice(offset));
464
+ const lines = content.split(`
465
+ `);
466
+ const xref = new Map;
467
+ let i = 0;
468
+ while (i < lines.length && !lines[i].trim().startsWith("xref"))
469
+ i++;
470
+ i++;
471
+ while (i < lines.length && !lines[i].trim().startsWith("trailer")) {
472
+ const subsection = lines[i].trim().split(/\s+/);
473
+ if (subsection.length === 2) {
474
+ const start = parseInt(subsection[0], 10);
475
+ const count = parseInt(subsection[1], 10);
476
+ i++;
477
+ for (let j = 0;j < count; j++) {
478
+ const entry = lines[i].trim().split(/\s+/);
479
+ if (entry.length >= 3 && entry[2] === "n") {
480
+ const offset2 = parseInt(entry[0], 10);
481
+ xref.set(start + j, offset2);
482
+ }
483
+ i++;
484
+ }
485
+ } else {
486
+ i++;
487
+ }
488
+ }
489
+ return xref;
490
+ }
491
+ parseTrailer(xrefOffset) {
492
+ const decoder = new TextDecoder;
493
+ const content = decoder.decode(this.data.slice(xrefOffset));
494
+ const trailerMatch = content.match(/trailer\s*<<[\s\S]*?>>/);
495
+ if (!trailerMatch) {
496
+ throw new PDFParseError("Could not find trailer");
497
+ }
498
+ const parser = new PDFParser(new TextEncoder().encode(trailerMatch[0].replace("trailer", "")));
499
+ return parser.parseValue();
500
+ }
501
+ readObjects(xrefTable) {
502
+ for (const [objectNum, offset] of xrefTable) {
503
+ try {
504
+ const objData = this.data.slice(offset);
505
+ const parser = new PDFParser(objData);
506
+ const obj = parser.parseIndirectObject();
507
+ this.objects.set(objectNum, obj.value);
508
+ } catch (error) {}
509
+ }
510
+ }
511
+ parseVersion() {
512
+ const decoder = new TextDecoder;
513
+ const header = decoder.decode(this.data.slice(0, 20));
514
+ const match = header.match(/%PDF-(\d+\.\d+)/);
515
+ return match ? match[1] : "1.7";
516
+ }
517
+ parsePages(catalogRef) {
518
+ const catalog = this.objects.get(catalogRef.objectNumber);
519
+ if (!catalog) {
520
+ throw new PDFParseError("Catalog not found");
521
+ }
522
+ const pagesRef = catalog.Pages;
523
+ const pagesTree = this.objects.get(pagesRef.objectNumber);
524
+ if (!pagesTree) {
525
+ throw new PDFParseError("Pages tree not found");
526
+ }
527
+ const kids = pagesTree.Kids;
528
+ const pages = [];
529
+ for (const kidRef of kids) {
530
+ if (typeof kidRef === "object" && "objectNumber" in kidRef) {
531
+ const page = this.parsePage(kidRef);
532
+ if (page)
533
+ pages.push(page);
534
+ }
535
+ }
536
+ return pages;
537
+ }
538
+ parsePage(ref) {
539
+ const pageDict = this.objects.get(ref.objectNumber);
540
+ if (!pageDict)
541
+ return null;
542
+ const mediaBox = pageDict.MediaBox;
543
+ const size = {
544
+ width: mediaBox[2],
545
+ height: mediaBox[3]
546
+ };
547
+ let content = "";
548
+ const contentsRef = pageDict.Contents;
549
+ if (contentsRef && typeof contentsRef === "object" && "objectNumber" in contentsRef) {
550
+ content = this.extractText(contentsRef);
551
+ }
552
+ return { ref, size, content };
553
+ }
554
+ extractText(ref) {
555
+ const stream = this.objects.get(ref.objectNumber);
556
+ if (!stream || !stream.data)
557
+ return "";
558
+ const decoder = new TextDecoder;
559
+ const content = decoder.decode(stream.data);
560
+ const texts = [];
561
+ const regex = /\(([^)]*)\)\s*Tj/g;
562
+ let match;
563
+ while ((match = regex.exec(content)) !== null) {
564
+ texts.push(match[1]);
565
+ }
566
+ return texts.join(" ");
567
+ }
568
+ }
569
+ export { PDFError, PDFParseError, PDFGenerationError, InvalidPDFObjectError, FontNotFoundError, InvalidImageError, PDFSignatureError, PDFEncryptionError, NotImplementedError, TokenType, PDFLexer, PDFParser, PDFReader };
570
+
571
+ //# debugId=2D25678A9DC8958E64756E2164756E21
572
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL3BhcnNpbmcvbGV4ZXIudHMiLCAic3JjL3BhcnNpbmcvcGFyc2VyLnRzIiwgInNyYy9lcnJvcnMudHMiLCAic3JjL3BhcnNpbmcvcmVhZGVyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgIi8qKlxuICogUERGIHRva2VuIHR5cGVzXG4gKi9cbmV4cG9ydCBlbnVtIFRva2VuVHlwZSB7XG4gICAvLyBQcmltaXRpdmVzXG4gICBOVU1CRVIgPSBcIk5VTUJFUlwiLFxuICAgU1RSSU5HID0gXCJTVFJJTkdcIixcbiAgIE5BTUUgPSBcIk5BTUVcIixcbiAgIEJPT0xFQU4gPSBcIkJPT0xFQU5cIixcbiAgIE5VTEwgPSBcIk5VTExcIixcblxuICAgLy8gRGVsaW1pdGVyc1xuICAgQVJSQVlfU1RBUlQgPSBcIkFSUkFZX1NUQVJUXCIsICAgICAvLyBbXG4gICBBUlJBWV9FTkQgPSBcIkFSUkFZX0VORFwiLCAgICAgICAgIC8vIF1cbiAgIERJQ1RfU1RBUlQgPSBcIkRJQ1RfU1RBUlRcIiwgICAgICAgLy8gPDxcbiAgIERJQ1RfRU5EID0gXCJESUNUX0VORFwiLCAgICAgICAgICAgLy8gPj5cblxuICAgLy8gS2V5d29yZHNcbiAgIE9CSiA9IFwiT0JKXCIsICAgICAgICAgICAgICAgICAgICAgLy8gb2JqXG4gICBFTkRPQkogPSBcIkVORE9CSlwiLCAgICAgICAgICAgICAgIC8vIGVuZG9ialxuICAgU1RSRUFNID0gXCJTVFJFQU1cIiwgICAgICAgICAgICAgICAvLyBzdHJlYW1cbiAgIEVORFNUUkVBTSA9IFwiRU5EU1RSRUFNXCIsICAgICAgICAgLy8gZW5kc3RyZWFtXG4gICBYUkVGID0gXCJYUkVGXCIsICAgICAgICAgICAgICAgICAgIC8vIHhyZWZcbiAgIFRSQUlMRVIgPSBcIlRSQUlMRVJcIiwgICAgICAgICAgICAgLy8gdHJhaWxlclxuICAgU1RBUlRYUkVGID0gXCJTVEFSVFhSRUZcIiwgICAgICAgICAvLyBzdGFydHhyZWZcbiAgIFIgPSBcIlJcIiwgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUiAocmVmZXJlbmNlKVxuXG4gICAvLyBTcGVjaWFsXG4gICBFT0YgPSBcIkVPRlwiLFxufVxuXG4vKipcbiAqIFBERiB0b2tlblxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuIHtcbiAgIHR5cGU6IFRva2VuVHlwZTtcbiAgIHZhbHVlOiBhbnk7XG4gICBwb3NpdGlvbjogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBERiBMZXhlclxuICovXG5leHBvcnQgY2xhc3MgUERGTGV4ZXIge1xuICAgcHJpdmF0ZSBkYXRhOiBVaW50OEFycmF5O1xuICAgcHJpdmF0ZSBwb3NpdGlvbjogbnVtYmVyID0gMDtcblxuICAgY29uc3RydWN0b3IoZGF0YTogVWludDhBcnJheSkge1xuICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBHZXQgbmV4dCB0b2tlblxuICAgICovXG4gICBuZXh0VG9rZW4oKTogVG9rZW4ge1xuICAgICAgdGhpcy5za2lwV2hpdGVzcGFjZSgpO1xuXG4gICAgICBpZiAodGhpcy5wb3NpdGlvbiA+PSB0aGlzLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuRU9GLCB2YWx1ZTogbnVsbCwgcG9zaXRpb246IHRoaXMucG9zaXRpb24gfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hhciA9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5kYXRhW3RoaXMucG9zaXRpb25dKTtcblxuICAgICAgLy8gRGVsaW1pdGVyc1xuICAgICAgaWYgKGNoYXIgPT09IFwiW1wiKSB7XG4gICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICAgICByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuQVJSQVlfU1RBUlQsIHZhbHVlOiBcIltcIiwgcG9zaXRpb246IHRoaXMucG9zaXRpb24gLSAxIH07XG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gXCJdXCIpIHtcbiAgICAgICAgIHRoaXMucG9zaXRpb24rKztcbiAgICAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5BUlJBWV9FTkQsIHZhbHVlOiBcIl1cIiwgcG9zaXRpb246IHRoaXMucG9zaXRpb24gLSAxIH07XG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gXCI8XCIgJiYgdGhpcy5wZWVrKCkgPT09IFwiPFwiKSB7XG4gICAgICAgICB0aGlzLnBvc2l0aW9uICs9IDI7XG4gICAgICAgICByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuRElDVF9TVEFSVCwgdmFsdWU6IFwiPDxcIiwgcG9zaXRpb246IHRoaXMucG9zaXRpb24gLSAyIH07XG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gXCI+XCIgJiYgdGhpcy5wZWVrKCkgPT09IFwiPlwiKSB7XG4gICAgICAgICB0aGlzLnBvc2l0aW9uICs9IDI7XG4gICAgICAgICByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuRElDVF9FTkQsIHZhbHVlOiBcIj4+XCIsIHBvc2l0aW9uOiB0aGlzLnBvc2l0aW9uIC0gMiB9O1xuICAgICAgfVxuXG4gICAgICAvLyBOYW1lIChzdGFydHMgd2l0aCAvKVxuICAgICAgaWYgKGNoYXIgPT09IFwiL1wiKSB7XG4gICAgICAgICByZXR1cm4gdGhpcy5yZWFkTmFtZSgpO1xuICAgICAgfVxuXG4gICAgICAvLyBTdHJpbmcgKHN0YXJ0cyB3aXRoICgpXG4gICAgICBpZiAoY2hhciA9PT0gXCIoXCIpIHtcbiAgICAgICAgIHJldHVybiB0aGlzLnJlYWRTdHJpbmcoKTtcbiAgICAgIH1cblxuICAgICAgLy8gTnVtYmVyIG9yIGtleXdvcmRcbiAgICAgIGlmIChjaGFyID09PSBcIi1cIiB8fCBjaGFyID09PSBcIitcIiB8fCBjaGFyID09PSBcIi5cIiB8fCAoY2hhciA+PSBcIjBcIiAmJiBjaGFyIDw9IFwiOVwiKSkge1xuICAgICAgICAgcmV0dXJuIHRoaXMucmVhZE51bWJlcigpO1xuICAgICAgfVxuXG4gICAgICAvLyBLZXl3b3JkIG9yIGJvb2xlYW5cbiAgICAgIHJldHVybiB0aGlzLnJlYWRLZXl3b3JkKCk7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGVlayBhdCBuZXh0IGNoYXJhY3RlciB3aXRob3V0IGNvbnN1bWluZ1xuICAgICovXG4gICBwcml2YXRlIHBlZWsoKTogc3RyaW5nIHtcbiAgICAgIGlmICh0aGlzLnBvc2l0aW9uICsgMSA+PSB0aGlzLmRhdGEubGVuZ3RoKSByZXR1cm4gXCJcIjtcbiAgICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uICsgMV0pO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFNraXAgd2hpdGVzcGFjZSBhbmQgY29tbWVudHNcbiAgICAqL1xuICAgcHJpdmF0ZSBza2lwV2hpdGVzcGFjZSgpOiB2b2lkIHtcbiAgICAgIHdoaWxlICh0aGlzLnBvc2l0aW9uIDwgdGhpcy5kYXRhLmxlbmd0aCkge1xuICAgICAgICAgY29uc3QgY2hhciA9IHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXTtcblxuICAgICAgICAgLy8gV2hpdGVzcGFjZVxuICAgICAgICAgaWYgKGNoYXIgPT09IDB4MjAgfHwgY2hhciA9PT0gMHgwOSB8fCBjaGFyID09PSAweDBBIHx8IGNoYXIgPT09IDB4MEQgfHwgY2hhciA9PT0gMHgwMCkge1xuICAgICAgICAgICAgdGhpcy5wb3NpdGlvbisrO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICB9XG5cbiAgICAgICAgIC8vIENvbW1lbnQgKHN0YXJ0cyB3aXRoICUpXG4gICAgICAgICBpZiAoY2hhciA9PT0gMHgyNSkge1xuICAgICAgICAgICAgd2hpbGUgKHRoaXMucG9zaXRpb24gPCB0aGlzLmRhdGEubGVuZ3RoICYmIHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSAhPT0gMHgwQSAmJiB0aGlzLmRhdGFbdGhpcy5wb3NpdGlvbl0gIT09IDB4MEQpIHtcbiAgICAgICAgICAgICAgIHRoaXMucG9zaXRpb24rKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgfVxuXG4gICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgIH1cblxuICAgLyoqXG4gICAgKiBSZWFkIGEgbmFtZSB0b2tlblxuICAgICovXG4gICBwcml2YXRlIHJlYWROYW1lKCk6IFRva2VuIHtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5wb3NpdGlvbjtcbiAgICAgIHRoaXMucG9zaXRpb24rKzsgLy8gU2tpcCAvXG5cbiAgICAgIGxldCB2YWx1ZSA9IFwiXCI7XG4gICAgICB3aGlsZSAodGhpcy5wb3NpdGlvbiA8IHRoaXMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgIGNvbnN0IGNoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSk7XG4gICAgICAgICBpZiAodGhpcy5pc0RlbGltaXRlcihjaGFyKSB8fCB0aGlzLmlzV2hpdGVzcGFjZSh0aGlzLmRhdGFbdGhpcy5wb3NpdGlvbl0pKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgIH1cbiAgICAgICAgIHZhbHVlICs9IGNoYXI7XG4gICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5OQU1FLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICB9XG5cbiAgIC8qKlxuICAgICogUmVhZCBhIHN0cmluZyB0b2tlblxuICAgICovXG4gICBwcml2YXRlIHJlYWRTdHJpbmcoKTogVG9rZW4ge1xuICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLnBvc2l0aW9uO1xuICAgICAgdGhpcy5wb3NpdGlvbisrOyAvLyBTa2lwIChcblxuICAgICAgbGV0IHZhbHVlID0gXCJcIjtcbiAgICAgIGxldCBkZXB0aCA9IDE7XG5cbiAgICAgIHdoaWxlICh0aGlzLnBvc2l0aW9uIDwgdGhpcy5kYXRhLmxlbmd0aCAmJiBkZXB0aCA+IDApIHtcbiAgICAgICAgIGNvbnN0IGNoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSk7XG5cbiAgICAgICAgIGlmIChjaGFyID09PSBcIlxcXFxcIikge1xuICAgICAgICAgICAgLy8gRXNjYXBlIHNlcXVlbmNlXG4gICAgICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICAgICAgICBpZiAodGhpcy5wb3NpdGlvbiA8IHRoaXMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgIGNvbnN0IGVzY2FwZWQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSk7XG4gICAgICAgICAgICAgICB2YWx1ZSArPSBlc2NhcGVkID09PSBcIm5cIiA/IFwiXFxuXCIgOiBlc2NhcGVkID09PSBcInJcIiA/IFwiXFxyXCIgOiBlc2NhcGVkID09PSBcInRcIiA/IFwiXFx0XCIgOiBlc2NhcGVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgfSBlbHNlIGlmIChjaGFyID09PSBcIihcIikge1xuICAgICAgICAgICAgZGVwdGgrKztcbiAgICAgICAgICAgIHZhbHVlICs9IGNoYXI7XG4gICAgICAgICB9IGVsc2UgaWYgKGNoYXIgPT09IFwiKVwiKSB7XG4gICAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICAgICAgaWYgKGRlcHRoID4gMCkgdmFsdWUgKz0gY2hhcjtcbiAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZSArPSBjaGFyO1xuICAgICAgICAgfVxuXG4gICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5TVFJJTkcsIHZhbHVlLCBwb3NpdGlvbjogc3RhcnQgfTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBSZWFkIGEgbnVtYmVyIHRva2VuXG4gICAgKi9cbiAgIHByaXZhdGUgcmVhZE51bWJlcigpOiBUb2tlbiB7XG4gICAgICBjb25zdCBzdGFydCA9IHRoaXMucG9zaXRpb247XG4gICAgICBsZXQgdmFsdWUgPSBcIlwiO1xuXG4gICAgICB3aGlsZSAodGhpcy5wb3NpdGlvbiA8IHRoaXMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgIGNvbnN0IGNoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZGF0YVt0aGlzLnBvc2l0aW9uXSk7XG4gICAgICAgICBpZiAoY2hhciA9PT0gXCItXCIgfHwgY2hhciA9PT0gXCIrXCIgfHwgY2hhciA9PT0gXCIuXCIgfHwgKGNoYXIgPj0gXCIwXCIgJiYgY2hhciA8PSBcIjlcIikpIHtcbiAgICAgICAgICAgIHZhbHVlICs9IGNoYXI7XG4gICAgICAgICAgICB0aGlzLnBvc2l0aW9uKys7XG4gICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5OVU1CRVIsIHZhbHVlOiB2YWx1ZS5pbmNsdWRlcyhcIi5cIikgPyBwYXJzZUZsb2F0KHZhbHVlKSA6IHBhcnNlSW50KHZhbHVlLCAxMCksIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFJlYWQgYSBrZXl3b3JkIHRva2VuXG4gICAgKi9cbiAgIHByaXZhdGUgcmVhZEtleXdvcmQoKTogVG9rZW4ge1xuICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLnBvc2l0aW9uO1xuICAgICAgbGV0IHZhbHVlID0gXCJcIjtcblxuICAgICAgd2hpbGUgKHRoaXMucG9zaXRpb24gPCB0aGlzLmRhdGEubGVuZ3RoKSB7XG4gICAgICAgICBjb25zdCBjaGFyID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmRhdGFbdGhpcy5wb3NpdGlvbl0pO1xuICAgICAgICAgaWYgKHRoaXMuaXNEZWxpbWl0ZXIoY2hhcikgfHwgdGhpcy5pc1doaXRlc3BhY2UodGhpcy5kYXRhW3RoaXMucG9zaXRpb25dKSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICB9XG4gICAgICAgICB2YWx1ZSArPSBjaGFyO1xuICAgICAgICAgdGhpcy5wb3NpdGlvbisrO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBmb3Iga2V5d29yZHNcbiAgICAgIGNvbnN0IHVwcGVyID0gdmFsdWUudG9VcHBlckNhc2UoKTtcbiAgICAgIGlmICh1cHBlciA9PT0gXCJPQkpcIikgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLk9CSiwgdmFsdWUsIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgICAgaWYgKHVwcGVyID09PSBcIkVORE9CSlwiKSByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuRU5ET0JKLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICAgICBpZiAodXBwZXIgPT09IFwiU1RSRUFNXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5TVFJFQU0sIHZhbHVlLCBwb3NpdGlvbjogc3RhcnQgfTtcbiAgICAgIGlmICh1cHBlciA9PT0gXCJFTkRTVFJFQU1cIikgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLkVORFNUUkVBTSwgdmFsdWUsIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgICAgaWYgKHVwcGVyID09PSBcIlhSRUZcIikgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLlhSRUYsIHZhbHVlLCBwb3NpdGlvbjogc3RhcnQgfTtcbiAgICAgIGlmICh1cHBlciA9PT0gXCJUUkFJTEVSXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5UUkFJTEVSLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICAgICBpZiAodXBwZXIgPT09IFwiU1RBUlRYUkVGXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5TVEFSVFhSRUYsIHZhbHVlLCBwb3NpdGlvbjogc3RhcnQgfTtcbiAgICAgIGlmICh1cHBlciA9PT0gXCJSXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5SLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICAgICBpZiAodXBwZXIgPT09IFwiVFJVRVwiKSByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuQk9PTEVBTiwgdmFsdWU6IHRydWUsIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgICAgaWYgKHVwcGVyID09PSBcIkZBTFNFXCIpIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5CT09MRUFOLCB2YWx1ZTogZmFsc2UsIHBvc2l0aW9uOiBzdGFydCB9O1xuICAgICAgaWYgKHVwcGVyID09PSBcIk5VTExcIikgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLk5VTEwsIHZhbHVlOiBudWxsLCBwb3NpdGlvbjogc3RhcnQgfTtcblxuICAgICAgLy8gVW5rbm93biBrZXl3b3JkIC0gdHJlYXQgYXMgbmFtZSB3aXRob3V0IC9cbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5OQU1FLCB2YWx1ZSwgcG9zaXRpb246IHN0YXJ0IH07XG4gICB9XG5cbiAgIC8qKlxuICAgICogQ2hlY2sgaWYgY2hhcmFjdGVyIGlzIGRlbGltaXRlclxuICAgICovXG4gICBwcml2YXRlIGlzRGVsaW1pdGVyKGNoYXI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIFtcIihcIiwgXCIpXCIsIFwiPFwiLCBcIj5cIiwgXCJbXCIsIFwiXVwiLCBcIntcIiwgXCJ9XCIsIFwiL1wiLCBcIiVcIl0uaW5jbHVkZXMoY2hhcik7XG4gICB9XG5cbiAgIC8qKlxuICAgICogQ2hlY2sgaWYgYnl0ZSBpcyB3aGl0ZXNwYWNlXG4gICAgKi9cbiAgIHByaXZhdGUgaXNXaGl0ZXNwYWNlKGJ5dGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIGJ5dGUgPT09IDB4MjAgfHwgYnl0ZSA9PT0gMHgwOSB8fCBieXRlID09PSAweDBBIHx8IGJ5dGUgPT09IDB4MEQgfHwgYnl0ZSA9PT0gMHgwMDtcbiAgIH1cbn1cbiIsCiAgICAiaW1wb3J0IHsgUERGTGV4ZXIsIFRva2VuVHlwZSwgdHlwZSBUb2tlbiB9IGZyb20gXCIuL2xleGVyLnRzXCI7XG5pbXBvcnQgdHlwZSB7IFBERlZhbHVlLCBQREZEaWN0aW9uYXJ5LCBQREZBcnJheSwgUERGUmVmLCBQREZTdHJlYW0gfSBmcm9tIFwiLi4vdHlwZXMudHNcIjtcbmltcG9ydCB7IGNyZWF0ZURpY3Rpb25hcnksIGNyZWF0ZUFycmF5LCBjcmVhdGVSZWYsIGNyZWF0ZU5hbWUsIGNyZWF0ZVN0cmVhbSB9IGZyb20gXCIuLi9jb3JlL29iamVjdHMudHNcIjtcblxuLyoqXG4gKiBQREYgUGFyc2VyXG4gKi9cbmV4cG9ydCBjbGFzcyBQREZQYXJzZXIge1xuICAgcHJpdmF0ZSBsZXhlcjogUERGTGV4ZXI7XG4gICBwcml2YXRlIGN1cnJlbnRUb2tlbjogVG9rZW47XG4gICBwcml2YXRlIG5leHRUb2tlbjogVG9rZW4gfCBudWxsID0gbnVsbDtcbiAgIHByaXZhdGUgZGF0YTogVWludDhBcnJheTtcblxuICAgY29uc3RydWN0b3IoZGF0YTogVWludDhBcnJheSkge1xuICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgIHRoaXMubGV4ZXIgPSBuZXcgUERGTGV4ZXIoZGF0YSk7XG4gICAgICB0aGlzLmN1cnJlbnRUb2tlbiA9IHRoaXMubGV4ZXIubmV4dFRva2VuKCk7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2UgYSBQREYgdmFsdWVcbiAgICAqL1xuICAgcGFyc2VWYWx1ZSgpOiBQREZWYWx1ZSB7XG4gICAgICBzd2l0Y2ggKHRoaXMuY3VycmVudFRva2VuLnR5cGUpIHtcbiAgICAgICAgIGNhc2UgVG9rZW5UeXBlLk5VTUJFUjpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcnNlTnVtYmVyT3JSZWYoKTtcbiAgICAgICAgIGNhc2UgVG9rZW5UeXBlLlNUUklORzpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcnNlU3RyaW5nKCk7XG4gICAgICAgICBjYXNlIFRva2VuVHlwZS5OQU1FOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VOYW1lKCk7XG4gICAgICAgICBjYXNlIFRva2VuVHlwZS5CT09MRUFOOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VCb29sZWFuKCk7XG4gICAgICAgICBjYXNlIFRva2VuVHlwZS5OVUxMOlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VOdWxsKCk7XG4gICAgICAgICBjYXNlIFRva2VuVHlwZS5BUlJBWV9TVEFSVDpcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcnNlQXJyYXkoKTtcbiAgICAgICAgIGNhc2UgVG9rZW5UeXBlLkRJQ1RfU1RBUlQ6XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZURpY3Rpb25hcnkoKTtcbiAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgdG9rZW46ICR7dGhpcy5jdXJyZW50VG9rZW4udHlwZX1gKTtcbiAgICAgIH1cbiAgIH1cblxuICAgLyoqXG4gICAgKiBQYXJzZSBudW1iZXIgb3IgcmVmZXJlbmNlIChudW1iZXIgbnVtYmVyIFIpXG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VOdW1iZXJPclJlZigpOiBudW1iZXIgfCBQREZSZWYge1xuICAgICAgY29uc3QgZmlyc3QgPSB0aGlzLmN1cnJlbnRUb2tlbi52YWx1ZSBhcyBudW1iZXI7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIHJlZmVyZW5jZSAodHdvIG51bWJlcnMgZm9sbG93ZWQgYnkgUilcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlID09PSBUb2tlblR5cGUuTlVNQkVSKSB7XG4gICAgICAgICBjb25zdCBzZWNvbmQgPSB0aGlzLmN1cnJlbnRUb2tlbi52YWx1ZSBhcyBudW1iZXI7XG4gICAgICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgICAgaWYgKHRoaXMuY3VycmVudFRva2VuLnR5cGUgPT09IFRva2VuVHlwZS5SKSB7XG4gICAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVSZWYoZmlyc3QsIHNlY29uZCk7XG4gICAgICAgICB9XG5cbiAgICAgICAgIC8vIE5vdCBhIHJlZmVyZW5jZSAtIHdlIGNvbnN1bWVkIHRoZSBzZWNvbmQgbnVtYmVyLCBuZWVkIHRvIHB1dCBpdCBiYWNrXG4gICAgICAgICAvLyBQdXQgdGhlIGN1cnJlbnQgdG9rZW4gKHRoaXJkIHRva2VuKSBpbnRvIG5leHRUb2tlbiBidWZmZXJcbiAgICAgICAgIC8vIFRoZW4gcmVzdG9yZSBzZWNvbmQgbnVtYmVyIGFzIGN1cnJlbnQgdG9rZW5cbiAgICAgICAgIGNvbnN0IHRoaXJkVG9rZW4gPSB0aGlzLmN1cnJlbnRUb2tlbjtcbiAgICAgICAgIHRoaXMuY3VycmVudFRva2VuID0geyB0eXBlOiBUb2tlblR5cGUuTlVNQkVSLCB2YWx1ZTogc2Vjb25kLCBwb3NpdGlvbjogMCB9O1xuICAgICAgICAgdGhpcy5uZXh0VG9rZW4gPSB0aGlyZFRva2VuO1xuICAgICAgICAgcmV0dXJuIGZpcnN0O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmlyc3Q7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2Ugc3RyaW5nXG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VTdHJpbmcoKTogc3RyaW5nIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5jdXJyZW50VG9rZW4udmFsdWUgYXMgc3RyaW5nO1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2UgbmFtZVxuICAgICovXG4gICBwcml2YXRlIHBhcnNlTmFtZSgpOiBQREZWYWx1ZSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuY3VycmVudFRva2VuLnZhbHVlIGFzIHN0cmluZztcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIGNyZWF0ZU5hbWUodmFsdWUpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIGJvb2xlYW5cbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZUJvb2xlYW4oKTogYm9vbGVhbiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuY3VycmVudFRva2VuLnZhbHVlIGFzIGJvb2xlYW47XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBQYXJzZSBudWxsXG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VOdWxsKCk6IG51bGwge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBQYXJzZSBhcnJheVxuICAgICovXG4gICBwcml2YXRlIHBhcnNlQXJyYXkoKTogUERGQXJyYXkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7IC8vIFNraXAgW1xuICAgICAgY29uc3QgdmFsdWVzOiBQREZWYWx1ZVtdID0gW107XG5cbiAgICAgIHdoaWxlICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuQVJSQVlfRU5EKSB7XG4gICAgICAgICBpZiAodGhpcy5jdXJyZW50VG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLkVPRikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5leHBlY3RlZCBFT0YgaW4gYXJyYXlcIik7XG4gICAgICAgICB9XG4gICAgICAgICB2YWx1ZXMucHVzaCh0aGlzLnBhcnNlVmFsdWUoKSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYWR2YW5jZSgpOyAvLyBTa2lwIF1cbiAgICAgIHJldHVybiBjcmVhdGVBcnJheSh2YWx1ZXMpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIGRpY3Rpb25hcnlcbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZURpY3Rpb25hcnkoKTogUERGRGljdGlvbmFyeSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTsgLy8gU2tpcCA8PFxuICAgICAgY29uc3QgZW50cmllczogUmVjb3JkPHN0cmluZywgUERGVmFsdWU+ID0ge307XG5cbiAgICAgIHdoaWxlICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuRElDVF9FTkQpIHtcbiAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlID09PSBUb2tlblR5cGUuRU9GKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIEVPRiBpbiBkaWN0aW9uYXJ5XCIpO1xuICAgICAgICAgfVxuXG4gICAgICAgICAvLyBLZXkgbXVzdCBiZSBhIG5hbWVcbiAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuTkFNRSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBuYW1lIGluIGRpY3Rpb25hcnksIGdvdCAke3RoaXMuY3VycmVudFRva2VuLnR5cGV9YCk7XG4gICAgICAgICB9XG4gICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmN1cnJlbnRUb2tlbi52YWx1ZSBhcyBzdHJpbmc7XG4gICAgICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgICAgLy8gVmFsdWVcbiAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5wYXJzZVZhbHVlKCk7XG4gICAgICAgICBlbnRyaWVzW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hZHZhbmNlKCk7IC8vIFNraXAgPj5cbiAgICAgIHJldHVybiBjcmVhdGVEaWN0aW9uYXJ5KGVudHJpZXMpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIGluZGlyZWN0IG9iamVjdFxuICAgICovXG4gICBwYXJzZUluZGlyZWN0T2JqZWN0KCk6IHsgcmVmOiBQREZSZWY7IHZhbHVlOiBQREZWYWx1ZSB9IHtcbiAgICAgIC8vIFBhcnNlOiBvYmplY3ROdW1iZXIgZ2VuZXJhdGlvbiBvYmpcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuTlVNQkVSKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCBvYmplY3QgbnVtYmVyXCIpO1xuICAgICAgfVxuICAgICAgY29uc3Qgb2JqZWN0TnVtYmVyID0gdGhpcy5jdXJyZW50VG9rZW4udmFsdWUgYXMgbnVtYmVyO1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG5cbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuTlVNQkVSKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCBnZW5lcmF0aW9uIG51bWJlclwiKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGdlbmVyYXRpb24gPSB0aGlzLmN1cnJlbnRUb2tlbi52YWx1ZSBhcyBudW1iZXI7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgaWYgKHRoaXMuY3VycmVudFRva2VuLnR5cGUgIT09IFRva2VuVHlwZS5PQkopIHtcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkICdvYmonIGtleXdvcmRcIik7XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcblxuICAgICAgLy8gUGFyc2Ugb2JqZWN0IHZhbHVlXG4gICAgICBsZXQgdmFsdWU6IFBERlZhbHVlID0gdGhpcy5wYXJzZVZhbHVlKCk7XG5cbiAgICAgIC8vIENoZWNrIGZvciBzdHJlYW1cbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlID09PSBUb2tlblR5cGUuU1RSRUFNKSB7XG4gICAgICAgICB2YWx1ZSA9IHRoaXMucGFyc2VTdHJlYW0odmFsdWUgYXMgUERGRGljdGlvbmFyeSk7XG4gICAgICB9XG5cbiAgICAgIC8vIEV4cGVjdCBlbmRvYmpcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuRU5ET0JKKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCAnZW5kb2JqJyBrZXl3b3JkXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5hZHZhbmNlKCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgICByZWY6IGNyZWF0ZVJlZihvYmplY3ROdW1iZXIsIGdlbmVyYXRpb24pLFxuICAgICAgICAgdmFsdWUsXG4gICAgICB9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIHN0cmVhbSAoZGljdGlvbmFyeSBhbHJlYWR5IHBhcnNlZClcbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZVN0cmVhbShkaWN0aW9uYXJ5OiBQREZEaWN0aW9uYXJ5KTogUERGU3RyZWFtIHtcbiAgICAgIC8vIEdldCBjdXJyZW50IHBvc2l0aW9uIHdoZXJlICdzdHJlYW0nIGtleXdvcmQgaXNcbiAgICAgIGNvbnN0IHN0cmVhbUtleXdvcmRQb3MgPSB0aGlzLmN1cnJlbnRUb2tlbi5wb3NpdGlvbjtcbiAgICAgIHRoaXMuYWR2YW5jZSgpOyAvLyBTa2lwICdzdHJlYW0nXG5cbiAgICAgIC8vIEZpbmQgdGhlIGFjdHVhbCBzdGFydCBvZiBzdHJlYW0gZGF0YSAoYWZ0ZXIgJ3N0cmVhbScga2V5d29yZCBhbmQgbmV3bGluZSlcbiAgICAgIC8vIFRoZSBzdHJlYW0ga2V5d29yZCBpcyBmb2xsb3dlZCBieSBlaXRoZXIgXFxuIG9yIFxcclxcblxuICAgICAgbGV0IHN0cmVhbURhdGFTdGFydCA9IHN0cmVhbUtleXdvcmRQb3MgKyA2OyAvLyAnc3RyZWFtJyBpcyA2IGNoYXJhY3RlcnNcbiAgICAgIFxuICAgICAgLy8gU2tpcCB0aGUgbmV3bGluZSBhZnRlciAnc3RyZWFtJ1xuICAgICAgd2hpbGUgKHN0cmVhbURhdGFTdGFydCA8IHRoaXMuZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgIGNvbnN0IGJ5dGUgPSB0aGlzLmRhdGFbc3RyZWFtRGF0YVN0YXJ0XTtcbiAgICAgICAgIGlmIChieXRlID09PSAweDBEIHx8IGJ5dGUgPT09IDB4MEEpIHsgLy8gXFxyIG9yIFxcblxuICAgICAgICAgICAgc3RyZWFtRGF0YVN0YXJ0Kys7XG4gICAgICAgICAgICAvLyBIYW5kbGUgXFxyXFxuXG4gICAgICAgICAgICBpZiAoYnl0ZSA9PT0gMHgwRCAmJiB0aGlzLmRhdGFbc3RyZWFtRGF0YVN0YXJ0XSA9PT0gMHgwQSkge1xuICAgICAgICAgICAgICAgc3RyZWFtRGF0YVN0YXJ0Kys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgIH1cbiAgICAgICAgIHN0cmVhbURhdGFTdGFydCsrO1xuICAgICAgfVxuXG4gICAgICAvLyBHZXQgc3RyZWFtIGxlbmd0aFxuICAgICAgY29uc3QgbGVuZ3RoID0gZGljdGlvbmFyeS5MZW5ndGggYXMgbnVtYmVyO1xuICAgICAgaWYgKHR5cGVvZiBsZW5ndGggIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlN0cmVhbSBkaWN0aW9uYXJ5IG1pc3NpbmcgTGVuZ3RoXCIpO1xuICAgICAgfVxuXG4gICAgICAvLyBFeHRyYWN0IHN0cmVhbSBkYXRhXG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5kYXRhLnNsaWNlKHN0cmVhbURhdGFTdGFydCwgc3RyZWFtRGF0YVN0YXJ0ICsgbGVuZ3RoKTtcblxuICAgICAgLy8gU2tpcCB0byBlbmRzdHJlYW1cbiAgICAgIHdoaWxlICh0aGlzLmN1cnJlbnRUb2tlbi50eXBlICE9PSBUb2tlblR5cGUuRU5EU1RSRUFNICYmIHRoaXMuY3VycmVudFRva2VuLnR5cGUgIT09IFRva2VuVHlwZS5FT0YpIHtcbiAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5jdXJyZW50VG9rZW4udHlwZSAhPT0gVG9rZW5UeXBlLkVORFNUUkVBTSkge1xuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgJ2VuZHN0cmVhbScga2V5d29yZFwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuXG4gICAgICByZXR1cm4gY3JlYXRlU3RyZWFtKGRhdGEsIGRpY3Rpb25hcnkpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIEFkdmFuY2UgdG8gbmV4dCB0b2tlblxuICAgICovXG4gICBwcml2YXRlIGFkdmFuY2UoKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5uZXh0VG9rZW4gIT09IG51bGwpIHtcbiAgICAgICAgIHRoaXMuY3VycmVudFRva2VuID0gdGhpcy5uZXh0VG9rZW47XG4gICAgICAgICB0aGlzLm5leHRUb2tlbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgdGhpcy5jdXJyZW50VG9rZW4gPSB0aGlzLmxleGVyLm5leHRUb2tlbigpO1xuICAgICAgfVxuICAgfVxuXG4gICAvKipcbiAgICAqIENoZWNrIGlmIG1vcmUgdG9rZW5zIGF2YWlsYWJsZVxuICAgICovXG4gICBoYXNNb3JlKCk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFRva2VuLnR5cGUgIT09IFRva2VuVHlwZS5FT0Y7XG4gICB9XG59XG4iLAogICAgIi8qKlxuICogQmFzZSBlcnJvciBjbGFzcyBmb3IgYWxsIFBERiBlcnJvcnNcbiAqL1xuZXhwb3J0IGNsYXNzIFBERkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgIHRoaXMubmFtZSA9IFwiUERGRXJyb3JcIjtcbiAgICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7XG4gICAgICB9XG4gICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gUERGIHBhcnNpbmcgZmFpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIFBERlBhcnNlRXJyb3IgZXh0ZW5kcyBQREZFcnJvciB7XG4gICBjb25zdHJ1Y3RvcihcbiAgICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICAgIHB1YmxpYyByZWFkb25seSBvZmZzZXQ/OiBudW1iZXIsXG4gICApIHtcbiAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgdGhpcy5uYW1lID0gXCJQREZQYXJzZUVycm9yXCI7XG4gICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gUERGIGdlbmVyYXRpb24gZmFpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIFBERkdlbmVyYXRpb25FcnJvciBleHRlbmRzIFBERkVycm9yIHtcbiAgIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICB0aGlzLm5hbWUgPSBcIlBERkdlbmVyYXRpb25FcnJvclwiO1xuICAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIFBERiBvYmplY3QgaXMgaW52YWxpZFxuICovXG5leHBvcnQgY2xhc3MgSW52YWxpZFBERk9iamVjdEVycm9yIGV4dGVuZHMgUERGRXJyb3Ige1xuICAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgb2JqZWN0VHlwZTogc3RyaW5nLFxuICAgICAgcmVhc29uOiBzdHJpbmcsXG4gICApIHtcbiAgICAgIHN1cGVyKGBJbnZhbGlkICR7b2JqZWN0VHlwZX06ICR7cmVhc29ufWApO1xuICAgICAgdGhpcy5uYW1lID0gXCJJbnZhbGlkUERGT2JqZWN0RXJyb3JcIjtcbiAgIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiBmb250IGlzIG5vdCBmb3VuZFxuICovXG5leHBvcnQgY2xhc3MgRm9udE5vdEZvdW5kRXJyb3IgZXh0ZW5kcyBQREZFcnJvciB7XG4gICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgZm9udE5hbWU6IHN0cmluZykge1xuICAgICAgc3VwZXIoYEZvbnQgbm90IGZvdW5kOiAke2ZvbnROYW1lfWApO1xuICAgICAgdGhpcy5uYW1lID0gXCJGb250Tm90Rm91bmRFcnJvclwiO1xuICAgfVxufVxuXG4vKipcbiAqIEVycm9yIHRocm93biB3aGVuIGltYWdlIGlzIGludmFsaWRcbiAqL1xuZXhwb3J0IGNsYXNzIEludmFsaWRJbWFnZUVycm9yIGV4dGVuZHMgUERGRXJyb3Ige1xuICAgY29uc3RydWN0b3IocmVhc29uOiBzdHJpbmcpIHtcbiAgICAgIHN1cGVyKGBJbnZhbGlkIGltYWdlOiAke3JlYXNvbn1gKTtcbiAgICAgIHRoaXMubmFtZSA9IFwiSW52YWxpZEltYWdlRXJyb3JcIjtcbiAgIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiBQREYgc2lnbmF0dXJlIGZhaWxzXG4gKi9cbmV4cG9ydCBjbGFzcyBQREZTaWduYXR1cmVFcnJvciBleHRlbmRzIFBERkVycm9yIHtcbiAgIGNvbnN0cnVjdG9yKHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICBzdXBlcihgUERGIHNpZ25hdHVyZSBlcnJvcjogJHtyZWFzb259YCk7XG4gICAgICB0aGlzLm5hbWUgPSBcIlBERlNpZ25hdHVyZUVycm9yXCI7XG4gICB9XG59XG5cbi8qKlxuICogRXJyb3IgdGhyb3duIHdoZW4gUERGIGVuY3J5cHRpb24gZmFpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIFBERkVuY3J5cHRpb25FcnJvciBleHRlbmRzIFBERkVycm9yIHtcbiAgIGNvbnN0cnVjdG9yKHJlYXNvbjogc3RyaW5nKSB7XG4gICAgICBzdXBlcihgUERGIGVuY3J5cHRpb24gZXJyb3I6ICR7cmVhc29ufWApO1xuICAgICAgdGhpcy5uYW1lID0gXCJQREZFbmNyeXB0aW9uRXJyb3JcIjtcbiAgIH1cbn1cblxuLyoqXG4gKiBFcnJvciB0aHJvd24gd2hlbiByZXF1aXJlZCBmZWF0dXJlIGlzIG5vdCBpbXBsZW1lbnRlZFxuICovXG5leHBvcnQgY2xhc3MgTm90SW1wbGVtZW50ZWRFcnJvciBleHRlbmRzIFBERkVycm9yIHtcbiAgIGNvbnN0cnVjdG9yKGZlYXR1cmU6IHN0cmluZykge1xuICAgICAgc3VwZXIoYEZlYXR1cmUgbm90IHlldCBpbXBsZW1lbnRlZDogJHtmZWF0dXJlfWApO1xuICAgICAgdGhpcy5uYW1lID0gXCJOb3RJbXBsZW1lbnRlZEVycm9yXCI7XG4gICB9XG59XG4iLAogICAgImltcG9ydCB7IFBERlBhcnNlciB9IGZyb20gXCIuL3BhcnNlci50c1wiO1xuaW1wb3J0IHR5cGUgeyBQREZEaWN0aW9uYXJ5LCBQREZSZWYsIFBERkFycmF5IH0gZnJvbSBcIi4uL3R5cGVzLnRzXCI7XG5pbXBvcnQgeyBQREZQYXJzZUVycm9yIH0gZnJvbSBcIi4uL2Vycm9ycy50c1wiO1xuXG4vKipcbiAqIFBhcnNlZCBQREYgRG9jdW1lbnRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXJzZWRQREYge1xuICAgdmVyc2lvbjogc3RyaW5nO1xuICAgY2F0YWxvZzogUERGUmVmO1xuICAgcGFnZXM6IFBERlBhZ2VbXTtcbiAgIG9iamVjdHM6IE1hcDxudW1iZXIsIGFueT47XG59XG5cbi8qKlxuICogUGFyc2VkIFBERiBQYWdlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUERGUGFnZSB7XG4gICByZWY6IFBERlJlZjtcbiAgIHNpemU6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfTtcbiAgIGNvbnRlbnQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBQREYgUmVhZGVyIC0gcmVhZHMgYW5kIHBhcnNlcyBleGlzdGluZyBQREZzXG4gKi9cbmV4cG9ydCBjbGFzcyBQREZSZWFkZXIge1xuICAgcHJpdmF0ZSBkYXRhOiBVaW50OEFycmF5O1xuICAgcHJpdmF0ZSBvYmplY3RzOiBNYXA8bnVtYmVyLCBhbnk+ID0gbmV3IE1hcCgpO1xuXG4gICBjb25zdHJ1Y3RvcihkYXRhOiBVaW50OEFycmF5KSB7XG4gICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIFBERiBmaWxlXG4gICAgKi9cbiAgIHBhcnNlKCk6IFBhcnNlZFBERiB7XG4gICAgICAvLyAxLiBGaW5kIGFuZCBwYXJzZSB4cmVmIHRhYmxlXG4gICAgICBjb25zdCB4cmVmT2Zmc2V0ID0gdGhpcy5maW5kU3RhcnRYUmVmKCk7XG4gICAgICBjb25zdCB4cmVmVGFibGUgPSB0aGlzLnBhcnNlWFJlZlRhYmxlKHhyZWZPZmZzZXQpO1xuXG4gICAgICAvLyAyLiBQYXJzZSB0cmFpbGVyXG4gICAgICBjb25zdCB0cmFpbGVyID0gdGhpcy5wYXJzZVRyYWlsZXIoeHJlZk9mZnNldCk7XG4gICAgICBjb25zdCBjYXRhbG9nUmVmID0gdHJhaWxlci5Sb290IGFzIFBERlJlZjtcblxuICAgICAgLy8gMy4gUmVhZCBhbGwgb2JqZWN0cyB1c2luZyB4cmVmIHRhYmxlXG4gICAgICB0aGlzLnJlYWRPYmplY3RzKHhyZWZUYWJsZSk7XG5cbiAgICAgIC8vIDQuIEdldCBQREYgdmVyc2lvbiBmcm9tIGhlYWRlclxuICAgICAgY29uc3QgdmVyc2lvbiA9IHRoaXMucGFyc2VWZXJzaW9uKCk7XG5cbiAgICAgIC8vIDUuIFBhcnNlIHBhZ2VzXG4gICAgICBjb25zdCBwYWdlcyA9IHRoaXMucGFyc2VQYWdlcyhjYXRhbG9nUmVmKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgIHZlcnNpb24sXG4gICAgICAgICBjYXRhbG9nOiBjYXRhbG9nUmVmLFxuICAgICAgICAgcGFnZXMsXG4gICAgICAgICBvYmplY3RzOiB0aGlzLm9iamVjdHMsXG4gICAgICB9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIEZpbmQgc3RhcnR4cmVmIG9mZnNldFxuICAgICovXG4gICBwcml2YXRlIGZpbmRTdGFydFhSZWYoKTogbnVtYmVyIHtcbiAgICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkZWNvZGVyLmRlY29kZSh0aGlzLmRhdGEpO1xuICAgICAgY29uc3QgbWF0Y2ggPSBjb250ZW50Lm1hdGNoKC9zdGFydHhyZWZcXHMrKFxcZCspLyk7XG4gICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgICB0aHJvdyBuZXcgUERGUGFyc2VFcnJvcihcIkNvdWxkIG5vdCBmaW5kIHN0YXJ0eHJlZlwiKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwYXJzZUludChtYXRjaFsxXSwgMTApO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIHhyZWYgdGFibGVcbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZVhSZWZUYWJsZShvZmZzZXQ6IG51bWJlcik6IE1hcDxudW1iZXIsIG51bWJlcj4ge1xuICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgICAgY29uc3QgY29udGVudCA9IGRlY29kZXIuZGVjb2RlKHRoaXMuZGF0YS5zbGljZShvZmZzZXQpKTtcbiAgICAgIGNvbnN0IGxpbmVzID0gY29udGVudC5zcGxpdChcIlxcblwiKTtcblxuICAgICAgY29uc3QgeHJlZiA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCk7XG4gICAgICBsZXQgaSA9IDA7XG5cbiAgICAgIC8vIFNraXAgXCJ4cmVmXCIga2V5d29yZFxuICAgICAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGggJiYgIWxpbmVzW2ldLnRyaW0oKS5zdGFydHNXaXRoKFwieHJlZlwiKSkgaSsrO1xuICAgICAgaSsrO1xuXG4gICAgICAvLyBQYXJzZSBzdWJzZWN0aW9uc1xuICAgICAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGggJiYgIWxpbmVzW2ldLnRyaW0oKS5zdGFydHNXaXRoKFwidHJhaWxlclwiKSkge1xuICAgICAgICAgY29uc3Qgc3Vic2VjdGlvbiA9IGxpbmVzW2ldLnRyaW0oKS5zcGxpdCgvXFxzKy8pO1xuICAgICAgICAgaWYgKHN1YnNlY3Rpb24ubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IHBhcnNlSW50KHN1YnNlY3Rpb25bMF0sIDEwKTtcbiAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gcGFyc2VJbnQoc3Vic2VjdGlvblsxXSwgMTApO1xuICAgICAgICAgICAgaSsrO1xuXG4gICAgICAgICAgICAvLyBQYXJzZSBlbnRyaWVzXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvdW50OyBqKyspIHtcbiAgICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gbGluZXNbaV0udHJpbSgpLnNwbGl0KC9cXHMrLyk7XG4gICAgICAgICAgICAgICBpZiAoZW50cnkubGVuZ3RoID49IDMgJiYgZW50cnlbMl0gPT09IFwiblwiKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSBwYXJzZUludChlbnRyeVswXSwgMTApO1xuICAgICAgICAgICAgICAgICAgeHJlZi5zZXQoc3RhcnQgKyBqLCBvZmZzZXQpO1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHhyZWY7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2UgdHJhaWxlciBkaWN0aW9uYXJ5XG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VUcmFpbGVyKHhyZWZPZmZzZXQ6IG51bWJlcik6IFBERkRpY3Rpb25hcnkge1xuICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xuICAgICAgY29uc3QgY29udGVudCA9IGRlY29kZXIuZGVjb2RlKHRoaXMuZGF0YS5zbGljZSh4cmVmT2Zmc2V0KSk7XG4gICAgICBjb25zdCB0cmFpbGVyTWF0Y2ggPSBjb250ZW50Lm1hdGNoKC90cmFpbGVyXFxzKjw8W1xcc1xcU10qPz4+Lyk7XG4gICAgICBpZiAoIXRyYWlsZXJNYXRjaCkge1xuICAgICAgICAgdGhyb3cgbmV3IFBERlBhcnNlRXJyb3IoXCJDb3VsZCBub3QgZmluZCB0cmFpbGVyXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXJzZXIgPSBuZXcgUERGUGFyc2VyKG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSh0cmFpbGVyTWF0Y2hbMF0ucmVwbGFjZShcInRyYWlsZXJcIiwgXCJcIikpKTtcbiAgICAgIHJldHVybiBwYXJzZXIucGFyc2VWYWx1ZSgpIGFzIFBERkRpY3Rpb25hcnk7XG4gICB9XG5cbiAgIC8qKlxuICAgICogUmVhZCBhbGwgb2JqZWN0cyBmcm9tIHhyZWYgdGFibGVcbiAgICAqL1xuICAgcHJpdmF0ZSByZWFkT2JqZWN0cyh4cmVmVGFibGU6IE1hcDxudW1iZXIsIG51bWJlcj4pOiB2b2lkIHtcbiAgICAgIGZvciAoY29uc3QgW29iamVjdE51bSwgb2Zmc2V0XSBvZiB4cmVmVGFibGUpIHtcbiAgICAgICAgIHRyeSB7XG4gICAgICAgICAgIGNvbnN0IG9iakRhdGEgPSB0aGlzLmRhdGEuc2xpY2Uob2Zmc2V0KTtcbiAgICAgICAgICAgY29uc3QgcGFyc2VyID0gbmV3IFBERlBhcnNlcihvYmpEYXRhKTtcbiAgICAgICAgICAgY29uc3Qgb2JqID0gcGFyc2VyLnBhcnNlSW5kaXJlY3RPYmplY3QoKTtcbiAgICAgICAgICAgdGhpcy5vYmplY3RzLnNldChvYmplY3ROdW0sIG9iai52YWx1ZSk7XG4gICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAvLyBTa2lwIG1hbGZvcm1lZCBvYmplY3RzXG4gICAgICAgICB9XG4gICAgICB9XG4gICB9XG5cbiAgIC8qKlxuICAgICogUGFyc2UgUERGIHZlcnNpb24gZnJvbSBoZWFkZXJcbiAgICAqL1xuICAgcHJpdmF0ZSBwYXJzZVZlcnNpb24oKTogc3RyaW5nIHtcbiAgICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgICAgIGNvbnN0IGhlYWRlciA9IGRlY29kZXIuZGVjb2RlKHRoaXMuZGF0YS5zbGljZSgwLCAyMCkpO1xuICAgICAgY29uc3QgbWF0Y2ggPSBoZWFkZXIubWF0Y2goLyVQREYtKFxcZCtcXC5cXGQrKS8pO1xuICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0gOiBcIjEuN1wiO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFBhcnNlIHBhZ2VzIGZyb20gY2F0YWxvZ1xuICAgICovXG4gICBwcml2YXRlIHBhcnNlUGFnZXMoY2F0YWxvZ1JlZjogUERGUmVmKTogUERGUGFnZVtdIHtcbiAgICAgIGNvbnN0IGNhdGFsb2cgPSB0aGlzLm9iamVjdHMuZ2V0KGNhdGFsb2dSZWYub2JqZWN0TnVtYmVyKSBhcyBQREZEaWN0aW9uYXJ5O1xuICAgICAgaWYgKCFjYXRhbG9nKSB7XG4gICAgICAgICB0aHJvdyBuZXcgUERGUGFyc2VFcnJvcihcIkNhdGFsb2cgbm90IGZvdW5kXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYWdlc1JlZiA9IGNhdGFsb2cuUGFnZXMgYXMgUERGUmVmO1xuICAgICAgY29uc3QgcGFnZXNUcmVlID0gdGhpcy5vYmplY3RzLmdldChwYWdlc1JlZi5vYmplY3ROdW1iZXIpIGFzIFBERkRpY3Rpb25hcnk7XG4gICAgICBpZiAoIXBhZ2VzVHJlZSkge1xuICAgICAgICAgdGhyb3cgbmV3IFBERlBhcnNlRXJyb3IoXCJQYWdlcyB0cmVlIG5vdCBmb3VuZFwiKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qga2lkcyA9IHBhZ2VzVHJlZS5LaWRzIGFzIFBERkFycmF5O1xuICAgICAgY29uc3QgcGFnZXM6IFBERlBhZ2VbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGtpZFJlZiBvZiBraWRzKSB7XG4gICAgICAgICBpZiAodHlwZW9mIGtpZFJlZiA9PT0gXCJvYmplY3RcIiAmJiBcIm9iamVjdE51bWJlclwiIGluIGtpZFJlZikge1xuICAgICAgICAgICAgY29uc3QgcGFnZSA9IHRoaXMucGFyc2VQYWdlKGtpZFJlZiBhcyBQREZSZWYpO1xuICAgICAgICAgICAgaWYgKHBhZ2UpIHBhZ2VzLnB1c2gocGFnZSk7XG4gICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYWdlcztcbiAgIH1cblxuICAgLyoqXG4gICAgKiBQYXJzZSBhIHNpbmdsZSBwYWdlXG4gICAgKi9cbiAgIHByaXZhdGUgcGFyc2VQYWdlKHJlZjogUERGUmVmKTogUERGUGFnZSB8IG51bGwge1xuICAgICAgY29uc3QgcGFnZURpY3QgPSB0aGlzLm9iamVjdHMuZ2V0KHJlZi5vYmplY3ROdW1iZXIpIGFzIFBERkRpY3Rpb25hcnk7XG4gICAgICBpZiAoIXBhZ2VEaWN0KSByZXR1cm4gbnVsbDtcblxuICAgICAgY29uc3QgbWVkaWFCb3ggPSBwYWdlRGljdC5NZWRpYUJveCBhcyBQREZBcnJheTtcbiAgICAgIGNvbnN0IHNpemUgPSB7XG4gICAgICAgICB3aWR0aDogbWVkaWFCb3hbMl0gYXMgbnVtYmVyLFxuICAgICAgICAgaGVpZ2h0OiBtZWRpYUJveFszXSBhcyBudW1iZXIsXG4gICAgICB9O1xuXG4gICAgICAvLyBFeHRyYWN0IGNvbnRlbnRcbiAgICAgIGxldCBjb250ZW50ID0gXCJcIjtcbiAgICAgIGNvbnN0IGNvbnRlbnRzUmVmID0gcGFnZURpY3QuQ29udGVudHMgYXMgUERGUmVmO1xuICAgICAgaWYgKGNvbnRlbnRzUmVmICYmIHR5cGVvZiBjb250ZW50c1JlZiA9PT0gXCJvYmplY3RcIiAmJiBcIm9iamVjdE51bWJlclwiIGluIGNvbnRlbnRzUmVmKSB7XG4gICAgICAgICBjb250ZW50ID0gdGhpcy5leHRyYWN0VGV4dChjb250ZW50c1JlZik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHJlZiwgc2l6ZSwgY29udGVudCB9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIEV4dHJhY3QgdGV4dCBmcm9tIGNvbnRlbnQgc3RyZWFtXG4gICAgKi9cbiAgIHByaXZhdGUgZXh0cmFjdFRleHQocmVmOiBQREZSZWYpOiBzdHJpbmcge1xuICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5vYmplY3RzLmdldChyZWYub2JqZWN0TnVtYmVyKTtcbiAgICAgIGlmICghc3RyZWFtIHx8ICFzdHJlYW0uZGF0YSkgcmV0dXJuIFwiXCI7XG5cbiAgICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoKTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkZWNvZGVyLmRlY29kZShzdHJlYW0uZGF0YSk7XG5cbiAgICAgIC8vIFNpbXBsZSB0ZXh0IGV4dHJhY3Rpb24gLSBsb29rIGZvciAodGV4dCkgVGogcGF0dGVybnNcbiAgICAgIGNvbnN0IHRleHRzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgY29uc3QgcmVnZXggPSAvXFwoKFteKV0qKVxcKVxccypUai9nO1xuICAgICAgbGV0IG1hdGNoO1xuICAgICAgd2hpbGUgKChtYXRjaCA9IHJlZ2V4LmV4ZWMoY29udGVudCkpICE9PSBudWxsKSB7XG4gICAgICAgICB0ZXh0cy5wdXNoKG1hdGNoWzFdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRleHRzLmpvaW4oXCIgXCIpO1xuICAgfVxufVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7O0FBR08sSUFBSztBQUFBLENBQUwsQ0FBSyxlQUFMO0FBQUEsRUFFSix1QkFBUztBQUFBLEVBQ1QsdUJBQVM7QUFBQSxFQUNULHFCQUFPO0FBQUEsRUFDUCx3QkFBVTtBQUFBLEVBQ1YscUJBQU87QUFBQSxFQUdQLDRCQUFjO0FBQUEsRUFDZCwwQkFBWTtBQUFBLEVBQ1osMkJBQWE7QUFBQSxFQUNiLHlCQUFXO0FBQUEsRUFHWCxvQkFBTTtBQUFBLEVBQ04sdUJBQVM7QUFBQSxFQUNULHVCQUFTO0FBQUEsRUFDVCwwQkFBWTtBQUFBLEVBQ1oscUJBQU87QUFBQSxFQUNQLHdCQUFVO0FBQUEsRUFDViwwQkFBWTtBQUFBLEVBQ1osa0JBQUk7QUFBQSxFQUdKLG9CQUFNO0FBQUEsR0F6Qkc7QUFBQTtBQXdDTCxNQUFNLFNBQVM7QUFBQSxFQUNYO0FBQUEsRUFDQSxXQUFtQjtBQUFBLEVBRTNCLFdBQVcsQ0FBQyxNQUFrQjtBQUFBLElBQzNCLEtBQUssT0FBTztBQUFBO0FBQUEsRUFNZixTQUFTLEdBQVU7QUFBQSxJQUNoQixLQUFLLGVBQWU7QUFBQSxJQUVwQixJQUFJLEtBQUssWUFBWSxLQUFLLEtBQUssUUFBUTtBQUFBLE1BQ3BDLE9BQU8sRUFBRSxNQUFNLGlCQUFlLE9BQU8sTUFBTSxVQUFVLEtBQUssU0FBUztBQUFBLElBQ3RF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LElBRXRCLE1BQU0sV0FBVyxTQUFTO0FBQUEsSUFDMUIsTUFBTSxPQUFPO0FBQUEsTUFDVixPQUFPLFNBQVM7QUFBQSxNQUNoQixRQUFRLFNBQVM7QUFBQSxJQUNwQjtBQUFBLElBR0EsSUFBSSxVQUFVO0FBQUEsSUFDZCxNQUFNLGNBQWMsU0FBUztBQUFBLElBQzdCLElBQUksZUFBZSxPQUFPLGdCQUFnQixZQUFZLGtCQUFrQixhQUFhO0FBQUEsTUFDbEYsVUFBVSxLQUFLLFlBQVksV0FBVztBQUFBLElBQ3pDO0FBQUEsSUFFQSxPQUFPLEVBQUUsS0FBSyxNQUFNLFFBQVE7QUFBQTtBQUFBLEVBTXZCLFdBQVcsQ0FBQyxLQUFxQjtBQUFBLElBQ3RDLE1BQU0sU0FBUyxLQUFLLFFBQVEsSUFBSSxJQUFJLFlBQVk7QUFBQSxJQUNoRCxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU87QUFBQSxNQUFNLE9BQU87QUFBQSxJQUVwQyxNQUFNLFVBQVUsSUFBSTtBQUFBLElBQ3BCLE1BQU0sVUFBVSxRQUFRLE9BQU8sT0FBTyxJQUFJO0FBQUEsSUFHMUMsTUFBTSxRQUFrQixDQUFDO0FBQUEsSUFDekIsTUFBTSxRQUFRO0FBQUEsSUFDZCxJQUFJO0FBQUEsSUFDSixRQUFRLFFBQVEsTUFBTSxLQUFLLE9BQU8sT0FBTyxNQUFNO0FBQUEsTUFDNUMsTUFBTSxLQUFLLE1BQU0sRUFBRTtBQUFBLElBQ3RCO0FBQUEsSUFFQSxPQUFPLE1BQU0sS0FBSyxHQUFHO0FBQUE7QUFFM0I7IiwKICAiZGVidWdJZCI6ICIyRDI1Njc4QTlEQzg5NThFNjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==