@testgorilla/tgo-typing-test 2.0.0 → 2.0.1

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