@testgorilla/tgo-typing-test 1.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.
- package/fesm2022/testgorilla-tgo-typing-test.mjs +795 -811
- package/fesm2022/testgorilla-tgo-typing-test.mjs.map +1 -1
- package/lib/helpers/config.d.ts +4 -4
- package/lib/utils/misc.d.ts +0 -1
- package/package.json +6 -8
- package/esm2022/index.mjs +0 -3
- package/esm2022/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.mjs +0 -45
- package/esm2022/lib/components/tgo-typing-test/tgo-typing-test.component.mjs +0 -299
- package/esm2022/lib/helpers/config.mjs +0 -24
- package/esm2022/lib/helpers/constants/default-config.mjs +0 -103
- package/esm2022/lib/helpers/controllers/input-controller.mjs +0 -586
- package/esm2022/lib/helpers/controllers/quotes-controller.mjs +0 -118
- package/esm2022/lib/helpers/observables/config-event.mjs +0 -16
- package/esm2022/lib/helpers/observables/timer-event.mjs +0 -16
- package/esm2022/lib/helpers/states/active-page.mjs +0 -8
- package/esm2022/lib/helpers/states/composition.mjs +0 -20
- package/esm2022/lib/helpers/states/page-transition.mjs +0 -8
- package/esm2022/lib/helpers/states/slow-timer.mjs +0 -15
- package/esm2022/lib/helpers/states/test-active.mjs +0 -8
- package/esm2022/lib/helpers/states/time.mjs +0 -11
- package/esm2022/lib/helpers/test/caps-warning.mjs +0 -50
- package/esm2022/lib/helpers/test/caret.mjs +0 -80
- package/esm2022/lib/helpers/test/custom-text.mjs +0 -59
- package/esm2022/lib/helpers/test/english-punctuation.mjs +0 -29
- package/esm2022/lib/helpers/test/focus.mjs +0 -35
- package/esm2022/lib/helpers/test/manual-restart-tracker.mjs +0 -11
- package/esm2022/lib/helpers/test/out-of-focus.mjs +0 -14
- package/esm2022/lib/helpers/test/replay.mjs +0 -217
- package/esm2022/lib/helpers/test/test-input.mjs +0 -264
- package/esm2022/lib/helpers/test/test-logic.mjs +0 -927
- package/esm2022/lib/helpers/test/test-state.mjs +0 -13
- package/esm2022/lib/helpers/test/test-stats.mjs +0 -342
- package/esm2022/lib/helpers/test/test-timer.mjs +0 -207
- package/esm2022/lib/helpers/test/test-ui.mjs +0 -341
- package/esm2022/lib/helpers/test/test-words.mjs +0 -69
- package/esm2022/lib/helpers/test/timer-progress.mjs +0 -15
- package/esm2022/lib/helpers/test/weak-spot.mjs +0 -65
- package/esm2022/lib/helpers/test/wordset.mjs +0 -100
- package/esm2022/lib/utils/misc.mjs +0 -673
- package/esm2022/testgorilla-tgo-typing-test.mjs +0 -5
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export let isRepeated = false;
|
|
2
|
-
export let isPaceRepeat = false;
|
|
3
|
-
export let activeChallenge = null;
|
|
4
|
-
export function setRepeated(tf) {
|
|
5
|
-
isRepeated = tf;
|
|
6
|
-
}
|
|
7
|
-
export function setPaceRepeat(tf) {
|
|
8
|
-
isPaceRepeat = tf;
|
|
9
|
-
}
|
|
10
|
-
export function setActiveChallenge(val) {
|
|
11
|
-
activeChallenge = val;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1zdGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3Rnby10eXBpbmctdGVzdC9zcmMvbGliL2hlbHBlcnMvdGVzdC90ZXN0LXN0YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE1BQU0sQ0FBQyxJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUM7QUFDOUIsTUFBTSxDQUFDLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztBQUNoQyxNQUFNLENBQUMsSUFBSSxlQUFlLEdBQWlDLElBQUksQ0FBQztBQUVoRSxNQUFNLFVBQVUsV0FBVyxDQUFDLEVBQVc7SUFDckMsVUFBVSxHQUFHLEVBQUUsQ0FBQztBQUNsQixDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxFQUFXO0lBQ3ZDLFlBQVksR0FBRyxFQUFFLENBQUM7QUFDcEIsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxHQUFpQztJQUNsRSxlQUFlLEdBQUcsR0FBRyxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNb25rZXlUeXBlcyB9IGZyb20gJy4uLy4uL3R5cGVzL3R5cGVzJztcblxuZXhwb3J0IGxldCBpc1JlcGVhdGVkID0gZmFsc2U7XG5leHBvcnQgbGV0IGlzUGFjZVJlcGVhdCA9IGZhbHNlO1xuZXhwb3J0IGxldCBhY3RpdmVDaGFsbGVuZ2U6IG51bGwgfCBNb25rZXlUeXBlcy5DaGFsbGVuZ2UgPSBudWxsO1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0UmVwZWF0ZWQodGY6IGJvb2xlYW4pOiB2b2lkIHtcbiAgaXNSZXBlYXRlZCA9IHRmO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0UGFjZVJlcGVhdCh0ZjogYm9vbGVhbik6IHZvaWQge1xuICBpc1BhY2VSZXBlYXQgPSB0Zjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldEFjdGl2ZUNoYWxsZW5nZSh2YWw6IG51bGwgfCBNb25rZXlUeXBlcy5DaGFsbGVuZ2UpOiB2b2lkIHtcbiAgYWN0aXZlQ2hhbGxlbmdlID0gdmFsO1xufVxuIl19
|
|
@@ -1,342 +0,0 @@
|
|
|
1
|
-
import Config from '../../helpers/config';
|
|
2
|
-
import * as Misc from '../../utils/misc';
|
|
3
|
-
import * as TestInput from './test-input';
|
|
4
|
-
import * as TestWords from './test-words';
|
|
5
|
-
export let invalid = false;
|
|
6
|
-
export let start, end;
|
|
7
|
-
export let start2, end2;
|
|
8
|
-
export let lastSecondNotRound = false;
|
|
9
|
-
export let lastTestWpm = 0;
|
|
10
|
-
export function setLastTestWpm(wpm) {
|
|
11
|
-
lastTestWpm = wpm;
|
|
12
|
-
}
|
|
13
|
-
export let lastResult;
|
|
14
|
-
export function setLastResult(result) {
|
|
15
|
-
lastResult = result;
|
|
16
|
-
}
|
|
17
|
-
let wpmCalcDebug = false;
|
|
18
|
-
export function wpmCalculationDebug() {
|
|
19
|
-
console.log('wpm calculation debug enabled');
|
|
20
|
-
wpmCalcDebug = true;
|
|
21
|
-
}
|
|
22
|
-
export function getStats() {
|
|
23
|
-
const ret = {
|
|
24
|
-
lastResult,
|
|
25
|
-
start,
|
|
26
|
-
end,
|
|
27
|
-
wpmHistory: TestInput.wpmHistory,
|
|
28
|
-
rawHistory: TestInput.wpmHistory,
|
|
29
|
-
burstHistory: TestInput.burstHistory,
|
|
30
|
-
keypressPerSecond: TestInput.keypressPerSecond,
|
|
31
|
-
currentKeypress: TestInput.currentKeypress,
|
|
32
|
-
lastKeypress: TestInput.lastKeypress,
|
|
33
|
-
currentBurstStart: TestInput.currentBurstStart,
|
|
34
|
-
lastSecondNotRound,
|
|
35
|
-
missedWords: TestInput.missedWords,
|
|
36
|
-
accuracy: TestInput.accuracy,
|
|
37
|
-
keypressTimings: TestInput.keypressTimings,
|
|
38
|
-
};
|
|
39
|
-
try {
|
|
40
|
-
ret.keySpacingStats = {
|
|
41
|
-
average: TestInput.keypressTimings.spacing.array.reduce((previous, current) => (current += previous)) / TestInput.keypressTimings.spacing.array.length,
|
|
42
|
-
sd: Misc.stdDev(TestInput.keypressTimings.spacing.array),
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
catch (e) {
|
|
46
|
-
//
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
ret.keyDurationStats = {
|
|
50
|
-
average: TestInput.keypressTimings.duration.array.reduce((previous, current) => (current += previous)) / TestInput.keypressTimings.duration.array.length,
|
|
51
|
-
sd: Misc.stdDev(TestInput.keypressTimings.duration.array),
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
//
|
|
56
|
-
}
|
|
57
|
-
return ret;
|
|
58
|
-
}
|
|
59
|
-
export function restart() {
|
|
60
|
-
start = 0;
|
|
61
|
-
end = 0;
|
|
62
|
-
invalid = false;
|
|
63
|
-
lastSecondNotRound = false;
|
|
64
|
-
}
|
|
65
|
-
export let restartCount = 0;
|
|
66
|
-
export let incompleteSeconds = 0;
|
|
67
|
-
export function incrementRestartCount() {
|
|
68
|
-
restartCount++;
|
|
69
|
-
}
|
|
70
|
-
export function incrementIncompleteSeconds(val) {
|
|
71
|
-
incompleteSeconds += val;
|
|
72
|
-
}
|
|
73
|
-
export function resetIncomplete() {
|
|
74
|
-
restartCount = 0;
|
|
75
|
-
incompleteSeconds = 0;
|
|
76
|
-
}
|
|
77
|
-
export function setInvalid() {
|
|
78
|
-
invalid = true;
|
|
79
|
-
}
|
|
80
|
-
export function calculateTestSeconds(now) {
|
|
81
|
-
if (now === undefined) {
|
|
82
|
-
const endAfkSeconds = (end - TestInput.lastKeypress) / 1000;
|
|
83
|
-
if ((Config.mode == 'zen' || TestInput.bailout) && endAfkSeconds < 7) {
|
|
84
|
-
return (TestInput.lastKeypress - start) / 1000;
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
return (end - start) / 1000;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
return (now - start) / 1000;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
export function calculateWpmAndRaw() {
|
|
95
|
-
let chars = 0;
|
|
96
|
-
let correctWordChars = 0;
|
|
97
|
-
let spaces = 0;
|
|
98
|
-
//check input history
|
|
99
|
-
for (let i = 0; i < TestInput.input.history.length; i++) {
|
|
100
|
-
const word = Config.mode == 'zen' ? TestInput.input.getHistory(i) : TestWords.words.get(i);
|
|
101
|
-
if (TestInput.input.getHistory(i) == word) {
|
|
102
|
-
//the word is correct
|
|
103
|
-
//+1 for space
|
|
104
|
-
correctWordChars += word.length;
|
|
105
|
-
if (i < TestInput.input.history.length - 1 &&
|
|
106
|
-
Misc.getLastChar(TestInput.input.getHistory(i)) !== '\n') {
|
|
107
|
-
spaces++;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
chars += TestInput.input.getHistory(i).length;
|
|
111
|
-
}
|
|
112
|
-
if (TestInput.input.current !== '') {
|
|
113
|
-
const word = Config.mode == 'zen' ? TestInput.input.current : TestWords.words.getCurrent();
|
|
114
|
-
//check whats currently typed
|
|
115
|
-
const toAdd = {
|
|
116
|
-
correct: 0,
|
|
117
|
-
incorrect: 0,
|
|
118
|
-
missed: 0,
|
|
119
|
-
};
|
|
120
|
-
for (let c = 0; c < word.length; c++) {
|
|
121
|
-
if (c < TestInput.input.current.length) {
|
|
122
|
-
//on char that still has a word list pair
|
|
123
|
-
if (TestInput.input.current[c] == word[c]) {
|
|
124
|
-
toAdd.correct++;
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
toAdd.incorrect++;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
//on char that is extra
|
|
132
|
-
toAdd.missed++;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
chars += toAdd.correct;
|
|
136
|
-
chars += toAdd.incorrect;
|
|
137
|
-
chars += toAdd.missed;
|
|
138
|
-
if (toAdd.incorrect == 0) {
|
|
139
|
-
//word is correct so far, add chars
|
|
140
|
-
correctWordChars += toAdd.correct;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
if (Config.funbox === 'nospace' || Config.funbox === 'arrows') {
|
|
144
|
-
spaces = 0;
|
|
145
|
-
}
|
|
146
|
-
chars += TestInput.input.current.length;
|
|
147
|
-
const testSeconds = calculateTestSeconds(performance.now());
|
|
148
|
-
const wpm = Math.round(((correctWordChars + spaces) * (60 / testSeconds)) / 5);
|
|
149
|
-
const raw = Math.round(((chars + spaces) * (60 / testSeconds)) / 5);
|
|
150
|
-
return {
|
|
151
|
-
wpm: wpm,
|
|
152
|
-
raw: raw,
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
export function setEnd(e) {
|
|
156
|
-
end = e;
|
|
157
|
-
end2 = Date.now();
|
|
158
|
-
}
|
|
159
|
-
export function setStart(s) {
|
|
160
|
-
start = s;
|
|
161
|
-
start2 = Date.now();
|
|
162
|
-
}
|
|
163
|
-
export function calculateAfkSeconds(testSeconds) {
|
|
164
|
-
let extraAfk = 0;
|
|
165
|
-
if (testSeconds !== undefined) {
|
|
166
|
-
if (Config.mode === 'time') {
|
|
167
|
-
extraAfk = Math.round(testSeconds) - TestInput.keypressPerSecond.length;
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
extraAfk = Math.ceil(testSeconds) - TestInput.keypressPerSecond.length;
|
|
171
|
-
}
|
|
172
|
-
if (extraAfk < 0)
|
|
173
|
-
extraAfk = 0;
|
|
174
|
-
// console.log("-- extra afk debug");
|
|
175
|
-
// console.log("should be " + Math.ceil(testSeconds));
|
|
176
|
-
// console.log(keypressPerSecond.length);
|
|
177
|
-
// console.log(
|
|
178
|
-
// `gonna add extra ${extraAfk} seconds of afk because of no keypress data`
|
|
179
|
-
// );
|
|
180
|
-
}
|
|
181
|
-
const ret = TestInput.keypressPerSecond.filter(x => x.afk).length;
|
|
182
|
-
return ret + extraAfk;
|
|
183
|
-
}
|
|
184
|
-
export function setLastSecondNotRound() {
|
|
185
|
-
lastSecondNotRound = true;
|
|
186
|
-
}
|
|
187
|
-
export function calculateBurst() {
|
|
188
|
-
const timeToWrite = (performance.now() - TestInput.currentBurstStart) / 1000;
|
|
189
|
-
let wordLength;
|
|
190
|
-
wordLength = TestInput.input.current.length;
|
|
191
|
-
if (wordLength == 0) {
|
|
192
|
-
wordLength = TestInput.input.getHistoryLast()?.length ?? 0;
|
|
193
|
-
}
|
|
194
|
-
if (wordLength == 0)
|
|
195
|
-
return 0;
|
|
196
|
-
const speed = Misc.roundTo2((wordLength * (60 / timeToWrite)) / 5);
|
|
197
|
-
return Math.round(speed);
|
|
198
|
-
}
|
|
199
|
-
export function calculateAccuracy() {
|
|
200
|
-
const acc = (TestInput.accuracy.correct / (TestInput.accuracy.correct + TestInput.accuracy.incorrect)) *
|
|
201
|
-
100;
|
|
202
|
-
return isNaN(acc) ? 0 : acc;
|
|
203
|
-
}
|
|
204
|
-
export function removeAfkData() {
|
|
205
|
-
const testSeconds = calculateTestSeconds();
|
|
206
|
-
TestInput.keypressPerSecond.splice(testSeconds);
|
|
207
|
-
TestInput.wpmHistory.splice(testSeconds);
|
|
208
|
-
TestInput.burstHistory.splice(testSeconds);
|
|
209
|
-
TestInput.rawHistory.splice(testSeconds);
|
|
210
|
-
}
|
|
211
|
-
function countChars() {
|
|
212
|
-
let correctWordChars = 0;
|
|
213
|
-
let correctChars = 0;
|
|
214
|
-
let incorrectChars = 0;
|
|
215
|
-
let extraChars = 0;
|
|
216
|
-
let missedChars = 0;
|
|
217
|
-
let spaces = 0;
|
|
218
|
-
let correctspaces = 0;
|
|
219
|
-
for (let i = 0; i < TestInput.input.history.length; i++) {
|
|
220
|
-
const word = Config.mode == 'zen' ? TestInput.input.getHistory(i) : TestWords.words.get(i);
|
|
221
|
-
if (TestInput.input.getHistory(i) === '') {
|
|
222
|
-
//last word that was not started
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
if (TestInput.input.getHistory(i) == word) {
|
|
226
|
-
//the word is correct
|
|
227
|
-
correctWordChars += word.length;
|
|
228
|
-
correctChars += word.length;
|
|
229
|
-
if (i < TestInput.input.history.length - 1 &&
|
|
230
|
-
Misc.getLastChar(TestInput.input.getHistory(i)) !== '\n') {
|
|
231
|
-
correctspaces++;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
else if (TestInput.input.getHistory(i).length >= word.length) {
|
|
235
|
-
//too many chars
|
|
236
|
-
for (let c = 0; c < TestInput.input.getHistory(i).length; c++) {
|
|
237
|
-
if (c < word.length) {
|
|
238
|
-
//on char that still has a word list pair
|
|
239
|
-
if (TestInput.input.getHistory(i)[c] == word[c]) {
|
|
240
|
-
correctChars++;
|
|
241
|
-
}
|
|
242
|
-
else {
|
|
243
|
-
incorrectChars++;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
//on char that is extra
|
|
248
|
-
extraChars++;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
//not enough chars
|
|
254
|
-
const toAdd = {
|
|
255
|
-
correct: 0,
|
|
256
|
-
incorrect: 0,
|
|
257
|
-
missed: 0,
|
|
258
|
-
};
|
|
259
|
-
for (let c = 0; c < word.length; c++) {
|
|
260
|
-
if (c < TestInput.input.getHistory(i).length) {
|
|
261
|
-
//on char that still has a word list pair
|
|
262
|
-
if (TestInput.input.getHistory(i)[c] == word[c]) {
|
|
263
|
-
toAdd.correct++;
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
toAdd.incorrect++;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
//on char that is extra
|
|
271
|
-
toAdd.missed++;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
correctChars += toAdd.correct;
|
|
275
|
-
incorrectChars += toAdd.incorrect;
|
|
276
|
-
if (i === TestInput.input.history.length - 1 && Config.mode == 'time') {
|
|
277
|
-
//last word - check if it was all correct - add to correct word chars
|
|
278
|
-
if (toAdd.incorrect === 0)
|
|
279
|
-
correctWordChars += toAdd.correct;
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
missedChars += toAdd.missed;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
if (i < TestInput.input.history.length - 1) {
|
|
286
|
-
spaces++;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
if (Config.funbox === 'nospace' || Config.funbox === 'arrows') {
|
|
290
|
-
spaces = 0;
|
|
291
|
-
correctspaces = 0;
|
|
292
|
-
}
|
|
293
|
-
return {
|
|
294
|
-
spaces: spaces,
|
|
295
|
-
correctWordChars: correctWordChars,
|
|
296
|
-
allCorrectChars: correctChars,
|
|
297
|
-
incorrectChars: Config.mode == 'zen' ? TestInput.accuracy.incorrect : incorrectChars,
|
|
298
|
-
extraChars: extraChars,
|
|
299
|
-
missedChars: missedChars,
|
|
300
|
-
correctSpaces: correctspaces,
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
export function calculateStats() {
|
|
304
|
-
let testSeconds = calculateTestSeconds();
|
|
305
|
-
if (wpmCalcDebug) {
|
|
306
|
-
console.log('date based time', (end2 - start2) / 1000);
|
|
307
|
-
console.log('performance.now based time', testSeconds);
|
|
308
|
-
}
|
|
309
|
-
if (Config.mode != 'custom') {
|
|
310
|
-
testSeconds = Misc.roundTo2(testSeconds);
|
|
311
|
-
if (wpmCalcDebug) {
|
|
312
|
-
console.log('mode is not custom - wounding');
|
|
313
|
-
console.log('new time', testSeconds);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
const chars = countChars();
|
|
317
|
-
const wpm = Misc.roundTo2(((chars.correctWordChars + chars.correctSpaces) * (60 / testSeconds)) / 5);
|
|
318
|
-
const wpmraw = Misc.roundTo2(((chars.allCorrectChars + chars.spaces + chars.incorrectChars + chars.extraChars) *
|
|
319
|
-
(60 / testSeconds)) /
|
|
320
|
-
5);
|
|
321
|
-
if (wpmCalcDebug) {
|
|
322
|
-
console.log('chars', chars);
|
|
323
|
-
console.log('wpm', ((chars.correctWordChars + chars.correctSpaces) * (60 / testSeconds)) / 5);
|
|
324
|
-
console.log('wpm rounded to 2', wpm);
|
|
325
|
-
console.log('wpmraw', wpmraw);
|
|
326
|
-
}
|
|
327
|
-
const acc = Misc.roundTo2(calculateAccuracy());
|
|
328
|
-
return {
|
|
329
|
-
wpm: isNaN(wpm) ? 0 : wpm,
|
|
330
|
-
wpmRaw: isNaN(wpmraw) ? 0 : wpmraw,
|
|
331
|
-
acc: acc,
|
|
332
|
-
correctChars: chars.correctWordChars,
|
|
333
|
-
incorrectChars: chars.incorrectChars,
|
|
334
|
-
missedChars: chars.missedChars,
|
|
335
|
-
extraChars: chars.extraChars,
|
|
336
|
-
allChars: chars.allCorrectChars + chars.spaces + chars.incorrectChars + chars.extraChars,
|
|
337
|
-
time: Misc.roundTo2(testSeconds),
|
|
338
|
-
spaces: chars.spaces,
|
|
339
|
-
correctSpaces: chars.correctSpaces,
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1zdGF0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3Rnby10eXBpbmctdGVzdC9zcmMvbGliL2hlbHBlcnMvdGVzdC90ZXN0LXN0YXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sTUFBTSxNQUFNLHNCQUFzQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxJQUFJLE1BQU0sa0JBQWtCLENBQUM7QUFDekMsT0FBTyxLQUFLLFNBQVMsTUFBTSxjQUFjLENBQUM7QUFDMUMsT0FBTyxLQUFLLFNBQVMsTUFBTSxjQUFjLENBQUM7QUErRTFDLE1BQU0sQ0FBQyxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUM7QUFDM0IsTUFBTSxDQUFDLElBQUksS0FBYSxFQUFFLEdBQVcsQ0FBQztBQUN0QyxNQUFNLENBQUMsSUFBSSxNQUFjLEVBQUUsSUFBWSxDQUFDO0FBQ3hDLE1BQU0sQ0FBQyxJQUFJLGtCQUFrQixHQUFHLEtBQUssQ0FBQztBQUV0QyxNQUFNLENBQUMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBRTNCLE1BQU0sVUFBVSxjQUFjLENBQUMsR0FBVztJQUN4QyxXQUFXLEdBQUcsR0FBRyxDQUFDO0FBQ3BCLENBQUM7QUFFRCxNQUFNLENBQUMsSUFBSSxVQUFnRCxDQUFDO0FBRTVELE1BQU0sVUFBVSxhQUFhLENBQUMsTUFBNEM7SUFDeEUsVUFBVSxHQUFHLE1BQU0sQ0FBQztBQUN0QixDQUFDO0FBRUQsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0FBQ3pCLE1BQU0sVUFBVSxtQkFBbUI7SUFDakMsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0lBQzdDLFlBQVksR0FBRyxJQUFJLENBQUM7QUFDdEIsQ0FBQztBQUVELE1BQU0sVUFBVSxRQUFRO0lBQ3RCLE1BQU0sR0FBRyxHQUFlO1FBQ3RCLFVBQVU7UUFDVixLQUFLO1FBQ0wsR0FBRztRQUNILFVB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LEtBQUssQ0FBQyxVQUFVO1FBQzVCLFFBQVEsRUFBRSxLQUFLLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUMsVUFBVTtRQUN4RixJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUM7UUFDaEMsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO1FBQ3BCLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtLQUNuQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDb25maWcgZnJvbSAnLi4vLi4vaGVscGVycy9jb25maWcnO1xuaW1wb3J0ICogYXMgTWlzYyBmcm9tICcuLi8uLi91dGlscy9taXNjJztcbmltcG9ydCAqIGFzIFRlc3RJbnB1dCBmcm9tICcuL3Rlc3QtaW5wdXQnO1xuaW1wb3J0ICogYXMgVGVzdFdvcmRzIGZyb20gJy4vdGVzdC13b3Jkcyc7XG5pbXBvcnQgeyBNb25rZXlUeXBlcyB9IGZyb20gJy4uLy4uL3R5cGVzL3R5cGVzJztcbmludGVyZmFjZSBDaGFyQ291bnQge1xuICBzcGFjZXM6IG51bWJlcjtcbiAgY29ycmVjdFdvcmRDaGFyczogbnVtYmVyO1xuICBhbGxDb3JyZWN0Q2hhcnM6IG51bWJlcjtcbiAgaW5jb3JyZWN0Q2hhcnM6IG51bWJlcjtcbiAgZXh0cmFDaGFyczogbnVtYmVyO1xuICBtaXNzZWRDaGFyczogbnVtYmVyO1xuICBjb3JyZWN0U3BhY2VzOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBLZXlwcmVzcyB7XG4gIGNvdW50OiBudW1iZXI7XG4gIGVycm9yczogbnVtYmVyO1xuICB3b3JkczogbnVtYmVyW107XG4gIGFmazogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIEtleXByZXNzVGltaW5ncyB7XG4gIHNwYWNpbmc6IHtcbiAgICBjdXJyZW50OiBudW1iZXI7XG4gICAgYXJyYXk6IG51bWJlcltdIHwgJ3Rvb2xvbmcnO1xuICB9O1xuICBkdXJhdGlvbjoge1xuICAgIGN1cnJlbnQ6IG51bWJlcjtcbiAgICBhcnJheTogbnVtYmVyW10gfCAndG9vbG9uZyc7XG4gIH07XG59XG5cbmludGVyZmFjZSBEZWJ1Z1N0YXRzIHtcbiAgbGFzdFJlc3VsdD86IE1vbmtleVR5cGVzLlJlc3VsdDxNb25rZXlUeXBlcy5Nb2RlPjtcbiAgc3RhcnQ6IG51bWJlcjtcbiAgZW5kOiBudW1iZXI7XG4gIHdwbUhpc3Rvcnk6IG51bWJlcltdO1xuICByYXdIaXN0b3J5OiBudW1iZXJbXTtcbiAgYnVyc3RIaXN0b3J5OiBudW1iZXJbXTtcbiAga2V5cHJlc3NQZXJTZWNvbmQ6IEtleXByZXNzW107XG4gIGN1cnJlbnRLZXlwcmVzczoge1xuICAgIGNvdW50OiBudW1iZXI7XG4gICAgZXJyb3JzOiBudW1iZXI7XG4gICAgd29yZHM6IG51bWJlcltdO1xuICAgIGFmazogYm9vbGVhbjtcbiAgfTtcbiAgbGFzdEtleXByZXNzOiBudW1iZXI7XG4gIGN1cnJlbnRCdXJzdFN0YXJ0OiBudW1iZXI7XG4gIGxhc3RTZWNvbmROb3RSb3VuZDogYm9vbGVhbjtcbiAgbWlzc2VkV29yZHM6IHtcbiAgICBbd29yZDogc3RyaW5nXTogbnVtYmVyO1xuICB9O1xuICBhY2N1cmFjeToge1xuICAgIGNvcnJlY3Q6IG51bWJlcjtcbiAgICBpbmNvcnJlY3Q6IG51bWJlcjtcbiAgfTtcbiAga2V5cHJlc3NUaW1pbmdzOiBLZXlwcmVzc1RpbWluZ3M7XG4gIGtleVNwYWNpbmdTdGF0cz86IHtcbiAgICBhdmVyYWdlOiBudW1iZXI7XG4gICAgc2Q6IG51bWJlcjtcbiAgfTtcbiAga2V5RHVyYXRpb25TdGF0cz86IHtcbiAgICBhdmVyYWdlOiBudW1iZXI7XG4gICAgc2Q6IG51bWJlcjtcbiAgfTtcbn1cblxuaW50ZXJmYWNlIFN0YXRzIHtcbiAgd3BtOiBudW1iZXI7XG4gIHdwbVJhdzogbnVtYmVyO1xuICBhY2M6IG51bWJlcjtcbiAgY29ycmVjdENoYXJzOiBudW1iZXI7XG4gIGluY29ycmVjdENoYXJzOiBudW1iZXI7XG4gIG1pc3NlZENoYXJzOiBudW1iZXI7XG4gIGV4dHJhQ2hhcnM6IG51bWJlcjtcbiAgYWxsQ2hhcnM6IG51bWJlcjtcbiAgdGltZTogbnVtYmVyO1xuICBzcGFjZXM6IG51bWJlcjtcbiAgY29ycmVjdFNwYWNlczogbnVtYmVyO1xufVxuXG5leHBvcnQgbGV0IGludmFsaWQgPSBmYWxzZTtcbmV4cG9ydCBsZXQgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXI7XG5leHBvcnQgbGV0IHN0YXJ0MjogbnVtYmVyLCBlbmQyOiBudW1iZXI7XG5leHBvcnQgbGV0IGxhc3RTZWNvbmROb3RSb3VuZCA9IGZhbHNlO1xuXG5leHBvcnQgbGV0IGxhc3RUZXN0V3BtID0gMDtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldExhc3RUZXN0V3BtKHdwbTogbnVtYmVyKTogdm9pZCB7XG4gIGxhc3RUZXN0V3BtID0gd3BtO1xufVxuXG5leHBvcnQgbGV0IGxhc3RSZXN1bHQ6IE1vbmtleVR5cGVzLlJlc3VsdDxNb25rZXlUeXBlcy5Nb2RlPjtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldExhc3RSZXN1bHQocmVzdWx0OiBNb25rZXlUeXBlcy5SZXN1bHQ8TW9ua2V5VHlwZXMuTW9kZT4pOiB2b2lkIHtcbiAgbGFzdFJlc3VsdCA9IHJlc3VsdDtcbn1cblxubGV0IHdwbUNhbGNEZWJ1ZyA9IGZhbHNlO1xuZXhwb3J0IGZ1bmN0aW9uIHdwbUNhbGN1bGF0aW9uRGVidWcoKTogdm9pZCB7XG4gIGNvbnNvbGUubG9nKCd3cG0gY2FsY3VsYXRpb24gZGVidWcgZW5hYmxlZCcpO1xuICB3cG1DYWxjRGVidWcgPSB0cnVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RhdHMoKTogRGVidWdTdGF0cyB7XG4gIGNvbnN0IHJldDogRGVidWdTdGF0cyA9IHtcbiAgICBsYXN0UmVzdWx0LFxuICAgIHN0YXJ0LFxuICAgIGVuZCxcbiAgICB3cG1IaXN0b3J5OiBUZXN0SW5wdXQud3BtSGlzdG9yeSxcbiAgICByYXdIaXN0b3J5OiBUZXN0SW5wdXQud3BtSGlzdG9yeSxcbiAgICBidXJzdEhpc3Rvcnk6IFRlc3RJbnB1dC5idXJzdEhpc3RvcnksXG4gICAga2V5cHJlc3NQZXJTZWNvbmQ6IFRlc3RJbnB1dC5rZXlwcmVzc1BlclNlY29uZCxcbiAgICBjdXJyZW50S2V5cHJlc3M6IFRlc3RJbnB1dC5jdXJyZW50S2V5cHJlc3MsXG4gICAgbGFzdEtleXByZXNzOiBUZXN0SW5wdXQubGFzdEtleXByZXNzLFxuICAgIGN1cnJlbnRCdXJzdFN0YXJ0OiBUZXN0SW5wdXQuY3VycmVudEJ1cnN0U3RhcnQsXG4gICAgbGFzdFNlY29uZE5vdFJvdW5kLFxuICAgIG1pc3NlZFdvcmRzOiBUZXN0SW5wdXQubWlzc2VkV29yZHMsXG4gICAgYWNjdXJhY3k6IFRlc3RJbnB1dC5hY2N1cmFjeSxcbiAgICBrZXlwcmVzc1RpbWluZ3M6IFRlc3RJbnB1dC5rZXlwcmVzc1RpbWluZ3MsXG4gIH07XG5cbiAgdHJ5IHtcbiAgICByZXQua2V5U3BhY2luZ1N0YXRzID0ge1xuICAgICAgYXZlcmFnZTpcbiAgICAgICAgKFRlc3RJbnB1dC5rZXlwcmVzc1RpbWluZ3Muc3BhY2luZy5hcnJheSBhcyBudW1iZXJbXSkucmVkdWNlKFxuICAgICAgICAgIChwcmV2aW91cywgY3VycmVudCkgPT4gKGN1cnJlbnQgKz0gcHJldmlvdXMpXG4gICAgICAgICkgLyBUZXN0SW5wdXQua2V5cHJlc3NUaW1pbmdzLnNwYWNpbmcuYXJyYXkubGVuZ3RoLFxuICAgICAgc2Q6IE1pc2Muc3RkRGV2KFRlc3RJbnB1dC5rZXlwcmVzc1RpbWluZ3Muc3BhY2luZy5hcnJheSBhcyBudW1iZXJbXSksXG4gICAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vXG4gIH1cbiAgdHJ5IHtcbiAgICByZXQua2V5RHVyYXRpb25TdGF0cyA9IHtcbiAgICAgIGF2ZXJhZ2U6XG4gICAgICAgIChUZXN0SW5wdXQua2V5cHJlc3NUaW1pbmdzLmR1cmF0aW9uLmFycmF5IGFzIG51bWJlcltdKS5yZWR1Y2UoXG4gICAgICAgICAgKHByZXZpb3VzLCBjdXJyZW50KSA9PiAoY3VycmVudCArPSBwcmV2aW91cylcbiAgICAgICAgKSAvIFRlc3RJbnB1dC5rZXlwcmVzc1RpbWluZ3MuZHVyYXRpb24uYXJyYXkubGVuZ3RoLFxuICAgICAgc2Q6IE1pc2Muc3RkRGV2KFRlc3RJbnB1dC5rZXlwcmVzc1RpbWluZ3MuZHVyYXRpb24uYXJyYXkgYXMgbnVtYmVyW10pLFxuICAgIH07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvL1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc3RhcnQoKTogdm9pZCB7XG4gIHN0YXJ0ID0gMDtcbiAgZW5kID0gMDtcbiAgaW52YWxpZCA9IGZhbHNlO1xuICBsYXN0U2Vjb25kTm90Um91bmQgPSBmYWxzZTtcbn1cblxuZXhwb3J0IGxldCByZXN0YXJ0Q291bnQgPSAwO1xuZXhwb3J0IGxldCBpbmNvbXBsZXRlU2Vjb25kcyA9IDA7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmNyZW1lbnRSZXN0YXJ0Q291bnQoKTogdm9pZCB7XG4gIHJlc3RhcnRDb3VudCsrO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaW5jcmVtZW50SW5jb21wbGV0ZVNlY29uZHModmFsOiBudW1iZXIpOiB2b2lkIHtcbiAgaW5jb21wbGV0ZVNlY29uZHMgKz0gdmFsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRJbmNvbXBsZXRlKCk6IHZvaWQge1xuICByZXN0YXJ0Q291bnQgPSAwO1xuICBpbmNvbXBsZXRlU2Vjb25kcyA9IDA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRJbnZhbGlkKCk6IHZvaWQge1xuICBpbnZhbGlkID0gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVRlc3RTZWNvbmRzKG5vdz86IG51bWJlcik6IG51bWJlciB7XG4gIGlmIChub3cgPT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGVuZEFma1NlY29uZHMgPSAoZW5kIC0gVGVzdElucHV0Lmxhc3RLZXlwcmVzcykgLyAxMDAwO1xuICAgIGlmICgoQ29uZmlnLm1vZGUgPT0gJ3plbicgfHwgVGVzdElucHV0LmJhaWxvdXQpICYmIGVuZEFma1NlY29uZHMgPCA3KSB7XG4gICAgICByZXR1cm4gKFRlc3RJbnB1dC5sYXN0S2V5cHJlc3MgLSBzdGFydCkgLyAxMDAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIDEwMDA7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiAobm93IC0gc3RhcnQpIC8gMTAwMDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlV3BtQW5kUmF3KCk6IE1vbmtleVR5cGVzLldvcmRzUGVyTWludXRlQW5kUmF3IHtcbiAgbGV0IGNoYXJzID0gMDtcbiAgbGV0IGNvcnJlY3RXb3JkQ2hhcnMgPSAwO1xuICBsZXQgc3BhY2VzID0gMDtcbiAgLy9jaGVjayBpbnB1dCBoaXN0b3J5XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgVGVzdElucHV0LmlucHV0Lmhpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCB3b3JkID0gQ29uZmlnLm1vZGUgPT0gJ3plbicgPyBUZXN0SW5wdXQuaW5wdXQuZ2V0SGlzdG9yeShpKSA6IFRlc3RXb3Jkcy53b3Jkcy5nZXQoaSk7XG4gICAgaWYgKFRlc3RJbnB1dC5pbnB1dC5nZXRIaXN0b3J5KGkpID09IHdvcmQpIHtcbiAgICAgIC8vdGhlIHdvcmQgaXMgY29ycmVjdFxuICAgICAgLy8rMSBmb3Igc3BhY2VcbiAgICAgIGNvcnJlY3RXb3JkQ2hhcnMgKz0gd29yZC5sZW5ndGg7XG4gICAgICBpZiAoXG4gICAgICAgIGkgPCBUZXN0SW5wdXQuaW5wdXQuaGlzdG9yeS5sZW5ndGggLSAxICYmXG4gICAgICAgIE1pc2MuZ2V0TGFzdENoYXIoVGVzdElucHV0LmlucHV0LmdldEhpc3RvcnkoaSkgYXMgc3RyaW5nKSAhPT0gJ1xcbidcbiAgICAgICkge1xuICAgICAgICBzcGFjZXMrKztcbiAgICAgIH1cbiAgICB9XG4gICAgY2hhcnMgKz0gVGVzdElucHV0LmlucHV0LmdldEhpc3RvcnkoaSkubGVuZ3RoO1xuICB9XG4gIGlmIChUZXN0SW5wdXQuaW5wdXQuY3VycmVudCAhPT0gJycpIHtcbiAgICBjb25zdCB3b3JkID0gQ29uZmlnLm1vZGUgPT0gJ3plbicgPyBUZXN0SW5wdXQuaW5wdXQuY3VycmVudCA6IFRlc3RXb3Jkcy53b3Jkcy5nZXRDdXJyZW50KCk7XG4gICAgLy9jaGVjayB3aGF0cyBjdXJyZW50bHkgdHlwZWRcbiAgICBjb25zdCB0b0FkZCA9IHtcbiAgICAgIGNvcnJlY3Q6IDAsXG4gICAgICBpbmNvcnJlY3Q6IDAsXG4gICAgICBtaXNzZWQ6IDAsXG4gICAgfTtcbiAgICBmb3IgKGxldCBjID0gMDsgYyA8IHdvcmQubGVuZ3RoOyBjKyspIHtcbiAgICAgIGlmIChjIDwgVGVzdElucHV0LmlucHV0LmN1cnJlbnQubGVuZ3RoKSB7XG4gICAgICAgIC8vb24gY2hhciB0aGF0IHN0aWxsIGhhcyBhIHdvcmQgbGlzdCBwYWlyXG4gICAgICAgIGlmIChUZXN0SW5wdXQuaW5wdXQuY3VycmVudFtjXSA9PSB3b3JkW2NdKSB7XG4gICAgICAgICAgdG9BZGQuY29ycmVjdCsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRvQWRkLmluY29ycmVjdCsrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvL29uIGNoYXIgdGhhdCBpcyBleHRyYVxuICAgICAgICB0b0FkZC5taXNzZWQrKztcbiAgICAgIH1cbiAgICB9XG4gICAgY2hhcnMgKz0gdG9BZGQuY29ycmVjdDtcbiAgICBjaGFycyArPSB0b0FkZC5pbmNvcnJlY3Q7XG4gICAgY2hhcnMgKz0gdG9BZGQubWlzc2VkO1xuICAgIGlmICh0b0FkZC5pbmNvcnJlY3QgPT0gMCkge1xuICAgICAgLy93b3JkIGlzIGNvcnJlY3Qgc28gZmFyLCBhZGQgY2hhcnNcbiAgICAgIGNvcnJlY3RXb3JkQ2hhcnMgKz0gdG9BZGQuY29ycmVjdDtcbiAgICB9XG4gIH1cbiAgaWYgKENvbmZpZy5mdW5ib3ggPT09ICdub3NwYWNlJyB8fCBDb25maWcuZnVuYm94ID09PSAnYXJyb3dzJykge1xuICAgIHNwYWNlcyA9IDA7XG4gIH1cbiAgY2hhcnMgKz0gVGVzdElucHV0LmlucHV0LmN1cnJlbnQubGVuZ3RoO1xuICBjb25zdCB0ZXN0U2Vjb25kcyA9IGNhbGN1bGF0ZVRlc3RTZWNvbmRzKHBlcmZvcm1hbmNlLm5vdygpKTtcbiAgY29uc3Qgd3BtID0gTWF0aC5yb3VuZCgoKGNvcnJlY3RXb3JkQ2hhcnMgKyBzcGFjZXMpICogKDYwIC8gdGVzdFNlY29uZHMpKSAvIDUpO1xuICBjb25zdCByYXcgPSBNYXRoLnJvdW5kKCgoY2hhcnMgKyBzcGFjZXMpICogKDYwIC8gdGVzdFNlY29uZHMpKSAvIDUpO1xuICByZXR1cm4ge1xuICAgIHdwbTogd3BtLFxuICAgIHJhdzogcmF3LFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0RW5kKGU6IG51bWJlcik6IHZvaWQge1xuICBlbmQgPSBlO1xuICBlbmQyID0gRGF0ZS5ub3coKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFN0YXJ0KHM6IG51bWJlcik6IHZvaWQge1xuICBzdGFydCA9IHM7XG4gIHN0YXJ0MiA9IERhdGUubm93KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVBZmtTZWNvbmRzKHRlc3RTZWNvbmRzOiBudW1iZXIpOiBudW1iZXIge1xuICBsZXQgZXh0cmFBZmsgPSAwO1xuICBpZiAodGVzdFNlY29uZHMgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChDb25maWcubW9kZSA9PT0gJ3RpbWUnKSB7XG4gICAgICBleHRyYUFmayA9IE1hdGgucm91bmQodGVzdFNlY29uZHMpIC0gVGVzdElucHV0LmtleXByZXNzUGVyU2Vjb25kLmxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgZXh0cmFBZmsgPSBNYXRoLmNlaWwodGVzdFNlY29uZHMpIC0gVGVzdElucHV0LmtleXByZXNzUGVyU2Vjb25kLmxlbmd0aDtcbiAgICB9XG4gICAgaWYgKGV4dHJhQWZrIDwgMCkgZXh0cmFBZmsgPSAwO1xuICAgIC8vIGNvbnNvbGUubG9nKFwiLS0gZXh0cmEgYWZrIGRlYnVnXCIpO1xuICAgIC8vIGNvbnNvbGUubG9nKFwic2hvdWxkIGJlIFwiICsgTWF0aC5jZWlsKHRlc3RTZWNvbmRzKSk7XG4gICAgLy8gY29uc29sZS5sb2coa2V5cHJlc3NQZXJTZWNvbmQubGVuZ3RoKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcbiAgICAvLyAgIGBnb25uYSBhZGQgZXh0cmEgJHtleHRyYUFma30gc2Vjb25kcyBvZiBhZmsgYmVjYXVzZSBvZiBubyBrZXlwcmVzcyBkYXRhYFxuICAgIC8vICk7XG4gIH1cbiAgY29uc3QgcmV0ID0gVGVzdElucHV0LmtleXByZXNzUGVyU2Vjb25kLmZpbHRlcih4ID0+IHguYWZrKS5sZW5ndGg7XG4gIHJldHVybiByZXQgKyBleHRyYUFmaztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldExhc3RTZWNvbmROb3RSb3VuZCgpOiB2b2lkIHtcbiAgbGFzdFNlY29uZE5vdFJvdW5kID0gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUJ1cnN0KCk6IG51bWJlciB7XG4gIGNvbnN0IHRpbWVUb1dyaXRlID0gKHBlcmZvcm1hbmNlLm5vdygpIC0gVGVzdElucHV0LmN1cnJlbnRCdXJzdFN0YXJ0KSAvIDEwMDA7XG4gIGxldCB3b3JkTGVuZ3RoOiBudW1iZXI7XG4gIHdvcmRMZW5ndGggPSBUZXN0SW5wdXQuaW5wdXQuY3VycmVudC5sZW5ndGg7XG4gIGlmICh3b3JkTGVuZ3RoID09IDApIHtcbiAgICB3b3JkTGVuZ3RoID0gVGVzdElucHV0LmlucHV0LmdldEhpc3RvcnlMYXN0KCk/Lmxlbmd0aCA/PyAwO1xuICB9XG4gIGlmICh3b3JkTGVuZ3RoID09IDApIHJldHVybiAwO1xuICBjb25zdCBzcGVlZCA9IE1pc2Mucm91bmRUbzIoKHdvcmRMZW5ndGggKiAoNjAgLyB0aW1lVG9Xcml0ZSkpIC8gNSk7XG4gIHJldHVybiBNYXRoLnJvdW5kKHNwZWVkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZUFjY3VyYWN5KCk6IG51bWJlciB7XG4gIGNvbnN0IGFjYyA9XG4gICAgKFRlc3RJbnB1dC5hY2N1cmFjeS5jb3JyZWN0IC8gKFRlc3RJbnB1dC5hY2N1cmFjeS5jb3JyZWN0ICsgVGVzdElucHV0LmFjY3VyYWN5LmluY29ycmVjdCkpICpcbiAgICAxMDA7XG4gIHJldHVybiBpc05hTihhY2MpID8gMCA6IGFjYztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUFma0RhdGEoKTogdm9pZCB7XG4gIGNvbnN0IHRlc3RTZWNvbmRzID0gY2FsY3VsYXRlVGVzdFNlY29uZHMoKTtcbiAgVGVzdElucHV0LmtleXByZXNzUGVyU2Vjb25kLnNwbGljZSh0ZXN0U2Vjb25kcyk7XG4gIFRlc3RJbnB1dC53cG1IaXN0b3J5LnNwbGljZSh0ZXN0U2Vjb25kcyk7XG4gIFRlc3RJbnB1dC5idXJzdEhpc3Rvcnkuc3BsaWNlKHRlc3RTZWNvbmRzKTtcbiAgVGVzdElucHV0LnJhd0hpc3Rvcnkuc3BsaWNlKHRlc3RTZWNvbmRzKTtcbn1cblxuZnVuY3Rpb24gY291bnRDaGFycygpOiBDaGFyQ291bnQge1xuICBsZXQgY29ycmVjdFdvcmRDaGFycyA9IDA7XG4gIGxldCBjb3JyZWN0Q2hhcnMgPSAwO1xuICBsZXQgaW5jb3JyZWN0Q2hhcnMgPSAwO1xuICBsZXQgZXh0cmFDaGFycyA9IDA7XG4gIGxldCBtaXNzZWRDaGFycyA9IDA7XG4gIGxldCBzcGFjZXMgPSAwO1xuICBsZXQgY29ycmVjdHNwYWNlcyA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgVGVzdElucHV0LmlucHV0Lmhpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCB3b3JkID0gQ29uZmlnLm1vZGUgPT0gJ3plbicgPyBUZXN0SW5wdXQuaW5wdXQuZ2V0SGlzdG9yeShpKSA6IFRlc3RXb3Jkcy53b3Jkcy5nZXQoaSk7XG4gICAgaWYgKFRlc3RJbnB1dC5pbnB1dC5nZXRIaXN0b3J5KGkpID09PSAnJykge1xuICAgICAgLy9sYXN0IHdvcmQgdGhhdCB3YXMgbm90IHN0YXJ0ZWRcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAoVGVzdElucHV0LmlucHV0LmdldEhpc3RvcnkoaSkgPT0gd29yZCkge1xuICAgICAgLy90aGUgd29yZCBpcyBjb3JyZWN0XG4gICAgICBjb3JyZWN0V29yZENoYXJzICs9IHdvcmQubGVuZ3RoO1xuICAgICAgY29ycmVjdENoYXJzICs9IHdvcmQubGVuZ3RoO1xuICAgICAgaWYgKFxuICAgICAgICBpIDwgVGVzdElucHV0LmlucHV0Lmhpc3RvcnkubGVuZ3RoIC0gMSAmJlxuICAgICAgICBNaXNjLmdldExhc3RDaGFyKFRlc3RJbnB1dC5pbnB1dC5nZXRIaXN0b3J5KGkpIGFzIHN0cmluZykgIT09ICdcXG4nXG4gICAgICApIHtcbiAgICAgICAgY29ycmVjdHNwYWNlcysrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoVGVzdElucHV0LmlucHV0LmdldEhpc3RvcnkoaSkubGVuZ3RoID49IHdvcmQubGVuZ3RoKSB7XG4gICAgICAvL3RvbyBtYW55IGNoYXJzXG4gICAgICBmb3IgKGxldCBjID0gMDsgYyA8IFRlc3RJbnB1dC5pbnB1dC5nZXRIaXN0b3J5KGkpLmxlbmd0aDsgYysrKSB7XG4gICAgICAgIGlmIChjIDwgd29yZC5sZW5ndGgpIHtcbiAgICAgICAgICAvL29uIGNoYXIgdGhhdCBzdGlsbCBoYXMgYSB3b3JkIGxpc3QgcGFpclxuICAgICAgICAgIGlmIChUZXN0SW5wdXQuaW5wdXQuZ2V0SGlzdG9yeShpKVtjXSA9PSB3b3JkW2NdKSB7XG4gICAgICAgICAgICBjb3JyZWN0Q2hhcnMrKztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5jb3JyZWN0Q2hhcnMrKztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy9vbiBjaGFyIHRoYXQgaXMgZXh0cmFcbiAgICAgICAgICBleHRyYUNoYXJzKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy9ub3QgZW5vdWdoIGNoYXJzXG4gICAgICBjb25zdCB0b0FkZCA9IHtcbiAgICAgICAgY29ycmVjdDogMCxcbiAgICAgICAgaW5jb3JyZWN0OiAwLFxuICAgICAgICBtaXNzZWQ6IDAsXG4gICAgICB9O1xuICAgICAgZm9yIChsZXQgYyA9IDA7IGMgPCB3b3JkLmxlbmd0aDsgYysrKSB7XG4gICAgICAgIGlmIChjIDwgVGVzdElucHV0LmlucHV0LmdldEhpc3RvcnkoaSkubGVuZ3RoKSB7XG4gICAgICAgICAgLy9vbiBjaGFyIHRoYXQgc3RpbGwgaGFzIGEgd29yZCBsaXN0IHBhaXJcbiAgICAgICAgICBpZiAoVGVzdElucHV0LmlucHV0LmdldEhpc3RvcnkoaSlbY10gPT0gd29yZFtjXSkge1xuICAgICAgICAgICAgdG9BZGQuY29ycmVjdCsrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b0FkZC5pbmNvcnJlY3QrKztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy9vbiBjaGFyIHRoYXQgaXMgZXh0cmFcbiAgICAgICAgICB0b0FkZC5taXNzZWQrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29ycmVjdENoYXJzICs9IHRvQWRkLmNvcnJlY3Q7XG4gICAgICBpbmNvcnJlY3RDaGFycyArPSB0b0FkZC5pbmNvcnJlY3Q7XG4gICAgICBpZiAoaSA9PT0gVGVzdElucHV0LmlucHV0Lmhpc3RvcnkubGVuZ3RoIC0gMSAmJiBDb25maWcubW9kZSA9PSAndGltZScpIHtcbiAgICAgICAgLy9sYXN0IHdvcmQgLSBjaGVjayBpZiBpdCB3YXMgYWxsIGNvcnJlY3QgLSBhZGQgdG8gY29ycmVjdCB3b3JkIGNoYXJzXG4gICAgICAgIGlmICh0b0FkZC5pbmNvcnJlY3QgPT09IDApIGNvcnJlY3RXb3JkQ2hhcnMgKz0gdG9BZGQuY29ycmVjdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1pc3NlZENoYXJzICs9IHRvQWRkLm1pc3NlZDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGkgPCBUZXN0SW5wdXQuaW5wdXQuaGlzdG9yeS5sZW5ndGggLSAxKSB7XG4gICAgICBzcGFjZXMrKztcbiAgICB9XG4gIH1cbiAgaWYgKENvbmZpZy5mdW5ib3ggPT09ICdub3NwYWNlJyB8fCBDb25maWcuZnVuYm94ID09PSAnYXJyb3dzJykge1xuICAgIHNwYWNlcyA9IDA7XG4gICAgY29ycmVjdHNwYWNlcyA9IDA7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBzcGFjZXM6IHNwYWNlcyxcbiAgICBjb3JyZWN0V29yZENoYXJzOiBjb3JyZWN0V29yZENoYXJzLFxuICAgIGFsbENvcnJlY3RDaGFyczogY29ycmVjdENoYXJzLFxuICAgIGluY29ycmVjdENoYXJzOiBDb25maWcubW9kZSA9PSAnemVuJyA/IFRlc3RJbnB1dC5hY2N1cmFjeS5pbmNvcnJlY3QgOiBpbmNvcnJlY3RDaGFycyxcbiAgICBleHRyYUNoYXJzOiBleHRyYUNoYXJzLFxuICAgIG1pc3NlZENoYXJzOiBtaXNzZWRDaGFycyxcbiAgICBjb3JyZWN0U3BhY2VzOiBjb3JyZWN0c3BhY2VzLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlU3RhdHMoKTogU3RhdHMge1xuICBsZXQgdGVzdFNlY29uZHMgPSBjYWxjdWxhdGVUZXN0U2Vjb25kcygpO1xuICBpZiAod3BtQ2FsY0RlYnVnKSB7XG4gICAgY29uc29sZS5sb2coJ2RhdGUgYmFzZWQgdGltZScsIChlbmQyIC0gc3RhcnQyKSAvIDEwMDApO1xuICAgIGNvbnNvbGUubG9nKCdwZXJmb3JtYW5jZS5ub3cgYmFzZWQgdGltZScsIHRlc3RTZWNvbmRzKTtcbiAgfVxuICBpZiAoQ29uZmlnLm1vZGUgIT0gJ2N1c3RvbScpIHtcbiAgICB0ZXN0U2Vjb25kcyA9IE1pc2Mucm91bmRUbzIodGVzdFNlY29uZHMpO1xuICAgIGlmICh3cG1DYWxjRGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdtb2RlIGlzIG5vdCBjdXN0b20gLSB3b3VuZGluZycpO1xuICAgICAgY29uc29sZS5sb2coJ25ldyB0aW1lJywgdGVzdFNlY29uZHMpO1xuICAgIH1cbiAgfVxuICBjb25zdCBjaGFycyA9IGNvdW50Q2hhcnMoKTtcbiAgY29uc3Qgd3BtID0gTWlzYy5yb3VuZFRvMihcbiAgICAoKGNoYXJzLmNvcnJlY3RXb3JkQ2hhcnMgKyBjaGFycy5jb3JyZWN0U3BhY2VzKSAqICg2MCAvIHRlc3RTZWNvbmRzKSkgLyA1XG4gICk7XG4gIGNvbnN0IHdwbXJhdyA9IE1pc2Mucm91bmRUbzIoXG4gICAgKChjaGFycy5hbGxDb3JyZWN0Q2hhcnMgKyBjaGFycy5zcGFjZXMgKyBjaGFycy5pbmNvcnJlY3RDaGFycyArIGNoYXJzLmV4dHJhQ2hhcnMpICpcbiAgICAgICg2MCAvIHRlc3RTZWNvbmRzKSkgL1xuICAgICAgNVxuICApO1xuICBpZiAod3BtQ2FsY0RlYnVnKSB7XG4gICAgY29uc29sZS5sb2coJ2NoYXJzJywgY2hhcnMpO1xuICAgIGNvbnNvbGUubG9nKCd3cG0nLCAoKGNoYXJzLmNvcnJlY3RXb3JkQ2hhcnMgKyBjaGFycy5jb3JyZWN0U3BhY2VzKSAqICg2MCAvIHRlc3RTZWNvbmRzKSkgLyA1KTtcbiAgICBjb25zb2xlLmxvZygnd3BtIHJvdW5kZWQgdG8gMicsIHdwbSk7XG4gICAgY29uc29sZS5sb2coJ3dwbXJhdycsIHdwbXJhdyk7XG4gIH1cbiAgY29uc3QgYWNjID0gTWlzYy5yb3VuZFRvMihjYWxjdWxhdGVBY2N1cmFjeSgpKTtcbiAgcmV0dXJuIHtcbiAgICB3cG06IGlzTmFOKHdwbSkgPyAwIDogd3BtLFxuICAgIHdwbVJhdzogaXNOYU4od3BtcmF3KSA/IDAgOiB3cG1yYXcsXG4gICAgYWNjOiBhY2MsXG4gICAgY29ycmVjdENoYXJzOiBjaGFycy5jb3JyZWN0V29yZENoYXJzLFxuICAgIGluY29ycmVjdENoYXJzOiBjaGFycy5pbmNvcnJlY3RDaGFycyxcbiAgICBtaXNzZWRDaGFyczogY2hhcnMubWlzc2VkQ2hhcnMsXG4gICAgZXh0cmFDaGFyczogY2hhcnMuZXh0cmFDaGFycyxcbiAgICBhbGxDaGFyczogY2hhcnMuYWxsQ29ycmVjdENoYXJzICsgY2hhcnMuc3BhY2VzICsgY2hhcnMuaW5jb3JyZWN0Q2hhcnMgKyBjaGFycy5leHRyYUNoYXJzLFxuICAgIHRpbWU6IE1pc2Mucm91bmRUbzIodGVzdFNlY29uZHMpLFxuICAgIHNwYWNlczogY2hhcnMuc3BhY2VzLFxuICAgIGNvcnJlY3RTcGFjZXM6IGNoYXJzLmNvcnJlY3RTcGFjZXMsXG4gIH07XG59XG4iXX0=
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
// Most of the code is thanks to
|
|
2
|
-
// https://stackoverflow.com/questions/29971898/how-to-create-an-accurate-timer-in-javascript
|
|
3
|
-
import Config from '../../helpers/config';
|
|
4
|
-
import * as Misc from '../../utils/misc';
|
|
5
|
-
import * as TimerEvent from '../observables/timer-event';
|
|
6
|
-
import * as SlowTimer from '../states/slow-timer';
|
|
7
|
-
import * as TestActive from '../states/test-active';
|
|
8
|
-
import * as Time from '../states/time';
|
|
9
|
-
import * as Caret from './caret';
|
|
10
|
-
import * as CustomText from './custom-text';
|
|
11
|
-
import * as TestInput from './test-input';
|
|
12
|
-
import * as TestStats from './test-stats';
|
|
13
|
-
import * as TestWords from './test-words';
|
|
14
|
-
import * as TimerProgress from './timer-progress';
|
|
15
|
-
let slowTimerCount = 0;
|
|
16
|
-
let timer = null;
|
|
17
|
-
const interval = 1000;
|
|
18
|
-
let expected = 0;
|
|
19
|
-
let timerDebug = false;
|
|
20
|
-
export function enableTimerDebug() {
|
|
21
|
-
timerDebug = true;
|
|
22
|
-
}
|
|
23
|
-
let checkIfTimeIsUpDisabled = false;
|
|
24
|
-
export function disableCheckIfTimeIsUp() {
|
|
25
|
-
checkIfTimeIsUpDisabled = true;
|
|
26
|
-
}
|
|
27
|
-
export function clear() {
|
|
28
|
-
Time.set(0);
|
|
29
|
-
if (timer !== null)
|
|
30
|
-
clearTimeout(timer);
|
|
31
|
-
}
|
|
32
|
-
function premid() {
|
|
33
|
-
if (timerDebug)
|
|
34
|
-
console.time('premid');
|
|
35
|
-
const premidSecondsLeft = document.querySelector('#premidSecondsLeft');
|
|
36
|
-
if (premidSecondsLeft !== null) {
|
|
37
|
-
premidSecondsLeft.innerHTML = (Config.time - Time.get()).toString();
|
|
38
|
-
}
|
|
39
|
-
if (timerDebug)
|
|
40
|
-
console.timeEnd('premid');
|
|
41
|
-
}
|
|
42
|
-
function updateTimer() {
|
|
43
|
-
if (timerDebug)
|
|
44
|
-
console.time('timer progress update');
|
|
45
|
-
if (Config.mode === 'time' || (Config.mode === 'custom' && CustomText.isTimeRandom)) {
|
|
46
|
-
TimerProgress.update();
|
|
47
|
-
}
|
|
48
|
-
if (timerDebug)
|
|
49
|
-
console.timeEnd('timer progress update');
|
|
50
|
-
}
|
|
51
|
-
function calculateWpmRaw() {
|
|
52
|
-
if (timerDebug)
|
|
53
|
-
console.time('calculate wpm and raw');
|
|
54
|
-
const wpmAndRaw = TestStats.calculateWpmAndRaw();
|
|
55
|
-
if (timerDebug)
|
|
56
|
-
console.timeEnd('calculate wpm and raw');
|
|
57
|
-
if (timerDebug)
|
|
58
|
-
console.time('push to history');
|
|
59
|
-
TestInput.pushToWpmHistory(wpmAndRaw.wpm);
|
|
60
|
-
TestInput.pushToRawHistory(wpmAndRaw.raw);
|
|
61
|
-
if (timerDebug)
|
|
62
|
-
console.timeEnd('push to history');
|
|
63
|
-
return wpmAndRaw;
|
|
64
|
-
}
|
|
65
|
-
function monkey(wpmAndRaw) {
|
|
66
|
-
if (timerDebug)
|
|
67
|
-
console.time('update monkey');
|
|
68
|
-
const num = Config.blindMode ? wpmAndRaw.raw : wpmAndRaw.wpm;
|
|
69
|
-
if (timerDebug)
|
|
70
|
-
console.timeEnd('update monkey');
|
|
71
|
-
}
|
|
72
|
-
function calculateAcc() {
|
|
73
|
-
if (timerDebug)
|
|
74
|
-
console.time('calculate acc');
|
|
75
|
-
const acc = Misc.roundTo2(TestStats.calculateAccuracy());
|
|
76
|
-
if (timerDebug)
|
|
77
|
-
console.timeEnd('calculate acc');
|
|
78
|
-
return acc;
|
|
79
|
-
}
|
|
80
|
-
function layoutfluid() {
|
|
81
|
-
if (timerDebug)
|
|
82
|
-
console.time('layoutfluid');
|
|
83
|
-
if (Config.funbox === 'layoutfluid' && Config.mode === 'time') {
|
|
84
|
-
const layouts = Config.customLayoutfluid
|
|
85
|
-
? Config.customLayoutfluid.split('#')
|
|
86
|
-
: ['qwerty', 'dvorak', 'colemak'];
|
|
87
|
-
const switchTime = Config.time / layouts.length;
|
|
88
|
-
const time = Time.get();
|
|
89
|
-
const index = Math.floor(time / switchTime);
|
|
90
|
-
const layout = layouts[index];
|
|
91
|
-
const flooredSwitchTimes = [];
|
|
92
|
-
for (let i = 1; i < layouts.length; i++) {
|
|
93
|
-
flooredSwitchTimes.push(Math.floor(switchTime * i));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
if (timerDebug)
|
|
97
|
-
console.timeEnd('layoutfluid');
|
|
98
|
-
}
|
|
99
|
-
function checkIfFailed(wpmAndRaw, acc) {
|
|
100
|
-
if (timerDebug)
|
|
101
|
-
console.time('fail conditions');
|
|
102
|
-
TestInput.pushKeypressesToHistory();
|
|
103
|
-
if (Config.minWpm === 'custom' &&
|
|
104
|
-
wpmAndRaw.wpm < Config.minWpmCustomSpeed &&
|
|
105
|
-
TestWords.words.currentIndex > 3) {
|
|
106
|
-
if (timer !== null)
|
|
107
|
-
clearTimeout(timer);
|
|
108
|
-
SlowTimer.clear();
|
|
109
|
-
slowTimerCount = 0;
|
|
110
|
-
TimerEvent.dispatch('fail', 'min wpm');
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (Config.minAcc === 'custom' && acc < Config.minAccCustom) {
|
|
114
|
-
if (timer !== null)
|
|
115
|
-
clearTimeout(timer);
|
|
116
|
-
SlowTimer.clear();
|
|
117
|
-
slowTimerCount = 0;
|
|
118
|
-
TimerEvent.dispatch('fail', 'min accuracy');
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
if (timerDebug)
|
|
122
|
-
console.timeEnd('fail conditions');
|
|
123
|
-
}
|
|
124
|
-
function checkIfTimeIsUp() {
|
|
125
|
-
if (timerDebug)
|
|
126
|
-
console.time('times up check');
|
|
127
|
-
if (Config.mode == 'time' || (Config.mode === 'custom' && CustomText.isTimeRandom)) {
|
|
128
|
-
if ((Time.get() >= Config.time && Config.time !== 0 && Config.mode === 'time') ||
|
|
129
|
-
(Time.get() >= CustomText.time && CustomText.time !== 0 && Config.mode === 'custom')) {
|
|
130
|
-
//times up
|
|
131
|
-
if (timer !== null)
|
|
132
|
-
clearTimeout(timer);
|
|
133
|
-
Caret.hide();
|
|
134
|
-
TestInput.input.pushHistory();
|
|
135
|
-
TestInput.corrected.pushHistory();
|
|
136
|
-
SlowTimer.clear();
|
|
137
|
-
slowTimerCount = 0;
|
|
138
|
-
TimerEvent.dispatch('finish');
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
if (timerDebug)
|
|
143
|
-
console.timeEnd('times up check');
|
|
144
|
-
}
|
|
145
|
-
// ---------------------------------------
|
|
146
|
-
let timerStats = [];
|
|
147
|
-
export function getTimerStats() {
|
|
148
|
-
return timerStats;
|
|
149
|
-
}
|
|
150
|
-
async function timerStep() {
|
|
151
|
-
if (timerDebug)
|
|
152
|
-
console.time('timer step -----------------------------');
|
|
153
|
-
Time.increment();
|
|
154
|
-
premid();
|
|
155
|
-
updateTimer();
|
|
156
|
-
const wpmAndRaw = calculateWpmRaw();
|
|
157
|
-
const acc = calculateAcc();
|
|
158
|
-
monkey(wpmAndRaw);
|
|
159
|
-
layoutfluid();
|
|
160
|
-
checkIfFailed(wpmAndRaw, acc);
|
|
161
|
-
if (!checkIfTimeIsUpDisabled) {
|
|
162
|
-
checkIfTimeIsUp();
|
|
163
|
-
}
|
|
164
|
-
if (timerDebug)
|
|
165
|
-
console.timeEnd('timer step -----------------------------');
|
|
166
|
-
}
|
|
167
|
-
export async function start() {
|
|
168
|
-
SlowTimer.clear();
|
|
169
|
-
slowTimerCount = 0;
|
|
170
|
-
timerStats = [];
|
|
171
|
-
expected = TestStats.start + interval;
|
|
172
|
-
(function loop() {
|
|
173
|
-
const delay = expected - performance.now();
|
|
174
|
-
timerStats.push({
|
|
175
|
-
dateNow: Date.now(),
|
|
176
|
-
now: performance.now(),
|
|
177
|
-
expected: expected,
|
|
178
|
-
nextDelay: delay,
|
|
179
|
-
});
|
|
180
|
-
if ((Config.mode === 'time' && Config.time < 130 && Config.time > 0) ||
|
|
181
|
-
(Config.mode === 'words' && Config.words < 250 && Config.words > 0)) {
|
|
182
|
-
if (delay < interval / 2) {
|
|
183
|
-
//slow timer
|
|
184
|
-
SlowTimer.set();
|
|
185
|
-
}
|
|
186
|
-
if (delay < interval / 10) {
|
|
187
|
-
slowTimerCount++;
|
|
188
|
-
if (slowTimerCount > 5) {
|
|
189
|
-
TimerEvent.dispatch('fail', 'slow timer');
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
timer = setTimeout(function () {
|
|
194
|
-
if (!TestActive.get()) {
|
|
195
|
-
if (timer !== null)
|
|
196
|
-
clearTimeout(timer);
|
|
197
|
-
SlowTimer.clear();
|
|
198
|
-
slowTimerCount = 0;
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
timerStep();
|
|
202
|
-
expected += interval;
|
|
203
|
-
loop();
|
|
204
|
-
}, delay);
|
|
205
|
-
})();
|
|
206
|
-
}
|
|
207
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC10aW1lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3Rnby10eXBpbmctdGVzdC9zcmMvbGliL2hlbHBlcnMvdGVzdC90ZXN0LXRpbWVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGdDQUFnQztBQUNoQyw2RkFBNkY7QUFFN0YsT0FBTyxNQUFNLE1BQU0sc0JBQXNCLENBQUM7QUFFMUMsT0FBTyxLQUFLLElBQUksTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEtBQUssVUFBVSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pELE9BQU8sS0FBSyxTQUFTLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxLQUFLLFVBQVUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRCxPQUFPLEtBQUssSUFBSSxNQUFNLGdCQUFnQixDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sS0FBSyxVQUFVLE1BQU0sZUFBZSxDQUFDO0FBQzVDLE9BQU8sS0FBSyxTQUFTLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sS0FBSyxTQUFTLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sS0FBSyxTQUFTLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sS0FBSyxhQUFhLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZCLElBQUksS0FBSyxHQUEwQixJQUFJLENBQUM7QUFDeEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3RCLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztBQUVqQixJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUM7QUFDdkIsTUFBTSxVQUFVLGdCQUFnQjtJQUM5QixVQUFVLEdBQUcsSUFBSSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxJQUFJLHVCQUF1QixHQUFHLEtBQUssQ0FBQztBQUNwQyxNQUFNLFVBQVUs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QUFFLENBQUM7Z0JBQ2pCLElBQUksY0FBYyxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUN2QixVQUFVLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQztnQkFDNUMsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQ0QsS0FBSyxHQUFHLFVBQVUsQ0FBQztZQUNqQixJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7Z0JBQ3RCLElBQUksS0FBSyxLQUFLLElBQUk7b0JBQUUsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUN4QyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ2xCLGNBQWMsR0FBRyxDQUFDLENBQUM7Z0JBQ25CLE9BQU87WUFDVCxDQUFDO1lBRUQsU0FBUyxFQUFFLENBQUM7WUFFWixRQUFRLElBQUksUUFBUSxDQUFDO1lBQ3JCLElBQUksRUFBRSxDQUFDO1FBQ1QsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ1osQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBNb3N0IG9mIHRoZSBjb2RlIGlzIHRoYW5rcyB0b1xuLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjk5NzE4OTgvaG93LXRvLWNyZWF0ZS1hbi1hY2N1cmF0ZS10aW1lci1pbi1qYXZhc2NyaXB0XG5cbmltcG9ydCBDb25maWcgZnJvbSAnLi4vLi4vaGVscGVycy9jb25maWcnO1xuaW1wb3J0IHsgTW9ua2V5VHlwZXMgfSBmcm9tICcuLi8uLi90eXBlcy90eXBlcyc7XG5pbXBvcnQgKiBhcyBNaXNjIGZyb20gJy4uLy4uL3V0aWxzL21pc2MnO1xuaW1wb3J0ICogYXMgVGltZXJFdmVudCBmcm9tICcuLi9vYnNlcnZhYmxlcy90aW1lci1ldmVudCc7XG5pbXBvcnQgKiBhcyBTbG93VGltZXIgZnJvbSAnLi4vc3RhdGVzL3Nsb3ctdGltZXInO1xuaW1wb3J0ICogYXMgVGVzdEFjdGl2ZSBmcm9tICcuLi9zdGF0ZXMvdGVzdC1hY3RpdmUnO1xuaW1wb3J0ICogYXMgVGltZSBmcm9tICcuLi9zdGF0ZXMvdGltZSc7XG5pbXBvcnQgKiBhcyBDYXJldCBmcm9tICcuL2NhcmV0JztcbmltcG9ydCAqIGFzIEN1c3RvbVRleHQgZnJvbSAnLi9jdXN0b20tdGV4dCc7XG5pbXBvcnQgKiBhcyBUZXN0SW5wdXQgZnJvbSAnLi90ZXN0LWlucHV0JztcbmltcG9ydCAqIGFzIFRlc3RTdGF0cyBmcm9tICcuL3Rlc3Qtc3RhdHMnO1xuaW1wb3J0ICogYXMgVGVzdFdvcmRzIGZyb20gJy4vdGVzdC13b3Jkcyc7XG5pbXBvcnQgKiBhcyBUaW1lclByb2dyZXNzIGZyb20gJy4vdGltZXItcHJvZ3Jlc3MnO1xubGV0IHNsb3dUaW1lckNvdW50ID0gMDtcbmxldCB0aW1lcjogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcbmNvbnN0IGludGVydmFsID0gMTAwMDtcbmxldCBleHBlY3RlZCA9IDA7XG5cbmxldCB0aW1lckRlYnVnID0gZmFsc2U7XG5leHBvcnQgZnVuY3Rpb24gZW5hYmxlVGltZXJEZWJ1ZygpOiB2b2lkIHtcbiAgdGltZXJEZWJ1ZyA9IHRydWU7XG59XG5cbmxldCBjaGVja0lmVGltZUlzVXBEaXNhYmxlZCA9IGZhbHNlO1xuZXhwb3J0IGZ1bmN0aW9uIGRpc2FibGVDaGVja0lmVGltZUlzVXAoKTogdm9pZCB7XG4gIGNoZWNrSWZUaW1lSXNVcERpc2FibGVkID0gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyKCk6IHZvaWQge1xuICBUaW1lLnNldCgwKTtcbiAgaWYgKHRpbWVyICE9PSBudWxsKSBjbGVhclRpbWVvdXQodGltZXIpO1xufVxuXG5mdW5jdGlvbiBwcmVtaWQoKTogdm9pZCB7XG4gIGlmICh0aW1lckRlYnVnKSBjb25zb2xlLnRpbWUoJ3ByZW1pZCcpO1xuICBjb25zdCBwcmVtaWRTZWNvbmRzTGVmdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNwcmVtaWRTZWNvbmRzTGVmdCcpO1xuXG4gIGlmIChwcmVtaWRTZWNvbmRzTGVmdCAhPT0gbnVsbCkge1xuICAgIHByZW1pZFNlY29uZHNMZWZ0LmlubmVySFRNTCA9IChDb25maWcudGltZSAtIFRpbWUuZ2V0KCkpLnRvU3RyaW5nKCk7XG4gIH1cbiAgaWYgKHRpbWVyRGVidWcpIGNvbnNvbGUudGltZUVuZCgncHJlbWlkJyk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVRpbWVyKCk6IHZvaWQge1xuICBpZiAodGltZXJEZWJ1ZykgY29uc29sZS50aW1lKCd0aW1lciBwcm9ncmVzcyB1cGRhdGUnKTtcbiAgaWYgKENvbmZpZy5tb2RlID09PSAndGltZScgfHwgKENvbmZpZy5tb2RlID09PSAnY3VzdG9tJyAmJiBDdXN0b21UZXh0LmlzVGltZVJhbmRvbSkpIHtcbiAgICBUaW1lclByb2dyZXNzLnVwZGF0ZSgpO1xuICB9XG4gIGlmICh0aW1lckRlYnVnKSBjb25zb2xlLnRpbWVFbmQoJ3RpbWVyIHByb2dyZXNzIHVwZGF0ZScpO1xufVxuXG5mdW5jdGlvbiBjYWxjdWxhdGVXcG1SYXcoKTogTW9ua2V5VHlwZXMuV29yZHNQZXJNaW51dGVBbmRSYXcge1xuICBpZiAodGltZXJEZWJ1ZykgY29uc29sZS50aW1lKCdjYWxjdWxhdGUgd3BtIGFuZCByYXcnKTtcbiAgY29uc3Qgd3BtQW5kUmF3ID0gVGVzdFN0YXRzLmNhbGN1bGF0ZVdwbUFuZFJhdygpO1xuICBpZiAodGltZXJEZWJ1ZykgY29uc29sZS50aW1lRW5kKCdjYWxjdWxhdGUgd3BtIGFuZCByYXcnKTtcbiAgaWYgKHRpbWVyRGVidWcpIGNvbnNvbGUudGltZSgncHVzaCB0byBoaXN0b3J5Jyk7XG4gIFRlc3RJbnB1dC5wdXNoVG9XcG1IaXN0b3J5KHdwbUFuZFJhdy53cG0pO1xuICBUZXN0SW5wdXQucHVzaFRvUmF3SGlzdG9yeSh3cG1BbmRSYXcucmF3KTtcbiAgaWYgKHRpbWVyRGVidWcpIGNvbnNvbGUudGltZUVuZCgncHVzaCB0byBoaXN0b3J5Jyk7XG4gIHJldHVybiB3cG1BbmRSYXc7XG59XG5cbmZ1bmN0aW9uIG1vbmtleSh3cG1BbmRSYXc6IE1vbmtleVR5cGVzLldvcmRzUGVyTWludXRlQW5kUmF3KTogdm9pZCB7XG4gIGlmICh0aW1lckRlYnVnKSBjb25zb2xlLnRpbWUoJ3VwZGF0ZSBtb25rZXknKTtcbiAgY29uc3QgbnVtID0gQ29uZmlnLmJsaW5kTW9kZSA/IHdwbUFuZFJhdy5yYXcgOiB3cG1BbmRSYXcud3BtO1xuICBpZiAodGltZXJEZWJ1ZykgY29uc29sZS50aW1lRW5kKCd1cGRhdGUgbW9ua2V5Jyk7XG59XG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZUFjYygpOiBudW1iZXIge1xuICBpZiAodGltZXJEZWJ1ZykgY29uc29sZS50aW1lKCdjYWxjdWxhdGUgYWNjJyk7XG4gIGNvbnN0IGFjYyA9IE1pc2Mucm91bmRUbzIoVGVzdFN0YXRzLmNhbGN1bGF0ZUFjY3VyYWN5KCkpO1xuICBpZiAodGltZXJEZWJ1ZykgY29uc29sZS50aW1lRW5kKCdjYWxjdWxhdGUgYWNjJyk7XG4gIHJldHVybiBhY2M7XG59XG5cbmZ1bmN0aW9uIGxheW91dGZsdWlkKCk6IHZvaWQge1xuICBpZiAodGltZXJEZWJ1ZykgY29uc29sZS50aW1lKCdsYXlvdXRmbHVpZCcpO1xuICBpZiAoQ29uZmlnLmZ1bmJveCA9PT0gJ2xheW91dGZsdWlkJyAmJiBDb25maWcubW9kZSA9PT0gJ3RpbWUnKSB7XG4gICAgY29uc3QgbGF5b3V0cyA9IENvbmZpZy5jdXN0b21MYXlvdXRmbHVpZFxuICAgICAgPyBDb25maWcuY3VzdG9tTGF5b3V0Zmx1aWQuc3BsaXQoJyMnKVxuICAgICAgOiBbJ3F3ZXJ0eScsICdkdm9yYWsnLCAnY29sZW1hayddO1xuICAgIGNvbnN0IHN3aXRjaFRpbWUgPSBDb25maWcudGltZSAvIGxheW91dHMubGVuZ3RoO1xuICAgIGNvbnN0IHRpbWUgPSBUaW1lLmdldCgpO1xuICAgIGNvbnN0IGluZGV4ID0gTWF0aC5mbG9vcih0aW1lIC8gc3dpdGNoVGltZSk7XG4gICAgY29uc3QgbGF5b3V0ID0gbGF5b3V0c1tpbmRleF07XG4gICAgY29uc3QgZmxvb3JlZFN3aXRjaFRpbWVzID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IGxheW91dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGZsb29yZWRTd2l0Y2hUaW1lcy5wdXNoKE1hdGguZmxvb3Ioc3dpdGNoVGltZSAqIGkpKTtcbiAgICB9XG4gIH1cbiAgaWYgKHRpbWVyRGVidWcpIGNvbnNvbGUudGltZUVuZCgnbGF5b3V0Zmx1aWQnKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tJZkZhaWxlZCh3cG1BbmRSYXc6IE1vbmtleVR5cGVzLldvcmRzUGVyTWludXRlQW5kUmF3LCBhY2M6IG51bWJlcik6IHZvaWQge1xuICBpZiAodGltZXJEZWJ1ZykgY29uc29sZS50aW1lKCdmYWlsIGNvbmRpdGlvbnMnKTtcbiAgVGVzdElucHV0LnB1c2hLZXlwcmVzc2VzVG9IaXN0b3J5KCk7XG4gIGlmIChcbiAgICBDb25maWcubWluV3BtID09PSAnY3VzdG9tJyAmJlxuICAgIHdwbUFuZFJhdy53cG0gPCBDb25maWcubWluV3BtQ3VzdG9tU3BlZWQgJiZcbiAgICBUZXN0V29yZHMud29yZHMuY3VycmVudEluZGV4ID4gM1xuICApIHtcbiAgICBpZiAodGltZXIgIT09IG51bGwpIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgU2xvd1RpbWVyLmNsZWFyKCk7XG4gICAgc2xvd1RpbWVyQ291bnQgPSAwO1xuICAgIFRpbWVyRXZlbnQuZGlzcGF0Y2goJ2ZhaWwnLCAnbWluIHdwbScpO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoQ29uZmlnLm1pbkFjYyA9PT0gJ2N1c3RvbScgJiYgYWNjIDwgQ29uZmlnLm1pbkFjY0N1c3RvbSkge1xuICAgIGlmICh0aW1lciAhPT0gbnVsbCkgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICBTbG93VGltZXIuY2xlYXIoKTtcbiAgICBzbG93VGltZXJDb3VudCA9IDA7XG4gICAgVGltZXJFdmVudC5kaXNwYXRjaCgnZmFpbCcsICdtaW4gYWNjdXJhY3knKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHRpbWVyRGVidWcpIGNvbnNvbGUudGltZUVuZCgnZmFpbCBjb25kaXRpb25zJyk7XG59XG5cbmZ1bmN0aW9uIGNoZWNrSWZUaW1lSXNVcCgpOiB2b2lkIHtcbiAgaWYgKHRpbWVyRGVidWcpIGNvbnNvbGUudGltZSgndGltZXMgdXAgY2hlY2snKTtcbiAgaWYgKENvbmZpZy5tb2RlID09ICd0aW1lJyB8fCAoQ29uZmlnLm1vZGUgPT09ICdjdXN0b20nICYmIEN1c3RvbVRleHQuaXNUaW1lUmFuZG9tKSkge1xuICAgIGlmIChcbiAgICAgIChUaW1lLmdldCgpID49IENvbmZpZy50aW1lICYmIENvbmZpZy50aW1lICE9PSAwICYmIENvbmZpZy5tb2RlID09PSAndGltZScpIHx8XG4gICAgICAoVGltZS5nZXQoKSA+PSBDdXN0b21UZXh0LnRpbWUgJiYgQ3VzdG9tVGV4dC50aW1lICE9PSAwICYmIENvbmZpZy5tb2RlID09PSAnY3VzdG9tJylcbiAgICApIHtcbiAgICAgIC8vdGltZXMgdXBcbiAgICAgIGlmICh0aW1lciAhPT0gbnVsbCkgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIENhcmV0LmhpZGUoKTtcbiAgICAgIFRlc3RJbnB1dC5pbnB1dC5wdXNoSGlzdG9yeSgpO1xuICAgICAgVGVzdElucHV0LmNvcnJlY3RlZC5wdXNoSGlzdG9yeSgpO1xuICAgICAgU2xvd1RpbWVyLmNsZWFyKCk7XG4gICAgICBzbG93VGltZXJDb3VudCA9IDA7XG4gICAgICBUaW1lckV2ZW50LmRpc3BhdGNoKCdmaW5pc2gnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cbiAgaWYgKHRpbWVyRGVidWcpIGNvbnNvbGUudGltZUVuZCgndGltZXMgdXAgY2hlY2snKTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmxldCB0aW1lclN0YXRzOiBNb25rZXlUeXBlcy5UaW1lclN0YXRzW10gPSBbXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpbWVyU3RhdHMoKTogTW9ua2V5VHlwZXMuVGltZXJTdGF0c1tdIHtcbiAgcmV0dXJuIHRpbWVyU3RhdHM7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRpbWVyU3RlcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKHRpbWVyRGVidWcpIGNvbnNvbGUudGltZSgndGltZXIgc3RlcCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpO1xuICBUaW1lLmluY3JlbWVudCgpO1xuICBwcmVtaWQoKTtcbiAgdXBkYXRlVGltZXIoKTtcbiAgY29uc3Qgd3BtQW5kUmF3ID0gY2FsY3VsYXRlV3BtUmF3KCk7XG4gIGNvbnN0IGFjYyA9IGNhbGN1bGF0ZUFjYygpO1xuICBtb25rZXkod3BtQW5kUmF3KTtcbiAgbGF5b3V0Zmx1aWQoKTtcbiAgY2hlY2tJZkZhaWxlZCh3cG1BbmRSYXcsIGFjYyk7XG4gIGlmICghY2hlY2tJZlRpbWVJc1VwRGlzYWJsZWQpIHtcbiAgICBjaGVja0lmVGltZUlzVXAoKTtcbiAgfVxuICBpZiAodGltZXJEZWJ1ZykgY29uc29sZS50aW1lRW5kKCd0aW1lciBzdGVwIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgU2xvd1RpbWVyLmNsZWFyKCk7XG4gIHNsb3dUaW1lckNvdW50ID0gMDtcbiAgdGltZXJTdGF0cyA9IFtdO1xuICBleHBlY3RlZCA9IFRlc3RTdGF0cy5zdGFydCArIGludGVydmFsO1xuICAoZnVuY3Rpb24gbG9vcCgpOiB2b2lkIHtcbiAgICBjb25zdCBkZWxheSA9IGV4cGVjdGVkIC0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgdGltZXJTdGF0cy5wdXNoKHtcbiAgICAgIGRhdGVOb3c6IERhdGUubm93KCksXG4gICAgICBub3c6IHBlcmZvcm1hbmNlLm5vdygpLFxuICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgICAgbmV4dERlbGF5OiBkZWxheSxcbiAgICB9KTtcbiAgICBpZiAoXG4gICAgICAoQ29uZmlnLm1vZGUgPT09ICd0aW1lJyAmJiBDb25maWcudGltZSA8IDEzMCAmJiBDb25maWcudGltZSA+IDApIHx8XG4gICAgICAoQ29uZmlnLm1vZGUgPT09ICd3b3JkcycgJiYgQ29uZmlnLndvcmRzIDwgMjUwICYmIENvbmZpZy53b3JkcyA+IDApXG4gICAgKSB7XG4gICAgICBpZiAoZGVsYXkgPCBpbnRlcnZhbCAvIDIpIHtcbiAgICAgICAgLy9zbG93IHRpbWVyXG4gICAgICAgIFNsb3dUaW1lci5zZXQoKTtcbiAgICAgIH1cbiAgICAgIGlmIChkZWxheSA8IGludGVydmFsIC8gMTApIHtcbiAgICAgICAgc2xvd1RpbWVyQ291bnQrKztcbiAgICAgICAgaWYgKHNsb3dUaW1lckNvdW50ID4gNSkge1xuICAgICAgICAgIFRpbWVyRXZlbnQuZGlzcGF0Y2goJ2ZhaWwnLCAnc2xvdyB0aW1lcicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIVRlc3RBY3RpdmUuZ2V0KCkpIHtcbiAgICAgICAgaWYgKHRpbWVyICE9PSBudWxsKSBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICBTbG93VGltZXIuY2xlYXIoKTtcbiAgICAgICAgc2xvd1RpbWVyQ291bnQgPSAwO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRpbWVyU3RlcCgpO1xuXG4gICAgICBleHBlY3RlZCArPSBpbnRlcnZhbDtcbiAgICAgIGxvb3AoKTtcbiAgICB9LCBkZWxheSk7XG4gIH0pKCk7XG59XG4iXX0=
|