@testgorilla/tgo-typing-test 1.0.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 (134) hide show
  1. package/.eslintrc.json +46 -0
  2. package/jest.config.ts +21 -0
  3. package/ng-package.json +15 -0
  4. package/package.json +7 -22
  5. package/project.json +36 -0
  6. package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.html +30 -0
  7. package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.spec.ts +250 -0
  8. package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.ts +47 -0
  9. package/src/lib/components/tgo-typing-test/tgo-typing-test.component.html +72 -0
  10. package/src/lib/components/tgo-typing-test/tgo-typing-test.component.spec.ts +699 -0
  11. package/src/lib/components/tgo-typing-test/tgo-typing-test.component.ts +287 -0
  12. package/src/lib/helpers/config.ts +28 -0
  13. package/src/lib/helpers/constants/default-config.ts +103 -0
  14. package/src/lib/helpers/controllers/input-controller.ts +710 -0
  15. package/src/lib/helpers/controllers/quotes-controller.ts +183 -0
  16. package/src/lib/helpers/observables/banner-event.ts +18 -0
  17. package/src/lib/helpers/observables/config-event.ts +31 -0
  18. package/src/lib/helpers/observables/timer-event.ts +18 -0
  19. package/src/lib/helpers/states/active-page.ts +9 -0
  20. package/src/lib/helpers/states/composition.ts +29 -0
  21. package/src/lib/helpers/states/page-transition.ts +9 -0
  22. package/src/lib/helpers/states/slow-timer.ts +16 -0
  23. package/src/lib/helpers/states/test-active.ts +9 -0
  24. package/src/lib/helpers/states/time.ts +13 -0
  25. package/src/lib/helpers/test/caps-warning.ts +50 -0
  26. package/src/lib/helpers/test/caret.ts +92 -0
  27. package/src/lib/helpers/test/custom-text.ts +73 -0
  28. package/src/lib/helpers/test/english-punctuation.ts +38 -0
  29. package/src/lib/helpers/test/focus.ts +39 -0
  30. package/src/lib/helpers/test/manual-restart-tracker.ts +13 -0
  31. package/src/lib/helpers/test/out-of-focus.ts +19 -0
  32. package/src/lib/helpers/test/replay.ts +265 -0
  33. package/src/lib/helpers/test/test-input.ts +320 -0
  34. package/src/lib/helpers/test/test-logic.ts +1039 -0
  35. package/src/lib/helpers/test/test-state.ts +17 -0
  36. package/src/lib/helpers/test/test-stats.ts +442 -0
  37. package/src/lib/helpers/test/test-timer.ts +209 -0
  38. package/src/lib/helpers/test/test-ui.ts +370 -0
  39. package/src/lib/helpers/test/test-words.ts +72 -0
  40. package/src/lib/helpers/test/timer-progress.ts +16 -0
  41. package/src/lib/helpers/test/tts.ts +42 -0
  42. package/src/lib/helpers/test/weak-spot.ts +74 -0
  43. package/src/lib/helpers/test/wordset.ts +109 -0
  44. package/src/lib/styles/animations.scss +101 -0
  45. package/src/lib/styles/caret.scss +108 -0
  46. package/src/lib/styles/core.scss +498 -0
  47. package/src/lib/styles/index.scss +19 -0
  48. package/src/lib/styles/inputs.scss +290 -0
  49. package/src/lib/styles/popups.scss +1311 -0
  50. package/src/lib/styles/test.scss +1008 -0
  51. package/src/lib/styles/z_media-queries.scss +848 -0
  52. package/src/lib/types/types.d.ts +731 -0
  53. package/src/lib/utils/misc.ts +776 -0
  54. package/src/test-setup.ts +20 -0
  55. package/tsconfig.json +16 -0
  56. package/tsconfig.lib.json +14 -0
  57. package/tsconfig.lib.prod.json +9 -0
  58. package/tsconfig.spec.json +11 -0
  59. package/esm2022/index.mjs +0 -3
  60. package/esm2022/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.mjs +0 -45
  61. package/esm2022/lib/components/tgo-typing-test/tgo-typing-test.component.mjs +0 -299
  62. package/esm2022/lib/helpers/config.mjs +0 -24
  63. package/esm2022/lib/helpers/constants/default-config.mjs +0 -103
  64. package/esm2022/lib/helpers/controllers/input-controller.mjs +0 -586
  65. package/esm2022/lib/helpers/controllers/quotes-controller.mjs +0 -118
  66. package/esm2022/lib/helpers/observables/config-event.mjs +0 -16
  67. package/esm2022/lib/helpers/observables/timer-event.mjs +0 -16
  68. package/esm2022/lib/helpers/states/active-page.mjs +0 -8
  69. package/esm2022/lib/helpers/states/composition.mjs +0 -20
  70. package/esm2022/lib/helpers/states/page-transition.mjs +0 -8
  71. package/esm2022/lib/helpers/states/slow-timer.mjs +0 -15
  72. package/esm2022/lib/helpers/states/test-active.mjs +0 -8
  73. package/esm2022/lib/helpers/states/time.mjs +0 -11
  74. package/esm2022/lib/helpers/test/caps-warning.mjs +0 -50
  75. package/esm2022/lib/helpers/test/caret.mjs +0 -80
  76. package/esm2022/lib/helpers/test/custom-text.mjs +0 -59
  77. package/esm2022/lib/helpers/test/english-punctuation.mjs +0 -29
  78. package/esm2022/lib/helpers/test/focus.mjs +0 -35
  79. package/esm2022/lib/helpers/test/manual-restart-tracker.mjs +0 -11
  80. package/esm2022/lib/helpers/test/out-of-focus.mjs +0 -14
  81. package/esm2022/lib/helpers/test/replay.mjs +0 -217
  82. package/esm2022/lib/helpers/test/test-input.mjs +0 -264
  83. package/esm2022/lib/helpers/test/test-logic.mjs +0 -927
  84. package/esm2022/lib/helpers/test/test-state.mjs +0 -13
  85. package/esm2022/lib/helpers/test/test-stats.mjs +0 -342
  86. package/esm2022/lib/helpers/test/test-timer.mjs +0 -207
  87. package/esm2022/lib/helpers/test/test-ui.mjs +0 -341
  88. package/esm2022/lib/helpers/test/test-words.mjs +0 -69
  89. package/esm2022/lib/helpers/test/timer-progress.mjs +0 -15
  90. package/esm2022/lib/helpers/test/weak-spot.mjs +0 -65
  91. package/esm2022/lib/helpers/test/wordset.mjs +0 -100
  92. package/esm2022/lib/utils/misc.mjs +0 -673
  93. package/esm2022/testgorilla-tgo-typing-test.mjs +0 -5
  94. package/fesm2022/testgorilla-tgo-typing-test.mjs +0 -4707
  95. package/fesm2022/testgorilla-tgo-typing-test.mjs.map +0 -1
  96. package/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.d.ts +0 -14
  97. package/lib/components/tgo-typing-test/tgo-typing-test.component.d.ts +0 -54
  98. package/lib/helpers/config.d.ts +0 -98
  99. package/lib/helpers/constants/default-config.d.ts +0 -3
  100. package/lib/helpers/controllers/input-controller.d.ts +0 -16
  101. package/lib/helpers/controllers/quotes-controller.d.ts +0 -20
  102. package/lib/helpers/observables/config-event.d.ts +0 -5
  103. package/lib/helpers/observables/timer-event.d.ts +0 -4
  104. package/lib/helpers/states/active-page.d.ts +0 -2
  105. package/lib/helpers/states/composition.d.ts +0 -10
  106. package/lib/helpers/states/page-transition.d.ts +0 -2
  107. package/lib/helpers/states/slow-timer.d.ts +0 -3
  108. package/lib/helpers/states/test-active.d.ts +0 -2
  109. package/lib/helpers/states/time.d.ts +0 -3
  110. package/lib/helpers/test/caps-warning.d.ts +0 -5
  111. package/lib/helpers/test/caret.d.ts +0 -11
  112. package/lib/helpers/test/custom-text.d.ts +0 -16
  113. package/lib/helpers/test/english-punctuation.d.ts +0 -3
  114. package/lib/helpers/test/focus.d.ts +0 -7
  115. package/lib/helpers/test/manual-restart-tracker.d.ts +0 -3
  116. package/lib/helpers/test/out-of-focus.d.ts +0 -4
  117. package/lib/helpers/test/replay.d.ts +0 -20
  118. package/lib/helpers/test/test-input.d.ts +0 -86
  119. package/lib/helpers/test/test-logic.d.ts +0 -25
  120. package/lib/helpers/test/test-state.d.ts +0 -7
  121. package/lib/helpers/test/test-stats.d.ts +0 -92
  122. package/lib/helpers/test/test-timer.d.ts +0 -6
  123. package/lib/helpers/test/test-ui.d.ts +0 -27
  124. package/lib/helpers/test/test-words.d.ts +0 -23
  125. package/lib/helpers/test/timer-progress.d.ts +0 -3
  126. package/lib/helpers/test/weak-spot.d.ts +0 -3
  127. package/lib/helpers/test/wordset.d.ts +0 -7
  128. package/lib/utils/misc.d.ts +0 -81
  129. /package/{assets → src/assets}/typing-test-languages/english.json +0 -0
  130. /package/{assets → src/assets}/typing-test-languages/english_punctuation.json +0 -0
  131. /package/{assets → src/assets}/typing-test-languages/quotes/english_version_1.json +0 -0
  132. /package/{assets → src/assets}/typing-test-languages/quotes/english_version_2.json +0 -0
  133. /package/{assets → src/assets}/typing-test-languages/quotes/filtered_sources.json +0 -0
  134. /package/{index.d.ts → src/index.ts} +0 -0
