@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,217 +0,0 @@
1
- import config from '../../helpers/config';
2
- let wordsList = [];
3
- let replayData = [];
4
- let replayStartTime = 0;
5
- let replayRecording = true;
6
- let wordPos = 0;
7
- let curPos = 0;
8
- let targetWordPos = 0;
9
- let targetCurPos = 0;
10
- let timeoutList = [];
11
- let stopwatchList = [];
12
- let toggleButton;
13
- let replayStopwatch;
14
- function setToggleButton(toggleButtonElement) {
15
- toggleButton = toggleButtonElement?.children[0];
16
- }
17
- function setReplayStopwatch(replayStopwatchElement) {
18
- replayStopwatch = replayStopwatchElement;
19
- }
20
- function replayGetWordsList(wordsListFromScript) {
21
- wordsList = wordsListFromScript;
22
- }
23
- function initializeReplayPrompt() {
24
- const replayWordsElement = document.getElementById('replayWords');
25
- if (replayWordsElement === null)
26
- return;
27
- replayWordsElement.innerHTML = '';
28
- let wordCount = 0;
29
- replayData.forEach(item => {
30
- if (item.action === 'backWord') {
31
- wordCount--;
32
- }
33
- else if (item.action === 'submitCorrectWord' || item.action === 'submitErrorWord') {
34
- wordCount++;
35
- }
36
- });
37
- wordsList.forEach((item, i) => {
38
- if (i > wordCount)
39
- return;
40
- const x = document.createElement('div');
41
- x.className = 'word';
42
- for (i = 0; i < item.length; i++) {
43
- const letter = document.createElement('letter');
44
- letter.innerHTML = item[i];
45
- x.appendChild(letter);
46
- }
47
- replayWordsElement.appendChild(x);
48
- if (config.funbox === 'tenKeyMode') {
49
- const y = document.createElement('div');
50
- y.className = 'newline';
51
- replayWordsElement.appendChild(y);
52
- }
53
- });
54
- }
55
- export function pauseReplay() {
56
- timeoutList.forEach(item => {
57
- clearTimeout(item);
58
- });
59
- timeoutList = [];
60
- stopwatchList.forEach(item => {
61
- clearTimeout(item);
62
- });
63
- stopwatchList = [];
64
- targetCurPos = curPos;
65
- targetWordPos = wordPos;
66
- if (toggleButton === undefined)
67
- return;
68
- toggleButton.className = 'Play';
69
- toggleButton.parentNode?.setAttribute('aria-label', 'Resume replay');
70
- }
71
- function handleDisplayLogic(item, nosound = false) {
72
- let activeWord = document.getElementById('replayWords')?.children[wordPos];
73
- if (activeWord === undefined)
74
- return;
75
- if (activeWord.className == 'newline') {
76
- curPos = 0;
77
- wordPos++;
78
- activeWord = document.getElementById('replayWords')?.children[wordPos];
79
- if (activeWord === undefined)
80
- return;
81
- }
82
- if (item.action === 'correctLetter') {
83
- // if (!nosound) playSound();
84
- activeWord.children[curPos].classList.add('correct');
85
- curPos++;
86
- }
87
- else if (item.action === 'incorrectLetter') {
88
- // if (!nosound) playSound(true);
89
- let myElement;
90
- if (curPos >= activeWord.children.length) {
91
- //if letter is an extra
92
- myElement = document.createElement('letter');
93
- myElement.classList.add('extra');
94
- myElement.innerHTML = item.value?.toString() ?? '';
95
- activeWord.appendChild(myElement);
96
- }
97
- myElement = activeWord.children[curPos];
98
- myElement.classList.add('incorrect');
99
- curPos++;
100
- }
101
- else if (item.action === 'setLetterIndex' && typeof item.value === 'number') {
102
- curPos = item.value;
103
- // remove all letters from cursor to end of word
104
- for (const myElement of Array.from(activeWord.children).slice(curPos)) {
105
- if (myElement.classList.contains('extra')) {
106
- myElement.remove();
107
- }
108
- else {
109
- myElement.className = '';
110
- }
111
- }
112
- }
113
- else if (item.action === 'submitCorrectWord') {
114
- wordPos++;
115
- curPos = 0;
116
- }
117
- else if (item.action === 'submitErrorWord') {
118
- activeWord.classList.add('error');
119
- wordPos++;
120
- curPos = 0;
121
- }
122
- else if (item.action === 'backWord') {
123
- wordPos--;
124
- const replayWords = document.getElementById('replayWords');
125
- if (replayWords !== null)
126
- activeWord = replayWords.children[wordPos];
127
- curPos = activeWord.children.length;
128
- while (activeWord.children[curPos - 1].className === '')
129
- curPos--;
130
- activeWord.classList.remove('error');
131
- }
132
- }
133
- function loadOldReplay() {
134
- let startingIndex = 0;
135
- curPos = 0;
136
- wordPos = 0;
137
- replayData.forEach((item, i) => {
138
- if (wordPos < targetWordPos || (wordPos === targetWordPos && curPos < targetCurPos)) {
139
- //quickly display everything up to the target
140
- handleDisplayLogic(item, true);
141
- startingIndex = i + 1;
142
- }
143
- });
144
- const time = Math.floor((replayData[startingIndex]?.time || 0) / 1000);
145
- replayStopwatch.innerText = time + 's';
146
- return startingIndex;
147
- }
148
- function startReplayRecording() {
149
- replayData = [];
150
- replayStartTime = performance.now();
151
- replayRecording = true;
152
- targetCurPos = 0;
153
- targetWordPos = 0;
154
- }
155
- function stopReplayRecording() {
156
- replayRecording = false;
157
- }
158
- function addReplayEvent(action, value) {
159
- if (!replayRecording) {
160
- return;
161
- }
162
- const timeDelta = performance.now() - replayStartTime;
163
- replayData.push({ action: action, value: value, time: timeDelta });
164
- }
165
- function playReplay() {
166
- curPos = 0;
167
- wordPos = 0;
168
- if (toggleButton === undefined)
169
- return;
170
- toggleButton.className = 'Pause';
171
- toggleButton.parentNode?.setAttribute('aria-label', 'Pause replay');
172
- initializeReplayPrompt();
173
- const startingIndex = loadOldReplay();
174
- const lastTime = replayData[startingIndex]?.time || 0;
175
- let swTime = Math.round(lastTime / 1000); //starting time
176
- const swEndTime = Math.round((replayData[replayData.length - 1]?.time || 0) / 1000);
177
- while (swTime <= swEndTime) {
178
- const time = swTime;
179
- stopwatchList.push(setTimeout(() => {
180
- replayStopwatch.innerText = time + 's';
181
- }, time * 1000 - lastTime));
182
- swTime++;
183
- }
184
- replayData.forEach((item, i) => {
185
- if (i < startingIndex)
186
- return;
187
- timeoutList.push(setTimeout(() => {
188
- handleDisplayLogic(item);
189
- }, item.time - lastTime));
190
- });
191
- timeoutList.push(setTimeout(() => {
192
- //after the replay has finished, this will run
193
- targetCurPos = 0;
194
- targetWordPos = 0;
195
- toggleButton.className = 'Play';
196
- toggleButton.parentNode.setAttribute('aria-label', 'Start replay');
197
- }, (replayData[replayData.length - 1]?.time || 0) - lastTime));
198
- }
199
- function getReplayExport() {
200
- return JSON.stringify({
201
- replayData: replayData,
202
- wordsList: wordsList,
203
- });
204
- }
205
- function setReplayData(data) {
206
- replayData = data;
207
- }
208
- function playpauseReplayButtonClick() {
209
- if (toggleButton?.className === 'Play') {
210
- playReplay();
211
- }
212
- else if (toggleButton?.className === 'Pause') {
213
- pauseReplay();
214
- }
215
- }
216
- export { addReplayEvent, getReplayExport, initializeReplayPrompt, loadOldReplay, playReplay, playpauseReplayButtonClick, replayGetWordsList, setReplayData, setReplayStopwatch, setToggleButton, startReplayRecording, stopReplayRecording, };
217
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwbGF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvdGdvLXR5cGluZy10ZXN0L3NyYy9saWIvaGVscGVycy90ZXN0L3JlcGxheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxzQkFBc0IsQ0FBQztBQWdCMUMsSUFBSSxTQUFTLEdBQWEsRUFBRSxDQUFDO0FBQzdCLElBQUksVUFBVSxHQUFhLEVBQUUsQ0FBQztBQUM5QixJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUM7QUFDeEIsSUFBSSxlQUFlLEdBQUcsSUFBSSxDQUFDO0FBQzNCLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztBQUNoQixJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDZixJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUM7QUFDdEIsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0FBQ3JCLElBQUksV0FBVyxHQUFxQixFQUFFLENBQUM7QUFDdkMsSUFBSSxhQUFhLEdBQXFCLEVBQUUsQ0FBQztBQUN6QyxJQUFJLFlBQXFCLENBQUM7QUFDMUIsSUFBSSxlQUE0QixDQUFDO0FBRWpDLFNBQVMsZUFBZSxDQUFDLG1CQUFnQztJQUN2RCxZQUFZLEdBQUcsbUJBQW1CLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xELENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLHNCQUFtQztJQUM3RCxlQUFlLEdBQUcsc0JBQXNCLENBQUM7QUFDM0MsQ0FBQztBQUVELFNBQVMsa0JBQWtCLENBQUMsbUJBQTZCO0lBQ3ZELFNBQVMsR0FBRyxtQkFBbUIsQ0FBQztBQUNsQyxDQUFDO0FBRUQsU0FBUyxzQkFBc0I7SUFDN0IsTUFBTSxrQkFBa0IsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBRWxFLElBQUksa0JBQWtCLEtBQUssSUFBSTtRQUFFLE9BQU87SUFFeEMsa0JB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Q0FBQztBQUNILENBQUM7QUFFRCxPQUFPLEVBQ0wsY0FBYyxFQUNkLGVBQWUsRUFDZixzQkFBc0IsRUFDdEIsYUFBYSxFQUNiLFVBQVUsRUFDViwwQkFBMEIsRUFDMUIsa0JBQWtCLEVBQ2xCLGFBQWEsRUFDYixrQkFBa0IsRUFDbEIsZUFBZSxFQUNmLG9CQUFvQixFQUNwQixtQkFBbUIsR0FDcEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjb25maWcgZnJvbSAnLi4vLi4vaGVscGVycy9jb25maWcnO1xuXG50eXBlIFJlcGxheUFjdGlvbiA9XG4gIHwgJ2NvcnJlY3RMZXR0ZXInXG4gIHwgJ2luY29ycmVjdExldHRlcidcbiAgfCAnYmFja1dvcmQnXG4gIHwgJ3N1Ym1pdENvcnJlY3RXb3JkJ1xuICB8ICdzdWJtaXRFcnJvcldvcmQnXG4gIHwgJ3NldExldHRlckluZGV4JztcblxuaW50ZXJmYWNlIFJlcGxheSB7XG4gIGFjdGlvbjogUmVwbGF5QWN0aW9uO1xuICB2YWx1ZT86IHN0cmluZyB8IG51bWJlcjtcbiAgdGltZTogbnVtYmVyO1xufVxuXG5sZXQgd29yZHNMaXN0OiBzdHJpbmdbXSA9IFtdO1xubGV0IHJlcGxheURhdGE6IFJlcGxheVtdID0gW107XG5sZXQgcmVwbGF5U3RhcnRUaW1lID0gMDtcbmxldCByZXBsYXlSZWNvcmRpbmcgPSB0cnVlO1xubGV0IHdvcmRQb3MgPSAwO1xubGV0IGN1clBvcyA9IDA7XG5sZXQgdGFyZ2V0V29yZFBvcyA9IDA7XG5sZXQgdGFyZ2V0Q3VyUG9zID0gMDtcbmxldCB0aW1lb3V0TGlzdDogTm9kZUpTLlRpbWVvdXRbXSA9IFtdO1xubGV0IHN0b3B3YXRjaExpc3Q6IE5vZGVKUy5UaW1lb3V0W10gPSBbXTtcbmxldCB0b2dnbGVCdXR0b246IEVsZW1lbnQ7XG5sZXQgcmVwbGF5U3RvcHdhdGNoOiBIVE1MRWxlbWVudDtcblxuZnVuY3Rpb24gc2V0VG9nZ2xlQnV0dG9uKHRvZ2dsZUJ1dHRvbkVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gIHRvZ2dsZUJ1dHRvbiA9IHRvZ2dsZUJ1dHRvbkVsZW1lbnQ/LmNoaWxkcmVuWzBdO1xufVxuXG5mdW5jdGlvbiBzZXRSZXBsYXlTdG9wd2F0Y2gocmVwbGF5U3RvcHdhdGNoRWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgcmVwbGF5U3RvcHdhdGNoID0gcmVwbGF5U3RvcHdhdGNoRWxlbWVudDtcbn1cblxuZnVuY3Rpb24gcmVwbGF5R2V0V29yZHNMaXN0KHdvcmRzTGlzdEZyb21TY3JpcHQ6IHN0cmluZ1tdKTogdm9pZCB7XG4gIHdvcmRzTGlzdCA9IHdvcmRzTGlzdEZyb21TY3JpcHQ7XG59XG5cbmZ1bmN0aW9uIGluaXRpYWxpemVSZXBsYXlQcm9tcHQoKTogdm9pZCB7XG4gIGNvbnN0IHJlcGxheVdvcmRzRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdyZXBsYXlXb3JkcycpO1xuXG4gIGlmIChyZXBsYXlXb3Jkc0VsZW1lbnQgPT09IG51bGwpIHJldHVybjtcblxuICByZXBsYXlXb3Jkc0VsZW1lbnQuaW5uZXJIVE1MID0gJyc7XG4gIGxldCB3b3JkQ291bnQgPSAwO1xuICByZXBsYXlEYXRhLmZvckVhY2goaXRlbSA9PiB7XG4gICAgaWYgKGl0ZW0uYWN0aW9uID09PSAnYmFja1dvcmQnKSB7XG4gICAgICB3b3JkQ291bnQtLTtcbiAgICB9IGVsc2UgaWYgKGl0ZW0uYWN0aW9uID09PSAnc3VibWl0Q29ycmVjdFdvcmQnIHx8IGl0ZW0uYWN0aW9uID09PSAnc3VibWl0RXJyb3JXb3JkJykge1xuICAgICAgd29yZENvdW50Kys7XG4gICAgfVxuICB9KTtcbiAgd29yZHNMaXN0LmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICBpZiAoaSA+IHdvcmRDb3VudCkgcmV0dXJuO1xuICAgIGNvbnN0IHggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB4LmNsYXNzTmFtZSA9ICd3b3JkJztcbiAgICBmb3IgKGkgPSAwOyBpIDwgaXRlbS5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgbGV0dGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGV0dGVyJyk7XG4gICAgICBsZXR0ZXIuaW5uZXJIVE1MID0gaXRlbVtpXTtcbiAgICAgIHguYXBwZW5kQ2hpbGQobGV0dGVyKTtcbiAgICB9XG4gICAgcmVwbGF5V29yZHNFbGVtZW50LmFwcGVuZENoaWxkKHgpO1xuICAgIGlmIChjb25maWcuZnVuYm94ID09PSAndGVuS2V5TW9kZScpIHtcbiAgICAgIGNvbnN0IHkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHkuY2xhc3NOYW1lID0gJ25ld2xpbmUnO1xuICAgICAgcmVwbGF5V29yZHNFbGVtZW50LmFwcGVuZENoaWxkKHkpO1xuICAgIH1cbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXVzZVJlcGxheSgpOiB2b2lkIHtcbiAgdGltZW91dExpc3QuZm9yRWFjaChpdGVtID0+IHtcbiAgICBjbGVhclRpbWVvdXQoaXRlbSk7XG4gIH0pO1xuICB0aW1lb3V0TGlzdCA9IFtdO1xuICBzdG9wd2F0Y2hMaXN0LmZvckVhY2goaXRlbSA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KGl0ZW0pO1xuICB9KTtcbiAgc3RvcHdhdGNoTGlzdCA9IFtdO1xuICB0YXJnZXRDdXJQb3MgPSBjdXJQb3M7XG4gIHRhcmdldFdvcmRQb3MgPSB3b3JkUG9zO1xuXG4gIGlmICh0b2dnbGVCdXR0b24gPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gIHRvZ2dsZUJ1dHRvbi5jbGFzc05hbWUgPSAnUGxheSc7XG4gICh0b2dnbGVCdXR0b24ucGFyZW50Tm9kZSBhcyBFbGVtZW50KT8uc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJywgJ1Jlc3VtZSByZXBsYXknKTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlRGlzcGxheUxvZ2ljKGl0ZW06IFJlcGxheSwgbm9zb3VuZCA9IGZhbHNlKTogdm9pZCB7XG4gIGxldCBhY3RpdmVXb3JkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlcGxheVdvcmRzJyk/LmNoaWxkcmVuW3dvcmRQb3NdO1xuXG4gIGlmIChhY3RpdmVXb3JkID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgaWYgKGFjdGl2ZVdvcmQuY2xhc3NOYW1lID09ICduZXdsaW5lJykge1xuICAgIGN1clBvcyA9IDA7XG4gICAgd29yZFBvcysrO1xuICAgIGFjdGl2ZVdvcmQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncmVwbGF5V29yZHMnKT8uY2hpbGRyZW5bd29yZFBvc107XG4gICAgaWYgKGFjdGl2ZVdvcmQgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICB9XG4gIGlmIChpdGVtLmFjdGlvbiA9PT0gJ2NvcnJlY3RMZXR0ZXInKSB7XG4gICAgLy8gaWYgKCFub3NvdW5kKSBwbGF5U291bmQoKTtcbiAgICBhY3RpdmVXb3JkLmNoaWxkcmVuW2N1clBvc10uY2xhc3NMaXN0LmFkZCgnY29ycmVjdCcpO1xuICAgIGN1clBvcysrO1xuICB9IGVsc2UgaWYgKGl0ZW0uYWN0aW9uID09PSAnaW5jb3JyZWN0TGV0dGVyJykge1xuICAgIC8vIGlmICghbm9zb3VuZCkgcGxheVNvdW5kKHRydWUpO1xuICAgIGxldCBteUVsZW1lbnQ7XG4gICAgaWYgKGN1clBvcyA+PSBhY3RpdmVXb3JkLmNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgLy9pZiBsZXR0ZXIgaXMgYW4gZXh0cmFcbiAgICAgIG15RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xldHRlcicpO1xuICAgICAgbXlFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2V4dHJhJyk7XG4gICAgICBteUVsZW1lbnQuaW5uZXJIVE1MID0gaXRlbS52YWx1ZT8udG9TdHJpbmcoKSA/PyAnJztcbiAgICAgIGFjdGl2ZVdvcmQuYXBwZW5kQ2hpbGQobXlFbGVtZW50KTtcbiAgICB9XG4gICAgbXlFbGVtZW50ID0gYWN0aXZlV29yZC5jaGlsZHJlbltjdXJQb3NdO1xuICAgIG15RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdpbmNvcnJlY3QnKTtcbiAgICBjdXJQb3MrKztcbiAgfSBlbHNlIGlmIChpdGVtLmFjdGlvbiA9PT0gJ3NldExldHRlckluZGV4JyAmJiB0eXBlb2YgaXRlbS52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICBjdXJQb3MgPSBpdGVtLnZhbHVlO1xuICAgIC8vIHJlbW92ZSBhbGwgbGV0dGVycyBmcm9tIGN1cnNvciB0byBlbmQgb2Ygd29yZFxuICAgIGZvciAoY29uc3QgbXlFbGVtZW50IG9mIEFycmF5LmZyb20oYWN0aXZlV29yZC5jaGlsZHJlbikuc2xpY2UoY3VyUG9zKSkge1xuICAgICAgaWYgKG15RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2V4dHJhJykpIHtcbiAgICAgICAgbXlFbGVtZW50LnJlbW92ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXlFbGVtZW50LmNsYXNzTmFtZSA9ICcnO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpdGVtLmFjdGlvbiA9PT0gJ3N1Ym1pdENvcnJlY3RXb3JkJykge1xuICAgIHdvcmRQb3MrKztcbiAgICBjdXJQb3MgPSAwO1xuICB9IGVsc2UgaWYgKGl0ZW0uYWN0aW9uID09PSAnc3VibWl0RXJyb3JXb3JkJykge1xuICAgIGFjdGl2ZVdvcmQuY2xhc3NMaXN0LmFkZCgnZXJyb3InKTtcbiAgICB3b3JkUG9zKys7XG4gICAgY3VyUG9zID0gMDtcbiAgfSBlbHNlIGlmIChpdGVtLmFjdGlvbiA9PT0gJ2JhY2tXb3JkJykge1xuICAgIHdvcmRQb3MtLTtcblxuICAgIGNvbnN0IHJlcGxheVdvcmRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3JlcGxheVdvcmRzJyk7XG5cbiAgICBpZiAocmVwbGF5V29yZHMgIT09IG51bGwpIGFjdGl2ZVdvcmQgPSByZXBsYXlXb3Jkcy5jaGlsZHJlblt3b3JkUG9zXTtcblxuICAgIGN1clBvcyA9IGFjdGl2ZVdvcmQuY2hpbGRyZW4ubGVuZ3RoO1xuICAgIHdoaWxlIChhY3RpdmVXb3JkLmNoaWxkcmVuW2N1clBvcyAtIDFdLmNsYXNzTmFtZSA9PT0gJycpIGN1clBvcy0tO1xuICAgIGFjdGl2ZVdvcmQuY2xhc3NMaXN0LnJlbW92ZSgnZXJyb3InKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBsb2FkT2xkUmVwbGF5KCk6IG51bWJlciB7XG4gIGxldCBzdGFydGluZ0luZGV4ID0gMDtcbiAgY3VyUG9zID0gMDtcbiAgd29yZFBvcyA9IDA7XG4gIHJlcGxheURhdGEuZm9yRWFjaCgoaXRlbSwgaSkgPT4ge1xuICAgIGlmICh3b3JkUG9zIDwgdGFyZ2V0V29yZFBvcyB8fCAod29yZFBvcyA9PT0gdGFyZ2V0V29yZFBvcyAmJiBjdXJQb3MgPCB0YXJnZXRDdXJQb3MpKSB7XG4gICAgICAvL3F1aWNrbHkgZGlzcGxheSBldmVyeXRoaW5nIHVwIHRvIHRoZSB0YXJnZXRcbiAgICAgIGhhbmRsZURpc3BsYXlMb2dpYyhpdGVtLCB0cnVlKTtcbiAgICAgIHN0YXJ0aW5nSW5kZXggPSBpICsgMTtcbiAgICB9XG4gIH0pO1xuICBjb25zdCB0aW1lID0gTWF0aC5mbG9vcigocmVwbGF5RGF0YVtzdGFydGluZ0luZGV4XT8udGltZSB8fCAwKSAvIDEwMDApO1xuICByZXBsYXlTdG9wd2F0Y2guaW5uZXJUZXh0ID0gdGltZSArICdzJztcbiAgcmV0dXJuIHN0YXJ0aW5nSW5kZXg7XG59XG5cbmZ1bmN0aW9uIHN0YXJ0UmVwbGF5UmVjb3JkaW5nKCk6IHZvaWQge1xuICByZXBsYXlEYXRhID0gW107XG4gIHJlcGxheVN0YXJ0VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICByZXBsYXlSZWNvcmRpbmcgPSB0cnVlO1xuICB0YXJnZXRDdXJQb3MgPSAwO1xuICB0YXJnZXRXb3JkUG9zID0gMDtcbn1cblxuZnVuY3Rpb24gc3RvcFJlcGxheVJlY29yZGluZygpOiB2b2lkIHtcbiAgcmVwbGF5UmVjb3JkaW5nID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGFkZFJlcGxheUV2ZW50KGFjdGlvbjogUmVwbGF5QWN0aW9uLCB2YWx1ZT86IG51bWJlciB8IHN0cmluZyk6IHZvaWQge1xuICBpZiAoIXJlcGxheVJlY29yZGluZykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHRpbWVEZWx0YSA9IHBlcmZvcm1hbmNlLm5vdygpIC0gcmVwbGF5U3RhcnRUaW1lO1xuICByZXBsYXlEYXRhLnB1c2goeyBhY3Rpb246IGFjdGlvbiwgdmFsdWU6IHZhbHVlLCB0aW1lOiB0aW1lRGVsdGEgfSk7XG59XG5cbmZ1bmN0aW9uIHBsYXlSZXBsYXkoKTogdm9pZCB7XG4gIGN1clBvcyA9IDA7XG4gIHdvcmRQb3MgPSAwO1xuXG4gIGlmICh0b2dnbGVCdXR0b24gPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gIHRvZ2dsZUJ1dHRvbi5jbGFzc05hbWUgPSAnUGF1c2UnO1xuICAodG9nZ2xlQnV0dG9uLnBhcmVudE5vZGUgYXMgRWxlbWVudCk/LnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcsICdQYXVzZSByZXBsYXknKTtcbiAgaW5pdGlhbGl6ZVJlcGxheVByb21wdCgpO1xuICBjb25zdCBzdGFydGluZ0luZGV4ID0gbG9hZE9sZFJlcGxheSgpO1xuICBjb25zdCBsYXN0VGltZSA9IHJlcGxheURhdGFbc3RhcnRpbmdJbmRleF0/LnRpbWUgfHwgMDtcbiAgbGV0IHN3VGltZSA9IE1hdGgucm91bmQobGFzdFRpbWUgLyAxMDAwKTsgLy9zdGFydGluZyB0aW1lXG4gIGNvbnN0IHN3RW5kVGltZSA9IE1hdGgucm91bmQoKHJlcGxheURhdGFbcmVwbGF5RGF0YS5sZW5ndGggLSAxXT8udGltZSB8fCAwKSAvIDEwMDApO1xuICB3aGlsZSAoc3dUaW1lIDw9IHN3RW5kVGltZSkge1xuICAgIGNvbnN0IHRpbWUgPSBzd1RpbWU7XG4gICAgc3RvcHdhdGNoTGlzdC5wdXNoKFxuICAgICAgc2V0VGltZW91dChcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHJlcGxheVN0b3B3YXRjaC5pbm5lclRleHQgPSB0aW1lICsgJ3MnO1xuICAgICAgICB9LFxuICAgICAgICB0aW1lICogMTAwMCAtIGxhc3RUaW1lXG4gICAgICApXG4gICAgKTtcbiAgICBzd1RpbWUrKztcbiAgfVxuICByZXBsYXlEYXRhLmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICBpZiAoaSA8IHN0YXJ0aW5nSW5kZXgpIHJldHVybjtcbiAgICB0aW1lb3V0TGlzdC5wdXNoKFxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGhhbmRsZURpc3BsYXlMb2dpYyhpdGVtKTtcbiAgICAgIH0sIGl0ZW0udGltZSAtIGxhc3RUaW1lKVxuICAgICk7XG4gIH0pO1xuICB0aW1lb3V0TGlzdC5wdXNoKFxuICAgIHNldFRpbWVvdXQoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIC8vYWZ0ZXIgdGhlIHJlcGxheSBoYXMgZmluaXNoZWQsIHRoaXMgd2lsbCBydW5cbiAgICAgICAgdGFyZ2V0Q3VyUG9zID0gMDtcbiAgICAgICAgdGFyZ2V0V29yZFBvcyA9IDA7XG4gICAgICAgIHRvZ2dsZUJ1dHRvbi5jbGFzc05hbWUgPSAnUGxheSc7XG4gICAgICAgICh0b2dnbGVCdXR0b24ucGFyZW50Tm9kZSBhcyBFbGVtZW50KS5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwnLCAnU3RhcnQgcmVwbGF5Jyk7XG4gICAgICB9LFxuICAgICAgKHJlcGxheURhdGFbcmVwbGF5RGF0YS5sZW5ndGggLSAxXT8udGltZSB8fCAwKSAtIGxhc3RUaW1lXG4gICAgKVxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRSZXBsYXlFeHBvcnQoKTogc3RyaW5nIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcbiAgICByZXBsYXlEYXRhOiByZXBsYXlEYXRhLFxuICAgIHdvcmRzTGlzdDogd29yZHNMaXN0LFxuICB9KTtcbn1cblxuZnVuY3Rpb24gc2V0UmVwbGF5RGF0YShkYXRhOiBSZXBsYXlbXSkge1xuICByZXBsYXlEYXRhID0gZGF0YTtcbn1cblxuZnVuY3Rpb24gcGxheXBhdXNlUmVwbGF5QnV0dG9uQ2xpY2soKSB7XG4gIGlmICh0b2dnbGVCdXR0b24/LmNsYXNzTmFtZSA9PT0gJ1BsYXknKSB7XG4gICAgcGxheVJlcGxheSgpO1xuICB9IGVsc2UgaWYgKHRvZ2dsZUJ1dHRvbj8uY2xhc3NOYW1lID09PSAnUGF1c2UnKSB7XG4gICAgcGF1c2VSZXBsYXkoKTtcbiAgfVxufVxuXG5leHBvcnQge1xuICBhZGRSZXBsYXlFdmVudCxcbiAgZ2V0UmVwbGF5RXhwb3J0LFxuICBpbml0aWFsaXplUmVwbGF5UHJvbXB0LFxuICBsb2FkT2xkUmVwbGF5LFxuICBwbGF5UmVwbGF5LFxuICBwbGF5cGF1c2VSZXBsYXlCdXR0b25DbGljayxcbiAgcmVwbGF5R2V0V29yZHNMaXN0LFxuICBzZXRSZXBsYXlEYXRhLFxuICBzZXRSZXBsYXlTdG9wd2F0Y2gsXG4gIHNldFRvZ2dsZUJ1dHRvbixcbiAgc3RhcnRSZXBsYXlSZWNvcmRpbmcsXG4gIHN0b3BSZXBsYXlSZWNvcmRpbmcsXG59O1xuIl19
@@ -1,264 +0,0 @@
1
- import * as TestWords from './test-words';
2
- import { roundTo2 } from '../../utils/misc';
3
- class Input {
4
- current;
5
- history;
6
- historyLength;
7
- length;
8
- constructor() {
9
- this.current = '';
10
- this.history = [];
11
- this.historyLength = 0;
12
- this.length = 0;
13
- }
14
- reset() {
15
- this.current = '';
16
- this.history = [];
17
- this.length = 0;
18
- }
19
- resetHistory() {
20
- this.history = [];
21
- this.length = 0;
22
- }
23
- setCurrent(val) {
24
- this.current = val;
25
- this.length = this.current.length;
26
- }
27
- appendCurrent(val) {
28
- this.current += val;
29
- this.length = this.current.length;
30
- }
31
- resetCurrent() {
32
- this.current = '';
33
- }
34
- getCurrent() {
35
- return this.current;
36
- }
37
- pushHistory() {
38
- this.history.push(this.current);
39
- this.historyLength = this.history.length;
40
- this.resetCurrent();
41
- }
42
- popHistory() {
43
- const ret = this.history.pop() ?? '';
44
- this.historyLength = this.history.length;
45
- return ret;
46
- }
47
- getHistory(i) {
48
- if (i === undefined) {
49
- return this.history;
50
- }
51
- else {
52
- return this.history[i];
53
- }
54
- }
55
- getHistoryLast() {
56
- return this.history[this.history.length - 1];
57
- }
58
- }
59
- class Corrected {
60
- current;
61
- history;
62
- constructor() {
63
- this.current = '';
64
- this.history = [];
65
- }
66
- setCurrent(val) {
67
- this.current = val;
68
- }
69
- appendCurrent(val) {
70
- this.current += val;
71
- }
72
- resetCurrent() {
73
- this.current = '';
74
- }
75
- resetHistory() {
76
- this.history = [];
77
- }
78
- reset() {
79
- this.resetCurrent();
80
- this.resetHistory();
81
- }
82
- getHistory(i) {
83
- return this.history[i];
84
- }
85
- popHistory() {
86
- return this.history.pop() ?? '';
87
- }
88
- pushHistory() {
89
- this.history.push(this.current);
90
- this.current = '';
91
- }
92
- }
93
- export const input = new Input();
94
- export const corrected = new Corrected();
95
- export let keypressPerSecond = [];
96
- export let currentKeypress = {
97
- count: 0,
98
- errors: 0,
99
- words: [],
100
- afk: true,
101
- };
102
- export let lastKeypress;
103
- export let currentBurstStart = 0;
104
- export let missedWords = {};
105
- export let accuracy = {
106
- correct: 0,
107
- incorrect: 0,
108
- };
109
- export let keypressTimings = {
110
- spacing: {
111
- current: -1,
112
- array: [],
113
- },
114
- duration: {
115
- current: -1,
116
- array: [],
117
- },
118
- };
119
- export let wpmHistory = [];
120
- export let rawHistory = [];
121
- export let burstHistory = [];
122
- export let bailout = false;
123
- export function setBailout(tf) {
124
- bailout = tf;
125
- }
126
- export let spacingDebug = false;
127
- export function enableSpacingDebug() {
128
- spacingDebug = true;
129
- console.clear();
130
- }
131
- export function updateLastKeypress() {
132
- lastKeypress = performance.now();
133
- }
134
- export function incrementKeypressCount() {
135
- currentKeypress.count++;
136
- }
137
- export function setKeypressNotAfk() {
138
- currentKeypress.afk = false;
139
- }
140
- export function incrementKeypressErrors() {
141
- currentKeypress.errors++;
142
- }
143
- export function pushKeypressWord(wordIndex) {
144
- currentKeypress.words.push(wordIndex);
145
- }
146
- export function setBurstStart(time) {
147
- currentBurstStart = time;
148
- }
149
- export function pushKeypressesToHistory() {
150
- keypressPerSecond.push(currentKeypress);
151
- currentKeypress = {
152
- count: 0,
153
- errors: 0,
154
- words: [],
155
- afk: true,
156
- };
157
- }
158
- export function incrementAccuracy(correctincorrect) {
159
- if (correctincorrect) {
160
- accuracy.correct++;
161
- }
162
- else {
163
- accuracy.incorrect++;
164
- }
165
- }
166
- export function setKeypressTimingsTooLong() {
167
- keypressTimings.spacing.array = 'toolong';
168
- keypressTimings.duration.array = 'toolong';
169
- }
170
- export function pushKeypressDuration(val) {
171
- keypressTimings.duration.array.push(roundTo2(val));
172
- }
173
- export function setKeypressDuration(val) {
174
- keypressTimings.duration.current = roundTo2(val);
175
- }
176
- function pushKeypressSpacing(val) {
177
- keypressTimings.spacing.array.push(roundTo2(val));
178
- }
179
- function setKeypressSpacing(val) {
180
- keypressTimings.spacing.current = roundTo2(val);
181
- }
182
- export function recordKeypressSpacing() {
183
- const now = performance.now();
184
- const diff = Math.abs(keypressTimings.spacing.current - now);
185
- if (keypressTimings.spacing.current !== -1) {
186
- pushKeypressSpacing(diff);
187
- if (spacingDebug) {
188
- console.log('spacing debug', 'push', diff, 'length', keypressTimings.spacing.array.length);
189
- }
190
- }
191
- setKeypressSpacing(now);
192
- if (spacingDebug) {
193
- console.log('spacing debug', 'set', now, 'length', keypressTimings.spacing.array.length);
194
- }
195
- if (spacingDebug) {
196
- console.log('spacing debug', 'recorded', 'length', keypressTimings.spacing.array.length);
197
- }
198
- }
199
- export function resetKeypressTimings() {
200
- keypressTimings = {
201
- spacing: {
202
- current: performance.now(),
203
- array: [],
204
- },
205
- duration: {
206
- current: performance.now(),
207
- array: [],
208
- },
209
- };
210
- if (spacingDebug)
211
- console.clear();
212
- }
213
- export function pushMissedWord(word) {
214
- if (!Object.keys(missedWords).includes(word)) {
215
- missedWords[word] = 1;
216
- }
217
- else {
218
- missedWords[word]++;
219
- }
220
- }
221
- export function pushToWpmHistory(wpm) {
222
- wpmHistory.push(wpm);
223
- }
224
- export function pushToRawHistory(raw) {
225
- rawHistory.push(raw);
226
- }
227
- export function pushBurstToHistory(speed) {
228
- if (burstHistory[TestWords.words.currentIndex] === undefined) {
229
- burstHistory.push(speed);
230
- }
231
- else {
232
- //repeated word - override
233
- burstHistory[TestWords.words.currentIndex] = speed;
234
- }
235
- }
236
- export function restart() {
237
- wpmHistory = [];
238
- rawHistory = [];
239
- burstHistory = [];
240
- keypressPerSecond = [];
241
- currentKeypress = {
242
- count: 0,
243
- errors: 0,
244
- words: [],
245
- afk: true,
246
- };
247
- currentBurstStart = 0;
248
- missedWords = {};
249
- accuracy = {
250
- correct: 0,
251
- incorrect: 0,
252
- };
253
- keypressTimings = {
254
- spacing: {
255
- current: -1,
256
- array: [],
257
- },
258
- duration: {
259
- current: -1,
260
- array: [],
261
- },
262
- };
263
- }
264
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1pbnB1dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3Rnby10eXBpbmctdGVzdC9zcmMvbGliL2hlbHBlcnMvdGVzdC90ZXN0LWlucHV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxTQUFTLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQW9CNUMsTUFBTSxLQUFLO0lBQ1QsT0FBTyxDQUFTO0lBQ2hCLE9BQU8sQ0FBVztJQUNsQixhQUFhLENBQVM7SUFDdEIsTUFBTSxDQUFTO0lBQ2Y7UUFDRSxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQztRQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNsQixDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2xCLENBQUM7SUFFRCxZQUFZO1FBQ1YsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDbEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDbEIsQ0FBQztJQUVELFVBQVUsQ0FBQyxHQUFXO1FBQ3BCLElBQUksQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDO1FBQ25CLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDcEMsQ0FBQztJQUVELGFBQWEsQ0FBQyxHQUFXO1FBQ3ZCLElBQUksQ0FBQyxPQUFPLElBQUksR0FBRyxDQUFDO1FBQ3BCLElBQUksQ0FB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MEJBQTBCO1FBQzFCLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLEtBQUssQ0FBQztJQUNyRCxDQUFDO0FBQ0gsQ0FBQztBQUVELE1BQU0sVUFBVSxPQUFPO0lBQ3JCLFVBQVUsR0FBRyxFQUFFLENBQUM7SUFDaEIsVUFBVSxHQUFHLEVBQUUsQ0FBQztJQUNoQixZQUFZLEdBQUcsRUFBRSxDQUFDO0lBQ2xCLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztJQUN2QixlQUFlLEdBQUc7UUFDaEIsS0FBSyxFQUFFLENBQUM7UUFDUixNQUFNLEVBQUUsQ0FBQztRQUNULEtBQUssRUFBRSxFQUFFO1FBQ1QsR0FBRyxFQUFFLElBQUk7S0FDVixDQUFDO0lBQ0YsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLFdBQVcsR0FBRyxFQUFFLENBQUM7SUFDakIsUUFBUSxHQUFHO1FBQ1QsT0FBTyxFQUFFLENBQUM7UUFDVixTQUFTLEVBQUUsQ0FBQztLQUNiLENBQUM7SUFDRixlQUFlLEdBQUc7UUFDaEIsT0FBTyxFQUFFO1lBQ1AsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNYLEtBQUssRUFBRSxFQUFFO1NBQ1Y7UUFDRCxRQUFRLEVBQUU7WUFDUixPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQ1gsS0FBSyxFQUFFLEVBQUU7U0FDVjtLQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgVGVzdFdvcmRzIGZyb20gJy4vdGVzdC13b3Jkcyc7XG5pbXBvcnQgeyByb3VuZFRvMiB9IGZyb20gJy4uLy4uL3V0aWxzL21pc2MnO1xuXG5pbnRlcmZhY2UgS2V5cHJlc3Mge1xuICBjb3VudDogbnVtYmVyO1xuICBlcnJvcnM6IG51bWJlcjtcbiAgd29yZHM6IG51bWJlcltdO1xuICBhZms6IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBLZXlwcmVzc1RpbWluZ3Mge1xuICBzcGFjaW5nOiB7XG4gICAgY3VycmVudDogbnVtYmVyO1xuICAgIGFycmF5OiBudW1iZXJbXSB8ICd0b29sb25nJztcbiAgfTtcbiAgZHVyYXRpb246IHtcbiAgICBjdXJyZW50OiBudW1iZXI7XG4gICAgYXJyYXk6IG51bWJlcltdIHwgJ3Rvb2xvbmcnO1xuICB9O1xufVxuXG5jbGFzcyBJbnB1dCB7XG4gIGN1cnJlbnQ6IHN0cmluZztcbiAgaGlzdG9yeTogc3RyaW5nW107XG4gIGhpc3RvcnlMZW5ndGg6IG51bWJlcjtcbiAgbGVuZ3RoOiBudW1iZXI7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuY3VycmVudCA9ICcnO1xuICAgIHRoaXMuaGlzdG9yeSA9IFtdO1xuICAgIHRoaXMuaGlzdG9yeUxlbmd0aCA9IDA7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5jdXJyZW50ID0gJyc7XG4gICAgdGhpcy5oaXN0b3J5ID0gW107XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgcmVzZXRIaXN0b3J5KCk6IHZvaWQge1xuICAgIHRoaXMuaGlzdG9yeSA9IFtdO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgfVxuXG4gIHNldEN1cnJlbnQodmFsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmN1cnJlbnQgPSB2YWw7XG4gICAgdGhpcy5sZW5ndGggPSB0aGlzLmN1cnJlbnQubGVuZ3RoO1xuICB9XG5cbiAgYXBwZW5kQ3VycmVudCh2YWw6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudCArPSB2YWw7XG4gICAgdGhpcy5sZW5ndGggPSB0aGlzLmN1cnJlbnQubGVuZ3RoO1xuICB9XG5cbiAgcmVzZXRDdXJyZW50KCk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudCA9ICcnO1xuICB9XG5cbiAgZ2V0Q3VycmVudCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnQ7XG4gIH1cblxuICBwdXNoSGlzdG9yeSgpOiB2b2lkIHtcbiAgICB0aGlzLmhpc3RvcnkucHVzaCh0aGlzLmN1cnJlbnQpO1xuICAgIHRoaXMuaGlzdG9yeUxlbmd0aCA9IHRoaXMuaGlzdG9yeS5sZW5ndGg7XG4gICAgdGhpcy5yZXNldEN1cnJlbnQoKTtcbiAgfVxuXG4gIHBvcEhpc3RvcnkoKTogc3RyaW5nIHtcbiAgICBjb25zdCByZXQgPSB0aGlzLmhpc3RvcnkucG9wKCkgPz8gJyc7XG4gICAgdGhpcy5oaXN0b3J5TGVuZ3RoID0gdGhpcy5oaXN0b3J5Lmxlbmd0aDtcbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgZ2V0SGlzdG9yeShpPzogbnVtYmVyKTogc3RyaW5nIHwgc3RyaW5nW10ge1xuICAgIGlmIChpID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLmhpc3Rvcnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmhpc3RvcnlbaV07XG4gICAgfVxuICB9XG5cbiAgZ2V0SGlzdG9yeUxhc3QoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5oaXN0b3J5W3RoaXMuaGlzdG9yeS5sZW5ndGggLSAxXTtcbiAgfVxufVxuXG5jbGFzcyBDb3JyZWN0ZWQge1xuICBjdXJyZW50OiBzdHJpbmc7XG4gIGhpc3Rvcnk6IHN0cmluZ1tdO1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmN1cnJlbnQgPSAnJztcbiAgICB0aGlzLmhpc3RvcnkgPSBbXTtcbiAgfVxuICBzZXRDdXJyZW50KHZhbDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jdXJyZW50ID0gdmFsO1xuICB9XG5cbiAgYXBwZW5kQ3VycmVudCh2YWw6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudCArPSB2YWw7XG4gIH1cblxuICByZXNldEN1cnJlbnQoKTogdm9pZCB7XG4gICAgdGhpcy5jdXJyZW50ID0gJyc7XG4gIH1cblxuICByZXNldEhpc3RvcnkoKTogdm9pZCB7XG4gICAgdGhpcy5oaXN0b3J5ID0gW107XG4gIH1cblxuICByZXNldCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlc2V0Q3VycmVudCgpO1xuICAgIHRoaXMucmVzZXRIaXN0b3J5KCk7XG4gIH1cblxuICBnZXRIaXN0b3J5KGk6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuaGlzdG9yeVtpXTtcbiAgfVxuXG4gIHBvcEhpc3RvcnkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5oaXN0b3J5LnBvcCgpID8/ICcnO1xuICB9XG5cbiAgcHVzaEhpc3RvcnkoKTogdm9pZCB7XG4gICAgdGhpcy5oaXN0b3J5LnB1c2godGhpcy5jdXJyZW50KTtcbiAgICB0aGlzLmN1cnJlbnQgPSAnJztcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgaW5wdXQgPSBuZXcgSW5wdXQoKTtcbmV4cG9ydCBjb25zdCBjb3JyZWN0ZWQgPSBuZXcgQ29ycmVjdGVkKCk7XG5cbmV4cG9ydCBsZXQga2V5cHJlc3NQZXJTZWNvbmQ6IEtleXByZXNzW10gPSBbXTtcbmV4cG9ydCBsZXQgY3VycmVudEtleXByZXNzOiBLZXlwcmVzcyA9IHtcbiAgY291bnQ6IDAsXG4gIGVycm9yczogMCxcbiAgd29yZHM6IFtdLFxuICBhZms6IHRydWUsXG59O1xuZXhwb3J0IGxldCBsYXN0S2V5cHJlc3M6IG51bWJlcjtcbmV4cG9ydCBsZXQgY3VycmVudEJ1cnN0U3RhcnQgPSAwO1xuZXhwb3J0IGxldCBtaXNzZWRXb3Jkczoge1xuICBbd29yZDogc3RyaW5nXTogbnVtYmVyO1xufSA9IHt9O1xuZXhwb3J0IGxldCBhY2N1cmFjeSA9IHtcbiAgY29ycmVjdDogMCxcbiAgaW5jb3JyZWN0OiAwLFxufTtcbmV4cG9ydCBsZXQga2V5cHJlc3NUaW1pbmdzOiBLZXlwcmVzc1RpbWluZ3MgPSB7XG4gIHNwYWNpbmc6IHtcbiAgICBjdXJyZW50OiAtMSxcbiAgICBhcnJheTogW10sXG4gIH0sXG4gIGR1cmF0aW9uOiB7XG4gICAgY3VycmVudDogLTEsXG4gICAgYXJyYXk6IFtdLFxuICB9LFxufTtcbmV4cG9ydCBsZXQgd3BtSGlzdG9yeTogbnVtYmVyW10gPSBbXTtcbmV4cG9ydCBsZXQgcmF3SGlzdG9yeTogbnVtYmVyW10gPSBbXTtcbmV4cG9ydCBsZXQgYnVyc3RIaXN0b3J5OiBudW1iZXJbXSA9IFtdO1xuZXhwb3J0IGxldCBiYWlsb3V0ID0gZmFsc2U7XG5leHBvcnQgZnVuY3Rpb24gc2V0QmFpbG91dCh0ZjogYm9vbGVhbik6IHZvaWQge1xuICBiYWlsb3V0ID0gdGY7XG59XG5cbmV4cG9ydCBsZXQgc3BhY2luZ0RlYnVnID0gZmFsc2U7XG5leHBvcnQgZnVuY3Rpb24gZW5hYmxlU3BhY2luZ0RlYnVnKCk6IHZvaWQge1xuICBzcGFjaW5nRGVidWcgPSB0cnVlO1xuICBjb25zb2xlLmNsZWFyKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVMYXN0S2V5cHJlc3MoKTogdm9pZCB7XG4gIGxhc3RLZXlwcmVzcyA9IHBlcmZvcm1hbmNlLm5vdygpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5jcmVtZW50S2V5cHJlc3NDb3VudCgpOiB2b2lkIHtcbiAgY3VycmVudEtleXByZXNzLmNvdW50Kys7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRLZXlwcmVzc05vdEFmaygpOiB2b2lkIHtcbiAgY3VycmVudEtleXByZXNzLmFmayA9IGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5jcmVtZW50S2V5cHJlc3NFcnJvcnMoKTogdm9pZCB7XG4gIGN1cnJlbnRLZXlwcmVzcy5lcnJvcnMrKztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHB1c2hLZXlwcmVzc1dvcmQod29yZEluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgY3VycmVudEtleXByZXNzLndvcmRzLnB1c2god29yZEluZGV4KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEJ1cnN0U3RhcnQodGltZTogbnVtYmVyKTogdm9pZCB7XG4gIGN1cnJlbnRCdXJzdFN0YXJ0ID0gdGltZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHB1c2hLZXlwcmVzc2VzVG9IaXN0b3J5KCk6IHZvaWQge1xuICBrZXlwcmVzc1BlclNlY29uZC5wdXNoKGN1cnJlbnRLZXlwcmVzcyk7XG4gIGN1cnJlbnRLZXlwcmVzcyA9IHtcbiAgICBjb3VudDogMCxcbiAgICBlcnJvcnM6IDAsXG4gICAgd29yZHM6IFtdLFxuICAgIGFmazogdHJ1ZSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluY3JlbWVudEFjY3VyYWN5KGNvcnJlY3RpbmNvcnJlY3Q6IGJvb2xlYW4pOiB2b2lkIHtcbiAgaWYgKGNvcnJlY3RpbmNvcnJlY3QpIHtcbiAgICBhY2N1cmFjeS5jb3JyZWN0Kys7XG4gIH0gZWxzZSB7XG4gICAgYWNjdXJhY3kuaW5jb3JyZWN0Kys7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEtleXByZXNzVGltaW5nc1Rvb0xvbmcoKTogdm9pZCB7XG4gIGtleXByZXNzVGltaW5ncy5zcGFjaW5nLmFycmF5ID0gJ3Rvb2xvbmcnO1xuICBrZXlwcmVzc1RpbWluZ3MuZHVyYXRpb24uYXJyYXkgPSAndG9vbG9uZyc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwdXNoS2V5cHJlc3NEdXJhdGlvbih2YWw6IG51bWJlcik6IHZvaWQge1xuICAoa2V5cHJlc3NUaW1pbmdzLmR1cmF0aW9uLmFycmF5IGFzIG51bWJlcltdKS5wdXNoKHJvdW5kVG8yKHZhbCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0S2V5cHJlc3NEdXJhdGlvbih2YWw6IG51bWJlcik6IHZvaWQge1xuICBrZXlwcmVzc1RpbWluZ3MuZHVyYXRpb24uY3VycmVudCA9IHJvdW5kVG8yKHZhbCk7XG59XG5cbmZ1bmN0aW9uIHB1c2hLZXlwcmVzc1NwYWNpbmcodmFsOiBudW1iZXIpOiB2b2lkIHtcbiAgKGtleXByZXNzVGltaW5ncy5zcGFjaW5nLmFycmF5IGFzIG51bWJlcltdKS5wdXNoKHJvdW5kVG8yKHZhbCkpO1xufVxuXG5mdW5jdGlvbiBzZXRLZXlwcmVzc1NwYWNpbmcodmFsOiBudW1iZXIpOiB2b2lkIHtcbiAga2V5cHJlc3NUaW1pbmdzLnNwYWNpbmcuY3VycmVudCA9IHJvdW5kVG8yKHZhbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRLZXlwcmVzc1NwYWNpbmcoKTogdm9pZCB7XG4gIGNvbnN0IG5vdyA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICBjb25zdCBkaWZmID0gTWF0aC5hYnMoa2V5cHJlc3NUaW1pbmdzLnNwYWNpbmcuY3VycmVudCAtIG5vdyk7XG4gIGlmIChrZXlwcmVzc1RpbWluZ3Muc3BhY2luZy5jdXJyZW50ICE9PSAtMSkge1xuICAgIHB1c2hLZXlwcmVzc1NwYWNpbmcoZGlmZik7XG4gICAgaWYgKHNwYWNpbmdEZWJ1Zykge1xuICAgICAgY29uc29sZS5sb2coJ3NwYWNpbmcgZGVidWcnLCAncHVzaCcsIGRpZmYsICdsZW5ndGgnLCBrZXlwcmVzc1RpbWluZ3Muc3BhY2luZy5hcnJheS5sZW5ndGgpO1xuICAgIH1cbiAgfVxuICBzZXRLZXlwcmVzc1NwYWNpbmcobm93KTtcbiAgaWYgKHNwYWNpbmdEZWJ1Zykge1xuICAgIGNvbnNvbGUubG9nKCdzcGFjaW5nIGRlYnVnJywgJ3NldCcsIG5vdywgJ2xlbmd0aCcsIGtleXByZXNzVGltaW5ncy5zcGFjaW5nLmFycmF5Lmxlbmd0aCk7XG4gIH1cbiAgaWYgKHNwYWNpbmdEZWJ1Zykge1xuICAgIGNvbnNvbGUubG9nKCdzcGFjaW5nIGRlYnVnJywgJ3JlY29yZGVkJywgJ2xlbmd0aCcsIGtleXByZXNzVGltaW5ncy5zcGFjaW5nLmFycmF5Lmxlbmd0aCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc2V0S2V5cHJlc3NUaW1pbmdzKCk6IHZvaWQge1xuICBrZXlwcmVzc1RpbWluZ3MgPSB7XG4gICAgc3BhY2luZzoge1xuICAgICAgY3VycmVudDogcGVyZm9ybWFuY2Uubm93KCksXG4gICAgICBhcnJheTogW10sXG4gICAgfSxcbiAgICBkdXJhdGlvbjoge1xuICAgICAgY3VycmVudDogcGVyZm9ybWFuY2Uubm93KCksXG4gICAgICBhcnJheTogW10sXG4gICAgfSxcbiAgfTtcbiAgaWYgKHNwYWNpbmdEZWJ1ZykgY29uc29sZS5jbGVhcigpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaE1pc3NlZFdvcmQod29yZDogc3RyaW5nKTogdm9pZCB7XG4gIGlmICghT2JqZWN0LmtleXMobWlzc2VkV29yZHMpLmluY2x1ZGVzKHdvcmQpKSB7XG4gICAgbWlzc2VkV29yZHNbd29yZF0gPSAxO1xuICB9IGVsc2Uge1xuICAgIG1pc3NlZFdvcmRzW3dvcmRdKys7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHB1c2hUb1dwbUhpc3Rvcnkod3BtOiBudW1iZXIpOiB2b2lkIHtcbiAgd3BtSGlzdG9yeS5wdXNoKHdwbSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwdXNoVG9SYXdIaXN0b3J5KHJhdzogbnVtYmVyKTogdm9pZCB7XG4gIHJhd0hpc3RvcnkucHVzaChyYXcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaEJ1cnN0VG9IaXN0b3J5KHNwZWVkOiBudW1iZXIpOiB2b2lkIHtcbiAgaWYgKGJ1cnN0SGlzdG9yeVtUZXN0V29yZHMud29yZHMuY3VycmVudEluZGV4XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYnVyc3RIaXN0b3J5LnB1c2goc3BlZWQpO1xuICB9IGVsc2Uge1xuICAgIC8vcmVwZWF0ZWQgd29yZCAtIG92ZXJyaWRlXG4gICAgYnVyc3RIaXN0b3J5W1Rlc3RXb3Jkcy53b3Jkcy5jdXJyZW50SW5kZXhdID0gc3BlZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc3RhcnQoKTogdm9pZCB7XG4gIHdwbUhpc3RvcnkgPSBbXTtcbiAgcmF3SGlzdG9yeSA9IFtdO1xuICBidXJzdEhpc3RvcnkgPSBbXTtcbiAga2V5cHJlc3NQZXJTZWNvbmQgPSBbXTtcbiAgY3VycmVudEtleXByZXNzID0ge1xuICAgIGNvdW50OiAwLFxuICAgIGVycm9yczogMCxcbiAgICB3b3JkczogW10sXG4gICAgYWZrOiB0cnVlLFxuICB9O1xuICBjdXJyZW50QnVyc3RTdGFydCA9IDA7XG4gIG1pc3NlZFdvcmRzID0ge307XG4gIGFjY3VyYWN5ID0ge1xuICAgIGNvcnJlY3Q6IDAsXG4gICAgaW5jb3JyZWN0OiAwLFxuICB9O1xuICBrZXlwcmVzc1RpbWluZ3MgPSB7XG4gICAgc3BhY2luZzoge1xuICAgICAgY3VycmVudDogLTEsXG4gICAgICBhcnJheTogW10sXG4gICAgfSxcbiAgICBkdXJhdGlvbjoge1xuICAgICAgY3VycmVudDogLTEsXG4gICAgICBhcnJheTogW10sXG4gICAgfSxcbiAgfTtcbn1cbiJdfQ==