diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 3a5980ede..ea7c5aef3 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -14,13 +14,8 @@ Sometimes your browser has old files cached and the bug you are experiencing mig
**Describe the bug**
-
+
**To Reproduce**
@@ -39,11 +34,4 @@ Sometimes things work in incognito mode, which allows me to further track down t
- Browser []
- Browser Version []
-**Smartphone:**
-
-- Device: []
-- OS: []
-- Browser []
-- Browser Version []
-
**Additional context**
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index ceaf5ec8d..aa840341f 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,18 +1,27 @@
-Adding a language or a theme? For languages, make sure to edit the `_list.json`, `_groups.json` files, and add the `language.json` file as well. For themes, make sure to add the `theme.css` file. It will not work if you don't follow these steps!
+
-Please reference any issues and or PRs related to your pull request.
+
+ -->
-### Checklist
+### Description
+
+
+
+
+
+### Checklist
- [] I have read the [`CODE_OF_CONDUCT.md`](https://github.com/Miodec/monkeytype/blob/master/CODE_OF_CONDUCT.md) and the [`CONTRIBUTING.md`](https://github.com/Miodec/monkeytype/blob/master/CONTRIBUTING.md)
-- [] If my PR is a new language or theme I modified the appropriate files to incorporate the language or theme
- [] I checked if my PR has any bugs or other issues that could reduce the stability of the project
-- [] I understand that the maintainer has the right to reject my PR and it may not get accepted.
+- [] I understand that the maintainer has the right to reject my contribution and it may not get accepted.
+- [] If my PR is a new language or theme I modified the appropriate files to incorporate the language or theme
-
+
+
Resolves #
+
+
diff --git a/functions/index.js b/functions/index.js
index 254381290..2b870b06a 100644
--- a/functions/index.js
+++ b/functions/index.js
@@ -2454,6 +2454,44 @@ exports.checkLeaderboards = functions.https.onRequest(
}
request = request.body.data;
+ if (request.token === undefined) {
+ response.status(200).send({
+ data: {
+ status: -999,
+ message: "No token",
+ },
+ });
+ return;
+ }
+ let tokenDecoded;
+ try {
+ tokenDecoded = await admin.auth().verifyIdToken(request.token);
+ } catch (e) {
+ response.status(200).send({
+ data: {
+ status: -999,
+ message: "Bad token",
+ },
+ });
+ return;
+ }
+ request.emailVerified = tokenDecoded.email_verified;
+ request.uid = tokenDecoded.uid;
+
+ // name:
+ // banned:
+ // verified:
+ // discordId
+
+ let userData = await db.collection("users").doc(request.uid).get();
+ userData = userData.data();
+
+ request.name = userData.name;
+ request.banned = userData.banned;
+ request.verified = userData.verified;
+ request.discordId = userData.discordId;
+ request.lbMemory = userData.lbMemory;
+
function verifyValue(val) {
let errCount = 0;
if (val === null || val === undefined) {
@@ -2488,15 +2526,8 @@ exports.checkLeaderboards = functions.https.onRequest(
return;
}
- let emailVerified = await admin
- .auth()
- .getUser(request.uid)
- .then((user) => {
- return user.emailVerified;
- });
-
try {
- if (emailVerified === false) {
+ if (request.emailVerified === false) {
response.status(200).send({
data: {
needsToVerifyEmail: true,
diff --git a/src/js/account/result-filters.js b/src/js/account/result-filters.js
index 82f9ae144..03c87ab3f 100644
--- a/src/js/account/result-filters.js
+++ b/src/js/account/result-filters.js
@@ -74,6 +74,7 @@ Promise.all([Misc.getLanguageList(), Misc.getFunboxList()]).then((values) => {
defaultResultFilters.funbox[funbox.name] = true;
});
// filters = defaultResultFilters;
+ load();
});
export function getFilters() {
@@ -110,7 +111,12 @@ export function load() {
// let newTags = $.cookie("activeTags");
try {
let newResultFilters = window.localStorage.getItem("resultFilters");
- if (newResultFilters != undefined && newResultFilters !== "") {
+ if (
+ newResultFilters != undefined &&
+ newResultFilters !== "" &&
+ Misc.countAllKeys(newResultFilters) >=
+ Misc.countAllKeys(defaultResultFilters)
+ ) {
filters = JSON.parse(newResultFilters);
save();
} else {
@@ -129,8 +135,6 @@ export function reset() {
save();
}
-load();
-
export function updateActive() {
let aboveChartDisplay = {};
Object.keys(getFilters()).forEach((group) => {
@@ -398,10 +402,10 @@ $(".pageAccount .topFilters .button.currentConfigFilter").click((e) => {
filters["language"][Config.language] = true;
}
- if (Funbox.active === "none") {
+ if (Config.funbox === "none") {
filters.funbox.none = true;
} else {
- filters.funbox[Funbox.active] = true;
+ filters.funbox[Config.funbox] = true;
}
filters["tags"]["none"] = true;
diff --git a/src/js/commandline-lists.js b/src/js/commandline-lists.js
index 70d6ac12f..957e2bc94 100644
--- a/src/js/commandline-lists.js
+++ b/src/js/commandline-lists.js
@@ -1815,7 +1815,7 @@ export let defaultCommands = {
input: true,
exec: (input) => {
UpdateConfig.setCustomLayoutfluid(input);
- if (Funbox.active === "layoutfluid") TestLogic.restart();
+ if (Config.funbox === "layoutfluid") TestLogic.restart();
// UpdateConfig.setLayout(
// Config.customLayoutfluid
// ? Config.customLayoutfluid.split("_")[0]
diff --git a/src/js/config.js b/src/js/config.js
index 2ef46f554..22deb0c72 100644
--- a/src/js/config.js
+++ b/src/js/config.js
@@ -74,6 +74,7 @@ let defaultConfig = {
flipTestColors: false,
capsLockBackspace: false,
layout: "default",
+ funbox: "none",
confidenceMode: "off",
indicateTypos: false,
timerStyle: "mini",
@@ -209,7 +210,7 @@ export function togglePunctuation() {
export function setMode(mode, nosave) {
if (TestUI.testRestarting) return;
- if (mode !== "words" && Funbox.active === "memory") {
+ if (mode !== "words" && config.funbox === "memory") {
Notifications.add("Memory funbox can only be used with words mode.", 0);
return;
}
@@ -237,11 +238,11 @@ export function setMode(mode, nosave) {
$("#top .config .quoteLength").addClass("hidden");
} else if (config.mode == "custom") {
if (
- Funbox.active === "58008" ||
- Funbox.active === "gibberish" ||
- Funbox.active === "ascii"
+ config.funbox === "58008" ||
+ config.funbox === "gibberish" ||
+ config.funbox === "ascii"
) {
- Funbox.setAcitve("none");
+ Funbox.setActive("none");
TestUI.updateModesNotice();
}
$("#top .config .wordCount").addClass("hidden");
@@ -327,6 +328,13 @@ export function setFavThemes(themes, nosave) {
}
}
+export function setFunbox(funbox, nosave) {
+ config.funbox = funbox ? funbox : "none";
+ if (!nosave) {
+ saveToLocalStorage();
+ }
+}
+
//blind mode
export function toggleBlindMode() {
let blind = !config.blindMode;
@@ -845,10 +853,10 @@ export function toggleLiveAcc() {
export function setHighlightMode(mode, nosave) {
if (
mode === "word" &&
- (Funbox.active === "nospace" ||
- Funbox.active === "read_ahead" ||
- Funbox.active === "read_ahead_easy" ||
- Funbox.active === "read_ahead_hard")
+ (config.funbox === "nospace" ||
+ config.funbox === "read_ahead" ||
+ config.funbox === "read_ahead_easy" ||
+ config.funbox === "read_ahead_hard")
) {
Notifications.add("Can't use word highlight with this funbox", 0);
return;
@@ -1533,6 +1541,7 @@ export function apply(configObj) {
setPlaySoundOnClick(configObj.playSoundOnClick, true);
setStopOnError(configObj.stopOnError, true);
setFavThemes(configObj.favThemes, true);
+ setFunbox(configObj.funbox, true);
setRandomTheme(configObj.randomTheme, true);
setShowAllLines(configObj.showAllLines, true);
setSwapEscAndTab(configObj.swapEscAndTab, true);
diff --git a/src/js/input-controller.js b/src/js/input-controller.js
index 1ce801213..e66cbd0dc 100644
--- a/src/js/input-controller.js
+++ b/src/js/input-controller.js
@@ -121,7 +121,7 @@ function handleBackspace(event) {
} else {
TestLogic.input.setCurrent(TestLogic.input.popHistory());
TestLogic.corrected.setCurrent(TestLogic.corrected.popHistory());
- if (Funbox.active === "nospace") {
+ if (Config.funbox === "nospace") {
TestLogic.input.setCurrent(
TestLogic.input.current.substring(
0,
@@ -194,7 +194,7 @@ function handleSpace(event, isEnter) {
if (!TestLogic.active) return;
if (TestLogic.input.current === "") return;
// let nextWord = wordsList[TestLogic.words.currentIndex + 1];
- // if ((isEnter && nextWord !== "\n") && (isEnter && Funbox.active !== "58008")) return;
+ // if ((isEnter && nextWord !== "\n") && (isEnter && Config.funbox !== "58008")) return;
// if (!isEnter && nextWord === "\n") return;
event.preventDefault();
@@ -204,7 +204,7 @@ function handleSpace(event, isEnter) {
}
let currentWord = TestLogic.words.getCurrent();
- if (Funbox.active === "layoutfluid" && Config.mode !== "time") {
+ if (Config.funbox === "layoutfluid" && Config.mode !== "time") {
// here I need to check if Config.customLayoutFluid exists because of my scuffed solution of returning whenever value is undefined in the setCustomLayoutfluid function
const layouts = Config.customLayoutfluid
? Config.customLayoutfluid.split("#")
@@ -246,14 +246,14 @@ function handleSpace(event, isEnter) {
TestStats.pushKeypressWord(TestLogic.words.currentIndex);
// currentKeypress.count++;
// currentKeypress.words.push(TestLogic.words.currentIndex);
- if (Funbox.active !== "nospace") {
+ if (Config.funbox !== "nospace") {
Sound.playClick(Config.playSoundOnClick);
}
Replay.addReplayEvent("submitCorrectWord");
} else {
//incorrect word
PaceCaret.handleSpace(false, currentWord);
- if (Funbox.active !== "nospace") {
+ if (Config.funbox !== "nospace") {
if (!Config.playSoundOnError || Config.blindMode) {
Sound.playClick(Config.playSoundOnClick);
} else {
@@ -697,7 +697,7 @@ function handleAlpha(event) {
//simulate space press in nospace funbox
if (
- (Funbox.active === "nospace" &&
+ (Config.funbox === "nospace" &&
TestLogic.input.current.length === TestLogic.words.getCurrent().length) ||
(event.key === "\n" && thisCharCorrect)
) {
@@ -814,7 +814,7 @@ $(document).keydown(function (event) {
handleBackspace(event);
}
- if (event.key === "Enter" && Funbox.active === "58008" && wordsFocused) {
+ if (event.key === "Enter" && Config.funbox === "58008" && wordsFocused) {
event.key = " ";
}
diff --git a/src/js/misc.js b/src/js/misc.js
index 291826076..ab481af82 100644
--- a/src/js/misc.js
+++ b/src/js/misc.js
@@ -728,3 +728,14 @@ export function setCharAt(str, index, chr) {
if (index > str.length - 1) return str;
return str.substring(0, index) + chr + str.substring(index + 1);
}
+
+//https://www.reddit.com/r/learnjavascript/comments/8ohug3/how_to_recursively_count_keys_in_an_object/e03fytn/
+function countAllKeys(obj) {
+ if (typeof obj !== "object" || obj === null) {
+ return 0;
+ }
+ const keys = Object.keys(obj);
+ let sum = keys.length;
+ keys.forEach((key) => (sum += countAllKeys(obj[key])));
+ return sum;
+}
diff --git a/src/js/route-controller.js b/src/js/route-controller.js
index 49beeb03d..d30f4fb40 100644
--- a/src/js/route-controller.js
+++ b/src/js/route-controller.js
@@ -1,5 +1,6 @@
import * as Funbox from "./funbox";
import * as UI from "./ui";
+import Config from "./config";
let mappedRoutes = {
"/": "pageTest",
@@ -19,7 +20,7 @@ export function handleInitialPageClasses(pathname) {
(function (history) {
var pushState = history.pushState;
history.pushState = function (state) {
- if (Funbox.active === "memory" && state !== "/") {
+ if (Config.funbox === "memory" && state !== "/") {
Funbox.resetMemoryTimer();
}
return pushState.apply(history, arguments);
diff --git a/src/js/settings.js b/src/js/settings.js
index 55cc64b9b..3cc089831 100644
--- a/src/js/settings.js
+++ b/src/js/settings.js
@@ -448,7 +448,7 @@ export function updateDiscordSection() {
function setActiveFunboxButton() {
$(`.pageSettings .section.funbox .button`).removeClass("active");
$(
- `.pageSettings .section.funbox .button[funbox='${Funbox.funboxSaved}']`
+ `.pageSettings .section.funbox .button[funbox='${Config.funbox}']`
).addClass("active");
}
diff --git a/src/js/test/funbox.js b/src/js/test/funbox.js
index c6350b7ed..60addd553 100644
--- a/src/js/test/funbox.js
+++ b/src/js/test/funbox.js
@@ -6,9 +6,7 @@ import * as ManualRestart from "./manual-restart-tracker";
import Config, * as UpdateConfig from "./config";
import * as Settings from "./settings";
-export let active = "none";
-export let funboxSaved = "none";
-export let modeSaved = null;
+let modeSaved = null;
let memoryTimer = null;
let memoryInterval = null;
@@ -76,13 +74,13 @@ export function startMemoryTimer() {
}
export function reset() {
- active = "none";
resetMemoryTimer();
}
export function toggleScript(...params) {
- if (active === "tts") {
+ if (Config.funbox === "tts") {
var msg = new SpeechSynthesisUtterance();
+ console.log("Speaking");
msg.text = params[0];
msg.lang = "en-US";
window.speechSynthesis.cancel();
@@ -90,9 +88,11 @@ export function toggleScript(...params) {
}
}
-export async function activate(funbox, mode) {
+export async function activate(funbox) {
+ let mode = modeSaved;
+
if (funbox === undefined || funbox === null) {
- funbox = funboxSaved;
+ funbox = Config.funbox;
}
if (Misc.getCurrentLanguage().ligatures) {
if (funbox == "choo_choo" || funbox == "earthquake") {
@@ -124,10 +124,8 @@ export async function activate(funbox, mode) {
ManualRestart.set();
if (mode === "style") {
- if (funbox != undefined) {
+ if (funbox != undefined)
$("#funBoxTheme").attr("href", `funbox/${funbox}.css`);
- active = funbox;
- }
if (funbox === "simon_says") {
rememberSetting(
@@ -220,7 +218,6 @@ export async function activate(funbox, mode) {
UpdateConfig.setHighlightMode("letter", true);
TestLogic.restart(false, true);
}
- active = funbox;
}
// if (funbox !== "layoutfluid" || mode !== "script") {
@@ -233,16 +230,8 @@ export async function activate(funbox, mode) {
return true;
}
export function setFunbox(funbox, mode) {
- if (TestLogic.active) {
- Notifications.add(
- "You can only change the funbox before starting a test.",
- 0
- );
- return false;
- }
if (funbox === "none") loadMemory();
- funboxSaved = funbox;
modeSaved = mode;
- active = funbox;
+ UpdateConfig.setFunbox(funbox);
return true;
}
diff --git a/src/js/test/test-leaderboards.js b/src/js/test/test-leaderboards.js
index c04111584..e26f9b771 100644
--- a/src/js/test/test-leaderboards.js
+++ b/src/js/test/test-leaderboards.js
@@ -130,7 +130,7 @@ export function show(data, mode2) {
$("#result .stats .leaderboards .bottom").html(string);
}
-export function check(completedEvent) {
+export async function check(completedEvent) {
try {
if (
completedEvent.funbox === "none" &&
@@ -162,13 +162,14 @@ export function check(completedEvent) {
delete lbRes.chartData;
/*
CloudFunctions.checkLeaderboards({
- uid: completedEvent.uid,
- lbMemory: DB.getSnapshot().lbMemory,
+ // uid: completedEvent.uid,
+ token: await firebase.auth().currentUser.getIdToken(),
+ // lbMemory: DB.getSnapshot().lbMemory,
// emailVerified: DB.getSnapshot().emailVerified,
- name: DB.getSnapshot().name,
- banned: DB.getSnapshot().banned,
- verified: DB.getSnapshot().verified,
- discordId: DB.getSnapshot().discordId,
+ // name: DB.getSnapshot().name,
+ // banned: DB.getSnapshot().banned,
+ // verified: DB.getSnapshot().verified,
+ // discordId: DB.getSnapshot().discordId,
result: lbRes,
})
*/
@@ -178,8 +179,21 @@ export function check(completedEvent) {
result: lbRes,
})
.then((data) => {
- Misc.clearTimeouts(textTimeouts);
- show(data.data, completedEvent.mode2);
+ if (data.data.status === -999) {
+ if (data.data.message === "Bad token") {
+ $("#result .stats .leaderboards").addClass("hidden");
+ Notifications.add(
+ "Bad token. This could mean your client is out of date and is sending data in the old format. Please refresh and clear your cache.",
+ -1
+ );
+ } else {
+ $("#result .stats .leaderboards").addClass("hidden");
+ Notifications.add(data.data.message, -1);
+ }
+ } else {
+ Misc.clearTimeouts(textTimeouts);
+ show(data.data, completedEvent.mode2);
+ }
})
.catch((e) => {
$("#result .stats .leaderboards").addClass("hidden");
diff --git a/src/js/test/test-logic.js b/src/js/test/test-logic.js
index 89cf44fbc..30b6c7be1 100644
--- a/src/js/test/test-logic.js
+++ b/src/js/test/test-logic.js
@@ -197,7 +197,7 @@ export function setRandomQuote(rq) {
export function punctuateWord(previousWord, currentWord, index, maxindex) {
let word = currentWord;
- if (Funbox.funboxSaved === "58008") {
+ if (Config.funbox === "58008") {
if (currentWord.length > 3) {
if (Math.random() < 0.75) {
let special = ["/", "*", "-", "+"][Math.floor(Math.random() * 4)];
@@ -336,7 +336,7 @@ export function startTest() {
TimerProgress.update(TestTimer.time);
TestTimer.clear();
- if (Funbox.active === "memory") {
+ if (Config.funbox === "memory") {
Funbox.resetMemoryTimer();
$("#wordsWrapper").addClass("hidden");
}
@@ -433,7 +433,7 @@ export async function init() {
if (Config.mode === "words" && Config.words === 0) {
wordsBound = 100;
}
- if (Funbox.funboxSaved === "plus_one") {
+ if (Config.funbox === "plus_one") {
wordsBound = 2;
}
let wordset = language.words;
@@ -462,7 +462,7 @@ export async function init() {
}
}
- if (Funbox.funboxSaved === "rAnDoMcAsE") {
+ if (Config.funbox === "rAnDoMcAsE") {
let randomcaseword = "";
for (let i = 0; i < randomWord.length; i++) {
if (i % 2 != 0) {
@@ -472,17 +472,17 @@ export async function init() {
}
}
randomWord = randomcaseword;
- } else if (Funbox.funboxSaved === "gibberish") {
+ } else if (Config.funbox === "gibberish") {
randomWord = Misc.getGibberish();
- } else if (Funbox.funboxSaved === "58008") {
+ } else if (Config.funbox === "58008") {
// UpdateConfig.setPunctuation(false, true);
UpdateConfig.setNumbers(false, true);
randomWord = Misc.getNumbers(7);
- } else if (Funbox.funboxSaved === "specials") {
+ } else if (Config.funbox === "specials") {
UpdateConfig.setPunctuation(false, true);
UpdateConfig.setNumbers(false, true);
randomWord = Misc.getSpecials();
- } else if (Funbox.funboxSaved === "ascii") {
+ } else if (Config.funbox === "ascii") {
UpdateConfig.setPunctuation(false, true);
UpdateConfig.setNumbers(false, true);
randomWord = Misc.getASCII();
@@ -774,7 +774,7 @@ export function restart(
document.querySelector("#liveWpm").innerHTML = "0";
document.querySelector("#liveAcc").innerHTML = "100%";
- if (Funbox.active === "memory") {
+ if (Config.funbox === "memory") {
Funbox.startMemoryTimer();
if (Config.keymapMode === "next") {
UpdateConfig.setKeymapMode("react");
@@ -792,15 +792,15 @@ export function restart(
mode2 = randomQuote.id;
}
let fbtext = "";
- if (Funbox.active !== "none") {
- fbtext = " " + Funbox.active;
+ if (Config.funbox !== "none") {
+ fbtext = " " + Config.funbox;
}
$(".pageTest #premidTestMode").text(
`${Config.mode} ${mode2} ${Config.language}${fbtext}`
);
$(".pageTest #premidSecondsLeft").text(Config.time);
- if (Funbox.active === "layoutfluid") {
+ if (Config.funbox === "layoutfluid") {
UpdateConfig.setLayout(
Config.customLayoutfluid
? Config.customLayoutfluid.split("#")[0]
@@ -874,7 +874,7 @@ export function calculateWpmAndRaw() {
if (words.getCurrent() == input.current) {
correctWordChars += input.current.length;
}
- if (Funbox.active === "nospace") {
+ if (Config.funbox === "nospace") {
spaces = 0;
}
chars += input.current.length;
@@ -889,7 +889,7 @@ export function calculateWpmAndRaw() {
export function addWord() {
let bound = 100;
- if (Funbox.active === "plus_one") bound = 1;
+ if (Config.funbox === "plus_one") bound = 1;
if (
words.length - input.history.length > bound ||
(Config.mode === "words" &&
@@ -942,7 +942,7 @@ export function addWord() {
}
}
- if (Funbox.active === "rAnDoMcAsE") {
+ if (Config.funbox === "rAnDoMcAsE") {
let randomcaseword = "";
for (let i = 0; i < randomWord.length; i++) {
if (i % 2 != 0) {
@@ -952,13 +952,13 @@ export function addWord() {
}
}
randomWord = randomcaseword;
- } else if (Funbox.active === "gibberish") {
+ } else if (Config.funbox === "gibberish") {
randomWord = Misc.getGibberish();
- } else if (Funbox.active === "58008") {
+ } else if (Config.funbox === "58008") {
randomWord = Misc.getNumbers(7);
- } else if (Funbox.active === "specials") {
+ } else if (Config.funbox === "specials") {
randomWord = Misc.getSpecials();
- } else if (Funbox.active === "ascii") {
+ } else if (Config.funbox === "ascii") {
randomWord = Misc.getASCII();
}
@@ -1379,7 +1379,7 @@ export function finish(difficultyFailed = false) {
keyDuration: TestStats.keypressTimings.duration.array,
consistency: consistency,
keyConsistency: keyConsistency,
- funbox: Funbox.funboxSaved,
+ funbox: Config.funbox,
bailedOut: bailout,
chartData: chartData,
customText: cdata,
@@ -1562,6 +1562,7 @@ export function finish(difficultyFailed = false) {
);
}
if (!window.navigator.onLine) {
+ AccountButton.loading(false);
Notifications.add("You are offline. Result not saved.", -1);
} else {
axiosInstance
@@ -1732,9 +1733,9 @@ export function finish(difficultyFailed = false) {
}
if (
Config.mode != "custom" &&
- Funbox.funboxSaved !== "gibberish" &&
- Funbox.funboxSaved !== "ascii" &&
- Funbox.funboxSaved !== "58008"
+ Config.funbox !== "gibberish" &&
+ Config.funbox !== "ascii" &&
+ Config.funbox !== "58008"
) {
testType += "
" + lang;
}
@@ -1747,8 +1748,8 @@ export function finish(difficultyFailed = false) {
if (Config.blindMode) {
testType += "
blind";
}
- if (Funbox.funboxSaved !== "none") {
- testType += "
" + Funbox.funboxSaved.replace(/_/g, " ");
+ if (Config.funbox !== "none") {
+ testType += "
" + Config.funbox.replace(/_/g, " ");
}
if (Config.difficulty == "expert") {
testType += "
expert";
@@ -1802,9 +1803,9 @@ export function finish(difficultyFailed = false) {
$("#result .stats .source").addClass("hidden");
}
- if (Funbox.funboxSaved !== "none") {
- let content = Funbox.funboxSaved;
- if (Funbox.funboxSaved === "layoutfluid") {
+ if (Config.funbox !== "none") {
+ let content = Config.funbox;
+ if (Config.funbox === "layoutfluid") {
content += " " + Config.customLayoutfluid.replace(/#/g, " ");
}
ChartController.result.options.annotation.annotations.push({
diff --git a/src/js/test/test-stats.js b/src/js/test/test-stats.js
index 26407e272..efe07a9b4 100644
--- a/src/js/test/test-stats.js
+++ b/src/js/test/test-stats.js
@@ -310,7 +310,7 @@ function countChars() {
spaces++;
}
}
- if (Funbox.active === "nospace") {
+ if (Config.funbox === "nospace") {
spaces = 0;
correctspaces = 0;
}
diff --git a/src/js/test/test-timer.js b/src/js/test/test-timer.js
index 991fbebab..94b3a954d 100644
--- a/src/js/test/test-timer.js
+++ b/src/js/test/test-timer.js
@@ -40,7 +40,7 @@ export function start() {
let acc = Misc.roundTo2(TestStats.calculateAccuracy());
- if (Funbox.active === "layoutfluid" && Config.mode === "time") {
+ if (Config.funbox === "layoutfluid" && Config.mode === "time") {
const layouts = Config.customLayoutfluid
? Config.customLayoutfluid.split("#")
: ["qwerty", "dvorak", "colemak"];
diff --git a/src/js/test/test-ui.js b/src/js/test/test-ui.js
index ba22f5e10..1fc21f262 100644
--- a/src/js/test/test-ui.js
+++ b/src/js/test/test-ui.js
@@ -524,9 +524,9 @@ export function updateModesNotice() {
);
}
- if (Funbox.active !== "none") {
+ if (Config.funbox !== "none") {
$(".pageTest #testModesNotice").append(
- `
${Funbox.active.replace(
+ `
${Config.funbox.replace(
/_/g,
" "
)}
`
diff --git a/src/js/ui.js b/src/js/ui.js
index ee7ba3474..c7c3e725b 100644
--- a/src/js/ui.js
+++ b/src/js/ui.js
@@ -138,7 +138,7 @@ export function changePage(page) {
TestStats.resetIncomplete();
ManualRestart.set();
TestLogic.restart();
- Funbox.activate(Funbox.funboxSaved, Funbox.modeSaved);
+ Funbox.activate(Config.funbox);
} else if (page == "about") {
setPageTransition(true);
TestLogic.restart();
@@ -147,7 +147,7 @@ export function changePage(page) {
history.pushState("about", null, "about");
$(".page.pageAbout").addClass("active");
});
- Funbox.activate("none", null);
+ Funbox.activate("none");
TestConfig.hide();
SignOutButton.hide();
} else if (page == "settings") {
@@ -158,7 +158,7 @@ export function changePage(page) {
history.pushState("settings", null, "settings");
$(".page.pageSettings").addClass("active");
});
- Funbox.activate("none", null);
+ Funbox.activate("none");
Settings.update();
TestConfig.hide();
SignOutButton.hide();
@@ -184,7 +184,7 @@ export function changePage(page) {
SignOutButton.show();
}
);
- Funbox.activate("none", null);
+ Funbox.activate("none");
Account.update();
TestConfig.hide();
}
@@ -199,7 +199,7 @@ export function changePage(page) {
history.pushState("login", null, "login");
$(".page.pageLogin").addClass("active");
});
- Funbox.activate("none", null);
+ Funbox.activate("none");
TestConfig.hide();
SignOutButton.hide();
}
diff --git a/static/ads.txt b/static/ads.txt
index b813e3385..76bfa696e 100644
--- a/static/ads.txt
+++ b/static/ads.txt
@@ -1 +1,291 @@
-google.com, pub-7261919841327810, DIRECT, f08c47fec0942fa0
\ No newline at end of file
+google.com, pub-7261919841327810, DIRECT, f08c47fec0942fa0
+
+#V 29.04.2021 VH
+
+#A9
+#------------------------------------------------------------------------------------------------------
+aps.amazon.com,70247b00-ff8f-4016-b3ab-8344daf96e09,DIRECT # Amazon UAM
+appnexus.com,806,DIRECT,f5ab79cb980f11d1 # Xandr TAM
+smartadserver.com,3490,DIRECT # Smart TAM
+sovrn.com,237754,DIRECT,fafdf38b16bf6b2b # Sovrn TAM
+lijit.com,237754,DIRECT,fafdf38b16bf6b2b # Sovrn TAM
+pubmatic.com,159401,DIRECT,5d62403b186f2ace # Pubmatic TAM
+pubmatic.com,160006,RESELLER,5d62403b186f2ace # Pubmatic UAM
+pubmatic.com,160096,RESELLER,5d62403b186f2ace # Pubmatic UAM
+openx.com,542378302,DIRECT,6a698e2ec38604c6 # OpenX TAM
+rubiconproject.com,18020,RESELLER,0bfd66d529a55807 # Rubicon UAM
+appnexus.com,1908,RESELLER,f5ab79cb980f11d1 # DistrictM TAM
+districtm.io,100749,RESELLER,3fd707be9c4527c3 # DistrictM TAM
+adtech.com,12068,RESELLER,e1a5b5b6e3255540 # Verizon UAM
+ad-generation.jp,12474,RESELLER,7f4ea9029ac04e53 # Ad Generation JP UAM
+appnexus.com,3663,RESELLER,f5ab79cb980f11d1 # Yahoo JP UAM
+rhythmone.com,1654642120,RESELLER,a670c89d4a324e47 # Unruly RMO UAM
+yahoo.com,55029,RESELLER,e1a5b5b6e3255540 # Verizon UAM
+yieldmo.com, 2467323546544578775, DIRECT # Yieldmo TAM
+conversantmedia.com, 41150, DIRECT, 03113cd04947736d # Conversant TAM
+Triplelift.com,5241,DIRECT,6c33edb13117fd86 # Triplelift TAM
+indexexchange.com,193067,DIRECT,50b1c356f2c5c8fc # Index TAM
+EMXDGT.com,1741, DIRECT, 1e1d41537f7cad7f # EMX Digital TAM
+Appnexus.com, 1356, RESELLER, f5ab79cb980f11d1 # EMX Digital TAM
+smaato.com,1100044650,RESELLER,07bcf65f187117b4 # Smaato UAM
+gumgum.com,14141,RESELLER,ffdef49475d318a9 # GumGum UAM
+admanmedia.com, 663, DIRECT # Adman TAM
+appnexus.com, 8804, RESELLER, f5ab79cb980f11d1 # Adman TAM
+pubmatic.com, 158481, RESELLER, 5d62403b186f2ace # Adman TAM
+smartadserver.com, 3713, RESELLER # Adman TAM
+openx.com, 540866936, RESELLER, 6a698e2ec38604c6 # Adman TAM
+admanmedia.com,726,RESELLER # Adman UAM
+yahoo.com, 58855, DIRECT, e1a5b5b6e3255540 # Verizon TAM
+
+
+
+#OB
+#------------------------------------------------------------------------------------------------------
+vdopia.com, 15297, DIRECT, 49a66ce31a704197 # Chocolate OB
+chocolateplatform.com, 15297, DIRECT, 49a66ce31a704197 # Chocolate OB
+adingo.jp, 24379, DIRECT # Fluct OB
+improvedigital.com, 1640, DIRECT # Improve OB
+indexexchange.com, 188416, DIRECT, 50b1c356f2c5c8fc # Index OB
+openx.com, 540368327, RESELLER, 6a698e2ec38604c6 # OpenX OB
+rubiconproject.com, 17902, RESELLER, 0bfd66d529a55807 # Rubicon OB
+pubmatic.com, 158940, DIRECT, 5d62403b186f2ace # Pubmatic OB
+smartadserver.com, 3490, DIRECT # Smart RTB OB
+sonobi.com, ae3eca5cbd, DIRECT, d1a215d9eb5aee9e # Sonobi OB
+lijit.com, 237754-eb, DIRECT, fafdf38b16bf6b2b # Sovrn OB
+video.unrulymedia.com, 2864567592, DIRECT # Unruly RONE OB
+rhythmone.com, 985572675, DIRECT, a670c89d4a324e47 # Unruly RONE OB
+yieldmo.com, 2440034292147889057, DIRECT # Yieldmo OB
+advertising.com, 28621, DIRECT # Verizon OB
+tremorhub.com, hpwve, RESELLER, 1a4e959a1b50034a # Telaria OB
+telaria.com, hpwve, RESELLER, 1a4e959a1b50034a # Telaria OB
+
+
+
+#Prebid
+#------------------------------------------------------------------------------------------------------
+33across.com,Qp92QD-Kr6yoFaKkGJozW, DIRECT, bbea06d9c4d2853c # 33Across
+google.com, pub-5781531207509232, DIRECT, f08c47fec0942fa0 # AdX
+google.com, pub-4968145218643279, DIRECT, f08c47fec0942fa0 # Adx Test
+google.com, pub-4968145218643279, RESELLER, f08c47fec0942fa0 # Adx Test
+google.com, pub-2553634189837243, DIRECT, f08c47fec0942fa0 # AdS
+adagio.io, 1090, DIRECT # Adagio
+rubiconproject.com, 19116, RESELLER, 0bfd66d529a55807 # Adagio
+pubmatic.com, 159110, RESELLER, 5d62403b186f2ace # Adagio
+improvedigital.com, 1790, RESELLER # Adagio
+onetag.com, 6b859b96c564fbe, RESELLER # Adagio
+adform.com, 2767, RESELLER # AdForm
+adyoulike.com, c1314a52de718f3c214c00173d2994f9, Direct # Adyoulike
+appnexus.com, 9733, RESELLER # Adyoulike
+openx.com, 540847510, RESELLER, 6a698e2ec38604c6 # Adyoulike
+rubiconproject.com, 20736, RESELLER, 0bfd66d529a55807 # Adyoulike
+amxrtb.com, 105199358, DIRECT # Appmonet
+smartadserver.com, 3056, RESELLER # Appmonet
+appnexus.com, 11786, RESELLER # Appmonet
+appnexus.com, 9393, RESELLER # Appmonet
+lijit.com, 260380, RESELLER, fafdf38b16bf6b2b # Appmonet
+indexexchange.com, 191503, RESELLER # Appmonet
+pubmatic.com, 158355, RESELLER, 5d62403b186f2ace # Appmonet
+criteo.com, B-062405, DIRECT, 9fac4a4a87c2a44f # Criteo
+districtm.io, 100749, DIRECT # DistrictM
+appnexus.com, 1908, RESELLER,f5ab79cb980f11d1 # DistrictM
+appnexus.com, 7944, RESELLER,f5ab79cb980f11d1 # DistrictM
+improvedigital.com, 1012, DIRECT # Improve prebid
+indexexchange.com, 183921, DIRECT, 50b1c356f2c5c8fc # Index Exchange Display and Video
+Media.net,8CU5786QK, DIRECT # Media.net
+openx.com, 537100188, RESELLER, 6a698e2ec38604c6 # Media.net
+pubmatic.com, 159463, RESELLER, 5d62403b186f2ace # Media.net
+onetag.com, 5d49f482552c9b6, Reseller # Media.net
+loopme.com, 10509, RESELLER, 6c8d5f95897a5a3b # LoopMe
+loopme.com, 11398, RESELLER, 6c8d5f95897a5a3b # LoopMe
+loopme.com, 10509, DIRECT, 6c8d5f95897a5a3b # LoopMe
+rubiconproject.com, 20744, RESELLER, 0bfd66d529a55807 # LoopMe
+engagebdr.com, 10181, RESELLER # LoopMe
+openx.com, 537144009, DIRECT, 6a698e2ec38604c6 # OpenX
+pubmatic.com,159234,DIRECT,5d62403b186f2ace # Pubmatic
+pubmatic.com,159234,RESELLER,5d62403b186f2ace # Pubmatic
+pubmatic.com, 160552, RESELLER, 5d62403b186f2ace # Pubmatic oRTB
+richaudience.com, 1XvIoD5o0S, DIRECT # Rich Audience
+adform.com, 1941, DIRECT # Rich Audience
+adform.com, 1942, DIRECT # Rich Audience
+advertising.com, 7574, DIRECT # Rich Audience
+appnexus.com, 8233, DIRECT # Rich Audience
+appnexus.com, 2928, DIRECT # Rich Audience
+pubmatic.com, 81564, DIRECT, 5d62403b186f2ace # Rich Audience
+pubmatic.com, 156538, DIRECT, 5d62403b186f2ace # Rich Audience
+rubiconproject.com, 13510, DIRECT # Rich Audience
+spotx.tv, 173175, DIRECT # Rich Audience
+spotx.tv, 173177, DIRECT # Rich Audience
+spotxchange.com, 173175, DIRECT # Rich Audience
+spotxchange.com, 173177, DIRECT # Rich Audience
+ironsrc.com, 5fa94677b2db6a00015b22a9, DIRECT # Rise
+risecodes.com, 5fa94677b2db6a00015b22a9, DIRECT # Rise
+Pubmatic.com, 160295, RESELLER, 5d62403b186f2ace # Rise
+spotxchange.com, 304965, RESELLER, 7842df1d2fe2db34 # Rise
+spotx.tv, 304965, RESELLER, 7842df1d2fe2db34 # Rise
+indexexchange.com, 185996, DIRECT # Rise
+rubiconproject.com, 13762, RESELLER, 0bfd66d529a55807 # Rubicon
+sharethrough.com, 31c129df, DIRECT, d53b998a7bd4ecd2 # Sharethrough
+indexexchange.com, 186046, RESELLER # Sharethrough
+rubiconproject.com, 18694, RESELLER, 0bfd66d529a55807 # Sharethrough
+smartadserver.com, 3490, DIRECT # Smart RTB Display and Video
+appnexus.com, 3703, RESELLER, f5ab79cb980f11d1 # Smart RTB
+rubiconproject.com, 16114, RESELLER, 0bfd66d529a55807 # Smart RTB
+sonobi.com, 116da9d98c, DIRECT, d1a215d9eb5aee9e # Sonobi
+rhythmone.com, 1059622079, RESELLER, a670c89d4a324e47 # Sonobi
+contextweb.com, 560606, RESELLER, 89ff185a4c4e857c # Sonobi
+sovrn.com, 237754, DIRECT, fafdf38b16bf6b2b # Sovrn
+themediagrid.com,FLBAK7,DIRECT,35d5010d7789b49d # Themediagrid
+themediagrid.com,LTW57M,DIRECT,35d5010d7789b49d # Themediagrid New
+triplelift.com, 6059, DIRECT, 6c33edb13117fd86 # Triplelift
+appnexus.com, 1314, RESELLER, f5ab79cb980f11d1 # Triplelift
+ucfunnel.com, pub-627DB429DDBB82ADFEE44B8DE4E78376, DIRECT # Ucfunnel
+aralego.com, pub-627DB429DDBB82ADFEE44B8DE4E78376, DIRECT # Aralego
+adiiix.com, pub-627DB429DDBB82ADFEE44B8DE4E78376, DIRECT # Adiiix
+undertone.com, 3860, DIRECT # Undertone
+appnexus.com, 2234, RESELLER # Undertone
+openx.com, 537153564, RESELLER, 6a698e2ec38604c6 # Undertone
+rubiconproject.com, 22412, RESELLER, 0bfd66d529a55807 # Undertone
+advertising.com, 28650, RESELLER # Undertone
+aol.com, 55305, DIRECT # Verizon
+yahoo.com, 55305, DIRECT # Verizon
+adtech.com, 4596, DIRECT # Verizon
+aolcloud.net, 4596, DIRECT # Verizon
+appnexus.com, 806, DIRECT, f5ab79cb980f11d1 # Xandr
+appnexus.com,1908,RESELLER,f5ab79cb980f11d1 # Xandr
+appnexus.com, 7911, RESELLER # Yieldmo
+rubiconproject.com, 17070, RESELLER, 0bfd66d529a55807 # Yieldmo
+yieldmo.com, 2440034636282143652, DIRECT # Yieldmo
+
+#Video
+#------------------------------------------------------------------------------------------------------
+
+advertising.com, 2694, DIRECT # Verizon AOL video
+google.com, pub-5781531207509232, DIRECT, f08c47fec0942fa0 # AdX
+google.com, pub-4968145218643279, DIRECT, f08c47fec0942fa0 # Adx Test
+google.com, pub-4968145218643279, RESELLER, f08c47fec0942fa0 # Adx Test
+google.com, pub-2553634189837243, DIRECT, f08c47fec0942fa0 # AdS
+aniview.com, 5f2063121d82c82557194737, RESELLER, 78b21b97965ec3f8 # Aniview
+advertising.com, 23089, RESELLER # Aniview
+appnexus.com, 9382, RESELLER, f5ab79cb980f11d1 # Aniview
+google.com, pub-5717092533913515, RESELLER, f08c47fec0942fa0 # Aniview
+google.com, pub-4586415728471297, RESELLER, f08c47fec0942fa0 # Aniview
+pubmatic.com, 159941, RESELLER, 5d62403b186f2ace # Aniview
+smartadserver.com, 2786, DIRECT # Aniview
+improvedigital.com, 1147, DIRECT # Aniview
+appnexus.com, 10112, RESELLER # Aniview
+appnexus.com, 7445, DIRECT # Adbility
+google.com, pub-7452201096415972, DIRECT, f08c47fec0942fa0 # Adbility
+smartclip.net, 8153, DIRECT # Adbility
+spotxchange.com, 245212, DIRECT, 7842df1d2fe2db34 # Adbility
+spotx.tv, 245212, DIRECT, 7842df1d2fe2db34 # Adbility
+adform.com, 2767, RESELLER # AdForm
+appnexus.com, 806, DIRECT # Xandr video
+spotxchange.com,81557, RESELLER, 7842df1d2fe2db34 # Digiteka
+spotx.tv, 81557, RESELLER, 7842df1d2fe2db34 # Digiteka
+spotxchange.com, 182292, RESELLER, 7842df1d2fe2db34 # Digiteka
+spotx.tv, 182292, RESELLER, 7842df1d2fe2db34 # Digiteka
+google.com, pub-7026431251527825, RESELLER, f08c47fec0942fa0 # Digiteka
+google.com, pub-5549723401598621, DIRECT, f08c47fec0942fa0 # Digiteka
+freewheel.tv, 1953, DIRECT # Freewheel
+freewheel.tv, 187721, DIRECT # Freewheel
+freewheel.tv, 211121, DIRECT # Freewheel
+freewheel.tv, 196129, DIRECT # Freewheel
+freewheel.tv, 228641, DIRECT # Freewheel
+freewheel.tv, 187865, DIRECT # Freewheel
+freewheel.tv, 211129, DIRECT # Freewheel
+freewheel.tv, 196145, DIRECT # Freewheel
+freewheel.tv, 228649, DIRECT # Freewheel
+improvedigital.com, 1012, DIRECT # Improve prebid
+indexexchange.com, 183921, DIRECT, 50b1c356f2c5c8fc # Index video
+ironsrc.com, 5fa94677b2db6a00015b22a9, DIRECT # IronSource
+ironsrc.com, 5a169d7d9515390002000001, DIRECT # IronSource
+openx.com, 537140488, Direct, 6a698e2ec38604c6 # IronSource
+Pubmatic.com, 159087, DIRECT, 5d62403b186f2ace # IronSource
+Advertising.com, 8693, DIRECT # IronSource
+lkqd.net, 304, DIRECT, 59c49fa9598a0117 # LKQD video
+lkqd.com, 304, RESELLER, 59c49fa9598a0117 # LKQD video
+loopme.com, 10509, RESELLER, 6c8d5f95897a5a3b # LoopMe
+loopme.com, 10509, DIRECT, 6c8d5f95897a5a3b # LoopMe
+rubiconproject.com, 20744, RESELLER, 0bfd66d529a55807 # LoopMe
+engagebdr.com, 10181, RESELLER # LoopMe
+onetag.com, 59c7d7f65f9d658, DIRECT # OneTag
+openx.com, 540134228, DIRECT, 6a698e2ec38604c6 # OpenX video
+openx.com, 540634629, DIRECT, 6a698e2ec38604c6 # OpenX video
+pubmatic.com,159234,DIRECT,5d62403b186f2ace # Pubmatic Video
+pubmatic.com, 160552, RESELLER, 5d62403b186f2ace # Pubmatic oRTB
+richaudience.com, 1XvIoD5o0S, DIRECT # Rich Audience
+risecodes.com, 5fa94677b2db6a00015b22a9, DIRECT # Rise Codes RTB
+rubiconproject.com, 13762, DIRECT, 0bfd66d529a55807 # Rubicon video
+smartadserver.com, 3490, DIRECT # Smartadserver video
+spotx.tv, 141412, DIRECT, 7842df1d2fe2db34 # Spotx video
+spotxchange.com, 141412, DIRECT, 7842df1d2fe2db34 # Spotx video
+springserve.com, 550, DIRECT, a24eb641fc82e93d # SpringServe
+beachfront.com, 4969, RESELLER, e2541279e8e2ca4d # SpringServe
+advertising.com, 26282, RESELLER # SpringServe
+pubmatic.com, 157310, RESELLER, 5d62403b186f2ace # SpringServe
+rhythmone.com, 2968119028, RESELLER, a670c89d4a324e47 # SpringServe
+spotxchange.com, 239904, RESELLER, 7842df1d2fe2db34 # SpringServe
+spotx.tv, 239904, RESELLER, 7842df1d2fe2db34 # SpringServe
+contextweb.com, 561910, RESELLER, 89ff185a4c4e857c # SpringServe
+openx.com, 540226160, RESELLER, 6a698e2ec38604c6 # SpringServe
+openx.com, 540255318, RESELLER, 6a698e2ec38604c6 # SpringServe
+ssp.ynxs.io, 185, RESELLER # SpringServe
+teads.tv, 16676, DIRECT, 15a9c44f6d26cbe1 # Teads video
+tremorhub.com, hpwve, RESELLER, 1a4e959a1b50034a # Telaria video
+telaria.com, hpwve, RESELLER, 1a4e959a1b50034a # Telaria video
+video.unrulymedia.com, UNRX-PUB-29dad46b-9bec-43c7-b950-c59d09cc8c71, DIRECT # Unruly RONE
+video.unrulymedia.com, 985572675, DIRECT # Unruly RONE
+rhythmone.com, 2864567592, DIRECT, a670c89d4a324e47 # Unruly RONE
+vidoomy.com, 56924, DIRECT # Vidoomy
+aol.com, 22762, DIRECT # Vidoomy
+freewheel.tv, 872257, DIRECT # Vidoomy
+freewheel.tv, 894193, DIRECT # Vidoomy
+lkqd.com, 430, DIRECT, 59c49fa9598a0117 # Vidoomy
+lkqd.net, 430, DIRECT, 59c49fa9598a0117 # Vidoomy
+openx.com, 540804929, DIRECT, 6a698e2ec38604c6 # Vidoomy
+spotx.tv, 218443, DIRECT, 7842df1d2fe2db34 # Vidoomy
+spotxchange.com, 218443, DIRECT, 7842df1d2fe2db34 # Vidoomy
+emxdgt.com, 1495, DIRECT, 1e1d41537f7cad7f # Vidoomy
+appnexus.com, 1356, DIRECT, f5ab79cb980f11d1 # Vidoomy
+
+#Rich Media
+#------------------------------------------------------------------------------------------------------
+openx.com, 539640546, RESELLER, 6a698e2ec38604c6 # JustP
+appnexus.com, 7118, RESELLER # JustP
+improvedigital.com, 185, RESELLER # JustP
+indexexchange.com, 189872, RESELLER # JustP
+pubmatic.com, 160210, RESELLER, 5d62403b186f2ace # JustP
+rhythmone.com,4116102010,RESELLER,a670c89d4a324e47 # JustP
+video.unrulymedia.com,4116102010, RESELLER # JustP
+
+
+#Affiliate
+#------------------------------------------------------------------------------------------------------
+revcontent.com, 130780, DIRECT # Rev Content
+appnexus.com, 7666, RESELLER, f5ab79cb980f11d1 # Rev Content
+my6sense.com, 9732, RESELLER # Rev Content
+engagebdr.com, 10304, RESELLER # Rev Content
+synacor.com, 82291, RESELLER, e108f11b2cdf7d5b # Rev Content
+indexexchange.com, 192143, RESELLER # Rev Content
+target.my.com, 10731977, DIRECT # Target
+pubmatic.com, 10731977, RESELLER # Target
+admixer.com, 10731977, RESELLER # Target
+onetag.com, 59d216e971852f2, RESELLER # Target
+admixer.net, 2878f07c-cc3f-4f8a-a26c-8e6033a539a6, RESELLER # Target
+betweendigital.com, 43092, RESELLER # Target
+e-planning.net, ec771b05828a67fa, RESELLER # Target
+improvedigital.com, 1532, RESELLER # Target
+lijit.com, 273644, RESELLER # Target
+loopme.com, 11278, RESELLER # Target
+onetag.com, 5d1628750185ace, RESELLER # Target
+openx.com, 540298543, RESELLER # Target
+openx.com, 541031350, RESELLER # Target
+openx.com, 541177349, RESELLER # Target
+pubmatic.com, 156631, RESELLER # Target
+pubmatic.com, 158154, RESELLER # Target
+pubmatic.com, 159542, RESELLER # Target
+pubmatic.com, 159668, RESELLER # Target
+rhythmone.com, 3880497124, RESELLER # Target
+rubiconproject.com, 19724, RESELLER # Target
+rubiconproject.com, 20744, RESELLER # Target
+sovrn.com, 273644, RESELLER # Target
diff --git a/static/languages/_groups.json b/static/languages/_groups.json
index a38dee3e6..8825f844b 100644
--- a/static/languages/_groups.json
+++ b/static/languages/_groups.json
@@ -21,6 +21,10 @@
"name": "arabic",
"languages": ["arabic"]
},
+ {
+ "name": "malagasy",
+ "languages": ["malagasy", "malagasy_1k"]
+ },
{
"name": "malay",
"languages": ["malay"]
diff --git a/static/languages/_list.json b/static/languages/_list.json
index 369e98330..4a69661cf 100644
--- a/static/languages/_list.json
+++ b/static/languages/_list.json
@@ -12,6 +12,8 @@
,"french_2k"
,"french_10k"
,"arabic"
+ ,"malagasy"
+ ,"malagasy_1k"
,"malay"
,"mongolian"
,"mongolian_10k"
diff --git a/static/languages/malagasy.json b/static/languages/malagasy.json
new file mode 100644
index 000000000..df9176132
--- /dev/null
+++ b/static/languages/malagasy.json
@@ -0,0 +1,206 @@
+{
+ "name": "malagasy",
+ "leftToRight": true,
+ "words": [
+ "izany",
+ "no",
+ "izy",
+ "anaka",
+ "hoy",
+ "ny",
+ "efa",
+ "ka",
+ "zakao",
+ "tsia",
+ "rainy",
+ "tsy",
+ "avy",
+ "izao",
+ "fa",
+ "atao",
+ "hoe",
+ "tsara",
+ "anie",
+ "izay",
+ "teto",
+ "anao",
+ "nefa",
+ "nisy",
+ "hono",
+ "ho",
+ "aho",
+ "ry",
+ "dada",
+ "ve",
+ "ity",
+ "ary",
+ "aminy",
+ "dia",
+ "vita",
+ "teny",
+ "misy",
+ "olona",
+ "azo",
+ "eny",
+ "ianao",
+ "ilay",
+ "raha",
+ "sy",
+ "hita",
+ "tody",
+ "dieny",
+ "aoka",
+ "eto",
+ "mba",
+ "loza",
+ "be",
+ "soa",
+ "ratsy",
+ "mamy",
+ "na",
+ "samy",
+ "hafa",
+ "asa",
+ "tokoa",
+ "io",
+ "natao",
+ "ireny",
+ "any",
+ "azy",
+ "noho",
+ "hahay",
+ "tia",
+ "ihany",
+ "koa",
+ "sady",
+ "saina",
+ "ireo",
+ "poeta",
+ "anefa",
+ "mety",
+ "akory",
+ "maha",
+ "eo",
+ "avo",
+ "isaky",
+ "isika",
+ "tena",
+ "feo",
+ "ao",
+ "manao",
+ "adidy",
+ "araka",
+ "injao",
+ "amina",
+ "iza",
+ "inona",
+ "fomba",
+ "mandà",
+ "asany",
+ "afaka",
+ "irery",
+ "tonga",
+ "azoko",
+ "toa",
+ "mila",
+ "iray",
+ "hatao",
+ "andry",
+ "momba",
+ "kosa",
+ "an’ny",
+ "zony",
+ "hiasa",
+ "mbola",
+ "aina",
+ "mahay",
+ "biby",
+ "anaty",
+ "aza",
+ "kokoa",
+ "ampy",
+ "olana",
+ "hery",
+ "toy",
+ "ara",
+ "antsy",
+ "nosy",
+ "vao",
+ "maro",
+ "dihy",
+ "vary",
+ "sisa",
+ "maso",
+ "aleo",
+ "very",
+ "may",
+ "vava",
+ "tsapa",
+ "tany",
+ "taona",
+ "tiako",
+ "ery",
+ "anay",
+ "loha",
+ "lova",
+ "malagasy",
+ "omeny",
+ "lanja",
+ "afa",
+ "miala",
+ "inty",
+ "àry",
+ "tao",
+ "teo",
+ "miova",
+ "ray",
+ "iny",
+ "saigy",
+ "fiara",
+ "tsiny",
+ "resy",
+ "hisy",
+ "aminy",
+ "milza",
+ "liana",
+ "azao",
+ "vola",
+ "dimy",
+ "arivo",
+ "krizy",
+ "firy",
+ "tsena",
+ "feno",
+ "lasa",
+ "manko",
+ "kiry",
+ "miasa",
+ "voho",
+ "dika",
+ "roa",
+ "telo",
+ "lany",
+ "hay",
+ "dia",
+ "maty",
+ "kanto",
+ "sy",
+ "aty",
+ "amidy",
+ "foana",
+ "boky",
+ "jamba",
+ "adika",
+ "radio",
+ "te",
+ "nanao",
+ "ireto",
+ "an'ny",
+ "ala",
+ "hazo",
+ "tiana",
+ "aloka",
+ "manja",
+ "lahy"
+ ]
+}
diff --git a/static/languages/malagasy_1k.json b/static/languages/malagasy_1k.json
new file mode 100644
index 000000000..f9d4a648d
--- /dev/null
+++ b/static/languages/malagasy_1k.json
@@ -0,0 +1,1006 @@
+{
+ "name": "malagasy_1k",
+ "leftToRight": true,
+ "words": [
+ "izany",
+ "anaka",
+ "ingahy",
+ "manohy",
+ "teniny",
+ "anjaranao",
+ "zakao",
+ "rainy",
+ "namaly",
+ "an-janany",
+ "aminay",
+ "mivady",
+ "velively",
+ "andeha",
+ "Andriamanitra",
+ "henoinao",
+ "tsara",
+ "firifiry",
+ "tovolahy",
+ "nangata-bady",
+ "tanteraka",
+ "mihantsy",
+ "an-drainy",
+ "heverinao",
+ "mariky",
+ "fahalemena",
+ "olombelona",
+ "fampidirana",
+ "anjara",
+ "mandalo",
+ "lahatra",
+ "vintana",
+ "rehefa",
+ "tsapany",
+ "mahita",
+ "vahaolana",
+ "hamaliany",
+ "mifanandrina",
+ "aminy",
+ "famotorana",
+ "olona",
+ "notanana",
+ "tamina",
+ "fitondrana",
+ "volamena",
+ "antsokosoko",
+ "aiditra",
+ "am-ponja",
+ "ianao",
+ "lahy",
+ "vehivavy",
+ "hiandry",
+ "fitsarana",
+ "mpitsara",
+ "mpanao",
+ "rehetra",
+ "dinihina",
+ "fakafakaina",
+ "fanafodin’izany",
+ "indrindra",
+ "manomana",
+ "fampiasana",
+ "lalàna",
+ "dieny",
+ "ankehitriny",
+ "rahampitso",
+ "rahafakampitso",
+ "hiara-mamafy",
+ "an-tany",
+ "mahasoa",
+ "hijinjana",
+ "taranaka",
+ "zazakely",
+ "mifandimby",
+ "rahatoandro",
+ "vokatry",
+ "ataona",
+ "tolakandro",
+ "mahatonga",
+ "fahoriana",
+ "ohatrinona",
+ "mameno",
+ "fiainana",
+ "amin’izao",
+ "fotoana",
+ "todiana",
+ "nataona",
+ "tandremo",
+ "levenam-bola",
+ "ratsy",
+ "mihantona",
+ "hosoran-tsakay",
+ "mangidy",
+ "hoditra",
+ "hosoran-tantely",
+ "maharatsy",
+ "amina",
+ "resaka",
+ "ifanaovana",
+ "andavanandro",
+ "mpanoratra",
+ "voasokajy",
+ "tokoa",
+ "satria",
+ "natao",
+ "hiantefa",
+ "mijanona",
+ "fananan-tsamirery",
+ "mirakitra",
+ "hafatra",
+ "hatrany",
+ "hahafahana",
+ "ireny",
+ "hipaka",
+ "marina",
+ "mpamaky",
+ "mpihaino",
+ "niniana",
+ "nampihaingoana",
+ "nampiavaka",
+ "fandre",
+ "lavina",
+ "ilaina",
+ "isam-batana",
+ "literatiora",
+ "mampianatra",
+ "hahay",
+ "hanasokajy",
+ "mandrisika",
+ "hitrandraka",
+ "hikajy",
+ "soatoavina",
+ "manefy",
+ "toe-tsaina",
+ "mamorona",
+ "mikaroka",
+ "vidiny",
+ "rahoviana",
+ "ihany",
+ "mpanabe",
+ "mpampianatra",
+ "tompon’andraikitra",
+ "fanolokoloana",
+ "saina",
+ "malagasy",
+ "mampahatsiahy",
+ "izahay",
+ "voafaritrao",
+ "poeta",
+ "sakafon-tsaina",
+ "natolotrao",
+ "nojerenao",
+ "akaiky",
+ "vangavanga",
+ "iainana",
+ "anananao",
+ "andraikitra",
+ "zava-bahiny",
+ "antonona",
+ "toe-batany",
+ "nasainao",
+ "nateliny",
+ "nankarary",
+ "ambavafony",
+ "anefa",
+ "varavarana",
+ "mampangetaheta",
+ "mangetaheta",
+ "impiry",
+ "mieritreritra",
+ "fahaizana",
+ "mandanjalanja",
+ "aminao",
+ "mamorika",
+ "saina",
+ "miharatsy",
+ "rahateo",
+ "làlana",
+ "mankaiza",
+ "hisarihanao",
+ "mpitari-dàlana",
+ "fanafoanana",
+ "akory",
+ "fanagasiana",
+ "fanandratana",
+ "toerana",
+ "isaky",
+ "mandinika",
+ "isika",
+ "hamantatra",
+ "ahoana",
+ "nahoana",
+ "toetr'andro",
+ "tokony",
+ "ara-bola",
+ "hitondrantsika",
+ "mibitsika",
+ "anatintsika",
+ "manao",
+ "roapolo",
+ "telopolo",
+ "vahoaka",
+ "hampiova",
+ "manomboka",
+ "efa-polo",
+ "adidinao",
+ "nahatanteraka",
+ "adidy",
+ "natolotra",
+ "antsika",
+ "araka",
+ "injao",
+ "manako",
+ "manohitra",
+ "ataontsika",
+ "miteny",
+ "amintsika",
+ "endrika",
+ "fibaikona",
+ "tsapantsika",
+ "maintsy",
+ "nipoitra",
+ "amina",
+ "fisiana",
+ "ambony",
+ "hitantsika",
+ "mazava",
+ "inona",
+ "fiarahamonina",
+ "mamolavola",
+ "ara-moraly",
+ "nametraka",
+ "fihetseham-po",
+ "mandidy",
+ "fitondratenantsika",
+ "fomba",
+ "hentitra",
+ "alalana",
+ "herintsika",
+ "mandà",
+ "hankato",
+ "baikony",
+ "asany",
+ "maneho",
+ "fieritreretantsika",
+ "fahatsiarovantenantsika",
+ "afaka",
+ "miara-monina",
+ "fijaliana",
+ "iraisantsika",
+ "manentana",
+ "fontsika",
+ "maha-olona",
+ "hataontsika",
+ "fifamatorana",
+ "fahafenoana",
+ "tsirairay",
+ "nanana",
+ "nilàna",
+ "nieritreritra",
+ "hitambatra",
+ "amin’izy",
+ "fahalementsika",
+ "teraka",
+ "fahasambarana",
+ "marefontsika",
+ "sambatra",
+ "mitoka-monina",
+ "irery",
+ "miaina",
+ "faratampony",
+ "tonga",
+ "lafatra",
+ "mahavita",
+ "samirery",
+ "hifaliany",
+ "hevintsika",
+ "mijaly",
+ "azoko",
+ "saintsainina",
+ "zavatra",
+ "teoria",
+ "fitambarana",
+ "hevitsika",
+ "ara-tsiansa",
+ "fandinihana",
+ "zava-misy",
+ "hatao",
+ "andry",
+ "iankinana",
+ "hevitra",
+ "fanadihadiana",
+ "vaovao",
+ "misotro",
+ "kanefa",
+ "ivalozana",
+ "vonona",
+ "handao",
+ "lalandava",
+ "hanova",
+ "momba",
+ "ankizy",
+ "intsony",
+ "indraim-bava",
+ "hovàna",
+ "hifanaraka",
+ "natiora",
+ "androany",
+ "fifehezana",
+ "faneriterena",
+ "hahatonga",
+ "fananana",
+ "ijoroana",
+ "fanjakana",
+ "hanafaka",
+ "tahotra",
+ "hiainany",
+ "am-pilaminana",
+ "hitazonany",
+ "tratra",
+ "miteraka",
+ "fahavoazana",
+ "ana",
+ "voa-janahary",
+ "hiaina",
+ "hiasa",
+ "mbola",
+ "averiko",
+ "indray",
+ "zava-kendrena",
+ "hamadika",
+ "zava-manana",
+ "mahay",
+ "anisany",
+ "masiaka",
+ "misaina",
+ "mifanohitra",
+ "amin’izany",
+ "najoro",
+ "hahafahana",
+ "fanahy",
+ "vatana",
+ "manefa",
+ "andraikiny",
+ "natiorany",
+ "anaty",
+ "fiaraha-monina",
+ "nilaina",
+ "notsiriritina",
+ "hiara-miaina",
+ "tombontsoa",
+ "iombonana",
+ "mampitambatra",
+ "iainany",
+ "tsaratsara",
+ "kokoa",
+ "tanjontsika",
+ "voalohany",
+ "iraisana",
+ "manokana",
+ "mitambatra",
+ "fiarovana",
+ "fotsiny",
+ "karazana",
+ "mihitsy",
+ "an’ireo",
+ "nitsinjarana",
+ "ianjadiana",
+ "loatra",
+ "antony",
+ "hijanonana",
+ "jadona",
+ "resahiko",
+ "afak'omaly",
+ "omaly",
+ "fitondram-panjakana",
+ "fitantanana",
+ "manampy",
+ "trotraka",
+ "olana",
+ "ara-drariny",
+ "anampina",
+ "hampiharihary",
+ "firavonana",
+ "fangejana",
+ "malaza",
+ "mpandala",
+ "demôkrasia",
+ "fahalalahana",
+ "fahefana",
+ "moraly",
+ "mitaky",
+ "fizika",
+ "manery",
+ "fandriana",
+ "andrirana",
+ "antsy",
+ "fombam-piainana",
+ "mahazatra",
+ "hoana",
+ "didiana",
+ "traikefa",
+ "hohamarinina",
+ "vitana",
+ "takiana",
+ "mametraka",
+ "atositosika",
+ "hiakatra",
+ "amboninan",
+ "baikona",
+ "manana",
+ "raharaha",
+ "voatokana",
+ "ara-tsosialy",
+ "anolona",
+ "tokana",
+ "finoana",
+ "siansa",
+ "matetika",
+ "mifankahala",
+ "voaaro",
+ "ara-piaraha-monina",
+ "andamosina",
+ "mijoro",
+ "vondron’olona",
+ "hihazakazaka",
+ "hamonjy",
+ "manam-piadiana",
+ "iantsoana",
+ "zanaky",
+ "Madagasikara",
+ "maheno",
+ "antsaina",
+ "tontolo",
+ "iainana",
+ "zava-maniry",
+ "toeran-kafa",
+ "kolontsaina",
+ "taozavatra",
+ "zavakanto",
+ "gadonkira",
+ "hosodoko",
+ "iangalian’ireo",
+ "mpanankato",
+ "mahalatsadanja",
+ "sehatra",
+ "iraisam-pirenena",
+ "vakoka",
+ "fitafy",
+ "hanin-kohanina",
+ "taotrano",
+ "isam-paritra",
+ "fonenana",
+ "tranogasy",
+ "mampiavaka",
+ "fisainana",
+ "amam-panahy",
+ "enti-miaina",
+ "fahendrena",
+ "fihavanana",
+ "fona",
+ "miainga",
+ "amin’ilay",
+ "filozofia",
+ "lalina",
+ "alina",
+ "halina",
+ "herinandro",
+ "voatondraka",
+ "ataovy",
+ "fihavana-molotra",
+ "tanana",
+ "maharary",
+ "molotra",
+ "manafosafo",
+ "mitsoka",
+ "amina",
+ "mpandoatra",
+ "sarahina",
+ "tapaka",
+ "tohiaina",
+ "iraisana",
+ "tsapa",
+ "alalana",
+ "anisana",
+ "fototra",
+ "ijorona",
+ "tambatra",
+ "marika",
+ "lehibe",
+ "ijoroana",
+ "firenena",
+ "anehoany",
+ "manetsa",
+ "eoropa",
+ "fankalazana",
+ "tondrahana",
+ "tamina",
+ "taona",
+ "tiako",
+ "homarihina",
+ "mahafinaritra",
+ "mandre",
+ "masoivoho",
+ "manintona",
+ "fiteninareo",
+ "tantarana",
+ "anareo",
+ "mampiray",
+ "ahafahanareo",
+ "mifanerasera",
+ "mifanakalo",
+ "iraisana",
+ "zanahary",
+ "razana",
+ "noheveriny",
+ "nahary",
+ "mitahy",
+ "lohasaha",
+ "mangina",
+ "jerena",
+ "an-tampona",
+ "nampoizina",
+ "nasesiky",
+ "fintinina",
+ "firaisana",
+ "amam-panao",
+ "mijoroa",
+ "malagasy",
+ "hitahiry",
+ "hanandratra",
+ "fototry",
+ "napetraky",
+ "razantsika",
+ "sombin-dahatsoratra",
+ "hananana",
+ "fampivoarana",
+ "hoentina",
+ "manadihady",
+ "lahatsoratra",
+ "haseho",
+ "takiana",
+ "mandala",
+ "hasina",
+ "tapany",
+ "faharoa",
+ "hanehoana",
+ "manaiky",
+ "fandrosoana",
+ "andro",
+ "hivoarana",
+ "hasin-javatra",
+ "omeny",
+ "lanja",
+ "anankinany",
+ "fiainany",
+ "fahavalo",
+ "avokoa",
+ "miala",
+ "nanankina",
+ "fahavelomany",
+ "tamin’ireo",
+ "kolon-tsaina",
+ "fomba-piheverana",
+ "manavaka",
+ "fanjanahantany",
+ "fidirana",
+ "vahiny",
+ "namotika",
+ "tsikelikely",
+ "am-pona",
+ "fanomezan-kasina",
+ "nentim-paharazana",
+ "nanosika",
+ "ankamaroana",
+ "hanentana",
+ "aminatokony",
+ "hitadiavana",
+ "hailika",
+ "homena",
+ "namiavaka",
+ "ntaolo",
+ "fanomezana",
+ "mampirindra",
+ "voahaja",
+ "fepetra",
+ "fahaiza-miaina",
+ "anivona",
+ "mpiara-belona",
+ "mitaiza",
+ "ara-pitondran-tena",
+ "ametrahana",
+ "ahiahy",
+ "hoenankaiza",
+ "fifanajana",
+ "niharava",
+ "fifampitokisana",
+ "nihavery",
+ "fakan-tahaka",
+ "ivelany",
+ "nanefy",
+ "hanambony",
+ "mihevi-tena",
+ "mandroso",
+ "mahafoy",
+ "endri-pifandraisana",
+ "tarafina",
+ "amin’ireo",
+ "tafalentika",
+ "an-tsaina",
+ "miova",
+ "maharaka",
+ "eran-tany",
+ "fombam-piheverana",
+ "noraisina",
+ "faharahana",
+ "toetr’andro",
+ "fivoarana",
+ "fifikirana",
+ "loharano",
+ "nipoirany",
+ "nohajaina",
+ "napetraka",
+ "hatramina",
+ "aman-dreny",
+ "nilaza",
+ "nahitana",
+ "masoandro",
+ "enin-kaja",
+ "enim-boninahitra",
+ "toe-javatra",
+ "harena",
+ "nandresy",
+ "averina",
+ "laoniny",
+ "fiatrehana",
+ "famerenana",
+ "toerany",
+ "hasina",
+ "fitaovana",
+ "mandrafitra",
+ "fiarovan-tena",
+ "arofanina",
+ "mamefy",
+ "fitondran-tena",
+ "nibaiko",
+ "hitady",
+ "filaminana",
+ "hanjakana",
+ "lavitry",
+ "herisetra",
+ "nahatonga",
+ "hilaza",
+ "hianjerana",
+ "nisongadina",
+ "tamin’iny",
+ "mamerina",
+ "hojerena",
+ "manaraka",
+ "fivoaram-piainana",
+ "mivoaka",
+ "saingy",
+ "mandray",
+ "mampivady",
+ "fandraisana",
+ "miditra",
+ "fandraharahana",
+ "kolon-tsaina",
+ "iorenana",
+ "olom-banona",
+ "an’ity",
+ "fiezahana",
+ "hametraka",
+ "mamantatra",
+ "hataony",
+ "hitarika",
+ "midika",
+ "manampanahy",
+ "mampandroso",
+ "alalana",
+ "fiezahana",
+ "fitondran-tenany",
+ "mendrika",
+ "olon-kendry",
+ "fahalalana",
+ "mavesatra",
+ "hiavaka",
+ "zava-boahary",
+ "narosona",
+ "marin-toetra",
+ "mahafantatra",
+ "anatrehany",
+ "iavahana",
+ "irosoany",
+ "naiorenana",
+ "fitsipika",
+ "ifampitondrany",
+ "niorenana",
+ "isana",
+ "lalàm-piarahamonina",
+ "nifampitondrana",
+ "fanajana",
+ "heverina",
+ "nahombiazana",
+ "fanabeazana",
+ "hampitaha",
+ "lalàna",
+ "tsiny",
+ "lalàm-pitondrana",
+ "napetrakiny",
+ "kristiana",
+ "antoka",
+ "tan-dalàna",
+ "miroso",
+ "liam-pivoarana",
+ "manamafy",
+ "amin’",
+ "lahatsorany",
+ "nandre",
+ "firenana",
+ "hivelona",
+ "handroso",
+ "mana-javatra",
+ "hajaina",
+ "atahorana",
+ "hiasana",
+ "fanahy-tahotra",
+ "fandrosoany",
+ "manodidina",
+ "fanomezan-danja",
+ "apetraka",
+ "nipoirana",
+ "notrandrahina",
+ "liana",
+ "hametrahana",
+ "hiavahana",
+ "hafalalàna",
+ "ahatanteraka",
+ "ifampifehezana",
+ "hisondrotana",
+ "firosoana",
+ "kendrena",
+ "hahavery",
+ "indindra",
+ "manoloana",
+ "fihazakazaky",
+ "ahitana",
+ "fiantraikany",
+ "ekonomia",
+ "fiaina",
+ "maneran-tany",
+ "valan’aretina",
+ "aretina",
+ "mponina",
+ "latsaky",
+ "arivo",
+ "isan’andro",
+ "mitarika",
+ "fanjarian-tsakafo",
+ "manasarotra",
+ "krizy",
+ "ara-toekarena",
+ "fizahan-tany",
+ "indostria",
+ "iankinana",
+ "toe-karena",
+ "fisiana",
+ "mpizahan-tany",
+ "mpikaroka",
+ "fahasahiranana",
+ "manimba",
+ "toe-karenany",
+ "hambopom-pirenena",
+ "firenen-dehibe",
+ "lembenana",
+ "mampiaka-peo",
+ "mandon-databatra",
+ "mahatsiaro",
+ "voatohatohana",
+ "tombotsoany",
+ "fiandrianam-pirenena",
+ "betsaka",
+ "kihana",
+ "lazaina",
+ "mikasika",
+ "an’izany",
+ "fanehoana",
+ "hambopo-pirenena",
+ "manamarika",
+ "angovo",
+ "fitiavan-tseza",
+ "fitiavan-tena",
+ "nanimbantsika",
+ "vitana",
+ "tenantsika",
+ "mandamina",
+ "mitondra",
+ "fampandrosoana",
+ "tanintsika",
+ "fivoarana",
+ "fampandehanan-draharaha",
+ "ara-panjakana",
+ "miankina",
+ "fanampiana",
+ "mpandraharaha",
+ "mitarain-dava",
+ "entana",
+ "manjaka",
+ "tsena",
+ "am-pelantanana",
+ "mpanambola",
+ "ara-ekonomika",
+ "fampiasany",
+ "firenen-tsamihafa",
+ "mahomby",
+ "ahafahana",
+ "mifehy",
+ "mamolaka",
+ "fahaiza-manao",
+ "tekinika",
+ "anabeazana",
+ "fampianaranaazy",
+ "itaizana",
+ "mpianatra",
+ "somary",
+ "nampihisatra",
+ "angamba",
+ "fanitsiana",
+ "lahatsoratry",
+ "iandreketako",
+ "navoakako",
+ "taitra",
+ "maharesaka",
+ "niezaka",
+ "hamelo-maso",
+ "mandrakariva",
+ "bolongana",
+ "mena-mitaha",
+ "amin'ireo",
+ "manandanja",
+ "fahasarotana",
+ "mirona",
+ "teknolojia",
+ "maoderina",
+ "resahina",
+ "mpampiasa",
+ "manko",
+ "mifanipaka",
+ "amin'izay",
+ "dikanteny",
+ "filohana",
+ "fikambanana",
+ "rindrambaiko",
+ "indraindray",
+ "mafiloha",
+ "fitazonana",
+ "maniry",
+ "fiarahana",
+ "miasa",
+ "manabe",
+ "an-tserasera",
+ "miangavy",
+ "fiteny",
+ "Anglisy",
+ "hanitsy",
+ "famoahan-kevitry",
+ "hohatsaraina",
+ "mamaky",
+ "haintsika",
+ "manolo-kevitra",
+ "ron-doha",
+ "avadika",
+ "hatramin'izao",
+ "tsotra",
+ "marihina",
+ "manampahaizana",
+ "nitozo",
+ "tamin'ilay",
+ "farany",
+ "hitafa",
+ "toetra",
+ "tanjaka",
+ "soavaly",
+ "ambany",
+ "kilasy",
+ "ampondra",
+ "fahaiza-manidina",
+ "vorona",
+ "voromailala",
+ "toe-po",
+ "fahatsiarovan-tena",
+ "samihafa",
+ "mitranga",
+ "ambonina",
+ "zava-manan’aina",
+ "anatina",
+ "tantarana",
+ "fandravana",
+ "fiakarana",
+ "isana",
+ "nifoha",
+ "maraina",
+ "olom-pirenena",
+ "taranja",
+ "fampianarana",
+ "tanjona",
+ "ahafahana",
+ "soratra",
+ "literera",
+ "mahafehy",
+ "lasitra",
+ "mikirakira",
+ "manatsoaka",
+ "manakatra",
+ "tara-kevitry",
+ "vanim-potoana",
+ "nolalovana",
+ "mahalala",
+ "lanjana",
+ "kanto",
+ "fanehoan-kevitra",
+ "am-bava",
+ "an-tsoratra",
+ "miafara",
+ "famoronana",
+ "aoriana",
+ "amidy",
+ "foana",
+ "havadika",
+ "jamba",
+ "amin’ity",
+ "adika",
+ "aparitaka",
+ "navadika",
+ "manaja",
+ "zona",
+ "mpamorona",
+ "asaivo",
+ "mihaino",
+ "radio",
+ "namanao",
+ "zanaka",
+ "hihaino",
+ "tantara",
+ "misaotra",
+ "sahady",
+ "nanao",
+ "maimaipona",
+ "ireto",
+ "mampiasa",
+ "fivarotana",
+ "fahazoan-dàlana",
+ "fizarana",
+ "ana",
+ "mikitroka",
+ "ampahany",
+ "varotra",
+ "mpiara-miombona",
+ "nahafahana",
+ "nahazo",
+ "fanampiny",
+ "Frantsay",
+ "vazaha",
+ "mpanjaka",
+ "Andriana",
+ "miombona",
+ "hatsiaka",
+ "mifanome",
+ "mibaliaka",
+ "lanitra",
+ "hifandrakotra",
+ "tafaray",
+ "ankijery",
+ "hanarina",
+ "mifanazava",
+ "handrodana",
+ "hasambarana",
+ "hisalasala",
+ "voafefy",
+ "mantsy",
+ "mandrakizay",
+ "akama",
+ "fahasalamana",
+ "manadala",
+ "mihazakazaka",
+ "politika",
+ "manahirana",
+ "mihonona",
+ "mangaina",
+ "vahana",
+ "fitiavanao",
+ "fodiana",
+ "fitiavana",
+ "soloina",
+ "mpanontany",
+ "henoko",
+ "hitako",
+ "mifamaly",
+ "misidina",
+ "tanora"
+ ]
+}
diff --git a/static/quotes/german.json b/static/quotes/german.json
index ebd634584..cbb686231 100644
--- a/static/quotes/german.json
+++ b/static/quotes/german.json
@@ -1,22 +1,10 @@
{
"language": "german",
"groups": [
- [
- 0,
- 100
- ],
- [
- 101,
- 300
- ],
- [
- 301,
- 600
- ],
- [
- 601,
- 9999
- ]
+ [0, 100],
+ [101, 300],
+ [301, 600],
+ [601, 9999]
],
"quotes": [
{
@@ -698,7 +686,7 @@
"id": 113
},
{
- "text": "Um halb neun griff Mr Dursley nach der Aktentasche, gab seiner Frau einen Schmatz auf die Wange und versuchte es auch bei Dudley mit einem Abschiedskuss. Der ging jedoch daneben, weil Dudley gerade einen Wutanfall hatte und die Wände mit seinem Haferbrei bewarf. >>Kleiner Schlingel<<, gluckste Mr Dursley, während er nach draußen ging. Er setzte sich in den Wagen und fuhr rückwärts die Einfahrt zu Nummer 4 hinaus.",
+ "text": "Um halb neun griff Mr Dursley nach der Aktentasche, gab seiner Frau einen Schmatz auf die Wange und versuchte es auch bei Dudley mit einem Abschiedskuss. Der ging jedoch daneben, weil Dudley gerade einen Wutanfall hatte und die Wände mit seinem Haferbrei bewarf. \"Kleiner Schlingel\", gluckste Mr Dursley, während er nach draußen ging. Er setzte sich in den Wagen und fuhr rückwärts die Einfahrt zu Nummer 4 hinaus.",
"source": "Harry Potter und der Stein der Weisen",
"length": 414,
"id": 114
@@ -788,4 +776,4 @@
"id": 128
}
]
-}
\ No newline at end of file
+}
diff --git a/static/themes/shadow.css b/static/themes/shadow.css
index facf19b8b..9fbb15169 100644
--- a/static/themes/shadow.css
+++ b/static/themes/shadow.css
@@ -43,7 +43,7 @@ a:hover {
}
#logo,
-.word letter.correct {
+#typingTest .word letter.correct {
animation-name: shadow;
animation-duration: 5s;
animation-iteration-count: 1;