ember-scoped-css 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +203 -47
  2. package/dist/cjs/all-Du43cBa9.cjs +1308 -0
  3. package/dist/cjs/all.cjs +3 -0
  4. package/dist/cjs/babel.cjs +9 -0
  5. package/dist/cjs/rollup.cjs +8 -0
  6. package/dist/cjs/vite.cjs +8 -0
  7. package/dist/runtime/index.d.ts +11 -0
  8. package/dist/runtime/index.d.ts.map +1 -0
  9. package/dist/runtime/index.js +12 -8
  10. package/dist/runtime/index.js.map +1 -7
  11. package/{declarations → dist}/runtime/test-support.d.ts +5 -2
  12. package/dist/runtime/test-support.d.ts.map +1 -0
  13. package/dist/runtime/test-support.js +357 -182
  14. package/dist/runtime/test-support.js.map +1 -7
  15. package/package.json +21 -24
  16. package/src/build/babel-plugin.js +4 -1
  17. package/src/build/public-exports/all.js +10 -0
  18. package/src/build/public-exports/babel.js +5 -0
  19. package/src/build/public-exports/rollup.js +3 -0
  20. package/src/build/public-exports/vite.js +3 -0
  21. package/src/build/scoped-css-unplugin.js +10 -33
  22. package/src/build/template-plugin.js +9 -19
  23. package/src/build/template-plugin.test.ts +108 -19
  24. package/src/build/unplugin-colocated.js +103 -0
  25. package/src/build/unplugin-inline.js +71 -0
  26. package/src/lib/css/rewrite.js +8 -8
  27. package/src/lib/css/rewrite.test.ts +69 -128
  28. package/src/lib/path/const.js +19 -0
  29. package/src/lib/path/hash-from-absolute-path.js +3 -2
  30. package/src/lib/path/template-transform-paths.js +3 -2
  31. package/src/lib/path/utils.appPath.test.ts +2 -2
  32. package/src/lib/path/utils.hashFrom.test.ts +2 -2
  33. package/src/lib/path/utils.js +63 -20
  34. package/src/lib/request.js +58 -33
  35. package/src/runtime/index.ts +1 -1
  36. package/declarations/build/template-plugin.d.ts +0 -7
  37. package/declarations/build/template-plugin.d.ts.map +0 -1
  38. package/declarations/build/template-plugin.test.d.ts +0 -2
  39. package/declarations/build/template-plugin.test.d.ts.map +0 -1
  40. package/declarations/lib/css/rewrite.d.ts +0 -2
  41. package/declarations/lib/css/rewrite.d.ts.map +0 -1
  42. package/declarations/lib/css/rewrite.test.d.ts +0 -2
  43. package/declarations/lib/css/rewrite.test.d.ts.map +0 -1
  44. package/declarations/lib/css/utils.d.ts +0 -29
  45. package/declarations/lib/css/utils.d.ts.map +0 -1
  46. package/declarations/lib/path/hash-from-absolute-path.d.ts +0 -3
  47. package/declarations/lib/path/hash-from-absolute-path.d.ts.map +0 -1
  48. package/declarations/lib/path/hash-from-absolute-path.test.d.ts +0 -2
  49. package/declarations/lib/path/hash-from-absolute-path.test.d.ts.map +0 -1
  50. package/declarations/lib/path/hash-from-module-path.d.ts +0 -31
  51. package/declarations/lib/path/hash-from-module-path.d.ts.map +0 -1
  52. package/declarations/lib/path/md5.d.ts +0 -12
  53. package/declarations/lib/path/md5.d.ts.map +0 -1
  54. package/declarations/lib/path/template-transform-paths.d.ts +0 -11
  55. package/declarations/lib/path/template-transform-paths.d.ts.map +0 -1
  56. package/declarations/lib/path/template-transform-paths.test.d.ts +0 -2
  57. package/declarations/lib/path/template-transform-paths.test.d.ts.map +0 -1
  58. package/declarations/lib/path/utils.appPath.test.d.ts +0 -2
  59. package/declarations/lib/path/utils.appPath.test.d.ts.map +0 -1
  60. package/declarations/lib/path/utils.d.ts +0 -94
  61. package/declarations/lib/path/utils.d.ts.map +0 -1
  62. package/declarations/lib/path/utils.findWorkspacePath.test.d.ts +0 -2
  63. package/declarations/lib/path/utils.findWorkspacePath.test.d.ts.map +0 -1
  64. package/declarations/lib/path/utils.hashFrom.test.d.ts +0 -2
  65. package/declarations/lib/path/utils.hashFrom.test.d.ts.map +0 -1
  66. package/declarations/lib/path/utils.isRelevantFile.test.d.ts +0 -2
  67. package/declarations/lib/path/utils.isRelevantFile.test.d.ts.map +0 -1
  68. package/declarations/lib/path/utils.paths.test.d.ts +0 -5
  69. package/declarations/lib/path/utils.paths.test.d.ts.map +0 -1
  70. package/declarations/lib/renameClass.d.ts +0 -9
  71. package/declarations/lib/renameClass.d.ts.map +0 -1
  72. package/declarations/lib/request.d.ts +0 -8
  73. package/declarations/lib/request.d.ts.map +0 -1
  74. package/declarations/lib/rewriteHbs.d.ts +0 -17
  75. package/declarations/lib/rewriteHbs.d.ts.map +0 -1
  76. package/declarations/runtime/index.d.ts +0 -8
  77. package/declarations/runtime/index.d.ts.map +0 -1
  78. package/declarations/runtime/test-support.d.ts.map +0 -1
  79. package/dist/cjs/babel-plugin.cjs +0 -176
  80. package/dist/cjs/index.cjs +0 -968
  81. package/dist/cjs/template-plugin.cjs +0 -856
  82. package/src/build/index.js +0 -7
  83. package/src/build/vite.js +0 -3