@@ -1,673 +0,0 @@
1
- import { BehaviorSubject } from 'rxjs';
2
- const QuoteNetworkErrorSubject = new BehaviorSubject('');
3
- export const QuoteNetworkErrorMessage = 'Text not loading.';
4
- export function emitQuoteNetworkError() {
5
- QuoteNetworkErrorSubject.next(QuoteNetworkErrorMessage);
6
- }
7
- export const QuoteNetworkError$ = QuoteNetworkErrorSubject.asObservable();
8
- function hexToHSL(hex) {
9
- // Convert hex to RGB first
10
- let r;
11
- let g;
12
- let b;
13
- if (hex.length == 4) {
14
- r = ('0x' + hex[1] + hex[1]);
15
- g = ('0x' + hex[2] + hex[2]);
16
- b = ('0x' + hex[3] + hex[3]);
17
- }
18
- else if (hex.length == 7) {
19
- r = ('0x' + hex[1] + hex[2]);
20
- g = ('0x' + hex[3] + hex[4]);
21
- b = ('0x' + hex[5] + hex[6]);
22
- }
23
- else {
24
- r = 0x00;
25
- g = 0x00;
26
- b = 0x00;
27
- }
28
- // Then to HSL
29
- r /= 255;
30
- g /= 255;
31
- b /= 255;
32
- const cmin = Math.min(r, g, b);
33
- const cmax = Math.max(r, g, b);
34
- const delta = cmax - cmin;
35
- let h = 0;
36
- let s = 0;
37
- let l = 0;
38
- if (delta == 0)
39
- h = 0;
40
- else if (cmax == r)
41
- h = ((g - b) / delta) % 6;
42
- else if (cmax == g)
43
- h = (b - r) / delta + 2;
44
- else
45
- h = (r - g) / delta + 4;
46
- h = Math.round(h * 60);
47
- if (h < 0)
48
- h += 360;
49
- l = (cmax + cmin) / 2;
50
- s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
51
- s = +(s * 100).toFixed(1);
52
- l = +(l * 100).toFixed(1);
53
- return {
54
- hue: h,
55
- sat: s,
56
- lgt: l,
57
- string: 'hsl(' + h + ',' + s + '%,' + l + '%)',
58
- };
59
- }
60
- export function isColorLight(hex) {
61
- const hsl = hexToHSL(hex);
62
- return hsl.lgt >= 50;
63
- }
64
- export function isColorDark(hex) {
65
- const hsl = hexToHSL(hex);
66
- return hsl.lgt < 50;
67
- }
68
- let currentLanguage;
69
- export async function getLanguage(lang) {
70
- try {
71
- if (currentLanguage == undefined || currentLanguage.name !== lang) {
72
- console.log('getting language json');
73
- await fetch(`/../assets/typing-test-languages/${lang}.json`)
74
- .then(res => res.json())
75
- .then(json => {
76
- currentLanguage = json;
77
- });
78
- }
79
- return currentLanguage;
80
- }
81
- catch (e) {
82
- console.error(`error getting language`);
83
- console.error(e);
84
- await fetch(`/../assets/typing-test-languages/english.json`)
85
- .then(res => res.json())
86
- .then(json => {
87
- currentLanguage = json;
88
- });
89
- return currentLanguage;
90
- }
91
- }
92
- export async function getCurrentLanguage(languageName) {
93
- return await getLanguage(languageName);
94
- }
95
- export function smooth(arr, windowSize, getter = (value) => value) {
96
- const get = getter;
97
- const result = [];
98
- for (let i = 0; i < arr.length; i += 1) {
99
- const leftOffeset = i - windowSize;
100
- const from = leftOffeset >= 0 ? leftOffeset : 0;
101
- const to = i + windowSize + 1;
102
- let count = 0;
103
- let sum = 0;
104
- for (let j = from; j < to && j < arr.length; j += 1) {
105
- sum += get(arr[j]);
106
- count += 1;
107
- }
108
- result[i] = sum / count;
109
- }
110
- return result;
111
- }
112
- export function stdDev(array) {
113
- try {
114
- const n = array.length;
115
- const mean = array.reduce((a, b) => a + b) / n;
116
- return Math.sqrt(array.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n);
117
- }
118
- catch (e) {
119
- return 0;
120
- }
121
- }
122
- export function mean(array) {
123
- try {
124
- return array.reduce((previous, current) => (current += previous)) / array.length;
125
- }
126
- catch (e) {
127
- return 0;
128
- }
129
- }
130
- //https://www.w3resource.com/javascript-exercises/fundamental/javascript-fundamental-exercise-88.php
131
- export function median(arr) {
132
- try {
133
- const mid = Math.floor(arr.length / 2), nums = [...arr].sort((a, b) => a - b);
134
- return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
135
- }
136
- catch (e) {
137
- return 0;
138
- }
139
- }
140
- export function getLastChar(word) {
141
- try {
142
- return word.charAt(word.length - 1);
143
- }
144
- catch {
145
- return '';
146
- }
147
- }
148
- export function capitalizeFirstLetterOfEachWord(str) {
149
- return str
150
- .split(/ +/)
151
- .map(s => s.charAt(0).toUpperCase() + s.slice(1))
152
- .join(' ');
153
- }
154
- export function isASCIILetter(c) {
155
- return c.length === 1 && /[a-z]/i.test(c);
156
- }
157
- export function kogasa(cov) {
158
- return 100 * (1 - Math.tanh(cov + Math.pow(cov, 3) / 3 + Math.pow(cov, 5) / 5));
159
- }
160
- export function whorf(speed, wordlen) {
161
- return Math.min(speed, Math.floor(speed * Math.pow(1.03, -2 * (wordlen - 3))));
162
- }
163
- export function roundTo2(num) {
164
- return Math.round((num + Number.EPSILON) * 100) / 100;
165
- }
166
- export function findLineByLeastSquares(values_y) {
167
- let sum_x = 0;
168
- let sum_y = 0;
169
- let sum_xy = 0;
170
- let sum_xx = 0;
171
- let count = 0;
172
- /*
173
- * We'll use those letiables for faster read/write access.
174
- */
175
- let x = 0;
176
- let y = 0;
177
- const values_length = values_y.length;
178
- /*
179
- * Nothing to do.
180
- */
181
- if (values_length === 0) {
182
- return [[], []];
183
- }
184
- /*
185
- * Calculate the sum for each of the parts necessary.
186
- */
187
- for (let v = 0; v < values_length; v++) {
188
- x = v + 1;
189
- y = values_y[v];
190
- sum_x += x;
191
- sum_y += y;
192
- sum_xx += x * x;
193
- sum_xy += x * y;
194
- count++;
195
- }
196
- /*
197
- * Calculate m and b for the formular:
198
- * y = x * m + b
199
- */
200
- const m = (count * sum_xy - sum_x * sum_y) / (count * sum_xx - sum_x * sum_x);
201
- const b = sum_y / count - (m * sum_x) / count;
202
- const returnpoint1 = [1, 1 * m + b];
203
- const returnpoint2 = [values_length, values_length * m + b];
204
- return [returnpoint1, returnpoint2];
205
- }
206
- export function getGibberish() {
207
- const randLen = randomIntFromRange(1, 7);
208
- let ret = '';
209
- for (let i = 0; i < randLen; i++) {
210
- ret += String.fromCharCode(97 + randomIntFromRange(0, 25));
211
- }
212
- return ret;
213
- }
214
- export function secondsToString(sec, alwaysShowMinutes = false, alwaysShowHours = false, delimiter = ':', showSeconds = true, showDays = false) {
215
- sec = Math.abs(sec);
216
- let days = 0;
217
- let hours;
218
- if (showDays) {
219
- days = Math.floor(sec / 86400);
220
- hours = Math.floor((sec % 86400) / 3600);
221
- }
222
- else {
223
- hours = Math.floor(sec / 3600);
224
- }
225
- const minutes = Math.floor((sec % 3600) / 60);
226
- const seconds = roundTo2((sec % 3600) % 60);
227
- let daysString;
228
- let hoursString;
229
- let minutesString;
230
- let secondsString;
231
- if (showDays) {
232
- days < 10 && delimiter !== 'text' ? (daysString = '0' + days) : (daysString = days);
233
- }
234
- hours < 10 && delimiter !== 'text' ? (hoursString = '0' + hours) : (hoursString = hours);
235
- minutes < 10 && delimiter !== 'text'
236
- ? (minutesString = '0' + minutes)
237
- : (minutesString = minutes);
238
- seconds < 10 && (minutes > 0 || hours > 0 || alwaysShowMinutes) && delimiter !== 'text'
239
- ? (secondsString = '0' + seconds)
240
- : (secondsString = seconds);
241
- let ret = '';
242
- if (days > 0 && showDays) {
243
- ret += daysString;
244
- if (delimiter === 'text') {
245
- if (days == 1) {
246
- ret += ' day ';
247
- }
248
- else {
249
- ret += ' days ';
250
- }
251
- }
252
- else {
253
- ret += delimiter;
254
- }
255
- }
256
- if (hours > 0 || alwaysShowHours) {
257
- ret += hoursString;
258
- if (delimiter === 'text') {
259
- if (hours == 1) {
260
- ret += ' hour ';
261
- }
262
- else {
263
- ret += ' hours ';
264
- }
265
- }
266
- else {
267
- ret += delimiter;
268
- }
269
- }
270
- if (minutes > 0 || hours > 0 || alwaysShowMinutes) {
271
- ret += minutesString;
272
- if (delimiter === 'text') {
273
- if (minutes == 1) {
274
- ret += ' minute ';
275
- }
276
- else {
277
- ret += ' minutes ';
278
- }
279
- }
280
- else if (showSeconds) {
281
- ret += delimiter;
282
- }
283
- }
284
- if (showSeconds) {
285
- ret += secondsString;
286
- if (delimiter === 'text') {
287
- if (seconds == 1) {
288
- ret += ' second';
289
- }
290
- else {
291
- ret += ' seconds';
292
- }
293
- }
294
- }
295
- if (hours === 0 && minutes === 0 && !showSeconds && delimiter === 'text') {
296
- ret = 'less than 1 minute';
297
- }
298
- return ret.trim();
299
- }
300
- export function getNumbers(len, start) {
301
- const randLen = randomIntFromRange(start ? start : 1, len);
302
- let ret = '';
303
- for (let i = 0; i < randLen; i++) {
304
- let randomNum;
305
- if (i === 0) {
306
- randomNum = randomIntFromRange(1, 9);
307
- }
308
- else {
309
- randomNum = randomIntFromRange(0, 9);
310
- }
311
- ret += randomNum.toString();
312
- }
313
- return ret;
314
- }
315
- //convert numbers to arabic-indic
316
- export function convertNumberToArabicIndic(numString) {
317
- const arabicIndic = '٠١٢٣٤٥٦٧٨٩';
318
- let ret = '';
319
- for (let i = 0; i < numString.length; i++) {
320
- ret += arabicIndic[parseInt(numString[i])];
321
- }
322
- return ret;
323
- }
324
- export function getSpecials() {
325
- const randLen = randomIntFromRange(1, 7);
326
- let ret = '';
327
- const specials = [
328
- '!',
329
- '@',
330
- '#',
331
- '$',
332
- '%',
333
- '^',
334
- '&',
335
- '*',
336
- '(',
337
- ')',
338
- '-',
339
- '_',
340
- '=',
341
- '+',
342
- '{',
343
- '}',
344
- '[',
345
- ']',
346
- "'",
347
- '"',
348
- '/',
349
- '\\',
350
- '|',
351
- ];
352
- for (let i = 0; i < randLen; i++) {
353
- ret += randomElementFromArray(specials);
354
- }
355
- return ret;
356
- }
357
- export function getASCII() {
358
- const randLen = randomIntFromRange(1, 10);
359
- let ret = '';
360
- for (let i = 0; i < randLen; i++) {
361
- const ran = 33 + randomIntFromRange(0, 93);
362
- ret += String.fromCharCode(ran);
363
- }
364
- return ret;
365
- }
366
- export function getArrows() {
367
- const arrowArray = ['←', '↑', '→', '↓'];
368
- let arrowWord = '';
369
- let lastchar;
370
- for (let i = 0; i < 5; i++) {
371
- let random = randomElementFromArray(arrowArray);
372
- while (random === lastchar) {
373
- random = randomElementFromArray(arrowArray);
374
- }
375
- lastchar = random;
376
- arrowWord += random;
377
- }
378
- return arrowWord;
379
- }
380
- export function getPositionString(number) {
381
- let numend = 'th';
382
- const t = number % 10;
383
- const h = number % 100;
384
- if (t == 1 && h != 11) {
385
- numend = 'st';
386
- }
387
- if (t == 2 && h != 12) {
388
- numend = 'nd';
389
- }
390
- if (t == 3 && h != 13) {
391
- numend = 'rd';
392
- }
393
- return number + numend;
394
- }
395
- export function findGetParameter(parameterName, getOverride) {
396
- let result = null;
397
- let tmp = [];
398
- let search = location.search;
399
- if (getOverride) {
400
- search = getOverride;
401
- }
402
- search
403
- .substr(1)
404
- .split('&')
405
- .forEach(function (item) {
406
- tmp = item.split('=');
407
- if (tmp[0] === parameterName)
408
- result = decodeURIComponent(tmp[1]);
409
- });
410
- return result;
411
- }
412
- export function objectToQueryString(obj) {
413
- const str = [];
414
- for (const p in obj) {
415
- if (Object.prototype.hasOwnProperty.call(obj, p)) {
416
- // Arrays get encoded as a comma(%2C)-separated list
417
- str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
418
- }
419
- }
420
- return str.join('&');
421
- }
422
- export function toggleFullscreen() {
423
- const elem = document.documentElement;
424
- if (!document.fullscreenElement &&
425
- !document.mozFullScreenElement &&
426
- !document.webkitFullscreenElement &&
427
- !document.msFullscreenElement) {
428
- if (elem.requestFullscreen) {
429
- elem.requestFullscreen();
430
- }
431
- else if (elem.msRequestFullscreen) {
432
- elem.msRequestFullscreen();
433
- }
434
- else if (elem.mozRequestFullScreen) {
435
- elem.mozRequestFullScreen();
436
- }
437
- else if (elem.webkitRequestFullscreen) {
438
- // @ts-expect-error - Element.ALLOW_KEYBOARD_INPUT is not defined
439
- elem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
440
- }
441
- }
442
- else {
443
- if (document.exitFullscreen) {
444
- document.exitFullscreen();
445
- }
446
- else if (document.msExitFullscreen) {
447
- document.msExitFullscreen();
448
- }
449
- else if (document.mozCancelFullScreen) {
450
- document.mozCancelFullScreen();
451
- }
452
- else if (document.webkitExitFullscreen) {
453
- document.webkitExitFullscreen();
454
- }
455
- }
456
- }
457
- //credit: https://www.w3resource.com/javascript-exercises/javascript-string-exercise-32.php
458
- export function remove_non_ascii(str) {
459
- if (str === null || str === '')
460
- return '';
461
- else
462
- str = str.toString();
463
- return str.replace(/[^\x20-\x7E]/g, '');
464
- }
465
- export function escapeRegExp(str) {
466
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
467
- }
468
- export function escapeHTML(str) {
469
- str = str
470
- .replace(/&/g, '&amp;')
471
- .replace(/</g, '&lt;')
472
- .replace(/>/g, '&gt;')
473
- .replace(/"/g, '&quot;')
474
- .replace(/'/g, '&#039;');
475
- return str;
476
- }
477
- export function cleanTypographySymbols(textToClean) {
478
- const specials = {
479
- '“': '"', // &ldquo; &#8220;
480
- '”': '"', // &rdquo; &#8221;
481
- '’': "'", // &lsquo; &#8216;
482
- '‘': "'", // &rsquo; &#8217;
483
- ',': ',', // &sbquo; &#8218;
484
- '—': '-', // &mdash; &#8212;
485
- '…': '...', // &hellip; &#8230;
486
- '«': '<<',
487
- '»': '>>',
488
- '–': '-',
489
- ' ': ' ',
490
- ' ': ' ',
491
- ' ': ' ',
492
- };
493
- return textToClean.replace(/[“”’‘—,…«»–\u2007\u202F\u00A0]/g, char => specials[char] || '');
494
- }
495
- export function isUsernameValid(name) {
496
- if (name === null || name === undefined || name === '')
497
- return false;
498
- if (/miodec/.test(name.toLowerCase()))
499
- return false;
500
- if (/bitly/.test(name.toLowerCase()))
501
- return false;
502
- if (name.length > 14)
503
- return false;
504
- if (/^\..*/.test(name.toLowerCase()))
505
- return false;
506
- return /^[0-9a-zA-Z_.-]+$/.test(name);
507
- }
508
- export function mapRange(x, in_min, in_max, out_min, out_max) {
509
- let num = ((x - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min;
510
- if (out_min > out_max) {
511
- if (num > out_min) {
512
- num = out_min;
513
- }
514
- else if (num < out_max) {
515
- num = out_max;
516
- }
517
- }
518
- else {
519
- if (num < out_min) {
520
- num = out_min;
521
- }
522
- else if (num > out_max) {
523
- num = out_max;
524
- }
525
- }
526
- return num;
527
- }
528
- export function canQuickRestart(mode, words, time, CustomText) {
529
- if ((mode === 'words' && words < 1000) ||
530
- (mode === 'time' && time < 3600) ||
531
- mode === 'quote' ||
532
- (mode === 'custom' && CustomText.isWordRandom && CustomText.word < 1000) ||
533
- (mode === 'custom' && CustomText.isTimeRandom && CustomText.time < 3600) ||
534
- (mode === 'custom' && !CustomText.isWordRandom && CustomText.text.length < 1000)) {
535
- return true;
536
- }
537
- else {
538
- return false;
539
- }
540
- }
541
- export function clearTimeouts(timeouts) {
542
- timeouts.forEach(to => {
543
- if (typeof to === 'number')
544
- clearTimeout(to);
545
- else
546
- clearTimeout(to);
547
- });
548
- }
549
- //https://stackoverflow.com/questions/1431094/how-do-i-replace-a-character-at-a-particular-index-in-javascript
550
- export function setCharAt(str, index, chr) {
551
- if (index > str.length - 1)
552
- return str;
553
- return str.substring(0, index) + chr + str.substring(index + 1);
554
- }
555
- //https://stackoverflow.com/questions/273789/is-there-a-version-of-javascripts-string-indexof-that-allows-for-regular-expr
556
- export function regexIndexOf(string, regex, startpos) {
557
- const indexOf = string.substring(startpos || 0).search(regex);
558
- return indexOf >= 0 ? indexOf + (startpos || 0) : indexOf;
559
- }
560
- export function convertRGBtoHEX(rgb) {
561
- const match = rgb.match(/^rgb\((\d+), \s*(\d+), \s*(\d+)\)$/);
562
- if (match === null)
563
- return;
564
- if (match.length < 3)
565
- return;
566
- function hexCode(i) {
567
- // Take the last 2 characters and convert
568
- // them to Hexadecimal.
569
- return ('0' + parseInt(i).toString(16)).slice(-2);
570
- }
571
- return '#' + hexCode(match[1]) + hexCode(match[2]) + hexCode(match[3]);
572
- }
573
- String.prototype.lastIndexOfRegex = function (regex) {
574
- const match = this.match(regex);
575
- return match ? this.lastIndexOf(match[match.length - 1]) : -1;
576
- };
577
- export const trailingComposeChars = /[\u02B0-\u02FF`´^¨~]+$|⎄.*$/;
578
- //https://stackoverflow.com/questions/36532307/rem-px-in-javascript
579
- export function convertRemToPixels(rem) {
580
- return rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
581
- }
582
- export function getMode2(config, randomQuote) {
583
- const mode = config.mode;
584
- if (mode === 'time') {
585
- return config.time.toString();
586
- }
587
- else if (mode === 'words') {
588
- return config.words.toString();
589
- }
590
- else if (mode === 'custom') {
591
- return 'custom';
592
- }
593
- else if (mode === 'zen') {
594
- return 'zen';
595
- }
596
- else if (mode === 'quote') {
597
- return randomQuote.id.toString();
598
- }
599
- return '';
600
- }
601
- /**
602
- * Gets an integer between min and max, both are inclusive.
603
- * @param min
604
- * @param max
605
- * @returns Random integer betwen min and max.
606
- */
607
- export function randomIntFromRange(min, max) {
608
- const minNorm = Math.ceil(min);
609
- const maxNorm = Math.floor(max);
610
- return Math.floor(Math.random() * (maxNorm - minNorm + 1) + minNorm);
611
- }
612
- /**
613
- * Shuffle an array of elements using the Fisher–Yates algorithm.
614
- * This function mutates the input array.
615
- * @param elements
616
- */
617
- export function shuffle(elements) {
618
- for (let i = elements.length - 1; i > 0; --i) {
619
- const j = randomIntFromRange(0, i);
620
- const temp = elements[j];
621
- elements[j] = elements[i];
622
- elements[i] = temp;
623
- }
624
- }
625
- export function randomElementFromArray(array) {
626
- return array[randomIntFromRange(0, array.length - 1)];
627
- }
628
- export function randomElementFromObject(object) {
629
- return randomElementFromArray(Object.values(object));
630
- }
631
- export function createErrorMessage(error, message) {
632
- if (error instanceof Error) {
633
- return `${message}: ${error.message}`;
634
- }
635
- const objectWithMessage = error;
636
- if (objectWithMessage?.message) {
637
- return `${message}: ${objectWithMessage.message}`;
638
- }
639
- return message;
640
- }
641
- export async function getDiscordAvatarUrl(discordId, discordAvatar, discordAvatarSize = 32) {
642
- if (!discordId || !discordAvatar) {
643
- return null;
644
- }
645
- // An invalid request to this URL will return a 404.
646
- try {
647
- const avatarUrl = `https://cdn.discordapp.com/avatars/${discordId}/${discordAvatar}.png?size=${discordAvatarSize}`;
648
- const response = await fetch(avatarUrl);
649
- if (!response.ok) {
650
- return null;
651
- }
652
- return avatarUrl;
653
- }
654
- catch (error) {
655
- console.error(error);
656
- }
657
- return null;
658
- }
659
- export function getLevel(xp) {
660
- return (1 / 98) * (-151 + Math.sqrt(392 * xp + 22801)) + 1;
661
- }
662
- export function getXpForLevel(level) {
663
- return 49 * (level - 1) + 100;
664
- }
665
- export function abbreviateNumber(num) {
666
- if (num < 1000) {
667
- return num.toString();
668
- }
669
- const exp = Math.floor(Math.log(num) / Math.log(1000));
670
- const pre = 'kmbtqQsSond'.charAt(exp - 1);
671
- return (num / Math.pow(1000, exp)).toFixed(1) + pre;
672
- }
673
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlzYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3Rnby10eXBpbmctdGVzdC9zcmMvbGliL3V0aWxzL21pc2MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUl2QyxNQUFNLHdCQUF3QixHQUFHLElBQUksZUFBZSxDQUFTLEVBQUUsQ0FBQyxDQUFDO0FBRWpFLE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUFHLG1CQUFtQixDQUFDO0FBRTVELE1BQU0sVUFBVSxxQkFBcUI7SUFDbkMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVELE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLHdCQUF3QixDQUFDLFlBQVksRUFBRSxDQUFDO0FBRTFFLFNBQVMsUUFBUSxDQUFDLEdBQVc7SUFNM0IsMkJBQTJCO0lBQzNCLElBQUksQ0FBUyxDQUFDO0lBQ2QsSUFBSSxDQUFTLENBQUM7SUFDZCxJQUFJLENBQVMsQ0FBQztJQUNkLElBQUksR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNwQixDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBc0IsQ0FBQztRQUNsRCxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBc0IsQ0FBQztRQUNsRCxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBc0IsQ0FBQztJQUNwRCxDQUFDO1NBQU0sSUFBSSxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzNCLENBQUMsR0FB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QUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7QUFDdEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBNb25rZXlUeXBlcyB9IGZyb20gJy4uL3R5cGVzL3R5cGVzJztcblxuY29uc3QgUXVvdGVOZXR3b3JrRXJyb3JTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcnKTtcblxuZXhwb3J0IGNvbnN0IFF1b3RlTmV0d29ya0Vycm9yTWVzc2FnZSA9ICdUZXh0IG5vdCBsb2FkaW5nLic7XG5cbmV4cG9ydCBmdW5jdGlvbiBlbWl0UXVvdGVOZXR3b3JrRXJyb3IoKTogdm9pZCB7XG4gIFF1b3RlTmV0d29ya0Vycm9yU3ViamVjdC5uZXh0KFF1b3RlTmV0d29ya0Vycm9yTWVzc2FnZSk7XG59XG5cbmV4cG9ydCBjb25zdCBRdW90ZU5ldHdvcmtFcnJvciQgPSBRdW90ZU5ldHdvcmtFcnJvclN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbmZ1bmN0aW9uIGhleFRvSFNMKGhleDogc3RyaW5nKToge1xuICBodWU6IG51bWJlcjtcbiAgc2F0OiBudW1iZXI7XG4gIGxndDogbnVtYmVyO1xuICBzdHJpbmc6IHN0cmluZztcbn0ge1xuICAvLyBDb252ZXJ0IGhleCB0byBSR0IgZmlyc3RcbiAgbGV0IHI6IG51bWJlcjtcbiAgbGV0IGc6IG51bWJlcjtcbiAgbGV0IGI6IG51bWJlcjtcbiAgaWYgKGhleC5sZW5ndGggPT0gNCkge1xuICAgIHIgPSAoJzB4JyArIGhleFsxXSArIGhleFsxXSkgYXMgdW5rbm93biBhcyBudW1iZXI7XG4gICAgZyA9ICgnMHgnICsgaGV4WzJdICsgaGV4WzJdKSBhcyB1bmtub3duIGFzIG51bWJlcjtcbiAgICBiID0gKCcweCcgKyBoZXhbM10gKyBoZXhbM10pIGFzIHVua25vd24gYXMgbnVtYmVyO1xuICB9IGVsc2UgaWYgKGhleC5sZW5ndGggPT0gNykge1xuICAgIHIgPSAoJzB4JyArIGhleFsxXSArIGhleFsyXSkgYXMgdW5rbm93biBhcyBudW1iZXI7XG4gICAgZyA9ICgnMHgnICsgaGV4WzNdICsgaGV4WzRdKSBhcyB1bmtub3duIGFzIG51bWJlcjtcbiAgICBiID0gKCcweCcgKyBoZXhbNV0gKyBoZXhbNl0pIGFzIHVua25vd24gYXMgbnVtYmVyO1xuICB9IGVsc2Uge1xuICAgIHIgPSAweDAwO1xuICAgIGcgPSAweDAwO1xuICAgIGIgPSAweDAwO1xuICB9XG4gIC8vIFRoZW4gdG8gSFNMXG4gIHIgLz0gMjU1O1xuICBnIC89IDI1NTtcbiAgYiAvPSAyNTU7XG4gIGNvbnN0IGNtaW4gPSBNYXRoLm1pbihyLCBnLCBiKTtcbiAgY29uc3QgY21heCA9IE1hdGgubWF4KHIsIGcsIGIpO1xuICBjb25zdCBkZWx0YSA9IGNtYXggLSBjbWluO1xuICBsZXQgaCA9IDA7XG4gIGxldCBzID0gMDtcbiAgbGV0IGwgPSAwO1xuXG4gIGlmIChkZWx0YSA9PSAwKSBoID0gMDtcbiAgZWxzZSBpZiAoY21heCA9PSByKSBoID0gKChnIC0gYikgLyBkZWx0YSkgJSA2O1xuICBlbHNlIGlmIChjbWF4ID09IGcpIGggPSAoYiAtIHIpIC8gZGVsdGEgKyAyO1xuICBlbHNlIGggPSAociAtIGcpIC8gZGVsdGEgKyA0O1xuXG4gIGggPSBNYXRoLnJvdW5kKGggKiA2MCk7XG5cbiAgaWYgKGggPCAwKSBoICs9IDM2MDtcblxuICBsID0gKGNtYXggKyBjbWluKSAvIDI7XG4gIHMgPSBkZWx0YSA9PSAwID8gMCA6IGRlbHRhIC8gKDEgLSBNYXRoLmFicygyICogbCAtIDEpKTtcbiAgcyA9ICsocyAqIDEwMCkudG9GaXhlZCgxKTtcbiAgbCA9ICsobCAqIDEwMCkudG9GaXhlZCgxKTtcblxuICByZXR1cm4ge1xuICAgIGh1ZTogaCxcbiAgICBzYXQ6IHMsXG4gICAgbGd0OiBsLFxuICAgIHN0cmluZzogJ2hzbCgnICsgaCArICcsJyArIHMgKyAnJSwnICsgbCArICclKScsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbG9yTGlnaHQoaGV4OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgaHNsID0gaGV4VG9IU0woaGV4KTtcbiAgcmV0dXJuIGhzbC5sZ3QgPj0gNTA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbG9yRGFyayhoZXg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBoc2wgPSBoZXhUb0hTTChoZXgpO1xuICByZXR1cm4gaHNsLmxndCA8IDUwO1xufVxuXG5sZXQgY3VycmVudExhbmd1YWdlOiBNb25rZXlUeXBlcy5MYW5ndWFnZU9iamVjdDtcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRMYW5ndWFnZShsYW5nOiBzdHJpbmcpOiBQcm9taXNlPE1vbmtleVR5cGVzLkxhbmd1YWdlT2JqZWN0PiB7XG4gIHRyeSB7XG4gICAgaWYgKGN1cnJlbnRMYW5ndWFnZSA9PSB1bmRlZmluZWQgfHwgY3VycmVudExhbmd1YWdlLm5hbWUgIT09IGxhbmcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdnZXR0aW5nIGxhbmd1YWdlIGpzb24nKTtcbiAgICAgIGF3YWl0IGZldGNoKGAvLi4vYXNzZXRzL3R5cGluZy10ZXN0LWxhbmd1YWdlcy8ke2xhbmd9Lmpzb25gKVxuICAgICAgICAudGhlbihyZXMgPT4gcmVzLmpzb24oKSlcbiAgICAgICAgLnRoZW4oanNvbiA9PiB7XG4gICAgICAgICAgY3VycmVudExhbmd1YWdlID0ganNvbjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBjdXJyZW50TGFuZ3VhZ2U7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKGBlcnJvciBnZXR0aW5nIGxhbmd1YWdlYCk7XG4gICAgY29uc29sZS5lcnJvcihlKTtcbiAgICBhd2FpdCBmZXRjaChgLy4uL2Fzc2V0cy90eXBpbmctdGVzdC1sYW5ndWFnZXMvZW5nbGlzaC5qc29uYClcbiAgICAgIC50aGVuKHJlcyA9PiByZXMuanNvbigpKVxuICAgICAgLnRoZW4oanNvbiA9PiB7XG4gICAgICAgIGN1cnJlbnRMYW5ndWFnZSA9IGpzb247XG4gICAgICB9KTtcbiAgICByZXR1cm4gY3VycmVudExhbmd1YWdlO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRDdXJyZW50TGFuZ3VhZ2UoXG4gIGxhbmd1YWdlTmFtZTogc3RyaW5nXG4pOiBQcm9taXNlPE1vbmtleVR5cGVzLkxhbmd1YWdlT2JqZWN0PiB7XG4gIHJldHVybiBhd2FpdCBnZXRMYW5ndWFnZShsYW5ndWFnZU5hbWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc21vb3RoKFxuICBhcnI6IG51bWJlcltdLFxuICB3aW5kb3dTaXplOiBudW1iZXIsXG4gIGdldHRlciA9ICh2YWx1ZTogbnVtYmVyKTogbnVtYmVyID0+IHZhbHVlXG4pOiBudW1iZXJbXSB7XG4gIGNvbnN0IGdldCA9IGdldHRlcjtcbiAgY29uc3QgcmVzdWx0ID0gW107XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCBsZWZ0T2ZmZXNldCA9IGkgLSB3aW5kb3dTaXplO1xuICAgIGNvbnN0IGZyb20gPSBsZWZ0T2ZmZXNldCA+PSAwID8gbGVmdE9mZmVzZXQgOiAwO1xuICAgIGNvbnN0IHRvID0gaSArIHdpbmRvd1NpemUgKyAxO1xuXG4gICAgbGV0IGNvdW50ID0gMDtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGxldCBqID0gZnJvbTsgaiA8IHRvICYmIGogPCBhcnIubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgIHN1bSArPSBnZXQoYXJyW2pdKTtcbiAgICAgIGNvdW50ICs9IDE7XG4gICAgfVxuXG4gICAgcmVzdWx0W2ldID0gc3VtIC8gY291bnQ7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RkRGV2KGFycmF5OiBudW1iZXJbXSk6IG51bWJlciB7XG4gIHRyeSB7XG4gICAgY29uc3QgbiA9IGFycmF5Lmxlbmd0aDtcbiAgICBjb25zdCBtZWFuID0gYXJyYXkucmVkdWNlKChhLCBiKSA9PiBhICsgYikgLyBuO1xuICAgIHJldHVybiBNYXRoLnNxcnQoYXJyYXkubWFwKHggPT4gTWF0aC5wb3coeCAtIG1lYW4sIDIpKS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiKSAvIG4pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1lYW4oYXJyYXk6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXJyYXkucmVkdWNlKChwcmV2aW91cywgY3VycmVudCkgPT4gKGN1cnJlbnQgKz0gcHJldmlvdXMpKSAvIGFycmF5Lmxlbmd0aDtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiAwO1xuICB9XG59XG5cbi8vaHR0cHM6Ly93d3cudzNyZXNvdXJjZS5jb20vamF2YXNjcmlwdC1leGVyY2lzZXMvZnVuZGFtZW50YWwvamF2YXNjcmlwdC1mdW5kYW1lbnRhbC1leGVyY2lzZS04OC5waHBcbmV4cG9ydCBmdW5jdGlvbiBtZWRpYW4oYXJyOiBudW1iZXJbXSk6IG51bWJlciB7XG4gIHRyeSB7XG4gICAgY29uc3QgbWlkID0gTWF0aC5mbG9vcihhcnIubGVuZ3RoIC8gMiksXG4gICAgICBudW1zID0gWy4uLmFycl0uc29ydCgoYSwgYikgPT4gYSAtIGIpO1xuICAgIHJldHVybiBhcnIubGVuZ3RoICUgMiAhPT0gMCA/IG51bXNbbWlkXSA6IChudW1zW21pZCAtIDFdICsgbnVtc1ttaWRdKSAvIDI7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGFzdENoYXIod29yZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd29yZC5jaGFyQXQod29yZC5sZW5ndGggLSAxKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuICcnO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYXBpdGFsaXplRmlyc3RMZXR0ZXJPZkVhY2hXb3JkKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0clxuICAgIC5zcGxpdCgvICsvKVxuICAgIC5tYXAocyA9PiBzLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcy5zbGljZSgxKSlcbiAgICAuam9pbignICcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNBU0NJSUxldHRlcihjOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGMubGVuZ3RoID09PSAxICYmIC9bYS16XS9pLnRlc3QoYyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBrb2dhc2EoY292OiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gMTAwICogKDEgLSBNYXRoLnRhbmgoY292ICsgTWF0aC5wb3coY292LCAzKSAvIDMgKyBNYXRoLnBvdyhjb3YsIDUpIC8gNSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2hvcmYoc3BlZWQ6IG51bWJlciwgd29yZGxlbjogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGgubWluKHNwZWVkLCBNYXRoLmZsb29yKHNwZWVkICogTWF0aC5wb3coMS4wMywgLTIgKiAod29yZGxlbiAtIDMpKSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcm91bmRUbzIobnVtOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5yb3VuZCgobnVtICsgTnVtYmVyLkVQU0lMT04pICogMTAwKSAvIDEwMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRMaW5lQnlMZWFzdFNxdWFyZXModmFsdWVzX3k6IG51bWJlcltdKTogbnVtYmVyW11bXSB7XG4gIGxldCBzdW1feCA9IDA7XG4gIGxldCBzdW1feSA9IDA7XG4gIGxldCBzdW1feHkgPSAwO1xuICBsZXQgc3VtX3h4ID0gMDtcbiAgbGV0IGNvdW50ID0gMDtcblxuICAvKlxuICAgKiBXZSdsbCB1c2UgdGhvc2UgbGV0aWFibGVzIGZvciBmYXN0ZXIgcmVhZC93cml0ZSBhY2Nlc3MuXG4gICAqL1xuICBsZXQgeCA9IDA7XG4gIGxldCB5ID0gMDtcbiAgY29uc3QgdmFsdWVzX2xlbmd0aCA9IHZhbHVlc195Lmxlbmd0aDtcblxuICAvKlxuICAgKiBOb3RoaW5nIHRvIGRvLlxuICAgKi9cbiAgaWYgKHZhbHVlc19sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW1tdLCBbXV07XG4gIH1cblxuICAvKlxuICAgKiBDYWxjdWxhdGUgdGhlIHN1bSBmb3IgZWFjaCBvZiB0aGUgcGFydHMgbmVjZXNzYXJ5LlxuICAgKi9cbiAgZm9yIChsZXQgdiA9IDA7IHYgPCB2YWx1ZXNfbGVuZ3RoOyB2KyspIHtcbiAgICB4ID0gdiArIDE7XG4gICAgeSA9IHZhbHVlc195W3ZdO1xuICAgIHN1bV94ICs9IHg7XG4gICAgc3VtX3kgKz0geTtcbiAgICBzdW1feHggKz0geCAqIHg7XG4gICAgc3VtX3h5ICs9IHggKiB5O1xuICAgIGNvdW50Kys7XG4gIH1cblxuICAvKlxuICAgKiBDYWxjdWxhdGUgbSBhbmQgYiBmb3IgdGhlIGZvcm11bGFyOlxuICAgKiB5ID0geCAqIG0gKyBiXG4gICAqL1xuICBjb25zdCBtID0gKGNvdW50ICogc3VtX3h5IC0gc3VtX3ggKiBzdW1feSkgLyAoY291bnQgKiBzdW1feHggLSBzdW1feCAqIHN1bV94KTtcbiAgY29uc3QgYiA9IHN1bV95IC8gY291bnQgLSAobSAqIHN1bV94KSAvIGNvdW50O1xuXG4gIGNvbnN0IHJldHVybnBvaW50MSA9IFsxLCAxICogbSArIGJdO1xuICBjb25zdCByZXR1cm5wb2ludDIgPSBbdmFsdWVzX2xlbmd0aCwgdmFsdWVzX2xlbmd0aCAqIG0gKyBiXTtcbiAgcmV0dXJuIFtyZXR1cm5wb2ludDEsIHJldHVybnBvaW50Ml07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHaWJiZXJpc2goKTogc3RyaW5nIHtcbiAgY29uc3QgcmFuZExlbiA9IHJhbmRvbUludEZyb21SYW5nZSgxLCA3KTtcbiAgbGV0IHJldCA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmRMZW47IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDk3ICsgcmFuZG9tSW50RnJvbVJhbmdlKDAsIDI1KSk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlY29uZHNUb1N0cmluZyhcbiAgc2VjOiBudW1iZXIsXG4gIGFsd2F5c1Nob3dNaW51dGVzID0gZmFsc2UsXG4gIGFsd2F5c1Nob3dIb3VycyA9IGZhbHNlLFxuICBkZWxpbWl0ZXI6ICc6JyB8ICd0ZXh0JyA9ICc6JyxcbiAgc2hvd1NlY29uZHMgPSB0cnVlLFxuICBzaG93RGF5cyA9IGZhbHNlXG4pOiBzdHJpbmcge1xuICBzZWMgPSBNYXRoLmFicyhzZWMpO1xuICBsZXQgZGF5cyA9IDA7XG4gIGxldCBob3VycztcbiAgaWYgKHNob3dEYXlzKSB7XG4gICAgZGF5cyA9IE1hdGguZmxvb3Ioc2VjIC8gODY0MDApO1xuICAgIGhvdXJzID0gTWF0aC5mbG9vcigoc2VjICUgODY0MDApIC8gMzYwMCk7XG4gIH0gZWxzZSB7XG4gICAgaG91cnMgPSBNYXRoLmZsb29yKHNlYyAvIDM2MDApO1xuICB9XG4gIGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKChzZWMgJSAzNjAwKSAvIDYwKTtcbiAgY29uc3Qgc2Vjb25kcyA9IHJvdW5kVG8yKChzZWMgJSAzNjAwKSAlIDYwKTtcblxuICBsZXQgZGF5c1N0cmluZztcbiAgbGV0IGhvdXJzU3RyaW5nO1xuICBsZXQgbWludXRlc1N0cmluZztcbiAgbGV0IHNlY29uZHNTdHJpbmc7XG5cbiAgaWYgKHNob3dEYXlzKSB7XG4gICAgZGF5cyA8IDEwICYmIGRlbGltaXRlciAhPT0gJ3RleHQnID8gKGRheXNTdHJpbmcgPSAnMCcgKyBkYXlzKSA6IChkYXlzU3RyaW5nID0gZGF5cyk7XG4gIH1cbiAgaG91cnMgPCAxMCAmJiBkZWxpbWl0ZXIgIT09ICd0ZXh0JyA/IChob3Vyc1N0cmluZyA9ICcwJyArIGhvdXJzKSA6IChob3Vyc1N0cmluZyA9IGhvdXJzKTtcbiAgbWludXRlcyA8IDEwICYmIGRlbGltaXRlciAhPT0gJ3RleHQnXG4gICAgPyAobWludXRlc1N0cmluZyA9ICcwJyArIG1pbnV0ZXMpXG4gICAgOiAobWludXRlc1N0cmluZyA9IG1pbnV0ZXMpO1xuICBzZWNvbmRzIDwgMTAgJiYgKG1pbnV0ZXMgPiAwIHx8IGhvdXJzID4gMCB8fCBhbHdheXNTaG93TWludXRlcykgJiYgZGVsaW1pdGVyICE9PSAndGV4dCdcbiAgICA/IChzZWNvbmRzU3RyaW5nID0gJzAnICsgc2Vjb25kcylcbiAgICA6IChzZWNvbmRzU3RyaW5nID0gc2Vjb25kcyk7XG5cbiAgbGV0IHJldCA9ICcnO1xuICBpZiAoZGF5cyA+IDAgJiYgc2hvd0RheXMpIHtcbiAgICByZXQgKz0gZGF5c1N0cmluZztcbiAgICBpZiAoZGVsaW1pdGVyID09PSAndGV4dCcpIHtcbiAgICAgIGlmIChkYXlzID09IDEpIHtcbiAgICAgICAgcmV0ICs9ICcgZGF5ICc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXQgKz0gJyBkYXlzICc7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldCArPSBkZWxpbWl0ZXI7XG4gICAgfVxuICB9XG4gIGlmIChob3VycyA+IDAgfHwgYWx3YXlzU2hvd0hvdXJzKSB7XG4gICAgcmV0ICs9IGhvdXJzU3RyaW5nO1xuICAgIGlmIChkZWxpbWl0ZXIgPT09ICd0ZXh0Jykge1xuICAgICAgaWYgKGhvdXJzID09IDEpIHtcbiAgICAgICAgcmV0ICs9ICcgaG91ciAnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0ICs9ICcgaG91cnMgJztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0ICs9IGRlbGltaXRlcjtcbiAgICB9XG4gIH1cbiAgaWYgKG1pbnV0ZXMgPiAwIHx8IGhvdXJzID4gMCB8fCBhbHdheXNTaG93TWludXRlcykge1xuICAgIHJldCArPSBtaW51dGVzU3RyaW5nO1xuICAgIGlmIChkZWxpbWl0ZXIgPT09ICd0ZXh0Jykge1xuICAgICAgaWYgKG1pbnV0ZXMgPT0gMSkge1xuICAgICAgICByZXQgKz0gJyBtaW51dGUgJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldCArPSAnIG1pbnV0ZXMgJztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNob3dTZWNvbmRzKSB7XG4gICAgICByZXQgKz0gZGVsaW1pdGVyO1xuICAgIH1cbiAgfVxuICBpZiAoc2hvd1NlY29uZHMpIHtcbiAgICByZXQgKz0gc2Vjb25kc1N0cmluZztcbiAgICBpZiAoZGVsaW1pdGVyID09PSAndGV4dCcpIHtcbiAgICAgIGlmIChzZWNvbmRzID09IDEpIHtcbiAgICAgICAgcmV0ICs9ICcgc2Vjb25kJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldCArPSAnIHNlY29uZHMnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoaG91cnMgPT09IDAgJiYgbWludXRlcyA9PT0gMCAmJiAhc2hvd1NlY29uZHMgJiYgZGVsaW1pdGVyID09PSAndGV4dCcpIHtcbiAgICByZXQgPSAnbGVzcyB0aGFuIDEgbWludXRlJztcbiAgfVxuICByZXR1cm4gcmV0LnRyaW0oKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE51bWJlcnMobGVuOiBudW1iZXIsIHN0YXJ0PzogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgcmFuZExlbiA9IHJhbmRvbUludEZyb21SYW5nZShzdGFydCA/IHN0YXJ0IDogMSwgbGVuKTtcbiAgbGV0IHJldCA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmRMZW47IGkrKykge1xuICAgIGxldCByYW5kb21OdW07XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIHJhbmRvbU51bSA9IHJhbmRvbUludEZyb21SYW5nZSgxLCA5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmFuZG9tTnVtID0gcmFuZG9tSW50RnJvbVJhbmdlKDAsIDkpO1xuICAgIH1cbiAgICByZXQgKz0gcmFuZG9tTnVtLnRvU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuLy9jb252ZXJ0IG51bWJlcnMgdG8gYXJhYmljLWluZGljXG5leHBvcnQgZnVuY3Rpb24gY29udmVydE51bWJlclRvQXJhYmljSW5kaWMobnVtU3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBhcmFiaWNJbmRpYyA9ICfZoNmh2aLZo9mk2aXZptmn2ajZqSc7XG4gIGxldCByZXQgPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1TdHJpbmcubGVuZ3RoOyBpKyspIHtcbiAgICByZXQgKz0gYXJhYmljSW5kaWNbcGFyc2VJbnQobnVtU3RyaW5nW2ldKV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNwZWNpYWxzKCk6IHN0cmluZyB7XG4gIGNvbnN0IHJhbmRMZW4gPSByYW5kb21JbnRGcm9tUmFuZ2UoMSwgNyk7XG4gIGxldCByZXQgPSAnJztcbiAgY29uc3Qgc3BlY2lhbHMgPSBbXG4gICAgJyEnLFxuICAgICdAJyxcbiAgICAnIycsXG4gICAgJyQnLFxuICAgICclJyxcbiAgICAnXicsXG4gICAgJyYnLFxuICAgICcqJyxcbiAgICAnKCcsXG4gICAgJyknLFxuICAgICctJyxcbiAgICAnXycsXG4gICAgJz0nLFxuICAgICcrJyxcbiAgICAneycsXG4gICAgJ30nLFxuICAgICdbJyxcbiAgICAnXScsXG4gICAgXCInXCIsXG4gICAgJ1wiJyxcbiAgICAnLycsXG4gICAgJ1xcXFwnLFxuICAgICd8JyxcbiAgXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5kTGVuOyBpKyspIHtcbiAgICByZXQgKz0gcmFuZG9tRWxlbWVudEZyb21BcnJheShzcGVjaWFscyk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFTQ0lJKCk6IHN0cmluZyB7XG4gIGNvbnN0IHJhbmRMZW4gPSByYW5kb21JbnRGcm9tUmFuZ2UoMSwgMTApO1xuICBsZXQgcmV0ID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZExlbjsgaSsrKSB7XG4gICAgY29uc3QgcmFuID0gMzMgKyByYW5kb21JbnRGcm9tUmFuZ2UoMCwgOTMpO1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHJhbik7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFycm93cygpOiBzdHJpbmcge1xuICBjb25zdCBhcnJvd0FycmF5ID0gWyfihpAnLCAn4oaRJywgJ+KGkicsICfihpMnXTtcbiAgbGV0IGFycm93V29yZCA9ICcnO1xuICBsZXQgbGFzdGNoYXI7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgbGV0IHJhbmRvbSA9IHJhbmRvbUVsZW1lbnRGcm9tQXJyYXkoYXJyb3dBcnJheSk7XG4gICAgd2hpbGUgKHJhbmRvbSA9PT0gbGFzdGNoYXIpIHtcbiAgICAgIHJhbmRvbSA9IHJhbmRvbUVsZW1lbnRGcm9tQXJyYXkoYXJyb3dBcnJheSk7XG4gICAgfVxuICAgIGxhc3RjaGFyID0gcmFuZG9tO1xuICAgIGFycm93V29yZCArPSByYW5kb207XG4gIH1cbiAgcmV0dXJuIGFycm93V29yZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvc2l0aW9uU3RyaW5nKG51bWJlcjogbnVtYmVyKTogc3RyaW5nIHtcbiAgbGV0IG51bWVuZCA9ICd0aCc7XG4gIGNvbnN0IHQgPSBudW1iZXIgJSAxMDtcbiAgY29uc3QgaCA9IG51bWJlciAlIDEwMDtcbiAgaWYgKHQgPT0gMSAmJiBoICE9IDExKSB7XG4gICAgbnVtZW5kID0gJ3N0JztcbiAgfVxuICBpZiAodCA9PSAyICYmIGggIT0gMTIpIHtcbiAgICBudW1lbmQgPSAnbmQnO1xuICB9XG4gIGlmICh0ID09IDMgJiYgaCAhPSAxMykge1xuICAgIG51bWVuZCA9ICdyZCc7XG4gIH1cbiAgcmV0dXJuIG51bWJlciArIG51bWVuZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRHZXRQYXJhbWV0ZXIocGFyYW1ldGVyTmFtZTogc3RyaW5nLCBnZXRPdmVycmlkZT86IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBsZXQgcmVzdWx0ID0gbnVsbDtcbiAgbGV0IHRtcCA9IFtdO1xuXG4gIGxldCBzZWFyY2ggPSBsb2NhdGlvbi5zZWFyY2g7XG4gIGlmIChnZXRPdmVycmlkZSkge1xuICAgIHNlYXJjaCA9IGdldE92ZXJyaWRlO1xuICB9XG5cbiAgc2VhcmNoXG4gICAgLnN1YnN0cigxKVxuICAgIC5zcGxpdCgnJicpXG4gICAgLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHRtcCA9IGl0ZW0uc3BsaXQoJz0nKTtcbiAgICAgIGlmICh0bXBbMF0gPT09IHBhcmFtZXRlck5hbWUpIHJlc3VsdCA9IGRlY29kZVVSSUNvbXBvbmVudCh0bXBbMV0pO1xuICAgIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0VG9RdWVyeVN0cmluZzxUIGV4dGVuZHMgc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbj4oXG4gIG9iajogUmVjb3JkPHN0cmluZywgVCB8IFRbXT5cbik6IHN0cmluZyB7XG4gIGNvbnN0IHN0ciA9IFtdO1xuICBmb3IgKGNvbnN0IHAgaW4gb2JqKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHApKSB7XG4gICAgICAvLyBBcnJheXMgZ2V0IGVuY29kZWQgYXMgYSBjb21tYSglMkMpLXNlcGFyYXRlZCBsaXN0XG4gICAgICBzdHIucHVzaChlbmNvZGVVUklDb21wb25lbnQocCkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQob2JqW3BdIGFzIHVua25vd24gYXMgVCkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3RyLmpvaW4oJyYnKTtcbn1cblxuZGVjbGFyZSBnbG9iYWwge1xuICBpbnRlcmZhY2UgRG9jdW1lbnQge1xuICAgIG1vekNhbmNlbEZ1bGxTY3JlZW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgIG1zUmVxdWVzdEZ1bGxzY3JlZW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgIG1zRXhpdEZ1bGxzY3JlZW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgIHdlYmtpdEV4aXRGdWxsc2NyZWVuPzogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgICBtb3pGdWxsU2NyZWVuRWxlbWVudD86IEVsZW1lbnQ7XG4gICAgbXNGdWxsc2NyZWVuRWxlbWVudD86IEVsZW1lbnQ7XG4gICAgd2Via2l0RnVsbHNjcmVlbkVsZW1lbnQ/OiBFbGVtZW50O1xuICB9XG4gIGludGVyZmFjZSBIVE1MRWxlbWVudCB7XG4gICAgbXNSZXF1ZXN0RnVsbHNjcmVlbj86ICgpID0+IFByb21pc2U8dm9pZD47XG4gICAgbW96UmVxdWVzdEZ1bGxTY3JlZW4/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgIHdlYmtpdFJlcXVlc3RGdWxsc2NyZWVuPzogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9nZ2xlRnVsbHNjcmVlbigpOiB2b2lkIHtcbiAgY29uc3QgZWxlbSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgaWYgKFxuICAgICFkb2N1bWVudC5mdWxsc2NyZWVuRWxlbWVudCAmJlxuICAgICFkb2N1bWVudC5tb3pGdWxsU2NyZWVuRWxlbWVudCAmJlxuICAgICFkb2N1bWVudC53ZWJraXRGdWxsc2NyZWVuRWxlbWVudCAmJlxuICAgICFkb2N1bWVudC5tc0Z1bGxzY3JlZW5FbGVtZW50XG4gICkge1xuICAgIGlmIChlbGVtLnJlcXVlc3RGdWxsc2NyZWVuKSB7XG4gICAgICBlbGVtLnJlcXVlc3RGdWxsc2NyZWVuKCk7XG4gICAgfSBlbHNlIGlmIChlbGVtLm1zUmVxdWVzdEZ1bGxzY3JlZW4pIHtcbiAgICAgIGVsZW0ubXNSZXF1ZXN0RnVsbHNjcmVlbigpO1xuICAgIH0gZWxzZSBpZiAoZWxlbS5tb3pSZXF1ZXN0RnVsbFNjcmVlbikge1xuICAgICAgZWxlbS5tb3pSZXF1ZXN0RnVsbFNjcmVlbigpO1xuICAgIH0gZWxzZSBpZiAoZWxlbS53ZWJraXRSZXF1ZXN0RnVsbHNjcmVlbikge1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciAtIEVsZW1lbnQuQUxMT1dfS0VZQk9BUkRfSU5QVVQgaXMgbm90IGRlZmluZWRcbiAgICAgIGVsZW0ud2Via2l0UmVxdWVzdEZ1bGxzY3JlZW4oRWxlbWVudC5BTExPV19LRVlCT0FSRF9JTlBVVCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChkb2N1bWVudC5leGl0RnVsbHNjcmVlbikge1xuICAgICAgZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKTtcbiAgICB9IGVsc2UgaWYgKGRvY3VtZW50Lm1zRXhpdEZ1bGxzY3JlZW4pIHtcbiAgICAgIGRvY3VtZW50Lm1zRXhpdEZ1bGxzY3JlZW4oKTtcbiAgICB9IGVsc2UgaWYgKGRvY3VtZW50Lm1vekNhbmNlbEZ1bGxTY3JlZW4pIHtcbiAgICAgIGRvY3VtZW50Lm1vekNhbmNlbEZ1bGxTY3JlZW4oKTtcbiAgICB9IGVsc2UgaWYgKGRvY3VtZW50LndlYmtpdEV4aXRGdWxsc2NyZWVuKSB7XG4gICAgICBkb2N1bWVudC53ZWJraXRFeGl0RnVsbHNjcmVlbigpO1xuICAgIH1cbiAgfVxufVxuXG4vL2NyZWRpdDogaHR0cHM6Ly93d3cudzNyZXNvdXJjZS5jb20vamF2YXNjcmlwdC1leGVyY2lzZXMvamF2YXNjcmlwdC1zdHJpbmctZXhlcmNpc2UtMzIucGhwXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlX25vbl9hc2NpaShzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChzdHIgPT09IG51bGwgfHwgc3RyID09PSAnJykgcmV0dXJuICcnO1xuICBlbHNlIHN0ciA9IHN0ci50b1N0cmluZygpO1xuXG4gIHJldHVybiBzdHIucmVwbGFjZSgvW15cXHgyMC1cXHg3RV0vZywgJycpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlSFRNTChzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHN0ciA9IHN0clxuICAgIC5yZXBsYWNlKC8mL2csICcmYW1wOycpXG4gICAgLnJlcGxhY2UoLzwvZywgJyZsdDsnKVxuICAgIC5yZXBsYWNlKC8+L2csICcmZ3Q7JylcbiAgICAucmVwbGFjZSgvXCIvZywgJyZxdW90OycpXG4gICAgLnJlcGxhY2UoLycvZywgJyYjMDM5OycpO1xuXG4gIHJldHVybiBzdHI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhblR5cG9ncmFwaHlTeW1ib2xzKHRleHRUb0NsZWFuOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBzcGVjaWFscyA9IHtcbiAgICAn4oCcJzogJ1wiJywgLy8gJmxkcXVvO1x0JiM4MjIwO1xuICAgICfigJ0nOiAnXCInLCAvLyAmcmRxdW87XHQmIzgyMjE7XG4gICAgJ+KAmSc6IFwiJ1wiLCAvLyAmbHNxdW87XHQmIzgyMTY7XG4gICAgJ+KAmCc6IFwiJ1wiLCAvLyAmcnNxdW87XHQmIzgyMTc7XG4gICAgJywnOiAnLCcsIC8vICZzYnF1bztcdCYjODIxODtcbiAgICAn4oCUJzogJy0nLCAvLyAmbWRhc2g7ICAmIzgyMTI7XG4gICAgJ+KApic6ICcuLi4nLCAvLyAmaGVsbGlwOyAmIzgyMzA7XG4gICAgJ8KrJzogJzw8JyxcbiAgICAnwrsnOiAnPj4nLFxuICAgICfigJMnOiAnLScsXG4gICAgJ+KAhyc6ICcgJyxcbiAgICAn4oCvJzogJyAnLFxuICAgICfCoCc6ICcgJyxcbiAgfTtcbiAgcmV0dXJuIHRleHRUb0NsZWFuLnJlcGxhY2UoXG4gICAgL1vigJzigJ3igJnigJjigJQs4oCmwqvCu+KAk1xcdTIwMDdcXHUyMDJGXFx1MDBBMF0vZyxcbiAgICBjaGFyID0+IHNwZWNpYWxzW2NoYXIgYXMga2V5b2YgdHlwZW9mIHNwZWNpYWxzXSB8fCAnJ1xuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNVc2VybmFtZVZhbGlkKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBpZiAobmFtZSA9PT0gbnVsbCB8fCBuYW1lID09PSB1bmRlZmluZWQgfHwgbmFtZSA9PT0gJycpIHJldHVybiBmYWxzZTtcbiAgaWYgKC9taW9kZWMvLnRlc3QobmFtZS50b0xvd2VyQ2FzZSgpKSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoL2JpdGx5Ly50ZXN0KG5hbWUudG9Mb3dlckNhc2UoKSkpIHJldHVybiBmYWxzZTtcbiAgaWYgKG5hbWUubGVuZ3RoID4gMTQpIHJldHVybiBmYWxzZTtcbiAgaWYgKC9eXFwuLiovLnRlc3QobmFtZS50b0xvd2VyQ2FzZSgpKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gL15bMC05YS16QS1aXy4tXSskLy50ZXN0KG5hbWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFwUmFuZ2UoXG4gIHg6IG51bWJlcixcbiAgaW5fbWluOiBudW1iZXIsXG4gIGluX21heDogbnVtYmVyLFxuICBvdXRfbWluOiBudW1iZXIsXG4gIG91dF9tYXg6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgbGV0IG51bSA9ICgoeCAtIGluX21pbikgKiAob3V0X21heCAtIG91dF9taW4pKSAvIChpbl9tYXggLSBpbl9taW4pICsgb3V0X21pbjtcblxuICBpZiAob3V0X21pbiA+IG91dF9tYXgpIHtcbiAgICBpZiAobnVtID4gb3V0X21pbikge1xuICAgICAgbnVtID0gb3V0X21pbjtcbiAgICB9IGVsc2UgaWYgKG51bSA8IG91dF9tYXgpIHtcbiAgICAgIG51bSA9IG91dF9tYXg7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChudW0gPCBvdXRfbWluKSB7XG4gICAgICBudW0gPSBvdXRfbWluO1xuICAgIH0gZWxzZSBpZiAobnVtID4gb3V0X21heCkge1xuICAgICAgbnVtID0gb3V0X21heDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhblF1aWNrUmVzdGFydChcbiAgbW9kZTogc3RyaW5nLFxuICB3b3JkczogbnVtYmVyLFxuICB0aW1lOiBudW1iZXIsXG4gIEN1c3RvbVRleHQ6IE1vbmtleVR5cGVzLkN1c3RvbVRleHRcbik6IGJvb2xlYW4ge1xuICBpZiAoXG4gICAgKG1vZGUgPT09ICd3b3JkcycgJiYgd29yZHMgPCAxMDAwKSB8fFxuICAgIChtb2RlID09PSAndGltZScgJiYgdGltZSA8IDM2MDApIHx8XG4gICAgbW9kZSA9PT0gJ3F1b3RlJyB8fFxuICAgIChtb2RlID09PSAnY3VzdG9tJyAmJiBDdXN0b21UZXh0LmlzV29yZFJhbmRvbSAmJiBDdXN0b21UZXh0LndvcmQgPCAxMDAwKSB8fFxuICAgIChtb2RlID09PSAnY3VzdG9tJyAmJiBDdXN0b21UZXh0LmlzVGltZVJhbmRvbSAmJiBDdXN0b21UZXh0LnRpbWUgPCAzNjAwKSB8fFxuICAgIChtb2RlID09PSAnY3VzdG9tJyAmJiAhQ3VzdG9tVGV4dC5pc1dvcmRSYW5kb20gJiYgQ3VzdG9tVGV4dC50ZXh0Lmxlbmd0aCA8IDEwMDApXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJUaW1lb3V0cyh0aW1lb3V0czogKG51bWJlciB8IE5vZGVKUy5UaW1lb3V0KVtdKTogdm9pZCB7XG4gIHRpbWVvdXRzLmZvckVhY2godG8gPT4ge1xuICAgIGlmICh0eXBlb2YgdG8gPT09ICdudW1iZXInKSBjbGVhclRpbWVvdXQodG8pO1xuICAgIGVsc2UgY2xlYXJUaW1lb3V0KHRvKTtcbiAgfSk7XG59XG5cbi8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTQzMTA5NC9ob3ctZG8taS1yZXBsYWNlLWEtY2hhcmFjdGVyLWF0LWEtcGFydGljdWxhci1pbmRleC1pbi1qYXZhc2NyaXB0XG5leHBvcnQgZnVuY3Rpb24gc2V0Q2hhckF0KHN0cjogc3RyaW5nLCBpbmRleDogbnVtYmVyLCBjaHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChpbmRleCA+IHN0ci5sZW5ndGggLSAxKSByZXR1cm4gc3RyO1xuICByZXR1cm4gc3RyLnN1YnN0cmluZygwLCBpbmRleCkgKyBjaHIgKyBzdHIuc3Vic3RyaW5nKGluZGV4ICsgMSk7XG59XG5cbi8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjczNzg5L2lzLXRoZXJlLWEtdmVyc2lvbi1vZi1qYXZhc2NyaXB0cy1zdHJpbmctaW5kZXhvZi10aGF0LWFsbG93cy1mb3ItcmVndWxhci1leHByXG5leHBvcnQgZnVuY3Rpb24gcmVnZXhJbmRleE9mKHN0cmluZzogc3RyaW5nLCByZWdleDogUmVnRXhwLCBzdGFydHBvczogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgaW5kZXhPZiA9IHN0cmluZy5zdWJzdHJpbmcoc3RhcnRwb3MgfHwgMCkuc2VhcmNoKHJlZ2V4KTtcbiAgcmV0dXJuIGluZGV4T2YgPj0gMCA/IGluZGV4T2YgKyAoc3RhcnRwb3MgfHwgMCkgOiBpbmRleE9mO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29udmVydFJHQnRvSEVYKHJnYjogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgbWF0Y2g6IFJlZ0V4cE1hdGNoQXJyYXkgfCBudWxsID0gcmdiLm1hdGNoKC9ecmdiXFwoKFxcZCspLCBcXHMqKFxcZCspLCBcXHMqKFxcZCspXFwpJC8pO1xuICBpZiAobWF0Y2ggPT09IG51bGwpIHJldHVybjtcbiAgaWYgKG1hdGNoLmxlbmd0aCA8IDMpIHJldHVybjtcbiAgZnVuY3Rpb24gaGV4Q29kZShpOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIC8vIFRha2UgdGhlIGxhc3QgMiBjaGFyYWN0ZXJzIGFuZCBjb252ZXJ0XG4gICAgLy8gdGhlbSB0byBIZXhhZGVjaW1hbC5cblxuICAgIHJldHVybiAoJzAnICsgcGFyc2VJbnQoaSkudG9TdHJpbmcoMTYpKS5zbGljZSgtMik7XG4gIH1cbiAgcmV0dXJuICcjJyArIGhleENvZGUobWF0Y2hbMV0pICsgaGV4Q29kZShtYXRjaFsyXSkgKyBoZXhDb2RlKG1hdGNoWzNdKTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHlwZXNcbmludGVyZmFjZSBMYXN0SW5kZXggZXh0ZW5kcyBTdHJpbmcge1xuICBsYXN0SW5kZXhPZlJlZ2V4KHJlZ2V4OiBSZWdFeHApOiBudW1iZXI7XG59XG5cbihTdHJpbmcucHJvdG90eXBlIGFzIHVua25vd24gYXMgTGFzdEluZGV4KS5sYXN0SW5kZXhPZlJlZ2V4ID0gZnVuY3Rpb24gKHJlZ2V4OiBSZWdFeHApOiBudW1iZXIge1xuICBjb25zdCBtYXRjaCA9IHRoaXMubWF0Y2gocmVnZXgpO1xuICByZXR1cm4gbWF0Y2ggPyB0aGlzLmxhc3RJbmRleE9mKG1hdGNoW21hdGNoLmxlbmd0aCAtIDFdKSA6IC0xO1xufTtcblxuZXhwb3J0IGNvbnN0IHRyYWlsaW5nQ29tcG9zZUNoYXJzID0gL1tcXHUwMkIwLVxcdTAyRkZgwrRewqh+XSskfOKOhC4qJC87XG5cbi8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzY1MzIzMDcvcmVtLXB4LWluLWphdmFzY3JpcHRcbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0UmVtVG9QaXhlbHMocmVtOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gcmVtICogcGFyc2VGbG9hdChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuZm9udFNpemUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TW9kZTIoY29uZmlnOiBNb25rZXlUeXBlcy5Db25maWcsIHJhbmRvbVF1b3RlOiBNb25rZXlUeXBlcy5RdW90ZSk6IHN0cmluZyB7XG4gIGNvbnN0IG1vZGUgPSBjb25maWcubW9kZTtcbiAgaWYgKG1vZGUgPT09ICd0aW1lJykge1xuICAgIHJldHVybiBjb25maWcudGltZS50b1N0cmluZygpO1xuICB9IGVsc2UgaWYgKG1vZGUgPT09ICd3b3JkcycpIHtcbiAgICByZXR1cm4gY29uZmlnLndvcmRzLnRvU3RyaW5nKCk7XG4gIH0gZWxzZSBpZiAobW9kZSA9PT0gJ2N1c3RvbScpIHtcbiAgICByZXR1cm4gJ2N1c3RvbSc7XG4gIH0gZWxzZSBpZiAobW9kZSA9PT0gJ3plbicpIHtcbiAgICByZXR1cm4gJ3plbic7XG4gIH0gZWxzZSBpZiAobW9kZSA9PT0gJ3F1b3RlJykge1xuICAgIHJldHVybiByYW5kb21RdW90ZS5pZC50b1N0cmluZygpO1xuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuXG4vKipcbiAqIEdldHMgYW4gaW50ZWdlciBiZXR3ZWVuIG1pbiBhbmQgbWF4LCBib3RoIGFyZSBpbmNsdXNpdmUuXG4gKiBAcGFyYW0gbWluXG4gKiBAcGFyYW0gbWF4XG4gKiBAcmV0dXJucyBSYW5kb20gaW50ZWdlciBiZXR3ZW4gbWluIGFuZCBtYXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5kb21JbnRGcm9tUmFuZ2UobWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgbWluTm9ybSA9IE1hdGguY2VpbChtaW4pO1xuICBjb25zdCBtYXhOb3JtID0gTWF0aC5mbG9vcihtYXgpO1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogKG1heE5vcm0gLSBtaW5Ob3JtICsgMSkgKyBtaW5Ob3JtKTtcbn1cblxuLyoqXG4gKiBTaHVmZmxlIGFuIGFycmF5IG9mIGVsZW1lbnRzIHVzaW5nIHRoZSBGaXNoZXLigJNZYXRlcyBhbGdvcml0aG0uXG4gKiBUaGlzIGZ1bmN0aW9uIG11dGF0ZXMgdGhlIGlucHV0IGFycmF5LlxuICogQHBhcmFtIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaHVmZmxlPFQ+KGVsZW1lbnRzOiBUW10pOiB2b2lkIHtcbiAgZm9yIChsZXQgaSA9IGVsZW1lbnRzLmxlbmd0aCAtIDE7IGkgPiAwOyAtLWkpIHtcbiAgICBjb25zdCBqID0gcmFuZG9tSW50RnJvbVJhbmdlKDAsIGkpO1xuICAgIGNvbnN0IHRlbXAgPSBlbGVtZW50c1tqXTtcbiAgICBlbGVtZW50c1tqXSA9IGVsZW1lbnRzW2ldO1xuICAgIGVsZW1lbnRzW2ldID0gdGVtcDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmFuZG9tRWxlbWVudEZyb21BcnJheTxUPihhcnJheTogVFtdKTogVCB7XG4gIHJldHVybiBhcnJheVtyYW5kb21JbnRGcm9tUmFuZ2UoMCwgYXJyYXkubGVuZ3RoIC0gMSldO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmFuZG9tRWxlbWVudEZyb21PYmplY3Q8VCBleHRlbmRzIG9iamVjdD4ob2JqZWN0OiBUKTogVFtrZXlvZiBUXSB7XG4gIHJldHVybiByYW5kb21FbGVtZW50RnJvbUFycmF5KE9iamVjdC52YWx1ZXMob2JqZWN0KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFcnJvck1lc3NhZ2UoZXJyb3I6IHVua25vd24sIG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgcmV0dXJuIGAke21lc3NhZ2V9OiAke2Vycm9yLm1lc3NhZ2V9YDtcbiAgfVxuXG4gIGNvbnN0IG9iamVjdFdpdGhNZXNzYWdlID0gZXJyb3IgYXMgeyBtZXNzYWdlPzogc3RyaW5nIH07XG5cbiAgaWYgKG9iamVjdFdpdGhNZXNzYWdlPy5tZXNzYWdlKSB7XG4gICAgcmV0dXJuIGAke21lc3NhZ2V9OiAke29iamVjdFdpdGhNZXNzYWdlLm1lc3NhZ2V9YDtcbiAgfVxuXG4gIHJldHVybiBtZXNzYWdlO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RGlzY29yZEF2YXRhclVybChcbiAgZGlzY29yZElkPzogc3RyaW5nLFxuICBkaXNjb3JkQXZhdGFyPzogc3RyaW5nLFxuICBkaXNjb3JkQXZhdGFyU2l6ZSA9IDMyXG4pOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgaWYgKCFkaXNjb3JkSWQgfHwgIWRpc2NvcmRBdmF0YXIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIEFuIGludmFsaWQgcmVxdWVzdCB0byB0aGlzIFVSTCB3aWxsIHJldHVybiBhIDQwNC5cbiAgdHJ5IHtcbiAgICBjb25zdCBhdmF0YXJVcmwgPSBgaHR0cHM6Ly9jZG4uZGlzY29yZGFwcC5jb20vYXZhdGFycy8ke2Rpc2NvcmRJZH0vJHtkaXNjb3JkQXZhdGFyfS5wbmc/c2l6ZT0ke2Rpc2NvcmRBdmF0YXJTaXplfWA7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGF2YXRhclVybCk7XG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF2YXRhclVybDtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGV2ZWwoeHA6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiAoMSAvIDk4KSAqICgtMTUxICsgTWF0aC5zcXJ0KDM5MiAqIHhwICsgMjI4MDEpKSArIDE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRYcEZvckxldmVsKGxldmVsOiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gNDkgKiAobGV2ZWwgLSAxKSArIDEwMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFiYnJldmlhdGVOdW1iZXIobnVtOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAobnVtIDwgMTAwMCkge1xuICAgIHJldHVybiBudW0udG9TdHJpbmcoKTtcbiAgfVxuXG4gIGNvbnN0IGV4cCA9IE1hdGguZmxvb3IoTWF0aC5sb2cobnVtKSAvIE1hdGgubG9nKDEwMDApKTtcbiAgY29uc3QgcHJlID0gJ2ttYnRxUXNTb25kJy5jaGFyQXQoZXhwIC0gMSk7XG4gIHJldHVybiAobnVtIC8gTWF0aC5wb3coMTAwMCwgZXhwKSkudG9GaXhlZCgxKSArIHByZTtcbn1cbiJdfQ==