ember-scoped-css 3.1.0 → 3.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.
@@ -0,0 +1,1534 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ let node_assert = require("node:assert");
25
+ node_assert = __toESM(node_assert);
26
+ let node_fs = require("node:fs");
27
+ node_fs = __toESM(node_fs);
28
+ let node_module = require("node:module");
29
+ node_module = __toESM(node_module);
30
+ let node_path = require("node:path");
31
+ node_path = __toESM(node_path);
32
+ let path = require("path");
33
+ path = __toESM(path);
34
+ let unplugin = require("unplugin");
35
+ unplugin = __toESM(unplugin);
36
+ let postcss = require("postcss");
37
+ postcss = __toESM(postcss);
38
+ let postcss_selector_parser = require("postcss-selector-parser");
39
+ postcss_selector_parser = __toESM(postcss_selector_parser);
40
+ let fs = require("fs");
41
+ fs = __toESM(fs);
42
+ let postcss_scss = require("postcss-scss");
43
+ postcss_scss = __toESM(postcss_scss);
44
+ let node_process = require("node:process");
45
+ node_process = __toESM(node_process);
46
+ let ember_template_recast = require("ember-template-recast");
47
+ ember_template_recast = __toESM(ember_template_recast);
48
+
49
+ //#region src/lib/path/const.js
50
+ /**
51
+ * Join will convert to whatever is appropriate fro the current platform
52
+ */
53
+ const leadingSlashPath = {
54
+ embroiderDir: path.default.join("/node_modules/.embroider/"),
55
+ atEmbroider: path.default.join("/@embroider"),
56
+ componentsDir: path.default.join("/components/"),
57
+ templatesDir: path.default.join("/templates/"),
58
+ routesDir: path.default.join("/routes/"),
59
+ testem: path.default.join("/testem"),
60
+ src: path.default.join("/src/"),
61
+ app: path.default.join("/app/")
62
+ };
63
+ const barePath = { pnpmDir: path.default.join("node_modules/.pnpm") };
64
+
65
+ //#endregion
66
+ //#region src/lib/path/md5.js
67
+ /**
68
+ * Add integers, wrapping at 2^32.
69
+ * This uses 16-bit operations internally to work around bugs in interpreters.
70
+ *
71
+ * @param {number} x First integer
72
+ * @param {number} y Second integer
73
+ * @returns {number} Sum
74
+ */
75
+ function safeAdd(x, y) {
76
+ var lsw = (x & 65535) + (y & 65535);
77
+ return (x >> 16) + (y >> 16) + (lsw >> 16) << 16 | lsw & 65535;
78
+ }
79
+ /**
80
+ * Bitwise rotate a 32-bit number to the left.
81
+ *
82
+ * @param {number} num 32-bit number
83
+ * @param {number} cnt Rotation count
84
+ * @returns {number} Rotated number
85
+ */
86
+ function bitRotateLeft(num, cnt) {
87
+ return num << cnt | num >>> 32 - cnt;
88
+ }
89
+ /**
90
+ * Basic operation the algorithm uses.
91
+ *
92
+ * @param {number} q q
93
+ * @param {number} a a
94
+ * @param {number} b b
95
+ * @param {number} x x
96
+ * @param {number} s s
97
+ * @param {number} t t
98
+ * @returns {number} Result
99
+ */
100
+ function md5cmn(q, a, b, x, s, t) {
101
+ return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
102
+ }
103
+ /**
104
+ * Basic operation the algorithm uses.
105
+ *
106
+ * @param {number} a a
107
+ * @param {number} b b
108
+ * @param {number} c c
109
+ * @param {number} d d
110
+ * @param {number} x x
111
+ * @param {number} s s
112
+ * @param {number} t t
113
+ * @returns {number} Result
114
+ */
115
+ function md5ff(a, b, c, d, x, s, t) {
116
+ return md5cmn(b & c | ~b & d, a, b, x, s, t);
117
+ }
118
+ /**
119
+ * Basic operation the algorithm uses.
120
+ *
121
+ * @param {number} a a
122
+ * @param {number} b b
123
+ * @param {number} c c
124
+ * @param {number} d d
125
+ * @param {number} x x
126
+ * @param {number} s s
127
+ * @param {number} t t
128
+ * @returns {number} Result
129
+ */
130
+ function md5gg(a, b, c, d, x, s, t) {
131
+ return md5cmn(b & d | c & ~d, a, b, x, s, t);
132
+ }
133
+ /**
134
+ * Basic operation the algorithm uses.
135
+ *
136
+ * @param {number} a a
137
+ * @param {number} b b
138
+ * @param {number} c c
139
+ * @param {number} d d
140
+ * @param {number} x x
141
+ * @param {number} s s
142
+ * @param {number} t t
143
+ * @returns {number} Result
144
+ */
145
+ function md5hh(a, b, c, d, x, s, t) {
146
+ return md5cmn(b ^ c ^ d, a, b, x, s, t);
147
+ }
148
+ /**
149
+ * Basic operation the algorithm uses.
150
+ *
151
+ * @param {number} a a
152
+ * @param {number} b b
153
+ * @param {number} c c
154
+ * @param {number} d d
155
+ * @param {number} x x
156
+ * @param {number} s s
157
+ * @param {number} t t
158
+ * @returns {number} Result
159
+ */
160
+ function md5ii(a, b, c, d, x, s, t) {
161
+ return md5cmn(c ^ (b | ~d), a, b, x, s, t);
162
+ }
163
+ /**
164
+ * Calculate the MD5 of an array of little-endian words, and a bit length.
165
+ *
166
+ * @param {Array} x Array of little-endian words
167
+ * @param {number} len Bit length
168
+ * @returns {Array<number>} MD5 Array
169
+ */
170
+ function binlMD5(x, len) {
171
+ x[len >> 5] |= 128 << len % 32;
172
+ x[(len + 64 >>> 9 << 4) + 14] = len;
173
+ var i;
174
+ var olda;
175
+ var oldb;
176
+ var oldc;
177
+ var oldd;
178
+ var a = 1732584193;
179
+ var b = -271733879;
180
+ var c = -1732584194;
181
+ var d = 271733878;
182
+ for (i = 0; i < x.length; i += 16) {
183
+ olda = a;
184
+ oldb = b;
185
+ oldc = c;
186
+ oldd = d;
187
+ a = md5ff(a, b, c, d, x[i], 7, -680876936);
188
+ d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
189
+ c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
190
+ b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
191
+ a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
192
+ d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
193
+ c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
194
+ b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
195
+ a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
196
+ d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
197
+ c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
198
+ b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
199
+ a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
200
+ d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
201
+ c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
202
+ b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
203
+ a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
204
+ d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
205
+ c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
206
+ b = md5gg(b, c, d, a, x[i], 20, -373897302);
207
+ a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
208
+ d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
209
+ c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
210
+ b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
211
+ a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
212
+ d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
213
+ c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
214
+ b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
215
+ a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
216
+ d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
217
+ c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
218
+ b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
219
+ a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
220
+ d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
221
+ c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
222
+ b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
223
+ a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
224
+ d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
225
+ c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
226
+ b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
227
+ a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
228
+ d = md5hh(d, a, b, c, x[i], 11, -358537222);
229
+ c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
230
+ b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
231
+ a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
232
+ d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
233
+ c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
234
+ b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
235
+ a = md5ii(a, b, c, d, x[i], 6, -198630844);
236
+ d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
237
+ c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
238
+ b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
239
+ a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
240
+ d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
241
+ c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
242
+ b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
243
+ a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
244
+ d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
245
+ c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
246
+ b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
247
+ a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
248
+ d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
249
+ c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
250
+ b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
251
+ a = safeAdd(a, olda);
252
+ b = safeAdd(b, oldb);
253
+ c = safeAdd(c, oldc);
254
+ d = safeAdd(d, oldd);
255
+ }
256
+ return [
257
+ a,
258
+ b,
259
+ c,
260
+ d
261
+ ];
262
+ }
263
+ /**
264
+ * Convert an array of little-endian words to a string
265
+ *
266
+ * @param {Array<number>} input MD5 Array
267
+ * @returns {string} MD5 string
268
+ */
269
+ function binl2rstr(input) {
270
+ var i;
271
+ var output = "";
272
+ var length32 = input.length * 32;
273
+ for (i = 0; i < length32; i += 8) output += String.fromCharCode(input[i >> 5] >>> i % 32 & 255);
274
+ return output;
275
+ }
276
+ /**
277
+ * Convert a raw string to an array of little-endian words
278
+ * Characters >255 have their high-byte silently ignored.
279
+ *
280
+ * @param {string} input Raw input string
281
+ * @returns {Array<number>} Array of little-endian words
282
+ */
283
+ function rstr2binl(input) {
284
+ var i;
285
+ var output = [];
286
+ output[(input.length >> 2) - 1] = void 0;
287
+ for (i = 0; i < output.length; i += 1) output[i] = 0;
288
+ var length8 = input.length * 8;
289
+ for (i = 0; i < length8; i += 8) output[i >> 5] |= (input.charCodeAt(i / 8) & 255) << i % 32;
290
+ return output;
291
+ }
292
+ /**
293
+ * Calculate the MD5 of a raw string
294
+ *
295
+ * @param {string} s Input string
296
+ * @returns {string} Raw MD5 string
297
+ */
298
+ function rstrMD5(s) {
299
+ return binl2rstr(binlMD5(rstr2binl(s), s.length * 8));
300
+ }
301
+ /**
302
+ * Calculates the HMAC-MD5 of a key and some data (raw strings)
303
+ *
304
+ * @param {string} key HMAC key
305
+ * @param {string} data Raw input string
306
+ * @returns {string} Raw MD5 string
307
+ */
308
+ function rstrHMACMD5(key, data) {
309
+ var i;
310
+ var bkey = rstr2binl(key);
311
+ var ipad = [];
312
+ var opad = [];
313
+ var hash$2;
314
+ ipad[15] = opad[15] = void 0;
315
+ if (bkey.length > 16) bkey = binlMD5(bkey, key.length * 8);
316
+ for (i = 0; i < 16; i += 1) {
317
+ ipad[i] = bkey[i] ^ 909522486;
318
+ opad[i] = bkey[i] ^ 1549556828;
319
+ }
320
+ hash$2 = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
321
+ return binl2rstr(binlMD5(opad.concat(hash$2), 640));
322
+ }
323
+ /**
324
+ * Convert a raw string to a hex string
325
+ *
326
+ * @param {string} input Raw input string
327
+ * @returns {string} Hex encoded string
328
+ */
329
+ function rstr2hex(input) {
330
+ var hexTab = "0123456789abcdef";
331
+ var output = "";
332
+ var x;
333
+ var i;
334
+ for (i = 0; i < input.length; i += 1) {
335
+ x = input.charCodeAt(i);
336
+ output += hexTab.charAt(x >>> 4 & 15) + hexTab.charAt(x & 15);
337
+ }
338
+ return output;
339
+ }
340
+ /**
341
+ * Encode a string as UTF-8
342
+ *
343
+ * @param {string} input Input string
344
+ * @returns {string} UTF8 string
345
+ */
346
+ function str2rstrUTF8(input) {
347
+ return unescape(encodeURIComponent(input));
348
+ }
349
+ /**
350
+ * Encodes input string as raw MD5 string
351
+ *
352
+ * @param {string} s Input string
353
+ * @returns {string} Raw MD5 string
354
+ */
355
+ function rawMD5(s) {
356
+ return rstrMD5(str2rstrUTF8(s));
357
+ }
358
+ /**
359
+ * Encodes input string as Hex encoded string
360
+ *
361
+ * @param {string} s Input string
362
+ * @returns {string} Hex encoded string
363
+ */
364
+ function hexMD5(s) {
365
+ return rstr2hex(rawMD5(s));
366
+ }
367
+ /**
368
+ * Calculates the raw HMAC-MD5 for the given key and data
369
+ *
370
+ * @param {string} k HMAC key
371
+ * @param {string} d Input string
372
+ * @returns {string} Raw MD5 string
373
+ */
374
+ function rawHMACMD5(k, d) {
375
+ return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d));
376
+ }
377
+ /**
378
+ * Calculates the Hex encoded HMAC-MD5 for the given key and data
379
+ *
380
+ * @param {string} k HMAC key
381
+ * @param {string} d Input string
382
+ * @returns {string} Raw MD5 string
383
+ */
384
+ function hexHMACMD5(k, d) {
385
+ return rstr2hex(rawHMACMD5(k, d));
386
+ }
387
+ /**
388
+ * Calculates MD5 value for a given string.
389
+ * If a key is provided, calculates the HMAC-MD5 value.
390
+ * Returns a Hex encoded string unless the raw argument is given.
391
+ *
392
+ * @param {string} string Input string
393
+ * @param {string} [key] HMAC key
394
+ * @param {boolean} [raw] Raw output switch
395
+ * @returns {string} MD5 output
396
+ */
397
+ function md5(string, key, raw) {
398
+ if (!key) {
399
+ if (!raw) return hexMD5(string);
400
+ return rawMD5(string);
401
+ }
402
+ if (!raw) return hexHMACMD5(key, string);
403
+ return rawHMACMD5(key, string);
404
+ }
405
+
406
+ //#endregion
407
+ //#region src/lib/path/hash-from-module-path.js
408
+ /**
409
+ * The intent of this function is to generate the suffix/postfix for the
410
+ * css classes, based on the module-scoped path name.
411
+ *
412
+ * for example,
413
+ * hash('my-app/components/foo')
414
+ * instead of
415
+ * hash('app/components/foo')
416
+ *
417
+ * (unless your app name is 'app')
418
+ *
419
+ * @param {string} modulePath
420
+ * @returns {string}
421
+ */
422
+ function hash$1(modulePath) {
423
+ return "e" + md5(modulePath).substring(0, 8);
424
+ }
425
+ const hashFromModulePath$1 = hash$1;
426
+
427
+ //#endregion
428
+ //#region src/lib/path/utils.js
429
+ /**
430
+ *
431
+ * @param {string} filePath
432
+ * @returns {string}
433
+ */
434
+ function hashFromModulePath(filePath) {
435
+ return hashFromModulePath$1(forcePosix(filePath));
436
+ }
437
+ /**
438
+ * @param {string} filePath
439
+ */
440
+ function forcePosix(filePath) {
441
+ const parsed = node_path.default.parse(filePath);
442
+ if (parsed.root === "") return filePath.replaceAll(node_path.default.win32.sep, node_path.default.posix.sep);
443
+ return filePath.replace(/* @__PURE__ */ new RegExp(`^${RegExp.escape(parsed.root)}`), node_path.default.posix.sep).replaceAll(node_path.default.win32.sep, node_path.default.posix.sep);
444
+ }
445
+ let here = require("url").pathToFileURL(__filename).href;
446
+ let ourRequire = globalThis.require ? globalThis.require : here && (0, node_module.createRequire)(here);
447
+ if (!ourRequire) ourRequire = require;
448
+ const IRRELEVANT_PATHS = [barePath.pnpmDir, "__vite-"];
449
+ const UNSUPPORTED_DIRECTORIES = new Set(["tests"]);
450
+ const CWD = process.cwd();
451
+ /**
452
+ * Based on ember's component location conventions,
453
+ * this function will provide a path for where we
454
+ * expect the CSS to live.
455
+ *
456
+ * For co-located structure:
457
+ * - components/my-component.hbs
458
+ * - components/my-component.css
459
+ *
460
+ * For nested co-located structure
461
+ * - components/my-component/foo.hbs
462
+ * - components/my-component/foo.css
463
+ *
464
+ * For Pods routes structure
465
+ * - routes/my-route/template.{hbs,js}
466
+ * - routes/my-route/styles.css
467
+ *
468
+ * Deliberately not supported:
469
+ * - components w/ pods -- this is deprecated in 5.10
470
+ *
471
+ * @param {string} fileName - the hbs, js, gjs, gts or whatever co-located path.
472
+ * @returns {string} - expected css path
473
+ */
474
+ function cssPathFor(fileName) {
475
+ let cssPath = withoutExtension(fileName) + ".css";
476
+ if (isPod(fileName)) cssPath = fileName.replace(/template\.js$/, "styles.css").replace(/template\.gjs/, "styles.css").replace(/template\.gts/, "styles.css").replace(/template\.hbs/, "styles.css");
477
+ return cssPath;
478
+ }
479
+ /**
480
+ * Note that components in the "pods" convention will
481
+ * never be supported.
482
+ *
483
+ * @param {string} filePath
484
+ */
485
+ function isPodTemplate(filePath) {
486
+ if (filePath.includes(leadingSlashPath.componentsDir)) return false;
487
+ return filePath.endsWith("template.js") || filePath.endsWith("template.hbs") || filePath.endsWith("template.gjs") || filePath.endsWith("template.gts");
488
+ }
489
+ /**
490
+ * Note that components in the "pods" convention will
491
+ * never be supported.
492
+ *
493
+ * Checks if a file ends with
494
+ * - template.js
495
+ * - template.hbs
496
+ * - styles.css
497
+ *
498
+ * @param {string} filePath
499
+ */
500
+ function isPod(filePath) {
501
+ if (filePath.includes(leadingSlashPath.componentsDir)) return false;
502
+ if (isPodTemplate(filePath)) return true;
503
+ return filePath.endsWith("styles.css");
504
+ }
505
+ /**
506
+ *
507
+ * @param {string} filePath
508
+ * @returns the same path, but without the extension
509
+ */
510
+ function withoutExtension(filePath) {
511
+ let parsed = node_path.default.parse(filePath);
512
+ return node_path.default.join(parsed.dir, parsed.name);
513
+ }
514
+ /**
515
+ * Examples for fileName
516
+ * - absolute on-disk path
517
+ * - in webpack
518
+ * - URL-absolute path, starting with /
519
+ *
520
+ * @param {string} fileName
521
+ * @param {{ additionalRoots?: string[]; cwd: string }} options
522
+ * @returns
523
+ */
524
+ function isRelevantFile(fileName, { additionalRoots, cwd }) {
525
+ if (fileName.startsWith(leadingSlashPath.testem)) return false;
526
+ if (fileName.startsWith("\0")) return false;
527
+ if (node_path.default.isAbsolute(fileName) === false) {
528
+ if (fileName.match(/^[a-zA-Z]/)) return false;
529
+ }
530
+ if (fileName.startsWith(leadingSlashPath.atEmbroider)) return false;
531
+ if (IRRELEVANT_PATHS.some((i) => fileName.includes(i))) return false;
532
+ (0, node_assert.default)(cwd, `cwd was not passed to isRelevantFile`);
533
+ let isInAdditionalRoot = additionalRoots?.some((root) => {
534
+ let relative = node_path.default.relative(node_path.default.resolve(cwd, root), fileName);
535
+ return relative !== ".." && !relative.startsWith(`..${node_path.default.sep}`) && !node_path.default.isAbsolute(relative);
536
+ });
537
+ let workspace = findWorkspacePath(fileName);
538
+ let ourWorkspace = findWorkspacePath(cwd);
539
+ if (workspace !== ourWorkspace && !isInAdditionalRoot) return false;
540
+ let isInWorkspaceAdditionalRoot = workspace === ourWorkspace && additionalRoots?.some((root) => {
541
+ if (node_path.default.isAbsolute(root)) return false;
542
+ let normalizedFileName = `${node_path.default.sep}${node_path.default.normalize(fileName)}${node_path.default.sep}`;
543
+ let normalizedRoot = `${node_path.default.sep}${node_path.default.normalize(root)}${node_path.default.sep}`;
544
+ return normalizedFileName.includes(normalizedRoot);
545
+ });
546
+ let [, ...parts] = fileName.replace(workspace, "").split(node_path.default.sep).filter(Boolean);
547
+ if (UNSUPPORTED_DIRECTORIES.has(parts[0])) return false;
548
+ /**
549
+ * Mostly pods support.
550
+ * folks need to opt in to pods (routes), because every pods app can be configured differently
551
+ */
552
+ let roots = [
553
+ leadingSlashPath.componentsDir,
554
+ leadingSlashPath.templatesDir,
555
+ leadingSlashPath.routesDir
556
+ ];
557
+ if (!isInAdditionalRoot && !isInWorkspaceAdditionalRoot && !roots.some((root) => fileName.includes(root))) return;
558
+ return true;
559
+ }
560
+ function packageScopedPathToModulePath(packageScopedPath) {
561
+ /**
562
+ * *By convention*, `src` is omitted from component paths.
563
+ * We can reflect the same behavior by replacing src/
564
+ * with an empty string.
565
+ *
566
+ * CSS isn't emitted as a co-located module, but
567
+ * to keep conventions consistent across languages,
568
+ * we can pretend it is.
569
+ *
570
+ * Any customization beyond removing `src` and `app` is potentially confusing.
571
+ * If we need further customizations, we'll want to match on `exports` in the
572
+ * corresponding package.json
573
+ */
574
+ let packageRelative = packageScopedPath.replace(/* @__PURE__ */ new RegExp(`^${RegExp.escape(leadingSlashPath.src)}`), node_path.default.sep);
575
+ let parsed = node_path.default.parse(packageRelative);
576
+ if (isPod(packageRelative))
577
+ /**
578
+ * For pods, we chop off the whole file, and use the dir name as the "modulePath"
579
+ */
580
+ return parsed.dir;
581
+ return node_path.default.join(parsed.dir, parsed.name);
582
+ }
583
+ /**
584
+ * returns the app-module path of the source file
585
+ *
586
+ * This assumes normal ember app conventions
587
+ *
588
+ * which is `<package.json#name>/path-to-file`
589
+ */
590
+ function appPath(sourcePath) {
591
+ let workspacePath = findWorkspacePath(sourcePath);
592
+ let name = moduleName(sourcePath);
593
+ /**
594
+ * Under embroider builds, the spec-compliant version of the app
595
+ * has all the files under a folder which represents the package name,
596
+ * rather than "app".
597
+ */
598
+ let packageRelative = sourcePath.replace(workspacePath, "");
599
+ /**
600
+ * But we also don't want 'app' -- which is present in the v1 addon pipeline
601
+ */
602
+ packageRelative = packageRelative.replace(leadingSlashPath.app, node_path.default.sep);
603
+ packageRelative = node_path.default.normalize(packageRelative);
604
+ return `${name}${packageScopedPathToModulePath(packageRelative)}`;
605
+ }
606
+ /**
607
+ * To avoid hitting the filesysetm, we'll store all found
608
+ * project paths bere, so we can, in memory,
609
+ * get the folder where a package.json exists, rather than
610
+ * hit the file system every time.
611
+ */
612
+ const SEEN = /* @__PURE__ */ new Set();
613
+ function getSeen(sourcePath) {
614
+ if (SEEN.has(sourcePath)) return sourcePath;
615
+ let parts = sourcePath.split(node_path.default.sep);
616
+ for (let i = parts.length - 1; i > 1; i--) {
617
+ let toCheck = parts.slice(0, i).join(node_path.default.sep);
618
+ if (SEEN.has(toCheck)) return toCheck;
619
+ }
620
+ }
621
+ function findWorkspacePath(sourcePath, options) {
622
+ let cwd = options?.cwd ?? CWD;
623
+ if (sourcePath.endsWith(node_path.default.sep)) sourcePath = sourcePath.replace(/* @__PURE__ */ new RegExp(`${RegExp.escape(node_path.default.sep)}$`), "");
624
+ let seen = getSeen(sourcePath);
625
+ if (seen) return seen;
626
+ let candidatePath = node_path.default.join(sourcePath, "package.json");
627
+ if (node_fs.default.existsSync(candidatePath)) return sourcePath;
628
+ const packageJsonPath = findPackageJsonUp(sourcePath, { cwd });
629
+ if (!packageJsonPath) throw new Error(`Could not determine project for ${sourcePath}`);
630
+ const workspacePath = node_path.default.dirname(packageJsonPath);
631
+ SEEN.add(workspacePath);
632
+ return workspacePath;
633
+ }
634
+ function findPackageJsonUp(startPath, options) {
635
+ let cwd = options?.cwd ?? CWD;
636
+ let parts = startPath.split(node_path.default.sep);
637
+ for (let i = parts.length - 1; i > 1; i--) {
638
+ let toCheck = parts.slice(0, i).join(node_path.default.sep);
639
+ let packageJson = node_path.default.join(toCheck, "package.json");
640
+ if (node_fs.default.existsSync(packageJson)) return packageJson;
641
+ if (toCheck === cwd) break;
642
+ }
643
+ return null;
644
+ }
645
+ const MANIFEST_CACHE = /* @__PURE__ */ new Map();
646
+ /**
647
+ * Will return the package.json#name, or config/environment#moudlePrefix (if v1 app)
648
+ *
649
+ * @param {string} sourcePath
650
+ */
651
+ function moduleName(sourcePath) {
652
+ return getManifest(findWorkspacePath(sourcePath)).name;
653
+ }
654
+ /**
655
+ * @param {string} workspace
656
+ */
657
+ function getManifest(workspace) {
658
+ let existing = MANIFEST_CACHE.get(workspace);
659
+ if (existing) return existing;
660
+ let content = node_fs.default.readFileSync(node_path.default.join(workspace, "package.json")).toString();
661
+ let json = JSON.parse(content);
662
+ MANIFEST_CACHE.set(workspace, json);
663
+ return json;
664
+ }
665
+
666
+ //#endregion
667
+ //#region src/lib/renameClass.js
668
+ /**
669
+ * Splits a space-separated class list (the value of a `class` attribute or of
670
+ * a `[class="..."]` selector) into its individual class names.
671
+ *
672
+ * @param {string} classList
673
+ * @returns {string[]}
674
+ */
675
+ function splitClassList(classList) {
676
+ return classList.split(/\s+/).filter(Boolean);
677
+ }
678
+ /**
679
+ *
680
+ * @param {string} className
681
+ * @param {string} postfix
682
+ * @param {Set<string>} [classesInCss]
683
+ * @returns
684
+ */
685
+ function renameClass(className, postfix, classesInCss) {
686
+ const renamedClasses = splitClassList(className).map((c) => {
687
+ if (!classesInCss || classesInCss.has(c)) {
688
+ if (c.endsWith(postfix)) return c;
689
+ return c + "_" + postfix;
690
+ }
691
+ return c;
692
+ }).join(" ");
693
+ return className.replace(className.trimStart().trimEnd(), renamedClasses);
694
+ }
695
+
696
+ //#endregion
697
+ //#region src/build/babel-plugin.js
698
+ function _isRelevantFile(state, cwd) {
699
+ let fileName = state.file.opts.filename;
700
+ let additionalRoots = state.opts?.additionalRoots;
701
+ return isRelevantFile(fileName, {
702
+ additionalRoots,
703
+ cwd
704
+ });
705
+ }
706
+ /**
707
+ * @param {any} env - babel plugin env, env.types is most commonly used (esp in TS)
708
+ * @param {object} options - the options for scoped-css -- this is also available in each visitor's state.opts
709
+ * @param {string} workingDirectory
710
+ */
711
+ const scopedCSS$1 = (config) => (env, options, workingDirectory) => {
712
+ options = {
713
+ ...config,
714
+ ...options
715
+ };
716
+ /**
717
+ * This babel plugin does two things:
718
+ * - removes the import of scopedClass, if it exists
719
+ * - if scopedClass was imported, it is removed from any component's "scope bag"
720
+ * (the scope bag being a low-level object used for passing what is "in scope" for a component)
721
+ */
722
+ return { visitor: {
723
+ Program: { enter(path$8, state) {
724
+ if (!_isRelevantFile(state, workingDirectory)) {
725
+ state.canSkip = true;
726
+ return;
727
+ }
728
+ state.postfix = hashFromModulePath(appPath(state.filename));
729
+ } },
730
+ ImportDeclaration(path$8, state) {
731
+ if (state.canSkip) return;
732
+ if (path$8.node.source.value === "ember-scoped-css") {
733
+ let specifier = path$8.node.specifiers.find((x) => x.imported.name === "scopedClass");
734
+ if (specifier) state.file.opts.importedScopedClass = specifier.local.name;
735
+ if (specifier.local.name !== "scopedClass") throw new Error(`The scopedClass import is a psuedo-helper, and may not be renamed as it is removed at build time.`);
736
+ path$8.remove();
737
+ }
738
+ },
739
+ CallExpression(path$8, state) {
740
+ if (state.canSkip) return;
741
+ if (path$8.node.callee.type === "Identifier" && path$8.node.callee.name === state.file.opts?.importedScopedClass) {
742
+ if (path$8.node.arguments.length !== 1 || path$8.node.arguments[0].type !== "StringLiteral") throw new Error(`The scopedClass helper only accepts a single, non-dynamic, string literal argument.`);
743
+ const original = path$8.node.arguments[0].value;
744
+ const renamed = renameClass(original, state.postfix, new Set([original]));
745
+ const transformedString = env.types.stringLiteral(renamed);
746
+ path$8.replaceWith(transformedString);
747
+ }
748
+ },
749
+ ObjectProperty(path$8, state) {
750
+ if (!state.file.opts?.importedScopedClass) return;
751
+ if (path$8.node.value.type === "Identifier" && path$8.node.value.name === state.file.opts?.importedScopedClass) path$8.remove();
752
+ }
753
+ } };
754
+ };
755
+
756
+ //#endregion
757
+ //#region src/lib/css/utils.js
758
+ /**
759
+ * @param {string} css
760
+ * @return {string} hashed down version of the CSS for disambiguating
761
+ */
762
+ function hash(css) {
763
+ return `css-${md5(css)}`;
764
+ }
765
+ /**
766
+ * Attribute selectors are scoped with one of two strategies:
767
+ *
768
+ * - **renamed value**: class-targeting selectors whose value names real
769
+ * class(es) (`[class="foo"]`, `[class~="foo"]`) are scoped by renaming the
770
+ * value the same way `.foo` is renamed to `.foo_postfix`. The renamed token
771
+ * is unique per file, so nothing else is needed.
772
+ * - **postfix class**: every other attribute selector keeps its discriminator
773
+ * and is scoped by the generated postfix class — appended to the selector
774
+ * in the CSS and added to matching elements in the template (the same
775
+ * strategy bare tag selectors use: `div` becomes `div.postfix`).
776
+ *
777
+ * This predicate decides between the two. It is shared by the CSS rewrite
778
+ * (which renames the selector value) and by discovery in this file (which
779
+ * registers the value's class names for template renaming) so both sides
780
+ * always classify a selector the same way.
781
+ *
782
+ * @param {import('postcss-selector-parser').Attribute} node
783
+ * @returns {boolean}
784
+ */
785
+ function isRenamedClassAttribute(node) {
786
+ return node.attribute === "class" && (node.operator === "=" || node.operator === "~=") && Boolean(node.value);
787
+ }
788
+ function isInsideGlobal(node, func) {
789
+ const parent = node.parent;
790
+ if (!parent) return false;
791
+ if (parent.type === "pseudo" && parent.value === ":global") return true;
792
+ return isInsideGlobal(parent, func);
793
+ }
794
+ /**
795
+ * @param {string} cssPath path to a CSS file
796
+ */
797
+ function getCSSInfo(cssPath) {
798
+ if (!(0, fs.existsSync)(cssPath)) return null;
799
+ return getCSSContentInfo((0, fs.readFileSync)(cssPath, "utf8"));
800
+ }
801
+ /**
802
+ * We use this function to check each class used in the template
803
+ * to see if we need to leave it alone or transform it
804
+ *
805
+ * @param {string} css the CSS's contents
806
+ * @param {string} [lang] optional language hint (e.g. 'scss', 'sass', 'less')
807
+ * @return {{ classes: Set<string>, tags: Set<string>, attributes: Set<string>, css: string, id: string }}
808
+ */
809
+ function getCSSContentInfo(css, lang) {
810
+ const classes = /* @__PURE__ */ new Set();
811
+ const tags = /* @__PURE__ */ new Set();
812
+ const attributes = /* @__PURE__ */ new Set();
813
+ const parseOptions = lang === "scss" || lang === "sass" ? { syntax: postcss_scss.default } : {};
814
+ const ast = postcss.default.parse(css, parseOptions);
815
+ const isScss = lang === "scss" || lang === "sass";
816
+ ast.walk((node) => {
817
+ if (node.type === "rule") collectSelectorInfo(isScss ? resolveNestedSassSelector(node) : node.selector, classes, tags, attributes);
818
+ });
819
+ return {
820
+ classes,
821
+ tags,
822
+ attributes,
823
+ css,
824
+ id: hash(css)
825
+ };
826
+ }
827
+ /**
828
+ * Resolves a nested SCSS selector by substituting `&` with the fully-resolved
829
+ * parent selector, recursively. This converts e.g. `&--modifier` (child of
830
+ * `.block`) into `.block--modifier`, and handles arbitrary nesting depth so
831
+ * that `&--modifier` inside `&--modifier` inside `.block` yields
832
+ * `.block--modifier--modifier`.
833
+ *
834
+ * @param {import('postcss').Rule} node
835
+ * @return {string}
836
+ */
837
+ function resolveNestedSassSelector(node) {
838
+ const { selector } = node;
839
+ if (!selector.includes("&")) return selector;
840
+ const parent = node.parent;
841
+ if (!parent || parent.type !== "rule") return selector;
842
+ const resolvedParent = resolveNestedSassSelector(parent);
843
+ return selector.replace(/&/g, resolvedParent);
844
+ }
845
+ function collectSelectorInfo(sel, classes, tags, attributes) {
846
+ const transform = (sls) => {
847
+ sls.walk((selector) => {
848
+ if (isInsideGlobal(selector)) return;
849
+ if (selector.type === "class") classes.add(selector.value);
850
+ else if (selector.type === "tag") tags.add(selector.value);
851
+ else if (selector.type === "attribute") if (isRenamedClassAttribute(selector)) for (let token of splitClassList(selector.value)) classes.add(token);
852
+ else attributes.add(selector.attribute.toLowerCase());
853
+ });
854
+ };
855
+ (0, postcss_selector_parser.default)(transform).processSync(sel);
856
+ }
857
+
858
+ //#endregion
859
+ //#region src/lib/css/rewrite.js
860
+ const SEP$1 = "__";
861
+ function isRule(node) {
862
+ return node.type === "rule";
863
+ }
864
+ function isDeclaration(node) {
865
+ return node.type === "decl";
866
+ }
867
+ /**
868
+ * NOTE: "keyframes" is a singular definition, in that it's a block containing keyframes
869
+ * using `@keyframes {}` with only one thing on the inside doesn't make sense.
870
+ */
871
+ function rewriteReferenceable(node, postfix) {
872
+ let originalName = node.params;
873
+ let postfixedName = node.params + SEP$1 + postfix;
874
+ node.params = postfixedName;
875
+ return {
876
+ originalName,
877
+ postfixedName
878
+ };
879
+ }
880
+ /**
881
+ * Walk left and right from `node` within its compound selector (bounded by
882
+ * combinators) to see if the postfix class has already been added. Used to add
883
+ * the postfix class at most once per compound, e.g. `input[type="text"]`
884
+ * becomes `input.postfix[type="text"]`, not `input.postfix[type="text"].postfix`.
885
+ */
886
+ function compoundHasPostfixClass(node, postfix) {
887
+ const siblings = node.parent.nodes;
888
+ const index = siblings.indexOf(node);
889
+ for (let i = index; i >= 0; i--) {
890
+ if (siblings[i].type === "combinator") break;
891
+ if (siblings[i].type === "class" && siblings[i].value === postfix) return true;
892
+ }
893
+ for (let i = index + 1; i < siblings.length; i++) {
894
+ if (siblings[i].type === "combinator") break;
895
+ if (siblings[i].type === "class" && siblings[i].value === postfix) return true;
896
+ }
897
+ return false;
898
+ }
899
+ function addPostfixClass(node, postfix) {
900
+ if (compoundHasPostfixClass(node, postfix)) return;
901
+ node.parent.insertAfter(node, postcss_selector_parser.default.className({ value: postfix }));
902
+ }
903
+ function rewriteSelector(sel, postfix) {
904
+ const transform = (selectors) => {
905
+ const needsPostfixClass = [];
906
+ selectors.walk((selector) => {
907
+ if (isInsideGlobal(selector)) return;
908
+ if (selector.type === "psuedo") return;
909
+ if (isNthOfType(selector)) return;
910
+ if (selector.type === "class") selector.value += "_" + postfix;
911
+ else if (selector.type === "tag") needsPostfixClass.push(selector);
912
+ else if (selector.type === "attribute") if (isRenamedClassAttribute(selector)) {
913
+ selector.value = renameClass(selector.value, postfix);
914
+ if (!selector.quoteMark) selector.quoteMark = "\"";
915
+ } else needsPostfixClass.push(selector);
916
+ });
917
+ for (const node of needsPostfixClass) addPostfixClass(node, postfix);
918
+ selectors.walk((selector) => {
919
+ if (selector.type === "pseudo" && selector.value === ":global") selector.replaceWith(...selector.nodes);
920
+ });
921
+ };
922
+ return (0, postcss_selector_parser.default)(transform).processSync(sel);
923
+ }
924
+ function isNthOfType(node) {
925
+ if (!node) return false;
926
+ return node.parent?.value === ":nth-of-type" || isNthOfType(node.parent);
927
+ }
928
+ function isInsideKeyframes(node) {
929
+ const parent = node.parent;
930
+ if (!parent) return false;
931
+ if (parent.type === "atrule" && parent.name === "keyframes") return true;
932
+ return isInsideKeyframes(parent);
933
+ }
934
+ function rewriteCss(css, postfix, fileName, layerName) {
935
+ const ast = postcss.default.parse(css);
936
+ /**
937
+ * kind => originalName => postfixedName
938
+ * @type {{ [kind: string]: { [originalName: string]: string }}}
939
+ */
940
+ const referenceables = {
941
+ keyframes: {},
942
+ "counter-style": {},
943
+ "position-try": {},
944
+ property: {}
945
+ };
946
+ const availableReferenceables = new Set(Object.keys(referenceables));
947
+ function isReferenceable(node) {
948
+ if (node.type !== "atrule") return;
949
+ return availableReferenceables.has(node.name);
950
+ }
951
+ function updateDirectReferences(node) {
952
+ if (!node.value) return;
953
+ for (let [, map] of Object.entries(referenceables)) if (map[node.value]) node.value = map[node.value];
954
+ }
955
+ function updateShorthandContents(node) {
956
+ if (node.prop === "animation") {
957
+ let match = node.value.split(" ").filter((x) => referenceables.keyframes[x]);
958
+ if (match.length) match.forEach((x) => {
959
+ let replacement = referenceables.keyframes[x];
960
+ if (!replacement) return;
961
+ node.value = node.value.replace(x, replacement);
962
+ });
963
+ }
964
+ for (let [lookFor, replaceWith] of Object.entries(referenceables.property)) {
965
+ let lookForVar = `var(${lookFor})`;
966
+ let replaceWithVar = `var(${replaceWith})`;
967
+ node.value = node.value.replace(lookForVar, replaceWithVar);
968
+ }
969
+ }
970
+ /**
971
+ * We have to do two passes:
972
+ * 1. postfix all the referenceable syntax
973
+ * 2. postfix as normal, but also checking values of CSS properties
974
+ * that could match postfixed referenceables from step 1
975
+ */
976
+ ast.walk((node) => {
977
+ /**
978
+ * @keyframes, @counter-style, etc
979
+ */
980
+ if (isReferenceable(node)) {
981
+ let name = node.name;
982
+ let { originalName, postfixedName } = rewriteReferenceable(node, postfix);
983
+ referenceables[name][originalName] = postfixedName;
984
+ return;
985
+ }
986
+ });
987
+ ast.walk((node) => {
988
+ if (isDeclaration(node)) {
989
+ updateDirectReferences(node);
990
+ updateShorthandContents(node);
991
+ return;
992
+ }
993
+ if (isRule(node)) {
994
+ /**
995
+ * The inner-contents of a keyframe are percentages, rather than selectors
996
+ */
997
+ if (isInsideKeyframes(node)) return;
998
+ node.selector = rewriteSelector(node.selector, postfix);
999
+ return;
1000
+ }
1001
+ });
1002
+ const rewrittenCss = ast.toString();
1003
+ return [
1004
+ `/* ${fileName} */`,
1005
+ layerName ? `@layer ${layerName} {` : "",
1006
+ rewrittenCss.trimEnd(),
1007
+ layerName ? `}` : ""
1008
+ ].filter(Boolean).join("\n") + "\n";
1009
+ }
1010
+
1011
+ //#endregion
1012
+ //#region src/lib/request.js
1013
+ const KEY = "ember-scoped.css";
1014
+ const SEP = "___";
1015
+ const request = {
1016
+ is: {
1017
+ inline(request$1) {
1018
+ return request$1.includes(KEY);
1019
+ },
1020
+ colocated(request$1) {
1021
+ return request$1.includes(".css?scoped=");
1022
+ }
1023
+ },
1024
+ inline: {
1025
+ create(cssHash, postfix, cssContents, lang) {
1026
+ let url = `./${postfix}${SEP}${cssHash}.${KEY}?css=${encodeURIComponent(cssContents)}`;
1027
+ if (lang) url += `&lang=${encodeURIComponent(lang)}`;
1028
+ return url;
1029
+ },
1030
+ decode(request$1) {
1031
+ let [left, qps] = request$1.split("?");
1032
+ left = left.slice(2).replace(`.${KEY}`, "");
1033
+ let [postfix, hash$2] = left.split(SEP);
1034
+ let search = new URLSearchParams(qps);
1035
+ return {
1036
+ hash: hash$2,
1037
+ postfix,
1038
+ css: search.get("css"),
1039
+ from: search.get("from"),
1040
+ lang: search.get("lang")
1041
+ };
1042
+ }
1043
+ },
1044
+ colocated: {
1045
+ create(cssHash, postfix, filePath) {
1046
+ return `./${node_path.default.basename(filePath)}?scoped=${postfix}&cssHash=${cssHash}`;
1047
+ },
1048
+ decode(request$1) {
1049
+ const [fileName, qs] = request$1.split("?");
1050
+ const search = new URLSearchParams(qs);
1051
+ return {
1052
+ fileName,
1053
+ cssHash: search.get("cssHash"),
1054
+ postfix: search.get("scoped")
1055
+ };
1056
+ }
1057
+ }
1058
+ };
1059
+
1060
+ //#endregion
1061
+ //#region src/build/unplugin-colocated.js
1062
+ const META$1 = "scoped-css:colocated";
1063
+ /** File extensions that Vite can preprocess via its CSS preprocessor pipeline */
1064
+ const PREPROCESSED_EXTENSIONS = new Set([
1065
+ ".scss",
1066
+ ".sass",
1067
+ ".less",
1068
+ ".styl",
1069
+ ".stylus"
1070
+ ]);
1071
+ /**
1072
+ * Plugin for supporting colocated styles
1073
+ *
1074
+ * e.g.:
1075
+ * src/components/my-component.js
1076
+ * src/components/my-component.css
1077
+ */
1078
+ function colocated(options = {}) {
1079
+ const CWD$1 = process.cwd();
1080
+ /** @type {import('vite').ResolvedConfig | undefined} */
1081
+ let viteConfig;
1082
+ /** @type {((code: string, filename: string, config: unknown) => Promise<{ code: string }>) | undefined} */
1083
+ let preprocessCSS;
1084
+ /**
1085
+ *
1086
+ * @param {string} id the request id / what was imported
1087
+ * @param {string} filePath path on disk
1088
+ * @returns
1089
+ */
1090
+ function buildResponse(id, filePath) {
1091
+ const parsed = request.colocated.decode(id);
1092
+ const relativeFilePath = node_path.default.relative(CWD$1, filePath);
1093
+ return {
1094
+ id: filePath,
1095
+ meta: { [META$1]: {
1096
+ postfix: parsed.postfix,
1097
+ fileName: relativeFilePath,
1098
+ fullPath: filePath
1099
+ } }
1100
+ };
1101
+ }
1102
+ return {
1103
+ name: "ember-scoped-css:colocated",
1104
+ resolveId(id, importer) {
1105
+ if (request.is.colocated(id)) {
1106
+ const parsed = request.colocated.decode(id);
1107
+ return buildResponse(id, node_path.default.resolve(node_path.default.dirname(importer), node_path.default.basename(parsed.fileName)));
1108
+ }
1109
+ },
1110
+ load(id) {
1111
+ const meta = this.getModuleInfo(id)?.meta?.[META$1];
1112
+ if (meta) {
1113
+ this.addWatchFile(meta.fullPath);
1114
+ return rewriteCss((0, node_fs.readFileSync)(meta.fullPath, "utf-8"), meta.postfix, meta.fileName, options.layerName);
1115
+ }
1116
+ },
1117
+ vite: {
1118
+ async configResolved(config) {
1119
+ viteConfig = config;
1120
+ try {
1121
+ preprocessCSS = (await import((0, node_module.createRequire)(node_path.default.join(config.root, "package.json")).resolve("vite"))).preprocessCSS;
1122
+ } catch {}
1123
+ },
1124
+ async load(id) {
1125
+ if (request.is.colocated(id)) {
1126
+ const parsed = request.colocated.decode(id);
1127
+ let code = (0, node_fs.readFileSync)(parsed.fileName, "utf-8");
1128
+ let relativeFilePath = node_path.default.relative(CWD$1, parsed.fileName);
1129
+ const ext = node_path.default.extname(parsed.fileName).toLowerCase();
1130
+ if (PREPROCESSED_EXTENSIONS.has(ext)) {
1131
+ if (!viteConfig || !preprocessCSS) throw new Error(`[ember-scoped-css] Colocated CSS file with extension '${ext}' requires Vite. CSS preprocessing is only supported in Vite builds.`);
1132
+ code = (await preprocessCSS(code, parsed.fileName, viteConfig)).code;
1133
+ }
1134
+ return rewriteCss(code, parsed.postfix, relativeFilePath, options.layerName);
1135
+ }
1136
+ }
1137
+ }
1138
+ };
1139
+ }
1140
+
1141
+ //#endregion
1142
+ //#region src/build/unplugin-inline.js
1143
+ const META = "scoped-css:inline";
1144
+ /**
1145
+ * Plugin for supporting the styles from
1146
+ *
1147
+ * <template>
1148
+ * <style>...</style>
1149
+ * </template>
1150
+ *
1151
+ * This plugin can't have HMR for CSS because changes to the CSS content alters the template content
1152
+ */
1153
+ function inline(options = {}) {
1154
+ const CWD$1 = process.cwd();
1155
+ /** @type {import('vite').ResolvedConfig | undefined} */
1156
+ let viteConfig;
1157
+ /** @type {((code: string, filename: string, config: unknown) => Promise<{ code: string }>) | undefined} */
1158
+ let preprocessCSS;
1159
+ /**
1160
+ * @param {string} id the request id / what was imported
1161
+ */
1162
+ function buildResponse(id, filePath) {
1163
+ const parsed = request.inline.decode(id);
1164
+ const relativeFilePath = node_path.default.relative(CWD$1, filePath);
1165
+ return {
1166
+ id: filePath.split("?")[0],
1167
+ meta: { [META]: {
1168
+ rawCss: parsed.css,
1169
+ postfix: parsed.postfix,
1170
+ fileName: relativeFilePath,
1171
+ lang: parsed.lang
1172
+ } }
1173
+ };
1174
+ }
1175
+ return {
1176
+ name: "ember-scoped-css:inline",
1177
+ resolveId(id, importer) {
1178
+ if (request.is.inline(id)) {
1179
+ const parsed = request.inline.decode(id);
1180
+ return buildResponse(id, node_path.default.resolve(node_path.default.dirname(importer), `${node_path.default.basename(importer, node_path.default.extname(importer))}-${parsed.hash}.css`));
1181
+ }
1182
+ },
1183
+ async load(id) {
1184
+ const meta = this.getModuleInfo(id)?.meta?.[META];
1185
+ if (meta) {
1186
+ let rawCss = meta.rawCss;
1187
+ if (meta.lang) {
1188
+ if (!viteConfig || !preprocessCSS) throw new Error(`[ember-scoped-css] <style scoped lang="${meta.lang}"> requires Vite. CSS preprocessing via the 'lang' attribute is only supported in Vite builds.`);
1189
+ const fakeFilename = `${meta.fileName}.${meta.lang}`;
1190
+ rawCss = (await preprocessCSS(rawCss, fakeFilename, viteConfig)).code;
1191
+ }
1192
+ return rewriteCss(rawCss, meta.postfix, `<inline>/${meta.fileName}`, options.layerName);
1193
+ }
1194
+ },
1195
+ vite: { async configResolved(config) {
1196
+ viteConfig = config;
1197
+ try {
1198
+ preprocessCSS = (await import((0, node_module.createRequire)(node_path.default.join(config.root, "package.json")).resolve("vite"))).preprocessCSS;
1199
+ } catch {}
1200
+ } }
1201
+ };
1202
+ }
1203
+
1204
+ //#endregion
1205
+ //#region src/build/scoped-css-unplugin.js
1206
+ /**
1207
+ * The plugin that handles CSS requests for `<style>` elements and transforms
1208
+ * for existing files
1209
+ *
1210
+ * vite: CSS files are resolved by vite. We use their resolver to also get
1211
+ * HMR. That is, for all non-physical CSS files, we extend vite by our
1212
+ * resolver and also can enrich metadata to it (for better debugging)
1213
+ */
1214
+ const unplugin$1 = (0, unplugin.createUnplugin)((options = {}) => {
1215
+ return [colocated(options), inline(options)];
1216
+ });
1217
+
1218
+ //#endregion
1219
+ //#region src/lib/path/template-transform-paths.js
1220
+ /**
1221
+ * template plugins do not hand us the correct file path.
1222
+ * additionally, we may not be able to rely on this data in the future,
1223
+ * so this functions acts as a means of normalizing _whatever_ we're given
1224
+ * in the future.
1225
+ *
1226
+ * @param {string} filename
1227
+ * @returns {string} the absolute path to the file
1228
+ */
1229
+ function fixFilename(filename) {
1230
+ let fileName = filename;
1231
+ let workspace = findWorkspacePath(fileName);
1232
+ /**
1233
+ * ember-source 5.8:
1234
+ * - the filename looks like an absolute path, but swapped out the 'app' part of the path
1235
+ * with the module name, so the file paths never exist on disk
1236
+ *
1237
+ * - in vite apps:
1238
+ * the 'app' part _may_ be `src`, so we also need to ensure that `src` is excluded as well
1239
+ */
1240
+ let hasAppDir = fileName.includes(node_path.default.join(workspace, "app"));
1241
+ let hasSrcDir = fileName.includes(node_path.default.join(workspace, "src"));
1242
+ if (!(hasAppDir || hasSrcDir) && !fileName.includes(leadingSlashPath.embroiderDir)) {
1243
+ let [maybeScope, ...rest] = fileName.replace(workspace, "").split(node_path.default.sep).filter(Boolean);
1244
+ let parts = rest;
1245
+ if (maybeScope.startsWith("@")) {
1246
+ let [, ...rester] = rest;
1247
+ parts = rester;
1248
+ }
1249
+ let relative = node_path.default.join(...parts);
1250
+ return node_path.default.join(workspace, "app", relative);
1251
+ }
1252
+ if (!fileName.includes(workspace)) return fileName;
1253
+ return fileName;
1254
+ }
1255
+
1256
+ //#endregion
1257
+ //#region src/lib/rewriteHbs.js
1258
+ /**
1259
+ * Whether an element may carry an attribute that appears in a scoped
1260
+ * attribute selector. This includes component invocations: a component
1261
+ * receives the postfix class through its `...attributes` the same way it
1262
+ * receives the matched attribute, so `[type="text"]` scopes
1263
+ * `<Foo type="text">` just as it scopes `<input type="text">`.
1264
+ *
1265
+ * An element that spreads `...attributes` can receive any attribute from its
1266
+ * caller at runtime, so it counts as long as the CSS scopes by attribute at
1267
+ * all — the preserved attribute selector still decides which rules actually
1268
+ * apply.
1269
+ *
1270
+ * `attributes` comes from parsing the CSS, so it can only contain valid
1271
+ * attribute-selector names — `@args` can never be in it and needs no special
1272
+ * handling.
1273
+ *
1274
+ * Names in `attributes` are lowercased at discovery (CSS matches HTML
1275
+ * attribute names case-insensitively), so compare lowercased.
1276
+ */
1277
+ function elementHasScopedAttribute(node, attributes) {
1278
+ if (attributes.size === 0) return false;
1279
+ return node.attributes.some((attr) => attr.name === "...attributes" || attributes.has(attr.name.toLowerCase()));
1280
+ }
1281
+ function templatePlugin({ classes, tags, attributes, postfix }) {
1282
+ let stack = [];
1283
+ let scopedClassCandidates = ["scoped-class", "scopedClass"];
1284
+ function isScopedClass(str) {
1285
+ if (!str) return false;
1286
+ return scopedClassCandidates.some((candidate) => candidate === str);
1287
+ }
1288
+ return {
1289
+ AttrNode(node) {
1290
+ if (node.name === "class") {
1291
+ if (node.value.type === "TextNode" && node.value.chars) {
1292
+ const renamedClass = renameClass(node.value.chars, postfix, classes);
1293
+ node.value.chars = renamedClass;
1294
+ } else if (node.value.type === "ConcatStatement") {
1295
+ for (let part of node.value.parts) if (part.type === "TextNode" && part.chars) part.chars = renameClass(part.chars, postfix, classes);
1296
+ else if (part.type === "MustacheStatement") ember_template_recast.traverse(part, { StringLiteral(node$1) {
1297
+ node$1.value = renameClass(node$1.value, postfix, classes);
1298
+ } });
1299
+ }
1300
+ }
1301
+ },
1302
+ ElementNode(node) {
1303
+ if (!(tags.has(node.tag) || elementHasScopedAttribute(node, attributes))) return;
1304
+ const classAttr = node.attributes.find((attr) => attr.name === "class");
1305
+ if (!classAttr) node.attributes.push(ember_template_recast.builders.attr("class", ember_template_recast.builders.text(postfix)));
1306
+ else if (classAttr.value.type === "TextNode") classAttr.value.chars += " " + postfix;
1307
+ else if (classAttr.value.type === "ConcatStatement") classAttr.value.parts.push(ember_template_recast.builders.text(" " + postfix));
1308
+ else {
1309
+ classAttr.value = ember_template_recast.builders.concat([classAttr.value, ember_template_recast.builders.text(" " + postfix)]);
1310
+ classAttr.quoteType = "\"";
1311
+ }
1312
+ },
1313
+ All: {
1314
+ enter(node) {
1315
+ stack.push(node);
1316
+ },
1317
+ exit() {
1318
+ stack.pop();
1319
+ }
1320
+ },
1321
+ MustacheStatement(node) {
1322
+ let cssClass;
1323
+ if (isScopedClass(getValue(node.path)) && node.params?.length === 1 && node.params[0].type === "StringLiteral") cssClass = node.params[0].value;
1324
+ if (isScopedClass(getValue(node.path?.path)) && node.path?.params?.length === 1 && node.path?.params[0].type === "StringLiteral") cssClass = node.path.params[0].value;
1325
+ if (cssClass) {
1326
+ const textNode = ember_template_recast.builders.text(renameClass(cssClass, postfix));
1327
+ const parent = stack[stack.length - 1];
1328
+ if (parent?.type === "AttrNode") parent.quoteType = "\"";
1329
+ return textNode;
1330
+ }
1331
+ },
1332
+ SubExpression(node) {
1333
+ if (isScopedClass(getValue(node.path)) && node.params?.length === 1 && node.params[0].type === "StringLiteral") {
1334
+ const cssClass = node.params[0].value;
1335
+ return ember_template_recast.builders.literal("StringLiteral", renameClass(cssClass, postfix));
1336
+ }
1337
+ }
1338
+ };
1339
+ }
1340
+ function getValue(path$8) {
1341
+ if (!path$8) return;
1342
+ if ("value" in path$8) return path$8.value;
1343
+ /**
1344
+ * Deprecated in ember 5.9+
1345
+ * (so we use the above for newer embers)
1346
+ */
1347
+ return path$8.original;
1348
+ }
1349
+
1350
+ //#endregion
1351
+ //#region src/build/template-plugin.js
1352
+ const noopPlugin = {
1353
+ name: "ember-scoped-css:noop",
1354
+ visitor: {}
1355
+ };
1356
+ /**
1357
+ * @returns {ASTPlugin}
1358
+ */
1359
+ function createPlugin(config) {
1360
+ /**
1361
+ *
1362
+ * @param {ASTPluginEnvironment} env
1363
+ */
1364
+ return function scopedCss(env) {
1365
+ let cwd = node_process.default.cwd();
1366
+ if (!isRelevantFile(env.filename, {
1367
+ additionalRoots: config.additionalRoots,
1368
+ cwd
1369
+ })) return noopPlugin;
1370
+ let absolutePath = fixFilename(env.filename);
1371
+ let postfix = hashFromModulePath(appPath(absolutePath));
1372
+ /**
1373
+ * The list of naked tag selectors found in the CSS
1374
+ *
1375
+ * @type {Set<string>}
1376
+ */
1377
+ let scopedTags = /* @__PURE__ */ new Set();
1378
+ /**
1379
+ * The list of classes found in the CSS
1380
+ *
1381
+ * @type {Set<string>}
1382
+ */
1383
+ let scopedClasses = /* @__PURE__ */ new Set();
1384
+ /**
1385
+ * The attribute names found in attribute selectors in the CSS, used to
1386
+ * mark matching elements with the scope class.
1387
+ *
1388
+ * @type {Set<string>}
1389
+ */
1390
+ let scopedAttributes = /* @__PURE__ */ new Set();
1391
+ /**
1392
+ * @param {{ tags: Set<string>; classes: Set<string>; attributes: Set<string> }} info
1393
+ */
1394
+ function addInfo(info$1) {
1395
+ for (let item of info$1.tags) scopedTags.add(item);
1396
+ for (let item of info$1.classes) scopedClasses.add(item);
1397
+ for (let item of info$1.attributes) scopedAttributes.add(item);
1398
+ }
1399
+ let cssPath = cssPathFor(absolutePath);
1400
+ let info = getCSSInfo(cssPath);
1401
+ let localCssPath = forcePosix(cssPath.replace(cwd + node_path.default.sep, ""));
1402
+ /**
1403
+ * This will be falsey if we don't have a co-located CSS file.
1404
+ * We'll still want to check for embedded <style scoped> tags though.
1405
+ */
1406
+ if (info) {
1407
+ addInfo(info);
1408
+ let cssRequest = request.colocated.create(info.id, postfix, localCssPath);
1409
+ /**
1410
+ * With this we don't need a JS plugin
1411
+ */
1412
+ env.meta.jsutils.importForSideEffect(cssRequest);
1413
+ }
1414
+ let visitors = templatePlugin({
1415
+ classes: scopedClasses,
1416
+ tags: scopedTags,
1417
+ attributes: scopedAttributes,
1418
+ postfix
1419
+ });
1420
+ return {
1421
+ name: "ember-scoped-css:template-plugin",
1422
+ visitor: {
1423
+ ...visitors,
1424
+ Template(node) {
1425
+ /**
1426
+ * We only allow a scoped <style> at the root
1427
+ */
1428
+ let styleTag = node.body.find((n) => n.type === "ElementNode" && n.tag === "style");
1429
+ if (hasScopedAttribute(styleTag)) {
1430
+ let css = textContent(styleTag);
1431
+ let lang = getLangAttribute(styleTag);
1432
+ let info$1 = getCSSContentInfo(css, lang);
1433
+ addInfo(info$1);
1434
+ if (hasInlineAttributeWithoutLang(styleTag))
1435
+ /**
1436
+ * This will be handled in ElementNode traversal
1437
+ */
1438
+ return;
1439
+ if (lang)
1440
+ /**
1441
+ * For <style scoped inline lang="..."> we cannot preprocess at Babel-time
1442
+ * (preprocessing is async and requires Vite's ResolvedConfig).
1443
+ * Remove the tag and inject via virtual CSS module and warn user.
1444
+ */
1445
+ console.warn(`[ember-scoped-css] <style scoped inline lang="${lang}"> is not supported (preprocessing is async and cannot run at Babel-time). Downgrading to non-inline: the style tag will be removed and injected as a virtual CSS module.`);
1446
+ let cssRequest = request.inline.create(info$1.id, postfix, css, lang);
1447
+ env.meta.jsutils.importForSideEffect(cssRequest);
1448
+ }
1449
+ },
1450
+ AttrNode(...args) {
1451
+ return visitors.AttrNode(...args);
1452
+ },
1453
+ ElementNode(node, walker) {
1454
+ visitors.ElementNode(node, walker);
1455
+ if (hasScopedAttribute(node)) {
1456
+ if (walker.parent?.node.type !== "Template") throw new Error("<style scoped> tags must be at the root of the template, they cannot be nested");
1457
+ if (hasInlineAttributeWithoutLang(node)) {
1458
+ let scopedText = rewriteCss(textContent(node), postfix, localCssPath, config.layerName);
1459
+ /**
1460
+ * Traverse this and allow interpolation
1461
+ */
1462
+ node.children = [env.syntax.builders.text(scopedText)];
1463
+ return;
1464
+ }
1465
+ return null;
1466
+ }
1467
+ if (hasInlineAttributeWithoutLang(node)) throw new Error(`<style inline> is not valid. Please add the scoped attribute: <style scoped inline>`);
1468
+ },
1469
+ MustacheStatement(...args) {
1470
+ return visitors.MustacheStatement(...args);
1471
+ },
1472
+ SubExpression(...args) {
1473
+ return visitors.SubExpression(...args);
1474
+ }
1475
+ }
1476
+ };
1477
+ };
1478
+ }
1479
+ /**
1480
+ * Thanks, CardStack and @ef4 for this code.
1481
+ */
1482
+ const SCOPED_ATTRIBUTE_NAME = "scoped";
1483
+ const INLINE_ATTRIBUTE_NAME = "inline";
1484
+ const LANG_ATTRIBUTE_NAME = "lang";
1485
+ function hasScopedAttribute(node) {
1486
+ if (!node) return;
1487
+ if (node.tag !== "style") return;
1488
+ if (node.type !== "ElementNode") return;
1489
+ return node.attributes.some((attribute) => attribute.name === SCOPED_ATTRIBUTE_NAME);
1490
+ }
1491
+ function hasInlineAttributeWithoutLang(node) {
1492
+ if (!node) return;
1493
+ if (node.tag !== "style") return;
1494
+ if (node.type !== "ElementNode") return;
1495
+ if (getLangAttribute(node)) return false;
1496
+ return node.attributes.some((attribute) => attribute.name === INLINE_ATTRIBUTE_NAME);
1497
+ }
1498
+ /**
1499
+ * Returns the value of the `lang` attribute on a `<style>` node, or null if absent.
1500
+ *
1501
+ * @param {object} node
1502
+ * @returns {string | null}
1503
+ */
1504
+ function getLangAttribute(node) {
1505
+ if (!node) return null;
1506
+ if (node.tag !== "style") return null;
1507
+ if (node.type !== "ElementNode") return null;
1508
+ const attr = node.attributes.find((attribute) => attribute.name === LANG_ATTRIBUTE_NAME);
1509
+ if (!attr) return null;
1510
+ const value = attr.value;
1511
+ if (value?.type === "TextNode") return value.chars || null;
1512
+ return null;
1513
+ }
1514
+ function textContent(node) {
1515
+ return node.children.filter((c) => c.type === "TextNode").map((c) => c.chars).join("");
1516
+ }
1517
+
1518
+ //#endregion
1519
+ //#region src/build/public-exports/all.js
1520
+ const scopedCSS = {
1521
+ vite: unplugin$1.vite,
1522
+ rollup: unplugin$1.rollup,
1523
+ babel: scopedCSS$1,
1524
+ template: createPlugin
1525
+ };
1526
+
1527
+ //#endregion
1528
+ Object.defineProperty(exports, 'scopedCSS', {
1529
+ enumerable: true,
1530
+ get: function () {
1531
+ return scopedCSS;
1532
+ }
1533
+ });
1534
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsLURKanI2WUV4LmNqcyIsIm5hbWVzIjpbImhhc2giLCJoYXNoIiwiaGFzaEZyb21Nb2R1bGVQYXRoIiwiaGFzaFBvc2l4TW9kdWxlUGF0aCIsInBhdGgiLCJmc1N5bmMiLCJzY29wZWRDU1MiLCJwYXRoIiwic2Nzc1N5bnRheCIsIlNFUCIsInBhcnNlciIsInJlcXVlc3QiLCJoYXNoIiwicGF0aCIsIk1FVEEiLCJDV0QiLCJwYXRoIiwiQ1dEIiwicGF0aCIsInVucGx1Z2luIiwicGF0aCIsIm5vZGUiLCJyZWNhc3QiLCJwYXRoIiwicHJvY2VzcyIsImluZm8iLCJwYXRoIiwidW5wbHVnaW4iLCJiYWJlbC5zY29wZWRDU1MiLCJ0ZW1wbGF0ZS5jcmVhdGVQbHVnaW4iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3BhdGgvY29uc3QuanMiLCIuLi8uLi9zcmMvbGliL3BhdGgvbWQ1LmpzIiwiLi4vLi4vc3JjL2xpYi9wYXRoL2hhc2gtZnJvbS1tb2R1bGUtcGF0aC5qcyIsIi4uLy4uL3NyYy9saWIvcGF0aC91dGlscy5qcyIsIi4uLy4uL3NyYy9saWIvcmVuYW1lQ2xhc3MuanMiLCIuLi8uLi9zcmMvYnVpbGQvYmFiZWwtcGx1Z2luLmpzIiwiLi4vLi4vc3JjL2xpYi9jc3MvdXRpbHMuanMiLCIuLi8uLi9zcmMvbGliL2Nzcy9yZXdyaXRlLmpzIiwiLi4vLi4vc3JjL2xpYi9yZXF1ZXN0LmpzIiwiLi4vLi4vc3JjL2J1aWxkL3VucGx1Z2luLWNvbG9jYXRlZC5qcyIsIi4uLy4uL3NyYy9idWlsZC91bnBsdWdpbi1pbmxpbmUuanMiLCIuLi8uLi9zcmMvYnVpbGQvc2NvcGVkLWNzcy11bnBsdWdpbi5qcyIsIi4uLy4uL3NyYy9saWIvcGF0aC90ZW1wbGF0ZS10cmFuc2Zvcm0tcGF0aHMuanMiLCIuLi8uLi9zcmMvbGliL3Jld3JpdGVIYnMuanMiLCIuLi8uLi9zcmMvYnVpbGQvdGVtcGxhdGUtcGx1Z2luLmpzIiwiLi4vLi4vc3JjL2J1aWxkL3B1YmxpYy1leHBvcnRzL2FsbC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuLyoqXG4gKiBKb2luIHdpbGwgY29udmVydCB0byB3aGF0ZXZlciBpcyBhcHByb3ByaWF0ZSBmcm8gdGhlIGN1cnJlbnQgcGxhdGZvcm1cbiAqL1xuXG5leHBvcnQgY29uc3QgbGVhZGluZ1NsYXNoUGF0aCA9IHtcbiAgZW1icm9pZGVyRGlyOiBwYXRoLmpvaW4oJy9ub2RlX21vZHVsZXMvLmVtYnJvaWRlci8nKSxcbiAgYXRFbWJyb2lkZXI6IHBhdGguam9pbignL0BlbWJyb2lkZXInKSxcbiAgY29tcG9uZW50c0RpcjogcGF0aC5qb2luKCcvY29tcG9uZW50cy8nKSxcbiAgdGVtcGxhdGVzRGlyOiBwYXRoLmpvaW4oJy90ZW1wbGF0ZXMvJyksXG4gIHJvdXRlc0RpcjogcGF0aC5qb2luKCcvcm91dGVzLycpLFxuICB0ZXN0ZW06IHBhdGguam9pbignL3Rlc3RlbScpLFxuICBzcmM6IHBhdGguam9pbignL3NyYy8nKSxcbiAgYXBwOiBwYXRoLmpvaW4oJy9hcHAvJyksXG59O1xuXG5leHBvcnQgY29uc3QgYmFyZVBhdGggPSB7XG4gIHBucG1EaXI6IHBhdGguam9pbignbm9kZV9tb2R1bGVzLy5wbnBtJyksXG59O1xuIiwiLypcbiAqIEphdmFTY3JpcHQgTUQ1XG4gKiBodHRwczovL2dpdGh1Yi5jb20vYmx1ZWltcC9KYXZhU2NyaXB0LU1ENVxuICpcbiAqIENvcHlyaWdodCAyMDExLCBTZWJhc3RpYW4gVHNjaGFuXG4gKiBodHRwczovL2JsdWVpbXAubmV0XG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlOlxuICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVRcbiAqXG4gKiBCYXNlZCBvblxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBSU0EgRGF0YSBTZWN1cml0eSwgSW5jLiBNRDUgTWVzc2FnZVxuICogRGlnZXN0IEFsZ29yaXRobSwgYXMgZGVmaW5lZCBpbiBSRkMgMTMyMS5cbiAqIFZlcnNpb24gMi4yIENvcHlyaWdodCAoQykgUGF1bCBKb2huc3RvbiAxOTk5IC0gMjAwOVxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlXG4gKiBTZWUgaHR0cDovL3BhamhvbWUub3JnLnVrL2NyeXB0L21kNSBmb3IgbW9yZSBpbmZvLlxuICpcbiAqIE1vZGlmaWNhdGlvbnM6XG4gKiAtIHJlbW92ZWQgSUlGRSwgZXhwb3J0ZWQgbWQ1ICh0aGlzIGZpbGUgaXMgbm93IEVTTSlcbiAqL1xuXG4vKipcbiAqIEFkZCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi5cbiAqIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucyBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gaW50ZXJwcmV0ZXJzLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IEZpcnN0IGludGVnZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFNlY29uZCBpbnRlZ2VyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBTdW1cbiAqL1xuZnVuY3Rpb24gc2FmZUFkZCh4LCB5KSB7XG4gIHZhciBsc3cgPSAoeCAmIDB4ZmZmZikgKyAoeSAmIDB4ZmZmZik7XG4gIHZhciBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcblxuICByZXR1cm4gKG1zdyA8PCAxNikgfCAobHN3ICYgMHhmZmZmKTtcbn1cblxuLyoqXG4gKiBCaXR3aXNlIHJvdGF0ZSBhIDMyLWJpdCBudW1iZXIgdG8gdGhlIGxlZnQuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IG51bSAzMi1iaXQgbnVtYmVyXG4gKiBAcGFyYW0ge251bWJlcn0gY250IFJvdGF0aW9uIGNvdW50XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSb3RhdGVkIG51bWJlclxuICovXG5mdW5jdGlvbiBiaXRSb3RhdGVMZWZ0KG51bSwgY250KSB7XG4gIHJldHVybiAobnVtIDw8IGNudCkgfCAobnVtID4+PiAoMzIgLSBjbnQpKTtcbn1cblxuLyoqXG4gKiBCYXNpYyBvcGVyYXRpb24gdGhlIGFsZ29yaXRobSB1c2VzLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBxIHFcbiAqIEBwYXJhbSB7bnVtYmVyfSBhIGFcbiAqIEBwYXJhbSB7bnVtYmVyfSBiIGJcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSBzIHNcbiAqIEBwYXJhbSB7bnVtYmVyfSB0IHRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlc3VsdFxuICovXG5mdW5jdGlvbiBtZDVjbW4ocSwgYSwgYiwgeCwgcywgdCkge1xuICByZXR1cm4gc2FmZUFkZChiaXRSb3RhdGVMZWZ0KHNhZmVBZGQoc2FmZUFkZChhLCBxKSwgc2FmZUFkZCh4LCB0KSksIHMpLCBiKTtcbn1cblxuLyoqXG4gKiBCYXNpYyBvcGVyYXRpb24gdGhlIGFsZ29yaXRobSB1c2VzLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBhIGFcbiAqIEBwYXJhbSB7bnVtYmVyfSBiIGJcbiAqIEBwYXJhbSB7bnVtYmVyfSBjIGNcbiAqIEBwYXJhbSB7bnVtYmVyfSBkIGRcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSBzIHNcbiAqIEBwYXJhbSB7bnVtYmVyfSB0IHRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlc3VsdFxuICovXG5mdW5jdGlvbiBtZDVmZihhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oKGIgJiBjKSB8ICh+YiAmIGQpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuLyoqXG4gKiBCYXNpYyBvcGVyYXRpb24gdGhlIGFsZ29yaXRobSB1c2VzLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBhIGFcbiAqIEBwYXJhbSB7bnVtYmVyfSBiIGJcbiAqIEBwYXJhbSB7bnVtYmVyfSBjIGNcbiAqIEBwYXJhbSB7bnVtYmVyfSBkIGRcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSBzIHNcbiAqIEBwYXJhbSB7bnVtYmVyfSB0IHRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlc3VsdFxuICovXG5mdW5jdGlvbiBtZDVnZyhhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oKGIgJiBkKSB8IChjICYgfmQpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuLyoqXG4gKiBCYXNpYyBvcGVyYXRpb24gdGhlIGFsZ29yaXRobSB1c2VzLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBhIGFcbiAqIEBwYXJhbSB7bnVtYmVyfSBiIGJcbiAqIEBwYXJhbSB7bnVtYmVyfSBjIGNcbiAqIEBwYXJhbSB7bnVtYmVyfSBkIGRcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSBzIHNcbiAqIEBwYXJhbSB7bnVtYmVyfSB0IHRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlc3VsdFxuICovXG5mdW5jdGlvbiBtZDVoaChhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oYiBeIGMgXiBkLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuLyoqXG4gKiBCYXNpYyBvcGVyYXRpb24gdGhlIGFsZ29yaXRobSB1c2VzLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBhIGFcbiAqIEBwYXJhbSB7bnVtYmVyfSBiIGJcbiAqIEBwYXJhbSB7bnVtYmVyfSBjIGNcbiAqIEBwYXJhbSB7bnVtYmVyfSBkIGRcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSBzIHNcbiAqIEBwYXJhbSB7bnVtYmVyfSB0IHRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlc3VsdFxuICovXG5mdW5jdGlvbiBtZDVpaShhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oYyBeIChiIHwgfmQpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIE1ENSBvZiBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzLCBhbmQgYSBiaXQgbGVuZ3RoLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHggQXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3Jkc1xuICogQHBhcmFtIHtudW1iZXJ9IGxlbiBCaXQgbGVuZ3RoXG4gKiBAcmV0dXJucyB7QXJyYXk8bnVtYmVyPn0gTUQ1IEFycmF5XG4gKi9cbmZ1bmN0aW9uIGJpbmxNRDUoeCwgbGVuKSB7XG4gIC8qIGFwcGVuZCBwYWRkaW5nICovXG4gIHhbbGVuID4+IDVdIHw9IDB4ODAgPDwgbGVuICUgMzI7XG4gIHhbKCgobGVuICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IGxlbjtcblxuICB2YXIgaTtcbiAgdmFyIG9sZGE7XG4gIHZhciBvbGRiO1xuICB2YXIgb2xkYztcbiAgdmFyIG9sZGQ7XG4gIHZhciBhID0gMTczMjU4NDE5MztcbiAgdmFyIGIgPSAtMjcxNzMzODc5O1xuICB2YXIgYyA9IC0xNzMyNTg0MTk0O1xuICB2YXIgZCA9IDI3MTczMzg3ODtcblxuICBmb3IgKGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkgKz0gMTYpIHtcbiAgICBvbGRhID0gYTtcbiAgICBvbGRiID0gYjtcbiAgICBvbGRjID0gYztcbiAgICBvbGRkID0gZDtcblxuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2ldLCA3LCAtNjgwODc2OTM2KTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgMV0sIDEyLCAtMzg5NTY0NTg2KTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgMl0sIDE3LCA2MDYxMDU4MTkpO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyAzXSwgMjIsIC0xMDQ0NTI1MzMwKTtcbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpICsgNF0sIDcsIC0xNzY0MTg4OTcpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyA1XSwgMTIsIDEyMDAwODA0MjYpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyA2XSwgMTcsIC0xNDczMjMxMzQxKTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgN10sIDIyLCAtNDU3MDU5ODMpO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2kgKyA4XSwgNywgMTc3MDAzNTQxNik7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDldLCAxMiwgLTE5NTg0MTQ0MTcpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyAxMF0sIDE3LCAtNDIwNjMpO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyAxMV0sIDIyLCAtMTk5MDQwNDE2Mik7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaSArIDEyXSwgNywgMTgwNDYwMzY4Mik7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDEzXSwgMTIsIC00MDM0MTEwMSk7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgMTVdLCAyMiwgMTIzNjUzNTMyOSk7XG5cbiAgICBhID0gbWQ1Z2coYSwgYiwgYywgZCwgeFtpICsgMV0sIDUsIC0xNjU3OTY1MTApO1xuICAgIGQgPSBtZDVnZyhkLCBhLCBiLCBjLCB4W2kgKyA2XSwgOSwgLTEwNjk1MDE2MzIpO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAxMV0sIDE0LCA2NDM3MTc3MTMpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2ldLCAyMCwgLTM3Mzg5NzMwMik7XG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDVdLCA1LCAtNzAxNTU4NjkxKTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMTBdLCA5LCAzODAxNjA4Myk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDE1XSwgMTQsIC02NjA0NzgzMzUpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2kgKyA0XSwgMjAsIC00MDU1Mzc4NDgpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyA5XSwgNSwgNTY4NDQ2NDM4KTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMTRdLCA5LCAtMTAxOTgwMzY5MCk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDNdLCAxNCwgLTE4NzM2Mzk2MSk7XG4gICAgYiA9IG1kNWdnKGIsIGMsIGQsIGEsIHhbaSArIDhdLCAyMCwgMTE2MzUzMTUwMSk7XG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDEzXSwgNSwgLTE0NDQ2ODE0NjcpO1xuICAgIGQgPSBtZDVnZyhkLCBhLCBiLCBjLCB4W2kgKyAyXSwgOSwgLTUxNDAzNzg0KTtcbiAgICBjID0gbWQ1Z2coYywgZCwgYSwgYiwgeFtpICsgN10sIDE0LCAxNzM1MzI4NDczKTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpICsgMTJdLCAyMCwgLTE5MjY2MDc3MzQpO1xuXG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDVdLCA0LCAtMzc4NTU4KTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgOF0sIDExLCAtMjAyMjU3NDQ2Myk7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDExXSwgMTYsIDE4MzkwMzA1NjIpO1xuICAgIGIgPSBtZDVoaChiLCBjLCBkLCBhLCB4W2kgKyAxNF0sIDIzLCAtMzUzMDk1NTYpO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyAxXSwgNCwgLTE1MzA5OTIwNjApO1xuICAgIGQgPSBtZDVoaChkLCBhLCBiLCBjLCB4W2kgKyA0XSwgMTEsIDEyNzI4OTMzNTMpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyA3XSwgMTYsIC0xNTU0OTc2MzIpO1xuICAgIGIgPSBtZDVoaChiLCBjLCBkLCBhLCB4W2kgKyAxMF0sIDIzLCAtMTA5NDczMDY0MCk7XG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDEzXSwgNCwgNjgxMjc5MTc0KTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpXSwgMTEsIC0zNTg1MzcyMjIpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyAzXSwgMTYsIC03MjI1MjE5NzkpO1xuICAgIGIgPSBtZDVoaChiLCBjLCBkLCBhLCB4W2kgKyA2XSwgMjMsIDc2MDI5MTg5KTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgOV0sIDQsIC02NDAzNjQ0ODcpO1xuICAgIGQgPSBtZDVoaChkLCBhLCBiLCBjLCB4W2kgKyAxMl0sIDExLCAtNDIxODE1ODM1KTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgMTVdLCAxNiwgNTMwNzQyNTIwKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMl0sIDIzLCAtOTk1MzM4NjUxKTtcblxuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2ldLCA2LCAtMTk4NjMwODQ0KTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgN10sIDEwLCAxMTI2ODkxNDE1KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgMTRdLCAxNSwgLTE0MTYzNTQ5MDUpO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyA1XSwgMjEsIC01NzQzNDA1NSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaSArIDEyXSwgNiwgMTcwMDQ4NTU3MSk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDNdLCAxMCwgLTE4OTQ5ODY2MDYpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyAxMF0sIDE1LCAtMTA1MTUyMyk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDFdLCAyMSwgLTIwNTQ5MjI3OTkpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2kgKyA4XSwgNiwgMTg3MzMxMzM1OSk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDE1XSwgMTAsIC0zMDYxMTc0NCk7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDZdLCAxNSwgLTE1NjAxOTgzODApO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyAxM10sIDIxLCAxMzA5MTUxNjQ5KTtcbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpICsgNF0sIDYsIC0xNDU1MjMwNzApO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyAxMV0sIDEwLCAtMTEyMDIxMDM3OSk7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDJdLCAxNSwgNzE4Nzg3MjU5KTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgOV0sIDIxLCAtMzQzNDg1NTUxKTtcblxuICAgIGEgPSBzYWZlQWRkKGEsIG9sZGEpO1xuICAgIGIgPSBzYWZlQWRkKGIsIG9sZGIpO1xuICAgIGMgPSBzYWZlQWRkKGMsIG9sZGMpO1xuICAgIGQgPSBzYWZlQWRkKGQsIG9sZGQpO1xuICB9XG5cbiAgcmV0dXJuIFthLCBiLCBjLCBkXTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMgdG8gYSBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGlucHV0IE1ENSBBcnJheVxuICogQHJldHVybnMge3N0cmluZ30gTUQ1IHN0cmluZ1xuICovXG5mdW5jdGlvbiBiaW5sMnJzdHIoaW5wdXQpIHtcbiAgdmFyIGk7XG4gIHZhciBvdXRwdXQgPSAnJztcbiAgdmFyIGxlbmd0aDMyID0gaW5wdXQubGVuZ3RoICogMzI7XG5cbiAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDMyOyBpICs9IDgpIHtcbiAgICBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoaW5wdXRbaSA+PiA1XSA+Pj4gaSAlIDMyKSAmIDB4ZmYpO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGEgcmF3IHN0cmluZyB0byBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzXG4gKiBDaGFyYWN0ZXJzID4yNTUgaGF2ZSB0aGVpciBoaWdoLWJ5dGUgc2lsZW50bHkgaWdub3JlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgUmF3IGlucHV0IHN0cmluZ1xuICogQHJldHVybnMge0FycmF5PG51bWJlcj59IEFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHNcbiAqL1xuZnVuY3Rpb24gcnN0cjJiaW5sKGlucHV0KSB7XG4gIHZhciBpO1xuICB2YXIgb3V0cHV0ID0gW107XG4gIG91dHB1dFsoaW5wdXQubGVuZ3RoID4+IDIpIC0gMV0gPSB1bmRlZmluZWQ7XG5cbiAgZm9yIChpID0gMDsgaSA8IG91dHB1dC5sZW5ndGg7IGkgKz0gMSkge1xuICAgIG91dHB1dFtpXSA9IDA7XG4gIH1cblxuICB2YXIgbGVuZ3RoOCA9IGlucHV0Lmxlbmd0aCAqIDg7XG5cbiAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDg7IGkgKz0gOCkge1xuICAgIG91dHB1dFtpID4+IDVdIHw9IChpbnB1dC5jaGFyQ29kZUF0KGkgLyA4KSAmIDB4ZmYpIDw8IGkgJSAzMjtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSBNRDUgb2YgYSByYXcgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHMgSW5wdXQgc3RyaW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSYXcgTUQ1IHN0cmluZ1xuICovXG5mdW5jdGlvbiByc3RyTUQ1KHMpIHtcbiAgcmV0dXJuIGJpbmwycnN0cihiaW5sTUQ1KHJzdHIyYmlubChzKSwgcy5sZW5ndGggKiA4KSk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgSE1BQy1NRDUgb2YgYSBrZXkgYW5kIHNvbWUgZGF0YSAocmF3IHN0cmluZ3MpXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBITUFDIGtleVxuICogQHBhcmFtIHtzdHJpbmd9IGRhdGEgUmF3IGlucHV0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ30gUmF3IE1ENSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gcnN0ckhNQUNNRDUoa2V5LCBkYXRhKSB7XG4gIHZhciBpO1xuICB2YXIgYmtleSA9IHJzdHIyYmlubChrZXkpO1xuICB2YXIgaXBhZCA9IFtdO1xuICB2YXIgb3BhZCA9IFtdO1xuICB2YXIgaGFzaDtcbiAgaXBhZFsxNV0gPSBvcGFkWzE1XSA9IHVuZGVmaW5lZDtcblxuICBpZiAoYmtleS5sZW5ndGggPiAxNikge1xuICAgIGJrZXkgPSBiaW5sTUQ1KGJrZXksIGtleS5sZW5ndGggKiA4KTtcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCAxNjsgaSArPSAxKSB7XG4gICAgaXBhZFtpXSA9IGJrZXlbaV0gXiAweDM2MzYzNjM2O1xuICAgIG9wYWRbaV0gPSBia2V5W2ldIF4gMHg1YzVjNWM1YztcbiAgfVxuXG4gIGhhc2ggPSBiaW5sTUQ1KGlwYWQuY29uY2F0KHJzdHIyYmlubChkYXRhKSksIDUxMiArIGRhdGEubGVuZ3RoICogOCk7XG5cbiAgcmV0dXJuIGJpbmwycnN0cihiaW5sTUQ1KG9wYWQuY29uY2F0KGhhc2gpLCA1MTIgKyAxMjgpKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGEgcmF3IHN0cmluZyB0byBhIGhleCBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgUmF3IGlucHV0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ30gSGV4IGVuY29kZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHJzdHIyaGV4KGlucHV0KSB7XG4gIHZhciBoZXhUYWIgPSAnMDEyMzQ1Njc4OWFiY2RlZic7XG4gIHZhciBvdXRwdXQgPSAnJztcbiAgdmFyIHg7XG4gIHZhciBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGg7IGkgKz0gMSkge1xuICAgIHggPSBpbnB1dC5jaGFyQ29kZUF0KGkpO1xuICAgIG91dHB1dCArPSBoZXhUYWIuY2hhckF0KCh4ID4+PiA0KSAmIDB4MGYpICsgaGV4VGFiLmNoYXJBdCh4ICYgMHgwZik7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG4vKipcbiAqIEVuY29kZSBhIHN0cmluZyBhcyBVVEYtOFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCBJbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFVURjggc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHN0cjJyc3RyVVRGOChpbnB1dCkge1xuICByZXR1cm4gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGlucHV0KSk7XG59XG5cbi8qKlxuICogRW5jb2RlcyBpbnB1dCBzdHJpbmcgYXMgcmF3IE1ENSBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcyBJbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJhdyBNRDUgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHJhd01ENShzKSB7XG4gIHJldHVybiByc3RyTUQ1KHN0cjJyc3RyVVRGOChzKSk7XG59XG5cbi8qKlxuICogRW5jb2RlcyBpbnB1dCBzdHJpbmcgYXMgSGV4IGVuY29kZWQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHMgSW5wdXQgc3RyaW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBIZXggZW5jb2RlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gaGV4TUQ1KHMpIHtcbiAgcmV0dXJuIHJzdHIyaGV4KHJhd01ENShzKSk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgcmF3IEhNQUMtTUQ1IGZvciB0aGUgZ2l2ZW4ga2V5IGFuZCBkYXRhXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGsgSE1BQyBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSBkIElucHV0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ30gUmF3IE1ENSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gcmF3SE1BQ01ENShrLCBkKSB7XG4gIHJldHVybiByc3RySE1BQ01ENShzdHIycnN0clVURjgoayksIHN0cjJyc3RyVVRGOChkKSk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgSGV4IGVuY29kZWQgSE1BQy1NRDUgZm9yIHRoZSBnaXZlbiBrZXkgYW5kIGRhdGFcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gayBITUFDIGtleVxuICogQHBhcmFtIHtzdHJpbmd9IGQgSW5wdXQgc3RyaW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSYXcgTUQ1IHN0cmluZ1xuICovXG5mdW5jdGlvbiBoZXhITUFDTUQ1KGssIGQpIHtcbiAgcmV0dXJuIHJzdHIyaGV4KHJhd0hNQUNNRDUoaywgZCkpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgTUQ1IHZhbHVlIGZvciBhIGdpdmVuIHN0cmluZy5cbiAqIElmIGEga2V5IGlzIHByb3ZpZGVkLCBjYWxjdWxhdGVzIHRoZSBITUFDLU1ENSB2YWx1ZS5cbiAqIFJldHVybnMgYSBIZXggZW5jb2RlZCBzdHJpbmcgdW5sZXNzIHRoZSByYXcgYXJndW1lbnQgaXMgZ2l2ZW4uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBJbnB1dCBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBba2V5XSBITUFDIGtleVxuICogQHBhcmFtIHtib29sZWFufSBbcmF3XSBSYXcgb3V0cHV0IHN3aXRjaFxuICogQHJldHVybnMge3N0cmluZ30gTUQ1IG91dHB1dFxuICovXG5leHBvcnQgZnVuY3Rpb24gbWQ1KHN0cmluZywga2V5LCByYXcpIHtcbiAgaWYgKCFrZXkpIHtcbiAgICBpZiAoIXJhdykge1xuICAgICAgcmV0dXJuIGhleE1ENShzdHJpbmcpO1xuICAgIH1cblxuICAgIHJldHVybiByYXdNRDUoc3RyaW5nKTtcbiAgfVxuXG4gIGlmICghcmF3KSB7XG4gICAgcmV0dXJuIGhleEhNQUNNRDUoa2V5LCBzdHJpbmcpO1xuICB9XG5cbiAgcmV0dXJuIHJhd0hNQUNNRDUoa2V5LCBzdHJpbmcpO1xufVxuIiwiaW1wb3J0IHsgbWQ1IH0gZnJvbSAnLi9tZDUuanMnO1xuXG4vKipcbiAqIFRoZSBpbnRlbnQgb2YgdGhpcyBmdW5jdGlvbiBpcyB0byBnZW5lcmF0ZSB0aGUgc3VmZml4L3Bvc3RmaXggZm9yIHRoZVxuICogY3NzIGNsYXNzZXMsIGJhc2VkIG9uIHRoZSBtb2R1bGUtc2NvcGVkIHBhdGggbmFtZS5cbiAqXG4gKiBmb3IgZXhhbXBsZSxcbiAqICAgIGhhc2goJ215LWFwcC9jb21wb25lbnRzL2ZvbycpXG4gKiAgaW5zdGVhZCBvZlxuICogICAgaGFzaCgnYXBwL2NvbXBvbmVudHMvZm9vJylcbiAqXG4gKiAgKHVubGVzcyB5b3VyIGFwcCBuYW1lIGlzICdhcHAnKVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtb2R1bGVQYXRoXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzaChtb2R1bGVQYXRoKSB7XG4gIHJldHVybiAnZScgKyBtZDUobW9kdWxlUGF0aCkuc3Vic3RyaW5nKDAsIDgpO1xufVxuXG5pZiAoaW1wb3J0Lm1ldGEudml0ZXN0KSB7XG4gIGNvbnN0IHsgaXQsIGV4cGVjdCB9ID0gaW1wb3J0Lm1ldGEudml0ZXN0O1xuXG4gIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHBvc3RmaXggPSBoYXNoKCdmb28uY3NzJyk7XG5cbiAgICBleHBlY3QocG9zdGZpeCkudG8uYmUuYSgnc3RyaW5nJyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RyaW5nIHN0YXJ0aW5nIHdpdGggXCJlXCInLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcG9zdGZpeCA9IGhhc2goJ2Zvby5jc3MnKTtcblxuICAgIGV4cGVjdChwb3N0Zml4KS50by5tYXRjaCgvXmUvKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXR1cm4gYSBzdHJpbmcgb2YgbGVuZ3RoIDknLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcG9zdGZpeCA9IGhhc2goJ2Zvby5jc3MnKTtcblxuICAgIGV4cGVjdChwb3N0Zml4KS50by5oYXZlLmxlbmd0aE9mKDkpO1xuICB9KTtcbn1cblxuZXhwb3J0IGNvbnN0IGhhc2hGcm9tTW9kdWxlUGF0aCA9IGhhc2g7XG4iLCJpbXBvcnQgYXNzZXJ0IGZyb20gJ25vZGU6YXNzZXJ0JztcbmltcG9ydCBmc1N5bmMsIHsgZXhpc3RzU3luYyB9IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHsgY3JlYXRlUmVxdWlyZSB9IGZyb20gJ25vZGU6bW9kdWxlJztcbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB7IGJhcmVQYXRoLCBsZWFkaW5nU2xhc2hQYXRoIH0gZnJvbSAnLi9jb25zdC5qcyc7XG5pbXBvcnQgeyBoYXNoRnJvbUFic29sdXRlUGF0aCB9IGZyb20gJy4vaGFzaC1mcm9tLWFic29sdXRlLXBhdGguanMnO1xuaW1wb3J0IHsgaGFzaEZyb21Nb2R1bGVQYXRoIGFzIGhhc2hQb3NpeE1vZHVsZVBhdGggfSBmcm9tICcuL2hhc2gtZnJvbS1tb2R1bGUtcGF0aC5qcyc7XG5cbmV4cG9ydCB7IGhhc2hGcm9tQWJzb2x1dGVQYXRoIH0gZnJvbSAnLi9oYXNoLWZyb20tYWJzb2x1dGUtcGF0aC5qcyc7XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aFxuICogQHJldHVybnMge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc2hGcm9tTW9kdWxlUGF0aChmaWxlUGF0aCkge1xuICBsZXQgcG9zaXhQYXRoID0gZm9yY2VQb3NpeChmaWxlUGF0aCk7XG5cbiAgcmV0dXJuIGhhc2hQb3NpeE1vZHVsZVBhdGgocG9zaXhQYXRoKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcmNlUG9zaXgoZmlsZVBhdGgpIHtcbiAgY29uc3QgcGFyc2VkID0gcGF0aC5wYXJzZShmaWxlUGF0aCk7XG5cbiAgaWYgKHBhcnNlZC5yb290ID09PSAnJykge1xuICAgIHJldHVybiBmaWxlUGF0aC5yZXBsYWNlQWxsKHBhdGgud2luMzIuc2VwLCBwYXRoLnBvc2l4LnNlcCk7XG4gIH1cblxuICBsZXQgcm9vdGxlc3MgPSBmaWxlUGF0aC5yZXBsYWNlKFxuICAgIG5ldyBSZWdFeHAoYF4ke1JlZ0V4cC5lc2NhcGUocGFyc2VkLnJvb3QpfWApLFxuICAgIHBhdGgucG9zaXguc2VwLFxuICApO1xuXG4gIHJldHVybiByb290bGVzcy5yZXBsYWNlQWxsKHBhdGgud2luMzIuc2VwLCBwYXRoLnBvc2l4LnNlcCk7XG59XG5cbmNvbnN0IENPTVBPTkVOVF9FWFRFTlNJT05TID0gWycuZ3RzJywgJy5nanMnLCAnLnRzJywgJy5qcycsICcuaGJzJ107XG5cbi8vIENKUyAvIEVTTT9cbmxldCBoZXJlID0gaW1wb3J0Lm1ldGEudXJsO1xubGV0IG91clJlcXVpcmUgPSBnbG9iYWxUaGlzLnJlcXVpcmVcbiAgPyBnbG9iYWxUaGlzLnJlcXVpcmVcbiAgOiBoZXJlICYmIGNyZWF0ZVJlcXVpcmUoaGVyZSk7XG5cbmlmICghb3VyUmVxdWlyZSkge1xuICBvdXJSZXF1aXJlID0gcmVxdWlyZTtcbn1cblxuY29uc3QgSVJSRUxFVkFOVF9QQVRIUyA9IFtiYXJlUGF0aC5wbnBtRGlyLCAnX192aXRlLSddO1xuY29uc3QgVU5TVVBQT1JURURfRElSRUNUT1JJRVMgPSBuZXcgU2V0KFsndGVzdHMnXSk7XG5cbmNvbnN0IENXRCA9IHByb2Nlc3MuY3dkKCk7XG5cbi8qKlxuICogUmVnYXJkbGVzcyBvZiB3aGF0IHRoZSBmaWxlUGF0aCBmb3JtYXQgaXMsXG4gKiB0aGlzIHdpbGwgdHJ5IHRvIHJldHVybiB0aGUgY29ycmVjdCBwb3N0Zml4LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aFxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc2hGcm9tKGZpbGVQYXRoKSB7XG4gIGlmIChwYXRoLmlzQWJzb2x1dGUoZmlsZVBhdGgpKSB7XG4gICAgcmV0dXJuIGhhc2hGcm9tQWJzb2x1dGVQYXRoKGZpbGVQYXRoKTtcbiAgfVxuXG4gIHJldHVybiBoYXNoRnJvbU1vZHVsZVBhdGgoZmlsZVBhdGgpO1xufVxuXG4vKipcbiAqXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjc3NIYXNBc3NvY2lhdGVkQ29tcG9uZW50KGNzc1BhdGgpIHtcbiAgcmV0dXJuIGNzc0hhc1N0YW5kYXJkRmlsZShjc3NQYXRoKSB8fCBjc3NIYXNQb2RzRmlsZShjc3NQYXRoKTtcbn1cblxuZnVuY3Rpb24gY3NzSGFzU3RhbmRhcmRGaWxlKGlkKSB7XG4gIC8qKlxuICAgKiBOb3JtYWxseSB3ZSBkb24ndCBuZWVkIHRvIGNoZWNrIGEgSlMgcGF0aCBoZXJlLCBidXQgd2hlbiB1c2luZ1xuICAgKiBlbWJyb2lkZXJAMywgd2UgaGF2ZSBhIFwicmV3cml0dGVuIGFwcFwiLCB3aGljaCBoYXMgYWxsIG91ciBzb3VyY2VcbiAgICogcHJlcHJvY2Vzc2VkIGEgYml0IGJlZm9yZSBzY29wZWQtY3NzIHRyYW5zZm9ybWF0aW9ucy5cbiAgICpcbiAgICogKEluIFZpdGUsIHdlIG9wZXJhdGUgbW9yZSBkaXJlY3RseSB3aXRoIHRoZSBzb3VyY2UpXG4gICAqL1xuICBmb3IgKGxldCBleHQgb2YgQ09NUE9ORU5UX0VYVEVOU0lPTlMpIHtcbiAgICBsZXQgY2FuZGlkYXRlUGF0aCA9IGlkLnJlcGxhY2UoL1xcLmNzcyQvLCBleHQpO1xuXG4gICAgaWYgKGV4aXN0c1N5bmMoY2FuZGlkYXRlUGF0aCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY3NzSGFzUG9kc0ZpbGUoaWQpIHtcbiAgaWYgKCFpZC5lbmRzV2l0aCgnc3R5bGVzLmNzcycpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLyoqXG4gICAqIE5vcm1hbGx5IHdlIGRvbid0IG5lZWQgdG8gY2hlY2sgYSBKUyBwYXRoIGhlcmUsIGJ1dCB3aGVuIHVzaW5nXG4gICAqIGVtYnJvaWRlckAzLCB3ZSBoYXZlIGEgXCJyZXdyaXR0ZW4gYXBwXCIsIHdoaWNoIGhhcyBhbGwgb3VyIHNvdXJjZVxuICAgKiBwcmVwcm9jZXNzZWQgYSBiaXQgYmVmb3JlIHNjb3BlZC1jc3MgdHJhbnNmb3JtYXRpb25zLlxuICAgKlxuICAgKiAoSW4gVml0ZSwgd2Ugb3BlcmF0ZSBtb3JlIGRpcmVjdGx5IHdpdGggdGhlIHNvdXJjZSlcbiAgICovXG4gIGZvciAobGV0IGV4dCBvZiBDT01QT05FTlRfRVhURU5TSU9OUykge1xuICAgIGxldCBjYW5kaWRhdGVQYXRoID0gaWQucmVwbGFjZSgvc3R5bGVzXFwuY3NzJC8sIGB0ZW1wbGF0ZSR7ZXh0fWApO1xuXG4gICAgaWYgKGV4aXN0c1N5bmMoY2FuZGlkYXRlUGF0aCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBCYXNlZCBvbiBlbWJlcidzIGNvbXBvbmVudCBsb2NhdGlvbiBjb252ZW50aW9ucyxcbiAqIHRoaXMgZnVuY3Rpb24gd2lsbCBwcm92aWRlIGEgcGF0aCBmb3Igd2hlcmUgd2VcbiAqIGV4cGVjdCB0aGUgQ1NTIHRvIGxpdmUuXG4gKlxuICogRm9yIGNvLWxvY2F0ZWQgc3RydWN0dXJlOlxuICogICAtIGNvbXBvbmVudHMvbXktY29tcG9uZW50Lmhic1xuICogICAtIGNvbXBvbmVudHMvbXktY29tcG9uZW50LmNzc1xuICpcbiAqIEZvciBuZXN0ZWQgY28tbG9jYXRlZCBzdHJ1Y3R1cmVcbiAqICAgLSBjb21wb25lbnRzL215LWNvbXBvbmVudC9mb28uaGJzXG4gKiAgIC0gY29tcG9uZW50cy9teS1jb21wb25lbnQvZm9vLmNzc1xuICpcbiAqIEZvciBQb2RzIHJvdXRlcyBzdHJ1Y3R1cmVcbiAqICAgLSByb3V0ZXMvbXktcm91dGUvdGVtcGxhdGUue2hicyxqc31cbiAqICAgLSByb3V0ZXMvbXktcm91dGUvc3R5bGVzLmNzc1xuICpcbiAqIERlbGliZXJhdGVseSBub3Qgc3VwcG9ydGVkOlxuICogICAtIGNvbXBvbmVudHMgdy8gcG9kcyAtLSB0aGlzIGlzIGRlcHJlY2F0ZWQgaW4gNS4xMFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlTmFtZSAtIHRoZSBoYnMsIGpzLCBnanMsIGd0cyBvciB3aGF0ZXZlciBjby1sb2NhdGVkIHBhdGguXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIGV4cGVjdGVkIGNzcyBwYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjc3NQYXRoRm9yKGZpbGVOYW1lKSB7XG4gIGxldCB3aXRob3V0RXh0ID0gd2l0aG91dEV4dGVuc2lvbihmaWxlTmFtZSk7XG4gIGxldCBjc3NQYXRoID0gd2l0aG91dEV4dCArICcuY3NzJztcblxuICBpZiAoaXNQb2QoZmlsZU5hbWUpKSB7XG4gICAgY3NzUGF0aCA9IGZpbGVOYW1lXG4gICAgICAucmVwbGFjZSgvdGVtcGxhdGVcXC5qcyQvLCAnc3R5bGVzLmNzcycpXG4gICAgICAucmVwbGFjZSgvdGVtcGxhdGVcXC5nanMvLCAnc3R5bGVzLmNzcycpXG4gICAgICAucmVwbGFjZSgvdGVtcGxhdGVcXC5ndHMvLCAnc3R5bGVzLmNzcycpXG4gICAgICAucmVwbGFjZSgvdGVtcGxhdGVcXC5oYnMvLCAnc3R5bGVzLmNzcycpO1xuICB9XG5cbiAgcmV0dXJuIGNzc1BhdGg7XG59XG5cbi8qKlxuICogTm90ZSB0aGF0IGNvbXBvbmVudHMgaW4gdGhlIFwicG9kc1wiIGNvbnZlbnRpb24gd2lsbFxuICogbmV2ZXIgYmUgc3VwcG9ydGVkLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQb2RUZW1wbGF0ZShmaWxlUGF0aCkge1xuICBpZiAoZmlsZVBhdGguaW5jbHVkZXMobGVhZGluZ1NsYXNoUGF0aC5jb21wb25lbnRzRGlyKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgZmlsZVBhdGguZW5kc1dpdGgoJ3RlbXBsYXRlLmpzJykgfHxcbiAgICBmaWxlUGF0aC5lbmRzV2l0aCgndGVtcGxhdGUuaGJzJykgfHxcbiAgICBmaWxlUGF0aC5lbmRzV2l0aCgndGVtcGxhdGUuZ2pzJykgfHxcbiAgICBmaWxlUGF0aC5lbmRzV2l0aCgndGVtcGxhdGUuZ3RzJylcbiAgKTtcbn1cblxuLyoqXG4gKiBOb3RlIHRoYXQgY29tcG9uZW50cyBpbiB0aGUgXCJwb2RzXCIgY29udmVudGlvbiB3aWxsXG4gKiBuZXZlciBiZSBzdXBwb3J0ZWQuXG4gKlxuICogQ2hlY2tzIGlmIGEgZmlsZSBlbmRzIHdpdGhcbiAqIC0gdGVtcGxhdGUuanNcbiAqIC0gdGVtcGxhdGUuaGJzXG4gKiAtIHN0eWxlcy5jc3NcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUG9kKGZpbGVQYXRoKSB7XG4gIGlmIChmaWxlUGF0aC5pbmNsdWRlcyhsZWFkaW5nU2xhc2hQYXRoLmNvbXBvbmVudHNEaXIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGlzUG9kVGVtcGxhdGUoZmlsZVBhdGgpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmlsZVBhdGguZW5kc1dpdGgoJ3N0eWxlcy5jc3MnKTtcbn1cblxuLyoqXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoXG4gKiBAcmV0dXJucyB0aGUgc2FtZSBwYXRoLCBidXQgd2l0aG91dCB0aGUgZXh0ZW5zaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRob3V0RXh0ZW5zaW9uKGZpbGVQYXRoKSB7XG4gIGxldCBwYXJzZWQgPSBwYXRoLnBhcnNlKGZpbGVQYXRoKTtcblxuICByZXR1cm4gcGF0aC5qb2luKHBhcnNlZC5kaXIsIHBhcnNlZC5uYW1lKTtcbn1cblxuLyoqXG4gKiBFeGFtcGxlcyBmb3IgZmlsZU5hbWVcbiAqIC0gYWJzb2x1dGUgb24tZGlzayBwYXRoXG4gKiAtIGluIHdlYnBhY2tcbiAqICAgLSBVUkwtYWJzb2x1dGUgcGF0aCwgc3RhcnRpbmcgd2l0aCAvXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVOYW1lXG4gKiBAcGFyYW0ge3sgYWRkaXRpb25hbFJvb3RzPzogc3RyaW5nW107IGN3ZDogc3RyaW5nIH19IG9wdGlvbnNcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1JlbGV2YW50RmlsZShmaWxlTmFtZSwgeyBhZGRpdGlvbmFsUm9vdHMsIGN3ZCB9KSB7XG4gIC8vIEZha2UgZmlsZSBoYW5kbGVkIGJ5IHRlc3RlbSBzZXJ2ZXIgd2hlbiBpdCBydW5zXG4gIGlmIChmaWxlTmFtZS5zdGFydHNXaXRoKGxlYWRpbmdTbGFzaFBhdGgudGVzdGVtKSkgcmV0dXJuIGZhbHNlO1xuICAvLyBQcml2YXRlIFZpcnR1YWwgTW9kdWxlc1xuICBpZiAoZmlsZU5hbWUuc3RhcnRzV2l0aCgnXFwwJykpIHJldHVybiBmYWxzZTtcblxuICAvLyBUaGVzZSBhcmUgbm90IHZhbGlkIHVzZXJsYW5kIG5hbWVzIChvciBhcmUgZnJvbSBsaWJyYXJpZXMpXG4gIGlmIChwYXRoLmlzQWJzb2x1dGUoZmlsZU5hbWUpID09PSBmYWxzZSkge1xuICAgIGlmIChmaWxlTmFtZS5tYXRjaCgvXlthLXpBLVpdLykpIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIEV4dGVybmFsIHRvIHVzXG4gIGlmIChmaWxlTmFtZS5zdGFydHNXaXRoKGxlYWRpbmdTbGFzaFBhdGguYXRFbWJyb2lkZXIpKSByZXR1cm4gZmFsc2U7XG4gIGlmIChJUlJFTEVWQU5UX1BBVEhTLnNvbWUoKGkpID0+IGZpbGVOYW1lLmluY2x1ZGVzKGkpKSkgcmV0dXJuIGZhbHNlO1xuXG4gIGFzc2VydChjd2QsIGBjd2Qgd2FzIG5vdCBwYXNzZWQgdG8gaXNSZWxldmFudEZpbGVgKTtcblxuICBsZXQgaXNJbkFkZGl0aW9uYWxSb290ID0gYWRkaXRpb25hbFJvb3RzPy5zb21lKChyb290KSA9PiB7XG4gICAgbGV0IHJlbGF0aXZlID0gcGF0aC5yZWxhdGl2ZShwYXRoLnJlc29sdmUoY3dkLCByb290KSwgZmlsZU5hbWUpO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIHJlbGF0aXZlICE9PSAnLi4nICYmXG4gICAgICAhcmVsYXRpdmUuc3RhcnRzV2l0aChgLi4ke3BhdGguc2VwfWApICYmXG4gICAgICAhcGF0aC5pc0Fic29sdXRlKHJlbGF0aXZlKVxuICAgICk7XG4gIH0pO1xuXG4gIGxldCB3b3Jrc3BhY2UgPSBmaW5kV29ya3NwYWNlUGF0aChmaWxlTmFtZSk7XG5cbiAgbGV0IG91cldvcmtzcGFjZSA9IGZpbmRXb3Jrc3BhY2VQYXRoKGN3ZCk7XG5cbiAgaWYgKHdvcmtzcGFjZSAhPT0gb3VyV29ya3NwYWNlICYmICFpc0luQWRkaXRpb25hbFJvb3QpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBsZXQgaXNJbldvcmtzcGFjZUFkZGl0aW9uYWxSb290ID1cbiAgICB3b3Jrc3BhY2UgPT09IG91cldvcmtzcGFjZSAmJlxuICAgIGFkZGl0aW9uYWxSb290cz8uc29tZSgocm9vdCkgPT4ge1xuICAgICAgaWYgKHBhdGguaXNBYnNvbHV0ZShyb290KSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICBsZXQgbm9ybWFsaXplZEZpbGVOYW1lID0gYCR7cGF0aC5zZXB9JHtwYXRoLm5vcm1hbGl6ZShmaWxlTmFtZSl9JHtwYXRoLnNlcH1gO1xuICAgICAgbGV0IG5vcm1hbGl6ZWRSb290ID0gYCR7cGF0aC5zZXB9JHtwYXRoLm5vcm1hbGl6ZShyb290KX0ke3BhdGguc2VwfWA7XG5cbiAgICAgIHJldHVybiBub3JtYWxpemVkRmlsZU5hbWUuaW5jbHVkZXMobm9ybWFsaXplZFJvb3QpO1xuICAgIH0pO1xuXG4gIGxldCBsb2NhbCA9IGZpbGVOYW1lLnJlcGxhY2Uod29ya3NwYWNlLCAnJyk7XG4gIGxldCBbLCAuLi5wYXJ0c10gPSBsb2NhbC5zcGxpdChwYXRoLnNlcCkuZmlsdGVyKEJvb2xlYW4pO1xuXG4gIGlmIChVTlNVUFBPUlRFRF9ESVJFQ1RPUklFUy5oYXMocGFydHNbMF0pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vc3RseSBwb2RzIHN1cHBvcnQuXG4gICAqIGZvbGtzIG5lZWQgdG8gb3B0IGluIHRvIHBvZHMgKHJvdXRlcyksIGJlY2F1c2UgZXZlcnkgcG9kcyBhcHAgY2FuIGJlIGNvbmZpZ3VyZWQgZGlmZmVyZW50bHlcbiAgICovXG4gIGxldCByb290cyA9IFtcbiAgICBsZWFkaW5nU2xhc2hQYXRoLmNvbXBvbmVudHNEaXIsXG4gICAgbGVhZGluZ1NsYXNoUGF0aC50ZW1wbGF0ZXNEaXIsXG4gICAgbGVhZGluZ1NsYXNoUGF0aC5yb3V0ZXNEaXIsXG4gIF07XG5cbiAgaWYgKFxuICAgICFpc0luQWRkaXRpb25hbFJvb3QgJiZcbiAgICAhaXNJbldvcmtzcGFjZUFkZGl0aW9uYWxSb290ICYmXG4gICAgIXJvb3RzLnNvbWUoKHJvb3QpID0+IGZpbGVOYW1lLmluY2x1ZGVzKHJvb3QpKVxuICApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhY2thZ2VTY29wZWRQYXRoVG9Nb2R1bGVQYXRoKHBhY2thZ2VTY29wZWRQYXRoKSB7XG4gIC8qKlxuICAgKiAqQnkgY29udmVudGlvbiosIGBzcmNgIGlzIG9taXR0ZWQgZnJvbSBjb21wb25lbnQgcGF0aHMuXG4gICAqIFdlIGNhbiByZWZsZWN0IHRoZSBzYW1lIGJlaGF2aW9yIGJ5IHJlcGxhY2luZyBzcmMvXG4gICAqIHdpdGggYW4gZW1wdHkgc3RyaW5nLlxuICAgKlxuICAgKiBDU1MgaXNuJ3QgZW1pdHRlZCBhcyBhIGNvLWxvY2F0ZWQgbW9kdWxlLCBidXRcbiAgICogdG8ga2VlcCBjb252ZW50aW9ucyBjb25zaXN0ZW50IGFjcm9zcyBsYW5ndWFnZXMsXG4gICAqIHdlIGNhbiBwcmV0ZW5kIGl0IGlzLlxuICAgKlxuICAgKiBBbnkgY3VzdG9taXphdGlvbiBiZXlvbmQgcmVtb3ZpbmcgYHNyY2AgYW5kIGBhcHBgIGlzIHBvdGVudGlhbGx5IGNvbmZ1c2luZy5cbiAgICogSWYgd2UgbmVlZCBmdXJ0aGVyIGN1c3RvbWl6YXRpb25zLCB3ZSdsbCB3YW50IHRvIG1hdGNoIG9uIGBleHBvcnRzYCBpbiB0aGVcbiAgICogY29ycmVzcG9uZGluZyBwYWNrYWdlLmpzb25cbiAgICovXG4gIGxldCBwYWNrYWdlUmVsYXRpdmUgPSBwYWNrYWdlU2NvcGVkUGF0aC5yZXBsYWNlKFxuICAgIG5ldyBSZWdFeHAoYF4ke1JlZ0V4cC5lc2NhcGUobGVhZGluZ1NsYXNoUGF0aC5zcmMpfWApLFxuICAgIHBhdGguc2VwLFxuICApO1xuXG4gIGxldCBwYXJzZWQgPSBwYXRoLnBhcnNlKHBhY2thZ2VSZWxhdGl2ZSk7XG5cbiAgaWYgKGlzUG9kKHBhY2thZ2VSZWxhdGl2ZSkpIHtcbiAgICAvKipcbiAgICAgKiBGb3IgcG9kcywgd2UgY2hvcCBvZmYgdGhlIHdob2xlIGZpbGUsIGFuZCB1c2UgdGhlIGRpciBuYW1lIGFzIHRoZSBcIm1vZHVsZVBhdGhcIlxuICAgICAqL1xuICAgIHJldHVybiBwYXJzZWQuZGlyO1xuICB9XG5cbiAgLyoqXG4gICAqIElmIGFuIGV4dGVuc2lvbiBpcyBwYXNzZWQsIHJlbW92ZSBpdC5cbiAgICogV2hlbiB1c2luZyBwYWNrYWdlcnMsIGZvbGtzIGFyZSB1c2VkIHRvIG5vdCBoYXZpbmcgdG8gc3BlY2lmeSBleHRlbnNpb25zIGZvciBmaWxlcy5cbiAgICogU2luY2Ugd2UgZG9uJ3QgZXZlbiBlbWl0IGNzcyBmaWxlcyBjby1sb2NhdGVkIHRvIGVhY2ggbW9kdWxlLFxuICAgKiB0aGlzIGhlbHBzIHVzIG5vdCBjb252ZXkgYSBsaWUgdGhhdCBhIGZpbGUgbWF5IGV4aXN0IGluIGF0IHJ1bnRpbWUuXG4gICAqXG4gICAqIEZvciBleGFtcGxlIGA8bW9kdWxlLW5hbWU+L2NvbXBvbmVudHMvYnV0dG9uYC5cbiAgICogSXQgZG9lc24ndCBtYXR0ZXIgd2hhdCB0aGUgZXh0ZW5zaW9uIGlzLCBiZWNhdXNlIHlvdSBjYW4gb25seSBoYXZlIG9uZSBjc3MgZmlsZVxuICAgKiBmb3IgdGhlIGJ1dHRvbiBtb2R1bGUgYW55d2F5LlxuICAgKi9cbiAgbGV0IGxvY2FsUGFja2FnZXJTdHlsZVBhdGggPSBwYXRoLmpvaW4ocGFyc2VkLmRpciwgcGFyc2VkLm5hbWUpO1xuXG4gIHJldHVybiBsb2NhbFBhY2thZ2VyU3R5bGVQYXRoO1xufVxuXG4vKipcbiAqIHJldHVybnMgdGhlIGFwcC1tb2R1bGUgcGF0aCBvZiB0aGUgc291cmNlIGZpbGVcbiAqXG4gKiBUaGlzIGFzc3VtZXMgbm9ybWFsIGVtYmVyIGFwcCBjb252ZW50aW9uc1xuICpcbiAqIHdoaWNoIGlzIGA8cGFja2FnZS5qc29uI25hbWU+L3BhdGgtdG8tZmlsZWBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcFBhdGgoc291cmNlUGF0aCkge1xuICBsZXQgd29ya3NwYWNlUGF0aCA9IGZpbmRXb3Jrc3BhY2VQYXRoKHNvdXJjZVBhdGgpO1xuICBsZXQgbmFtZSA9IG1vZHVsZU5hbWUoc291cmNlUGF0aCk7XG5cbiAgLyoqXG4gICAqICBVbmRlciBlbWJyb2lkZXIgYnVpbGRzLCB0aGUgc3BlYy1jb21wbGlhbnQgdmVyc2lvbiBvZiB0aGUgYXBwXG4gICAqIGhhcyBhbGwgdGhlIGZpbGVzIHVuZGVyIGEgZm9sZGVyIHdoaWNoIHJlcHJlc2VudHMgdGhlIHBhY2thZ2UgbmFtZSxcbiAgICogcmF0aGVyIHRoYW4gXCJhcHBcIi5cbiAgICovXG4gIGxldCBwYWNrYWdlUmVsYXRpdmUgPSBzb3VyY2VQYXRoLnJlcGxhY2Uod29ya3NwYWNlUGF0aCwgJycpO1xuXG4gIC8qKlxuICAgKiBCdXQgd2UgYWxzbyBkb24ndCB3YW50ICdhcHAnIC0tIHdoaWNoIGlzIHByZXNlbnQgaW4gdGhlIHYxIGFkZG9uIHBpcGVsaW5lXG4gICAqL1xuICBwYWNrYWdlUmVsYXRpdmUgPSBwYWNrYWdlUmVsYXRpdmUucmVwbGFjZShsZWFkaW5nU2xhc2hQYXRoLmFwcCwgcGF0aC5zZXApO1xuXG4gIC8vIEFueSBvZiB0aGUgYWJvdmUgcmVscGFjZW1lbnRzIGNvdWxkIGFjY2lkZW50YWxseSBnaXZlIHVzIGFuIGV4dHJhIC8gKGRlcGVuZGluZyBvbiBvdXIgYnVpbGQgZW52aXJvbm1lbnQpXG4gIHBhY2thZ2VSZWxhdGl2ZSA9IHBhdGgubm9ybWFsaXplKHBhY2thZ2VSZWxhdGl2ZSk7XG5cbiAgbGV0IGxvY2FsUGFja2FnZXJTdHlsZVBhdGggPSBwYWNrYWdlU2NvcGVkUGF0aFRvTW9kdWxlUGF0aChwYWNrYWdlUmVsYXRpdmUpO1xuXG4gIHJldHVybiBgJHtuYW1lfSR7bG9jYWxQYWNrYWdlclN0eWxlUGF0aH1gO1xufVxuXG4vKipcbiAqIFRvIGF2b2lkIGhpdHRpbmcgdGhlIGZpbGVzeXNldG0sIHdlJ2xsIHN0b3JlIGFsbCBmb3VuZFxuICogcHJvamVjdCBwYXRocyBiZXJlLCBzbyB3ZSBjYW4sIGluIG1lbW9yeSxcbiAqIGdldCB0aGUgZm9sZGVyIHdoZXJlIGEgcGFja2FnZS5qc29uIGV4aXN0cywgcmF0aGVyIHRoYW5cbiAqIGhpdCB0aGUgZmlsZSBzeXN0ZW0gZXZlcnkgdGltZS5cbiAqL1xuY29uc3QgU0VFTiA9IG5ldyBTZXQoKTtcblxuZnVuY3Rpb24gZ2V0U2Vlbihzb3VyY2VQYXRoKSB7XG4gIGlmIChTRUVOLmhhcyhzb3VyY2VQYXRoKSkgcmV0dXJuIHNvdXJjZVBhdGg7XG5cbiAgbGV0IHBhcnRzID0gc291cmNlUGF0aC5zcGxpdChwYXRoLnNlcCk7XG5cbiAgZm9yIChsZXQgaSA9IHBhcnRzLmxlbmd0aCAtIDE7IGkgPiAxOyBpLS0pIHtcbiAgICBsZXQgdG9DaGVjayA9IHBhcnRzLnNsaWNlKDAsIGkpLmpvaW4ocGF0aC5zZXApO1xuXG4gICAgbGV0IHNlZW4gPSBTRUVOLmhhcyh0b0NoZWNrKTtcblxuICAgIGlmIChzZWVuKSB7XG4gICAgICByZXR1cm4gdG9DaGVjaztcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRXb3Jrc3BhY2VQYXRoKHNvdXJjZVBhdGgsIG9wdGlvbnMpIHtcbiAgbGV0IGN3ZCA9IG9wdGlvbnM/LmN3ZCA/PyBDV0Q7XG5cbiAgaWYgKHNvdXJjZVBhdGguZW5kc1dpdGgocGF0aC5zZXApKSB7XG4gICAgc291cmNlUGF0aCA9IHNvdXJjZVBhdGgucmVwbGFjZShcbiAgICAgIG5ldyBSZWdFeHAoYCR7UmVnRXhwLmVzY2FwZShwYXRoLnNlcCl9JGApLFxuICAgICAgJycsXG4gICAgKTtcbiAgfVxuXG4gIGxldCBzZWVuID0gZ2V0U2Vlbihzb3VyY2VQYXRoKTtcblxuICBpZiAoc2Vlbikge1xuICAgIHJldHVybiBzZWVuO1xuICB9XG5cbiAgbGV0IGNhbmRpZGF0ZVBhdGggPSBwYXRoLmpvaW4oc291cmNlUGF0aCwgJ3BhY2thZ2UuanNvbicpO1xuXG4gIGNvbnN0IGlzV29ya3NwYWNlID0gZnNTeW5jLmV4aXN0c1N5bmMoY2FuZGlkYXRlUGF0aCk7XG5cbiAgaWYgKGlzV29ya3NwYWNlKSB7XG4gICAgcmV0dXJuIHNvdXJjZVBhdGg7XG4gIH1cblxuICBjb25zdCBwYWNrYWdlSnNvblBhdGggPSBmaW5kUGFja2FnZUpzb25VcChzb3VyY2VQYXRoLCB7IGN3ZCB9KTtcblxuICBpZiAoIXBhY2thZ2VKc29uUGF0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IGRldGVybWluZSBwcm9qZWN0IGZvciAke3NvdXJjZVBhdGh9YCk7XG4gIH1cblxuICBjb25zdCB3b3Jrc3BhY2VQYXRoID0gcGF0aC5kaXJuYW1lKHBhY2thZ2VKc29uUGF0aCk7XG5cbiAgU0VFTi5hZGQod29ya3NwYWNlUGF0aCk7XG5cbiAgcmV0dXJuIHdvcmtzcGFjZVBhdGg7XG59XG5cbmZ1bmN0aW9uIGZpbmRQYWNrYWdlSnNvblVwKHN0YXJ0UGF0aCwgb3B0aW9ucykge1xuICBsZXQgY3dkID0gb3B0aW9ucz8uY3dkID8/IENXRDtcbiAgbGV0IHBhcnRzID0gc3RhcnRQYXRoLnNwbGl0KHBhdGguc2VwKTtcblxuICBmb3IgKGxldCBpID0gcGFydHMubGVuZ3RoIC0gMTsgaSA+IDE7IGktLSkge1xuICAgIGxldCB0b0NoZWNrID0gcGFydHMuc2xpY2UoMCwgaSkuam9pbihwYXRoLnNlcCk7XG5cbiAgICBsZXQgcGFja2FnZUpzb24gPSBwYXRoLmpvaW4odG9DaGVjaywgJ3BhY2thZ2UuanNvbicpO1xuICAgIGxldCBleGlzdHMgPSBmc1N5bmMuZXhpc3RzU3luYyhwYWNrYWdlSnNvbik7XG5cbiAgICBpZiAoZXhpc3RzKSB7XG4gICAgICByZXR1cm4gcGFja2FnZUpzb247XG4gICAgfVxuXG4gICAgLy8gRG9uJ3QgdHJhdmVyc2UgYWxsIHRoZSB3YXkgdG8gdGhlIHJvb3Qgb2YgdGhlIGZpbGUgc3lzdGVtLlxuICAgIGlmICh0b0NoZWNrID09PSBjd2QpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBNQU5JRkVTVF9DQUNIRSA9IG5ldyBNYXAoKTtcblxuLyoqXG4gKiBXaWxsIHJldHVybiB0aGUgcGFja2FnZS5qc29uI25hbWUsIG9yIGNvbmZpZy9lbnZpcm9ubWVudCNtb3VkbGVQcmVmaXggKGlmIHYxIGFwcClcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlUGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gbW9kdWxlTmFtZShzb3VyY2VQYXRoKSB7XG4gIGNvbnN0IHdvcmtzcGFjZSA9IGZpbmRXb3Jrc3BhY2VQYXRoKHNvdXJjZVBhdGgpO1xuICBjb25zdCBtYW5pZmVzdCA9IGdldE1hbmlmZXN0KHdvcmtzcGFjZSk7XG5cbiAgcmV0dXJuIG1hbmlmZXN0Lm5hbWU7XG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHdvcmtzcGFjZVxuICovXG5mdW5jdGlvbiBnZXRNYW5pZmVzdCh3b3Jrc3BhY2UpIHtcbiAgbGV0IGV4aXN0aW5nID0gTUFOSUZFU1RfQ0FDSEUuZ2V0KHdvcmtzcGFjZSk7XG5cbiAgaWYgKGV4aXN0aW5nKSB7XG4gICAgcmV0dXJuIGV4aXN0aW5nO1xuICB9XG5cbiAgbGV0IGJ1ZmZlciA9IGZzU3luYy5yZWFkRmlsZVN5bmMocGF0aC5qb2luKHdvcmtzcGFjZSwgJ3BhY2thZ2UuanNvbicpKTtcbiAgbGV0IGNvbnRlbnQgPSBidWZmZXIudG9TdHJpbmcoKTtcbiAgbGV0IGpzb24gPSBKU09OLnBhcnNlKGNvbnRlbnQpO1xuXG4gIE1BTklGRVNUX0NBQ0hFLnNldCh3b3Jrc3BhY2UsIGpzb24pO1xuXG4gIHJldHVybiBqc29uO1xufVxuIiwiLyoqXG4gKiBTcGxpdHMgYSBzcGFjZS1zZXBhcmF0ZWQgY2xhc3MgbGlzdCAodGhlIHZhbHVlIG9mIGEgYGNsYXNzYCBhdHRyaWJ1dGUgb3Igb2ZcbiAqIGEgYFtjbGFzcz1cIi4uLlwiXWAgc2VsZWN0b3IpIGludG8gaXRzIGluZGl2aWR1YWwgY2xhc3MgbmFtZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzTGlzdFxuICogQHJldHVybnMge3N0cmluZ1tdfVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3BsaXRDbGFzc0xpc3QoY2xhc3NMaXN0KSB7XG4gIHJldHVybiBjbGFzc0xpc3Quc3BsaXQoL1xccysvKS5maWx0ZXIoQm9vbGVhbik7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBwb3N0Zml4XG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBbY2xhc3Nlc0luQ3NzXVxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmFtZUNsYXNzKGNsYXNzTmFtZSwgcG9zdGZpeCwgY2xhc3Nlc0luQ3NzKSB7XG4gIGNvbnN0IHJlbmFtZWRDbGFzc2VzID0gc3BsaXRDbGFzc0xpc3QoY2xhc3NOYW1lKVxuICAgIC5tYXAoKGMpID0+IHtcbiAgICAgIGlmICghY2xhc3Nlc0luQ3NzIHx8IGNsYXNzZXNJbkNzcy5oYXMoYykpIHtcbiAgICAgICAgaWYgKGMuZW5kc1dpdGgocG9zdGZpeCkpIHJldHVybiBjO1xuXG4gICAgICAgIHJldHVybiBjICsgJ18nICsgcG9zdGZpeDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGM7XG4gICAgfSlcbiAgICAuam9pbignICcpO1xuXG4gIGNvbnN0IHJlbmFtZWRXaXRoUHJlc2VydmVkU3BhY2VzID0gY2xhc3NOYW1lLnJlcGxhY2UoXG4gICAgY2xhc3NOYW1lLnRyaW1TdGFydCgpLnRyaW1FbmQoKSxcbiAgICByZW5hbWVkQ2xhc3NlcyxcbiAgKTtcblxuICByZXR1cm4gcmVuYW1lZFdpdGhQcmVzZXJ2ZWRTcGFjZXM7XG59XG4iLCJpbXBvcnQge1xuICBhcHBQYXRoLFxuICBoYXNoRnJvbU1vZHVsZVBhdGgsXG4gIGlzUmVsZXZhbnRGaWxlLFxufSBmcm9tICcuLi9saWIvcGF0aC91dGlscy5qcyc7XG5pbXBvcnQgeyByZW5hbWVDbGFzcyB9IGZyb20gJy4uL2xpYi9yZW5hbWVDbGFzcy5qcyc7XG5cbmZ1bmN0aW9uIF9pc1JlbGV2YW50RmlsZShzdGF0ZSwgY3dkKSB7XG4gIGxldCBmaWxlTmFtZSA9IHN0YXRlLmZpbGUub3B0cy5maWxlbmFtZTtcbiAgbGV0IGFkZGl0aW9uYWxSb290cyA9IHN0YXRlLm9wdHM/LmFkZGl0aW9uYWxSb290cztcblxuICByZXR1cm4gaXNSZWxldmFudEZpbGUoZmlsZU5hbWUsIHtcbiAgICBhZGRpdGlvbmFsUm9vdHMsXG4gICAgY3dkLFxuICB9KTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge2FueX0gZW52IC0gYmFiZWwgcGx1Z2luIGVudiwgZW52LnR5cGVzIGlzIG1vc3QgY29tbW9ubHkgdXNlZCAoZXNwIGluIFRTKVxuICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnMgLSB0aGUgb3B0aW9ucyBmb3Igc2NvcGVkLWNzcyAtLSB0aGlzIGlzIGFsc28gYXZhaWxhYmxlIGluIGVhY2ggdmlzaXRvcidzIHN0YXRlLm9wdHNcbiAqIEBwYXJhbSB7c3RyaW5nfSB3b3JraW5nRGlyZWN0b3J5XG4gKi9cbmV4cG9ydCBjb25zdCBzY29wZWRDU1MgPSAoY29uZmlnKSA9PiAoZW52LCBvcHRpb25zLCB3b3JraW5nRGlyZWN0b3J5KSA9PiB7XG4gIC8vIG5vdCByZWFsbHkgYSBkZWVwIG1lcmdlLCBidXQgdGhlIGlkZWEgaXMgdG8gdXNlIG9uZSBvciB0aGUgb3RoZXIgYW5kIG5vdCBtaXggdGhlIGNvbmZpZ3NcbiAgb3B0aW9ucyA9IHsgLi4uY29uZmlnLCAuLi5vcHRpb25zIH07XG5cbiAgLyoqXG4gICAqIFRoaXMgYmFiZWwgcGx1Z2luIGRvZXMgdHdvIHRoaW5nczpcbiAgICogLSByZW1vdmVzIHRoZSBpbXBvcnQgb2Ygc2NvcGVkQ2xhc3MsIGlmIGl0IGV4aXN0c1xuICAgKiAgIC0gaWYgc2NvcGVkQ2xhc3Mgd2FzIGltcG9ydGVkLCBpdCBpcyByZW1vdmVkIGZyb20gYW55IGNvbXBvbmVudCdzIFwic2NvcGUgYmFnXCJcbiAgICogICAgICh0aGUgc2NvcGUgYmFnIGJlaW5nIGEgbG93LWxldmVsIG9iamVjdCB1c2VkIGZvciBwYXNzaW5nIHdoYXQgaXMgXCJpbiBzY29wZVwiIGZvciBhIGNvbXBvbmVudClcbiAgICovXG4gIHJldHVybiB7XG4gICAgdmlzaXRvcjoge1xuICAgICAgUHJvZ3JhbToge1xuICAgICAgICBlbnRlcihwYXRoLCBzdGF0ZSkge1xuICAgICAgICAgIGlmICghX2lzUmVsZXZhbnRGaWxlKHN0YXRlLCB3b3JraW5nRGlyZWN0b3J5KSkge1xuICAgICAgICAgICAgc3RhdGUuY2FuU2tpcCA9IHRydWU7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgbW9kdWxlUGF0aCA9IGFwcFBhdGgoc3RhdGUuZmlsZW5hbWUpO1xuXG4gICAgICAgICAgc3RhdGUucG9zdGZpeCA9IGhhc2hGcm9tTW9kdWxlUGF0aChtb2R1bGVQYXRoKTtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBJbXBvcnREZWNsYXJhdGlvbihwYXRoLCBzdGF0ZSkge1xuICAgICAgICBpZiAoc3RhdGUuY2FuU2tpcCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXRoLm5vZGUuc291cmNlLnZhbHVlID09PSAnZW1iZXItc2NvcGVkLWNzcycpIHtcbiAgICAgICAgICBsZXQgc3BlY2lmaWVyID0gcGF0aC5ub2RlLnNwZWNpZmllcnMuZmluZChcbiAgICAgICAgICAgICh4KSA9PiB4LmltcG9ydGVkLm5hbWUgPT09ICdzY29wZWRDbGFzcycsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChzcGVjaWZpZXIpIHtcbiAgICAgICAgICAgIHN0YXRlLmZpbGUub3B0cy5pbXBvcnRlZFNjb3BlZENsYXNzID0gc3BlY2lmaWVyLmxvY2FsLm5hbWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNwZWNpZmllci5sb2NhbC5uYW1lICE9PSAnc2NvcGVkQ2xhc3MnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgIGBUaGUgc2NvcGVkQ2xhc3MgaW1wb3J0IGlzIGEgcHN1ZWRvLWhlbHBlciwgYW5kIG1heSBub3QgYmUgcmVuYW1lZCBhcyBpdCBpcyByZW1vdmVkIGF0IGJ1aWxkIHRpbWUuYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcGF0aC5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8qKlxuICAgICAgICogUmVuYW1lIHVzYWdlcyBpbiBKUy9UUy9HSlMvR1RTXG4gICAgICAgKi9cbiAgICAgIENhbGxFeHByZXNzaW9uKHBhdGgsIHN0YXRlKSB7XG4gICAgICAgIGlmIChzdGF0ZS5jYW5Ta2lwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHBhdGgubm9kZS5jYWxsZWUudHlwZSA9PT0gJ0lkZW50aWZpZXInICYmXG4gICAgICAgICAgcGF0aC5ub2RlLmNhbGxlZS5uYW1lID09PSBzdGF0ZS5maWxlLm9wdHM/LmltcG9ydGVkU2NvcGVkQ2xhc3NcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcGF0aC5ub2RlLmFyZ3VtZW50cy5sZW5ndGggIT09IDEgfHxcbiAgICAgICAgICAgIHBhdGgubm9kZS5hcmd1bWVudHNbMF0udHlwZSAhPT0gJ1N0cmluZ0xpdGVyYWwnXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgIGBUaGUgc2NvcGVkQ2xhc3MgaGVscGVyIG9ubHkgYWNjZXB0cyBhIHNpbmdsZSwgbm9uLWR5bmFtaWMsIHN0cmluZyBsaXRlcmFsIGFyZ3VtZW50LmAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IG9yaWdpbmFsID0gcGF0aC5ub2RlLmFyZ3VtZW50c1swXS52YWx1ZTtcbiAgICAgICAgICBjb25zdCByZW5hbWVkID0gcmVuYW1lQ2xhc3MoXG4gICAgICAgICAgICBvcmlnaW5hbCxcbiAgICAgICAgICAgIHN0YXRlLnBvc3RmaXgsXG4gICAgICAgICAgICBuZXcgU2V0KFtvcmlnaW5hbF0pLFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRTdHJpbmcgPSBlbnYudHlwZXMuc3RyaW5nTGl0ZXJhbChyZW5hbWVkKTtcblxuICAgICAgICAgIHBhdGgucmVwbGFjZVdpdGgodHJhbnNmb3JtZWRTdHJpbmcpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgLyoqXG4gICAgICAgKiBPbmx5IGluIHN0cmljdCBtb2RlLCBkbyB3ZSBjYXJlIGFib3V0IHJlbW9uaW5nIHRoZSBzY29wZSBiYWcgcmVmZXJlbmNlXG4gICAgICAgKi9cbiAgICAgIE9iamVjdFByb3BlcnR5KHBhdGgsIHN0YXRlKSB7XG4gICAgICAgIGlmICghc3RhdGUuZmlsZS5vcHRzPy5pbXBvcnRlZFNjb3BlZENsYXNzKSByZXR1cm47XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHBhdGgubm9kZS52YWx1ZS50eXBlID09PSAnSWRlbnRpZmllcicgJiZcbiAgICAgICAgICBwYXRoLm5vZGUudmFsdWUubmFtZSA9PT0gc3RhdGUuZmlsZS5vcHRzPy5pbXBvcnRlZFNjb3BlZENsYXNzXG4gICAgICAgICkge1xuICAgICAgICAgIHBhdGgucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbn07XG4iLCJpbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgcG9zdGNzcyBmcm9tICdwb3N0Y3NzJztcbmltcG9ydCBzY3NzU3ludGF4IGZyb20gJ3Bvc3Rjc3Mtc2Nzcyc7XG5pbXBvcnQgcGFyc2VyIGZyb20gJ3Bvc3Rjc3Mtc2VsZWN0b3ItcGFyc2VyJztcblxuaW1wb3J0IHsgbWQ1IH0gZnJvbSAnLi4vcGF0aC9tZDUuanMnO1xuaW1wb3J0IHsgc3BsaXRDbGFzc0xpc3QgfSBmcm9tICcuLi9yZW5hbWVDbGFzcy5qcyc7XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGNzc1xuICogQHJldHVybiB7c3RyaW5nfSBoYXNoZWQgZG93biB2ZXJzaW9uIG9mIHRoZSBDU1MgZm9yIGRpc2FtYmlndWF0aW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoKGNzcykge1xuICByZXR1cm4gYGNzcy0ke21kNShjc3MpfWA7XG59XG5cbi8qKlxuICogQXR0cmlidXRlIHNlbGVjdG9ycyBhcmUgc2NvcGVkIHdpdGggb25lIG9mIHR3byBzdHJhdGVnaWVzOlxuICpcbiAqIC0gKipyZW5hbWVkIHZhbHVlKio6IGNsYXNzLXRhcmdldGluZyBzZWxlY3RvcnMgd2hvc2UgdmFsdWUgbmFtZXMgcmVhbFxuICogICBjbGFzcyhlcykgKGBbY2xhc3M9XCJmb29cIl1gLCBgW2NsYXNzfj1cImZvb1wiXWApIGFyZSBzY29wZWQgYnkgcmVuYW1pbmcgdGhlXG4gKiAgIHZhbHVlIHRoZSBzYW1lIHdheSBgLmZvb2AgaXMgcmVuYW1lZCB0byBgLmZvb19wb3N0Zml4YC4gVGhlIHJlbmFtZWQgdG9rZW5cbiAqICAgaXMgdW5pcXVlIHBlciBmaWxlLCBzbyBub3RoaW5nIGVsc2UgaXMgbmVlZGVkLlxuICogLSAqKnBvc3RmaXggY2xhc3MqKjogZXZlcnkgb3RoZXIgYXR0cmlidXRlIHNlbGVjdG9yIGtlZXBzIGl0cyBkaXNjcmltaW5hdG9yXG4gKiAgIGFuZCBpcyBzY29wZWQgYnkgdGhlIGdlbmVyYXRlZCBwb3N0Zml4IGNsYXNzIOKAlCBhcHBlbmRlZCB0byB0aGUgc2VsZWN0b3JcbiAqICAgaW4gdGhlIENTUyBhbmQgYWRkZWQgdG8gbWF0Y2hpbmcgZWxlbWVudHMgaW4gdGhlIHRlbXBsYXRlICh0aGUgc2FtZVxuICogICBzdHJhdGVneSBiYXJlIHRhZyBzZWxlY3RvcnMgdXNlOiBgZGl2YCBiZWNvbWVzIGBkaXYucG9zdGZpeGApLlxuICpcbiAqIFRoaXMgcHJlZGljYXRlIGRlY2lkZXMgYmV0d2VlbiB0aGUgdHdvLiBJdCBpcyBzaGFyZWQgYnkgdGhlIENTUyByZXdyaXRlXG4gKiAod2hpY2ggcmVuYW1lcyB0aGUgc2VsZWN0b3IgdmFsdWUpIGFuZCBieSBkaXNjb3ZlcnkgaW4gdGhpcyBmaWxlICh3aGljaFxuICogcmVnaXN0ZXJzIHRoZSB2YWx1ZSdzIGNsYXNzIG5hbWVzIGZvciB0ZW1wbGF0ZSByZW5hbWluZykgc28gYm90aCBzaWRlc1xuICogYWx3YXlzIGNsYXNzaWZ5IGEgc2VsZWN0b3IgdGhlIHNhbWUgd2F5LlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KCdwb3N0Y3NzLXNlbGVjdG9yLXBhcnNlcicpLkF0dHJpYnV0ZX0gbm9kZVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1JlbmFtZWRDbGFzc0F0dHJpYnV0ZShub2RlKSB7XG4gIHJldHVybiAoXG4gICAgbm9kZS5hdHRyaWJ1dGUgPT09ICdjbGFzcycgJiZcbiAgICAobm9kZS5vcGVyYXRvciA9PT0gJz0nIHx8IG5vZGUub3BlcmF0b3IgPT09ICd+PScpICYmXG4gICAgQm9vbGVhbihub2RlLnZhbHVlKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNJbnNpZGVHbG9iYWwobm9kZSwgZnVuYykge1xuICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudDtcblxuICBpZiAoIXBhcmVudCkgcmV0dXJuIGZhbHNlO1xuICBpZiAocGFyZW50LnR5cGUgPT09ICdwc2V1ZG8nICYmIHBhcmVudC52YWx1ZSA9PT0gJzpnbG9iYWwnKSByZXR1cm4gdHJ1ZTtcblxuICByZXR1cm4gaXNJbnNpZGVHbG9iYWwocGFyZW50LCBmdW5jKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gY3NzUGF0aCBwYXRoIHRvIGEgQ1NTIGZpbGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENTU0luZm8oY3NzUGF0aCkge1xuICBpZiAoIWV4aXN0c1N5bmMoY3NzUGF0aCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGxldCBjc3MgPSByZWFkRmlsZVN5bmMoY3NzUGF0aCwgJ3V0ZjgnKTtcblxuICByZXR1cm4gZ2V0Q1NTQ29udGVudEluZm8oY3NzKTtcbn1cblxuLyoqXG4gKiBXZSB1c2UgdGhpcyBmdW5jdGlvbiB0byBjaGVjayBlYWNoIGNsYXNzIHVzZWQgaW4gdGhlIHRlbXBsYXRlXG4gKiB0byBzZWUgaWYgd2UgbmVlZCB0byBsZWF2ZSBpdCBhbG9uZSBvciB0cmFuc2Zvcm0gaXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY3NzIHRoZSBDU1MncyBjb250ZW50c1xuICogQHBhcmFtIHtzdHJpbmd9IFtsYW5nXSBvcHRpb25hbCBsYW5ndWFnZSBoaW50IChlLmcuICdzY3NzJywgJ3Nhc3MnLCAnbGVzcycpXG4gKiBAcmV0dXJuIHt7IGNsYXNzZXM6IFNldDxzdHJpbmc+LCB0YWdzOiBTZXQ8c3RyaW5nPiwgYXR0cmlidXRlczogU2V0PHN0cmluZz4sIGNzczogc3RyaW5nLCBpZDogc3RyaW5nIH19XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDU1NDb250ZW50SW5mbyhjc3MsIGxhbmcpIHtcbiAgY29uc3QgY2xhc3NlcyA9IG5ldyBTZXQoKTtcbiAgY29uc3QgdGFncyA9IG5ldyBTZXQoKTtcbiAgY29uc3QgYXR0cmlidXRlcyA9IG5ldyBTZXQoKTtcblxuICBjb25zdCBwYXJzZU9wdGlvbnMgPVxuICAgIGxhbmcgPT09ICdzY3NzJyB8fCBsYW5nID09PSAnc2FzcycgPyB7IHN5bnRheDogc2Nzc1N5bnRheCB9IDoge307XG5cbiAgY29uc3QgYXN0ID0gcG9zdGNzcy5wYXJzZShjc3MsIHBhcnNlT3B0aW9ucyk7XG5cbiAgY29uc3QgaXNTY3NzID0gbGFuZyA9PT0gJ3Njc3MnIHx8IGxhbmcgPT09ICdzYXNzJztcblxuICBhc3Qud2Fsaygobm9kZSkgPT4ge1xuICAgIGlmIChub2RlLnR5cGUgPT09ICdydWxlJykge1xuICAgICAgY29uc3Qgc2VsZWN0b3IgPSBpc1Njc3MgPyByZXNvbHZlTmVzdGVkU2Fzc1NlbGVjdG9yKG5vZGUpIDogbm9kZS5zZWxlY3RvcjtcblxuICAgICAgY29sbGVjdFNlbGVjdG9ySW5mbyhzZWxlY3RvciwgY2xhc3NlcywgdGFncywgYXR0cmlidXRlcyk7XG4gICAgfVxuICB9KTtcblxuICBsZXQgaWQgPSBoYXNoKGNzcyk7XG5cbiAgcmV0dXJuIHsgY2xhc3NlcywgdGFncywgYXR0cmlidXRlcywgY3NzLCBpZCB9O1xufVxuXG4vKipcbiAqIFJlc29sdmVzIGEgbmVzdGVkIFNDU1Mgc2VsZWN0b3IgYnkgc3Vic3RpdHV0aW5nIGAmYCB3aXRoIHRoZSBmdWxseS1yZXNvbHZlZFxuICogcGFyZW50IHNlbGVjdG9yLCByZWN1cnNpdmVseS4gVGhpcyBjb252ZXJ0cyBlLmcuIGAmLS1tb2RpZmllcmAgKGNoaWxkIG9mXG4gKiBgLmJsb2NrYCkgaW50byBgLmJsb2NrLS1tb2RpZmllcmAsIGFuZCBoYW5kbGVzIGFyYml0cmFyeSBuZXN0aW5nIGRlcHRoIHNvXG4gKiB0aGF0IGAmLS1tb2RpZmllcmAgaW5zaWRlIGAmLS1tb2RpZmllcmAgaW5zaWRlIGAuYmxvY2tgIHlpZWxkc1xuICogYC5ibG9jay0tbW9kaWZpZXItLW1vZGlmaWVyYC5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydCgncG9zdGNzcycpLlJ1bGV9IG5vZGVcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZU5lc3RlZFNhc3NTZWxlY3Rvcihub2RlKSB7XG4gIGNvbnN0IHsgc2VsZWN0b3IgfSA9IG5vZGU7XG5cbiAgaWYgKCFzZWxlY3Rvci5pbmNsdWRlcygnJicpKSB7XG4gICAgcmV0dXJuIHNlbGVjdG9yO1xuICB9XG5cbiAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnQ7XG5cbiAgaWYgKCFwYXJlbnQgfHwgcGFyZW50LnR5cGUgIT09ICdydWxlJykge1xuICAgIC8vIE5vIHBhcmVudCBydWxlIOKAlCBgJmAgaGFzIG5vdGhpbmcgdG8gc3Vic3RpdHV0ZSwgcmV0dXJuIGFzLWlzXG4gICAgcmV0dXJuIHNlbGVjdG9yO1xuICB9XG5cbiAgLy8gUmVjdXJzaXZlbHkgcmVzb2x2ZSB0aGUgcGFyZW50IGZpcnN0LCB0aGVuIHN1YnN0aXR1dGUgaW50byB0aGlzIHNlbGVjdG9yXG4gIGNvbnN0IHJlc29sdmVkUGFyZW50ID0gcmVzb2x2ZU5lc3RlZFNhc3NTZWxlY3RvcihwYXJlbnQpO1xuXG4gIHJldHVybiBzZWxlY3Rvci5yZXBsYWNlKC8mL2csIHJlc29sdmVkUGFyZW50KTtcbn1cblxuZnVuY3Rpb24gY29sbGVjdFNlbGVjdG9ySW5mbyhzZWwsIGNsYXNzZXMsIHRhZ3MsIGF0dHJpYnV0ZXMpIHtcbiAgY29uc3QgdHJhbnNmb3JtID0gKHNscykgPT4ge1xuICAgIHNscy53YWxrKChzZWxlY3RvcikgPT4ge1xuICAgICAgaWYgKGlzSW5zaWRlR2xvYmFsKHNlbGVjdG9yKSkgcmV0dXJuO1xuXG4gICAgICBpZiAoc2VsZWN0b3IudHlwZSA9PT0gJ2NsYXNzJykge1xuICAgICAgICBjbGFzc2VzLmFkZChzZWxlY3Rvci52YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHNlbGVjdG9yLnR5cGUgPT09ICd0YWcnKSB7XG4gICAgICAgIHRhZ3MuYWRkKHNlbGVjdG9yLnZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAoc2VsZWN0b3IudHlwZSA9PT0gJ2F0dHJpYnV0ZScpIHtcbiAgICAgICAgaWYgKGlzUmVuYW1lZENsYXNzQXR0cmlidXRlKHNlbGVjdG9yKSkge1xuICAgICAgICAgIC8vIFJlZ2lzdGVyIHRoZSB2YWx1ZSdzIGNsYXNzIG5hbWVzIHNvIHRoZSB0ZW1wbGF0ZSByZW5hbWVzIHRoZW0uXG4gICAgICAgICAgLy9cbiAgICAgICAgICAvLyBwb3N0Y3NzLXNlbGVjdG9yLXBhcnNlciBleHBvc2VzIHRoZSBhdHRyaWJ1dGUgdmFsdWUgb25seSBhcyBhblxuICAgICAgICAgIC8vIG9wYXF1ZSBzdHJpbmcsIHNvIHNwbGl0dGluZyBgW2NsYXNzPVwiZm9vIGJhclwiXWAgaW50byBpdHNcbiAgICAgICAgICAvLyBzcGFjZS1zZXBhcmF0ZWQgY2xhc3MgbmFtZXMgaXMgb24gdXMg4oCUIGBzcGxpdENsYXNzTGlzdGAgaXMgdGhlXG4gICAgICAgICAgLy8gc2FtZSB0b2tlbml6YXRpb24gYHJlbmFtZUNsYXNzYCBhcHBsaWVzLlxuICAgICAgICAgIGZvciAobGV0IHRva2VuIG9mIHNwbGl0Q2xhc3NMaXN0KHNlbGVjdG9yLnZhbHVlKSkge1xuICAgICAgICAgICAgY2xhc3Nlcy5hZGQodG9rZW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBFbGVtZW50cyBjYXJyeWluZyB0aGlzIGF0dHJpYnV0ZSBnZXQgdGhlIHBvc3RmaXggY2xhc3MuIEZvclxuICAgICAgICAgIC8vIGNsYXNzLXRhcmdldCBvcGVyYXRvcnMgKF49LCAqPSwgJD0sIHw9KSBhbmQgcHJlc2VuY2UsIHRoZSBuYW1lXG4gICAgICAgICAgLy8gaXMgYGNsYXNzYC5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIENTUyBtYXRjaGVzIEhUTUwgYXR0cmlidXRlIG5hbWVzIGNhc2UtaW5zZW5zaXRpdmVseSwgc28gc3RvcmUgdGhlXG4gICAgICAgICAgLy8gbmFtZSBsb3dlcmNhc2VkIGFuZCBjb21wYXJlIGFnYWluc3QgbG93ZXJjYXNlZCB0ZW1wbGF0ZSBhdHRyaWJ1dGVcbiAgICAgICAgICAvLyBuYW1lcy4gKENvYXJzZXIgdGhhbiBTVkcncyBjYXNlLXNlbnNpdGl2ZSBtYXRjaGluZywgYnV0IHRoZSB0d29cbiAgICAgICAgICAvLyBzaWRlcyBhbHdheXMgYWdyZWU7IHdvcnN0IGNhc2UgYW4gZWxlbWVudCBnZXRzIHRoZSBwb3N0Zml4IGNsYXNzXG4gICAgICAgICAgLy8gaXQgZGlkbid0IHN0cmljdGx5IG5lZWQuKVxuICAgICAgICAgIGF0dHJpYnV0ZXMuYWRkKHNlbGVjdG9yLmF0dHJpYnV0ZS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIHBhcnNlcih0cmFuc2Zvcm0pLnByb2Nlc3NTeW5jKHNlbCk7XG59XG5cbmlmIChpbXBvcnQubWV0YS52aXRlc3QpIHtcbiAgY29uc3QgeyBpdCwgZXhwZWN0IH0gPSBpbXBvcnQubWV0YS52aXRlc3Q7XG5cbiAgaXQoJ3Nob3VsZCByZXR1cm4gY2xhc3NlcyBhbmQgdGFncyB0aGF0IGFyZSBub3QgaW4gOmdsb2JhbCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjc3MgPSAnLmJheiA6Z2xvYmFsKC5mb28pIC5iYXIgZGl2IDpnbG9iYWwocCkgIHsgY29sb3I6IHJlZDsgfSc7XG4gICAgY29uc3QgeyBjbGFzc2VzLCB0YWdzIH0gPSBnZXRDU1NDb250ZW50SW5mbyhjc3MpO1xuXG4gICAgLy8gY2xhc3NlcyBzaG91bGQgYmUgYmF6IGFuZCBiYXJcbiAgICBleHBlY3QoY2xhc3Nlcy5zaXplKS50by5lcXVhbCgyKTtcbiAgICBleHBlY3QoWy4uLmNsYXNzZXNdKS50by5oYXZlLm1lbWJlcnMoWydiYXonLCAnYmFyJ10pO1xuICAgIGV4cGVjdCh0YWdzLnNpemUpLnRvLmVxdWFsKDEpO1xuICAgIGV4cGVjdChbLi4udGFnc10pLnRvLmhhdmUubWVtYmVycyhbJ2RpdiddKTtcbiAgfSk7XG5cbiAgaXQoJ2NvbGxlY3RzIGF0dHJpYnV0ZSBuYW1lcyBmb3IgcG9zdGZpeC1jbGFzcyBzY29waW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGNzcyA9ICdbZGlzYWJsZWRdIFtkYXRhLXg9XCJ5XCJdIHsgY29sb3I6IHJlZDsgfSc7XG4gICAgY29uc3QgeyBhdHRyaWJ1dGVzIH0gPSBnZXRDU1NDb250ZW50SW5mbyhjc3MpO1xuXG4gICAgZXhwZWN0KGF0dHJpYnV0ZXMpLnRvLmRlZXAuZXF1YWwobmV3IFNldChbJ2Rpc2FibGVkJywgJ2RhdGEteCddKSk7XG4gIH0pO1xuXG4gIGl0KCd0cmVhdHMgPS9+PSBjbGFzcyBhdHRyaWJ1dGUgdmFsdWVzIGFzIHJlbmFtZWQgY2xhc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjc3MgPSAnW2NsYXNzPVwiZm9vIGJhclwiXSBbY2xhc3N+PVwiYmF6XCJdIHsgY29sb3I6IHJlZDsgfSc7XG4gICAgY29uc3QgeyBjbGFzc2VzLCBhdHRyaWJ1dGVzIH0gPSBnZXRDU1NDb250ZW50SW5mbyhjc3MpO1xuXG4gICAgZXhwZWN0KGNsYXNzZXMpLnRvLmRlZXAuZXF1YWwobmV3IFNldChbJ2ZvbycsICdiYXInLCAnYmF6J10pKTtcbiAgICBleHBlY3QoYXR0cmlidXRlcykudG8uZGVlcC5lcXVhbChuZXcgU2V0KCkpO1xuICB9KTtcblxuICBpdCgndHJlYXRzIG90aGVyIGNsYXNzIGF0dHJpYnV0ZSBvcGVyYXRvcnMgYXMgcG9zdGZpeC1jbGFzcyBhdHRyaWJ1dGVzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGNzcyA9ICdbY2xhc3NePVwiZm9vXCJdIFtjbGFzcyo9XCJiYXJcIl0geyBjb2xvcjogcmVkOyB9JztcbiAgICBjb25zdCB7IGNsYXNzZXMsIGF0dHJpYnV0ZXMgfSA9IGdldENTU0NvbnRlbnRJbmZvKGNzcyk7XG5cbiAgICBleHBlY3QoY2xhc3NlcykudG8uZGVlcC5lcXVhbChuZXcgU2V0KCkpO1xuICAgIGV4cGVjdChhdHRyaWJ1dGVzKS50by5kZWVwLmVxdWFsKG5ldyBTZXQoWydjbGFzcyddKSk7XG4gIH0pO1xuXG4gIGl0KCdsb3dlcmNhc2VzIGF0dHJpYnV0ZSBuYW1lcyAoQ1NTIG1hdGNoZXMgdGhlbSBjYXNlLWluc2Vuc2l0aXZlbHkpJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGNzcyA9ICdbVFlQRT1cInN1Ym1pdFwiXSB7IGNvbG9yOiByZWQ7IH0nO1xuICAgIGNvbnN0IHsgYXR0cmlidXRlcyB9ID0gZ2V0Q1NTQ29udGVudEluZm8oY3NzKTtcblxuICAgIGV4cGVjdChhdHRyaWJ1dGVzKS50by5kZWVwLmVxdWFsKG5ldyBTZXQoWyd0eXBlJ10pKTtcbiAgfSk7XG5cbiAgaXQoJ2lnbm9yZXMgYXR0cmlidXRlIHNlbGVjdG9ycyBpbnNpZGUgOmdsb2JhbCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjc3MgPSAnOmdsb2JhbChbZGF0YS14XSkgW2RhdGEteV0geyBjb2xvcjogcmVkOyB9JztcbiAgICBjb25zdCB7IGF0dHJpYnV0ZXMgfSA9IGdldENTU0NvbnRlbnRJbmZvKGNzcyk7XG5cbiAgICBleHBlY3QoYXR0cmlidXRlcykudG8uZGVlcC5lcXVhbChuZXcgU2V0KFsnZGF0YS15J10pKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBwYXJzZSBTQ1NTIG5lc3Rpbmcgc3ludGF4IHdpdGhvdXQgY3Jhc2hpbmcgd2hlbiBsYW5nPXNjc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2NzcyA9IGBcbiAgICAgICRiYXNlLWNvbG9yOiAjYzY1MzhjO1xuICAgICAgJGJvcmRlci1kYXJrOiByZ2JhKCRiYXNlLWNvbG9yLCAwLjg4KTtcblxuICAgICAgLnBhcmVudCB7XG4gICAgICAgICY6aG92ZXIgeyBjb2xvcjogJGJhc2UtY29sb3I7IH1cbiAgICAgICAgLmNoaWxkIHsgYm9yZGVyOiAxcHggc29saWQgJGJvcmRlci1kYXJrOyB9XG4gICAgICAgIGNvbG9yOiByZWQ7XG4gICAgICB9XG4gICAgYDtcbiAgICBjb25zdCB7IGNsYXNzZXMgfSA9IGdldENTU0NvbnRlbnRJbmZvKHNjc3MsICdzY3NzJyk7XG5cbiAgICBleHBlY3QoWy4uLmNsYXNzZXNdKS50b01hdGNoSW5saW5lU25hcHNob3QoYFxuICAgICAgW1xuICAgICAgICBcInBhcmVudFwiLFxuICAgICAgICBcImNoaWxkXCIsXG4gICAgICBdXG4gICAgYCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcGFyc2UgU0NTUyBuZXN0aW5nIHN5bnRheCB3aXRob3V0IGNyYXNoaW5nIHdoZW4gbGFuZz1zYXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNjc3MgPSBgXG4gICAgICAkYmFzZS1jb2xvcjogZ3JlZW47XG4gICAgICAuYmxvY2sge1xuICAgICAgICAmLS1tb2RpZmllciB7IGNvbG9yOiAkYmFzZS1jb2xvcjsgfVxuICAgICAgfVxuICAgIGA7XG4gICAgY29uc3QgeyBjbGFzc2VzIH0gPSBnZXRDU1NDb250ZW50SW5mbyhzY3NzLCAnc2FzcycpO1xuXG4gICAgZXhwZWN0KFsuLi5jbGFzc2VzXSkudG9NYXRjaElubGluZVNuYXBzaG90KGBcbiAgICAgIFtcbiAgICAgICAgXCJibG9ja1wiLFxuICAgICAgICBcImJsb2NrLS1tb2RpZmllclwiLFxuICAgICAgXVxuICAgIGApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHBhcnNlIFNDU1MgZGVlcGx5IG5lc3RlZCBCRU0gd2hlbiBsYW5nPXNhc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2NzcyA9IGBcbiAgICAgICRiYXNlLWNvbG9yOiBncmVlbjtcbiAgICAgIC5ibG9jayB7XG4gICAgICAgICYtLW1vZGlmaWVyIHtcbiAgICAgICAgICBjb2xvcjogJGJhc2UtY29sb3I7XG4gICAgICAgICAgJi0tbW9kaWZpZXIge1xuICAgICAgICAgICAgY29sb3I6ICRiYXNlLWNvbG9yO1xuICAgICAgICAgICAgJi0tbW9kaWZpZXIge1xuICAgICAgICAgICAgICBjb2xvcjogJGJhc2UtY29sb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgYDtcbiAgICBjb25zdCB7IGNsYXNzZXMgfSA9IGdldENTU0NvbnRlbnRJbmZvKHNjc3MsICdzYXNzJyk7XG5cbiAgICBleHBlY3QoWy4uLmNsYXNzZXNdKS50b01hdGNoSW5saW5lU25hcHNob3QoYFxuICAgICAgW1xuICAgICAgICBcImJsb2NrXCIsXG4gICAgICAgIFwiYmxvY2stLW1vZGlmaWVyXCIsXG4gICAgICAgIFwiYmxvY2stLW1vZGlmaWVyLS1tb2RpZmllclwiLFxuICAgICAgICBcImJsb2NrLS1tb2RpZmllci0tbW9kaWZpZXItLW1vZGlmaWVyXCIsXG4gICAgICBdXG4gICAgYCk7XG4gIH0pO1xufVxuIiwiLyoqXG4gKiBJbXBvcnRhbnQgZG9jczpcbiAqIC0gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL1xuICovXG5pbXBvcnQgcG9zdGNzcyBmcm9tICdwb3N0Y3NzJztcbmltcG9ydCBwYXJzZXIgZnJvbSAncG9zdGNzcy1zZWxlY3Rvci1wYXJzZXInO1xuXG5pbXBvcnQgeyByZW5hbWVDbGFzcyB9IGZyb20gJy4uL3JlbmFtZUNsYXNzLmpzJztcbmltcG9ydCB7IGlzSW5zaWRlR2xvYmFsLCBpc1JlbmFtZWRDbGFzc0F0dHJpYnV0ZSB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG5jb25zdCBTRVAgPSAnX18nO1xuXG5mdW5jdGlvbiBpc1J1bGUobm9kZSkge1xuICByZXR1cm4gbm9kZS50eXBlID09PSAncnVsZSc7XG59XG5cbmZ1bmN0aW9uIGlzRGVjbGFyYXRpb24obm9kZSkge1xuICByZXR1cm4gbm9kZS50eXBlID09PSAnZGVjbCc7XG59XG5cbi8qKlxuICogTk9URTogXCJrZXlmcmFtZXNcIiBpcyBhIHNpbmd1bGFyIGRlZmluaXRpb24sIGluIHRoYXQgaXQncyBhIGJsb2NrIGNvbnRhaW5pbmcga2V5ZnJhbWVzXG4gKiAgICAgICB1c2luZyBgQGtleWZyYW1lcyB7fWAgd2l0aCBvbmx5IG9uZSB0aGluZyBvbiB0aGUgaW5zaWRlIGRvZXNuJ3QgbWFrZSBzZW5zZS5cbiAqL1xuZnVuY3Rpb24gcmV3cml0ZVJlZmVyZW5jZWFibGUobm9kZSwgcG9zdGZpeCkge1xuICBsZXQgb3JpZ2luYWxOYW1lID0gbm9kZS5wYXJhbXM7XG4gIGxldCBwb3N0Zml4ZWROYW1lID0gbm9kZS5wYXJhbXMgKyBTRVAgKyBwb3N0Zml4O1xuXG4gIG5vZGUucGFyYW1zID0gcG9zdGZpeGVkTmFtZTtcblxuICByZXR1cm4ge1xuICAgIG9yaWdpbmFsTmFtZSxcbiAgICBwb3N0Zml4ZWROYW1lLFxuICB9O1xufVxuXG4vKipcbiAqIFdhbGsgbGVmdCBhbmQgcmlnaHQgZnJvbSBgbm9kZWAgd2l0aGluIGl0cyBjb21wb3VuZCBzZWxlY3RvciAoYm91bmRlZCBieVxuICogY29tYmluYXRvcnMpIHRvIHNlZSBpZiB0aGUgcG9zdGZpeCBjbGFzcyBoYXMgYWxyZWFkeSBiZWVuIGFkZGVkLiBVc2VkIHRvIGFkZFxuICogdGhlIHBvc3RmaXggY2xhc3MgYXQgbW9zdCBvbmNlIHBlciBjb21wb3VuZCwgZS5nLiBgaW5wdXRbdHlwZT1cInRleHRcIl1gXG4gKiBiZWNvbWVzIGBpbnB1dC5wb3N0Zml4W3R5cGU9XCJ0ZXh0XCJdYCwgbm90IGBpbnB1dC5wb3N0Zml4W3R5cGU9XCJ0ZXh0XCJdLnBvc3RmaXhgLlxuICovXG5mdW5jdGlvbiBjb21wb3VuZEhhc1Bvc3RmaXhDbGFzcyhub2RlLCBwb3N0Zml4KSB7XG4gIGNvbnN0IHNpYmxpbmdzID0gbm9kZS5wYXJlbnQubm9kZXM7XG4gIGNvbnN0IGluZGV4ID0gc2libGluZ3MuaW5kZXhPZihub2RlKTtcblxuICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKHNpYmxpbmdzW2ldLnR5cGUgPT09ICdjb21iaW5hdG9yJykgYnJlYWs7XG4gICAgaWYgKHNpYmxpbmdzW2ldLnR5cGUgPT09ICdjbGFzcycgJiYgc2libGluZ3NbaV0udmFsdWUgPT09IHBvc3RmaXgpXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSBpbmRleCArIDE7IGkgPCBzaWJsaW5ncy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChzaWJsaW5nc1tpXS50eXBlID09PSAnY29tYmluYXRvcicpIGJyZWFrO1xuICAgIGlmIChzaWJsaW5nc1tpXS50eXBlID09PSAnY2xhc3MnICYmIHNpYmxpbmdzW2ldLnZhbHVlID09PSBwb3N0Zml4KVxuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGFkZFBvc3RmaXhDbGFzcyhub2RlLCBwb3N0Zml4KSB7XG4gIGlmIChjb21wb3VuZEhhc1Bvc3RmaXhDbGFzcyhub2RlLCBwb3N0Zml4KSkgcmV0dXJuO1xuXG4gIG5vZGUucGFyZW50Lmluc2VydEFmdGVyKG5vZGUsIHBhcnNlci5jbGFzc05hbWUoeyB2YWx1ZTogcG9zdGZpeCB9KSk7XG59XG5cbmZ1bmN0aW9uIHJld3JpdGVTZWxlY3RvcihzZWwsIHBvc3RmaXgpIHtcbiAgY29uc3QgdHJhbnNmb3JtID0gKHNlbGVjdG9ycykgPT4ge1xuICAgIC8vIE5vZGVzIHRoYXQgbmVlZCB0aGUgcG9zdGZpeCBjbGFzcyBhZGRlZCBuZXh0IHRvIHRoZW0uIFdlIGNvbGxlY3QgdGhlbVxuICAgIC8vIGR1cmluZyB0aGUgd2FsayBhbmQgaW5zZXJ0IHRoZSBjbGFzc2VzIGFmdGVyd2FyZHMgc28gdGhlIGZyZXNobHktaW5zZXJ0ZWRcbiAgICAvLyBjbGFzc2VzIGFyZSBuZXZlciB0aGVtc2VsdmVzIHJlLXZpc2l0ZWQgYnkgdGhlIHdhbGsuXG4gICAgY29uc3QgbmVlZHNQb3N0Zml4Q2xhc3MgPSBbXTtcblxuICAgIHNlbGVjdG9ycy53YWxrKChzZWxlY3RvcikgPT4ge1xuICAgICAgaWYgKGlzSW5zaWRlR2xvYmFsKHNlbGVjdG9yKSkgcmV0dXJuO1xuXG4gICAgICAvLyBXZSBuZXZlciB3YW50IHRvIHRvdWNoIHBzdWVkbyBzZWxlY3RvcnMgc2luY2Ugd2UgYW5kIHRoZSB1c2VyIGRvZXNuJ3Qgb3duIHRoZW0uXG4gICAgICBpZiAoc2VsZWN0b3IudHlwZSA9PT0gJ3BzdWVkbycpIHJldHVybjtcblxuICAgICAgLy8gOm50aC1vZi10eXBlIGhhcyBzcGVjaWFsIHN5bnRheCB3aGVyZSB0aGUgdmFsdWVzIHBhc3NlZCB0byBudGgtb2YtdHlwZSgpXG4gICAgICAvLyBtdXN0IGVpdGhlciBiZSBleGFjdGx5IFwib2RkXCIsIFwiZXZlblwiLCBvciBhIHNpbXBsZSBmb3JtdWxhXG4gICAgICAvL1xuICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTLzpudGgtb2YtdHlwZVxuICAgICAgaWYgKGlzTnRoT2ZUeXBlKHNlbGVjdG9yKSkgcmV0dXJuO1xuXG4gICAgICBpZiAoc2VsZWN0b3IudHlwZSA9PT0gJ2NsYXNzJykge1xuICAgICAgICBzZWxlY3Rvci52YWx1ZSArPSAnXycgKyBwb3N0Zml4O1xuICAgICAgfSBlbHNlIGlmIChzZWxlY3Rvci50eXBlID09PSAndGFnJykge1xuICAgICAgICBuZWVkc1Bvc3RmaXhDbGFzcy5wdXNoKHNlbGVjdG9yKTtcbiAgICAgIH0gZWxzZSBpZiAoc2VsZWN0b3IudHlwZSA9PT0gJ2F0dHJpYnV0ZScpIHtcbiAgICAgICAgaWYgKGlzUmVuYW1lZENsYXNzQXR0cmlidXRlKHNlbGVjdG9yKSkge1xuICAgICAgICAgIC8vIFRoZSByZW5hbWVkIHRva2VuIChlLmcuIGBmb29fcG9zdGZpeGApIGlzIGFscmVhZHkgdW5pcXVlIHBlclxuICAgICAgICAgIC8vIGZpbGUsIHNvIG5vIHBvc3RmaXggY2xhc3MgaXMgbmVlZGVkLlxuICAgICAgICAgIHNlbGVjdG9yLnZhbHVlID0gcmVuYW1lQ2xhc3Moc2VsZWN0b3IudmFsdWUsIHBvc3RmaXgpO1xuICAgICAgICAgIGlmICghc2VsZWN0b3IucXVvdGVNYXJrKSBzZWxlY3Rvci5xdW90ZU1hcmsgPSAnXCInO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGBbY2xhc3N8PVwiZm9vXCJdYCBhbmQgYFtjbGFzcyQ9XCJmb29cIl1gIGNhbm5vdCBiZSByZWxpYWJseSBzY29wZWRcbiAgICAgICAgICAvLyB3aXRoIHRoZSBwb3N0Zml4IGNsYXNzICh0aGUgcG9zdGZpeCBjbGFzcyBkZWZlYXRzIHRoZW0pLiBUaGF0IGlzXG4gICAgICAgICAgLy8gc3VyZmFjZWQgdG8gYXV0aG9ycyBieSB0aGVcbiAgICAgICAgICAvLyBgZW1iZXItc2NvcGVkLWNzcy9uby11bnNjb3BhYmxlLWNsYXNzLWF0dHJpYnV0ZS1zZWxlY3RvcnNgXG4gICAgICAgICAgLy8gc3R5bGVsaW50IHJ1bGUgcmF0aGVyIHRoYW4gYSBydW50aW1lIHdhcm5pbmcuXG4gICAgICAgICAgbmVlZHNQb3N0Zml4Q2xhc3MucHVzaChzZWxlY3Rvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBuZWVkc1Bvc3RmaXhDbGFzcykge1xuICAgICAgYWRkUG9zdGZpeENsYXNzKG5vZGUsIHBvc3RmaXgpO1xuICAgIH1cblxuICAgIC8vIHJlbW92ZSA6Z2xvYmFsXG4gICAgc2VsZWN0b3JzLndhbGsoKHNlbGVjdG9yKSA9PiB7XG4gICAgICBpZiAoc2VsZWN0b3IudHlwZSA9PT0gJ3BzZXVkbycgJiYgc2VsZWN0b3IudmFsdWUgPT09ICc6Z2xvYmFsJykge1xuICAgICAgICBzZWxlY3Rvci5yZXBsYWNlV2l0aCguLi5zZWxlY3Rvci5ub2Rlcyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG4gIGNvbnN0IHRyYW5zZm9ybWVkID0gcGFyc2VyKHRyYW5zZm9ybSkucHJvY2Vzc1N5bmMoc2VsKTtcblxuICByZXR1cm4gdHJhbnNmb3JtZWQ7XG59XG5cbmZ1bmN0aW9uIGlzTnRoT2ZUeXBlKG5vZGUpIHtcbiAgaWYgKCFub2RlKSByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIG5vZGUucGFyZW50Py52YWx1ZSA9PT0gJzpudGgtb2YtdHlwZScgfHwgaXNOdGhPZlR5cGUobm9kZS5wYXJlbnQpO1xufVxuXG5mdW5jdGlvbiBpc0luc2lkZUtleWZyYW1lcyhub2RlKSB7XG4gIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50O1xuXG4gIGlmICghcGFyZW50KSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXJlbnQudHlwZSA9PT0gJ2F0cnVsZScgJiYgcGFyZW50Lm5hbWUgPT09ICdrZXlmcmFtZXMnKSByZXR1cm4gdHJ1ZTtcblxuICByZXR1cm4gaXNJbnNpZGVLZXlmcmFtZXMocGFyZW50KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJld3JpdGVDc3MoY3NzLCBwb3N0Zml4LCBmaWxlTmFtZSwgbGF5ZXJOYW1lKSB7XG4gIGNvbnN0IGFzdCA9IHBvc3Rjc3MucGFyc2UoY3NzKTtcbiAgLyoqXG4gICAqIGtpbmQgPT4gb3JpZ2luYWxOYW1lID0+IHBvc3RmaXhlZE5hbWVcbiAgICogQHR5cGUge3sgW2tpbmQ6IHN0cmluZ106IHsgW29yaWdpbmFsTmFtZTogc3RyaW5nXTogc3RyaW5nIH19fVxuICAgKi9cbiAgY29uc3QgcmVmZXJlbmNlYWJsZXMgPSB7XG4gICAga2V5ZnJhbWVzOiB7fSxcbiAgICAnY291bnRlci1zdHlsZSc6IHt9LFxuICAgICdwb3NpdGlvbi10cnknOiB7fSxcbiAgICBwcm9wZXJ0eToge30sXG4gIH07XG5cbiAgY29uc3QgYXZhaWxhYmxlUmVmZXJlbmNlYWJsZXMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKHJlZmVyZW5jZWFibGVzKSk7XG5cbiAgZnVuY3Rpb24gaXNSZWZlcmVuY2VhYmxlKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlICE9PSAnYXRydWxlJykgcmV0dXJuO1xuXG4gICAgcmV0dXJuIGF2YWlsYWJsZVJlZmVyZW5jZWFibGVzLmhhcyhub2RlLm5hbWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlRGlyZWN0UmVmZXJlbmNlcyhub2RlKSB7XG4gICAgaWYgKCFub2RlLnZhbHVlKSByZXR1cm47XG5cbiAgICBmb3IgKGxldCBbLCBtYXBdIG9mIE9iamVjdC5lbnRyaWVzKHJlZmVyZW5jZWFibGVzKSkge1xuICAgICAgaWYgKG1hcFtub2RlLnZhbHVlXSkge1xuICAgICAgICBub2RlLnZhbHVlID0gbWFwW25vZGUudmFsdWVdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVNob3J0aGFuZENvbnRlbnRzKG5vZGUpIHtcbiAgICBpZiAobm9kZS5wcm9wID09PSAnYW5pbWF0aW9uJykge1xuICAgICAgbGV0IHBhcnRzID0gbm9kZS52YWx1ZS5zcGxpdCgnICcpO1xuICAgICAgbGV0IG1hdGNoID0gcGFydHMuZmlsdGVyKCh4KSA9PiByZWZlcmVuY2VhYmxlcy5rZXlmcmFtZXNbeF0pO1xuXG4gICAgICBpZiAobWF0Y2gubGVuZ3RoKSB7XG4gICAgICAgIG1hdGNoLmZvckVhY2goKHgpID0+IHtcbiAgICAgICAgICBsZXQgcmVwbGFjZW1lbnQgPSByZWZlcmVuY2VhYmxlcy5rZXlmcmFtZXNbeF07XG5cbiAgICAgICAgICBpZiAoIXJlcGxhY2VtZW50KSByZXR1cm47XG5cbiAgICAgICAgICBub2RlLnZhbHVlID0gbm9kZS52YWx1ZS5yZXBsYWNlKHgsIHJlcGxhY2VtZW50KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgW2xvb2tGb3IsIHJlcGxhY2VXaXRoXSBvZiBPYmplY3QuZW50cmllcyhcbiAgICAgIHJlZmVyZW5jZWFibGVzLnByb3BlcnR5LFxuICAgICkpIHtcbiAgICAgIGxldCBsb29rRm9yVmFyID0gYHZhcigke2xvb2tGb3J9KWA7XG4gICAgICBsZXQgcmVwbGFjZVdpdGhWYXIgPSBgdmFyKCR7cmVwbGFjZVdpdGh9KWA7XG5cbiAgICAgIG5vZGUudmFsdWUgPSBub2RlLnZhbHVlLnJlcGxhY2UobG9va0ZvclZhciwgcmVwbGFjZVdpdGhWYXIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXZSBoYXZlIHRvIGRvIHR3byBwYXNzZXM6XG4gICAqIDEuIHBvc3RmaXggYWxsIHRoZSByZWZlcmVuY2VhYmxlIHN5bnRheFxuICAgKiAyLiBwb3N0Zml4IGFzIG5vcm1hbCwgYnV0IGFsc28gY2hlY2tpbmcgdmFsdWVzIG9mIENTUyBwcm9wZXJ0aWVzXG4gICAqICAgIHRoYXQgY291bGQgbWF0Y2ggcG9zdGZpeGVkIHJlZmVyZW5jZWFibGVzIGZyb20gc3RlcCAxXG4gICAqL1xuXG4gIC8vIFN0ZXAgMTogZmluZCByZWZlcmVuY2VhYmxlc1xuICBhc3Qud2Fsaygobm9kZSkgPT4ge1xuICAgIC8qKlxuICAgICAqIEBrZXlmcmFtZXMsIEBjb3VudGVyLXN0eWxlLCBldGNcbiAgICAgKi9cbiAgICBpZiAoaXNSZWZlcmVuY2VhYmxlKG5vZGUpKSB7XG4gICAgICBsZXQgbmFtZSA9IG5vZGUubmFtZTtcbiAgICAgIGxldCB7IG9yaWdpbmFsTmFtZSwgcG9zdGZpeGVkTmFtZSB9ID0gcmV3cml0ZVJlZmVyZW5jZWFibGUobm9kZSwgcG9zdGZpeCk7XG5cbiAgICAgIHJlZmVyZW5jZWFibGVzW25hbWVdW29yaWdpbmFsTmFtZV0gPSBwb3N0Zml4ZWROYW1lO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICB9KTtcblxuICAvLyBTdGVwIDI6IHBvc3RmaXggYW5kIHVwZGF0ZSByZWZlcmVuY2VkIHJlZmVyZW5jZWFibGVzXG4gIGFzdC53YWxrKChub2RlKSA9PiB7XG4gICAgaWYgKGlzRGVjbGFyYXRpb24obm9kZSkpIHtcbiAgICAgIHVwZGF0ZURpcmVjdFJlZmVyZW5jZXMobm9kZSk7XG4gICAgICB1cGRhdGVTaG9ydGhhbmRDb250ZW50cyhub2RlKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpc1J1bGUobm9kZSkpIHtcbiAgICAgIC8qKlxuICAgICAgICogVGhlIGlubmVyLWNvbnRlbnRzIG9mIGEga2V5ZnJhbWUgYXJlIHBlcmNlbnRhZ2VzLCByYXRoZXIgdGhhbiBzZWxlY3RvcnNcbiAgICAgICAqL1xuICAgICAgaWYgKGlzSW5zaWRlS2V5ZnJhbWVzKG5vZGUpKSByZXR1cm47XG5cbiAgICAgIG5vZGUuc2VsZWN0b3IgPSByZXdyaXRlU2VsZWN0b3Iobm9kZS5zZWxlY3RvciwgcG9zdGZpeCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IHJld3JpdHRlbkNzcyA9IGFzdC50b1N0cmluZygpO1xuXG4gIHJldHVybiAoXG4gICAgW1xuICAgICAgYC8qICR7ZmlsZU5hbWV9ICovYCxcbiAgICAgIGxheWVyTmFtZSA/IGBAbGF5ZXIgJHtsYXllck5hbWV9IHtgIDogJycsXG4gICAgICByZXdyaXR0ZW5Dc3MudHJpbUVuZCgpLFxuICAgICAgbGF5ZXJOYW1lID8gYH1gIDogJycsXG4gICAgXVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLmpvaW4oJ1xcbicpICsgJ1xcbidcbiAgKTtcbn1cbiIsImltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5cbmNvbnN0IEtFWSA9ICdlbWJlci1zY29wZWQuY3NzJztcbmNvbnN0IFNFUCA9ICdfX18nO1xuXG5leHBvcnQgY29uc3QgcmVxdWVzdCA9IHtcbiAgaXM6IHtcbiAgICBpbmxpbmUocmVxdWVzdCkge1xuICAgICAgcmV0dXJuIHJlcXVlc3QuaW5jbHVkZXMoS0VZKTtcbiAgICB9LFxuICAgIGNvbG9jYXRlZChyZXF1ZXN0KSB7XG4gICAgICByZXR1cm4gcmVxdWVzdC5pbmNsdWRlcygnLmNzcz9zY29wZWQ9Jyk7XG4gICAgfSxcbiAgfSxcbiAgaW5saW5lOiB7XG4gICAgLyoqXG4gICAgICogTWFrZXMgcmVxdWVzdCBVUkwgZm9yIGVtYmVkZGluZyBgPHN0eWxlPmAgYXMgYDxsaW5rPmAgaW50byB0aGUgYDxoZWFkPmBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjc3NIYXNoIHRoZSBoYXNoIG9mIHRoZSBDU1MgY29udGVudHNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zdGZpeCB0aGUgaGFzaCBvZiB0aGUgZmlsZSB0aGF0IF9pbmNsdWRlc18gdGhlIGxpbmtlZCBmaWxlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNzc0NvbnRlbnRzIHRoZSBjb250ZW50cyBvZiB0aGUgQ1NTIGZpbGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhbmddIG9wdGlvbmFsIHByZXByb2Nlc3NvciBsYW5ndWFnZSAoZS5nLiAnc2NzcycsICdzYXNzJywgJ2xlc3MnKVxuICAgICAqL1xuICAgIGNyZWF0ZShjc3NIYXNoLCBwb3N0Zml4LCBjc3NDb250ZW50cywgbGFuZykge1xuICAgICAgbGV0IHVybCA9IGAuLyR7cG9zdGZpeH0ke1NFUH0ke2Nzc0hhc2h9LiR7S0VZfT9jc3M9JHtlbmNvZGVVUklDb21wb25lbnQoY3NzQ29udGVudHMpfWA7XG5cbiAgICAgIGlmIChsYW5nKSB7XG4gICAgICAgIHVybCArPSBgJmxhbmc9JHtlbmNvZGVVUklDb21wb25lbnQobGFuZyl9YDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHVybDtcbiAgICB9LFxuICAgIGRlY29kZShyZXF1ZXN0KSB7XG4gICAgICBsZXQgW2xlZnQsIHFwc10gPSByZXF1ZXN0LnNwbGl0KCc/Jyk7XG5cbiAgICAgIGxlZnQgPSBsZWZ0LnNsaWNlKDIpLnJlcGxhY2UoYC4ke0tFWX1gLCAnJyk7XG5cbiAgICAgIGxldCBbcG9zdGZpeCwgaGFzaF0gPSBsZWZ0LnNwbGl0KFNFUCk7XG5cbiAgICAgIGxldCBzZWFyY2ggPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHFwcyk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGhhc2gsXG4gICAgICAgIHBvc3RmaXgsXG4gICAgICAgIGNzczogc2VhcmNoLmdldCgnY3NzJyksXG4gICAgICAgIGZyb206IHNlYXJjaC5nZXQoJ2Zyb20nKSxcbiAgICAgICAgbGFuZzogc2VhcmNoLmdldCgnbGFuZycpLFxuICAgICAgfTtcbiAgICB9LFxuICB9LFxuICBjb2xvY2F0ZWQ6IHtcbiAgICAvKipcbiAgICAgKiBNYWtlcyByZXF1ZXN0IFVSTCBmb3IgZW1iZWRkaW5nIHNlcGFyYXRlIENTUyBGaWxlIGFzIGA8bGluaz5gIGludG8gdGhlIGA8aGVhZD5gXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY3NzSGFzaCB0aGUgaGFzaCBvZiB0aGUgQ1NTIGNvbnRlbnRzXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBvc3RmaXggdGhlIGhhc2ggb2YgdGhlIGZpbGUgdGhhdCBfaW5jbHVkZXNfIHRoZSBsaW5rZWQgZmlsZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCBwYXRoIHRvIHRoZSBzZXBhcmF0ZSBDU1MgRmlsZVxuICAgICAqL1xuICAgIGNyZWF0ZShjc3NIYXNoLCBwb3N0Zml4LCBmaWxlUGF0aCkge1xuICAgICAgcmV0dXJuIGAuLyR7cGF0aC5iYXNlbmFtZShmaWxlUGF0aCl9P3Njb3BlZD0ke3Bvc3RmaXh9JmNzc0hhc2g9JHtjc3NIYXNofWA7XG4gICAgfSxcbiAgICBkZWNvZGUocmVxdWVzdCkge1xuICAgICAgY29uc3QgW2ZpbGVOYW1lLCBxc10gPSByZXF1ZXN0LnNwbGl0KCc/Jyk7XG4gICAgICBjb25zdCBzZWFyY2ggPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHFzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZmlsZU5hbWUsXG4gICAgICAgIGNzc0hhc2g6IHNlYXJjaC5nZXQoJ2Nzc0hhc2gnKSxcbiAgICAgICAgcG9zdGZpeDogc2VhcmNoLmdldCgnc2NvcGVkJyksXG4gICAgICB9O1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgeyBjcmVhdGVSZXF1aXJlIH0gZnJvbSAnbm9kZTptb2R1bGUnO1xuaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcblxuaW1wb3J0IHsgcmV3cml0ZUNzcyB9IGZyb20gJy4uL2xpYi9jc3MvcmV3cml0ZS5qcyc7XG5pbXBvcnQgeyByZXF1ZXN0IH0gZnJvbSAnLi4vbGliL3JlcXVlc3QuanMnO1xuXG5jb25zdCBNRVRBID0gJ3Njb3BlZC1jc3M6Y29sb2NhdGVkJztcblxuLyoqIEZpbGUgZXh0ZW5zaW9ucyB0aGF0IFZpdGUgY2FuIHByZXByb2Nlc3MgdmlhIGl0cyBDU1MgcHJlcHJvY2Vzc29yIHBpcGVsaW5lICovXG5jb25zdCBQUkVQUk9DRVNTRURfRVhURU5TSU9OUyA9IG5ldyBTZXQoW1xuICAnLnNjc3MnLFxuICAnLnNhc3MnLFxuICAnLmxlc3MnLFxuICAnLnN0eWwnLFxuICAnLnN0eWx1cycsXG5dKTtcblxuLyoqXG4gKiBQbHVnaW4gZm9yIHN1cHBvcnRpbmcgY29sb2NhdGVkIHN0eWxlc1xuICpcbiAqIGUuZy46XG4gKiAgc3JjL2NvbXBvbmVudHMvbXktY29tcG9uZW50LmpzXG4gKiAgc3JjL2NvbXBvbmVudHMvbXktY29tcG9uZW50LmNzc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY29sb2NhdGVkKG9wdGlvbnMgPSB7fSkge1xuICBjb25zdCBDV0QgPSBwcm9jZXNzLmN3ZCgpO1xuXG4gIC8qKiBAdHlwZSB7aW1wb3J0KCd2aXRlJykuUmVzb2x2ZWRDb25maWcgfCB1bmRlZmluZWR9ICovXG4gIGxldCB2aXRlQ29uZmlnO1xuXG4gIC8qKiBAdHlwZSB7KChjb2RlOiBzdHJpbmcsIGZpbGVuYW1lOiBzdHJpbmcsIGNvbmZpZzogdW5rbm93bikgPT4gUHJvbWlzZTx7IGNvZGU6IHN0cmluZyB9PikgfCB1bmRlZmluZWR9ICovXG4gIGxldCBwcmVwcm9jZXNzQ1NTO1xuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgdGhlIHJlcXVlc3QgaWQgLyB3aGF0IHdhcyBpbXBvcnRlZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGggIHBhdGggb24gZGlza1xuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgZnVuY3Rpb24gYnVpbGRSZXNwb25zZShpZCwgZmlsZVBhdGgpIHtcbiAgICBjb25zdCBwYXJzZWQgPSByZXF1ZXN0LmNvbG9jYXRlZC5kZWNvZGUoaWQpO1xuICAgIGNvbnN0IHJlbGF0aXZlRmlsZVBhdGggPSBwYXRoLnJlbGF0aXZlKENXRCwgZmlsZVBhdGgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBmaWxlUGF0aCxcbiAgICAgIG1ldGE6IHtcbiAgICAgICAgW01FVEFdOiB7XG4gICAgICAgICAgcG9zdGZpeDogcGFyc2VkLnBvc3RmaXgsXG4gICAgICAgICAgZmlsZU5hbWU6IHJlbGF0aXZlRmlsZVBhdGgsXG4gICAgICAgICAgZnVsbFBhdGg6IGZpbGVQYXRoLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnZW1iZXItc2NvcGVkLWNzczpjb2xvY2F0ZWQnLFxuICAgIHJlc29sdmVJZChpZCwgaW1wb3J0ZXIpIHtcbiAgICAgIC8vIGhhbmRsZXM6IHNvbWUtZmlsZS5jc3M/c2NvcGVkPVtwb3N0Zml4XVxuICAgICAgLy8gdGhpcyBpcyBvbmx5IHJ1biBpbiByb2xsdXAsIHZpdGUgaGFuZGxlcyBpdCBkaWZmZXJlbnRseVxuICAgICAgaWYgKHJlcXVlc3QuaXMuY29sb2NhdGVkKGlkKSkge1xuICAgICAgICBjb25zdCBwYXJzZWQgPSByZXF1ZXN0LmNvbG9jYXRlZC5kZWNvZGUoaWQpO1xuXG4gICAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKFxuICAgICAgICAgIHBhdGguZGlybmFtZShpbXBvcnRlciksXG4gICAgICAgICAgcGF0aC5iYXNlbmFtZShwYXJzZWQuZmlsZU5hbWUpLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiBidWlsZFJlc3BvbnNlKGlkLCBmaWxlUGF0aCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBsb2FkKGlkKSB7XG4gICAgICBjb25zdCBtZXRhID0gdGhpcy5nZXRNb2R1bGVJbmZvKGlkKT8ubWV0YT8uW01FVEFdO1xuXG4gICAgICBpZiAobWV0YSkge1xuICAgICAgICB0aGlzLmFkZFdhdGNoRmlsZShtZXRhLmZ1bGxQYXRoKTtcblxuICAgICAgICBsZXQgY29kZSA9IHJlYWRGaWxlU3luYyhtZXRhLmZ1bGxQYXRoLCAndXRmLTgnKTtcblxuICAgICAgICBsZXQgY3NzID0gcmV3cml0ZUNzcyhcbiAgICAgICAgICBjb2RlLFxuICAgICAgICAgIG1ldGEucG9zdGZpeCxcbiAgICAgICAgICBtZXRhLmZpbGVOYW1lLFxuICAgICAgICAgIG9wdGlvbnMubGF5ZXJOYW1lLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiBjc3M7XG4gICAgICB9XG4gICAgfSxcbiAgICB2aXRlOiB7XG4gICAgICBhc3luYyBjb25maWdSZXNvbHZlZChjb25maWcpIHtcbiAgICAgICAgdml0ZUNvbmZpZyA9IGNvbmZpZztcblxuICAgICAgICAvLyBSZXNvbHZlIFZpdGUncyBwcmVwcm9jZXNzQ1NTIGZyb20gdGhlIGFwcCByb290IHRvIGVuc3VyZSB3ZSBmaW5kXG4gICAgICAgIC8vIHRoZSBjb3JyZWN0IFZpdGUgaW5zdGFsbGF0aW9uIChub3QgYSBzdGFsZSBvciBtaXNzaW5nIG9uZSkuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVxdWlyZSA9IGNyZWF0ZVJlcXVpcmUocGF0aC5qb2luKGNvbmZpZy5yb290LCAncGFja2FnZS5qc29uJykpO1xuICAgICAgICAgIGNvbnN0IHZpdGVQYXRoID0gcmVxdWlyZS5yZXNvbHZlKCd2aXRlJyk7XG4gICAgICAgICAgY29uc3Qgdml0ZU1vZHVsZSA9IGF3YWl0IGltcG9ydCh2aXRlUGF0aCk7XG5cbiAgICAgICAgICBwcmVwcm9jZXNzQ1NTID0gdml0ZU1vZHVsZS5wcmVwcm9jZXNzQ1NTO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAvLyBWaXRlIG1heSBub3QgYmUgcmVzb2x2YWJsZSBmcm9tIHRoZSBjb25maWcgcm9vdCBpbiBzb21lIHNldHVwcztcbiAgICAgICAgICAvLyBwcmVwcm9jZXNzb3Igc3VwcG9ydCBmb3IgY29sb2NhdGVkIC5zY3NzIGZpbGVzIHdpbGwgdGhyb3cgYSBjbGVhclxuICAgICAgICAgIC8vIGVycm9yIGF0IGxvYWQgdGltZSBpZiB1c2VkLlxuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFRoZXJlIG1heSBub3QgYmUgbWV0YSBmb3IgdGhpcyByZXF1ZXN0IHlldC5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0geyp9IGlkXG4gICAgICAgKi9cbiAgICAgIGFzeW5jIGxvYWQoaWQpIHtcbiAgICAgICAgaWYgKHJlcXVlc3QuaXMuY29sb2NhdGVkKGlkKSkge1xuICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHJlcXVlc3QuY29sb2NhdGVkLmRlY29kZShpZCk7XG5cbiAgICAgICAgICBsZXQgY29kZSA9IHJlYWRGaWxlU3luYyhwYXJzZWQuZmlsZU5hbWUsICd1dGYtOCcpO1xuICAgICAgICAgIGxldCByZWxhdGl2ZUZpbGVQYXRoID0gcGF0aC5yZWxhdGl2ZShDV0QsIHBhcnNlZC5maWxlTmFtZSk7XG5cbiAgICAgICAgICBjb25zdCBleHQgPSBwYXRoLmV4dG5hbWUocGFyc2VkLmZpbGVOYW1lKS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICAgICAgaWYgKFBSRVBST0NFU1NFRF9FWFRFTlNJT05TLmhhcyhleHQpKSB7XG4gICAgICAgICAgICBpZiAoIXZpdGVDb25maWcgfHwgIXByZXByb2Nlc3NDU1MpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIGBbZW1iZXItc2NvcGVkLWNzc10gQ29sb2NhdGVkIENTUyBmaWxlIHdpdGggZXh0ZW5zaW9uICcke2V4dH0nIHJlcXVpcmVzIFZpdGUuIGAgK1xuICAgICAgICAgICAgICAgICAgYENTUyBwcmVwcm9jZXNzaW5nIGlzIG9ubHkgc3VwcG9ydGVkIGluIFZpdGUgYnVpbGRzLmAsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByZXByb2Nlc3NDU1MoXG4gICAgICAgICAgICAgIGNvZGUsXG4gICAgICAgICAgICAgIHBhcnNlZC5maWxlTmFtZSxcbiAgICAgICAgICAgICAgdml0ZUNvbmZpZyxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvZGUgPSByZXN1bHQuY29kZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsZXQgY3NzID0gcmV3cml0ZUNzcyhcbiAgICAgICAgICAgIGNvZGUsXG4gICAgICAgICAgICBwYXJzZWQucG9zdGZpeCxcbiAgICAgICAgICAgIHJlbGF0aXZlRmlsZVBhdGgsXG4gICAgICAgICAgICBvcHRpb25zLmxheWVyTmFtZSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIGNzcztcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICB9O1xufVxuIiwiaW1wb3J0IHsgY3JlYXRlUmVxdWlyZSB9IGZyb20gJ25vZGU6bW9kdWxlJztcbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB7IHJld3JpdGVDc3MgfSBmcm9tICcuLi9saWIvY3NzL3Jld3JpdGUuanMnO1xuaW1wb3J0IHsgcmVxdWVzdCB9IGZyb20gJy4uL2xpYi9yZXF1ZXN0LmpzJztcblxuY29uc3QgTUVUQSA9ICdzY29wZWQtY3NzOmlubGluZSc7XG5cbi8qKlxuICogUGx1Z2luIGZvciBzdXBwb3J0aW5nIHRoZSBzdHlsZXMgZnJvbVxuICpcbiAqIDx0ZW1wbGF0ZT5cbiAqICAgPHN0eWxlPi4uLjwvc3R5bGU+XG4gKiA8L3RlbXBsYXRlPlxuICpcbiAqIFRoaXMgcGx1Z2luIGNhbid0IGhhdmUgSE1SIGZvciBDU1MgYmVjYXVzZSBjaGFuZ2VzIHRvIHRoZSBDU1MgY29udGVudCBhbHRlcnMgdGhlIHRlbXBsYXRlIGNvbnRlbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlubGluZShvcHRpb25zID0ge30pIHtcbiAgY29uc3QgQ1dEID0gcHJvY2Vzcy5jd2QoKTtcblxuICAvKiogQHR5cGUge2ltcG9ydCgndml0ZScpLlJlc29sdmVkQ29uZmlnIHwgdW5kZWZpbmVkfSAqL1xuICBsZXQgdml0ZUNvbmZpZztcblxuICAvKiogQHR5cGUgeygoY29kZTogc3RyaW5nLCBmaWxlbmFtZTogc3RyaW5nLCBjb25maWc6IHVua25vd24pID0+IFByb21pc2U8eyBjb2RlOiBzdHJpbmcgfT4pIHwgdW5kZWZpbmVkfSAqL1xuICBsZXQgcHJlcHJvY2Vzc0NTUztcblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGlkIHRoZSByZXF1ZXN0IGlkIC8gd2hhdCB3YXMgaW1wb3J0ZWRcbiAgICovXG4gIGZ1bmN0aW9uIGJ1aWxkUmVzcG9uc2UoaWQsIGZpbGVQYXRoKSB7XG4gICAgY29uc3QgcGFyc2VkID0gcmVxdWVzdC5pbmxpbmUuZGVjb2RlKGlkKTtcblxuICAgIGNvbnN0IHJlbGF0aXZlRmlsZVBhdGggPSBwYXRoLnJlbGF0aXZlKENXRCwgZmlsZVBhdGgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBmaWxlUGF0aC5zcGxpdCgnPycpWzBdLFxuICAgICAgbWV0YToge1xuICAgICAgICBbTUVUQV06IHtcbiAgICAgICAgICByYXdDc3M6IHBhcnNlZC5jc3MsXG4gICAgICAgICAgcG9zdGZpeDogcGFyc2VkLnBvc3RmaXgsXG4gICAgICAgICAgZmlsZU5hbWU6IHJlbGF0aXZlRmlsZVBhdGgsXG4gICAgICAgICAgbGFuZzogcGFyc2VkLmxhbmcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdlbWJlci1zY29wZWQtY3NzOmlubGluZScsXG4gICAgcmVzb2x2ZUlkKGlkLCBpbXBvcnRlcikge1xuICAgICAgaWYgKHJlcXVlc3QuaXMuaW5saW5lKGlkKSkge1xuICAgICAgICBjb25zdCBwYXJzZWQgPSByZXF1ZXN0LmlubGluZS5kZWNvZGUoaWQpO1xuXG4gICAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKFxuICAgICAgICAgIHBhdGguZGlybmFtZShpbXBvcnRlciksXG4gICAgICAgICAgYCR7cGF0aC5iYXNlbmFtZShpbXBvcnRlciwgcGF0aC5leHRuYW1lKGltcG9ydGVyKSl9LSR7cGFyc2VkLmhhc2h9LmNzc2AsXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIGJ1aWxkUmVzcG9uc2UoaWQsIGZpbGVQYXRoKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGFzeW5jIGxvYWQoaWQpIHtcbiAgICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldE1vZHVsZUluZm8oaWQpPy5tZXRhPy5bTUVUQV07XG5cbiAgICAgIGlmIChtZXRhKSB7XG4gICAgICAgIGxldCByYXdDc3MgPSBtZXRhLnJhd0NzcztcblxuICAgICAgICBpZiAobWV0YS5sYW5nKSB7XG4gICAgICAgICAgaWYgKCF2aXRlQ29uZmlnIHx8ICFwcmVwcm9jZXNzQ1NTKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgIGBbZW1iZXItc2NvcGVkLWNzc10gPHN0eWxlIHNjb3BlZCBsYW5nPVwiJHttZXRhLmxhbmd9XCI+IHJlcXVpcmVzIFZpdGUuIGAgK1xuICAgICAgICAgICAgICAgIGBDU1MgcHJlcHJvY2Vzc2luZyB2aWEgdGhlICdsYW5nJyBhdHRyaWJ1dGUgaXMgb25seSBzdXBwb3J0ZWQgaW4gVml0ZSBidWlsZHMuYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZmFrZUZpbGVuYW1lID0gYCR7bWV0YS5maWxlTmFtZX0uJHttZXRhLmxhbmd9YDtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcmVwcm9jZXNzQ1NTKHJhd0NzcywgZmFrZUZpbGVuYW1lLCB2aXRlQ29uZmlnKTtcblxuICAgICAgICAgIHJhd0NzcyA9IHJlc3VsdC5jb2RlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY3NzID0gcmV3cml0ZUNzcyhcbiAgICAgICAgICByYXdDc3MsXG4gICAgICAgICAgbWV0YS5wb3N0Zml4LFxuICAgICAgICAgIGA8aW5saW5lPi8ke21ldGEuZmlsZU5hbWV9YCxcbiAgICAgICAgICBvcHRpb25zLmxheWVyTmFtZSxcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gY3NzO1xuICAgICAgfVxuICAgIH0sXG4gICAgdml0ZToge1xuICAgICAgYXN5bmMgY29uZmlnUmVzb2x2ZWQoY29uZmlnKSB7XG4gICAgICAgIHZpdGVDb25maWcgPSBjb25maWc7XG5cbiAgICAgICAgLy8gUmVzb2x2ZSBWaXRlJ3MgcHJlcHJvY2Vzc0NTUyBmcm9tIHRoZSBhcHAgcm9vdCB0byBlbnN1cmUgd2UgZmluZFxuICAgICAgICAvLyB0aGUgY29ycmVjdCBWaXRlIGluc3RhbGxhdGlvbiAobm90IGEgc3RhbGUgb3IgbWlzc2luZyBvbmUpLlxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlcXVpcmUgPSBjcmVhdGVSZXF1aXJlKHBhdGguam9pbihjb25maWcucm9vdCwgJ3BhY2thZ2UuanNvbicpKTtcbiAgICAgICAgICBjb25zdCB2aXRlUGF0aCA9IHJlcXVpcmUucmVzb2x2ZSgndml0ZScpO1xuICAgICAgICAgIGNvbnN0IHZpdGVNb2R1bGUgPSBhd2FpdCBpbXBvcnQodml0ZVBhdGgpO1xuXG4gICAgICAgICAgcHJlcHJvY2Vzc0NTUyA9IHZpdGVNb2R1bGUucHJlcHJvY2Vzc0NTUztcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLy8gVml0ZSBtYXkgbm90IGJlIHJlc29sdmFibGUgZnJvbSB0aGUgY29uZmlnIHJvb3QgaW4gc29tZSBzZXR1cHM7XG4gICAgICAgICAgLy8gbGFuZz0gc3VwcG9ydCB3aWxsIHRocm93IGEgY2xlYXIgZXJyb3IgYXQgbG9hZCB0aW1lIGlmIHVzZWQuXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbn1cbiIsImltcG9ydCB7IGNyZWF0ZVVucGx1Z2luIH0gZnJvbSAndW5wbHVnaW4nO1xuXG5pbXBvcnQgeyBjb2xvY2F0ZWQgfSBmcm9tICcuL3VucGx1Z2luLWNvbG9jYXRlZC5qcyc7XG5pbXBvcnQgeyBpbmxpbmUgfSBmcm9tICcuL3VucGx1Z2luLWlubGluZS5qcyc7XG5cbi8qKlxuICogVGhlIHBsdWdpbiB0aGF0IGhhbmRsZXMgQ1NTIHJlcXVlc3RzIGZvciBgPHN0eWxlPmAgZWxlbWVudHMgYW5kIHRyYW5zZm9ybXNcbiAqIGZvciBleGlzdGluZyBmaWxlc1xuICpcbiAqIHZpdGU6IENTUyBmaWxlcyBhcmUgcmVzb2x2ZWQgYnkgdml0ZS4gV2UgdXNlIHRoZWlyIHJlc29sdmVyIHRvIGFsc28gZ2V0XG4gKiAgICAgICBITVIuIFRoYXQgaXMsIGZvciBhbGwgbm9uLXBoeXNpY2FsIENTUyBmaWxlcywgd2UgZXh0ZW5kIHZpdGUgYnkgb3VyXG4gKiAgICAgICByZXNvbHZlciBhbmQgYWxzbyBjYW4gZW5yaWNoIG1ldGFkYXRhIHRvIGl0IChmb3IgYmV0dGVyIGRlYnVnZ2luZylcbiAqL1xuZXhwb3J0IGNvbnN0IHVucGx1Z2luID0gY3JlYXRlVW5wbHVnaW4oKG9wdGlvbnMgPSB7fSkgPT4ge1xuICByZXR1cm4gW2NvbG9jYXRlZChvcHRpb25zKSwgaW5saW5lKG9wdGlvbnMpXTtcbn0pO1xuIiwiaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcblxuaW1wb3J0IHsgbGVhZGluZ1NsYXNoUGF0aCB9IGZyb20gJy4vY29uc3QuanMnO1xuaW1wb3J0IHsgZmluZFdvcmtzcGFjZVBhdGggfSBmcm9tICcuL3V0aWxzLmpzJztcblxuLyoqXG4gKiB0ZW1wbGF0ZSBwbHVnaW5zIGRvIG5vdCBoYW5kIHVzIHRoZSBjb3JyZWN0IGZpbGUgcGF0aC5cbiAqIGFkZGl0aW9uYWxseSwgd2UgbWF5IG5vdCBiZSBhYmxlIHRvIHJlbHkgb24gdGhpcyBkYXRhIGluIHRoZSBmdXR1cmUsXG4gKiBzbyB0aGlzIGZ1bmN0aW9ucyBhY3RzIGFzIGEgbWVhbnMgb2Ygbm9ybWFsaXppbmcgX3doYXRldmVyXyB3ZSdyZSBnaXZlblxuICogaW4gdGhlIGZ1dHVyZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBmaWxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaXhGaWxlbmFtZShmaWxlbmFtZSkge1xuICBsZXQgZmlsZU5hbWUgPSBmaWxlbmFtZTtcbiAgbGV0IHdvcmtzcGFjZSA9IGZpbmRXb3Jrc3BhY2VQYXRoKGZpbGVOYW1lKTtcblxuICAvKipcbiAgICogZW1iZXItc291cmNlIDUuODpcbiAgICogLSB0aGUgZmlsZW5hbWUgbG9va3MgbGlrZSBhbiBhYnNvbHV0ZSBwYXRoLCBidXQgc3dhcHBlZCBvdXQgdGhlICdhcHAnIHBhcnQgb2YgdGhlIHBhdGhcbiAgICogICB3aXRoIHRoZSBtb2R1bGUgbmFtZSwgc28gdGhlIGZpbGUgcGF0aHMgbmV2ZXIgZXhpc3Qgb24gZGlza1xuICAgKlxuICAgKiAtIGluIHZpdGUgYXBwczpcbiAgICogICB0aGUgJ2FwcCcgcGFydCBfbWF5XyBiZSBgc3JjYCwgc28gd2UgYWxzbyBuZWVkIHRvIGVuc3VyZSB0aGF0IGBzcmNgIGlzIGV4Y2x1ZGVkIGFzIHdlbGxcbiAgICovXG4gIGxldCBoYXNBcHBEaXIgPSBmaWxlTmFtZS5pbmNsdWRlcyhwYXRoLmpvaW4od29ya3NwYWNlLCAnYXBwJykpO1xuICBsZXQgaGFzU3JjRGlyID0gZmlsZU5hbWUuaW5jbHVkZXMocGF0aC5qb2luKHdvcmtzcGFjZSwgJ3NyYycpKTtcblxuICBpZiAoXG4gICAgIShoYXNBcHBEaXIgfHwgaGFzU3JjRGlyKSAmJlxuICAgICFmaWxlTmFtZS5pbmNsdWRlcyhsZWFkaW5nU2xhc2hQYXRoLmVtYnJvaWRlckRpcilcbiAgKSB7XG4gICAgbGV0IG1heWJlTW9kdWxlID0gZmlsZU5hbWUucmVwbGFjZSh3b3Jrc3BhY2UsICcnKTtcbiAgICBsZXQgW21heWJlU2NvcGUsIC4uLnJlc3RdID0gbWF5YmVNb2R1bGUuc3BsaXQocGF0aC5zZXApLmZpbHRlcihCb29sZWFuKTtcbiAgICBsZXQgcGFydHMgPSByZXN0O1xuXG4gICAgaWYgKG1heWJlU2NvcGUuc3RhcnRzV2l0aCgnQCcpKSB7XG4gICAgICBsZXQgWywgLi4ucmVzdGVyXSA9IHJlc3Q7XG5cbiAgICAgIHBhcnRzID0gcmVzdGVyO1xuICAgIH1cblxuICAgIGxldCByZWxhdGl2ZSA9IHBhdGguam9pbiguLi5wYXJ0cyk7XG5cbiAgICAvKipcbiAgICAgKiBXZSBkb24ndCBhY3R1YWxseSBrbm93IGlmIHRoaXMgZmlsZSBpcyBhbiBhcHAuXG4gICAgICogaXQgY291bGQgYmUgYW4gYWRkb24gKHYxIG9yIHYyKVxuICAgICAqXG4gICAgICogU28gaGVyZSB3ZSBsb2cgdG8gc2VlIGlmIHdlIGhhdmUgdW5oYW5kbGVkIHNpdHVhdGlvbnMuXG4gICAgICovXG4gICAgbGV0IGNhbmRpZGF0ZVBhdGggPSBwYXRoLmpvaW4od29ya3NwYWNlLCAnYXBwJywgcmVsYXRpdmUpO1xuXG4gICAgcmV0dXJuIGNhbmRpZGF0ZVBhdGg7XG4gIH1cblxuICAvLyBUT0RPOiB3aHkgYXJlIHdlIHBhc3NlZCBmaWxlcyB0byBvdGhlciBwcm9qZWN0cz9cbiAgaWYgKCFmaWxlTmFtZS5pbmNsdWRlcyh3b3Jrc3BhY2UpKSB7XG4gICAgcmV0dXJuIGZpbGVOYW1lO1xuICB9XG5cbiAgLy8gRmFsbGJhY2sgdG8gd2hhdCB0aGUgcGx1Z2luIHN5c3RlbSBnaXZlcyB1cy5cbiAgLy8gVGhpcyBtYXkgYmUgd3JvbmcsIGFuZCBpZiB3cm9uZywgcmV2ZWFsc1xuICAvLyB1bmhhbmRsZWQgc2NlbmFyaW9zIHdpdGggdGhlIGZpbGUgbmFtZXMgaW4gdGhlIHBsdWdpbiBpbmZyYVxuICByZXR1cm4gZmlsZU5hbWU7XG59XG4iLCJpbXBvcnQgKiBhcyByZWNhc3QgZnJvbSAnZW1iZXItdGVtcGxhdGUtcmVjYXN0JztcblxuaW1wb3J0IHsgcmVuYW1lQ2xhc3MgfSBmcm9tICcuL3JlbmFtZUNsYXNzLmpzJztcblxuLyoqXG4gKiBXaGV0aGVyIGFuIGVsZW1lbnQgbWF5IGNhcnJ5IGFuIGF0dHJpYnV0ZSB0aGF0IGFwcGVhcnMgaW4gYSBzY29wZWRcbiAqIGF0dHJpYnV0ZSBzZWxlY3Rvci4gVGhpcyBpbmNsdWRlcyBjb21wb25lbnQgaW52b2NhdGlvbnM6IGEgY29tcG9uZW50XG4gKiByZWNlaXZlcyB0aGUgcG9zdGZpeCBjbGFzcyB0aHJvdWdoIGl0cyBgLi4uYXR0cmlidXRlc2AgdGhlIHNhbWUgd2F5IGl0XG4gKiByZWNlaXZlcyB0aGUgbWF0Y2hlZCBhdHRyaWJ1dGUsIHNvIGBbdHlwZT1cInRleHRcIl1gIHNjb3Blc1xuICogYDxGb28gdHlwZT1cInRleHRcIj5gIGp1c3QgYXMgaXQgc2NvcGVzIGA8aW5wdXQgdHlwZT1cInRleHRcIj5gLlxuICpcbiAqIEFuIGVsZW1lbnQgdGhhdCBzcHJlYWRzIGAuLi5hdHRyaWJ1dGVzYCBjYW4gcmVjZWl2ZSBhbnkgYXR0cmlidXRlIGZyb20gaXRzXG4gKiBjYWxsZXIgYXQgcnVudGltZSwgc28gaXQgY291bnRzIGFzIGxvbmcgYXMgdGhlIENTUyBzY29wZXMgYnkgYXR0cmlidXRlIGF0XG4gKiBhbGwg4oCUIHRoZSBwcmVzZXJ2ZWQgYXR0cmlidXRlIHNlbGVjdG9yIHN0aWxsIGRlY2lkZXMgd2hpY2ggcnVsZXMgYWN0dWFsbHlcbiAqIGFwcGx5LlxuICpcbiAqIGBhdHRyaWJ1dGVzYCBjb21lcyBmcm9tIHBhcnNpbmcgdGhlIENTUywgc28gaXQgY2FuIG9ubHkgY29udGFpbiB2YWxpZFxuICogYXR0cmlidXRlLXNlbGVjdG9yIG5hbWVzIOKAlCBgQGFyZ3NgIGNhbiBuZXZlciBiZSBpbiBpdCBhbmQgbmVlZHMgbm8gc3BlY2lhbFxuICogaGFuZGxpbmcuXG4gKlxuICogTmFtZXMgaW4gYGF0dHJpYnV0ZXNgIGFyZSBsb3dlcmNhc2VkIGF0IGRpc2NvdmVyeSAoQ1NTIG1hdGNoZXMgSFRNTFxuICogYXR0cmlidXRlIG5hbWVzIGNhc2UtaW5zZW5zaXRpdmVseSksIHNvIGNvbXBhcmUgbG93ZXJjYXNlZC5cbiAqL1xuZnVuY3Rpb24gZWxlbWVudEhhc1Njb3BlZEF0dHJpYnV0ZShub2RlLCBhdHRyaWJ1dGVzKSB7XG4gIGlmIChhdHRyaWJ1dGVzLnNpemUgPT09IDApIHJldHVybiBmYWxzZTtcblxuICByZXR1cm4gbm9kZS5hdHRyaWJ1dGVzLnNvbWUoXG4gICAgKGF0dHIpID0+XG4gICAgICBhdHRyLm5hbWUgPT09ICcuLi5hdHRyaWJ1dGVzJyB8fCBhdHRyaWJ1dGVzLmhhcyhhdHRyLm5hbWUudG9Mb3dlckNhc2UoKSksXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0ZW1wbGF0ZVBsdWdpbih7IGNsYXNzZXMsIHRhZ3MsIGF0dHJpYnV0ZXMsIHBvc3RmaXggfSkge1xuICBsZXQgc3RhY2sgPSBbXTtcbiAgLy8gc2NvcGVkLWNsYXNzIGlzIGEgZ2xvYmFsIHdlIGFsbG93IGluIGhic1xuICAvLyBzY29wZWRDbGFzcyBpcyBpbXBvcnRhYmxlLCBhbmQgd2UnbGwgZXJyb3IgaWYgc29tZW9uZSB0cmllcyB0byByZW5hbWUgaXRcbiAgbGV0IHNjb3BlZENsYXNzQ2FuZGlkYXRlcyA9IFsnc2NvcGVkLWNsYXNzJywgJ3Njb3BlZENsYXNzJ107XG5cbiAgZnVuY3Rpb24gaXNTY29wZWRDbGFzcyhzdHIpIHtcbiAgICBpZiAoIXN0cikgcmV0dXJuIGZhbHNlO1xuXG4gICAgcmV0dXJuIHNjb3BlZENsYXNzQ2FuZGlkYXRlcy5zb21lKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZSA9PT0gc3RyKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgQXR0ck5vZGUobm9kZSkge1xuICAgICAgaWYgKG5vZGUubmFtZSA9PT0gJ2NsYXNzJykge1xuICAgICAgICBpZiAobm9kZS52YWx1ZS50eXBlID09PSAnVGV4dE5vZGUnICYmIG5vZGUudmFsdWUuY2hhcnMpIHtcbiAgICAgICAgICBjb25zdCByZW5hbWVkQ2xhc3MgPSByZW5hbWVDbGFzcyhub2RlLnZhbHVlLmNoYXJzLCBwb3N0Zml4LCBjbGFzc2VzKTtcblxuICAgICAgICAgIG5vZGUudmFsdWUuY2hhcnMgPSByZW5hbWVkQ2xhc3M7XG4gICAgICAgIH0gZWxzZSBpZiAobm9kZS52YWx1ZS50eXBlID09PSAnQ29uY2F0U3RhdGVtZW50Jykge1xuICAgICAgICAgIGZvciAobGV0IHBhcnQgb2Ygbm9kZS52YWx1ZS5wYXJ0cykge1xuICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gJ1RleHROb2RlJyAmJiBwYXJ0LmNoYXJzKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlbmFtZWRDbGFzcyA9IHJlbmFtZUNsYXNzKHBhcnQuY2hhcnMsIHBvc3RmaXgsIGNsYXNzZXMpO1xuXG4gICAgICAgICAgICAgIHBhcnQuY2hhcnMgPSByZW5hbWVkQ2xhc3M7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gJ011c3RhY2hlU3RhdGVtZW50Jykge1xuICAgICAgICAgICAgICByZWNhc3QudHJhdmVyc2UocGFydCwge1xuICAgICAgICAgICAgICAgIFN0cmluZ0xpdGVyYWwobm9kZSkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVuYW1lZENsYXNzID0gcmVuYW1lQ2xhc3MoXG4gICAgICAgICAgICAgICAgICAgIG5vZGUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBvc3RmaXgsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzZXMsXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICBub2RlLnZhbHVlID0gcmVuYW1lZENsYXNzO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBFbGVtZW50Tm9kZShub2RlKSB7XG4gICAgICAvLyBBbiBlbGVtZW50IGlzIGluIHNjb3BlIGlmIGl0cyB0YWcgbWF0Y2hlcyBhIHRhZyBzZWxlY3Rvciwgb3IgaWYgaXRcbiAgICAgIC8vIGNhcnJpZXMgYW4gYXR0cmlidXRlIG5hbWVkIGluIGEgc2NvcGVkIGF0dHJpYnV0ZSBzZWxlY3Rvci4gV2UgYWRkIHRoZVxuICAgICAgLy8gcG9zdGZpeCBjbGFzcyBhdCBtb3N0IG9uY2UgcmVnYXJkbGVzcyBvZiBob3cgbWFueSB0aGluZ3MgbWF0Y2hlZC5cbiAgICAgIGNvbnN0IHNob3VsZFNjb3BlID1cbiAgICAgICAgdGFncy5oYXMobm9kZS50YWcpIHx8IGVsZW1lbnRIYXNTY29wZWRBdHRyaWJ1dGUobm9kZSwgYXR0cmlidXRlcyk7XG5cbiAgICAgIGlmICghc2hvdWxkU2NvcGUpIHJldHVybjtcblxuICAgICAgLy8gY2hlY2sgaWYgY2xhc3MgYXR0cmlidXRlIGFscmVhZHkgZXhpc3RzXG4gICAgICBjb25zdCBjbGFzc0F0dHIgPSBub2RlLmF0dHJpYnV0ZXMuZmluZCgoYXR0cikgPT4gYXR0ci5uYW1lID09PSAnY2xhc3MnKTtcblxuICAgICAgaWYgKCFjbGFzc0F0dHIpIHtcbiAgICAgICAgLy8gcHVzaCBjbGFzcyBhdHRyaWJ1dGVcbiAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnB1c2goXG4gICAgICAgICAgcmVjYXN0LmJ1aWxkZXJzLmF0dHIoJ2NsYXNzJywgcmVjYXN0LmJ1aWxkZXJzLnRleHQocG9zdGZpeCkpLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChjbGFzc0F0dHIudmFsdWUudHlwZSA9PT0gJ1RleHROb2RlJykge1xuICAgICAgICBjbGFzc0F0dHIudmFsdWUuY2hhcnMgKz0gJyAnICsgcG9zdGZpeDtcbiAgICAgIH0gZWxzZSBpZiAoY2xhc3NBdHRyLnZhbHVlLnR5cGUgPT09ICdDb25jYXRTdGF0ZW1lbnQnKSB7XG4gICAgICAgIC8vIGNsYXNzPVwiZm9vIHt7YmFyfX1cIlxuICAgICAgICBjbGFzc0F0dHIudmFsdWUucGFydHMucHVzaChyZWNhc3QuYnVpbGRlcnMudGV4dCgnICcgKyBwb3N0Zml4KSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBjbGFzcz17e3RoaXMuZm9vfX0g4oCUIHdyYXAgaW4gYSBjb25jYXQgc28gd2UgY2FuIGFwcGVuZCB0aGUgdGV4dCBwYXJ0XG4gICAgICAgIGNsYXNzQXR0ci52YWx1ZSA9IHJlY2FzdC5idWlsZGVycy5jb25jYXQoW1xuICAgICAgICAgIGNsYXNzQXR0ci52YWx1ZSxcbiAgICAgICAgICByZWNhc3QuYnVpbGRlcnMudGV4dCgnICcgKyBwb3N0Zml4KSxcbiAgICAgICAgXSk7XG4gICAgICAgIGNsYXNzQXR0ci5xdW90ZVR5cGUgPSAnXCInO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBBbGw6IHtcbiAgICAgIGVudGVyKG5vZGUpIHtcbiAgICAgICAgc3RhY2sucHVzaChub2RlKTtcbiAgICAgIH0sXG4gICAgICBleGl0KCkge1xuICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgIH0sXG4gICAgfSxcblxuICAgIE11c3RhY2hlU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgIGxldCBjc3NDbGFzcztcblxuICAgICAgaWYgKFxuICAgICAgICBpc1Njb3BlZENsYXNzKGdldFZhbHVlKG5vZGUucGF0aCkpICYmXG4gICAgICAgIG5vZGUucGFyYW1zPy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgbm9kZS5wYXJhbXNbMF0udHlwZSA9PT0gJ1N0cmluZ0xpdGVyYWwnXG4gICAgICApIHtcbiAgICAgICAgY3NzQ2xhc3MgPSBub2RlLnBhcmFtc1swXS52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBpc1Njb3BlZENsYXNzKGdldFZhbHVlKG5vZGUucGF0aD8ucGF0aCkpICYmXG4gICAgICAgIG5vZGUucGF0aD8ucGFyYW1zPy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgbm9kZS5wYXRoPy5wYXJhbXNbMF0udHlwZSA9PT0gJ1N0cmluZ0xpdGVyYWwnXG4gICAgICApIHtcbiAgICAgICAgY3NzQ2xhc3MgPSBub2RlLnBhdGgucGFyYW1zWzBdLnZhbHVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY3NzQ2xhc3MpIHtcbiAgICAgICAgY29uc3QgdGV4dE5vZGUgPSByZWNhc3QuYnVpbGRlcnMudGV4dChyZW5hbWVDbGFzcyhjc3NDbGFzcywgcG9zdGZpeCkpO1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTtcblxuICAgICAgICBpZiAocGFyZW50Py50eXBlID09PSAnQXR0ck5vZGUnKSB7XG4gICAgICAgICAgcGFyZW50LnF1b3RlVHlwZSA9ICdcIic7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGV4dE5vZGU7XG4gICAgICB9XG4gICAgfSxcblxuICAgIFN1YkV4cHJlc3Npb24obm9kZSkge1xuICAgICAgaWYgKFxuICAgICAgICBpc1Njb3BlZENsYXNzKGdldFZhbHVlKG5vZGUucGF0aCkpICYmXG4gICAgICAgIG5vZGUucGFyYW1zPy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgbm9kZS5wYXJhbXNbMF0udHlwZSA9PT0gJ1N0cmluZ0xpdGVyYWwnXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgY3NzQ2xhc3MgPSBub2RlLnBhcmFtc1swXS52YWx1ZTtcbiAgICAgICAgY29uc3QgdGV4dE5vZGUgPSByZWNhc3QuYnVpbGRlcnMubGl0ZXJhbChcbiAgICAgICAgICAnU3RyaW5nTGl0ZXJhbCcsXG4gICAgICAgICAgcmVuYW1lQ2xhc3MoY3NzQ2xhc3MsIHBvc3RmaXgpLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB0ZXh0Tm9kZTtcbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZShwYXRoKSB7XG4gIGlmICghcGF0aCkgcmV0dXJuO1xuXG4gIGlmICgndmFsdWUnIGluIHBhdGgpIHtcbiAgICByZXR1cm4gcGF0aC52YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXByZWNhdGVkIGluIGVtYmVyIDUuOStcbiAgICogKHNvIHdlIHVzZSB0aGUgYWJvdmUgZm9yIG5ld2VyIGVtYmVycylcbiAgICovXG4gIHJldHVybiBwYXRoLm9yaWdpbmFsO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZXdyaXRlSGJzKFxuICBoYnMsXG4gIGNsYXNzZXMsXG4gIHRhZ3MsXG4gIHBvc3RmaXgsXG4gIGF0dHJpYnV0ZXMgPSBuZXcgU2V0KCksXG4pIHtcbiAgbGV0IGFzdCA9IHJlY2FzdC5wYXJzZShoYnMpO1xuXG4gIHJlY2FzdC50cmF2ZXJzZShhc3QsIHRlbXBsYXRlUGx1Z2luKHsgY2xhc3NlcywgdGFncywgYXR0cmlidXRlcywgcG9zdGZpeCB9KSk7XG5cbiAgbGV0IHJlc3VsdCA9IHJlY2FzdC5wcmludChhc3QpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iLCIvKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BnbGltbWVyL3N5bnRheCcpLkFTVFBsdWdpbn0gQVNUUGx1Z2luXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAZ2xpbW1lci9zeW50YXgnKS5BU1RQbHVnaW5FbnZpcm9ubWVudH0gQVNUUGx1Z2luRW52aXJvbm1lbnRcbiAqXG4gKi9cblxuaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB7IHJld3JpdGVDc3MgfSBmcm9tICcuLi9saWIvY3NzL3Jld3JpdGUuanMnO1xuaW1wb3J0IHsgZ2V0Q1NTQ29udGVudEluZm8sIGdldENTU0luZm8gfSBmcm9tICcuLi9saWIvY3NzL3V0aWxzLmpzJztcbmltcG9ydCB7IGZpeEZpbGVuYW1lIH0gZnJvbSAnLi4vbGliL3BhdGgvdGVtcGxhdGUtdHJhbnNmb3JtLXBhdGhzLmpzJztcbmltcG9ydCB7XG4gIGFwcFBhdGgsXG4gIGNzc1BhdGhGb3IsXG4gIGZvcmNlUG9zaXgsXG4gIGhhc2hGcm9tTW9kdWxlUGF0aCxcbiAgaXNSZWxldmFudEZpbGUsXG59IGZyb20gJy4uL2xpYi9wYXRoL3V0aWxzLmpzJztcbmltcG9ydCB7IHJlcXVlc3QgfSBmcm9tICcuLi9saWIvcmVxdWVzdC5qcyc7XG5pbXBvcnQgeyB0ZW1wbGF0ZVBsdWdpbiB9IGZyb20gJy4uL2xpYi9yZXdyaXRlSGJzLmpzJztcblxuY29uc3Qgbm9vcFBsdWdpbiA9IHtcbiAgbmFtZTogJ2VtYmVyLXNjb3BlZC1jc3M6bm9vcCcsXG4gIHZpc2l0b3I6IHt9LFxufTtcblxuLyoqXG4gKiBAcmV0dXJucyB7QVNUUGx1Z2lufVxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUGx1Z2luKGNvbmZpZykge1xuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtBU1RQbHVnaW5FbnZpcm9ubWVudH0gZW52XG4gICAqL1xuICByZXR1cm4gZnVuY3Rpb24gc2NvcGVkQ3NzKGVudikge1xuICAgIGxldCBjd2QgPSBwcm9jZXNzLmN3ZCgpO1xuXG4gICAgbGV0IGlzUmVsZXZhbnQgPSBpc1JlbGV2YW50RmlsZShlbnYuZmlsZW5hbWUsIHtcbiAgICAgIGFkZGl0aW9uYWxSb290czogY29uZmlnLmFkZGl0aW9uYWxSb290cyxcbiAgICAgIGN3ZCxcbiAgICB9KTtcblxuICAgIGlmICghaXNSZWxldmFudCkge1xuICAgICAgcmV0dXJuIG5vb3BQbHVnaW47XG4gICAgfVxuXG4gICAgbGV0IGFic29sdXRlUGF0aCA9IGZpeEZpbGVuYW1lKGVudi5maWxlbmFtZSk7XG4gICAgbGV0IG1vZHVsZVBhdGggPSBhcHBQYXRoKGFic29sdXRlUGF0aCk7XG4gICAgbGV0IHBvc3RmaXggPSBoYXNoRnJvbU1vZHVsZVBhdGgobW9kdWxlUGF0aCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbGlzdCBvZiBuYWtlZCB0YWcgc2VsZWN0b3JzIGZvdW5kIGluIHRoZSBDU1NcbiAgICAgKlxuICAgICAqIEB0eXBlIHtTZXQ8c3RyaW5nPn1cbiAgICAgKi9cbiAgICBsZXQgc2NvcGVkVGFncyA9IG5ldyBTZXQoKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0IG9mIGNsYXNzZXMgZm91bmQgaW4gdGhlIENTU1xuICAgICAqXG4gICAgICogQHR5cGUge1NldDxzdHJpbmc+fVxuICAgICAqL1xuICAgIGxldCBzY29wZWRDbGFzc2VzID0gbmV3IFNldCgpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGF0dHJpYnV0ZSBuYW1lcyBmb3VuZCBpbiBhdHRyaWJ1dGUgc2VsZWN0b3JzIGluIHRoZSBDU1MsIHVzZWQgdG9cbiAgICAgKiBtYXJrIG1hdGNoaW5nIGVsZW1lbnRzIHdpdGggdGhlIHNjb3BlIGNsYXNzLlxuICAgICAqXG4gICAgICogQHR5cGUge1NldDxzdHJpbmc+fVxuICAgICAqL1xuICAgIGxldCBzY29wZWRBdHRyaWJ1dGVzID0gbmV3IFNldCgpO1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHt7IHRhZ3M6IFNldDxzdHJpbmc+OyBjbGFzc2VzOiBTZXQ8c3RyaW5nPjsgYXR0cmlidXRlczogU2V0PHN0cmluZz4gfX0gaW5mb1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFkZEluZm8oaW5mbykge1xuICAgICAgZm9yIChsZXQgaXRlbSBvZiBpbmZvLnRhZ3MpIHtcbiAgICAgICAgc2NvcGVkVGFncy5hZGQoaXRlbSk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGl0ZW0gb2YgaW5mby5jbGFzc2VzKSB7XG4gICAgICAgIHNjb3BlZENsYXNzZXMuYWRkKGl0ZW0pO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpdGVtIG9mIGluZm8uYXR0cmlidXRlcykge1xuICAgICAgICBzY29wZWRBdHRyaWJ1dGVzLmFkZChpdGVtKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgY3NzUGF0aCA9IGNzc1BhdGhGb3IoYWJzb2x1dGVQYXRoKTtcbiAgICBsZXQgaW5mbyA9IGdldENTU0luZm8oY3NzUGF0aCk7XG4gICAgbGV0IGxvY2FsQ3NzUGF0aCA9IGZvcmNlUG9zaXgoY3NzUGF0aC5yZXBsYWNlKGN3ZCArIHBhdGguc2VwLCAnJykpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyB3aWxsIGJlIGZhbHNleSBpZiB3ZSBkb24ndCBoYXZlIGEgY28tbG9jYXRlZCBDU1MgZmlsZS5cbiAgICAgKiBXZSdsbCBzdGlsbCB3YW50IHRvIGNoZWNrIGZvciBlbWJlZGRlZCA8c3R5bGUgc2NvcGVkPiB0YWdzIHRob3VnaC5cbiAgICAgKi9cbiAgICBpZiAoaW5mbykge1xuICAgICAgYWRkSW5mbyhpbmZvKTtcblxuICAgICAgbGV0IGNzc1JlcXVlc3QgPSByZXF1ZXN0LmNvbG9jYXRlZC5jcmVhdGUoaW5mby5pZCwgcG9zdGZpeCwgbG9jYWxDc3NQYXRoKTtcblxuICAgICAgLyoqXG4gICAgICAgKiBXaXRoIHRoaXMgd2UgZG9uJ3QgbmVlZCBhIEpTIHBsdWdpblxuICAgICAgICovXG4gICAgICBlbnYubWV0YS5qc3V0aWxzLmltcG9ydEZvclNpZGVFZmZlY3QoY3NzUmVxdWVzdCk7XG4gICAgfVxuXG4gICAgbGV0IHZpc2l0b3JzID0gdGVtcGxhdGVQbHVnaW4oe1xuICAgICAgY2xhc3Nlczogc2NvcGVkQ2xhc3NlcyxcbiAgICAgIHRhZ3M6IHNjb3BlZFRhZ3MsXG4gICAgICBhdHRyaWJ1dGVzOiBzY29wZWRBdHRyaWJ1dGVzLFxuICAgICAgcG9zdGZpeCxcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiAnZW1iZXItc2NvcGVkLWNzczp0ZW1wbGF0ZS1wbHVnaW4nLFxuICAgICAgdmlzaXRvcjoge1xuICAgICAgICAvLyBTdGFjayBNYW5hZ2VyXG4gICAgICAgIC4uLnZpc2l0b3JzLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXZSBoYXZlIHRvIGVhZ2VybHkgZ2V0IHRoZSA8c3R5bGUgc2NvcGVkPiBjb250ZW50cywgc28gd2UgY2FuIHByZS1wYXJzZVxuICAgICAgICAgKiB0aGUgdGFncyBhbmQgY2xhc3NlcyB0byB0aGVuIHBhc3MgdG8gdGhlIG90aGVyIHZpc2l0b3JzIHNvIHRoYXQgdGhleSBjYW5cbiAgICAgICAgICogYXBwcm9wcmlhdGVseSBjaGFuZ2UgbWF0Y2hpbmcgY2xhc3NlcyAvIHRhZ3MuXG4gICAgICAgICAqL1xuICAgICAgICBUZW1wbGF0ZShub2RlKSB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogV2Ugb25seSBhbGxvdyBhIHNjb3BlZCA8c3R5bGU+IGF0IHRoZSByb290XG4gICAgICAgICAgICovXG4gICAgICAgICAgbGV0IHN0eWxlVGFnID0gbm9kZS5ib2R5LmZpbmQoXG4gICAgICAgICAgICAobikgPT4gbi50eXBlID09PSAnRWxlbWVudE5vZGUnICYmIG4udGFnID09PSAnc3R5bGUnLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoaGFzU2NvcGVkQXR0cmlidXRlKHN0eWxlVGFnKSkge1xuICAgICAgICAgICAgbGV0IGNzcyA9IHRleHRDb250ZW50KHN0eWxlVGFnKTtcbiAgICAgICAgICAgIGxldCBsYW5nID0gZ2V0TGFuZ0F0dHJpYnV0ZShzdHlsZVRhZyk7XG4gICAgICAgICAgICBsZXQgaW5mbyA9IGdldENTU0NvbnRlbnRJbmZvKGNzcywgbGFuZyk7XG5cbiAgICAgICAgICAgIGFkZEluZm8oaW5mbyk7XG5cbiAgICAgICAgICAgIGlmIChoYXNJbmxpbmVBdHRyaWJ1dGVXaXRob3V0TGFuZyhzdHlsZVRhZykpIHtcbiAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAqIFRoaXMgd2lsbCBiZSBoYW5kbGVkIGluIEVsZW1lbnROb2RlIHRyYXZlcnNhbFxuICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobGFuZykge1xuICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICogRm9yIDxzdHlsZSBzY29wZWQgaW5saW5lIGxhbmc9XCIuLi5cIj4gd2UgY2Fubm90IHByZXByb2Nlc3MgYXQgQmFiZWwtdGltZVxuICAgICAgICAgICAgICAgKiAocHJlcHJvY2Vzc2luZyBpcyBhc3luYyBhbmQgcmVxdWlyZXMgVml0ZSdzIFJlc29sdmVkQ29uZmlnKS5cbiAgICAgICAgICAgICAgICogUmVtb3ZlIHRoZSB0YWcgYW5kIGluamVjdCB2aWEgdmlydHVhbCBDU1MgbW9kdWxlIGFuZCB3YXJuIHVzZXIuXG4gICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgYFtlbWJlci1zY29wZWQtY3NzXSA8c3R5bGUgc2NvcGVkIGlubGluZSBsYW5nPVwiJHtsYW5nfVwiPiBpcyBub3Qgc3VwcG9ydGVkIGAgK1xuICAgICAgICAgICAgICAgICAgYChwcmVwcm9jZXNzaW5nIGlzIGFzeW5jIGFuZCBjYW5ub3QgcnVuIGF0IEJhYmVsLXRpbWUpLiBgICtcbiAgICAgICAgICAgICAgICAgIGBEb3duZ3JhZGluZyB0byBub24taW5saW5lOiB0aGUgc3R5bGUgdGFnIHdpbGwgYmUgcmVtb3ZlZCBhbmQgaW5qZWN0ZWQgYXMgYSB2aXJ0dWFsIENTUyBtb2R1bGUuYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGNzc1JlcXVlc3QgPSByZXF1ZXN0LmlubGluZS5jcmVhdGUoaW5mby5pZCwgcG9zdGZpeCwgY3NzLCBsYW5nKTtcblxuICAgICAgICAgICAgZW52Lm1ldGEuanN1dGlscy5pbXBvcnRGb3JTaWRlRWZmZWN0KGNzc1JlcXVlc3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvLyBWaXNpdG9ycyBicm9rZW4gb3V0IGxpa2UgdGhpcyBzbyB3ZSBjYW4gY29uZGl0aW9uYWxseVxuICAgICAgICAvLyBkZWJ1ZyBiYXNlZCBvbiBmaWxlIHBhdGguXG4gICAgICAgIEF0dHJOb2RlKC4uLmFyZ3MpIHtcbiAgICAgICAgICByZXR1cm4gdmlzaXRvcnMuQXR0ck5vZGUoLi4uYXJncyk7XG4gICAgICAgIH0sXG4gICAgICAgIEVsZW1lbnROb2RlKG5vZGUsIHdhbGtlcikge1xuICAgICAgICAgIC8vIGNsYXNzIGF0dHJpYnV0ZSBoYW5kbGluZ1xuICAgICAgICAgIHZpc2l0b3JzLkVsZW1lbnROb2RlKG5vZGUsIHdhbGtlcik7XG5cbiAgICAgICAgICBpZiAoaGFzU2NvcGVkQXR0cmlidXRlKG5vZGUpKSB7XG4gICAgICAgICAgICBpZiAod2Fsa2VyLnBhcmVudD8ubm9kZS50eXBlICE9PSAnVGVtcGxhdGUnKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnPHN0eWxlIHNjb3BlZD4gdGFncyBtdXN0IGJlIGF0IHRoZSByb290IG9mIHRoZSB0ZW1wbGF0ZSwgdGhleSBjYW5ub3QgYmUgbmVzdGVkJyxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGhhc0lubGluZUF0dHJpYnV0ZVdpdGhvdXRMYW5nKG5vZGUpKSB7XG4gICAgICAgICAgICAgIGxldCB0ZXh0ID0gdGV4dENvbnRlbnQobm9kZSk7XG4gICAgICAgICAgICAgIGxldCBzY29wZWRUZXh0ID0gcmV3cml0ZUNzcyhcbiAgICAgICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgICAgIHBvc3RmaXgsXG4gICAgICAgICAgICAgICAgbG9jYWxDc3NQYXRoLFxuICAgICAgICAgICAgICAgIGNvbmZpZy5sYXllck5hbWUsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAqIFRyYXZlcnNlIHRoaXMgYW5kIGFsbG93IGludGVycG9sYXRpb25cbiAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4gPSBbZW52LnN5bnRheC5idWlsZGVycy50ZXh0KHNjb3BlZFRleHQpXTtcblxuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJldHVybmluZyBudWxsIHJlbW92ZXMgdGhlIG5vZGVcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChoYXNJbmxpbmVBdHRyaWJ1dGVXaXRob3V0TGFuZyhub2RlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgPHN0eWxlIGlubGluZT4gaXMgbm90IHZhbGlkLiBQbGVhc2UgYWRkIHRoZSBzY29wZWQgYXR0cmlidXRlOiA8c3R5bGUgc2NvcGVkIGlubGluZT5gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIE11c3RhY2hlU3RhdGVtZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICByZXR1cm4gdmlzaXRvcnMuTXVzdGFjaGVTdGF0ZW1lbnQoLi4uYXJncyk7XG4gICAgICAgIH0sXG4gICAgICAgIFN1YkV4cHJlc3Npb24oLi4uYXJncykge1xuICAgICAgICAgIHJldHVybiB2aXNpdG9ycy5TdWJFeHByZXNzaW9uKC4uLmFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9O1xufVxuXG4vKipcbiAqIFRoYW5rcywgQ2FyZFN0YWNrIGFuZCBAZWY0IGZvciB0aGlzIGNvZGUuXG4gKi9cbmNvbnN0IFNDT1BFRF9BVFRSSUJVVEVfTkFNRSA9ICdzY29wZWQnO1xuY29uc3QgSU5MSU5FX0FUVFJJQlVURV9OQU1FID0gJ2lubGluZSc7XG5jb25zdCBMQU5HX0FUVFJJQlVURV9OQU1FID0gJ2xhbmcnO1xuXG5mdW5jdGlvbiBoYXNTY29wZWRBdHRyaWJ1dGUobm9kZSkge1xuICBpZiAoIW5vZGUpIHJldHVybjtcbiAgaWYgKG5vZGUudGFnICE9PSAnc3R5bGUnKSByZXR1cm47XG4gIGlmIChub2RlLnR5cGUgIT09ICdFbGVtZW50Tm9kZScpIHJldHVybjtcblxuICByZXR1cm4gbm9kZS5hdHRyaWJ1dGVzLnNvbWUoXG4gICAgKGF0dHJpYnV0ZSkgPT4gYXR0cmlidXRlLm5hbWUgPT09IFNDT1BFRF9BVFRSSUJVVEVfTkFNRSxcbiAgKTtcbn1cblxuZnVuY3Rpb24gaGFzSW5saW5lQXR0cmlidXRlV2l0aG91dExhbmcobm9kZSkge1xuICBpZiAoIW5vZGUpIHJldHVybjtcbiAgaWYgKG5vZGUudGFnICE9PSAnc3R5bGUnKSByZXR1cm47XG4gIGlmIChub2RlLnR5cGUgIT09ICdFbGVtZW50Tm9kZScpIHJldHVybjtcblxuICBpZiAoZ2V0TGFuZ0F0dHJpYnV0ZShub2RlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBub2RlLmF0dHJpYnV0ZXMuc29tZShcbiAgICAoYXR0cmlidXRlKSA9PiBhdHRyaWJ1dGUubmFtZSA9PT0gSU5MSU5FX0FUVFJJQlVURV9OQU1FLFxuICApO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBgbGFuZ2AgYXR0cmlidXRlIG9uIGEgYDxzdHlsZT5gIG5vZGUsIG9yIG51bGwgaWYgYWJzZW50LlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBub2RlXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH1cbiAqL1xuZnVuY3Rpb24gZ2V0TGFuZ0F0dHJpYnV0ZShub2RlKSB7XG4gIGlmICghbm9kZSkgcmV0dXJuIG51bGw7XG4gIGlmIChub2RlLnRhZyAhPT0gJ3N0eWxlJykgcmV0dXJuIG51bGw7XG4gIGlmIChub2RlLnR5cGUgIT09ICdFbGVtZW50Tm9kZScpIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IGF0dHIgPSBub2RlLmF0dHJpYnV0ZXMuZmluZChcbiAgICAoYXR0cmlidXRlKSA9PiBhdHRyaWJ1dGUubmFtZSA9PT0gTEFOR19BVFRSSUJVVEVfTkFNRSxcbiAgKTtcblxuICBpZiAoIWF0dHIpIHJldHVybiBudWxsO1xuXG4gIC8vIFRoZSBhdHRyaWJ1dGUgdmFsdWUgaXMgYSBUZXh0Tm9kZSBjaGlsZCBvZiB0aGUgQXR0ck5vZGUncyB2YWx1ZVxuICBjb25zdCB2YWx1ZSA9IGF0dHIudmFsdWU7XG5cbiAgaWYgKHZhbHVlPy50eXBlID09PSAnVGV4dE5vZGUnKSByZXR1cm4gdmFsdWUuY2hhcnMgfHwgbnVsbDtcblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gdGV4dENvbnRlbnQobm9kZSkge1xuICBsZXQgdGV4dENoaWxkcmVuID0gbm9kZS5jaGlsZHJlbi5maWx0ZXIoKGMpID0+IGMudHlwZSA9PT0gJ1RleHROb2RlJyk7XG5cbiAgcmV0dXJuIHRleHRDaGlsZHJlbi5tYXAoKGMpID0+IGMuY2hhcnMpLmpvaW4oJycpO1xufVxuIiwiaW1wb3J0ICogYXMgYmFiZWwgZnJvbSAnLi4vYmFiZWwtcGx1Z2luLmpzJztcbmltcG9ydCB7IHVucGx1Z2luIH0gZnJvbSAnLi4vc2NvcGVkLWNzcy11bnBsdWdpbi5qcyc7XG5pbXBvcnQgKiBhcyB0ZW1wbGF0ZSBmcm9tICcuLi90ZW1wbGF0ZS1wbHVnaW4uanMnO1xuXG5leHBvcnQgY29uc3Qgc2NvcGVkQ1NTID0ge1xuICB2aXRlOiB1bnBsdWdpbi52aXRlLFxuICByb2xsdXA6IHVucGx1Z2luLnJvbGx1cCxcbiAgYmFiZWw6IGJhYmVsLnNjb3BlZENTUyxcbiAgdGVtcGxhdGU6IHRlbXBsYXRlLmNyZWF0ZVBsdWdpbixcbn07XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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TUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxZQUFZO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksVUFBVTtBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLFdBQVc7QUFDOUMsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxZQUFZO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksT0FBTztBQUM1QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFlBQVk7QUFDakQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssR0FBRyxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksVUFBVTtBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFlBQVk7QUFDakQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxXQUFXO0FBRWhELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsV0FBVztBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLFlBQVk7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxVQUFVO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLFdBQVc7QUFDM0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxXQUFXO0FBQzlDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLEdBQUcsU0FBUztBQUM3QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFdBQVc7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsVUFBVTtBQUM3QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxHQUFHLFlBQVk7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxHQUFHLFlBQVk7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxVQUFVO0FBQzdDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFlBQVk7QUFFakQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxRQUFRO0FBQzNDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksWUFBWTtBQUNoRCxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFdBQVc7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxVQUFVO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsWUFBWTtBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFdBQVc7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksWUFBWTtBQUNqRCxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxHQUFHLFVBQVU7QUFDOUMsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksV0FBVztBQUMzQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFdBQVc7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxTQUFTO0FBQzdDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsV0FBVztBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFdBQVc7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxVQUFVO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUUvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksR0FBRyxXQUFXO0FBQzFDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxF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