@@ -0,0 +1,1308 @@
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 node_process = require("node:process");
43
+ node_process = __toESM(node_process);
44
+ let ember_template_recast = require("ember-template-recast");
45
+ ember_template_recast = __toESM(ember_template_recast);
46
+
47
+ //#region src/lib/path/const.js
48
+ /**
49
+ * Join will convert to whatever is appropriate fro the current platform
50
+ */
51
+ const leadingSlashPath = {
52
+ embroiderDir: path.default.join("/node_modules/.embroider/"),
53
+ atEmbroider: path.default.join("/@embroider"),
54
+ componentsDir: path.default.join("/components/"),
55
+ templatesDir: path.default.join("/templates/"),
56
+ testem: path.default.join("/testem"),
57
+ src: path.default.join("/src/"),
58
+ app: path.default.join("/app/")
59
+ };
60
+ const barePath = { pnpmDir: path.default.join("node_modules/.pnpm") };
61
+
62
+ //#endregion
63
+ //#region src/lib/path/md5.js
64
+ /**
65
+ * Add integers, wrapping at 2^32.
66
+ * This uses 16-bit operations internally to work around bugs in interpreters.
67
+ *
68
+ * @param {number} x First integer
69
+ * @param {number} y Second integer
70
+ * @returns {number} Sum
71
+ */
72
+ function safeAdd(x, y) {
73
+ var lsw = (x & 65535) + (y & 65535);
74
+ return (x >> 16) + (y >> 16) + (lsw >> 16) << 16 | lsw & 65535;
75
+ }
76
+ /**
77
+ * Bitwise rotate a 32-bit number to the left.
78
+ *
79
+ * @param {number} num 32-bit number
80
+ * @param {number} cnt Rotation count
81
+ * @returns {number} Rotated number
82
+ */
83
+ function bitRotateLeft(num, cnt) {
84
+ return num << cnt | num >>> 32 - cnt;
85
+ }
86
+ /**
87
+ * Basic operation the algorithm uses.
88
+ *
89
+ * @param {number} q q
90
+ * @param {number} a a
91
+ * @param {number} b b
92
+ * @param {number} x x
93
+ * @param {number} s s
94
+ * @param {number} t t
95
+ * @returns {number} Result
96
+ */
97
+ function md5cmn(q, a, b, x, s, t) {
98
+ return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
99
+ }
100
+ /**
101
+ * Basic operation the algorithm uses.
102
+ *
103
+ * @param {number} a a
104
+ * @param {number} b b
105
+ * @param {number} c c
106
+ * @param {number} d d
107
+ * @param {number} x x
108
+ * @param {number} s s
109
+ * @param {number} t t
110
+ * @returns {number} Result
111
+ */
112
+ function md5ff(a, b, c, d, x, s, t) {
113
+ return md5cmn(b & c | ~b & d, a, b, x, s, t);
114
+ }
115
+ /**
116
+ * Basic operation the algorithm uses.
117
+ *
118
+ * @param {number} a a
119
+ * @param {number} b b
120
+ * @param {number} c c
121
+ * @param {number} d d
122
+ * @param {number} x x
123
+ * @param {number} s s
124
+ * @param {number} t t
125
+ * @returns {number} Result
126
+ */
127
+ function md5gg(a, b, c, d, x, s, t) {
128
+ return md5cmn(b & d | c & ~d, a, b, x, s, t);
129
+ }
130
+ /**
131
+ * Basic operation the algorithm uses.
132
+ *
133
+ * @param {number} a a
134
+ * @param {number} b b
135
+ * @param {number} c c
136
+ * @param {number} d d
137
+ * @param {number} x x
138
+ * @param {number} s s
139
+ * @param {number} t t
140
+ * @returns {number} Result
141
+ */
142
+ function md5hh(a, b, c, d, x, s, t) {
143
+ return md5cmn(b ^ c ^ d, a, b, x, s, t);
144
+ }
145
+ /**
146
+ * Basic operation the algorithm uses.
147
+ *
148
+ * @param {number} a a
149
+ * @param {number} b b
150
+ * @param {number} c c
151
+ * @param {number} d d
152
+ * @param {number} x x
153
+ * @param {number} s s
154
+ * @param {number} t t
155
+ * @returns {number} Result
156
+ */
157
+ function md5ii(a, b, c, d, x, s, t) {
158
+ return md5cmn(c ^ (b | ~d), a, b, x, s, t);
159
+ }
160
+ /**
161
+ * Calculate the MD5 of an array of little-endian words, and a bit length.
162
+ *
163
+ * @param {Array} x Array of little-endian words
164
+ * @param {number} len Bit length
165
+ * @returns {Array<number>} MD5 Array
166
+ */
167
+ function binlMD5(x, len) {
168
+ x[len >> 5] |= 128 << len % 32;
169
+ x[(len + 64 >>> 9 << 4) + 14] = len;
170
+ var i;
171
+ var olda;
172
+ var oldb;
173
+ var oldc;
174
+ var oldd;
175
+ var a = 1732584193;
176
+ var b = -271733879;
177
+ var c = -1732584194;
178
+ var d = 271733878;
179
+ for (i = 0; i < x.length; i += 16) {
180
+ olda = a;
181
+ oldb = b;
182
+ oldc = c;
183
+ oldd = d;
184
+ a = md5ff(a, b, c, d, x[i], 7, -680876936);
185
+ d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
186
+ c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
187
+ b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
188
+ a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
189
+ d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
190
+ c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
191
+ b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
192
+ a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
193
+ d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
194
+ c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
195
+ b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
196
+ a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
197
+ d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
198
+ c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
199
+ b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
200
+ a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
201
+ d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
202
+ c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
203
+ b = md5gg(b, c, d, a, x[i], 20, -373897302);
204
+ a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
205
+ d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
206
+ c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
207
+ b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
208
+ a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
209
+ d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
210
+ c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
211
+ b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
212
+ a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
213
+ d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
214
+ c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
215
+ b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
216
+ a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
217
+ d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
218
+ c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
219
+ b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
220
+ a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
221
+ d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
222
+ c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
223
+ b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
224
+ a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
225
+ d = md5hh(d, a, b, c, x[i], 11, -358537222);
226
+ c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
227
+ b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
228
+ a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
229
+ d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
230
+ c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
231
+ b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
232
+ a = md5ii(a, b, c, d, x[i], 6, -198630844);
233
+ d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
234
+ c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
235
+ b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
236
+ a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
237
+ d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
238
+ c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
239
+ b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
240
+ a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
241
+ d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
242
+ c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
243
+ b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
244
+ a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
245
+ d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
246
+ c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
247
+ b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
248
+ a = safeAdd(a, olda);
249
+ b = safeAdd(b, oldb);
250
+ c = safeAdd(c, oldc);
251
+ d = safeAdd(d, oldd);
252
+ }
253
+ return [
254
+ a,
255
+ b,
256
+ c,
257
+ d
258
+ ];
259
+ }
260
+ /**
261
+ * Convert an array of little-endian words to a string
262
+ *
263
+ * @param {Array<number>} input MD5 Array
264
+ * @returns {string} MD5 string
265
+ */
266
+ function binl2rstr(input) {
267
+ var i;
268
+ var output = "";
269
+ var length32 = input.length * 32;
270
+ for (i = 0; i < length32; i += 8) output += String.fromCharCode(input[i >> 5] >>> i % 32 & 255);
271
+ return output;
272
+ }
273
+ /**
274
+ * Convert a raw string to an array of little-endian words
275
+ * Characters >255 have their high-byte silently ignored.
276
+ *
277
+ * @param {string} input Raw input string
278
+ * @returns {Array<number>} Array of little-endian words
279
+ */
280
+ function rstr2binl(input) {
281
+ var i;
282
+ var output = [];
283
+ output[(input.length >> 2) - 1] = void 0;
284
+ for (i = 0; i < output.length; i += 1) output[i] = 0;
285
+ var length8 = input.length * 8;
286
+ for (i = 0; i < length8; i += 8) output[i >> 5] |= (input.charCodeAt(i / 8) & 255) << i % 32;
287
+ return output;
288
+ }
289
+ /**
290
+ * Calculate the MD5 of a raw string
291
+ *
292
+ * @param {string} s Input string
293
+ * @returns {string} Raw MD5 string
294
+ */
295
+ function rstrMD5(s) {
296
+ return binl2rstr(binlMD5(rstr2binl(s), s.length * 8));
297
+ }
298
+ /**
299
+ * Calculates the HMAC-MD5 of a key and some data (raw strings)
300
+ *
301
+ * @param {string} key HMAC key
302
+ * @param {string} data Raw input string
303
+ * @returns {string} Raw MD5 string
304
+ */
305
+ function rstrHMACMD5(key, data) {
306
+ var i;
307
+ var bkey = rstr2binl(key);
308
+ var ipad = [];
309
+ var opad = [];
310
+ var hash$2;
311
+ ipad[15] = opad[15] = void 0;
312
+ if (bkey.length > 16) bkey = binlMD5(bkey, key.length * 8);
313
+ for (i = 0; i < 16; i += 1) {
314
+ ipad[i] = bkey[i] ^ 909522486;
315
+ opad[i] = bkey[i] ^ 1549556828;
316
+ }
317
+ hash$2 = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
318
+ return binl2rstr(binlMD5(opad.concat(hash$2), 640));
319
+ }
320
+ /**
321
+ * Convert a raw string to a hex string
322
+ *
323
+ * @param {string} input Raw input string
324
+ * @returns {string} Hex encoded string
325
+ */
326
+ function rstr2hex(input) {
327
+ var hexTab = "0123456789abcdef";
328
+ var output = "";
329
+ var x;
330
+ var i;
331
+ for (i = 0; i < input.length; i += 1) {
332
+ x = input.charCodeAt(i);
333
+ output += hexTab.charAt(x >>> 4 & 15) + hexTab.charAt(x & 15);
334
+ }
335
+ return output;
336
+ }
337
+ /**
338
+ * Encode a string as UTF-8
339
+ *
340
+ * @param {string} input Input string
341
+ * @returns {string} UTF8 string
342
+ */
343
+ function str2rstrUTF8(input) {
344
+ return unescape(encodeURIComponent(input));
345
+ }
346
+ /**
347
+ * Encodes input string as raw MD5 string
348
+ *
349
+ * @param {string} s Input string
350
+ * @returns {string} Raw MD5 string
351
+ */
352
+ function rawMD5(s) {
353
+ return rstrMD5(str2rstrUTF8(s));
354
+ }
355
+ /**
356
+ * Encodes input string as Hex encoded string
357
+ *
358
+ * @param {string} s Input string
359
+ * @returns {string} Hex encoded string
360
+ */
361
+ function hexMD5(s) {
362
+ return rstr2hex(rawMD5(s));
363
+ }
364
+ /**
365
+ * Calculates the raw HMAC-MD5 for the given key and data
366
+ *
367
+ * @param {string} k HMAC key
368
+ * @param {string} d Input string
369
+ * @returns {string} Raw MD5 string
370
+ */
371
+ function rawHMACMD5(k, d) {
372
+ return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d));
373
+ }
374
+ /**
375
+ * Calculates the Hex encoded HMAC-MD5 for the given key and data
376
+ *
377
+ * @param {string} k HMAC key
378
+ * @param {string} d Input string
379
+ * @returns {string} Raw MD5 string
380
+ */
381
+ function hexHMACMD5(k, d) {
382
+ return rstr2hex(rawHMACMD5(k, d));
383
+ }
384
+ /**
385
+ * Calculates MD5 value for a given string.
386
+ * If a key is provided, calculates the HMAC-MD5 value.
387
+ * Returns a Hex encoded string unless the raw argument is given.
388
+ *
389
+ * @param {string} string Input string
390
+ * @param {string} [key] HMAC key
391
+ * @param {boolean} [raw] Raw output switch
392
+ * @returns {string} MD5 output
393
+ */
394
+ function md5(string, key, raw) {
395
+ if (!key) {
396
+ if (!raw) return hexMD5(string);
397
+ return rawMD5(string);
398
+ }
399
+ if (!raw) return hexHMACMD5(key, string);
400
+ return rawHMACMD5(key, string);
401
+ }
402
+
403
+ //#endregion
404
+ //#region src/lib/path/hash-from-module-path.js
405
+ /**
406
+ * The intent of this function is to generate the suffix/postfix for the
407
+ * css classes, based on the module-scoped path name.
408
+ *
409
+ * for example,
410
+ * hash('my-app/components/foo')
411
+ * instead of
412
+ * hash('app/components/foo')
413
+ *
414
+ * (unless your app name is 'app')
415
+ *
416
+ * @param {string} modulePath
417
+ * @returns {string}
418
+ */
419
+ function hash$1(modulePath) {
420
+ return "e" + md5(modulePath).substring(0, 8);
421
+ }
422
+ const hashFromModulePath$1 = hash$1;
423
+
424
+ //#endregion
425
+ //#region src/lib/path/utils.js
426
+ /**
427
+ *
428
+ * @param {string} filePath
429
+ * @returns {string}
430
+ */
431
+ function hashFromModulePath(filePath) {
432
+ return hashFromModulePath$1(forcePosix(filePath));
433
+ }
434
+ /**
435
+ * @param {string} filePath
436
+ */
437
+ function forcePosix(filePath) {
438
+ const parsed = node_path.default.parse(filePath);
439
+ if (parsed.root === "") return filePath.replaceAll(node_path.default.win32.sep, node_path.default.posix.sep);
440
+ 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);
441
+ }
442
+ let here = require("url").pathToFileURL(__filename).href;
443
+ let ourRequire = globalThis.require ? globalThis.require : here && (0, node_module.createRequire)(here);
444
+ if (!ourRequire) ourRequire = require;
445
+ const IRRELEVANT_PATHS = [barePath.pnpmDir, "__vite-"];
446
+ const UNSUPPORTED_DIRECTORIES = new Set(["tests"]);
447
+ const CWD = process.cwd();
448
+ /**
449
+ * Based on ember's component location conventions,
450
+ * this function will provide a path for where we
451
+ * expect the CSS to live.
452
+ *
453
+ * For co-located structure:
454
+ * - components/my-component.hbs
455
+ * - components/my-component.css
456
+ *
457
+ * For nested co-located structure
458
+ * - components/my-component/foo.hbs
459
+ * - components/my-component/foo.css
460
+ *
461
+ * For Pods routes structure
462
+ * - routes/my-route/template.{hbs,js}
463
+ * - routes/my-route/styles.css
464
+ *
465
+ * Deliberately not supported:
466
+ * - components w/ pods -- this is deprecated in 5.10
467
+ *
468
+ * @param {string} fileName - the hbs, js, gjs, gts or whatever co-located path.
469
+ * @returns {string} - expected css path
470
+ */
471
+ function cssPathFor(fileName) {
472
+ let cssPath = withoutExtension(fileName) + ".css";
473
+ if (isPod(fileName)) cssPath = fileName.replace(/template\.js$/, "styles.css").replace(/template\.hbs/, "styles.css");
474
+ return cssPath;
475
+ }
476
+ /**
477
+ * Note that components in the "pods" convention will
478
+ * never be supported.
479
+ *
480
+ * @param {string} filePath
481
+ */
482
+ function isPodTemplate(filePath) {
483
+ if (filePath.includes(leadingSlashPath.componentsDir)) return false;
484
+ return filePath.endsWith("template.js") || filePath.endsWith("template.hbs");
485
+ }
486
+ /**
487
+ * Note that components in the "pods" convention will
488
+ * never be supported.
489
+ *
490
+ * Checks if a file ends with
491
+ * - template.js
492
+ * - template.hbs
493
+ * - styles.css
494
+ *
495
+ * @param {string} filePath
496
+ */
497
+ function isPod(filePath) {
498
+ if (filePath.includes(leadingSlashPath.componentsDir)) return false;
499
+ if (isPodTemplate(filePath)) return true;
500
+ return filePath.endsWith("styles.css");
501
+ }
502
+ /**
503
+ *
504
+ * @param {string} filePath
505
+ * @returns the same path, but without the extension
506
+ */
507
+ function withoutExtension(filePath) {
508
+ let parsed = node_path.default.parse(filePath);
509
+ return node_path.default.join(parsed.dir, parsed.name);
510
+ }
511
+ /**
512
+ * Examples for fileName
513
+ * - absolute on-disk path
514
+ * - in webpack
515
+ * - URL-absolute path, starting with /
516
+ *
517
+ * @param {string} fileName
518
+ * @param {{ additionalRoots?: string[]; cwd: string }} options
519
+ * @returns
520
+ */
521
+ function isRelevantFile(fileName, { additionalRoots, cwd }) {
522
+ if (fileName.startsWith(leadingSlashPath.testem)) return false;
523
+ if (fileName.startsWith("\0")) return false;
524
+ if (node_path.default.isAbsolute(fileName) === false) {
525
+ if (fileName.match(/^[a-zA-Z]/)) return false;
526
+ }
527
+ if (fileName.startsWith(leadingSlashPath.atEmbroider)) return false;
528
+ if (IRRELEVANT_PATHS.some((i) => fileName.includes(i))) return false;
529
+ let workspace = findWorkspacePath(fileName);
530
+ (0, node_assert.default)(cwd, `cwd was not passed to isRelevantFile`);
531
+ if (workspace !== findWorkspacePath(cwd)) return false;
532
+ let [, ...parts] = fileName.replace(workspace, "").split(node_path.default.sep).filter(Boolean);
533
+ if (UNSUPPORTED_DIRECTORIES.has(parts[0])) return false;
534
+ if (![
535
+ leadingSlashPath.componentsDir,
536
+ leadingSlashPath.templatesDir,
537
+ ...additionalRoots || []
538
+ ].some((root) => fileName.includes(root))) return;
539
+ return true;
540
+ }
541
+ function packageScopedPathToModulePath(packageScopedPath) {
542
+ /**
543
+ * *By convention*, `src` is omitted from component paths.
544
+ * We can reflect the same behavior by replacing src/
545
+ * with an empty string.
546
+ *
547
+ * CSS isn't emitted as a co-located module, but
548
+ * to keep conventions consistent across languages,
549
+ * we can pretend it is.
550
+ *
551
+ * Any customization beyond removing `src` and `app` is potentially confusing.
552
+ * If we need further customizations, we'll want to match on `exports` in the
553
+ * corresponding package.json
554
+ */
555
+ let packageRelative = packageScopedPath.replace(/* @__PURE__ */ new RegExp(`^${RegExp.escape(leadingSlashPath.src)}`), node_path.default.sep);
556
+ let parsed = node_path.default.parse(packageRelative);
557
+ if (isPod(packageRelative))
558
+ /**
559
+ * For pods, we chop off the whole file, and use the dir name as the "modulePath"
560
+ */
561
+ return parsed.dir;
562
+ return node_path.default.join(parsed.dir, parsed.name);
563
+ }
564
+ /**
565
+ * returns the app-module path of the source file
566
+ *
567
+ * This assumes normal ember app conventions
568
+ *
569
+ * which is `<package.json#name>/path-to-file`
570
+ */
571
+ function appPath(sourcePath) {
572
+ let workspacePath = findWorkspacePath(sourcePath);
573
+ let name = moduleName(sourcePath);
574
+ /**
575
+ * Under embroider builds, the spec-compliant version of the app
576
+ * has all the files under a folder which represents the package name,
577
+ * rather than "app".
578
+ */
579
+ let packageRelative = sourcePath.replace(workspacePath, "");
580
+ /**
581
+ * But we also don't want 'app' -- which is present in the v1 addon pipeline
582
+ */
583
+ packageRelative = packageRelative.replace(leadingSlashPath.app, node_path.default.sep);
584
+ packageRelative = node_path.default.normalize(packageRelative);
585
+ return `${name}${packageScopedPathToModulePath(packageRelative)}`;
586
+ }
587
+ /**
588
+ * To avoid hitting the filesysetm, we'll store all found
589
+ * project paths bere, so we can, in memory,
590
+ * get the folder where a package.json exists, rather than
591
+ * hit the file system every time.
592
+ */
593
+ const SEEN = /* @__PURE__ */ new Set();
594
+ function getSeen(sourcePath) {
595
+ if (SEEN.has(sourcePath)) return sourcePath;
596
+ let parts = sourcePath.split(node_path.default.sep);
597
+ for (let i = parts.length - 1; i > 1; i--) {
598
+ let toCheck = parts.slice(0, i).join(node_path.default.sep);
599
+ if (SEEN.has(toCheck)) return toCheck;
600
+ }
601
+ }
602
+ function findWorkspacePath(sourcePath, options) {
603
+ let cwd = options?.cwd ?? CWD;
604
+ if (sourcePath.endsWith(node_path.default.sep)) sourcePath = sourcePath.replace(/* @__PURE__ */ new RegExp(`${RegExp.escape(node_path.default.sep)}$`), "");
605
+ let seen = getSeen(sourcePath);
606
+ if (seen) return seen;
607
+ let candidatePath = node_path.default.join(sourcePath, "package.json");
608
+ if (node_fs.default.existsSync(candidatePath)) return sourcePath;
609
+ const packageJsonPath = findPackageJsonUp(sourcePath, { cwd });
610
+ if (!packageJsonPath) throw new Error(`Could not determine project for ${sourcePath}`);
611
+ const workspacePath = node_path.default.dirname(packageJsonPath);
612
+ SEEN.add(workspacePath);
613
+ return workspacePath;
614
+ }
615
+ function findPackageJsonUp(startPath, options) {
616
+ let cwd = options?.cwd ?? CWD;
617
+ let parts = startPath.split(node_path.default.sep);
618
+ for (let i = parts.length - 1; i > 1; i--) {
619
+ let toCheck = parts.slice(0, i).join(node_path.default.sep);
620
+ let packageJson = node_path.default.join(toCheck, "package.json");
621
+ if (node_fs.default.existsSync(packageJson)) return packageJson;
622
+ if (toCheck === cwd) break;
623
+ }
624
+ return null;
625
+ }
626
+ const MANIFEST_CACHE = /* @__PURE__ */ new Map();
627
+ /**
628
+ * Will return the package.json#name, or config/environment#moudlePrefix (if v1 app)
629
+ *
630
+ * @param {string} sourcePath
631
+ */
632
+ function moduleName(sourcePath) {
633
+ return getManifest(findWorkspacePath(sourcePath)).name;
634
+ }
635
+ /**
636
+ * @param {string} workspace
637
+ */
638
+ function getManifest(workspace) {
639
+ let existing = MANIFEST_CACHE.get(workspace);
640
+ if (existing) return existing;
641
+ let content = node_fs.default.readFileSync(node_path.default.join(workspace, "package.json")).toString();
642
+ let json = JSON.parse(content);
643
+ MANIFEST_CACHE.set(workspace, json);
644
+ return json;
645
+ }
646
+
647
+ //#endregion
648
+ //#region src/build/babel-plugin.js
649
+ function _isRelevantFile(state, cwd) {
650
+ let fileName = state.file.opts.filename;
651
+ let additionalRoots = state.opts?.additionalRoots;
652
+ return isRelevantFile(fileName, {
653
+ additionalRoots,
654
+ cwd
655
+ });
656
+ }
657
+ /**
658
+ * @param {any} env - babel plugin env, env.types is most commonly used (esp in TS)
659
+ * @param {object} options - the options for scoped-css -- this is also available in each visitor's state.opts
660
+ * @param {string} workingDirectory
661
+ */
662
+ const scopedCSS$1 = (config) => (env, options, workingDirectory) => {
663
+ options = {
664
+ ...config,
665
+ ...options
666
+ };
667
+ /**
668
+ * This babel plugin does two things:
669
+ * - removes the import of scopedClass, if it exists
670
+ * - if scopedClass was imported, it is removed from any component's "scope bag"
671
+ * (the scope bag being a low-level object used for passing what is "in scope" for a component)
672
+ */
673
+ return { visitor: {
674
+ Program: { enter(path$8, state) {
675
+ if (!_isRelevantFile(state, workingDirectory)) {
676
+ state.canSkip = true;
677
+ return;
678
+ }
679
+ } },
680
+ ImportDeclaration(path$8, state) {
681
+ if (state.canSkip) return;
682
+ if (path$8.node.source.value === "ember-scoped-css") {
683
+ let specifier = path$8.node.specifiers.find((x) => x.imported.name === "scopedClass");
684
+ if (specifier) state.file.opts.importedScopedClass = specifier.local.name;
685
+ 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.`);
686
+ path$8.remove();
687
+ }
688
+ },
689
+ ObjectProperty(path$8, state) {
690
+ if (!state.file.opts?.importedScopedClass) return;
691
+ if (path$8.node.value.type === "Identifier" && path$8.node.value.name === state.file.opts?.importedScopedClass) path$8.remove();
692
+ }
693
+ } };
694
+ };
695
+
696
+ //#endregion
697
+ //#region src/lib/css/utils.js
698
+ /**
699
+ * @param {string} css
700
+ * @return {string} hashed down version of the CSS for disambiguating
701
+ */
702
+ function hash(css) {
703
+ return `css-${md5(css)}`;
704
+ }
705
+ function isInsideGlobal(node, func) {
706
+ const parent = node.parent;
707
+ if (!parent) return false;
708
+ if (parent.type === "pseudo" && parent.value === ":global") return true;
709
+ return isInsideGlobal(parent, func);
710
+ }
711
+ /**
712
+ * @param {string} cssPath path to a CSS file
713
+ */
714
+ function getCSSInfo(cssPath) {
715
+ if (!(0, fs.existsSync)(cssPath)) return null;
716
+ return getCSSContentInfo((0, fs.readFileSync)(cssPath, "utf8"));
717
+ }
718
+ /**
719
+ * We use this function to check each class used in the template
720
+ * to see if we need to leave it alone or transform it
721
+ *
722
+ * @param {string} css the CSS's contents
723
+ * @return {{ classes: Set<string>, tags: Set<string>, css: string, id: string }}
724
+ */
725
+ function getCSSContentInfo(css) {
726
+ const classes = /* @__PURE__ */ new Set();
727
+ const tags = /* @__PURE__ */ new Set();
728
+ postcss.default.parse(css).walk((node) => {
729
+ if (node.type === "rule") getClassesAndTags(node.selector, classes, tags);
730
+ });
731
+ return {
732
+ classes,
733
+ tags,
734
+ css,
735
+ id: hash(css)
736
+ };
737
+ }
738
+ function getClassesAndTags(sel, classes, tags) {
739
+ const transform = (sls) => {
740
+ sls.walk((selector) => {
741
+ if (selector.type === "class" && !isInsideGlobal(selector)) classes.add(selector.value);
742
+ else if (selector.type === "tag" && !isInsideGlobal(selector)) tags.add(selector.value);
743
+ });
744
+ };
745
+ (0, postcss_selector_parser.default)(transform).processSync(sel);
746
+ }
747
+
748
+ //#endregion
749
+ //#region src/lib/css/rewrite.js
750
+ const SEP$1 = "__";
751
+ function isRule(node) {
752
+ return node.type === "rule";
753
+ }
754
+ function isDeclaration(node) {
755
+ return node.type === "decl";
756
+ }
757
+ /**
758
+ * NOTE: "keyframes" is a singular definition, in that it's a block containing keyframes
759
+ * using `@keyframes {}` with only one thing on the inside doesn't make sense.
760
+ */
761
+ function rewriteReferencable(node, postfix) {
762
+ let originalName = node.params;
763
+ let postfixedName = node.params + SEP$1 + postfix;
764
+ node.params = postfixedName;
765
+ return {
766
+ originalName,
767
+ postfixedName
768
+ };
769
+ }
770
+ function rewriteSelector(sel, postfix) {
771
+ const transform = (selectors) => {
772
+ selectors.walk((selector) => {
773
+ if (isInsideGlobal(selector)) return;
774
+ if (selector.type === "psuedo") return;
775
+ if (isNthOfType(selector)) return;
776
+ if (selector.type === "class") selector.value += "_" + postfix;
777
+ else if (selector.type === "tag") selector.replaceWith(postcss_selector_parser.default.tag({ value: selector.value }), postcss_selector_parser.default.className({ value: postfix }));
778
+ });
779
+ selectors.walk((selector) => {
780
+ if (selector.type === "pseudo" && selector.value === ":global") selector.replaceWith(...selector.nodes);
781
+ });
782
+ };
783
+ return (0, postcss_selector_parser.default)(transform).processSync(sel);
784
+ }
785
+ function isNthOfType(node) {
786
+ if (!node) return false;
787
+ return node.parent?.value === ":nth-of-type" || isNthOfType(node.parent);
788
+ }
789
+ function isInsideKeyframes(node) {
790
+ const parent = node.parent;
791
+ if (!parent) return false;
792
+ if (parent.type === "atrule" && parent.name === "keyframes") return true;
793
+ return isInsideKeyframes(parent);
794
+ }
795
+ function rewriteCss(css, postfix, fileName, layerName) {
796
+ const ast = postcss.default.parse(css);
797
+ /**
798
+ * kind => originalName => postfixedName
799
+ * @type {{ [kind: string]: { [originalName: string]: string }}}
800
+ */
801
+ const referencables = {
802
+ keyframes: {},
803
+ "counter-style": {},
804
+ "position-try": {},
805
+ property: {}
806
+ };
807
+ const availableReferencables = new Set(Object.keys(referencables));
808
+ function isReferencable(node) {
809
+ if (node.type !== "atrule") return;
810
+ return availableReferencables.has(node.name);
811
+ }
812
+ function updateDirectReferences(node) {
813
+ if (!node.value) return;
814
+ for (let [, map] of Object.entries(referencables)) if (map[node.value]) node.value = map[node.value];
815
+ }
816
+ function updateShorthandContents(node) {
817
+ if (node.prop === "animation") {
818
+ let match = node.value.split(" ").filter((x) => referencables.keyframes[x]);
819
+ if (match.length) match.forEach((x) => {
820
+ let replacement = referencables.keyframes[x];
821
+ if (!replacement) return;
822
+ node.value = node.value.replace(x, replacement);
823
+ });
824
+ }
825
+ for (let [lookFor, replaceWith] of Object.entries(referencables.property)) {
826
+ let lookForVar = `var(${lookFor})`;
827
+ let replaceWithVar = `var(${replaceWith})`;
828
+ node.value = node.value.replace(lookForVar, replaceWithVar);
829
+ }
830
+ }
831
+ /**
832
+ * We have to do two passes:
833
+ * 1. postfix all the referencable syntax
834
+ * 2. postfix as normal, but also checking values of CSS properties
835
+ * that could match postfixed referencables from step 1
836
+ */
837
+ ast.walk((node) => {
838
+ /**
839
+ * @keyframes, @counter-style, etc
840
+ */
841
+ if (isReferencable(node)) {
842
+ let name = node.name;
843
+ let { originalName, postfixedName } = rewriteReferencable(node, postfix);
844
+ referencables[name][originalName] = postfixedName;
845
+ return;
846
+ }
847
+ });
848
+ ast.walk((node) => {
849
+ if (isDeclaration(node)) {
850
+ updateDirectReferences(node);
851
+ updateShorthandContents(node);
852
+ return;
853
+ }
854
+ if (isRule(node)) {
855
+ /**
856
+ * The inner-contents of a keyframe are percentages, rather than selectors
857
+ */
858
+ if (isInsideKeyframes(node)) return;
859
+ node.selector = rewriteSelector(node.selector, postfix);
860
+ return;
861
+ }
862
+ });
863
+ const rewrittenCss = ast.toString();
864
+ return [
865
+ `/* ${fileName} */`,
866
+ layerName ? `@layer ${layerName} {` : "",
867
+ rewrittenCss.trimEnd(),
868
+ layerName ? `}` : ""
869
+ ].filter(Boolean).join("\n") + "\n";
870
+ }
871
+
872
+ //#endregion
873
+ //#region src/lib/request.js
874
+ const KEY = "ember-scoped.css";
875
+ const SEP = "___";
876
+ const request = {
877
+ is: {
878
+ inline(request$1) {
879
+ return request$1.includes(KEY);
880
+ },
881
+ colocated(request$1) {
882
+ return request$1.includes(".css?scoped=");
883
+ }
884
+ },
885
+ inline: {
886
+ create(cssHash, postfix, cssContents) {
887
+ return `./${postfix}${SEP}${cssHash}.${KEY}?css=${encodeURIComponent(cssContents)}`;
888
+ },
889
+ decode(request$1) {
890
+ let [left, qps] = request$1.split("?");
891
+ left = left.slice(2).replace(`.${KEY}`, "");
892
+ let [postfix, hash$2] = left.split(SEP);
893
+ let search = new URLSearchParams(qps);
894
+ return {
895
+ hash: hash$2,
896
+ postfix,
897
+ css: search.get("css"),
898
+ from: search.get("from")
899
+ };
900
+ }
901
+ },
902
+ colocated: {
903
+ create(cssHash, postfix, filePath) {
904
+ return `./${node_path.default.basename(filePath)}?scoped=${postfix}&cssHash=${cssHash}`;
905
+ },
906
+ decode(request$1) {
907
+ const [fileName, qs] = request$1.split("?");
908
+ const search = new URLSearchParams(qs);
909
+ return {
910
+ fileName,
911
+ cssHash: search.get("cssHash"),
912
+ postfix: search.get("scoped")
913
+ };
914
+ }
915
+ }
916
+ };
917
+
918
+ //#endregion
919
+ //#region src/build/unplugin-colocated.js
920
+ const META$1 = "scoped-css:colocated";
921
+ /**
922
+ * Plugin for supporting colocated styles
923
+ *
924
+ * e.g.:
925
+ * src/components/my-component.js
926
+ * src/components/my-component.css
927
+ */
928
+ function colocated(options = {}) {
929
+ const CWD$1 = process.cwd();
930
+ /**
931
+ *
932
+ * @param {string} id the request id / what was imported
933
+ * @param {string} filePath path on disk
934
+ * @returns
935
+ */
936
+ function buildResponse(id, filePath) {
937
+ const parsed = request.colocated.decode(id);
938
+ const relativeFilePath = node_path.default.relative(CWD$1, filePath);
939
+ return {
940
+ id: filePath,
941
+ meta: { [META$1]: {
942
+ postfix: parsed.postfix,
943
+ fileName: relativeFilePath,
944
+ fullPath: filePath
945
+ } }
946
+ };
947
+ }
948
+ return {
949
+ name: "ember-scoped-css:colocated",
950
+ resolveId(id, importer) {
951
+ if (request.is.colocated(id)) {
952
+ const parsed = request.colocated.decode(id);
953
+ const filePath = node_path.default.resolve(node_path.default.dirname(importer), node_path.default.basename(parsed.fileName));
954
+ /**
955
+ * Rollup doesn't normally watch CSS files
956
+ */
957
+ this.addWatchFile(filePath);
958
+ return buildResponse(id, filePath);
959
+ }
960
+ },
961
+ load(id) {
962
+ const meta = this.getModuleInfo(id)?.meta?.[META$1];
963
+ if (meta) return rewriteCss((0, node_fs.readFileSync)(meta.fullPath, "utf-8"), meta.postfix, meta.fileName, options.layerName);
964
+ },
965
+ vite: { load(id) {
966
+ if (request.is.colocated(id)) {
967
+ const parsed = request.colocated.decode(id);
968
+ let code = (0, node_fs.readFileSync)(parsed.fileName, "utf-8");
969
+ let relativeFilePath = node_path.default.relative(CWD$1, parsed.fileName);
970
+ return rewriteCss(code, parsed.postfix, relativeFilePath, options.layerName);
971
+ }
972
+ } }
973
+ };
974
+ }
975
+
976
+ //#endregion
977
+ //#region src/build/unplugin-inline.js
978
+ const META = "scoped-css:inline";
979
+ /**
980
+ * Plugin for supporting the styles from
981
+ *
982
+ * <template>
983
+ * <style>...</style>
984
+ * </template>
985
+ *
986
+ * This plugin can't have HMR for CSS because changes to the CSS content alters the template content
987
+ */
988
+ function inline(options = {}) {
989
+ const CWD$1 = process.cwd();
990
+ /**
991
+ * @param {string} id the request id / what was imported
992
+ */
993
+ function buildResponse(id, filePath) {
994
+ const parsed = request.inline.decode(id);
995
+ const relativeFilePath = node_path.default.relative(CWD$1, filePath);
996
+ const css = rewriteCss(parsed.css, parsed.postfix, `<inline>/${relativeFilePath}`, options.layerName);
997
+ return {
998
+ id: filePath.split("?")[0],
999
+ meta: { [META]: {
1000
+ css,
1001
+ postfix: parsed.postfix,
1002
+ fileName: relativeFilePath
1003
+ } }
1004
+ };
1005
+ }
1006
+ return {
1007
+ name: "ember-scoped-css:inline",
1008
+ resolveId(id, importer) {
1009
+ if (request.is.inline(id)) {
1010
+ const parsed = request.inline.decode(id);
1011
+ 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`));
1012
+ }
1013
+ },
1014
+ load(id) {
1015
+ const meta = this.getModuleInfo(id)?.meta?.[META];
1016
+ if (meta) return meta.css;
1017
+ }
1018
+ };
1019
+ }
1020
+
1021
+ //#endregion
1022
+ //#region src/build/scoped-css-unplugin.js
1023
+ /**
1024
+ * The plugin that handles CSS requests for `<style>` elements and transforms
1025
+ * for existing files
1026
+ *
1027
+ * vite: CSS files are resolved by vite. We use their resolver to also get
1028
+ * HMR. That is, for all non-physical CSS files, we extend vite by our
1029
+ * resolver and also can enrich metadata to it (for better debugging)
1030
+ */
1031
+ const unplugin$1 = (0, unplugin.createUnplugin)((options = {}) => {
1032
+ return [colocated(options), inline(options)];
1033
+ });
1034
+
1035
+ //#endregion
1036
+ //#region src/lib/path/template-transform-paths.js
1037
+ /**
1038
+ * template plugins do not hand us the correct file path.
1039
+ * additionally, we may not be able to rely on this data in the future,
1040
+ * so this functions acts as a means of normalizing _whatever_ we're given
1041
+ * in the future.
1042
+ *
1043
+ * @param {string} filename
1044
+ * @returns {string} the absolute path to the file
1045
+ */
1046
+ function fixFilename(filename) {
1047
+ let fileName = filename;
1048
+ let workspace = findWorkspacePath(fileName);
1049
+ /**
1050
+ * ember-source 5.8:
1051
+ * - the filename looks like an absolute path, but swapped out the 'app' part of the path
1052
+ * with the module name, so the file paths never exist on disk
1053
+ *
1054
+ * - in vite apps:
1055
+ * the 'app' part _may_ be `src`, so we also need to ensure that `src` is excluded as well
1056
+ */
1057
+ let hasAppDir = fileName.includes(node_path.default.join(workspace, "app"));
1058
+ let hasSrcDir = fileName.includes(node_path.default.join(workspace, "src"));
1059
+ if (!(hasAppDir || hasSrcDir) && !fileName.includes(leadingSlashPath.embroiderDir)) {
1060
+ let [maybeScope, ...rest] = fileName.replace(workspace, "").split(node_path.default.sep).filter(Boolean);
1061
+ let parts = rest;
1062
+ if (maybeScope.startsWith("@")) {
1063
+ let [, ...rester] = rest;
1064
+ parts = rester;
1065
+ }
1066
+ let relative = node_path.default.join(...parts);
1067
+ return node_path.default.join(workspace, "app", relative);
1068
+ }
1069
+ if (!fileName.includes(workspace)) return fileName;
1070
+ return fileName;
1071
+ }
1072
+
1073
+ //#endregion
1074
+ //#region src/lib/renameClass.js
1075
+ /**
1076
+ *
1077
+ * @param {string} className
1078
+ * @param {string} postfix
1079
+ * @param {Set<string>} [classesInCss]
1080
+ * @returns
1081
+ */
1082
+ function renameClass(className, postfix, classesInCss) {
1083
+ const renamedClasses = className.split(/\s+/).filter((c) => c).map((c) => c.trim()).map((c) => {
1084
+ if (!classesInCss || classesInCss.has(c)) {
1085
+ if (c.endsWith(postfix)) return c;
1086
+ return c + "_" + postfix;
1087
+ }
1088
+ return c;
1089
+ }).join(" ");
1090
+ return className.replace(className.trimStart().trimEnd(), renamedClasses);
1091
+ }
1092
+
1093
+ //#endregion
1094
+ //#region src/lib/rewriteHbs.js
1095
+ function templatePlugin({ classes, tags, postfix }) {
1096
+ let stack = [];
1097
+ let scopedClassCandidates = ["scoped-class", "scopedClass"];
1098
+ function isScopedClass(str) {
1099
+ if (!str) return false;
1100
+ return scopedClassCandidates.some((candidate) => candidate === str);
1101
+ }
1102
+ return {
1103
+ AttrNode(node) {
1104
+ if (node.name === "class") {
1105
+ if (node.value.type === "TextNode" && node.value.chars) {
1106
+ const renamedClass = renameClass(node.value.chars, postfix, classes);
1107
+ node.value.chars = renamedClass;
1108
+ } else if (node.value.type === "ConcatStatement") {
1109
+ for (let part of node.value.parts) if (part.type === "TextNode" && part.chars) part.chars = renameClass(part.chars, postfix, classes);
1110
+ else if (part.type === "MustacheStatement") ember_template_recast.default.traverse(part, { StringLiteral(node$1) {
1111
+ node$1.value = renameClass(node$1.value, postfix, classes);
1112
+ } });
1113
+ }
1114
+ }
1115
+ },
1116
+ ElementNode(node) {
1117
+ if (tags.has(node.tag)) {
1118
+ const classAttr = node.attributes.find((attr) => attr.name === "class");
1119
+ if (classAttr) classAttr.value.chars += " " + postfix;
1120
+ else node.attributes.push(ember_template_recast.default.builders.attr("class", ember_template_recast.default.builders.text(postfix)));
1121
+ }
1122
+ },
1123
+ All: {
1124
+ enter(node) {
1125
+ stack.push(node);
1126
+ },
1127
+ exit() {
1128
+ stack.pop();
1129
+ }
1130
+ },
1131
+ MustacheStatement(node) {
1132
+ let cssClass;
1133
+ if (isScopedClass(getValue(node.path)) && node.params?.length === 1 && node.params[0].type === "StringLiteral") cssClass = node.params[0].value;
1134
+ if (isScopedClass(getValue(node.path?.path)) && node.path?.params?.length === 1 && node.path?.params[0].type === "StringLiteral") cssClass = node.path.params[0].value;
1135
+ if (cssClass) {
1136
+ const textNode = ember_template_recast.default.builders.text(renameClass(cssClass, postfix));
1137
+ const parent = stack[stack.length - 1];
1138
+ if (parent?.type === "AttrNode") parent.quoteType = "\"";
1139
+ return textNode;
1140
+ }
1141
+ },
1142
+ SubExpression(node) {
1143
+ if (isScopedClass(getValue(node.path)) && node.params?.length === 1 && node.params[0].type === "StringLiteral") {
1144
+ const cssClass = node.params[0].value;
1145
+ return ember_template_recast.default.builders.literal("StringLiteral", renameClass(cssClass, postfix));
1146
+ }
1147
+ }
1148
+ };
1149
+ }
1150
+ function getValue(path$8) {
1151
+ if (!path$8) return;
1152
+ if ("value" in path$8) return path$8.value;
1153
+ /**
1154
+ * Deprecated in ember 5.9+
1155
+ * (so we use the above for newer embers)
1156
+ */
1157
+ return path$8.original;
1158
+ }
1159
+
1160
+ //#endregion
1161
+ //#region src/build/template-plugin.js
1162
+ const noopPlugin = {
1163
+ name: "ember-scoped-css:noop",
1164
+ visitor: {}
1165
+ };
1166
+ /**
1167
+ * @returns {ASTPlugin}
1168
+ */
1169
+ function createPlugin(config) {
1170
+ /**
1171
+ *
1172
+ * @param {ASTPluginEnvironment} env
1173
+ */
1174
+ return function scopedCss(env) {
1175
+ let cwd = node_process.default.cwd();
1176
+ if (!isRelevantFile(env.filename, {
1177
+ additionalRoots: config.additionalRoots,
1178
+ cwd
1179
+ })) return noopPlugin;
1180
+ let absolutePath = fixFilename(env.filename);
1181
+ let postfix = hashFromModulePath(appPath(absolutePath));
1182
+ /**
1183
+ * The list of naked tag selectors found in the CSS
1184
+ *
1185
+ * @type {Set<string>}
1186
+ */
1187
+ let scopedTags = /* @__PURE__ */ new Set();
1188
+ /**
1189
+ * The list of classes found in the CSS
1190
+ *
1191
+ * @type {Set<string>}
1192
+ */
1193
+ let scopedClasses = /* @__PURE__ */ new Set();
1194
+ /**
1195
+ * @param {{ tags: Set<string>; classes: Set<string> }} info
1196
+ */
1197
+ function addInfo(info$1) {
1198
+ for (let item of info$1.tags) scopedTags.add(item);
1199
+ for (let item of info$1.classes) scopedClasses.add(item);
1200
+ }
1201
+ let cssPath = cssPathFor(absolutePath);
1202
+ let info = getCSSInfo(cssPath);
1203
+ let localCssPath = forcePosix(cssPath.replace(cwd + node_path.default.sep, ""));
1204
+ /**
1205
+ * This will be falsey if we don't have a co-located CSS file.
1206
+ * We'll still want to check for embedded <style scoped> tags though.
1207
+ */
1208
+ if (info) {
1209
+ addInfo(info);
1210
+ let cssRequest = request.colocated.create(info.id, postfix, localCssPath);
1211
+ /**
1212
+ * With this we don't need a JS plugin
1213
+ */
1214
+ env.meta.jsutils.importForSideEffect(cssRequest);
1215
+ }
1216
+ let visitors = templatePlugin({
1217
+ classes: scopedClasses,
1218
+ tags: scopedTags,
1219
+ postfix
1220
+ });
1221
+ return {
1222
+ name: "ember-scoped-css:template-plugin",
1223
+ visitor: {
1224
+ ...visitors,
1225
+ Template(node) {
1226
+ /**
1227
+ * We only allow a scoped <style> at the root
1228
+ */
1229
+ let styleTag = node.body.find((n) => n.type === "ElementNode" && n.tag === "style");
1230
+ if (hasScopedAttribute(styleTag)) {
1231
+ let css = textContent(styleTag);
1232
+ let info$1 = getCSSContentInfo(css);
1233
+ addInfo(info$1);
1234
+ /**
1235
+ * This will be handled in ElementNode traversal
1236
+ */
1237
+ if (hasInlineAttribute(styleTag)) return;
1238
+ let cssRequest = request.inline.create(info$1.id, postfix, css);
1239
+ env.meta.jsutils.importForSideEffect(cssRequest);
1240
+ }
1241
+ },
1242
+ AttrNode(...args) {
1243
+ return visitors.AttrNode(...args);
1244
+ },
1245
+ ElementNode(node, walker) {
1246
+ visitors.ElementNode(node, walker);
1247
+ if (hasScopedAttribute(node)) {
1248
+ if (walker.parent?.node.type !== "Template") throw new Error("<style scoped> tags must be at the root of the template, they cannot be nested");
1249
+ if (hasInlineAttribute(node)) {
1250
+ let scopedText = rewriteCss(textContent(node), postfix, localCssPath, config.layerName);
1251
+ /**
1252
+ * Traverse this and allow interpolation
1253
+ */
1254
+ node.children = [env.syntax.builders.text(scopedText)];
1255
+ return;
1256
+ }
1257
+ return null;
1258
+ }
1259
+ if (hasInlineAttribute(node)) throw new Error(`<style inline> is not valid. Please add the scoped attribute: <style scoped inline>`);
1260
+ },
1261
+ MustacheStatement(...args) {
1262
+ return visitors.MustacheStatement(...args);
1263
+ },
1264
+ SubExpression(...args) {
1265
+ return visitors.SubExpression(...args);
1266
+ }
1267
+ }
1268
+ };
1269
+ };
1270
+ }
1271
+ /**
1272
+ * Thanks, CardStack and @ef4 for this code.
1273
+ */
1274
+ const SCOPED_ATTRIBUTE_NAME = "scoped";
1275
+ const INLINE_ATTRIBUTE_NAME = "inline";
1276
+ function hasScopedAttribute(node) {
1277
+ if (!node) return;
1278
+ if (node.tag !== "style") return;
1279
+ if (node.type !== "ElementNode") return;
1280
+ return node.attributes.some((attribute) => attribute.name === SCOPED_ATTRIBUTE_NAME);
1281
+ }
1282
+ function hasInlineAttribute(node) {
1283
+ if (!node) return;
1284
+ if (node.tag !== "style") return;
1285
+ if (node.type !== "ElementNode") return;
1286
+ return node.attributes.some((attribute) => attribute.name === INLINE_ATTRIBUTE_NAME);
1287
+ }
1288
+ function textContent(node) {
1289
+ return node.children.filter((c) => c.type === "TextNode").map((c) => c.chars).join("");
1290
+ }
1291
+
1292
+ //#endregion
1293
+ //#region src/build/public-exports/all.js
1294
+ const scopedCSS = {
1295
+ vite: unplugin$1.vite,
1296
+ rollup: unplugin$1.rollup,
1297
+ babel: scopedCSS$1,
1298
+ template: createPlugin
1299
+ };
1300
+
1301
+ //#endregion
1302
+ Object.defineProperty(exports, 'scopedCSS', {
1303
+ enumerable: true,
1304
+ get: function () {
1305
+ return scopedCSS;
1306
+ }
1307
+ });
1308
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxsLUR1NDNjQmE5LmNqcyIsIm5hbWVzIjpbImhhc2giLCJoYXNoIiwiaGFzaEZyb21Nb2R1bGVQYXRoIiwiaGFzaFBvc2l4TW9kdWxlUGF0aCIsInBhdGgiLCJmc1N5bmMiLCJzY29wZWRDU1MiLCJwYXRoIiwiU0VQIiwicGFyc2VyIiwicmVxdWVzdCIsImhhc2giLCJwYXRoIiwiTUVUQSIsIkNXRCIsInBhdGgiLCJDV0QiLCJwYXRoIiwidW5wbHVnaW4iLCJwYXRoIiwibm9kZSIsInJlY2FzdCIsInBhdGgiLCJwcm9jZXNzIiwiaW5mbyIsInBhdGgiLCJ1bnBsdWdpbiIsImJhYmVsLnNjb3BlZENTUyIsInRlbXBsYXRlLmNyZWF0ZVBsdWdpbiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvcGF0aC9jb25zdC5qcyIsIi4uLy4uL3NyYy9saWIvcGF0aC9tZDUuanMiLCIuLi8uLi9zcmMvbGliL3BhdGgvaGFzaC1mcm9tLW1vZHVsZS1wYXRoLmpzIiwiLi4vLi4vc3JjL2xpYi9wYXRoL3V0aWxzLmpzIiwiLi4vLi4vc3JjL2J1aWxkL2JhYmVsLXBsdWdpbi5qcyIsIi4uLy4uL3NyYy9saWIvY3NzL3V0aWxzLmpzIiwiLi4vLi4vc3JjL2xpYi9jc3MvcmV3cml0ZS5qcyIsIi4uLy4uL3NyYy9saWIvcmVxdWVzdC5qcyIsIi4uLy4uL3NyYy9idWlsZC91bnBsdWdpbi1jb2xvY2F0ZWQuanMiLCIuLi8uLi9zcmMvYnVpbGQvdW5wbHVnaW4taW5saW5lLmpzIiwiLi4vLi4vc3JjL2J1aWxkL3Njb3BlZC1jc3MtdW5wbHVnaW4uanMiLCIuLi8uLi9zcmMvbGliL3BhdGgvdGVtcGxhdGUtdHJhbnNmb3JtLXBhdGhzLmpzIiwiLi4vLi4vc3JjL2xpYi9yZW5hbWVDbGFzcy5qcyIsIi4uLy4uL3NyYy9saWIvcmV3cml0ZUhicy5qcyIsIi4uLy4uL3NyYy9idWlsZC90ZW1wbGF0ZS1wbHVnaW4uanMiLCIuLi8uLi9zcmMvYnVpbGQvcHVibGljLWV4cG9ydHMvYWxsLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuXG4vKipcbiAqIEpvaW4gd2lsbCBjb252ZXJ0IHRvIHdoYXRldmVyIGlzIGFwcHJvcHJpYXRlIGZybyB0aGUgY3VycmVudCBwbGF0Zm9ybVxuICovXG5cbmV4cG9ydCBjb25zdCBsZWFkaW5nU2xhc2hQYXRoID0ge1xuICBlbWJyb2lkZXJEaXI6IHBhdGguam9pbignL25vZGVfbW9kdWxlcy8uZW1icm9pZGVyLycpLFxuICBhdEVtYnJvaWRlcjogcGF0aC5qb2luKCcvQGVtYnJvaWRlcicpLFxuICBjb21wb25lbnRzRGlyOiBwYXRoLmpvaW4oJy9jb21wb25lbnRzLycpLFxuICB0ZW1wbGF0ZXNEaXI6IHBhdGguam9pbignL3RlbXBsYXRlcy8nKSxcbiAgdGVzdGVtOiBwYXRoLmpvaW4oJy90ZXN0ZW0nKSxcbiAgc3JjOiBwYXRoLmpvaW4oJy9zcmMvJyksXG4gIGFwcDogcGF0aC5qb2luKCcvYXBwLycpLFxufTtcblxuZXhwb3J0IGNvbnN0IGJhcmVQYXRoID0ge1xuICBwbnBtRGlyOiBwYXRoLmpvaW4oJ25vZGVfbW9kdWxlcy8ucG5wbScpLFxufTtcbiIsIi8qXG4gKiBKYXZhU2NyaXB0IE1ENVxuICogaHR0cHM6Ly9naXRodWIuY29tL2JsdWVpbXAvSmF2YVNjcmlwdC1NRDVcbiAqXG4gKiBDb3B5cmlnaHQgMjAxMSwgU2ViYXN0aWFuIFRzY2hhblxuICogaHR0cHM6Ly9ibHVlaW1wLm5ldFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZTpcbiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXG4gKlxuICogQmFzZWQgb25cbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgUlNBIERhdGEgU2VjdXJpdHksIEluYy4gTUQ1IE1lc3NhZ2VcbiAqIERpZ2VzdCBBbGdvcml0aG0sIGFzIGRlZmluZWQgaW4gUkZDIDEzMjEuXG4gKiBWZXJzaW9uIDIuMiBDb3B5cmlnaHQgKEMpIFBhdWwgSm9obnN0b24gMTk5OSAtIDIwMDlcbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIG1vcmUgaW5mby5cbiAqXG4gKiBNb2RpZmljYXRpb25zOlxuICogLSByZW1vdmVkIElJRkUsIGV4cG9ydGVkIG1kNSAodGhpcyBmaWxlIGlzIG5vdyBFU00pXG4gKi9cblxuLyoqXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuXG4gKiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnMgaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIGludGVycHJldGVycy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0geCBGaXJzdCBpbnRlZ2VyXG4gKiBAcGFyYW0ge251bWJlcn0geSBTZWNvbmQgaW50ZWdlclxuICogQHJldHVybnMge251bWJlcn0gU3VtXG4gKi9cbmZ1bmN0aW9uIHNhZmVBZGQoeCwgeSkge1xuICB2YXIgbHN3ID0gKHggJiAweGZmZmYpICsgKHkgJiAweGZmZmYpO1xuICB2YXIgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG5cbiAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4ZmZmZik7XG59XG5cbi8qKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW0gMzItYml0IG51bWJlclxuICogQHBhcmFtIHtudW1iZXJ9IGNudCBSb3RhdGlvbiBjb3VudFxuICogQHJldHVybnMge251bWJlcn0gUm90YXRlZCBudW1iZXJcbiAqL1xuZnVuY3Rpb24gYml0Um90YXRlTGVmdChudW0sIGNudCkge1xuICByZXR1cm4gKG51bSA8PCBjbnQpIHwgKG51bSA+Pj4gKDMyIC0gY250KSk7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gcSBxXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1Y21uKHEsIGEsIGIsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIHNhZmVBZGQoYml0Um90YXRlTGVmdChzYWZlQWRkKHNhZmVBZGQoYSwgcSksIHNhZmVBZGQoeCwgdCkpLCBzKSwgYik7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0gYyBjXG4gKiBAcGFyYW0ge251bWJlcn0gZCBkXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1ZmYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKChiICYgYykgfCAofmIgJiBkKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0gYyBjXG4gKiBAcGFyYW0ge251bWJlcn0gZCBkXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1Z2coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKChiICYgZCkgfCAoYyAmIH5kKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0gYyBjXG4gKiBAcGFyYW0ge251bWJlcn0gZCBkXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1aGgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qKlxuICogQmFzaWMgb3BlcmF0aW9uIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYSBhXG4gKiBAcGFyYW0ge251bWJlcn0gYiBiXG4gKiBAcGFyYW0ge251bWJlcn0gYyBjXG4gKiBAcGFyYW0ge251bWJlcn0gZCBkXG4gKiBAcGFyYW0ge251bWJlcn0geCB4XG4gKiBAcGFyYW0ge251bWJlcn0gcyBzXG4gKiBAcGFyYW0ge251bWJlcn0gdCB0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXN1bHRcbiAqL1xuZnVuY3Rpb24gbWQ1aWkoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGMgXiAoYiB8IH5kKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIHRoZSBNRDUgb2YgYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3JkcywgYW5kIGEgYml0IGxlbmd0aC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSB4IEFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gQml0IGxlbmd0aFxuICogQHJldHVybnMge0FycmF5PG51bWJlcj59IE1ENSBBcnJheVxuICovXG5mdW5jdGlvbiBiaW5sTUQ1KHgsIGxlbikge1xuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xuICB4W2xlbiA+PiA1XSB8PSAweDgwIDw8IGxlbiAlIDMyO1xuICB4WygoKGxlbiArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNF0gPSBsZW47XG5cbiAgdmFyIGk7XG4gIHZhciBvbGRhO1xuICB2YXIgb2xkYjtcbiAgdmFyIG9sZGM7XG4gIHZhciBvbGRkO1xuICB2YXIgYSA9IDE3MzI1ODQxOTM7XG4gIHZhciBiID0gLTI3MTczMzg3OTtcbiAgdmFyIGMgPSAtMTczMjU4NDE5NDtcbiAgdmFyIGQgPSAyNzE3MzM4Nzg7XG5cbiAgZm9yIChpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KSB7XG4gICAgb2xkYSA9IGE7XG4gICAgb2xkYiA9IGI7XG4gICAgb2xkYyA9IGM7XG4gICAgb2xkZCA9IGQ7XG5cbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpXSwgNywgLTY4MDg3NjkzNik7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDFdLCAxMiwgLTM4OTU2NDU4Nik7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDJdLCAxNywgNjA2MTA1ODE5KTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgM10sIDIyLCAtMTA0NDUyNTMzMCk7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaSArIDRdLCA3LCAtMTc2NDE4ODk3KTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgNV0sIDEyLCAxMjAwMDgwNDI2KTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgNl0sIDE3LCAtMTQ3MzIzMTM0MSk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDddLCAyMiwgLTQ1NzA1OTgzKTtcbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpICsgOF0sIDcsIDE3NzAwMzU0MTYpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyA5XSwgMTIsIC0xOTU4NDE0NDE3KTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgMTBdLCAxNywgLTQyMDYzKTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2kgKyAxMl0sIDcsIDE4MDQ2MDM2ODIpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyAxM10sIDEyLCAtNDAzNDExMDEpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyAxNF0sIDE3LCAtMTUwMjAwMjI5MCk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDE1XSwgMjIsIDEyMzY1MzUzMjkpO1xuXG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDFdLCA1LCAtMTY1Nzk2NTEwKTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgNl0sIDksIC0xMDY5NTAxNjMyKTtcbiAgICBjID0gbWQ1Z2coYywgZCwgYSwgYiwgeFtpICsgMTFdLCAxNCwgNjQzNzE3NzEzKTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpXSwgMjAsIC0zNzM4OTczMDIpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyA1XSwgNSwgLTcwMTU1ODY5MSk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDEwXSwgOSwgMzgwMTYwODMpO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAxNV0sIDE0LCAtNjYwNDc4MzM1KTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpICsgNF0sIDIwLCAtNDA1NTM3ODQ4KTtcbiAgICBhID0gbWQ1Z2coYSwgYiwgYywgZCwgeFtpICsgOV0sIDUsIDU2ODQ0NjQzOCk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDE0XSwgOSwgLTEwMTk4MDM2OTApO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAzXSwgMTQsIC0xODczNjM5NjEpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2kgKyA4XSwgMjAsIDExNjM1MzE1MDEpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyAxM10sIDUsIC0xNDQ0NjgxNDY3KTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMl0sIDksIC01MTQwMzc4NCk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDddLCAxNCwgMTczNTMyODQ3Myk7XG4gICAgYiA9IG1kNWdnKGIsIGMsIGQsIGEsIHhbaSArIDEyXSwgMjAsIC0xOTI2NjA3NzM0KTtcblxuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyA1XSwgNCwgLTM3ODU1OCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaSArIDhdLCAxMSwgLTIwMjI1NzQ0NjMpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyAxMV0sIDE2LCAxODM5MDMwNTYyKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMTRdLCAyMywgLTM1MzA5NTU2KTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgMV0sIDQsIC0xNTMwOTkyMDYwKTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgNF0sIDExLCAxMjcyODkzMzUzKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgN10sIDE2LCAtMTU1NDk3NjMyKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMTBdLCAyMywgLTEwOTQ3MzA2NDApO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyAxM10sIDQsIDY4MTI3OTE3NCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaV0sIDExLCAtMzU4NTM3MjIyKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgM10sIDE2LCAtNzIyNTIxOTc5KTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgNl0sIDIzLCA3NjAyOTE4OSk7XG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDldLCA0LCAtNjQwMzY0NDg3KTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgMTJdLCAxMSwgLTQyMTgxNTgzNSk7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDE1XSwgMTYsIDUzMDc0MjUyMCk7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDJdLCAyMywgLTk5NTMzODY1MSk7XG5cbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpXSwgNiwgLTE5ODYzMDg0NCk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDddLCAxMCwgMTEyNjg5MTQxNSk7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDE0XSwgMTUsIC0xNDE2MzU0OTA1KTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgNV0sIDIxLCAtNTc0MzQwNTUpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2kgKyAxMl0sIDYsIDE3MDA0ODU1NzEpO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyAzXSwgMTAsIC0xODk0OTg2NjA2KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgMTBdLCAxNSwgLTEwNTE1MjMpO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyAxXSwgMjEsIC0yMDU0OTIyNzk5KTtcbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpICsgOF0sIDYsIDE4NzMzMTMzNTkpO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyAxNV0sIDEwLCAtMzA2MTE3NDQpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyA2XSwgMTUsIC0xNTYwMTk4MzgwKTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgMTNdLCAyMSwgMTMwOTE1MTY0OSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaSArIDRdLCA2LCAtMTQ1NTIzMDcwKTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyAyXSwgMTUsIDcxODc4NzI1OSk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDldLCAyMSwgLTM0MzQ4NTU1MSk7XG5cbiAgICBhID0gc2FmZUFkZChhLCBvbGRhKTtcbiAgICBiID0gc2FmZUFkZChiLCBvbGRiKTtcbiAgICBjID0gc2FmZUFkZChjLCBvbGRjKTtcbiAgICBkID0gc2FmZUFkZChkLCBvbGRkKTtcbiAgfVxuXG4gIHJldHVybiBbYSwgYiwgYywgZF07XG59XG5cbi8qKlxuICogQ29udmVydCBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzIHRvIGEgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBpbnB1dCBNRDUgQXJyYXlcbiAqIEByZXR1cm5zIHtzdHJpbmd9IE1ENSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gYmlubDJyc3RyKGlucHV0KSB7XG4gIHZhciBpO1xuICB2YXIgb3V0cHV0ID0gJyc7XG4gIHZhciBsZW5ndGgzMiA9IGlucHV0Lmxlbmd0aCAqIDMyO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBsZW5ndGgzMjsgaSArPSA4KSB7XG4gICAgb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGlucHV0W2kgPj4gNV0gPj4+IGkgJSAzMikgJiAweGZmKTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbi8qKlxuICogQ29udmVydCBhIHJhdyBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3Jkc1xuICogQ2hhcmFjdGVycyA+MjU1IGhhdmUgdGhlaXIgaGlnaC1ieXRlIHNpbGVudGx5IGlnbm9yZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IFJhdyBpbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtBcnJheTxudW1iZXI+fSBBcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzXG4gKi9cbmZ1bmN0aW9uIHJzdHIyYmlubChpbnB1dCkge1xuICB2YXIgaTtcbiAgdmFyIG91dHB1dCA9IFtdO1xuICBvdXRwdXRbKGlucHV0Lmxlbmd0aCA+PiAyKSAtIDFdID0gdW5kZWZpbmVkO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBvdXRwdXQubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBvdXRwdXRbaV0gPSAwO1xuICB9XG5cbiAgdmFyIGxlbmd0aDggPSBpbnB1dC5sZW5ndGggKiA4O1xuXG4gIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg4OyBpICs9IDgpIHtcbiAgICBvdXRwdXRbaSA+PiA1XSB8PSAoaW5wdXQuY2hhckNvZGVBdChpIC8gOCkgJiAweGZmKSA8PCBpICUgMzI7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgTUQ1IG9mIGEgcmF3IHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzIElucHV0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ30gUmF3IE1ENSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gcnN0ck1ENShzKSB7XG4gIHJldHVybiBiaW5sMnJzdHIoYmlubE1ENShyc3RyMmJpbmwocyksIHMubGVuZ3RoICogOCkpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIEhNQUMtTUQ1IG9mIGEga2V5IGFuZCBzb21lIGRhdGEgKHJhdyBzdHJpbmdzKVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgSE1BQyBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhIFJhdyBpbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJhdyBNRDUgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHJzdHJITUFDTUQ1KGtleSwgZGF0YSkge1xuICB2YXIgaTtcbiAgdmFyIGJrZXkgPSByc3RyMmJpbmwoa2V5KTtcbiAgdmFyIGlwYWQgPSBbXTtcbiAgdmFyIG9wYWQgPSBbXTtcbiAgdmFyIGhhc2g7XG4gIGlwYWRbMTVdID0gb3BhZFsxNV0gPSB1bmRlZmluZWQ7XG5cbiAgaWYgKGJrZXkubGVuZ3RoID4gMTYpIHtcbiAgICBia2V5ID0gYmlubE1ENShia2V5LCBrZXkubGVuZ3RoICogOCk7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkgKz0gMSkge1xuICAgIGlwYWRbaV0gPSBia2V5W2ldIF4gMHgzNjM2MzYzNjtcbiAgICBvcGFkW2ldID0gYmtleVtpXSBeIDB4NWM1YzVjNWM7XG4gIH1cblxuICBoYXNoID0gYmlubE1ENShpcGFkLmNvbmNhdChyc3RyMmJpbmwoZGF0YSkpLCA1MTIgKyBkYXRhLmxlbmd0aCAqIDgpO1xuXG4gIHJldHVybiBiaW5sMnJzdHIoYmlubE1ENShvcGFkLmNvbmNhdChoYXNoKSwgNTEyICsgMTI4KSk7XG59XG5cbi8qKlxuICogQ29udmVydCBhIHJhdyBzdHJpbmcgdG8gYSBoZXggc3RyaW5nXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IFJhdyBpbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJpbmd9IEhleCBlbmNvZGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiByc3RyMmhleChpbnB1dCkge1xuICB2YXIgaGV4VGFiID0gJzAxMjM0NTY3ODlhYmNkZWYnO1xuICB2YXIgb3V0cHV0ID0gJyc7XG4gIHZhciB4O1xuICB2YXIgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpICs9IDEpIHtcbiAgICB4ID0gaW5wdXQuY2hhckNvZGVBdChpKTtcbiAgICBvdXRwdXQgKz0gaGV4VGFiLmNoYXJBdCgoeCA+Pj4gNCkgJiAweDBmKSArIGhleFRhYi5jaGFyQXQoeCAmIDB4MGYpO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBFbmNvZGUgYSBzdHJpbmcgYXMgVVRGLThcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgSW5wdXQgc3RyaW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBVVEY4IHN0cmluZ1xuICovXG5mdW5jdGlvbiBzdHIycnN0clVURjgoaW5wdXQpIHtcbiAgcmV0dXJuIHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChpbnB1dCkpO1xufVxuXG4vKipcbiAqIEVuY29kZXMgaW5wdXQgc3RyaW5nIGFzIHJhdyBNRDUgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHMgSW5wdXQgc3RyaW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSYXcgTUQ1IHN0cmluZ1xuICovXG5mdW5jdGlvbiByYXdNRDUocykge1xuICByZXR1cm4gcnN0ck1ENShzdHIycnN0clVURjgocykpO1xufVxuXG4vKipcbiAqIEVuY29kZXMgaW5wdXQgc3RyaW5nIGFzIEhleCBlbmNvZGVkIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzIElucHV0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ30gSGV4IGVuY29kZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGhleE1ENShzKSB7XG4gIHJldHVybiByc3RyMmhleChyYXdNRDUocykpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHJhdyBITUFDLU1ENSBmb3IgdGhlIGdpdmVuIGtleSBhbmQgZGF0YVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrIEhNQUMga2V5XG4gKiBAcGFyYW0ge3N0cmluZ30gZCBJbnB1dCBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJhdyBNRDUgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHJhd0hNQUNNRDUoaywgZCkge1xuICByZXR1cm4gcnN0ckhNQUNNRDUoc3RyMnJzdHJVVEY4KGspLCBzdHIycnN0clVURjgoZCkpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIEhleCBlbmNvZGVkIEhNQUMtTUQ1IGZvciB0aGUgZ2l2ZW4ga2V5IGFuZCBkYXRhXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGsgSE1BQyBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSBkIElucHV0IHN0cmluZ1xuICogQHJldHVybnMge3N0cmluZ30gUmF3IE1ENSBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gaGV4SE1BQ01ENShrLCBkKSB7XG4gIHJldHVybiByc3RyMmhleChyYXdITUFDTUQ1KGssIGQpKTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGVzIE1ENSB2YWx1ZSBmb3IgYSBnaXZlbiBzdHJpbmcuXG4gKiBJZiBhIGtleSBpcyBwcm92aWRlZCwgY2FsY3VsYXRlcyB0aGUgSE1BQy1NRDUgdmFsdWUuXG4gKiBSZXR1cm5zIGEgSGV4IGVuY29kZWQgc3RyaW5nIHVubGVzcyB0aGUgcmF3IGFyZ3VtZW50IGlzIGdpdmVuLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgSW5wdXQgc3RyaW5nXG4gKiBAcGFyYW0ge3N0cmluZ30gW2tleV0gSE1BQyBrZXlcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Jhd10gUmF3IG91dHB1dCBzd2l0Y2hcbiAqIEByZXR1cm5zIHtzdHJpbmd9IE1ENSBvdXRwdXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1kNShzdHJpbmcsIGtleSwgcmF3KSB7XG4gIGlmICgha2V5KSB7XG4gICAgaWYgKCFyYXcpIHtcbiAgICAgIHJldHVybiBoZXhNRDUoc3RyaW5nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmF3TUQ1KHN0cmluZyk7XG4gIH1cblxuICBpZiAoIXJhdykge1xuICAgIHJldHVybiBoZXhITUFDTUQ1KGtleSwgc3RyaW5nKTtcbiAgfVxuXG4gIHJldHVybiByYXdITUFDTUQ1KGtleSwgc3RyaW5nKTtcbn1cbiIsImltcG9ydCB7IG1kNSB9IGZyb20gJy4vbWQ1LmpzJztcblxuLyoqXG4gKiBUaGUgaW50ZW50IG9mIHRoaXMgZnVuY3Rpb24gaXMgdG8gZ2VuZXJhdGUgdGhlIHN1ZmZpeC9wb3N0Zml4IGZvciB0aGVcbiAqIGNzcyBjbGFzc2VzLCBiYXNlZCBvbiB0aGUgbW9kdWxlLXNjb3BlZCBwYXRoIG5hbWUuXG4gKlxuICogZm9yIGV4YW1wbGUsXG4gKiAgICBoYXNoKCdteS1hcHAvY29tcG9uZW50cy9mb28nKVxuICogIGluc3RlYWQgb2ZcbiAqICAgIGhhc2goJ2FwcC9jb21wb25lbnRzL2ZvbycpXG4gKlxuICogICh1bmxlc3MgeW91ciBhcHAgbmFtZSBpcyAnYXBwJylcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlUGF0aFxuICogQHJldHVybnMge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc2gobW9kdWxlUGF0aCkge1xuICByZXR1cm4gJ2UnICsgbWQ1KG1vZHVsZVBhdGgpLnN1YnN0cmluZygwLCA4KTtcbn1cblxuaWYgKGltcG9ydC5tZXRhLnZpdGVzdCkge1xuICBjb25zdCB7IGl0LCBleHBlY3QgfSA9IGltcG9ydC5tZXRhLnZpdGVzdDtcblxuICBpdCgnc2hvdWxkIHJldHVybiBhIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBwb3N0Zml4ID0gaGFzaCgnZm9vLmNzcycpO1xuXG4gICAgZXhwZWN0KHBvc3RmaXgpLnRvLmJlLmEoJ3N0cmluZycpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJldHVybiBhIHN0cmluZyBzdGFydGluZyB3aXRoIFwiZVwiJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHBvc3RmaXggPSBoYXNoKCdmb28uY3NzJyk7XG5cbiAgICBleHBlY3QocG9zdGZpeCkudG8ubWF0Y2goL15lLyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmV0dXJuIGEgc3RyaW5nIG9mIGxlbmd0aCA5JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHBvc3RmaXggPSBoYXNoKCdmb28uY3NzJyk7XG5cbiAgICBleHBlY3QocG9zdGZpeCkudG8uaGF2ZS5sZW5ndGhPZig5KTtcbiAgfSk7XG59XG5cbmV4cG9ydCBjb25zdCBoYXNoRnJvbU1vZHVsZVBhdGggPSBoYXNoO1xuIiwiaW1wb3J0IGFzc2VydCBmcm9tICdub2RlOmFzc2VydCc7XG5pbXBvcnQgZnNTeW5jLCB7IGV4aXN0c1N5bmMgfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tICdub2RlOm1vZHVsZSc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuXG5pbXBvcnQgeyBiYXJlUGF0aCwgbGVhZGluZ1NsYXNoUGF0aCB9IGZyb20gJy4vY29uc3QuanMnO1xuaW1wb3J0IHsgaGFzaEZyb21BYnNvbHV0ZVBhdGggfSBmcm9tICcuL2hhc2gtZnJvbS1hYnNvbHV0ZS1wYXRoLmpzJztcbmltcG9ydCB7IGhhc2hGcm9tTW9kdWxlUGF0aCBhcyBoYXNoUG9zaXhNb2R1bGVQYXRoIH0gZnJvbSAnLi9oYXNoLWZyb20tbW9kdWxlLXBhdGguanMnO1xuXG5leHBvcnQgeyBoYXNoRnJvbUFic29sdXRlUGF0aCB9IGZyb20gJy4vaGFzaC1mcm9tLWFic29sdXRlLXBhdGguanMnO1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoRnJvbU1vZHVsZVBhdGgoZmlsZVBhdGgpIHtcbiAgbGV0IHBvc2l4UGF0aCA9IGZvcmNlUG9zaXgoZmlsZVBhdGgpO1xuXG4gIHJldHVybiBoYXNoUG9zaXhNb2R1bGVQYXRoKHBvc2l4UGF0aCk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JjZVBvc2l4KGZpbGVQYXRoKSB7XG4gIGNvbnN0IHBhcnNlZCA9IHBhdGgucGFyc2UoZmlsZVBhdGgpO1xuXG4gIGlmIChwYXJzZWQucm9vdCA9PT0gJycpIHtcbiAgICByZXR1cm4gZmlsZVBhdGgucmVwbGFjZUFsbChwYXRoLndpbjMyLnNlcCwgcGF0aC5wb3NpeC5zZXApO1xuICB9XG5cbiAgbGV0IHJvb3RsZXNzID0gZmlsZVBhdGgucmVwbGFjZShcbiAgICBuZXcgUmVnRXhwKGBeJHtSZWdFeHAuZXNjYXBlKHBhcnNlZC5yb290KX1gKSxcbiAgICBwYXRoLnBvc2l4LnNlcCxcbiAgKTtcblxuICByZXR1cm4gcm9vdGxlc3MucmVwbGFjZUFsbChwYXRoLndpbjMyLnNlcCwgcGF0aC5wb3NpeC5zZXApO1xufVxuXG5jb25zdCBDT01QT05FTlRfRVhURU5TSU9OUyA9IFsnLmd0cycsICcuZ2pzJywgJy50cycsICcuanMnLCAnLmhicyddO1xuXG4vLyBDSlMgLyBFU00/XG5sZXQgaGVyZSA9IGltcG9ydC5tZXRhLnVybDtcbmxldCBvdXJSZXF1aXJlID0gZ2xvYmFsVGhpcy5yZXF1aXJlXG4gID8gZ2xvYmFsVGhpcy5yZXF1aXJlXG4gIDogaGVyZSAmJiBjcmVhdGVSZXF1aXJlKGhlcmUpO1xuXG5pZiAoIW91clJlcXVpcmUpIHtcbiAgb3VyUmVxdWlyZSA9IHJlcXVpcmU7XG59XG5cbmNvbnN0IElSUkVMRVZBTlRfUEFUSFMgPSBbYmFyZVBhdGgucG5wbURpciwgJ19fdml0ZS0nXTtcbmNvbnN0IFVOU1VQUE9SVEVEX0RJUkVDVE9SSUVTID0gbmV3IFNldChbJ3Rlc3RzJ10pO1xuXG5jb25zdCBDV0QgPSBwcm9jZXNzLmN3ZCgpO1xuXG4vKipcbiAqIFJlZ2FyZGxlc3Mgb2Ygd2hhdCB0aGUgZmlsZVBhdGggZm9ybWF0IGlzLFxuICogdGhpcyB3aWxsIHRyeSB0byByZXR1cm4gdGhlIGNvcnJlY3QgcG9zdGZpeC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoRnJvbShmaWxlUGF0aCkge1xuICBpZiAocGF0aC5pc0Fic29sdXRlKGZpbGVQYXRoKSkge1xuICAgIHJldHVybiBoYXNoRnJvbUFic29sdXRlUGF0aChmaWxlUGF0aCk7XG4gIH1cblxuICByZXR1cm4gaGFzaEZyb21Nb2R1bGVQYXRoKGZpbGVQYXRoKTtcbn1cblxuLyoqXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3NzSGFzQXNzb2NpYXRlZENvbXBvbmVudChjc3NQYXRoKSB7XG4gIHJldHVybiBjc3NIYXNTdGFuZGFyZEZpbGUoY3NzUGF0aCkgfHwgY3NzSGFzUG9kc0ZpbGUoY3NzUGF0aCk7XG59XG5cbmZ1bmN0aW9uIGNzc0hhc1N0YW5kYXJkRmlsZShpZCkge1xuICAvKipcbiAgICogTm9ybWFsbHkgd2UgZG9uJ3QgbmVlZCB0byBjaGVjayBhIEpTIHBhdGggaGVyZSwgYnV0IHdoZW4gdXNpbmdcbiAgICogZW1icm9pZGVyQDMsIHdlIGhhdmUgYSBcInJld3JpdHRlbiBhcHBcIiwgd2hpY2ggaGFzIGFsbCBvdXIgc291cmNlXG4gICAqIHByZXByb2Nlc3NlZCBhIGJpdCBiZWZvcmUgc2NvcGVkLWNzcyB0cmFuc2Zvcm1hdGlvbnMuXG4gICAqXG4gICAqIChJbiBWaXRlLCB3ZSBvcGVyYXRlIG1vcmUgZGlyZWN0bHkgd2l0aCB0aGUgc291cmNlKVxuICAgKi9cbiAgZm9yIChsZXQgZXh0IG9mIENPTVBPTkVOVF9FWFRFTlNJT05TKSB7XG4gICAgbGV0IGNhbmRpZGF0ZVBhdGggPSBpZC5yZXBsYWNlKC9cXC5jc3MkLywgZXh0KTtcblxuICAgIGlmIChleGlzdHNTeW5jKGNhbmRpZGF0ZVBhdGgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGNzc0hhc1BvZHNGaWxlKGlkKSB7XG4gIGlmICghaWQuZW5kc1dpdGgoJ3N0eWxlcy5jc3MnKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxseSB3ZSBkb24ndCBuZWVkIHRvIGNoZWNrIGEgSlMgcGF0aCBoZXJlLCBidXQgd2hlbiB1c2luZ1xuICAgKiBlbWJyb2lkZXJAMywgd2UgaGF2ZSBhIFwicmV3cml0dGVuIGFwcFwiLCB3aGljaCBoYXMgYWxsIG91ciBzb3VyY2VcbiAgICogcHJlcHJvY2Vzc2VkIGEgYml0IGJlZm9yZSBzY29wZWQtY3NzIHRyYW5zZm9ybWF0aW9ucy5cbiAgICpcbiAgICogKEluIFZpdGUsIHdlIG9wZXJhdGUgbW9yZSBkaXJlY3RseSB3aXRoIHRoZSBzb3VyY2UpXG4gICAqL1xuICBmb3IgKGxldCBleHQgb2YgQ09NUE9ORU5UX0VYVEVOU0lPTlMpIHtcbiAgICBsZXQgY2FuZGlkYXRlUGF0aCA9IGlkLnJlcGxhY2UoL3N0eWxlc1xcLmNzcyQvLCBgdGVtcGxhdGUke2V4dH1gKTtcblxuICAgIGlmIChleGlzdHNTeW5jKGNhbmRpZGF0ZVBhdGgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQmFzZWQgb24gZW1iZXIncyBjb21wb25lbnQgbG9jYXRpb24gY29udmVudGlvbnMsXG4gKiB0aGlzIGZ1bmN0aW9uIHdpbGwgcHJvdmlkZSBhIHBhdGggZm9yIHdoZXJlIHdlXG4gKiBleHBlY3QgdGhlIENTUyB0byBsaXZlLlxuICpcbiAqIEZvciBjby1sb2NhdGVkIHN0cnVjdHVyZTpcbiAqICAgLSBjb21wb25lbnRzL215LWNvbXBvbmVudC5oYnNcbiAqICAgLSBjb21wb25lbnRzL215LWNvbXBvbmVudC5jc3NcbiAqXG4gKiBGb3IgbmVzdGVkIGNvLWxvY2F0ZWQgc3RydWN0dXJlXG4gKiAgIC0gY29tcG9uZW50cy9teS1jb21wb25lbnQvZm9vLmhic1xuICogICAtIGNvbXBvbmVudHMvbXktY29tcG9uZW50L2Zvby5jc3NcbiAqXG4gKiBGb3IgUG9kcyByb3V0ZXMgc3RydWN0dXJlXG4gKiAgIC0gcm91dGVzL215LXJvdXRlL3RlbXBsYXRlLntoYnMsanN9XG4gKiAgIC0gcm91dGVzL215LXJvdXRlL3N0eWxlcy5jc3NcbiAqXG4gKiBEZWxpYmVyYXRlbHkgbm90IHN1cHBvcnRlZDpcbiAqICAgLSBjb21wb25lbnRzIHcvIHBvZHMgLS0gdGhpcyBpcyBkZXByZWNhdGVkIGluIDUuMTBcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZU5hbWUgLSB0aGUgaGJzLCBqcywgZ2pzLCBndHMgb3Igd2hhdGV2ZXIgY28tbG9jYXRlZCBwYXRoLlxuICogQHJldHVybnMge3N0cmluZ30gLSBleHBlY3RlZCBjc3MgcGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3NzUGF0aEZvcihmaWxlTmFtZSkge1xuICBsZXQgd2l0aG91dEV4dCA9IHdpdGhvdXRFeHRlbnNpb24oZmlsZU5hbWUpO1xuICBsZXQgY3NzUGF0aCA9IHdpdGhvdXRFeHQgKyAnLmNzcyc7XG5cbiAgaWYgKGlzUG9kKGZpbGVOYW1lKSkge1xuICAgIGNzc1BhdGggPSBmaWxlTmFtZVxuICAgICAgLnJlcGxhY2UoL3RlbXBsYXRlXFwuanMkLywgJ3N0eWxlcy5jc3MnKVxuICAgICAgLnJlcGxhY2UoL3RlbXBsYXRlXFwuaGJzLywgJ3N0eWxlcy5jc3MnKTtcbiAgfVxuXG4gIHJldHVybiBjc3NQYXRoO1xufVxuXG4vKipcbiAqIE5vdGUgdGhhdCBjb21wb25lbnRzIGluIHRoZSBcInBvZHNcIiBjb252ZW50aW9uIHdpbGxcbiAqIG5ldmVyIGJlIHN1cHBvcnRlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUG9kVGVtcGxhdGUoZmlsZVBhdGgpIHtcbiAgaWYgKGZpbGVQYXRoLmluY2x1ZGVzKGxlYWRpbmdTbGFzaFBhdGguY29tcG9uZW50c0RpcikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gZmlsZVBhdGguZW5kc1dpdGgoJ3RlbXBsYXRlLmpzJykgfHwgZmlsZVBhdGguZW5kc1dpdGgoJ3RlbXBsYXRlLmhicycpO1xufVxuXG4vKipcbiAqIE5vdGUgdGhhdCBjb21wb25lbnRzIGluIHRoZSBcInBvZHNcIiBjb252ZW50aW9uIHdpbGxcbiAqIG5ldmVyIGJlIHN1cHBvcnRlZC5cbiAqXG4gKiBDaGVja3MgaWYgYSBmaWxlIGVuZHMgd2l0aFxuICogLSB0ZW1wbGF0ZS5qc1xuICogLSB0ZW1wbGF0ZS5oYnNcbiAqIC0gc3R5bGVzLmNzc1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQb2QoZmlsZVBhdGgpIHtcbiAgaWYgKGZpbGVQYXRoLmluY2x1ZGVzKGxlYWRpbmdTbGFzaFBhdGguY29tcG9uZW50c0RpcikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoaXNQb2RUZW1wbGF0ZShmaWxlUGF0aCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmaWxlUGF0aC5lbmRzV2l0aCgnc3R5bGVzLmNzcycpO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGhcbiAqIEByZXR1cm5zIHRoZSBzYW1lIHBhdGgsIGJ1dCB3aXRob3V0IHRoZSBleHRlbnNpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhvdXRFeHRlbnNpb24oZmlsZVBhdGgpIHtcbiAgbGV0IHBhcnNlZCA9IHBhdGgucGFyc2UoZmlsZVBhdGgpO1xuXG4gIHJldHVybiBwYXRoLmpvaW4ocGFyc2VkLmRpciwgcGFyc2VkLm5hbWUpO1xufVxuXG4vKipcbiAqIEV4YW1wbGVzIGZvciBmaWxlTmFtZVxuICogLSBhYnNvbHV0ZSBvbi1kaXNrIHBhdGhcbiAqIC0gaW4gd2VicGFja1xuICogICAtIFVSTC1hYnNvbHV0ZSBwYXRoLCBzdGFydGluZyB3aXRoIC9cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZU5hbWVcbiAqIEBwYXJhbSB7eyBhZGRpdGlvbmFsUm9vdHM/OiBzdHJpbmdbXTsgY3dkOiBzdHJpbmcgfX0gb3B0aW9uc1xuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUmVsZXZhbnRGaWxlKGZpbGVOYW1lLCB7IGFkZGl0aW9uYWxSb290cywgY3dkIH0pIHtcbiAgLy8gRmFrZSBmaWxlIGhhbmRsZWQgYnkgdGVzdGVtIHNlcnZlciB3aGVuIGl0IHJ1bnNcbiAgaWYgKGZpbGVOYW1lLnN0YXJ0c1dpdGgobGVhZGluZ1NsYXNoUGF0aC50ZXN0ZW0pKSByZXR1cm4gZmFsc2U7XG4gIC8vIFByaXZhdGUgVmlydHVhbCBNb2R1bGVzXG4gIGlmIChmaWxlTmFtZS5zdGFydHNXaXRoKCdcXDAnKSkgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIFRoZXNlIGFyZSBub3QgdmFsaWQgdXNlcmxhbmQgbmFtZXMgKG9yIGFyZSBmcm9tIGxpYnJhcmllcylcbiAgaWYgKHBhdGguaXNBYnNvbHV0ZShmaWxlTmFtZSkgPT09IGZhbHNlKSB7XG4gICAgaWYgKGZpbGVOYW1lLm1hdGNoKC9eW2EtekEtWl0vKSkgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gRXh0ZXJuYWwgdG8gdXNcbiAgaWYgKGZpbGVOYW1lLnN0YXJ0c1dpdGgobGVhZGluZ1NsYXNoUGF0aC5hdEVtYnJvaWRlcikpIHJldHVybiBmYWxzZTtcbiAgaWYgKElSUkVMRVZBTlRfUEFUSFMuc29tZSgoaSkgPT4gZmlsZU5hbWUuaW5jbHVkZXMoaSkpKSByZXR1cm4gZmFsc2U7XG5cbiAgbGV0IHdvcmtzcGFjZSA9IGZpbmRXb3Jrc3BhY2VQYXRoKGZpbGVOYW1lKTtcblxuICBhc3NlcnQoY3dkLCBgY3dkIHdhcyBub3QgcGFzc2VkIHRvIGlzUmVsZXZhbnRGaWxlYCk7XG5cbiAgbGV0IG91cldvcmtzcGFjZSA9IGZpbmRXb3Jrc3BhY2VQYXRoKGN3ZCk7XG5cbiAgaWYgKHdvcmtzcGFjZSAhPT0gb3VyV29ya3NwYWNlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgbGV0IGxvY2FsID0gZmlsZU5hbWUucmVwbGFjZSh3b3Jrc3BhY2UsICcnKTtcbiAgbGV0IFssIC4uLnBhcnRzXSA9IGxvY2FsLnNwbGl0KHBhdGguc2VwKS5maWx0ZXIoQm9vbGVhbik7XG5cbiAgaWYgKFVOU1VQUE9SVEVEX0RJUkVDVE9SSUVTLmhhcyhwYXJ0c1swXSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogTW9zdGx5IHBvZHMgc3VwcG9ydC5cbiAgICogZm9sa3MgbmVlZCB0byBvcHQgaW4gdG8gcG9kcyAocm91dGVzKSwgYmVjYXVzZSBldmVyeSBwb2RzIGFwcCBjYW4gYmUgY29uZmlndXJlZCBkaWZmZXJlbnRseVxuICAgKi9cbiAgbGV0IHJvb3RzID0gW1xuICAgIGxlYWRpbmdTbGFzaFBhdGguY29tcG9uZW50c0RpcixcbiAgICBsZWFkaW5nU2xhc2hQYXRoLnRlbXBsYXRlc0RpcixcbiAgICAuLi4oYWRkaXRpb25hbFJvb3RzIHx8IFtdKSxcbiAgXTtcblxuICBpZiAoIXJvb3RzLnNvbWUoKHJvb3QpID0+IGZpbGVOYW1lLmluY2x1ZGVzKHJvb3QpKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFja2FnZVNjb3BlZFBhdGhUb01vZHVsZVBhdGgocGFja2FnZVNjb3BlZFBhdGgpIHtcbiAgLyoqXG4gICAqICpCeSBjb252ZW50aW9uKiwgYHNyY2AgaXMgb21pdHRlZCBmcm9tIGNvbXBvbmVudCBwYXRocy5cbiAgICogV2UgY2FuIHJlZmxlY3QgdGhlIHNhbWUgYmVoYXZpb3IgYnkgcmVwbGFjaW5nIHNyYy9cbiAgICogd2l0aCBhbiBlbXB0eSBzdHJpbmcuXG4gICAqXG4gICAqIENTUyBpc24ndCBlbWl0dGVkIGFzIGEgY28tbG9jYXRlZCBtb2R1bGUsIGJ1dFxuICAgKiB0byBrZWVwIGNvbnZlbnRpb25zIGNvbnNpc3RlbnQgYWNyb3NzIGxhbmd1YWdlcyxcbiAgICogd2UgY2FuIHByZXRlbmQgaXQgaXMuXG4gICAqXG4gICAqIEFueSBjdXN0b21pemF0aW9uIGJleW9uZCByZW1vdmluZyBgc3JjYCBhbmQgYGFwcGAgaXMgcG90ZW50aWFsbHkgY29uZnVzaW5nLlxuICAgKiBJZiB3ZSBuZWVkIGZ1cnRoZXIgY3VzdG9taXphdGlvbnMsIHdlJ2xsIHdhbnQgdG8gbWF0Y2ggb24gYGV4cG9ydHNgIGluIHRoZVxuICAgKiBjb3JyZXNwb25kaW5nIHBhY2thZ2UuanNvblxuICAgKi9cbiAgbGV0IHBhY2thZ2VSZWxhdGl2ZSA9IHBhY2thZ2VTY29wZWRQYXRoLnJlcGxhY2UoXG4gICAgbmV3IFJlZ0V4cChgXiR7UmVnRXhwLmVzY2FwZShsZWFkaW5nU2xhc2hQYXRoLnNyYyl9YCksXG4gICAgcGF0aC5zZXAsXG4gICk7XG5cbiAgbGV0IHBhcnNlZCA9IHBhdGgucGFyc2UocGFja2FnZVJlbGF0aXZlKTtcblxuICBpZiAoaXNQb2QocGFja2FnZVJlbGF0aXZlKSkge1xuICAgIC8qKlxuICAgICAqIEZvciBwb2RzLCB3ZSBjaG9wIG9mZiB0aGUgd2hvbGUgZmlsZSwgYW5kIHVzZSB0aGUgZGlyIG5hbWUgYXMgdGhlIFwibW9kdWxlUGF0aFwiXG4gICAgICovXG4gICAgcmV0dXJuIHBhcnNlZC5kaXI7XG4gIH1cblxuICAvKipcbiAgICogSWYgYW4gZXh0ZW5zaW9uIGlzIHBhc3NlZCwgcmVtb3ZlIGl0LlxuICAgKiBXaGVuIHVzaW5nIHBhY2thZ2VycywgZm9sa3MgYXJlIHVzZWQgdG8gbm90IGhhdmluZyB0byBzcGVjaWZ5IGV4dGVuc2lvbnMgZm9yIGZpbGVzLlxuICAgKiBTaW5jZSB3ZSBkb24ndCBldmVuIGVtaXQgY3NzIGZpbGVzIGNvLWxvY2F0ZWQgdG8gZWFjaCBtb2R1bGUsXG4gICAqIHRoaXMgaGVscHMgdXMgbm90IGNvbnZleSBhIGxpZSB0aGF0IGEgZmlsZSBtYXkgZXhpc3QgaW4gYXQgcnVudGltZS5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUgYDxtb2R1bGUtbmFtZT4vY29tcG9uZW50cy9idXR0b25gLlxuICAgKiBJdCBkb2Vzbid0IG1hdHRlciB3aGF0IHRoZSBleHRlbnNpb24gaXMsIGJlY2F1c2UgeW91IGNhbiBvbmx5IGhhdmUgb25lIGNzcyBmaWxlXG4gICAqIGZvciB0aGUgYnV0dG9uIG1vZHVsZSBhbnl3YXkuXG4gICAqL1xuICBsZXQgbG9jYWxQYWNrYWdlclN0eWxlUGF0aCA9IHBhdGguam9pbihwYXJzZWQuZGlyLCBwYXJzZWQubmFtZSk7XG5cbiAgcmV0dXJuIGxvY2FsUGFja2FnZXJTdHlsZVBhdGg7XG59XG5cbi8qKlxuICogcmV0dXJucyB0aGUgYXBwLW1vZHVsZSBwYXRoIG9mIHRoZSBzb3VyY2UgZmlsZVxuICpcbiAqIFRoaXMgYXNzdW1lcyBub3JtYWwgZW1iZXIgYXBwIGNvbnZlbnRpb25zXG4gKlxuICogd2hpY2ggaXMgYDxwYWNrYWdlLmpzb24jbmFtZT4vcGF0aC10by1maWxlYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwUGF0aChzb3VyY2VQYXRoKSB7XG4gIGxldCB3b3Jrc3BhY2VQYXRoID0gZmluZFdvcmtzcGFjZVBhdGgoc291cmNlUGF0aCk7XG4gIGxldCBuYW1lID0gbW9kdWxlTmFtZShzb3VyY2VQYXRoKTtcblxuICAvKipcbiAgICogIFVuZGVyIGVtYnJvaWRlciBidWlsZHMsIHRoZSBzcGVjLWNvbXBsaWFudCB2ZXJzaW9uIG9mIHRoZSBhcHBcbiAgICogaGFzIGFsbCB0aGUgZmlsZXMgdW5kZXIgYSBmb2xkZXIgd2hpY2ggcmVwcmVzZW50cyB0aGUgcGFja2FnZSBuYW1lLFxuICAgKiByYXRoZXIgdGhhbiBcImFwcFwiLlxuICAgKi9cbiAgbGV0IHBhY2thZ2VSZWxhdGl2ZSA9IHNvdXJjZVBhdGgucmVwbGFjZSh3b3Jrc3BhY2VQYXRoLCAnJyk7XG5cbiAgLyoqXG4gICAqIEJ1dCB3ZSBhbHNvIGRvbid0IHdhbnQgJ2FwcCcgLS0gd2hpY2ggaXMgcHJlc2VudCBpbiB0aGUgdjEgYWRkb24gcGlwZWxpbmVcbiAgICovXG4gIHBhY2thZ2VSZWxhdGl2ZSA9IHBhY2thZ2VSZWxhdGl2ZS5yZXBsYWNlKGxlYWRpbmdTbGFzaFBhdGguYXBwLCBwYXRoLnNlcCk7XG5cbiAgLy8gQW55IG9mIHRoZSBhYm92ZSByZWxwYWNlbWVudHMgY291bGQgYWNjaWRlbnRhbGx5IGdpdmUgdXMgYW4gZXh0cmEgLyAoZGVwZW5kaW5nIG9uIG91ciBidWlsZCBlbnZpcm9ubWVudClcbiAgcGFja2FnZVJlbGF0aXZlID0gcGF0aC5ub3JtYWxpemUocGFja2FnZVJlbGF0aXZlKTtcblxuICBsZXQgbG9jYWxQYWNrYWdlclN0eWxlUGF0aCA9IHBhY2thZ2VTY29wZWRQYXRoVG9Nb2R1bGVQYXRoKHBhY2thZ2VSZWxhdGl2ZSk7XG5cbiAgcmV0dXJuIGAke25hbWV9JHtsb2NhbFBhY2thZ2VyU3R5bGVQYXRofWA7XG59XG5cbi8qKlxuICogVG8gYXZvaWQgaGl0dGluZyB0aGUgZmlsZXN5c2V0bSwgd2UnbGwgc3RvcmUgYWxsIGZvdW5kXG4gKiBwcm9qZWN0IHBhdGhzIGJlcmUsIHNvIHdlIGNhbiwgaW4gbWVtb3J5LFxuICogZ2V0IHRoZSBmb2xkZXIgd2hlcmUgYSBwYWNrYWdlLmpzb24gZXhpc3RzLCByYXRoZXIgdGhhblxuICogaGl0IHRoZSBmaWxlIHN5c3RlbSBldmVyeSB0aW1lLlxuICovXG5jb25zdCBTRUVOID0gbmV3IFNldCgpO1xuXG5mdW5jdGlvbiBnZXRTZWVuKHNvdXJjZVBhdGgpIHtcbiAgaWYgKFNFRU4uaGFzKHNvdXJjZVBhdGgpKSByZXR1cm4gc291cmNlUGF0aDtcblxuICBsZXQgcGFydHMgPSBzb3VyY2VQYXRoLnNwbGl0KHBhdGguc2VwKTtcblxuICBmb3IgKGxldCBpID0gcGFydHMubGVuZ3RoIC0gMTsgaSA+IDE7IGktLSkge1xuICAgIGxldCB0b0NoZWNrID0gcGFydHMuc2xpY2UoMCwgaSkuam9pbihwYXRoLnNlcCk7XG5cbiAgICBsZXQgc2VlbiA9IFNFRU4uaGFzKHRvQ2hlY2spO1xuXG4gICAgaWYgKHNlZW4pIHtcbiAgICAgIHJldHVybiB0b0NoZWNrO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZFdvcmtzcGFjZVBhdGgoc291cmNlUGF0aCwgb3B0aW9ucykge1xuICBsZXQgY3dkID0gb3B0aW9ucz8uY3dkID8/IENXRDtcblxuICBpZiAoc291cmNlUGF0aC5lbmRzV2l0aChwYXRoLnNlcCkpIHtcbiAgICBzb3VyY2VQYXRoID0gc291cmNlUGF0aC5yZXBsYWNlKFxuICAgICAgbmV3IFJlZ0V4cChgJHtSZWdFeHAuZXNjYXBlKHBhdGguc2VwKX0kYCksXG4gICAgICAnJyxcbiAgICApO1xuICB9XG5cbiAgbGV0IHNlZW4gPSBnZXRTZWVuKHNvdXJjZVBhdGgpO1xuXG4gIGlmIChzZWVuKSB7XG4gICAgcmV0dXJuIHNlZW47XG4gIH1cblxuICBsZXQgY2FuZGlkYXRlUGF0aCA9IHBhdGguam9pbihzb3VyY2VQYXRoLCAncGFja2FnZS5qc29uJyk7XG5cbiAgY29uc3QgaXNXb3Jrc3BhY2UgPSBmc1N5bmMuZXhpc3RzU3luYyhjYW5kaWRhdGVQYXRoKTtcblxuICBpZiAoaXNXb3Jrc3BhY2UpIHtcbiAgICByZXR1cm4gc291cmNlUGF0aDtcbiAgfVxuXG4gIGNvbnN0IHBhY2thZ2VKc29uUGF0aCA9IGZpbmRQYWNrYWdlSnNvblVwKHNvdXJjZVBhdGgsIHsgY3dkIH0pO1xuXG4gIGlmICghcGFja2FnZUpzb25QYXRoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgZGV0ZXJtaW5lIHByb2plY3QgZm9yICR7c291cmNlUGF0aH1gKTtcbiAgfVxuXG4gIGNvbnN0IHdvcmtzcGFjZVBhdGggPSBwYXRoLmRpcm5hbWUocGFja2FnZUpzb25QYXRoKTtcblxuICBTRUVOLmFkZCh3b3Jrc3BhY2VQYXRoKTtcblxuICByZXR1cm4gd29ya3NwYWNlUGF0aDtcbn1cblxuZnVuY3Rpb24gZmluZFBhY2thZ2VKc29uVXAoc3RhcnRQYXRoLCBvcHRpb25zKSB7XG4gIGxldCBjd2QgPSBvcHRpb25zPy5jd2QgPz8gQ1dEO1xuICBsZXQgcGFydHMgPSBzdGFydFBhdGguc3BsaXQocGF0aC5zZXApO1xuXG4gIGZvciAobGV0IGkgPSBwYXJ0cy5sZW5ndGggLSAxOyBpID4gMTsgaS0tKSB7XG4gICAgbGV0IHRvQ2hlY2sgPSBwYXJ0cy5zbGljZSgwLCBpKS5qb2luKHBhdGguc2VwKTtcblxuICAgIGxldCBwYWNrYWdlSnNvbiA9IHBhdGguam9pbih0b0NoZWNrLCAncGFja2FnZS5qc29uJyk7XG4gICAgbGV0IGV4aXN0cyA9IGZzU3luYy5leGlzdHNTeW5jKHBhY2thZ2VKc29uKTtcblxuICAgIGlmIChleGlzdHMpIHtcbiAgICAgIHJldHVybiBwYWNrYWdlSnNvbjtcbiAgICB9XG5cbiAgICAvLyBEb24ndCB0cmF2ZXJzZSBhbGwgdGhlIHdheSB0byB0aGUgcm9vdCBvZiB0aGUgZmlsZSBzeXN0ZW0uXG4gICAgaWYgKHRvQ2hlY2sgPT09IGN3ZCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmNvbnN0IE1BTklGRVNUX0NBQ0hFID0gbmV3IE1hcCgpO1xuXG4vKipcbiAqIFdpbGwgcmV0dXJuIHRoZSBwYWNrYWdlLmpzb24jbmFtZSwgb3IgY29uZmlnL2Vudmlyb25tZW50I21vdWRsZVByZWZpeCAoaWYgdjEgYXBwKVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2VQYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2R1bGVOYW1lKHNvdXJjZVBhdGgpIHtcbiAgY29uc3Qgd29ya3NwYWNlID0gZmluZFdvcmtzcGFjZVBhdGgoc291cmNlUGF0aCk7XG4gIGNvbnN0IG1hbmlmZXN0ID0gZ2V0TWFuaWZlc3Qod29ya3NwYWNlKTtcblxuICByZXR1cm4gbWFuaWZlc3QubmFtZTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gd29ya3NwYWNlXG4gKi9cbmZ1bmN0aW9uIGdldE1hbmlmZXN0KHdvcmtzcGFjZSkge1xuICBsZXQgZXhpc3RpbmcgPSBNQU5JRkVTVF9DQUNIRS5nZXQod29ya3NwYWNlKTtcblxuICBpZiAoZXhpc3RpbmcpIHtcbiAgICByZXR1cm4gZXhpc3Rpbmc7XG4gIH1cblxuICBsZXQgYnVmZmVyID0gZnNTeW5jLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4od29ya3NwYWNlLCAncGFja2FnZS5qc29uJykpO1xuICBsZXQgY29udGVudCA9IGJ1ZmZlci50b1N0cmluZygpO1xuICBsZXQganNvbiA9IEpTT04ucGFyc2UoY29udGVudCk7XG5cbiAgTUFOSUZFU1RfQ0FDSEUuc2V0KHdvcmtzcGFjZSwganNvbik7XG5cbiAgcmV0dXJuIGpzb247XG59XG4iLCJpbXBvcnQgeyBpc1JlbGV2YW50RmlsZSB9IGZyb20gJy4uL2xpYi9wYXRoL3V0aWxzLmpzJztcblxuZnVuY3Rpb24gX2lzUmVsZXZhbnRGaWxlKHN0YXRlLCBjd2QpIHtcbiAgbGV0IGZpbGVOYW1lID0gc3RhdGUuZmlsZS5vcHRzLmZpbGVuYW1lO1xuICBsZXQgYWRkaXRpb25hbFJvb3RzID0gc3RhdGUub3B0cz8uYWRkaXRpb25hbFJvb3RzO1xuXG4gIHJldHVybiBpc1JlbGV2YW50RmlsZShmaWxlTmFtZSwge1xuICAgIGFkZGl0aW9uYWxSb290cyxcbiAgICBjd2QsXG4gIH0pO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7YW55fSBlbnYgLSBiYWJlbCBwbHVnaW4gZW52LCBlbnYudHlwZXMgaXMgbW9zdCBjb21tb25seSB1c2VkIChlc3AgaW4gVFMpXG4gKiBAcGFyYW0ge29iamVjdH0gb3B0aW9ucyAtIHRoZSBvcHRpb25zIGZvciBzY29wZWQtY3NzIC0tIHRoaXMgaXMgYWxzbyBhdmFpbGFibGUgaW4gZWFjaCB2aXNpdG9yJ3Mgc3RhdGUub3B0c1xuICogQHBhcmFtIHtzdHJpbmd9IHdvcmtpbmdEaXJlY3RvcnlcbiAqL1xuZXhwb3J0IGNvbnN0IHNjb3BlZENTUyA9IChjb25maWcpID0+IChlbnYsIG9wdGlvbnMsIHdvcmtpbmdEaXJlY3RvcnkpID0+IHtcbiAgLy8gbm90IHJlYWxseSBhIGRlZXAgbWVyZ2UsIGJ1dCB0aGUgaWRlYSBpcyB0byB1c2Ugb25lIG9yIHRoZSBvdGhlciBhbmQgbm90IG1peCB0aGUgY29uZmlnc1xuICBvcHRpb25zID0geyAuLi5jb25maWcsIC4uLm9wdGlvbnMgfTtcblxuICAvKipcbiAgICogVGhpcyBiYWJlbCBwbHVnaW4gZG9lcyB0d28gdGhpbmdzOlxuICAgKiAtIHJlbW92ZXMgdGhlIGltcG9ydCBvZiBzY29wZWRDbGFzcywgaWYgaXQgZXhpc3RzXG4gICAqICAgLSBpZiBzY29wZWRDbGFzcyB3YXMgaW1wb3J0ZWQsIGl0IGlzIHJlbW92ZWQgZnJvbSBhbnkgY29tcG9uZW50J3MgXCJzY29wZSBiYWdcIlxuICAgKiAgICAgKHRoZSBzY29wZSBiYWcgYmVpbmcgYSBsb3ctbGV2ZWwgb2JqZWN0IHVzZWQgZm9yIHBhc3Npbmcgd2hhdCBpcyBcImluIHNjb3BlXCIgZm9yIGEgY29tcG9uZW50KVxuICAgKi9cbiAgcmV0dXJuIHtcbiAgICB2aXNpdG9yOiB7XG4gICAgICBQcm9ncmFtOiB7XG4gICAgICAgIGVudGVyKHBhdGgsIHN0YXRlKSB7XG4gICAgICAgICAgaWYgKCFfaXNSZWxldmFudEZpbGUoc3RhdGUsIHdvcmtpbmdEaXJlY3RvcnkpKSB7XG4gICAgICAgICAgICBzdGF0ZS5jYW5Ta2lwID0gdHJ1ZTtcblxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBJbXBvcnREZWNsYXJhdGlvbihwYXRoLCBzdGF0ZSkge1xuICAgICAgICBpZiAoc3RhdGUuY2FuU2tpcCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXRoLm5vZGUuc291cmNlLnZhbHVlID09PSAnZW1iZXItc2NvcGVkLWNzcycpIHtcbiAgICAgICAgICBsZXQgc3BlY2lmaWVyID0gcGF0aC5ub2RlLnNwZWNpZmllcnMuZmluZChcbiAgICAgICAgICAgICh4KSA9PiB4LmltcG9ydGVkLm5hbWUgPT09ICdzY29wZWRDbGFzcycsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChzcGVjaWZpZXIpIHtcbiAgICAgICAgICAgIHN0YXRlLmZpbGUub3B0cy5pbXBvcnRlZFNjb3BlZENsYXNzID0gc3BlY2lmaWVyLmxvY2FsLm5hbWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNwZWNpZmllci5sb2NhbC5uYW1lICE9PSAnc2NvcGVkQ2xhc3MnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgIGBUaGUgc2NvcGVkQ2xhc3MgaW1wb3J0IGlzIGEgcHN1ZWRvLWhlbHBlciwgYW5kIG1heSBub3QgYmUgcmVuYW1lZCBhcyBpdCBpcyByZW1vdmVkIGF0IGJ1aWxkIHRpbWUuYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcGF0aC5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8qKlxuICAgICAgICogT25seSBpbiBzdHJpY3QgbW9kZSwgZG8gd2UgY2FyZSBhYm91dCByZW1vbmluZyB0aGUgc2NvcGUgYmFnIHJlZmVyZW5jZVxuICAgICAgICovXG4gICAgICBPYmplY3RQcm9wZXJ0eShwYXRoLCBzdGF0ZSkge1xuICAgICAgICBpZiAoIXN0YXRlLmZpbGUub3B0cz8uaW1wb3J0ZWRTY29wZWRDbGFzcykgcmV0dXJuO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBwYXRoLm5vZGUudmFsdWUudHlwZSA9PT0gJ0lkZW50aWZpZXInICYmXG4gICAgICAgICAgcGF0aC5ub2RlLnZhbHVlLm5hbWUgPT09IHN0YXRlLmZpbGUub3B0cz8uaW1wb3J0ZWRTY29wZWRDbGFzc1xuICAgICAgICApIHtcbiAgICAgICAgICBwYXRoLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59O1xuIiwiaW1wb3J0IHsgZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jIH0gZnJvbSAnZnMnO1xuaW1wb3J0IHBvc3Rjc3MgZnJvbSAncG9zdGNzcyc7XG5pbXBvcnQgcGFyc2VyIGZyb20gJ3Bvc3Rjc3Mtc2VsZWN0b3ItcGFyc2VyJztcblxuaW1wb3J0IHsgbWQ1IH0gZnJvbSAnLi4vcGF0aC9tZDUuanMnO1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBjc3NcbiAqIEByZXR1cm4ge3N0cmluZ30gaGFzaGVkIGRvd24gdmVyc2lvbiBvZiB0aGUgQ1NTIGZvciBkaXNhbWJpZ3VhdGluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzaChjc3MpIHtcbiAgcmV0dXJuIGBjc3MtJHttZDUoY3NzKX1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNJbnNpZGVHbG9iYWwobm9kZSwgZnVuYykge1xuICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudDtcblxuICBpZiAoIXBhcmVudCkgcmV0dXJuIGZhbHNlO1xuICBpZiAocGFyZW50LnR5cGUgPT09ICdwc2V1ZG8nICYmIHBhcmVudC52YWx1ZSA9PT0gJzpnbG9iYWwnKSByZXR1cm4gdHJ1ZTtcblxuICByZXR1cm4gaXNJbnNpZGVHbG9iYWwocGFyZW50LCBmdW5jKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gY3NzUGF0aCBwYXRoIHRvIGEgQ1NTIGZpbGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENTU0luZm8oY3NzUGF0aCkge1xuICBpZiAoIWV4aXN0c1N5bmMoY3NzUGF0aCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGxldCBjc3MgPSByZWFkRmlsZVN5bmMoY3NzUGF0aCwgJ3V0ZjgnKTtcblxuICByZXR1cm4gZ2V0Q1NTQ29udGVudEluZm8oY3NzKTtcbn1cblxuLyoqXG4gKiBXZSB1c2UgdGhpcyBmdW5jdGlvbiB0byBjaGVjayBlYWNoIGNsYXNzIHVzZWQgaW4gdGhlIHRlbXBsYXRlXG4gKiB0byBzZWUgaWYgd2UgbmVlZCB0byBsZWF2ZSBpdCBhbG9uZSBvciB0cmFuc2Zvcm0gaXRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY3NzIHRoZSBDU1MncyBjb250ZW50c1xuICogQHJldHVybiB7eyBjbGFzc2VzOiBTZXQ8c3RyaW5nPiwgdGFnczogU2V0PHN0cmluZz4sIGNzczogc3RyaW5nLCBpZDogc3RyaW5nIH19XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDU1NDb250ZW50SW5mbyhjc3MpIHtcbiAgY29uc3QgY2xhc3NlcyA9IG5ldyBTZXQoKTtcbiAgY29uc3QgdGFncyA9IG5ldyBTZXQoKTtcblxuICBjb25zdCBhc3QgPSBwb3N0Y3NzLnBhcnNlKGNzcyk7XG5cbiAgYXN0LndhbGsoKG5vZGUpID0+IHtcbiAgICBpZiAobm9kZS50eXBlID09PSAncnVsZScpIHtcbiAgICAgIGdldENsYXNzZXNBbmRUYWdzKG5vZGUuc2VsZWN0b3IsIGNsYXNzZXMsIHRhZ3MpO1xuICAgIH1cbiAgfSk7XG5cbiAgbGV0IGlkID0gaGFzaChjc3MpO1xuXG4gIHJldHVybiB7IGNsYXNzZXMsIHRhZ3MsIGNzcywgaWQgfTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2xhc3Nlc0FuZFRhZ3Moc2VsLCBjbGFzc2VzLCB0YWdzKSB7XG4gIGNvbnN0IHRyYW5zZm9ybSA9IChzbHMpID0+IHtcbiAgICBzbHMud2Fsaygoc2VsZWN0b3IpID0+IHtcbiAgICAgIGlmIChzZWxlY3Rvci50eXBlID09PSAnY2xhc3MnICYmICFpc0luc2lkZUdsb2JhbChzZWxlY3RvcikpIHtcbiAgICAgICAgY2xhc3Nlcy5hZGQoc2VsZWN0b3IudmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChzZWxlY3Rvci50eXBlID09PSAndGFnJyAmJiAhaXNJbnNpZGVHbG9iYWwoc2VsZWN0b3IpKSB7XG4gICAgICAgIHRhZ3MuYWRkKHNlbGVjdG9yLnZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICBwYXJzZXIodHJhbnNmb3JtKS5wcm9jZXNzU3luYyhzZWwpO1xufVxuXG5pZiAoaW1wb3J0Lm1ldGEudml0ZXN0KSB7XG4gIGNvbnN0IHsgaXQsIGV4cGVjdCB9ID0gaW1wb3J0Lm1ldGEudml0ZXN0O1xuXG4gIGl0KCdzaG91bGQgcmV0dXJuIGNsYXNzZXMgYW5kIHRhZ3MgdGhhdCBhcmUgbm90IGluIDpnbG9iYWwnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgY3NzID0gJy5iYXogOmdsb2JhbCguZm9vKSAuYmFyIGRpdiA6Z2xvYmFsKHApICB7IGNvbG9yOiByZWQ7IH0nO1xuICAgIGNvbnN0IHsgY2xhc3NlcywgdGFncyB9ID0gZ2V0Q1NTQ29udGVudEluZm8oY3NzKTtcblxuICAgIC8vIGNsYXNzZXMgc2hvdWxkIGJlIGJheiBhbmQgYmFyXG4gICAgZXhwZWN0KGNsYXNzZXMuc2l6ZSkudG8uZXF1YWwoMik7XG4gICAgZXhwZWN0KFsuLi5jbGFzc2VzXSkudG8uaGF2ZS5tZW1iZXJzKFsnYmF6JywgJ2JhciddKTtcbiAgICBleHBlY3QodGFncy5zaXplKS50by5lcXVhbCgxKTtcbiAgICBleHBlY3QoWy4uLnRhZ3NdKS50by5oYXZlLm1lbWJlcnMoWydkaXYnXSk7XG4gIH0pO1xufVxuIiwiLyoqXG4gKiBJbXBvcnRhbnQgZG9jczpcbiAqIC0gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL1xuICovXG5pbXBvcnQgcG9zdGNzcyBmcm9tICdwb3N0Y3NzJztcbmltcG9ydCBwYXJzZXIgZnJvbSAncG9zdGNzcy1zZWxlY3Rvci1wYXJzZXInO1xuXG5pbXBvcnQgeyBpc0luc2lkZUdsb2JhbCB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG5jb25zdCBTRVAgPSAnX18nO1xuXG5mdW5jdGlvbiBpc1J1bGUobm9kZSkge1xuICByZXR1cm4gbm9kZS50eXBlID09PSAncnVsZSc7XG59XG5cbmZ1bmN0aW9uIGlzRGVjbGFyYXRpb24obm9kZSkge1xuICByZXR1cm4gbm9kZS50eXBlID09PSAnZGVjbCc7XG59XG5cbi8qKlxuICogTk9URTogXCJrZXlmcmFtZXNcIiBpcyBhIHNpbmd1bGFyIGRlZmluaXRpb24sIGluIHRoYXQgaXQncyBhIGJsb2NrIGNvbnRhaW5pbmcga2V5ZnJhbWVzXG4gKiAgICAgICB1c2luZyBgQGtleWZyYW1lcyB7fWAgd2l0aCBvbmx5IG9uZSB0aGluZyBvbiB0aGUgaW5zaWRlIGRvZXNuJ3QgbWFrZSBzZW5zZS5cbiAqL1xuZnVuY3Rpb24gcmV3cml0ZVJlZmVyZW5jYWJsZShub2RlLCBwb3N0Zml4KSB7XG4gIGxldCBvcmlnaW5hbE5hbWUgPSBub2RlLnBhcmFtcztcbiAgbGV0IHBvc3RmaXhlZE5hbWUgPSBub2RlLnBhcmFtcyArIFNFUCArIHBvc3RmaXg7XG5cbiAgbm9kZS5wYXJhbXMgPSBwb3N0Zml4ZWROYW1lO1xuXG4gIHJldHVybiB7XG4gICAgb3JpZ2luYWxOYW1lLFxuICAgIHBvc3RmaXhlZE5hbWUsXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJld3JpdGVTZWxlY3RvcihzZWwsIHBvc3RmaXgpIHtcbiAgY29uc3QgdHJhbnNmb3JtID0gKHNlbGVjdG9ycykgPT4ge1xuICAgIHNlbGVjdG9ycy53YWxrKChzZWxlY3RvcikgPT4ge1xuICAgICAgaWYgKGlzSW5zaWRlR2xvYmFsKHNlbGVjdG9yKSkgcmV0dXJuO1xuXG4gICAgICAvLyBXZSBuZXZlciB3YW50IHRvIHRvdWNoIHBzdWVkbyBzZWxlY3RvcnMgc2luY2Ugd2UgYW5kIHRoZSB1c2VyIGRvZXNuJ3Qgb3duIHRoZW0uXG4gICAgICBpZiAoc2VsZWN0b3IudHlwZSA9PT0gJ3BzdWVkbycpIHJldHVybjtcblxuICAgICAgLy8gOm50aC1vZi10eXBlIGhhcyBzcGVjaWFsIHN5bnRheCB3aGVyZSB0aGUgdmFsdWVzIHBhc3NlZCB0byBudGgtb2YtdHlwZSgpXG4gICAgICAvLyBtdXN0IGVpdGhlciBiZSBleGFjdGx5IFwib2RkXCIsIFwiZXZlblwiLCBvciBhIHNpbXBsZSBmb3JtdWxhXG4gICAgICAvL1xuICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTLzpudGgtb2YtdHlwZVxuICAgICAgaWYgKGlzTnRoT2ZUeXBlKHNlbGVjdG9yKSkgcmV0dXJuO1xuXG4gICAgICBpZiAoc2VsZWN0b3IudHlwZSA9PT0gJ2NsYXNzJykge1xuICAgICAgICBzZWxlY3Rvci52YWx1ZSArPSAnXycgKyBwb3N0Zml4O1xuICAgICAgfSBlbHNlIGlmIChzZWxlY3Rvci50eXBlID09PSAndGFnJykge1xuICAgICAgICBzZWxlY3Rvci5yZXBsYWNlV2l0aChcbiAgICAgICAgICBwYXJzZXIudGFnKHsgdmFsdWU6IHNlbGVjdG9yLnZhbHVlIH0pLFxuICAgICAgICAgIHBhcnNlci5jbGFzc05hbWUoeyB2YWx1ZTogcG9zdGZpeCB9KSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIHJlbW92ZSA6Z2xvYmFsXG4gICAgc2VsZWN0b3JzLndhbGsoKHNlbGVjdG9yKSA9PiB7XG4gICAgICBpZiAoc2VsZWN0b3IudHlwZSA9PT0gJ3BzZXVkbycgJiYgc2VsZWN0b3IudmFsdWUgPT09ICc6Z2xvYmFsJykge1xuICAgICAgICBzZWxlY3Rvci5yZXBsYWNlV2l0aCguLi5zZWxlY3Rvci5ub2Rlcyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG4gIGNvbnN0IHRyYW5zZm9ybWVkID0gcGFyc2VyKHRyYW5zZm9ybSkucHJvY2Vzc1N5bmMoc2VsKTtcblxuICByZXR1cm4gdHJhbnNmb3JtZWQ7XG59XG5cbmZ1bmN0aW9uIGlzTnRoT2ZUeXBlKG5vZGUpIHtcbiAgaWYgKCFub2RlKSByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIG5vZGUucGFyZW50Py52YWx1ZSA9PT0gJzpudGgtb2YtdHlwZScgfHwgaXNOdGhPZlR5cGUobm9kZS5wYXJlbnQpO1xufVxuXG5mdW5jdGlvbiBpc0luc2lkZUtleWZyYW1lcyhub2RlKSB7XG4gIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50O1xuXG4gIGlmICghcGFyZW50KSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXJlbnQudHlwZSA9PT0gJ2F0cnVsZScgJiYgcGFyZW50Lm5hbWUgPT09ICdrZXlmcmFtZXMnKSByZXR1cm4gdHJ1ZTtcblxuICByZXR1cm4gaXNJbnNpZGVLZXlmcmFtZXMocGFyZW50KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJld3JpdGVDc3MoY3NzLCBwb3N0Zml4LCBmaWxlTmFtZSwgbGF5ZXJOYW1lKSB7XG4gIGNvbnN0IGFzdCA9IHBvc3Rjc3MucGFyc2UoY3NzKTtcbiAgLyoqXG4gICAqIGtpbmQgPT4gb3JpZ2luYWxOYW1lID0+IHBvc3RmaXhlZE5hbWVcbiAgICogQHR5cGUge3sgW2tpbmQ6IHN0cmluZ106IHsgW29yaWdpbmFsTmFtZTogc3RyaW5nXTogc3RyaW5nIH19fVxuICAgKi9cbiAgY29uc3QgcmVmZXJlbmNhYmxlcyA9IHtcbiAgICBrZXlmcmFtZXM6IHt9LFxuICAgICdjb3VudGVyLXN0eWxlJzoge30sXG4gICAgJ3Bvc2l0aW9uLXRyeSc6IHt9LFxuICAgIHByb3BlcnR5OiB7fSxcbiAgfTtcblxuICBjb25zdCBhdmFpbGFibGVSZWZlcmVuY2FibGVzID0gbmV3IFNldChPYmplY3Qua2V5cyhyZWZlcmVuY2FibGVzKSk7XG5cbiAgZnVuY3Rpb24gaXNSZWZlcmVuY2FibGUobm9kZSkge1xuICAgIGlmIChub2RlLnR5cGUgIT09ICdhdHJ1bGUnKSByZXR1cm47XG5cbiAgICByZXR1cm4gYXZhaWxhYmxlUmVmZXJlbmNhYmxlcy5oYXMobm9kZS5uYW1lKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZURpcmVjdFJlZmVyZW5jZXMobm9kZSkge1xuICAgIGlmICghbm9kZS52YWx1ZSkgcmV0dXJuO1xuXG4gICAgZm9yIChsZXQgWywgbWFwXSBvZiBPYmplY3QuZW50cmllcyhyZWZlcmVuY2FibGVzKSkge1xuICAgICAgaWYgKG1hcFtub2RlLnZhbHVlXSkge1xuICAgICAgICBub2RlLnZhbHVlID0gbWFwW25vZGUudmFsdWVdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVNob3J0aGFuZENvbnRlbnRzKG5vZGUpIHtcbiAgICBpZiAobm9kZS5wcm9wID09PSAnYW5pbWF0aW9uJykge1xuICAgICAgbGV0IHBhcnRzID0gbm9kZS52YWx1ZS5zcGxpdCgnICcpO1xuICAgICAgbGV0IG1hdGNoID0gcGFydHMuZmlsdGVyKCh4KSA9PiByZWZlcmVuY2FibGVzLmtleWZyYW1lc1t4XSk7XG5cbiAgICAgIGlmIChtYXRjaC5sZW5ndGgpIHtcbiAgICAgICAgbWF0Y2guZm9yRWFjaCgoeCkgPT4ge1xuICAgICAgICAgIGxldCByZXBsYWNlbWVudCA9IHJlZmVyZW5jYWJsZXMua2V5ZnJhbWVzW3hdO1xuXG4gICAgICAgICAgaWYgKCFyZXBsYWNlbWVudCkgcmV0dXJuO1xuXG4gICAgICAgICAgbm9kZS52YWx1ZSA9IG5vZGUudmFsdWUucmVwbGFjZSh4LCByZXBsYWNlbWVudCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IFtsb29rRm9yLCByZXBsYWNlV2l0aF0gb2YgT2JqZWN0LmVudHJpZXMocmVmZXJlbmNhYmxlcy5wcm9wZXJ0eSkpIHtcbiAgICAgIGxldCBsb29rRm9yVmFyID0gYHZhcigke2xvb2tGb3J9KWA7XG4gICAgICBsZXQgcmVwbGFjZVdpdGhWYXIgPSBgdmFyKCR7cmVwbGFjZVdpdGh9KWA7XG5cbiAgICAgIG5vZGUudmFsdWUgPSBub2RlLnZhbHVlLnJlcGxhY2UobG9va0ZvclZhciwgcmVwbGFjZVdpdGhWYXIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXZSBoYXZlIHRvIGRvIHR3byBwYXNzZXM6XG4gICAqIDEuIHBvc3RmaXggYWxsIHRoZSByZWZlcmVuY2FibGUgc3ludGF4XG4gICAqIDIuIHBvc3RmaXggYXMgbm9ybWFsLCBidXQgYWxzbyBjaGVja2luZyB2YWx1ZXMgb2YgQ1NTIHByb3BlcnRpZXNcbiAgICogICAgdGhhdCBjb3VsZCBtYXRjaCBwb3N0Zml4ZWQgcmVmZXJlbmNhYmxlcyBmcm9tIHN0ZXAgMVxuICAgKi9cblxuICAvLyBTdGVwIDE6IGZpbmQgcmVmZXJlbmNhYmxlc1xuICBhc3Qud2Fsaygobm9kZSkgPT4ge1xuICAgIC8qKlxuICAgICAqIEBrZXlmcmFtZXMsIEBjb3VudGVyLXN0eWxlLCBldGNcbiAgICAgKi9cbiAgICBpZiAoaXNSZWZlcmVuY2FibGUobm9kZSkpIHtcbiAgICAgIGxldCBuYW1lID0gbm9kZS5uYW1lO1xuICAgICAgbGV0IHsgb3JpZ2luYWxOYW1lLCBwb3N0Zml4ZWROYW1lIH0gPSByZXdyaXRlUmVmZXJlbmNhYmxlKG5vZGUsIHBvc3RmaXgpO1xuXG4gICAgICByZWZlcmVuY2FibGVzW25hbWVdW29yaWdpbmFsTmFtZV0gPSBwb3N0Zml4ZWROYW1lO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICB9KTtcblxuICAvLyBTdGVwIDI6IHBvc3RmaXggYW5kIHVwZGF0ZSByZWZlbmNlZCByZWZlcmVuY2FibGVzXG4gIGFzdC53YWxrKChub2RlKSA9PiB7XG4gICAgaWYgKGlzRGVjbGFyYXRpb24obm9kZSkpIHtcbiAgICAgIHVwZGF0ZURpcmVjdFJlZmVyZW5jZXMobm9kZSk7XG4gICAgICB1cGRhdGVTaG9ydGhhbmRDb250ZW50cyhub2RlKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpc1J1bGUobm9kZSkpIHtcbiAgICAgIC8qKlxuICAgICAgICogVGhlIGlubmVyLWNvbnRlbnRzIG9mIGEga2V5ZnJhbWUgYXJlIHBlcmNlbnRhZ2VzLCByYXRoZXIgdGhhbiBzZWxlY3RvcnNcbiAgICAgICAqL1xuICAgICAgaWYgKGlzSW5zaWRlS2V5ZnJhbWVzKG5vZGUpKSByZXR1cm47XG5cbiAgICAgIG5vZGUuc2VsZWN0b3IgPSByZXdyaXRlU2VsZWN0b3Iobm9kZS5zZWxlY3RvciwgcG9zdGZpeCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IHJld3JpdHRlbkNzcyA9IGFzdC50b1N0cmluZygpO1xuXG4gIHJldHVybiAoXG4gICAgW1xuICAgICAgYC8qICR7ZmlsZU5hbWV9ICovYCxcbiAgICAgIGxheWVyTmFtZSA/IGBAbGF5ZXIgJHtsYXllck5hbWV9IHtgIDogJycsXG4gICAgICByZXdyaXR0ZW5Dc3MudHJpbUVuZCgpLFxuICAgICAgbGF5ZXJOYW1lID8gYH1gIDogJycsXG4gICAgXVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLmpvaW4oJ1xcbicpICsgJ1xcbidcbiAgKTtcbn1cbiIsImltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5cbmNvbnN0IEtFWSA9ICdlbWJlci1zY29wZWQuY3NzJztcbmNvbnN0IFNFUCA9ICdfX18nO1xuXG5leHBvcnQgY29uc3QgcmVxdWVzdCA9IHtcbiAgaXM6IHtcbiAgICBpbmxpbmUocmVxdWVzdCkge1xuICAgICAgcmV0dXJuIHJlcXVlc3QuaW5jbHVkZXMoS0VZKTtcbiAgICB9LFxuICAgIGNvbG9jYXRlZChyZXF1ZXN0KSB7XG4gICAgICByZXR1cm4gcmVxdWVzdC5pbmNsdWRlcygnLmNzcz9zY29wZWQ9Jyk7XG4gICAgfSxcbiAgfSxcbiAgaW5saW5lOiB7XG4gICAgLyoqXG4gICAgICogTWFrZXMgcmVxdWVzdCBVUkwgZm9yIGVtYmVkZGluZyBgPHN0eWxlPmAgYXMgYDxsaW5rPmAgaW50byB0aGUgYDxoZWFkPmBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjc3NIYXNoIHRoZSBoYXNoIG9mIHRoZSBDU1MgY29udGVudHNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zdGZpeCB0aGUgaGFzaCBvZiB0aGUgZmlsZSB0aGF0IF9pbmNsdWRlc18gdGhlIGxpbmtlZCBmaWxlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNzc0NvbnRlbnRzIHRoZSBjb250ZW50cyBvZiB0aGUgQ1NTIGZpbGVcbiAgICAgKi9cbiAgICBjcmVhdGUoY3NzSGFzaCwgcG9zdGZpeCwgY3NzQ29udGVudHMpIHtcbiAgICAgIHJldHVybiBgLi8ke3Bvc3RmaXh9JHtTRVB9JHtjc3NIYXNofS4ke0tFWX0/Y3NzPSR7ZW5jb2RlVVJJQ29tcG9uZW50KGNzc0NvbnRlbnRzKX1gO1xuICAgIH0sXG4gICAgZGVjb2RlKHJlcXVlc3QpIHtcbiAgICAgIGxldCBbbGVmdCwgcXBzXSA9IHJlcXVlc3Quc3BsaXQoJz8nKTtcblxuICAgICAgbGVmdCA9IGxlZnQuc2xpY2UoMikucmVwbGFjZShgLiR7S0VZfWAsICcnKTtcblxuICAgICAgbGV0IFtwb3N0Zml4LCBoYXNoXSA9IGxlZnQuc3BsaXQoU0VQKTtcblxuICAgICAgbGV0IHNlYXJjaCA9IG5ldyBVUkxTZWFyY2hQYXJhbXMocXBzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaGFzaCxcbiAgICAgICAgcG9zdGZpeCxcbiAgICAgICAgY3NzOiBzZWFyY2guZ2V0KCdjc3MnKSxcbiAgICAgICAgZnJvbTogc2VhcmNoLmdldCgnZnJvbScpLFxuICAgICAgfTtcbiAgICB9LFxuICB9LFxuICBjb2xvY2F0ZWQ6IHtcbiAgICAvKipcbiAgICAgKiBNYWtlcyByZXF1ZXN0IFVSTCBmb3IgZW1iZWRkaW5nIHNlcGFyYXRlIENTUyBGaWxlIGFzIGA8bGluaz5gIGludG8gdGhlIGA8aGVhZD5gXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY3NzSGFzaCB0aGUgaGFzaCBvZiB0aGUgQ1NTIGNvbnRlbnRzXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBvc3RmaXggdGhlIGhhc2ggb2YgdGhlIGZpbGUgdGhhdCBfaW5jbHVkZXNfIHRoZSBsaW5rZWQgZmlsZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCBwYXRoIHRvIHRoZSBzZXBhcmF0ZSBDU1MgRmlsZVxuICAgICAqL1xuICAgIGNyZWF0ZShjc3NIYXNoLCBwb3N0Zml4LCBmaWxlUGF0aCkge1xuICAgICAgcmV0dXJuIGAuLyR7cGF0aC5iYXNlbmFtZShmaWxlUGF0aCl9P3Njb3BlZD0ke3Bvc3RmaXh9JmNzc0hhc2g9JHtjc3NIYXNofWA7XG4gICAgfSxcbiAgICBkZWNvZGUocmVxdWVzdCkge1xuICAgICAgY29uc3QgW2ZpbGVOYW1lLCBxc10gPSByZXF1ZXN0LnNwbGl0KCc/Jyk7XG4gICAgICBjb25zdCBzZWFyY2ggPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHFzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZmlsZU5hbWUsXG4gICAgICAgIGNzc0hhc2g6IHNlYXJjaC5nZXQoJ2Nzc0hhc2gnKSxcbiAgICAgICAgcG9zdGZpeDogc2VhcmNoLmdldCgnc2NvcGVkJyksXG4gICAgICB9O1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuXG5pbXBvcnQgeyByZXdyaXRlQ3NzIH0gZnJvbSAnLi4vbGliL2Nzcy9yZXdyaXRlLmpzJztcbmltcG9ydCB7IHJlcXVlc3QgfSBmcm9tICcuLi9saWIvcmVxdWVzdC5qcyc7XG5cbmNvbnN0IE1FVEEgPSAnc2NvcGVkLWNzczpjb2xvY2F0ZWQnO1xuXG4vKipcbiAqIFBsdWdpbiBmb3Igc3VwcG9ydGluZyBjb2xvY2F0ZWQgc3R5bGVzXG4gKlxuICogZS5nLjpcbiAqICBzcmMvY29tcG9uZW50cy9teS1jb21wb25lbnQuanNcbiAqICBzcmMvY29tcG9uZW50cy9teS1jb21wb25lbnQuY3NzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb2xvY2F0ZWQob3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IENXRCA9IHByb2Nlc3MuY3dkKCk7XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCB0aGUgcmVxdWVzdCBpZCAvIHdoYXQgd2FzIGltcG9ydGVkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCAgcGF0aCBvbiBkaXNrXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBmdW5jdGlvbiBidWlsZFJlc3BvbnNlKGlkLCBmaWxlUGF0aCkge1xuICAgIGNvbnN0IHBhcnNlZCA9IHJlcXVlc3QuY29sb2NhdGVkLmRlY29kZShpZCk7XG4gICAgY29uc3QgcmVsYXRpdmVGaWxlUGF0aCA9IHBhdGgucmVsYXRpdmUoQ1dELCBmaWxlUGF0aCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IGZpbGVQYXRoLFxuICAgICAgbWV0YToge1xuICAgICAgICBbTUVUQV06IHtcbiAgICAgICAgICBwb3N0Zml4OiBwYXJzZWQucG9zdGZpeCxcbiAgICAgICAgICBmaWxlTmFtZTogcmVsYXRpdmVGaWxlUGF0aCxcbiAgICAgICAgICBmdWxsUGF0aDogZmlsZVBhdGgsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdlbWJlci1zY29wZWQtY3NzOmNvbG9jYXRlZCcsXG4gICAgcmVzb2x2ZUlkKGlkLCBpbXBvcnRlcikge1xuICAgICAgLy8gaGFuZGxlczogc29tZS1maWxlLmNzcz9zY29wZWQ9W3Bvc3RmaXhdXG4gICAgICAvLyB0aGlzIGlzIG9ubHkgcnVuIGluIHJvbGx1cCwgdml0ZSBoYW5kbGVzIGl0IGRpZmZlcmVudGx5XG4gICAgICBpZiAocmVxdWVzdC5pcy5jb2xvY2F0ZWQoaWQpKSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IHJlcXVlc3QuY29sb2NhdGVkLmRlY29kZShpZCk7XG5cbiAgICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLnJlc29sdmUoXG4gICAgICAgICAgcGF0aC5kaXJuYW1lKGltcG9ydGVyKSxcbiAgICAgICAgICBwYXRoLmJhc2VuYW1lKHBhcnNlZC5maWxlTmFtZSksXG4gICAgICAgICk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJvbGx1cCBkb2Vzbid0IG5vcm1hbGx5IHdhdGNoIENTUyBmaWxlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hZGRXYXRjaEZpbGUoZmlsZVBhdGgpO1xuXG4gICAgICAgIHJldHVybiBidWlsZFJlc3BvbnNlKGlkLCBmaWxlUGF0aCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBsb2FkKGlkKSB7XG4gICAgICBjb25zdCBtZXRhID0gdGhpcy5nZXRNb2R1bGVJbmZvKGlkKT8ubWV0YT8uW01FVEFdO1xuXG4gICAgICBpZiAobWV0YSkge1xuICAgICAgICBsZXQgY29kZSA9IHJlYWRGaWxlU3luYyhtZXRhLmZ1bGxQYXRoLCAndXRmLTgnKTtcblxuICAgICAgICBsZXQgY3NzID0gcmV3cml0ZUNzcyhcbiAgICAgICAgICBjb2RlLFxuICAgICAgICAgIG1ldGEucG9zdGZpeCxcbiAgICAgICAgICBtZXRhLmZpbGVOYW1lLFxuICAgICAgICAgIG9wdGlvbnMubGF5ZXJOYW1lLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiBjc3M7XG4gICAgICB9XG4gICAgfSxcbiAgICB2aXRlOiB7XG4gICAgICAvKipcbiAgICAgICAqIFRoZXJlIG1heSBub3QgYmUgbWV0YSBmb3IgdGhpcyByZXF1ZXN0IHlldC5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0geyp9IGlkXG4gICAgICAgKi9cbiAgICAgIGxvYWQoaWQpIHtcbiAgICAgICAgaWYgKHJlcXVlc3QuaXMuY29sb2NhdGVkKGlkKSkge1xuICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHJlcXVlc3QuY29sb2NhdGVkLmRlY29kZShpZCk7XG5cbiAgICAgICAgICBsZXQgY29kZSA9IHJlYWRGaWxlU3luYyhwYXJzZWQuZmlsZU5hbWUsICd1dGYtOCcpO1xuICAgICAgICAgIGxldCByZWxhdGl2ZUZpbGVQYXRoID0gcGF0aC5yZWxhdGl2ZShDV0QsIHBhcnNlZC5maWxlTmFtZSk7XG5cbiAgICAgICAgICBsZXQgY3NzID0gcmV3cml0ZUNzcyhcbiAgICAgICAgICAgIGNvZGUsXG4gICAgICAgICAgICBwYXJzZWQucG9zdGZpeCxcbiAgICAgICAgICAgIHJlbGF0aXZlRmlsZVBhdGgsXG4gICAgICAgICAgICBvcHRpb25zLmxheWVyTmFtZSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIGNzcztcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICB9O1xufVxuIiwiaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcblxuaW1wb3J0IHsgcmV3cml0ZUNzcyB9IGZyb20gJy4uL2xpYi9jc3MvcmV3cml0ZS5qcyc7XG5pbXBvcnQgeyByZXF1ZXN0IH0gZnJvbSAnLi4vbGliL3JlcXVlc3QuanMnO1xuXG5jb25zdCBNRVRBID0gJ3Njb3BlZC1jc3M6aW5saW5lJztcblxuLyoqXG4gKiBQbHVnaW4gZm9yIHN1cHBvcnRpbmcgdGhlIHN0eWxlcyBmcm9tXG4gKlxuICogPHRlbXBsYXRlPlxuICogICA8c3R5bGU+Li4uPC9zdHlsZT5cbiAqIDwvdGVtcGxhdGU+XG4gKlxuICogVGhpcyBwbHVnaW4gY2FuJ3QgaGF2ZSBITVIgZm9yIENTUyBiZWNhdXNlIGNoYW5nZXMgdG8gdGhlIENTUyBjb250ZW50IGFsdGVycyB0aGUgdGVtcGxhdGUgY29udGVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5saW5lKG9wdGlvbnMgPSB7fSkge1xuICBjb25zdCBDV0QgPSBwcm9jZXNzLmN3ZCgpO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgdGhlIHJlcXVlc3QgaWQgLyB3aGF0IHdhcyBpbXBvcnRlZFxuICAgKi9cbiAgZnVuY3Rpb24gYnVpbGRSZXNwb25zZShpZCwgZmlsZVBhdGgpIHtcbiAgICBjb25zdCBwYXJzZWQgPSByZXF1ZXN0LmlubGluZS5kZWNvZGUoaWQpO1xuXG4gICAgY29uc3QgcmVsYXRpdmVGaWxlUGF0aCA9IHBhdGgucmVsYXRpdmUoQ1dELCBmaWxlUGF0aCk7XG5cbiAgICBjb25zdCBjc3MgPSByZXdyaXRlQ3NzKFxuICAgICAgcGFyc2VkLmNzcyxcbiAgICAgIHBhcnNlZC5wb3N0Zml4LFxuICAgICAgYDxpbmxpbmU+LyR7cmVsYXRpdmVGaWxlUGF0aH1gLFxuICAgICAgb3B0aW9ucy5sYXllck5hbWUsXG4gICAgKTtcblxuICAgIGNvbnN0IG5leHRJZCA9IGZpbGVQYXRoLnNwbGl0KCc/JylbMF07XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IG5leHRJZCxcbiAgICAgIG1ldGE6IHtcbiAgICAgICAgW01FVEFdOiB7XG4gICAgICAgICAgY3NzLFxuICAgICAgICAgIHBvc3RmaXg6IHBhcnNlZC5wb3N0Zml4LFxuICAgICAgICAgIGZpbGVOYW1lOiByZWxhdGl2ZUZpbGVQYXRoLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAnZW1iZXItc2NvcGVkLWNzczppbmxpbmUnLFxuICAgIHJlc29sdmVJZChpZCwgaW1wb3J0ZXIpIHtcbiAgICAgIGlmIChyZXF1ZXN0LmlzLmlubGluZShpZCkpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gcmVxdWVzdC5pbmxpbmUuZGVjb2RlKGlkKTtcblxuICAgICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGgucmVzb2x2ZShcbiAgICAgICAgICBwYXRoLmRpcm5hbWUoaW1wb3J0ZXIpLFxuICAgICAgICAgIGAke3BhdGguYmFzZW5hbWUoaW1wb3J0ZXIsIHBhdGguZXh0bmFtZShpbXBvcnRlcikpfS0ke3BhcnNlZC5oYXNofS5jc3NgLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiBidWlsZFJlc3BvbnNlKGlkLCBmaWxlUGF0aCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBsb2FkKGlkKSB7XG4gICAgICBjb25zdCBtZXRhID0gdGhpcy5nZXRNb2R1bGVJbmZvKGlkKT8ubWV0YT8uW01FVEFdO1xuXG4gICAgICBpZiAobWV0YSkge1xuICAgICAgICByZXR1cm4gbWV0YS5jc3M7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cbiIsImltcG9ydCB7IGNyZWF0ZVVucGx1Z2luIH0gZnJvbSAndW5wbHVnaW4nO1xuXG5pbXBvcnQgeyBjb2xvY2F0ZWQgfSBmcm9tICcuL3VucGx1Z2luLWNvbG9jYXRlZC5qcyc7XG5pbXBvcnQgeyBpbmxpbmUgfSBmcm9tICcuL3VucGx1Z2luLWlubGluZS5qcyc7XG5cbi8qKlxuICogVGhlIHBsdWdpbiB0aGF0IGhhbmRsZXMgQ1NTIHJlcXVlc3RzIGZvciBgPHN0eWxlPmAgZWxlbWVudHMgYW5kIHRyYW5zZm9ybXNcbiAqIGZvciBleGlzdGluZyBmaWxlc1xuICpcbiAqIHZpdGU6IENTUyBmaWxlcyBhcmUgcmVzb2x2ZWQgYnkgdml0ZS4gV2UgdXNlIHRoZWlyIHJlc29sdmVyIHRvIGFsc28gZ2V0XG4gKiAgICAgICBITVIuIFRoYXQgaXMsIGZvciBhbGwgbm9uLXBoeXNpY2FsIENTUyBmaWxlcywgd2UgZXh0ZW5kIHZpdGUgYnkgb3VyXG4gKiAgICAgICByZXNvbHZlciBhbmQgYWxzbyBjYW4gZW5yaWNoIG1ldGFkYXRhIHRvIGl0IChmb3IgYmV0dGVyIGRlYnVnZ2luZylcbiAqL1xuZXhwb3J0IGNvbnN0IHVucGx1Z2luID0gY3JlYXRlVW5wbHVnaW4oKG9wdGlvbnMgPSB7fSkgPT4ge1xuICByZXR1cm4gW2NvbG9jYXRlZChvcHRpb25zKSwgaW5saW5lKG9wdGlvbnMpXTtcbn0pO1xuIiwiaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcblxuaW1wb3J0IHsgbGVhZGluZ1NsYXNoUGF0aCB9IGZyb20gJy4vY29uc3QuanMnO1xuaW1wb3J0IHsgZmluZFdvcmtzcGFjZVBhdGggfSBmcm9tICcuL3V0aWxzLmpzJztcblxuLyoqXG4gKiB0ZW1wbGF0ZSBwbHVnaW5zIGRvIG5vdCBoYW5kIHVzIHRoZSBjb3JyZWN0IGZpbGUgcGF0aC5cbiAqIGFkZGl0aW9uYWxseSwgd2UgbWF5IG5vdCBiZSBhYmxlIHRvIHJlbHkgb24gdGhpcyBkYXRhIGluIHRoZSBmdXR1cmUsXG4gKiBzbyB0aGlzIGZ1bmN0aW9ucyBhY3RzIGFzIGEgbWVhbnMgb2Ygbm9ybWFsaXppbmcgX3doYXRldmVyXyB3ZSdyZSBnaXZlblxuICogaW4gdGhlIGZ1dHVyZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBmaWxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaXhGaWxlbmFtZShmaWxlbmFtZSkge1xuICBsZXQgZmlsZU5hbWUgPSBmaWxlbmFtZTtcbiAgbGV0IHdvcmtzcGFjZSA9IGZpbmRXb3Jrc3BhY2VQYXRoKGZpbGVOYW1lKTtcblxuICAvKipcbiAgICogZW1iZXItc291cmNlIDUuODpcbiAgICogLSB0aGUgZmlsZW5hbWUgbG9va3MgbGlrZSBhbiBhYnNvbHV0ZSBwYXRoLCBidXQgc3dhcHBlZCBvdXQgdGhlICdhcHAnIHBhcnQgb2YgdGhlIHBhdGhcbiAgICogICB3aXRoIHRoZSBtb2R1bGUgbmFtZSwgc28gdGhlIGZpbGUgcGF0aHMgbmV2ZXIgZXhpc3Qgb24gZGlza1xuICAgKlxuICAgKiAtIGluIHZpdGUgYXBwczpcbiAgICogICB0aGUgJ2FwcCcgcGFydCBfbWF5XyBiZSBgc3JjYCwgc28gd2UgYWxzbyBuZWVkIHRvIGVuc3VyZSB0aGF0IGBzcmNgIGlzIGV4Y2x1ZGVkIGFzIHdlbGxcbiAgICovXG4gIGxldCBoYXNBcHBEaXIgPSBmaWxlTmFtZS5pbmNsdWRlcyhwYXRoLmpvaW4od29ya3NwYWNlLCAnYXBwJykpO1xuICBsZXQgaGFzU3JjRGlyID0gZmlsZU5hbWUuaW5jbHVkZXMocGF0aC5qb2luKHdvcmtzcGFjZSwgJ3NyYycpKTtcblxuICBpZiAoXG4gICAgIShoYXNBcHBEaXIgfHwgaGFzU3JjRGlyKSAmJlxuICAgICFmaWxlTmFtZS5pbmNsdWRlcyhsZWFkaW5nU2xhc2hQYXRoLmVtYnJvaWRlckRpcilcbiAgKSB7XG4gICAgbGV0IG1heWJlTW9kdWxlID0gZmlsZU5hbWUucmVwbGFjZSh3b3Jrc3BhY2UsICcnKTtcbiAgICBsZXQgW21heWJlU2NvcGUsIC4uLnJlc3RdID0gbWF5YmVNb2R1bGUuc3BsaXQocGF0aC5zZXApLmZpbHRlcihCb29sZWFuKTtcbiAgICBsZXQgcGFydHMgPSByZXN0O1xuXG4gICAgaWYgKG1heWJlU2NvcGUuc3RhcnRzV2l0aCgnQCcpKSB7XG4gICAgICBsZXQgWywgLi4ucmVzdGVyXSA9IHJlc3Q7XG5cbiAgICAgIHBhcnRzID0gcmVzdGVyO1xuICAgIH1cblxuICAgIGxldCByZWxhdGl2ZSA9IHBhdGguam9pbiguLi5wYXJ0cyk7XG5cbiAgICAvKipcbiAgICAgKiBXZSBkb24ndCBhY3R1YWxseSBrbm93IGlmIHRoaXMgZmlsZSBpcyBhbiBhcHAuXG4gICAgICogaXQgY291bGQgYmUgYW4gYWRkb24gKHYxIG9yIHYyKVxuICAgICAqXG4gICAgICogU28gaGVyZSB3ZSBsb2cgdG8gc2VlIGlmIHdlIGhhdmUgdW5oYW5kbGVkIHNpdHVhdGlvbnMuXG4gICAgICovXG4gICAgbGV0IGNhbmRpZGF0ZVBhdGggPSBwYXRoLmpvaW4od29ya3NwYWNlLCAnYXBwJywgcmVsYXRpdmUpO1xuXG4gICAgcmV0dXJuIGNhbmRpZGF0ZVBhdGg7XG4gIH1cblxuICAvLyBUT0RPOiB3aHkgYXJlIHdlIHBhc3NlZCBmaWxlcyB0byBvdGhlciBwcm9qZWN0cz9cbiAgaWYgKCFmaWxlTmFtZS5pbmNsdWRlcyh3b3Jrc3BhY2UpKSB7XG4gICAgcmV0dXJuIGZpbGVOYW1lO1xuICB9XG5cbiAgLy8gRmFsbGJhY2sgdG8gd2hhdCB0aGUgcGx1Z2luIHN5c3RlbSBnaXZlcyB1cy5cbiAgLy8gVGhpcyBtYXkgYmUgd3JvbmcsIGFuZCBpZiB3cm9uZywgcmV2ZWFsc1xuICAvLyB1bmhhbmRsZWQgc2NlbmFyaW9zIHdpdGggdGhlIGZpbGUgbmFtZXMgaW4gdGhlIHBsdWdpbiBpbmZyYVxuICByZXR1cm4gZmlsZU5hbWU7XG59XG4iLCIvKipcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lXG4gKiBAcGFyYW0ge3N0cmluZ30gcG9zdGZpeFxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gW2NsYXNzZXNJbkNzc11cbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5hbWVDbGFzcyhjbGFzc05hbWUsIHBvc3RmaXgsIGNsYXNzZXNJbkNzcykge1xuICBjb25zdCBjbGFzc2VzID0gY2xhc3NOYW1lLnNwbGl0KC9cXHMrLyk7XG4gIGNvbnN0IHJlbmFtZWRDbGFzc2VzID0gY2xhc3Nlc1xuICAgIC5maWx0ZXIoKGMpID0+IGMpXG4gICAgLm1hcCgoYykgPT4gYy50cmltKCkpXG4gICAgLm1hcCgoYykgPT4ge1xuICAgICAgaWYgKCFjbGFzc2VzSW5Dc3MgfHwgY2xhc3Nlc0luQ3NzLmhhcyhjKSkge1xuICAgICAgICBpZiAoYy5lbmRzV2l0aChwb3N0Zml4KSkgcmV0dXJuIGM7XG5cbiAgICAgICAgcmV0dXJuIGMgKyAnXycgKyBwb3N0Zml4O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYztcbiAgICB9KVxuICAgIC5qb2luKCcgJyk7XG5cbiAgY29uc3QgcmVuYW1lZFdpdGhQcmVzZXJ2ZWRTcGFjZXMgPSBjbGFzc05hbWUucmVwbGFjZShcbiAgICBjbGFzc05hbWUudHJpbVN0YXJ0KCkudHJpbUVuZCgpLFxuICAgIHJlbmFtZWRDbGFzc2VzLFxuICApO1xuXG4gIHJldHVybiByZW5hbWVkV2l0aFByZXNlcnZlZFNwYWNlcztcbn1cbiIsImltcG9ydCByZWNhc3QgZnJvbSAnZW1iZXItdGVtcGxhdGUtcmVjYXN0JztcblxuaW1wb3J0IHsgcmVuYW1lQ2xhc3MgfSBmcm9tICcuL3JlbmFtZUNsYXNzLmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHRlbXBsYXRlUGx1Z2luKHsgY2xhc3NlcywgdGFncywgcG9zdGZpeCB9KSB7XG4gIGxldCBzdGFjayA9IFtdO1xuICAvLyBzY29wZWQtY2xhc3MgaXMgYSBnbG9iYWwgd2UgYWxsb3cgaW4gaGJzXG4gIC8vIHNjb3BlZENsYXNzIGlzIGltcG9ydGFibGUsIGFuZCB3ZSdsbCBlcnJvciBpZiBzb21lb25lIHRyaWVzIHRvIHJlbmFtZSBpdFxuICBsZXQgc2NvcGVkQ2xhc3NDYW5kaWRhdGVzID0gWydzY29wZWQtY2xhc3MnLCAnc2NvcGVkQ2xhc3MnXTtcblxuICBmdW5jdGlvbiBpc1Njb3BlZENsYXNzKHN0cikge1xuICAgIGlmICghc3RyKSByZXR1cm4gZmFsc2U7XG5cbiAgICByZXR1cm4gc2NvcGVkQ2xhc3NDYW5kaWRhdGVzLnNvbWUoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlID09PSBzdHIpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBBdHRyTm9kZShub2RlKSB7XG4gICAgICBpZiAobm9kZS5uYW1lID09PSAnY2xhc3MnKSB7XG4gICAgICAgIGlmIChub2RlLnZhbHVlLnR5cGUgPT09ICdUZXh0Tm9kZScgJiYgbm9kZS52YWx1ZS5jaGFycykge1xuICAgICAgICAgIGNvbnN0IHJlbmFtZWRDbGFzcyA9IHJlbmFtZUNsYXNzKG5vZGUudmFsdWUuY2hhcnMsIHBvc3RmaXgsIGNsYXNzZXMpO1xuXG4gICAgICAgICAgbm9kZS52YWx1ZS5jaGFycyA9IHJlbmFtZWRDbGFzcztcbiAgICAgICAgfSBlbHNlIGlmIChub2RlLnZhbHVlLnR5cGUgPT09ICdDb25jYXRTdGF0ZW1lbnQnKSB7XG4gICAgICAgICAgZm9yIChsZXQgcGFydCBvZiBub2RlLnZhbHVlLnBhcnRzKSB7XG4gICAgICAgICAgICBpZiAocGFydC50eXBlID09PSAnVGV4dE5vZGUnICYmIHBhcnQuY2hhcnMpIHtcbiAgICAgICAgICAgICAgY29uc3QgcmVuYW1lZENsYXNzID0gcmVuYW1lQ2xhc3MocGFydC5jaGFycywgcG9zdGZpeCwgY2xhc3Nlcyk7XG5cbiAgICAgICAgICAgICAgcGFydC5jaGFycyA9IHJlbmFtZWRDbGFzcztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSAnTXVzdGFjaGVTdGF0ZW1lbnQnKSB7XG4gICAgICAgICAgICAgIHJlY2FzdC50cmF2ZXJzZShwYXJ0LCB7XG4gICAgICAgICAgICAgICAgU3RyaW5nTGl0ZXJhbChub2RlKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCByZW5hbWVkQ2xhc3MgPSByZW5hbWVDbGFzcyhcbiAgICAgICAgICAgICAgICAgICAgbm9kZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zdGZpeCxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NlcyxcbiAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgIG5vZGUudmFsdWUgPSByZW5hbWVkQ2xhc3M7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIEVsZW1lbnROb2RlKG5vZGUpIHtcbiAgICAgIGlmICh0YWdzLmhhcyhub2RlLnRhZykpIHtcbiAgICAgICAgLy8gY2hlY2sgaWYgY2xhc3MgYXR0cmlidXRlIGFscmVhZHkgZXhpc3RzXG4gICAgICAgIGNvbnN0IGNsYXNzQXR0ciA9IG5vZGUuYXR0cmlidXRlcy5maW5kKChhdHRyKSA9PiBhdHRyLm5hbWUgPT09ICdjbGFzcycpO1xuXG4gICAgICAgIGlmIChjbGFzc0F0dHIpIHtcbiAgICAgICAgICBjbGFzc0F0dHIudmFsdWUuY2hhcnMgKz0gJyAnICsgcG9zdGZpeDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBwdXNoIGNsYXNzIGF0dHJpYnV0ZVxuICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5wdXNoKFxuICAgICAgICAgICAgcmVjYXN0LmJ1aWxkZXJzLmF0dHIoJ2NsYXNzJywgcmVjYXN0LmJ1aWxkZXJzLnRleHQocG9zdGZpeCkpLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgQWxsOiB7XG4gICAgICBlbnRlcihub2RlKSB7XG4gICAgICAgIHN0YWNrLnB1c2gobm9kZSk7XG4gICAgICB9LFxuICAgICAgZXhpdCgpIHtcbiAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICB9LFxuICAgIH0sXG5cbiAgICBNdXN0YWNoZVN0YXRlbWVudChub2RlKSB7XG4gICAgICBsZXQgY3NzQ2xhc3M7XG5cbiAgICAgIGlmIChcbiAgICAgICAgaXNTY29wZWRDbGFzcyhnZXRWYWx1ZShub2RlLnBhdGgpKSAmJlxuICAgICAgICBub2RlLnBhcmFtcz8ubGVuZ3RoID09PSAxICYmXG4gICAgICAgIG5vZGUucGFyYW1zWzBdLnR5cGUgPT09ICdTdHJpbmdMaXRlcmFsJ1xuICAgICAgKSB7XG4gICAgICAgIGNzc0NsYXNzID0gbm9kZS5wYXJhbXNbMF0udmFsdWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgaXNTY29wZWRDbGFzcyhnZXRWYWx1ZShub2RlLnBhdGg/LnBhdGgpKSAmJlxuICAgICAgICBub2RlLnBhdGg/LnBhcmFtcz8ubGVuZ3RoID09PSAxICYmXG4gICAgICAgIG5vZGUucGF0aD8ucGFyYW1zWzBdLnR5cGUgPT09ICdTdHJpbmdMaXRlcmFsJ1xuICAgICAgKSB7XG4gICAgICAgIGNzc0NsYXNzID0gbm9kZS5wYXRoLnBhcmFtc1swXS52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNzc0NsYXNzKSB7XG4gICAgICAgIGNvbnN0IHRleHROb2RlID0gcmVjYXN0LmJ1aWxkZXJzLnRleHQocmVuYW1lQ2xhc3MoY3NzQ2xhc3MsIHBvc3RmaXgpKTtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07XG5cbiAgICAgICAgaWYgKHBhcmVudD8udHlwZSA9PT0gJ0F0dHJOb2RlJykge1xuICAgICAgICAgIHBhcmVudC5xdW90ZVR5cGUgPSAnXCInO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRleHROb2RlO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBTdWJFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgIGlmIChcbiAgICAgICAgaXNTY29wZWRDbGFzcyhnZXRWYWx1ZShub2RlLnBhdGgpKSAmJlxuICAgICAgICBub2RlLnBhcmFtcz8ubGVuZ3RoID09PSAxICYmXG4gICAgICAgIG5vZGUucGFyYW1zWzBdLnR5cGUgPT09ICdTdHJpbmdMaXRlcmFsJ1xuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGNzc0NsYXNzID0gbm9kZS5wYXJhbXNbMF0udmFsdWU7XG4gICAgICAgIGNvbnN0IHRleHROb2RlID0gcmVjYXN0LmJ1aWxkZXJzLmxpdGVyYWwoXG4gICAgICAgICAgJ1N0cmluZ0xpdGVyYWwnLFxuICAgICAgICAgIHJlbmFtZUNsYXNzKGNzc0NsYXNzLCBwb3N0Zml4KSxcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gdGV4dE5vZGU7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0VmFsdWUocGF0aCkge1xuICBpZiAoIXBhdGgpIHJldHVybjtcblxuICBpZiAoJ3ZhbHVlJyBpbiBwYXRoKSB7XG4gICAgcmV0dXJuIHBhdGgudmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogRGVwcmVjYXRlZCBpbiBlbWJlciA1LjkrXG4gICAqIChzbyB3ZSB1c2UgdGhlIGFib3ZlIGZvciBuZXdlciBlbWJlcnMpXG4gICAqL1xuICByZXR1cm4gcGF0aC5vcmlnaW5hbDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmV3cml0ZUhicyhoYnMsIGNsYXNzZXMsIHRhZ3MsIHBvc3RmaXgpIHtcbiAgbGV0IGFzdCA9IHJlY2FzdC5wYXJzZShoYnMpO1xuXG4gIHJlY2FzdC50cmF2ZXJzZShhc3QsIHRlbXBsYXRlUGx1Z2luKHsgY2xhc3NlcywgdGFncywgcG9zdGZpeCB9KSk7XG5cbiAgbGV0IHJlc3VsdCA9IHJlY2FzdC5wcmludChhc3QpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iLCIvKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BnbGltbWVyL3N5bnRheCcpLkFTVFBsdWdpbn0gQVNUUGx1Z2luXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAZ2xpbW1lci9zeW50YXgnKS5BU1RQbHVnaW5FbnZpcm9ubWVudH0gQVNUUGx1Z2luRW52aXJvbm1lbnRcbiAqXG4gKi9cblxuaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbmltcG9ydCB7IHJld3JpdGVDc3MgfSBmcm9tICcuLi9saWIvY3NzL3Jld3JpdGUuanMnO1xuaW1wb3J0IHsgZ2V0Q1NTQ29udGVudEluZm8sIGdldENTU0luZm8gfSBmcm9tICcuLi9saWIvY3NzL3V0aWxzLmpzJztcbmltcG9ydCB7IGZpeEZpbGVuYW1lIH0gZnJvbSAnLi4vbGliL3BhdGgvdGVtcGxhdGUtdHJhbnNmb3JtLXBhdGhzLmpzJztcbmltcG9ydCB7XG4gIGFwcFBhdGgsXG4gIGNzc1BhdGhGb3IsXG4gIGZvcmNlUG9zaXgsXG4gIGhhc2hGcm9tTW9kdWxlUGF0aCxcbiAgaXNSZWxldmFudEZpbGUsXG59IGZyb20gJy4uL2xpYi9wYXRoL3V0aWxzLmpzJztcbmltcG9ydCB7IHJlcXVlc3QgfSBmcm9tICcuLi9saWIvcmVxdWVzdC5qcyc7XG5pbXBvcnQgeyB0ZW1wbGF0ZVBsdWdpbiB9IGZyb20gJy4uL2xpYi9yZXdyaXRlSGJzLmpzJztcblxuY29uc3Qgbm9vcFBsdWdpbiA9IHtcbiAgbmFtZTogJ2VtYmVyLXNjb3BlZC1jc3M6bm9vcCcsXG4gIHZpc2l0b3I6IHt9LFxufTtcblxuLyoqXG4gKiBAcmV0dXJucyB7QVNUUGx1Z2lufVxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUGx1Z2luKGNvbmZpZykge1xuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtBU1RQbHVnaW5FbnZpcm9ubWVudH0gZW52XG4gICAqL1xuICByZXR1cm4gZnVuY3Rpb24gc2NvcGVkQ3NzKGVudikge1xuICAgIGxldCBjd2QgPSBwcm9jZXNzLmN3ZCgpO1xuXG4gICAgbGV0IGlzUmVsZXZhbnQgPSBpc1JlbGV2YW50RmlsZShlbnYuZmlsZW5hbWUsIHtcbiAgICAgIGFkZGl0aW9uYWxSb290czogY29uZmlnLmFkZGl0aW9uYWxSb290cyxcbiAgICAgIGN3ZCxcbiAgICB9KTtcblxuICAgIGlmICghaXNSZWxldmFudCkge1xuICAgICAgcmV0dXJuIG5vb3BQbHVnaW47XG4gICAgfVxuXG4gICAgbGV0IGFic29sdXRlUGF0aCA9IGZpeEZpbGVuYW1lKGVudi5maWxlbmFtZSk7XG4gICAgbGV0IG1vZHVsZVBhdGggPSBhcHBQYXRoKGFic29sdXRlUGF0aCk7XG4gICAgbGV0IHBvc3RmaXggPSBoYXNoRnJvbU1vZHVsZVBhdGgobW9kdWxlUGF0aCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbGlzdCBvZiBuYWtlZCB0YWcgc2VsZWN0b3JzIGZvdW5kIGluIHRoZSBDU1NcbiAgICAgKlxuICAgICAqIEB0eXBlIHtTZXQ8c3RyaW5nPn1cbiAgICAgKi9cbiAgICBsZXQgc2NvcGVkVGFncyA9IG5ldyBTZXQoKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0IG9mIGNsYXNzZXMgZm91bmQgaW4gdGhlIENTU1xuICAgICAqXG4gICAgICogQHR5cGUge1NldDxzdHJpbmc+fVxuICAgICAqL1xuICAgIGxldCBzY29wZWRDbGFzc2VzID0gbmV3IFNldCgpO1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHt7IHRhZ3M6IFNldDxzdHJpbmc+OyBjbGFzc2VzOiBTZXQ8c3RyaW5nPiB9fSBpbmZvXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWRkSW5mbyhpbmZvKSB7XG4gICAgICBmb3IgKGxldCBpdGVtIG9mIGluZm8udGFncykge1xuICAgICAgICBzY29wZWRUYWdzLmFkZChpdGVtKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaXRlbSBvZiBpbmZvLmNsYXNzZXMpIHtcbiAgICAgICAgc2NvcGVkQ2xhc3Nlcy5hZGQoaXRlbSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGNzc1BhdGggPSBjc3NQYXRoRm9yKGFic29sdXRlUGF0aCk7XG4gICAgbGV0IGluZm8gPSBnZXRDU1NJbmZvKGNzc1BhdGgpO1xuICAgIGxldCBsb2NhbENzc1BhdGggPSBmb3JjZVBvc2l4KGNzc1BhdGgucmVwbGFjZShjd2QgKyBwYXRoLnNlcCwgJycpKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgd2lsbCBiZSBmYWxzZXkgaWYgd2UgZG9uJ3QgaGF2ZSBhIGNvLWxvY2F0ZWQgQ1NTIGZpbGUuXG4gICAgICogV2UnbGwgc3RpbGwgd2FudCB0byBjaGVjayBmb3IgZW1iZWRkZWQgPHN0eWxlIHNjb3BlZD4gdGFncyB0aG91Z2guXG4gICAgICovXG4gICAgaWYgKGluZm8pIHtcbiAgICAgIGFkZEluZm8oaW5mbyk7XG5cbiAgICAgIGxldCBjc3NSZXF1ZXN0ID0gcmVxdWVzdC5jb2xvY2F0ZWQuY3JlYXRlKGluZm8uaWQsIHBvc3RmaXgsIGxvY2FsQ3NzUGF0aCk7XG5cbiAgICAgIC8qKlxuICAgICAgICogV2l0aCB0aGlzIHdlIGRvbid0IG5lZWQgYSBKUyBwbHVnaW5cbiAgICAgICAqL1xuICAgICAgZW52Lm1ldGEuanN1dGlscy5pbXBvcnRGb3JTaWRlRWZmZWN0KGNzc1JlcXVlc3QpO1xuICAgIH1cblxuICAgIGxldCB2aXNpdG9ycyA9IHRlbXBsYXRlUGx1Z2luKHtcbiAgICAgIGNsYXNzZXM6IHNjb3BlZENsYXNzZXMsXG4gICAgICB0YWdzOiBzY29wZWRUYWdzLFxuICAgICAgcG9zdGZpeCxcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiAnZW1iZXItc2NvcGVkLWNzczp0ZW1wbGF0ZS1wbHVnaW4nLFxuICAgICAgdmlzaXRvcjoge1xuICAgICAgICAvLyBTdGFjayBNYW5hZ2VyXG4gICAgICAgIC4uLnZpc2l0b3JzLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXZSBoYXZlIHRvIGVhZ2VybHkgZ2V0IHRoZSA8c3R5bGUgc2NvcGVkPiBjb250ZW50cywgc28gd2UgY2FuIHByZS1wYXJzZVxuICAgICAgICAgKiB0aGUgdGFncyBhbmQgY2xhc3NlcyB0byB0aGVuIHBhc3MgdG8gdGhlIG90aGVyIHZpc2l0b3JzIHNvIHRoYXQgdGhleSBjYW5cbiAgICAgICAgICogYXBwcm9wcmlhdGVseSBjaGFuZ2UgbWF0Y2hpbmcgY2xhc3NlcyAvIHRhZ3MuXG4gICAgICAgICAqL1xuICAgICAgICBUZW1wbGF0ZShub2RlKSB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogV2Ugb25seSBhbGxvdyBhIHNjb3BlZCA8c3R5bGU+IGF0IHRoZSByb290XG4gICAgICAgICAgICovXG4gICAgICAgICAgbGV0IHN0eWxlVGFnID0gbm9kZS5ib2R5LmZpbmQoXG4gICAgICAgICAgICAobikgPT4gbi50eXBlID09PSAnRWxlbWVudE5vZGUnICYmIG4udGFnID09PSAnc3R5bGUnLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoaGFzU2NvcGVkQXR0cmlidXRlKHN0eWxlVGFnKSkge1xuICAgICAgICAgICAgbGV0IGNzcyA9IHRleHRDb250ZW50KHN0eWxlVGFnKTtcbiAgICAgICAgICAgIGxldCBpbmZvID0gZ2V0Q1NTQ29udGVudEluZm8oY3NzKTtcblxuICAgICAgICAgICAgYWRkSW5mbyhpbmZvKTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBUaGlzIHdpbGwgYmUgaGFuZGxlZCBpbiBFbGVtZW50Tm9kZSB0cmF2ZXJzYWxcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKGhhc0lubGluZUF0dHJpYnV0ZShzdHlsZVRhZykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgY3NzUmVxdWVzdCA9IHJlcXVlc3QuaW5saW5lLmNyZWF0ZShpbmZvLmlkLCBwb3N0Zml4LCBjc3MpO1xuXG4gICAgICAgICAgICBlbnYubWV0YS5qc3V0aWxzLmltcG9ydEZvclNpZGVFZmZlY3QoY3NzUmVxdWVzdCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIC8vIFZpc2l0b3JzIGJyb2tlbiBvdXQgbGlrZSB0aGlzIHNvIHdlIGNhbiBjb25kaXRpb25hbGx5XG4gICAgICAgIC8vIGRlYnVnIGJhc2VkIG9uIGZpbGUgcGF0aC5cbiAgICAgICAgQXR0ck5vZGUoLi4uYXJncykge1xuICAgICAgICAgIHJldHVybiB2aXNpdG9ycy5BdHRyTm9kZSguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgRWxlbWVudE5vZGUobm9kZSwgd2Fsa2VyKSB7XG4gICAgICAgICAgLy8gY2xhc3MgYXR0cmlidXRlIGhhbmRsaW5nXG4gICAgICAgICAgdmlzaXRvcnMuRWxlbWVudE5vZGUobm9kZSwgd2Fsa2VyKTtcblxuICAgICAgICAgIGlmIChoYXNTY29wZWRBdHRyaWJ1dGUobm9kZSkpIHtcbiAgICAgICAgICAgIGlmICh3YWxrZXIucGFyZW50Py5ub2RlLnR5cGUgIT09ICdUZW1wbGF0ZScpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICc8c3R5bGUgc2NvcGVkPiB0YWdzIG11c3QgYmUgYXQgdGhlIHJvb3Qgb2YgdGhlIHRlbXBsYXRlLCB0aGV5IGNhbm5vdCBiZSBuZXN0ZWQnLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaGFzSW5saW5lQXR0cmlidXRlKG5vZGUpKSB7XG4gICAgICAgICAgICAgIGxldCB0ZXh0ID0gdGV4dENvbnRlbnQobm9kZSk7XG4gICAgICAgICAgICAgIGxldCBzY29wZWRUZXh0ID0gcmV3cml0ZUNzcyhcbiAgICAgICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgICAgIHBvc3RmaXgsXG4gICAgICAgICAgICAgICAgbG9jYWxDc3NQYXRoLFxuICAgICAgICAgICAgICAgIGNvbmZpZy5sYXllck5hbWUsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAqIFRyYXZlcnNlIHRoaXMgYW5kIGFsbG93IGludGVycG9sYXRpb25cbiAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4gPSBbZW52LnN5bnRheC5idWlsZGVycy50ZXh0KHNjb3BlZFRleHQpXTtcblxuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJldHVybmluZyBudWxsIHJlbW92ZXMgdGhlIG5vZGVcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChoYXNJbmxpbmVBdHRyaWJ1dGUobm9kZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYDxzdHlsZSBpbmxpbmU+IGlzIG5vdCB2YWxpZC4gUGxlYXNlIGFkZCB0aGUgc2NvcGVkIGF0dHJpYnV0ZTogPHN0eWxlIHNjb3BlZCBpbmxpbmU+YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBNdXN0YWNoZVN0YXRlbWVudCguLi5hcmdzKSB7XG4gICAgICAgICAgcmV0dXJuIHZpc2l0b3JzLk11c3RhY2hlU3RhdGVtZW50KC4uLmFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBTdWJFeHByZXNzaW9uKC4uLmFyZ3MpIHtcbiAgICAgICAgICByZXR1cm4gdmlzaXRvcnMuU3ViRXhwcmVzc2lvbiguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGFua3MsIENhcmRTdGFjayBhbmQgQGVmNCBmb3IgdGhpcyBjb2RlLlxuICovXG5jb25zdCBTQ09QRURfQVRUUklCVVRFX05BTUUgPSAnc2NvcGVkJztcbmNvbnN0IElOTElORV9BVFRSSUJVVEVfTkFNRSA9ICdpbmxpbmUnO1xuXG5mdW5jdGlvbiBoYXNTY29wZWRBdHRyaWJ1dGUobm9kZSkge1xuICBpZiAoIW5vZGUpIHJldHVybjtcbiAgaWYgKG5vZGUudGFnICE9PSAnc3R5bGUnKSByZXR1cm47XG4gIGlmIChub2RlLnR5cGUgIT09ICdFbGVtZW50Tm9kZScpIHJldHVybjtcblxuICByZXR1cm4gbm9kZS5hdHRyaWJ1dGVzLnNvbWUoXG4gICAgKGF0dHJpYnV0ZSkgPT4gYXR0cmlidXRlLm5hbWUgPT09IFNDT1BFRF9BVFRSSUJVVEVfTkFNRSxcbiAgKTtcbn1cblxuZnVuY3Rpb24gaGFzSW5saW5lQXR0cmlidXRlKG5vZGUpIHtcbiAgaWYgKCFub2RlKSByZXR1cm47XG4gIGlmIChub2RlLnRhZyAhPT0gJ3N0eWxlJykgcmV0dXJuO1xuICBpZiAobm9kZS50eXBlICE9PSAnRWxlbWVudE5vZGUnKSByZXR1cm47XG5cbiAgcmV0dXJuIG5vZGUuYXR0cmlidXRlcy5zb21lKFxuICAgIChhdHRyaWJ1dGUpID0+IGF0dHJpYnV0ZS5uYW1lID09PSBJTkxJTkVfQVRUUklCVVRFX05BTUUsXG4gICk7XG59XG5cbmZ1bmN0aW9uIHRleHRDb250ZW50KG5vZGUpIHtcbiAgbGV0IHRleHRDaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4uZmlsdGVyKChjKSA9PiBjLnR5cGUgPT09ICdUZXh0Tm9kZScpO1xuXG4gIHJldHVybiB0ZXh0Q2hpbGRyZW4ubWFwKChjKSA9PiBjLmNoYXJzKS5qb2luKCcnKTtcbn1cbiIsImltcG9ydCAqIGFzIGJhYmVsIGZyb20gJy4uL2JhYmVsLXBsdWdpbi5qcyc7XG5pbXBvcnQgeyB1bnBsdWdpbiB9IGZyb20gJy4uL3Njb3BlZC1jc3MtdW5wbHVnaW4uanMnO1xuaW1wb3J0ICogYXMgdGVtcGxhdGUgZnJvbSAnLi4vdGVtcGxhdGUtcGx1Z2luLmpzJztcblxuZXhwb3J0IGNvbnN0IHNjb3BlZENTUyA9IHtcbiAgdml0ZTogdW5wbHVnaW4udml0ZSxcbiAgcm9sbHVwOiB1bnBsdWdpbi5yb2xsdXAsXG4gIGJhYmVsOiBiYWJlbC5zY29wZWRDU1MsXG4gIHRlbXBsYXRlOiB0ZW1wbGF0ZS5jcmVhdGVQbHVnaW4sXG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQU1BLE1BQWEsbUJBQW1CO0NBQzlCLGNBQWMsYUFBSyxLQUFLLDRCQUE0QjtDQUNw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SUFBSSxJQUFJLElBQUksVUFBVTtBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLFdBQVc7QUFDOUMsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxZQUFZO0FBQ2hELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksT0FBTztBQUM1QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFlBQVk7QUFDakQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssR0FBRyxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksVUFBVTtBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFlBQVk7QUFDakQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxXQUFXO0FBRWhELE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsV0FBVztBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLFlBQVk7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxVQUFVO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLFdBQVc7QUFDM0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxXQUFXO0FBQzlDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLEdBQUcsU0FBUztBQUM3QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFdBQVc7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsVUFBVTtBQUM3QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxHQUFHLFlBQVk7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxHQUFHLFlBQVk7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxVQUFVO0FBQzdDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFlBQVk7QUFFakQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksR0FBRyxRQUFRO0FBQzNDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksWUFBWTtBQUNoRCxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFdBQVc7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxVQUFVO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsWUFBWTtBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFdBQVc7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxXQUFXO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxLQUFLLElBQUksWUFBWTtBQUNqRCxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxHQUFHLFVBQVU7QUFDOUMsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksV0FBVztBQUMzQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxJQUFJLFdBQVc7QUFDL0MsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxTQUFTO0FBQzdDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLEdBQUcsV0FBVztBQUM5QyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFdBQVc7QUFDaEQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLEtBQUssSUFBSSxVQUFVO0FBQy9DLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUUvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksR0FBRyxXQUFXO0FBQzFDLE1BQUksTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEVBQUUsSUFBSSxJQUFJLElBQUksV0FBVztBQUMvQyxNQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksS0FBSyxJQUFJLFlBQVk7QUFDakQsTUFBSSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksSUFBSSxVQUFVO0FBQzlDLE1BQUks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