This commit is contained in:
BuildTools 2021-03-27 18:39:55 +00:00
commit 9d1acdde28
28 changed files with 625 additions and 686 deletions

View file

@ -104,7 +104,6 @@ const refactoredSrc = [
"./src/js/chart-controller.js",
"./src/js/theme-controller.js",
"./src/js/test/caret.js",
"./src/js/word-filter.js",
"./src/js/custom-text-popup.js",
"./src/js/manual-restart-tracker.js",
"./src/js/config.js",

View file

@ -622,14 +622,6 @@ export let miniResult = new Chart($(".pageAccount #miniResultChart"), {
},
});
Chart.prototype.updateColors = function () {
updateColors(this);
};
export function setDefaultFontFamily(font) {
Chart.defaults.global.defaultFontFamily = font.replace(/_/g, " ");
}
export function updateColors(chart) {
if (ThemeColors.main == "") {
ThemeColors.update();
@ -689,6 +681,14 @@ export function updateColors(chart) {
chart.update();
}
Chart.prototype.updateColors = function () {
updateColors(this);
};
export function setDefaultFontFamily(font) {
Chart.defaults.global.defaultFontFamily = font.replace(/_/g, " ");
}
export function updateAllChartColors() {
ThemeColors.update();
accountHistory.updateColors();

View file

@ -114,42 +114,15 @@ let defaultConfig = {
oppositeShiftMode: "off",
};
let config = {
...defaultConfig,
};
export function reset() {
config = {
...defaultConfig,
};
apply();
saveToCookie();
}
function isConfigKeyValid(name) {
if (name === null || name === undefined || name === "") return false;
if (name.length > 30) return false;
return /^[0-9a-zA-Z_.\-#+]+$/.test(name);
}
export function loadFromCookie() {
console.log("loading cookie config");
// let newConfig = $.cookie("config");
let newConfig = Misc.getCookie("config");
if (newConfig !== undefined && newConfig !== "") {
try {
newConfig = JSON.parse(newConfig);
} catch (e) {
newConfig = {};
}
apply(newConfig);
console.log("applying cookie config");
cookieConfig = newConfig;
saveToCookie(true);
console.log("saving cookie config");
}
TestLogic.restart(false, true);
}
let config = {
...defaultConfig,
};
export async function saveToCookie(noDbCheck = false) {
if (!dbConfigLoaded && !noDbCheck) {
@ -168,6 +141,134 @@ export async function saveToCookie(noDbCheck = false) {
if (!noDbCheck) await DB.saveConfig(save);
}
//numbers
export function setNumbers(numb, nosave) {
if (config.mode === "quote") {
numb = false;
}
config.numbers = numb;
if (!config.numbers) {
$("#top .config .numbersMode .text-button").removeClass("active");
} else {
$("#top .config .numbersMode .text-button").addClass("active");
}
if (!nosave) saveToCookie();
}
export function toggleNumbers() {
config.numbers = !config.numbers;
if (config.mode === "quote") {
config.numbers = false;
}
if (config.numbers) {
$("#top .config .numbersMode .text-button").addClass("active");
} else {
$("#top .config .numbersMode .text-button").removeClass("active");
}
saveToCookie();
}
//punctuation
export function setPunctuation(punc, nosave) {
if (config.mode === "quote") {
punc = false;
}
config.punctuation = punc;
if (!config.punctuation) {
$("#top .config .punctuationMode .text-button").removeClass("active");
} else {
$("#top .config .punctuationMode .text-button").addClass("active");
}
if (!nosave) saveToCookie();
}
export function togglePunctuation() {
config.punctuation = !config.punctuation;
if (config.mode === "quote") {
config.punctuation = false;
}
if (config.punctuation) {
$("#top .config .punctuationMode .text-button").addClass("active");
} else {
$("#top .config .punctuationMode .text-button").removeClass("active");
}
saveToCookie();
}
export function setMode(mode, nosave) {
if (TestUI.testRestarting) return;
if (mode !== "words" && Funbox.active === "memory") {
Notifications.add("Memory funbox can only be used with words mode.", 0);
return;
}
config.mode = mode;
$("#top .config .mode .text-button").removeClass("active");
$("#top .config .mode .text-button[mode='" + mode + "']").addClass("active");
if (config.mode == "time") {
$("#top .config .wordCount").addClass("hidden");
$("#top .config .time").removeClass("hidden");
$("#top .config .customText").addClass("hidden");
$("#top .config .punctuationMode").removeClass("disabled");
$("#top .config .numbersMode").removeClass("disabled");
$("#top .config .punctuationMode").removeClass("hidden");
$("#top .config .numbersMode").removeClass("hidden");
$("#top .config .quoteLength").addClass("hidden");
} else if (config.mode == "words") {
$("#top .config .wordCount").removeClass("hidden");
$("#top .config .time").addClass("hidden");
$("#top .config .customText").addClass("hidden");
$("#top .config .punctuationMode").removeClass("disabled");
$("#top .config .numbersMode").removeClass("disabled");
$("#top .config .punctuationMode").removeClass("hidden");
$("#top .config .numbersMode").removeClass("hidden");
$("#top .config .quoteLength").addClass("hidden");
} else if (config.mode == "custom") {
if (
Funbox.active === "58008" ||
Funbox.active === "gibberish" ||
Funbox.active === "ascii"
) {
Funbox.setAcitve("none");
TestUI.updateModesNotice();
}
$("#top .config .wordCount").addClass("hidden");
$("#top .config .time").addClass("hidden");
$("#top .config .customText").removeClass("hidden");
$("#top .config .punctuationMode").removeClass("disabled");
$("#top .config .numbersMode").removeClass("disabled");
$("#top .config .punctuationMode").removeClass("hidden");
$("#top .config .numbersMode").removeClass("hidden");
$("#top .config .quoteLength").addClass("hidden");
setPunctuation(false, true);
setNumbers(false, true);
} else if (config.mode == "quote") {
setPunctuation(false, nosave);
setNumbers(false, nosave);
$("#top .config .wordCount").addClass("hidden");
$("#top .config .time").addClass("hidden");
$("#top .config .customText").addClass("hidden");
$("#top .config .punctuationMode").addClass("disabled");
$("#top .config .numbersMode").addClass("disabled");
$("#top .config .punctuationMode").removeClass("hidden");
$("#top .config .numbersMode").removeClass("hidden");
$("#result .stats .source").removeClass("hidden");
$("#top .config .quoteLength").removeClass("hidden");
} else if (config.mode == "zen") {
$("#top .config .wordCount").addClass("hidden");
$("#top .config .time").addClass("hidden");
$("#top .config .customText").addClass("hidden");
$("#top .config .punctuationMode").addClass("hidden");
$("#top .config .numbersMode").addClass("hidden");
$("#top .config .quoteLength").addClass("hidden");
if (config.paceCaret != "off") {
Notifications.add(`Pace caret will not work with zen mode.`, 0);
}
// setPaceCaret("off", true);
}
if (!nosave) saveToCookie();
}
export function setPlaySoundOnError(val, nosave) {
if (val == undefined) {
val = false;
@ -954,60 +1055,6 @@ export function toggleQuickTabMode() {
console.log(config.quickTab);
}
//numbers
export function setNumbers(numb, nosave) {
if (config.mode === "quote") {
numb = false;
}
config.numbers = numb;
if (!config.numbers) {
$("#top .config .numbersMode .text-button").removeClass("active");
} else {
$("#top .config .numbersMode .text-button").addClass("active");
}
if (!nosave) saveToCookie();
}
export function toggleNumbers() {
config.numbers = !config.numbers;
if (config.mode === "quote") {
config.numbers = false;
}
if (config.numbers) {
$("#top .config .numbersMode .text-button").addClass("active");
} else {
$("#top .config .numbersMode .text-button").removeClass("active");
}
saveToCookie();
}
//punctuation
export function setPunctuation(punc, nosave) {
if (config.mode === "quote") {
punc = false;
}
config.punctuation = punc;
if (!config.punctuation) {
$("#top .config .punctuationMode .text-button").removeClass("active");
} else {
$("#top .config .punctuationMode .text-button").addClass("active");
}
if (!nosave) saveToCookie();
}
export function togglePunctuation() {
config.punctuation = !config.punctuation;
if (config.mode === "quote") {
config.punctuation = false;
}
if (config.punctuation) {
$("#top .config .punctuationMode .text-button").addClass("active");
} else {
$("#top .config .punctuationMode .text-button").removeClass("active");
}
saveToCookie();
}
export function previewFontFamily(font) {
if (font == undefined) {
font = "Roboto_Mono";
@ -1098,6 +1145,11 @@ export function setIndicateTypos(it, nosave) {
if (!nosave) saveToCookie();
}
export function setCustomTheme(boolean, nosave) {
if (boolean !== undefined) config.customTheme = boolean;
if (!nosave) saveToCookie();
}
export function setTheme(name, nosave) {
config.theme = name;
setCustomTheme(false, true);
@ -1116,11 +1168,6 @@ export function setRandomTheme(val, nosave) {
if (!nosave) saveToCookie();
}
export function setCustomTheme(boolean, nosave) {
if (boolean !== undefined) config.customTheme = boolean;
if (!nosave) saveToCookie();
}
export function toggleCustomTheme(nosave) {
if (config.customTheme) {
setCustomTheme(false);
@ -1135,7 +1182,6 @@ export function toggleCustomTheme(nosave) {
export function setCustomThemeColors(colors, nosave) {
if (colors !== undefined) {
config.customThemeColors = colors;
ThemeController.setCustomColors(colors);
// ThemeController.set("custom");
// applyCustomThemeColors();
}
@ -1192,26 +1238,6 @@ export function toggleCapsLockBackspace() {
setCapsLockBackspace(!config.capsLockBackspace, false);
}
export function setLayout(layout, nosave) {
if (layout == null || layout == undefined) {
layout = "qwerty";
}
config.layout = layout;
TestUI.updateModesNotice();
if (config.keymapLayout === "overrideSync") {
Keymap.refreshKeys(config.keymapLayout, setKeymapLayout);
}
if (!nosave) saveToCookie();
}
export function setSavedLayout(layout, nosave) {
if (layout == null || layout == undefined) {
layout = "qwerty";
}
config.savedLayout = layout;
setLayout(layout, nosave);
}
export function setKeymapMode(mode, nosave) {
if (mode == null || mode == undefined) {
mode = "off";
@ -1252,6 +1278,26 @@ export function setKeymapLayout(layout, nosave) {
if (!nosave) saveToCookie();
}
export function setLayout(layout, nosave) {
if (layout == null || layout == undefined) {
layout = "qwerty";
}
config.layout = layout;
TestUI.updateModesNotice();
if (config.keymapLayout === "overrideSync") {
Keymap.refreshKeys(config.keymapLayout, setKeymapLayout);
}
if (!nosave) saveToCookie();
}
export function setSavedLayout(layout, nosave) {
if (layout == null || layout == undefined) {
layout = "qwerty";
}
config.savedLayout = layout;
setLayout(layout, nosave);
}
export function setFontSize(fontSize, nosave) {
if (fontSize == null || fontSize == undefined) {
fontSize = 1;
@ -1291,80 +1337,6 @@ export function setFontSize(fontSize, nosave) {
if (!nosave) saveToCookie();
}
export function setMode(mode, nosave) {
if (TestUI.testRestarting) return;
if (mode !== "words" && Funbox.active === "memory") {
Notifications.add("Memory funbox can only be used with words mode.", 0);
return;
}
config.mode = mode;
$("#top .config .mode .text-button").removeClass("active");
$("#top .config .mode .text-button[mode='" + mode + "']").addClass("active");
if (config.mode == "time") {
$("#top .config .wordCount").addClass("hidden");
$("#top .config .time").removeClass("hidden");
$("#top .config .customText").addClass("hidden");
$("#top .config .punctuationMode").removeClass("disabled");
$("#top .config .numbersMode").removeClass("disabled");
$("#top .config .punctuationMode").removeClass("hidden");
$("#top .config .numbersMode").removeClass("hidden");
$("#top .config .quoteLength").addClass("hidden");
} else if (config.mode == "words") {
$("#top .config .wordCount").removeClass("hidden");
$("#top .config .time").addClass("hidden");
$("#top .config .customText").addClass("hidden");
$("#top .config .punctuationMode").removeClass("disabled");
$("#top .config .numbersMode").removeClass("disabled");
$("#top .config .punctuationMode").removeClass("hidden");
$("#top .config .numbersMode").removeClass("hidden");
$("#top .config .quoteLength").addClass("hidden");
} else if (config.mode == "custom") {
if (
Funbox.active === "58008" ||
Funbox.active === "gibberish" ||
Funbox.active === "ascii"
) {
Funbox.setAcitve("none");
TestUI.updateModesNotice();
}
$("#top .config .wordCount").addClass("hidden");
$("#top .config .time").addClass("hidden");
$("#top .config .customText").removeClass("hidden");
$("#top .config .punctuationMode").removeClass("disabled");
$("#top .config .numbersMode").removeClass("disabled");
$("#top .config .punctuationMode").removeClass("hidden");
$("#top .config .numbersMode").removeClass("hidden");
$("#top .config .quoteLength").addClass("hidden");
setPunctuation(false, true);
setNumbers(false, true);
} else if (config.mode == "quote") {
setPunctuation(false, nosave);
setNumbers(false, nosave);
$("#top .config .wordCount").addClass("hidden");
$("#top .config .time").addClass("hidden");
$("#top .config .customText").addClass("hidden");
$("#top .config .punctuationMode").addClass("disabled");
$("#top .config .numbersMode").addClass("disabled");
$("#top .config .punctuationMode").removeClass("hidden");
$("#top .config .numbersMode").removeClass("hidden");
$("#result .stats .source").removeClass("hidden");
$("#top .config .quoteLength").removeClass("hidden");
} else if (config.mode == "zen") {
$("#top .config .wordCount").addClass("hidden");
$("#top .config .time").addClass("hidden");
$("#top .config .customText").addClass("hidden");
$("#top .config .punctuationMode").addClass("hidden");
$("#top .config .numbersMode").addClass("hidden");
$("#top .config .quoteLength").addClass("hidden");
if (config.paceCaret != "off") {
Notifications.add(`Pace caret will not work with zen mode.`, 0);
}
// setPaceCaret("off", true);
}
if (!nosave) saveToCookie();
}
export function apply(configObj) {
if (configObj == null || configObj == undefined) {
Notifications.add("Could not apply config", -1, 3);
@ -1625,4 +1597,31 @@ export function apply(configObj) {
TestUI.updateModesNotice();
}
export function reset() {
config = {
...defaultConfig,
};
apply();
saveToCookie();
}
export function loadFromCookie() {
console.log("loading cookie config");
// let newConfig = $.cookie("config");
let newConfig = Misc.getCookie("config");
if (newConfig !== undefined && newConfig !== "") {
try {
newConfig = JSON.parse(newConfig);
} catch (e) {
newConfig = {};
}
apply(newConfig);
console.log("applying cookie config");
cookieConfig = newConfig;
saveToCookie(true);
console.log("saving cookie config");
}
TestLogic.restart(false, true);
}
export default config;

View file

@ -2,7 +2,6 @@ import * as CustomText from "./custom-text";
import * as ManualRestart from "./manual-restart-tracker";
import * as Misc from "./misc";
import * as Notifications from "./notification-center";
import * as WordFilter from "./word-filter";
import * as TestLogic from "./test-logic";
let wrapper = "#customTextPopupWrapper";
@ -82,7 +81,7 @@ $(`${popup} .randomInputFields .time input`).keypress((e) => {
$(`${popup} .randomInputFields .wordcount input`).val("");
});
$("#customTextPopup .apply").click(() => {
$("#customTextPopup .button").click(() => {
let text = $("#customTextPopup textarea").val();
text = text.trim();
// text = text.replace(/[\r]/gm, " ");
@ -155,7 +154,3 @@ $("#customTextPopup .apply").click(() => {
TestLogic.restart();
hide();
});
$("#customTextPopup .wordfilter").click(() => {
WordFilter.showWordFilterPopup();
})

View file

@ -1,5 +1,4 @@
import * as DB from "./db";
import Config, * as UpdateConfig from "./config";
import Config from "./config";
export function showBackgroundLoader() {
$("#backgroundLoader").stop(true, true).fadeIn(125);

View file

@ -10,5 +10,3 @@ global.snapshot = DB.getSnapshot;
global.config = Config;
// global.addnotif = Notifications.add;
global.link = linkWithGoogle;
global.wordFilter = WordFilter;

View file

@ -30,7 +30,6 @@ import * as OutOfFocus from "./out-of-focus";
import * as ChartController from "./chart-controller";
import * as ThemeController from "./theme-controller";
import * as Caret from "./caret";
import * as WordFilter from "./word-filter";
import * as CustomTextPopup from "./custom-text-popup";
import * as ManualRestart from "./manual-restart-tracker";
import Config, * as UpdateConfig from "./config";

View file

@ -4,24 +4,6 @@ import * as Notifications from "./notification-center";
let currentLeaderboard = "time_15";
export function show() {
if ($("#leaderboardsWrapper").hasClass("hidden")) {
$("#leaderboardsWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate(
{
opacity: 1,
},
125,
() => {
update();
}
);
}
}
export function hide() {
$("#leaderboardsWrapper")
.stop(true, true)
@ -268,6 +250,24 @@ function update() {
});
}
export function show() {
if ($("#leaderboardsWrapper").hasClass("hidden")) {
$("#leaderboardsWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate(
{
opacity: 1,
},
125,
() => {
update();
}
);
}
}
$("#leaderboardsWrapper").click((e) => {
if ($(e.target).attr("id") === "leaderboardsWrapper") {
hide();

View file

@ -1,56 +1,11 @@
import * as Misc from "./misc";
import * as Notifications from "./notification-center";
import Config, * as UpdateConfig from "./config";
import Config from "./config";
import * as ManualRestart from "./manual-restart-tracker";
import * as TestLogic from "./test-logic";
export let selectedId = 1;
export async function show() {
if ($("#quoteSearchPopupWrapper").hasClass("hidden")) {
$("#quoteSearchPopup input").val("");
$("#quoteSearchPopupWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate({ opacity: 1 }, 100, (e) => {
$("#quoteSearchPopup input").focus().select();
updateResults("");
});
}
}
export function hide() {
if (!$("#quoteSearchPopupWrapper").hasClass("hidden")) {
$("#quoteSearchPopupWrapper")
.stop(true, true)
.css("opacity", 1)
.animate(
{
opacity: 0,
},
100,
(e) => {
$("#quoteSearchPopupWrapper").addClass("hidden");
}
);
}
}
function apply(val) {
if (isNaN(val)) {
val = document.getElementById("searchBox").value;
}
if (val !== null && !isNaN(val) && val >= 0) {
selectedId = val;
ManualRestart.set();
TestLogic.restart();
} else {
Notifications.add("Quote ID must be at least 1", 0);
}
hide();
}
async function updateResults(searchText) {
let quotes = await Misc.getQuotes(Config.language);
let reg = new RegExp(searchText, "i");
@ -114,6 +69,51 @@ async function updateResults(searchText) {
}
}
export async function show() {
if ($("#quoteSearchPopupWrapper").hasClass("hidden")) {
$("#quoteSearchPopup input").val("");
$("#quoteSearchPopupWrapper")
.stop(true, true)
.css("opacity", 0)
.removeClass("hidden")
.animate({ opacity: 1 }, 100, (e) => {
$("#quoteSearchPopup input").focus().select();
updateResults("");
});
}
}
export function hide() {
if (!$("#quoteSearchPopupWrapper").hasClass("hidden")) {
$("#quoteSearchPopupWrapper")
.stop(true, true)
.css("opacity", 1)
.animate(
{
opacity: 0,
},
100,
(e) => {
$("#quoteSearchPopupWrapper").addClass("hidden");
}
);
}
}
function apply(val) {
if (isNaN(val)) {
val = document.getElementById("searchBox").value;
}
if (val !== null && !isNaN(val) && val >= 0) {
selectedId = val;
ManualRestart.set();
TestLogic.restart();
} else {
Notifications.add("Quote ID must be at least 1", 0);
}
hide();
}
$("#quoteSearchPopup .searchBox").keydown((e) => {
setTimeout(() => {
let searchText = document.getElementById("searchBox").value;

View file

@ -813,8 +813,7 @@ $(document).keydown(function (event) {
let modePopupVisible =
!$("#customTextPopupWrapper").hasClass("hidden") ||
!$("#customMode2PopupWrapper").hasClass("hidden") ||
!$("#quoteSearchPopupWrapper").hasClass("hidden") ||
!$("#wordFilterPopupWrapper").hasClass("hidden");
!$("#quoteSearchPopupWrapper").hasClass("hidden");
if (
pageTestActive &&
!commandLineVisible &&

View file

@ -1,4 +1,4 @@
import Config, * as UpdateConfig from "./config";
import Config from "./config";
let errorSound = new Audio("../sound/error.wav");
let clickSounds = null;

View file

@ -2,20 +2,6 @@ import * as DB from "./db";
import * as TestUI from "./test-ui";
import * as Misc from "./misc";
export function toggle(tagid, nosave = false) {
DB.getSnapshot().tags.forEach((tag) => {
if (tag.id === tagid) {
if (tag.active === undefined) {
tag.active = true;
} else {
tag.active = !tag.active;
}
}
});
TestUI.updateModesNotice();
if (!nosave) saveActiveToCookie();
}
export function saveActiveToCookie() {
let tags = [];
@ -36,6 +22,20 @@ export function saveActiveToCookie() {
} catch (e) {}
}
export function toggle(tagid, nosave = false) {
DB.getSnapshot().tags.forEach((tag) => {
if (tag.id === tagid) {
if (tag.active === undefined) {
tag.active = true;
} else {
tag.active = !tag.active;
}
}
});
TestUI.updateModesNotice();
if (!nosave) saveActiveToCookie();
}
export function loadActiveFromCookie() {
// let newTags = $.cookie("activeTags");
let newTags = Misc.getCookie("activeTags");

View file

@ -1,4 +1,4 @@
import Config, * as UpdateConfig from "./config";
import Config from "./config";
function show() {
if ($("#capsWarning").hasClass("hidden")) {

View file

@ -1,5 +1,5 @@
import * as Misc from "./misc";
import Config, * as UpdateConfig from "./config";
import Config from "./config";
import * as TestLogic from "./test-logic";
export let caretAnimating = true;
@ -12,7 +12,6 @@ export function stopAnimation() {
}
}
//TODO remove config when module
export function startAnimation() {
if (caretAnimating === false) {
if (Config.smoothCaret) {
@ -28,16 +27,6 @@ export function hide() {
$("#caret").addClass("hidden");
}
export function show() {
if ($("#result").hasClass("hidden")) {
updatePosition();
$("#caret").removeClass("hidden");
startAnimation();
}
}
//TODO remove this after test logic is a module
//TODO remove config when module
export function updatePosition() {
if ($("#wordsWrapper").hasClass("hidden")) return;
if ($("#caret").hasClass("off")) {
@ -128,3 +117,11 @@ export function updatePosition() {
console.log("could not move caret: " + e.message);
}
}
export function show() {
if ($("#result").hasClass("hidden")) {
updatePosition();
$("#caret").removeClass("hidden");
startAnimation();
}
}

View file

@ -9,32 +9,6 @@ export let active = "none";
let memoryTimer = null;
let memoryInterval = null;
export function reset() {
active = "none";
resetMemoryTimer();
}
export function startMemoryTimer() {
resetMemoryTimer();
memoryTimer = Math.round(Math.pow(TestLogic.words.length, 1.2));
updateMemoryTimer(memoryTimer);
showMemoryTimer();
memoryInterval = setInterval(() => {
memoryTimer -= 1;
memoryTimer == 0 ? hideMemoryTimer() : updateMemoryTimer(memoryTimer);
if (memoryTimer <= 0) {
resetMemoryTimer();
$("#wordsWrapper").addClass("hidden");
}
}, 1000);
}
export function resetMemoryTimer() {
memoryInterval = clearInterval(memoryInterval);
memoryTimer = null;
hideMemoryTimer();
}
function showMemoryTimer() {
$("#typingTest #memoryTimer").stop(true, true).animate(
{
@ -53,12 +27,38 @@ function hideMemoryTimer() {
);
}
export function resetMemoryTimer() {
memoryInterval = clearInterval(memoryInterval);
memoryTimer = null;
hideMemoryTimer();
}
function updateMemoryTimer(sec) {
$("#typingTest #memoryTimer").text(
`Timer left to memorise all words: ${sec}s`
);
}
export function startMemoryTimer() {
resetMemoryTimer();
memoryTimer = Math.round(Math.pow(TestLogic.words.length, 1.2));
updateMemoryTimer(memoryTimer);
showMemoryTimer();
memoryInterval = setInterval(() => {
memoryTimer -= 1;
memoryTimer == 0 ? hideMemoryTimer() : updateMemoryTimer(memoryTimer);
if (memoryTimer <= 0) {
resetMemoryTimer();
$("#wordsWrapper").addClass("hidden");
}
}, 1000);
}
export function reset() {
active = "none";
resetMemoryTimer();
}
export function toggleScript(...params) {
if (active === "tts") {
var msg = new SpeechSynthesisUtterance();

View file

@ -152,8 +152,7 @@ export function show() {
$(".keymap").removeClass("hidden");
}
//TODO remove setkeymaplayout after userconfig is a module
export function refreshKeys(layout, setKeymapLayout) {
export function refreshKeys(layout) {
try {
let lts = layouts[layout]; //layout to show
let layoutString = layout;
@ -240,6 +239,6 @@ export function refreshKeys(layout, setKeymapLayout) {
console.log(
"something went wrong when changing layout, resettings: " + e.message
);
setKeymapLayout("qwerty", true);
UpdateConfig.setKeymapLayout("qwerty", true);
}
}

View file

@ -1,4 +1,5 @@
import Config, * as UpdateConfig from "./config";
import Config from "./config";
import * as TestLogic from "./test-logic";
export function update(acc) {
let number = Math.floor(acc);
@ -11,7 +12,7 @@ export function update(acc) {
export function show() {
if (!Config.showLiveAcc) return;
// if (!TestLogic.active) return;
if (!TestLogic.active) return;
if (Config.timerStyle === "mini") {
// $("#miniTimerAndLiveWpm .wpm").css("opacity", Config.timerOpacity);
if (!$("#miniTimerAndLiveWpm .acc").hasClass("hidden")) return;

View file

@ -1,4 +1,5 @@
import Config, * as UpdateConfig from "./config";
import Config from "./config";
import * as TestLogic from "./test-logic";
export function update(wpm, raw) {
// if (!TestLogic.active || !Config.showLiveWpm) {
@ -17,9 +18,9 @@ export function update(wpm, raw) {
document.querySelector("#liveWpm").innerHTML = number;
}
//TODO needs to check if test is active
export function show() {
if (!Config.showLiveWpm) return;
if (!TestLogic.active) return;
if (Config.timerStyle === "mini") {
// $("#miniTimerAndLiveWpm .wpm").css("opacity", Config.timerOpacity);
if (!$("#miniTimerAndLiveWpm .wpm").hasClass("hidden")) return;

View file

@ -1,12 +1,30 @@
import * as TestLogic from "./test-logic";
import * as TestUI from "./test-ui";
import Config, * as UpdateConfig from "./config";
import Config from "./config";
import * as DB from "./db";
export let settings = null;
export function start() {
update(performance.now() + settings.spc * 1000);
function resetCaretPosition() {
if (Config.paceCaret === "off") return;
if (!$("#paceCaret").hasClass("hidden")) {
$("#paceCaret").addClass("hidden");
}
if (Config.mode === "zen") return;
let caret = $("#paceCaret");
let firstLetter = document
.querySelector("#words .word")
.querySelector("letter");
caret.stop(true, true).animate(
{
top: firstLetter.offsetTop - $(firstLetter).height() / 4,
left: firstLetter.offsetLeft,
},
0,
"linear"
);
}
export async function init() {
@ -139,14 +157,13 @@ export function update(expectedStepEnd) {
let newIndex =
settings.currentWordIndex -
(TestLogic.words.currentIndex - TestUI.currentWordElementIndex);
let word = document.querySelectorAll("#words .word")[newIndex];
if (settings.currentLetterIndex === -1) {
currentLetter = document
.querySelectorAll("#words .word")
[newIndex].querySelectorAll("letter")[0];
currentLetter = word.querySelectorAll("letter")[0];
} else {
currentLetter = document
.querySelectorAll("#words .word")
[newIndex].querySelectorAll("letter")[settings.currentLetterIndex];
currentLetter = word.querySelectorAll("letter")[
settings.currentLetterIndex
];
}
newTop = currentLetter.offsetTop - $(currentLetter).height() / 5;
newLeft;
@ -202,28 +219,6 @@ export function update(expectedStepEnd) {
}
}
function resetCaretPosition() {
if (Config.paceCaret === "off") return;
if (!$("#paceCaret").hasClass("hidden")) {
$("#paceCaret").addClass("hidden");
}
if (Config.mode === "zen") return;
let caret = $("#paceCaret");
let firstLetter = document
.querySelector("#words .word")
.querySelector("letter");
caret.stop(true, true).animate(
{
top: firstLetter.offsetTop - $(firstLetter).height() / 4,
left: firstLetter.offsetLeft,
},
0,
"linear"
);
}
export function reset() {
settings = null;
if (settings !== null) clearTimeout(settings.timeout);
@ -250,3 +245,7 @@ export function handleSpace(correct, currentWord) {
}
}
}
export function start() {
update(performance.now() + settings.spc * 1000);
}

View file

@ -1,65 +1,11 @@
import * as CloudFunctions from "./cloud-functions";
import * as DB from "./db";
import * as Notifications from "./notification-center";
import Config, * as UpdateConfig from "./config";
import Config from "./config";
import * as Misc from "./misc";
let textTimeouts = [];
export function check(completedEvent) {
try {
if (
completedEvent.funbox === "none" &&
completedEvent.language === "english" &&
completedEvent.mode === "time" &&
["15", "60"].includes(String(completedEvent.mode2))
) {
$("#result .stats .leaderboards").removeClass("hidden");
$("#result .stats .leaderboards .bottom").html(
`checking <i class="fas fa-spin fa-fw fa-circle-notch"></i>`
);
textTimeouts.push(
setTimeout(() => {
$("#result .stats .leaderboards .bottom").html(
`still checking <i class="fas fa-spin fa-fw fa-circle-notch"></i>`
);
}, 5000)
);
textTimeouts.push(
setTimeout(() => {
$("#result .stats .leaderboards .bottom").html(
`leaderboard seems<br>to be very busy <i class="fas fa-spin fa-fw fa-circle-notch"></i>`
);
}, 10000)
);
let lbRes = completedEvent;
delete lbRes.keySpacing;
delete lbRes.keyDuration;
delete lbRes.chartData;
CloudFunctions.checkLeaderboards({
uid: completedEvent.uid,
lbMemory: DB.getSnapshot().lbMemory,
emailVerified: DB.getSnapshot().emailVerified,
name: DB.getSnapshot().name,
banned: DB.getSnapshot().banned,
verified: DB.getSnapshot().verified,
discordId: DB.getSnapshot().discordId,
result: lbRes,
})
.then((data) => {
Misc.clearTimeouts(textTimeouts);
show(data.data, completedEvent.mode2);
})
.catch((e) => {
$("#result .stats .leaderboards").addClass("hidden");
Notifications.add(e, -1);
});
}
} catch (e) {
Notifications.add(`Error while checking leaderboards: ${e}`, -1);
}
}
export function show(data, mode2) {
let string = "";
if (data.needsToVerifyEmail === true) {
@ -183,3 +129,57 @@ export function show(data, mode2) {
$("#result .stats .leaderboards").removeClass("hidden");
$("#result .stats .leaderboards .bottom").html(string);
}
export function check(completedEvent) {
try {
if (
completedEvent.funbox === "none" &&
completedEvent.language === "english" &&
completedEvent.mode === "time" &&
["15", "60"].includes(String(completedEvent.mode2))
) {
$("#result .stats .leaderboards").removeClass("hidden");
$("#result .stats .leaderboards .bottom").html(
`checking <i class="fas fa-spin fa-fw fa-circle-notch"></i>`
);
textTimeouts.push(
setTimeout(() => {
$("#result .stats .leaderboards .bottom").html(
`still checking <i class="fas fa-spin fa-fw fa-circle-notch"></i>`
);
}, 5000)
);
textTimeouts.push(
setTimeout(() => {
$("#result .stats .leaderboards .bottom").html(
`leaderboard seems<br>to be very busy <i class="fas fa-spin fa-fw fa-circle-notch"></i>`
);
}, 10000)
);
let lbRes = completedEvent;
delete lbRes.keySpacing;
delete lbRes.keyDuration;
delete lbRes.chartData;
CloudFunctions.checkLeaderboards({
uid: completedEvent.uid,
lbMemory: DB.getSnapshot().lbMemory,
emailVerified: DB.getSnapshot().emailVerified,
name: DB.getSnapshot().name,
banned: DB.getSnapshot().banned,
verified: DB.getSnapshot().verified,
discordId: DB.getSnapshot().discordId,
result: lbRes,
})
.then((data) => {
Misc.clearTimeouts(textTimeouts);
show(data.data, completedEvent.mode2);
})
.catch((e) => {
$("#result .stats .leaderboards").addClass("hidden");
Notifications.add(e, -1);
});
}
} catch (e) {
Notifications.add(`Error while checking leaderboards: ${e}`, -1);
}
}

View file

@ -188,6 +188,108 @@ export function setRandomQuote(rq) {
randomQuote = rq;
}
export function punctuateWord(previousWord, currentWord, index, maxindex) {
let word = currentWord;
if (
(index == 0 ||
Misc.getLastChar(previousWord) == "." ||
Misc.getLastChar(previousWord) == "?" ||
Misc.getLastChar(previousWord) == "!") &&
UpdateConfig.language.split("_")[0] != "code"
) {
//always capitalise the first word or if there was a dot unless using a code alphabet
word = Misc.capitalizeFirstLetter(word);
} else if (
(Math.random() < 0.1 &&
Misc.getLastChar(previousWord) != "." &&
Misc.getLastChar(previousWord) != "," &&
index != maxindex - 2) ||
index == maxindex - 1
) {
let rand = Math.random();
if (rand <= 0.8) {
word += ".";
} else if (rand > 0.8 && rand < 0.9) {
if (Config.language.split("_")[0] == "french") {
word = "?";
} else {
word += "?";
}
} else {
if (Config.language.split("_")[0] == "french") {
word = "!";
} else {
word += "!";
}
}
} else if (
Math.random() < 0.01 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "." &&
UpdateConfig.language.split("_")[0] !== "russian"
) {
word = `"${word}"`;
} else if (
Math.random() < 0.011 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "." &&
UpdateConfig.language.split("_")[0] !== "russian"
) {
word = `'${word}'`;
} else if (
Math.random() < 0.012 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "."
) {
if (Config.language.split("_")[0] == "code") {
let r = Math.random();
if (r < 0.25) {
word = `(${word})`;
} else if (r < 0.5) {
word = `{${word}}`;
} else if (r < 0.75) {
word = `[${word}]`;
} else {
word = `<${word}>`;
}
} else {
word = `(${word})`;
}
} else if (Math.random() < 0.013) {
if (Config.language.split("_")[0] == "french") {
word = ":";
} else {
word += ":";
}
} else if (
Math.random() < 0.014 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "." &&
previousWord != "-"
) {
word = "-";
} else if (
Math.random() < 0.015 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "." &&
Misc.getLastChar(previousWord) != ";"
) {
if (Config.language.split("_")[0] == "french") {
word = ";";
} else {
word += ";";
}
} else if (Math.random() < 0.2 && Misc.getLastChar(previousWord) != ",") {
word += ",";
} else if (Math.random() < 0.25 && Config.language.split("_")[0] == "code") {
let specials = ["{", "}", "[", "]", "(", ")", ";", "=", "%", "/"];
word = specials[Math.floor(Math.random() * 10)];
}
return word;
}
export async function init() {
setActive(false);
words.reset();
@ -566,108 +668,6 @@ export function addWord() {
$("#words").append(w);
}
export function punctuateWord(previousWord, currentWord, index, maxindex) {
let word = currentWord;
if (
(index == 0 ||
Misc.getLastChar(previousWord) == "." ||
Misc.getLastChar(previousWord) == "?" ||
Misc.getLastChar(previousWord) == "!") &&
UpdateConfig.language.split("_")[0] != "code"
) {
//always capitalise the first word or if there was a dot unless using a code alphabet
word = Misc.capitalizeFirstLetter(word);
} else if (
(Math.random() < 0.1 &&
Misc.getLastChar(previousWord) != "." &&
Misc.getLastChar(previousWord) != "," &&
index != maxindex - 2) ||
index == maxindex - 1
) {
let rand = Math.random();
if (rand <= 0.8) {
word += ".";
} else if (rand > 0.8 && rand < 0.9) {
if (Config.language.split("_")[0] == "french") {
word = "?";
} else {
word += "?";
}
} else {
if (Config.language.split("_")[0] == "french") {
word = "!";
} else {
word += "!";
}
}
} else if (
Math.random() < 0.01 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "." &&
UpdateConfig.language.split("_")[0] !== "russian"
) {
word = `"${word}"`;
} else if (
Math.random() < 0.011 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "." &&
UpdateConfig.language.split("_")[0] !== "russian"
) {
word = `'${word}'`;
} else if (
Math.random() < 0.012 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "."
) {
if (Config.language.split("_")[0] == "code") {
let r = Math.random();
if (r < 0.25) {
word = `(${word})`;
} else if (r < 0.5) {
word = `{${word}}`;
} else if (r < 0.75) {
word = `[${word}]`;
} else {
word = `<${word}>`;
}
} else {
word = `(${word})`;
}
} else if (Math.random() < 0.013) {
if (Config.language.split("_")[0] == "french") {
word = ":";
} else {
word += ":";
}
} else if (
Math.random() < 0.014 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "." &&
previousWord != "-"
) {
word = "-";
} else if (
Math.random() < 0.015 &&
Misc.getLastChar(previousWord) != "," &&
Misc.getLastChar(previousWord) != "." &&
Misc.getLastChar(previousWord) != ";"
) {
if (Config.language.split("_")[0] == "french") {
word = ";";
} else {
word += ";";
}
} else if (Math.random() < 0.2 && Misc.getLastChar(previousWord) != ",") {
word += ",";
} else if (Math.random() < 0.25 && Config.language.split("_")[0] == "code") {
let specials = ["{", "}", "[", "]", "(", ")", ";", "=", "%", "/"];
word = specials[Math.floor(Math.random() * 10)];
}
return word;
}
export function restart(withSameWordset = false, nosave = false, event) {
if (TestUI.testRestarting || TestUI.resultCalculating) {
try {

View file

@ -1,5 +1,5 @@
import * as TestLogic from "./test-logic";
import Config, * as UpdateConfig from "./config";
import Config from "./config";
import * as Funbox from "./funbox";
import * as Misc from "./misc";
import * as TestStats from "./test-stats";
@ -182,6 +182,10 @@ export function pushKeypressSpacing(val) {
keypressTimings.spacing.array.push(val);
}
export function setKeypressSpacing(val) {
keypressTimings.spacing.current = val;
}
export function recordKeypressSpacing() {
let now = performance.now();
let diff = Math.abs(keypressTimings.spacing.current - now);
@ -191,10 +195,6 @@ export function recordKeypressSpacing() {
setKeypressSpacing(now);
}
export function setKeypressSpacing(val) {
keypressTimings.spacing.current = val;
}
export function resetKeypressTimings() {
keypressTimings = {
spacing: {

View file

@ -10,7 +10,6 @@ import * as Funbox from "./funbox";
import * as TestLogic from "./test-logic";
import * as Caret from "./caret";
import * as Keymap from "./keymap";
import * as TestUI from "./test-ui";
export let time = 0;
let timer = null;

View file

@ -42,6 +42,33 @@ export function reset() {
currentWordElementIndex = 0;
}
export function updateActiveElement(backspace) {
let active = document.querySelector("#words .active");
if (Config.mode == "zen" && backspace) {
active.remove();
} else if (active !== null) {
if (Config.highlightMode == "word") {
active.querySelectorAll("letter").forEach((e) => {
e.classList.remove("correct");
});
}
active.classList.remove("active");
}
try {
let activeWord = document.querySelectorAll("#words .word")[
currentWordElementIndex
];
activeWord.classList.add("active");
activeWord.classList.remove("error");
activeWordTop = document.querySelector("#words .active").offsetTop;
if (Config.highlightMode == "word") {
activeWord.querySelectorAll("letter").forEach((e) => {
e.classList.add("correct");
});
}
} catch (e) {}
}
export function showWords() {
$("#words").empty();
@ -122,33 +149,6 @@ export function showWords() {
Caret.updatePosition();
}
export function updateActiveElement(backspace) {
let active = document.querySelector("#words .active");
if (Config.mode == "zen" && backspace) {
active.remove();
} else if (active !== null) {
if (Config.highlightMode == "word") {
active.querySelectorAll("letter").forEach((e) => {
e.classList.remove("correct");
});
}
active.classList.remove("active");
}
try {
let activeWord = document.querySelectorAll("#words .word")[
currentWordElementIndex
];
activeWord.classList.add("active");
activeWord.classList.remove("error");
activeWordTop = document.querySelector("#words .active").offsetTop;
if (Config.highlightMode == "word") {
activeWord.querySelectorAll("letter").forEach((e) => {
e.classList.add("correct");
});
}
} catch (e) {}
}
export function flipColors(tf) {
if (tf) {
$("#words").addClass("flipped");

View file

@ -1,7 +1,8 @@
import Config, * as UpdateConfig from "./config";
import Config from "./config";
import * as CustomText from "./custom-text";
import * as Misc from "./misc";
import * as TestLogic from "./test-logic";
import * as TestTimer from "./test-timer";
export function show() {
let op = Config.showTimerProgress ? Config.timerOpacity : 0;
@ -84,8 +85,8 @@ export function restart() {
}
}
//TODO remove the parameters once they are inside a module
export function update(time) {
export function update() {
let time = TestTimer.time;
if (
Config.mode === "time" ||
(Config.mode === "custom" && CustomText.isTimeRandom)

View file

@ -2,24 +2,12 @@ import * as ThemeColors from "./theme-colors";
import * as ChartController from "./chart-controller";
import * as Misc from "./misc";
import * as Notifications from "./notification-center";
import Config, * as UpdateConfig from "./config";
import Config from "./config";
import { swapElements } from "./dom-util";
let isPreviewingTheme = false;
let randomTheme = null;
//TODO remove current theme and customcolors once config is a module
let currentTheme = "serika_dark";
let customColors = [
"#323437",
"#e2b714",
"#e2b714",
"#646669",
"#d1d0c5",
"#ca4754",
"#7e2a33",
"#ca4754",
"#7e2a33",
];
export const colorVars = [
"--bg-color",
"--main-color",
@ -32,92 +20,6 @@ export const colorVars = [
"--colorful-error-extra-color",
];
export function apply(themeName) {
clearCustomTheme();
let name = "serika_dark";
if (themeName !== "custom") {
name = themeName;
swapElements(
$('.pageSettings [tabContent="custom"]'),
$('.pageSettings [tabContent="preset"]'),
250
);
} else {
//is custom
swapElements(
$('.pageSettings [tabContent="preset"]'),
$('.pageSettings [tabContent="custom"]'),
250
);
}
$(".keymap-key").attr("style", "");
$("#currentTheme").attr("href", `themes/${name}.css`);
$(".current-theme").text(themeName.replace("_", " "));
if (themeName === "custom") {
colorVars.forEach((e, index) => {
document.documentElement.style.setProperty(e, customColors[index]);
});
}
try {
firebase.analytics().logEvent("changedTheme", {
theme: themeName,
});
} catch (e) {
console.log("Analytics unavailable");
}
setTimeout(() => {
$(".keymap-key").attr("style", "");
ChartController.updateAllChartColors();
updateFavicon(32, 14);
$("#metaThemeColor").attr("content", ThemeColors.main);
}, 500);
}
export function preview(themeName) {
isPreviewingTheme = true;
apply(themeName);
}
export function set(themeName) {
currentTheme = themeName;
apply(themeName);
}
export function clearPreview() {
if (isPreviewingTheme) {
isPreviewingTheme = false;
apply(currentTheme);
}
}
export function setCustomColors(colors) {
customColors = colors;
}
//TODO remove config once config is a module
export function randomiseTheme() {
var randomList;
Misc.getThemesList().then((themes) => {
randomList = themes.map((t) => {
return t.name;
});
if (Config.randomTheme === "fav" && Config.favThemes.length > 0)
randomList = Config.favThemes;
randomTheme = randomList[Math.floor(Math.random() * randomList.length)];
preview(randomTheme);
Notifications.add(randomTheme.replace(/_/g, " "), 0);
});
}
export function clearRandom() {
randomTheme = null;
}
function updateFavicon(size, curveSize) {
let maincolor, bgcolor;
@ -158,3 +60,86 @@ function clearCustomTheme() {
document.documentElement.style.setProperty(e, "");
});
}
export function apply(themeName) {
clearCustomTheme();
let name = "serika_dark";
if (themeName !== "custom") {
name = themeName;
swapElements(
$('.pageSettings [tabContent="custom"]'),
$('.pageSettings [tabContent="preset"]'),
250
);
} else {
//is custom
swapElements(
$('.pageSettings [tabContent="preset"]'),
$('.pageSettings [tabContent="custom"]'),
250
);
}
$(".keymap-key").attr("style", "");
$("#currentTheme").attr("href", `themes/${name}.css`);
$(".current-theme").text(themeName.replace("_", " "));
if (themeName === "custom") {
colorVars.forEach((e, index) => {
document.documentElement.style.setProperty(
e,
Config.customThemeColors[index]
);
});
}
try {
firebase.analytics().logEvent("changedTheme", {
theme: themeName,
});
} catch (e) {
console.log("Analytics unavailable");
}
setTimeout(() => {
$(".keymap-key").attr("style", "");
ChartController.updateAllChartColors();
updateFavicon(32, 14);
$("#metaThemeColor").attr("content", ThemeColors.main);
}, 500);
}
export function preview(themeName) {
isPreviewingTheme = true;
apply(themeName);
}
export function set(themeName) {
apply(themeName);
}
export function clearPreview() {
if (isPreviewingTheme) {
isPreviewingTheme = false;
apply(Config.theme);
}
}
export function randomiseTheme() {
var randomList;
Misc.getThemesList().then((themes) => {
randomList = themes.map((t) => {
return t.name;
});
if (Config.randomTheme === "fav" && Config.favThemes.length > 0)
randomList = Config.favThemes;
randomTheme = randomList[Math.floor(Math.random() * randomList.length)];
preview(randomTheme);
Notifications.add(randomTheme.replace(/_/g, " "), 0);
});
}
export function clearRandom() {
randomTheme = null;
}

View file

@ -493,11 +493,6 @@ a:hover {
gap: 1rem;
width: 60vw;
.wordfilter{
width: 33%;
justify-self:right;
}
textarea {
background: var(--bg-color);
padding: 1rem;
@ -511,8 +506,6 @@ a:hover {
resize: vertical;
height: 200px;
color: var(--text-color);
overflow-x: hidden;
overflow-y: scroll;
}
.inputs {

View file

@ -5,7 +5,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Monkeytype</title>
<!-- <link rel="stylesheet" href="css/fa.css" /> -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<link rel="stylesheet" href="css/balloon.css" />
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="themes/serika_dark.css" id="currentTheme" />
@ -103,7 +102,6 @@
</div>
<div id="customTextPopupWrapper" class="hidden">
<div id="customTextPopup" action="">
<div class="wordfilter button"><i class="fas fa-filter"></i>Words filter</div>
<textarea class="textarea" placeholder="Custom text"></textarea>
<div class="inputs">
<label class="check">
@ -135,27 +133,6 @@
</span>
</label>
</div>
<div class="button apply">ok</div>
</div>
</div>
<div id="wordFilterPopupWrapper" class="hidden">
<div id="wordFilterPopup">
<div class="wftitle">language</div>
<select id="languageList" class="">
</select>
<div class="lengthgrid">
<div id="wordMinTitle" class="wftitle">min length</div>
<div id="wordMaxTitle" class="wftitle">max length</div>
<input id="wordMin" class="wordLength" autocomplete="off" type="number">
<input id="wordMax" class="wordLength" autocomplete="off" type="number">
</div>
<div class="wftitle">include</div>
<input id="wordFilter" autocomplete="off">
<div class="wftitle">exclude</div>
<input id="wordExclude" autocomplete="off">
<div class="wftip">Use the above filters to include and exclude words or characters (separated by spaces)</div>
<i class="fas fa-fw fa-spin fa-circle-notch hidden wfload"></i>
<div class="button">ok</div>
</div>
</div>
@ -3777,6 +3754,5 @@
<script src="js/jquery.cookie-1.4.1.min.js"></script>
<script src="js/moment.min.js"></script>
<script src="js/html2canvas.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script src="js/monkeytype.js"></script>
</html>