Merge branch 'master' into mongo

This commit is contained in:
Miodec 2021-07-12 23:17:12 +01:00
commit 0036af9f73
22 changed files with 1023 additions and 276 deletions

View file

@ -3,9 +3,9 @@
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
size, disability, ethnicity, sex characteristics, gender identity, and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
@ -14,22 +14,22 @@ appearance, race, religion, or sexual identity and orientation.
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
@ -48,7 +48,7 @@ threatening, offensive, or harmful.
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
address, posting via an official social media account or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
@ -58,7 +58,7 @@ Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at bartnikjack@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
obligated to maintain confidentiality concerning the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good

View file

@ -1,15 +1,48 @@
# Contributing
## Technologies
### **Table of Contents**
- NodeJS < 14
- Firebase
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Text Editor](#text-editor)
- [Git ](#git)
- [NodeJS](#nodejs)
- [Firebase](#firebase)
- [Building and Running Monkeytype](#building-and-running-monkeytype)
- [Standards and Guidelines](#standards-and-guidelines)
- [Theme Guidelines](#theme-guidelines)
- [Language Guidelines](#language-guidelines)
- [Quote Guidelines](#quote-guidelines)
- [Questions](#questions)
## Prerequisite - Firebase Setup
---
## Getting Started
When contributing to Monkeytype, it's good to know our best practices, tips, and tricks. First, Monkeytype is written in Javascript, CSS and HTML(in order of how much of the project is in what language); thus we assume you are comfortable in in these languages or have basic knowledge of them. Our backend is in NodeJS and we use Firebase to store our user data. We use Prettier to format our code.
### Prerequisites
While most contributions don't require that you install dependencies, there are a few minimum requirements you will need to meet to be able to run the project(this is useful and almost always necessary for tasks like creating features and fixing bugs, running the project is also useful if you are contributing a theme and want to view it on the site before you contribute it). You will need a computer with a stable internet connection, Git, NodeJS with a version < 14 and Firebase, and a text editor.
#### Text Editor
If you are not a developer and wish to contribute themes, new languages, or quotes, having a text editor will make contributions _much_ easier. A popular and relatively lightweight editor [Visual Studio Code](https://code.visualstudio.com/) or VS Code. Is is the free and open-source from Microsoft. Run the installer and follow the prompts. Once you have VS Code installed, you are ready to start contributing.
#### Git
Git is optional but we _highly_ recommend you use it. Monkeytype used the Git source control management system for its version control. Assuming you don't have experience typing commmands in the command line, we suggest installing [Sourcetree](https://www.sourcetreeapp.com/). You will be able to utilize the power of Git without needing to remember any cryptic commands. However using a Git client won't give you access to the full functionality of Git but provides an easy to understand graphical user interface(GUI). Once you have downloaded Sourcetree, run the installer. While installing Sourcetree, keep your eyes peeled for the option to also install Git with Sourcetree. This is the option you will need to look for in order to install Git. **Make sure to click yes in the installer to install Git with Sourcetree.**
#### NodeJS
The installation process of NodeJS is fairly simple, navigate to the NodeJS [website](https://nodejs.org/en/) and download the `xx.xx.x LTS`. Run the installer once the download has finished.
#### Firebase
1. Create a Firebase account if you already haven't done so.
1. [Create a new Firebase project.](https://console.firebase.google.com/u/0/)
- The project name doesn't really matter, but just name it `monkeytype`.
- The project name doesn't matter, but the name `monkeytype` would be preferred.
- Google Analytics is not necessary.
1. [Install the Firebase CLI](https://firebase.google.com/docs/cli)
@ -38,7 +71,7 @@
1. Enable Firebase Authentication
- In the Firebase console, go to Authentication
- Click on `Email/Password`, enable it and save
- Click on `Email/Password`, enable it, and save
- Click on `Google`, add a support email and save
## Prerequisite - Mongo Setup
@ -48,19 +81,43 @@
1. Optional - Install [Mongodb-compass](https://www.mongodb.com/try/download/compass?tck=docs_compass). This tool can be used to see and manipulate your data visually.
1. To connect, type `mongodb://localhost:27017` in the connection string box and press connect. The monkeytype database will be created and shown` after the server is started.
## Building and Running
### Building and Running Monkeytype
<!-- https://en.wikipedia.org/wiki/Control-C#:~:text=In%20many%20command,to%20the%20user. -->
Once you have completed the above steps, you are ready to build and run Monkeytype.
1. Run `npm install` in the project root directory to install dependencies.
1. Run `npm run start:dev` to start a local dev server on port 5000. It will watch for changes and rebuild when you edit files in `src/` or `public/` directories. Use <kbd>control c</kbd> to abort it.
1. Run `npm run start:dev` to start a local dev server on [port 5000](http://localhost:5000). It will watch for changes and rebuild when you edit files in `src/` or `public/` directories. Use <kbd>Ctrl+ C</kbd> to abort it.
- Run `firebase use {your-project-id}` if you run into any errors for this.
## Standards and Conventions
### Standards and Guidelines
1. Code style is enforced by [Prettier](https://prettier.io/docs/en/install.html), which is automatically ran every time you `git commit` (if you've followed the above instructions properly).
1. If you are unsure of the best practices and conventions of Javascript, please take a look at the [JavaScript Best Practices](https://www.w3schools.com/js/js_best_practices.asp) and [JavaScript Coding Conventions](https://www.w3schools.com/js/js_conventions.asp)
Code style is enforced by [Prettier](https://prettier.io/docs/en/install.html), which automatically runs every time you `git commit` (if you've followed the above instructions properly).
Following the guidelines below will increase your chance of getting your change accepted.
#### Theme Guidelines
<!-- TODO: add screenshots to provide examples for dos and don'ts -->
- Make sure your theme is unique and a similar looking one is not already available
- The text color is either black or white (or very close to)
- Your theme has been added to the `_list` file and the `textColor` property is the theme's main color
- Your theme is clear and readable with both `flip test colors` and `colorful mode` enabled and disabled
#### Language Guidelines
- Do not include swear words
- Ensure that your contribution meets JSON standards (no trailing comma at the end of a list)
- Be sure to add your language to the `_list` and `_groups` files
- Make sure the number of words corresponds to the file name (for example: `languageName.json` is 200 words, `langugeName_1k.json` is 1000 words, and so on)
#### Quote Guidelines
- Do not include swear words
- Ensure that your contribution meets JSON standards (no trailing comma at the end of a list)
- Verify the `length` property is correct (length of the text in characters)
- Verify the `id` property is incremented correctly
## Questions
If you run into any problems, let me know on [GitHub](https://github.com/Miodec) or [Discord](https://discord.gg/monkeytype) in the `#development` channel.
If you have any questions, comments, concerns, or problems let me know on [GitHub](https://github.com/Miodec), [Discord](https://discord.gg/monkeytype) in the `#development` channel, or on Monkeytype's [GitHub discussions](https://github.com/Miodec/monkeytype/discussions).

View file

@ -11,7 +11,7 @@
# About
Monkeytype is a minimalistic, customisable typing test, featuring many test modes, an account system to save your typing speed history and user-configurable features like themes, sounds, a smooth caret and more.
Monkeytype is a minimalistic, customizable typing test, featuring many test modes, an account system to save your typing speed history, and user-configurable features like themes, sounds, a smooth caret, and more.
# Features
@ -30,7 +30,7 @@ Monkeytype is a minimalistic, customisable typing test, featuring many test mode
# Discord bot
On the [monkeytype Discord server](https://www.discord.gg/monkeytype), we added a Discord bot to autoassign roles on our server. You can find its code over at https://github.com/Miodec/monkey-bot
On the [monkeytype Discord server](https://www.discord.gg/monkeytype), we added a Discord bot to auto-assign roles on our server. You can find its code over at https://github.com/Miodec/monkey-bot
# Bug report or Feature request
@ -48,7 +48,7 @@ Before contributing to this repository please carefully read and understand the
[Montydrei](https://www.reddit.com/user/montydrei) for the name suggestion.
Everyone who provided valuable feedback on the [original reddit post](https://www.reddit.com/r/MechanicalKeyboards/comments/gc6wx3/experimenting_with_a_completely_new_type_of/) for the prototype of this website.
Everyone who provided valuable feedback on the [original Reddit post](https://www.reddit.com/r/MechanicalKeyboards/comments/gc6wx3/experimenting_with_a_completely_new_type_of/) for the prototype of this website.
All the [contributors](https://github.com/Miodec/monkeytype/graphs/contributors) that have helped with implementing various features, adding themes, fixing bugs, and more.

View file

@ -170,6 +170,7 @@ const refactoredSrc = [
"./src/js/test/layout-emulator.js",
"./src/js/test/poetry.js",
"./src/js/test/today-tracker.js",
"./src/js/test/weak-spot.js",
"./src/js/replay.js",
];

View file

@ -431,7 +431,7 @@ let commandsKeyTips = {
display: "off",
configValue: false,
exec: () => {
UpdateConfig.setShowKeyTips(false);
UpdateConfig.setKeyTips(false);
},
},
{
@ -439,7 +439,7 @@ let commandsKeyTips = {
display: "on",
configValue: true,
exec: () => {
UpdateConfig.setShowKeyTips(true);
UpdateConfig.setKeyTips(true);
},
},
],
@ -2482,12 +2482,30 @@ export let defaultCommands = {
icon: "fa-ad",
subgroup: commandsEnableAds,
},
{
id: "changeTheme",
display: "Theme...",
icon: "fa-palette",
subgroup: themeCommands,
},
{
id: "setCustomTheme",
display: "Custom theme...",
icon: "fa-palette",
subgroup: commandsCustomTheme,
},
{
id: "changeRandomTheme",
display: "Random theme...",
icon: "fa-random",
subgroup: commandsRandomTheme,
},
{
id: "randomizeTheme",
display: "Next random theme",
icon: "fa-random",
exec: () => ThemeController.randomizeTheme(),
},
{
id: "changeDifficulty",
display: "Difficulty...",
@ -2552,18 +2570,6 @@ export let defaultCommands = {
UpdateConfig.setCustomBackground(input);
},
},
{
id: "changeTheme",
display: "Theme...",
icon: "fa-palette",
subgroup: themeCommands,
},
{
id: "changeRandomTheme",
display: "Random theme...",
icon: "fa-random",
subgroup: commandsRandomTheme,
},
{
id: "changeLanguage",
display: "Language...",
@ -2656,12 +2662,6 @@ export let defaultCommands = {
icon: "fa-arrows-alt-h",
subgroup: commandsPageWidth,
},
{
id: "randomizeTheme",
display: "Next random theme",
icon: "fa-palette",
exec: () => ThemeController.randomizeTheme(),
},
{
id: "viewTypingPage",
display: "View Typing Page",

View file

@ -242,6 +242,7 @@ function addChildCommands(
commandItemDisplay =
parentCommandDisplay + " > " + icon + commandItemDisplay;
if (commandItem.subgroup) {
if (commandItem.beforeSubgroup) commandItem.beforeSubgroup();
try {
commandItem.subgroup.list.forEach((cmd) => {
commandItem.configKey = commandItem.subgroup.configKey;

View file

@ -123,6 +123,9 @@ let defaultConfig = {
customBackgroundFilter: [0, 1, 1, 1, 1],
customLayoutfluid: "qwerty#dvorak#colemak",
monkeyPowerLevel: "off",
minBurst: "off",
minBurstCustomSpeed: 100,
burstHeatmap: false,
};
function isConfigKeyValid(name) {
@ -1184,7 +1187,7 @@ export function setFontFamily(font, nosave) {
config.fontFamily = font;
document.documentElement.style.setProperty(
"--font",
'"' + font.replace(/_/g, " ") + '"'
`"${font.replace(/_/g, " ")}", "Roboto Mono"`
);
ChartController.setDefaultFontFamily(font);
if (!nosave) saveToLocalStorage();
@ -1546,6 +1549,15 @@ export function setMonkeyPowerLevel(level, nosave) {
if (!nosave) saveToLocalStorage();
}
export function setBurstHeatmap(value, nosave) {
if (!value) {
value = false;
}
config.burstHeatmap = value;
TestUI.applyBurstHeatmap();
if (!nosave) saveToLocalStorage();
}
export function apply(configObj) {
if (configObj == null || configObj == undefined) {
Notifications.add("Could not apply config", -1, 3);
@ -1634,6 +1646,7 @@ export function apply(configObj) {
setMonkey(configObj.monkey, true);
setRepeatQuotes(configObj.repeatQuotes, true);
setMonkeyPowerLevel(configObj.monkeyPowerLevel, true);
setBurstHeatmap(configObj.burstHeatmap, true);
LanguagePicker.setActiveGroup();

View file

@ -23,6 +23,7 @@ import * as Focus from "./focus";
import * as ShiftTracker from "./shift-tracker";
import * as Replay from "./replay.js";
import * as MonkeyPower from "./monkey-power";
import * as WeakSpot from "./weak-spot";
$("#wordsInput").keypress((event) => {
event.preventDefault();
@ -166,7 +167,7 @@ function handleBackspace(event) {
// }
if (
/^[ £§`~!@#$%^&*()_+-=[\]{};':"|,./<>?]*$/g.test(
/^[ £§`~!@#$%^&*()_+\-=[\]{};':"|,./<>?]*$/g.test(
TestLogic.input.getCurrent()
)
) {
@ -185,20 +186,22 @@ function handleBackspace(event) {
TestLogic.input.popHistory();
TestLogic.corrected.popHistory();
} else {
const regex = new RegExp(/[ £§`~!@#$%^&*()_+-=[\]{};':"|,./<>?]/, "g");
const regex = new RegExp(/[ £§`~!@#$%^&*()_+\-=[\]{};':"|,./<>?]/, "g");
let input = TestLogic.input.getCurrent();
regex.test(input);
// let puncIndex = regex.lastIndex;
let puncIndex = input.lastIndexOfRegex(
/[ £§`~!@#$%^&*()_+-=[\]{};':"|,./<>?]/g
/[ £§`~!@#$%^&*()_+\-=[\]{};':"|,./<>?]/g
);
while (/[ £§`~!@#$%^&*()_+-=[\]{};':"|,./<>?]/g.test(input.slice(-1))) {
while (
/[ £§`~!@#$%^&*()_+\-=[\]{};':"|,./<>?]/g.test(input.slice(-1))
) {
input = input.substring(0, input.length - 1);
}
puncIndex = input.lastIndexOfRegex(
/[ £§`~!@#$%^&*()_+-=[\]{};':"|,./<>?]/g
/[ £§`~!@#$%^&*()_+\-=[\]{};':"|,./<>?]/g
);
TestLogic.input.setCurrent(input.substring(0, puncIndex + 1));
}
@ -660,6 +663,7 @@ function handleAlpha(event) {
);
}
}
WeakSpot.updateScore(nextCharInWord, thisCharCorrect);
if (thisCharCorrect) {
Sound.playClick(Config.playSoundOnClick);

View file

@ -150,23 +150,27 @@ list.updateEmail = new SimplePopup(
initVal: "",
},
{
placeholder: "Current email",
placeholder: "New email",
initVal: "",
},
{
placeholder: "New email",
placeholder: "Confirm new email",
initVal: "",
},
],
"",
"Update",
(pass, previousEmail, newEmail) => {
(pass, email, emailConfirm) => {
try {
const user = firebase.auth().currentUser;
const credential = firebase.auth.EmailAuthProvider.credential(
user.email,
pass
);
if (email !== emailConfirm) {
Notifications.add("Emails don't match", 0);
return;
}
Loader.show();
user
.reauthenticateWithCredential(credential)
@ -174,7 +178,7 @@ list.updateEmail = new SimplePopup(
axiosInstance
.post("/user/updateEmail", {
uid: user.uid,
previousEmail: previousEmail,
previousEmail: user.email,
newEmail: newEmail,
})
.then((data) => {
@ -206,7 +210,7 @@ list.updatePassword = new SimplePopup(
"Update Password",
[
{
placeholder: "Current password",
placeholder: "Password",
type: "password",
initVal: "",
},
@ -308,31 +312,45 @@ list.resetPersonalBests = new SimplePopup(
"resetPersonalBests",
"text",
"Reset Personal Bests",
[],
"Are you sure you want to reset all your personal bests?",
[
{
placeholder: "Password",
type: "password",
initVal: "",
},
],
"",
"Reset",
() => {
async (password) => {
try {
const user = firebase.auth().currentUser;
const credential = firebase.auth.EmailAuthProvider.credential(
user.email,
password
);
Loader.show();
axiosInstance.post("/resetPersonalBests").then((res) => {
if (res) {
Loader.hide();
Notifications.add(
"Personal bests removed, refreshing the page...",
0
);
setTimeout(() => {
location.reload();
}, 1500);
} else {
Notifications.add(
"Something went wrong while removing personal bests...",
-1
);
}
await user.reauthenticateWithCredential(credential);
let resetResult = await CloudFunctions.resetPersonalBests({
uid: firebase.auth().currentUser.uid,
});
let resetResult = await axiosInstance.post("/resetPersonalBests");
if (resetResult.status === 200) {
Loader.hide();
Notifications.add("Personal bests removed, refreshing the page...", 0);
setTimeout(() => {
location.reload();
}, 1500);
} else {
Loader.hide();
Notifications.add(
"Something went wrong while removing personal bests...",
-1
);
}
} catch (e) {
Notifications.add("Something went wrong: " + e, -1);
Loader.hide();
Notifications.add(e, -1);
}
},
() => {}

View file

@ -32,6 +32,7 @@ import axiosInstance from "./axios-instance";
import * as MonkeyPower from "./monkey-power";
import * as Poetry from "./poetry.js";
import * as TodayTracker from "./today-tracker";
import * as WeakSpot from "./weak-spot";
let glarsesMode = false;
@ -573,6 +574,8 @@ export async function init() {
UpdateConfig.setPunctuation(false, true);
UpdateConfig.setNumbers(false, true);
randomWord = Misc.getASCII();
} else if (Config.funbox === "weakspot") {
randomWord = WeakSpot.getWord(wordset);
}
if (Config.punctuation) {
@ -1548,6 +1551,13 @@ export function finish(difficultyFailed = false) {
if (lpb < stats.wpm && stats.wpm < highestwpm) {
dontShowCrown = true;
}
if (
Config.funbox !== "none" &&
Config.funbox !== "plus_one" &&
Config.funbox !== "plus_two"
) {
dontShowCrown = true;
}
if (Config.mode == "quote") dontShowCrown = true;
if (lpb < stats.wpm) {
//new pb based on local
@ -1967,7 +1977,7 @@ export function finish(difficultyFailed = false) {
$("#words").empty();
ChartController.result.resize();
if (TestUI.heatmapEnabled) {
if (Config.burstHeatmap) {
TestUI.applyBurstHeatmap();
}
$("#testModesNotice").addClass("hidden");

View file

@ -15,7 +15,7 @@ import * as ManualRestart from "./manual-restart-tracker";
import * as PractiseMissed from "./practise-missed";
import * as Replay from "./replay";
import * as TestStats from "./test-stats";
import * as Misc from './misc';
import * as Misc from "./misc";
export let currentWordElementIndex = 0;
export let resultVisible = false;
@ -192,6 +192,7 @@ export function screenshot() {
$("#notificationCenter").removeClass("hidden");
$("#commandLineMobileButton").removeClass("hidden");
$(".pageTest .ssWatermark").addClass("hidden");
$(".pageTest .ssWatermark").text("monkeytype.com");
$(".pageTest .buttons").removeClass("hidden");
if (revealReplay) $("#resultReplay").removeClass("hidden");
if (firebase.auth().currentUser == null)
@ -204,6 +205,11 @@ export function screenshot() {
}
$("#resultReplay").addClass("hidden");
$(".pageTest .ssWatermark").removeClass("hidden");
if (firebase.auth().currentUser != null) {
$(".pageTest .ssWatermark").text(
DB.getSnapshot().name + " | monkeytype.com"
);
}
$(".pageTest .buttons").addClass("hidden");
let src = $("#middle");
var sourceX = src.position().left; /*X position from div#target*/
@ -784,87 +790,80 @@ export function toggleResultWords() {
}
}
}
export let heatmapEnabled = false;
function toggleBurstHeatmap(){
if(!heatmapEnabled){
applyBurstHeatmap();
}else{
//clear all classes
$("#resultWordsHistory .heatmapLegend").addClass('hidden');
$('#resultWordsHistory .words .word').removeClass("heatmap-0");
$('#resultWordsHistory .words .word').removeClass("heatmap-1");
$('#resultWordsHistory .words .word').removeClass("heatmap-2");
$('#resultWordsHistory .words .word').removeClass("heatmap-3");
$('#resultWordsHistory .words .word').removeClass("heatmap-4");
export function applyBurstHeatmap() {
if (Config.burstHeatmap) {
$("#resultWordsHistory .heatmapLegend").removeClass("hidden");
let min = Math.min(...TestStats.burstHistory);
let max = Math.max(...TestStats.burstHistory);
// let step = (max - min) / 5;
// let steps = [
// {
// val: min,
// class: 'heatmap-0'
// },
// {
// val: min + (step * 1),
// class: 'heatmap-1'
// },
// {
// val: min + (step * 2),
// class: 'heatmap-2'
// },
// {
// val: min + (step * 3),
// class: 'heatmap-3'
// },
// {
// val: min + (step * 4),
// class: 'heatmap-4'
// },
// ];
let median = Misc.median(TestStats.burstHistory);
let adatm = [];
TestStats.burstHistory.forEach((burst) => {
adatm.push(Math.abs(median - burst));
});
let step = Misc.mean(adatm);
// let step = Misc.stdDev(TestStats.burstHistory)/2;
let steps = [
{
val: 0,
class: "heatmap-0",
},
{
val: median - step * 1.5,
class: "heatmap-1",
},
{
val: median - step * 0.5,
class: "heatmap-2",
},
{
val: median + step * 0.5,
class: "heatmap-3",
},
{
val: median + step * 1.5,
class: "heatmap-4",
},
];
$("#resultWordsHistory .words .word").each((index, word) => {
let wordBurstVal = parseInt($(word).attr("burst"));
let cls = "";
steps.forEach((step) => {
if (wordBurstVal > step.val) cls = step.class;
});
$(word).addClass(cls);
});
} else {
$("#resultWordsHistory .heatmapLegend").addClass("hidden");
$("#resultWordsHistory .words .word").removeClass("heatmap-0");
$("#resultWordsHistory .words .word").removeClass("heatmap-1");
$("#resultWordsHistory .words .word").removeClass("heatmap-2");
$("#resultWordsHistory .words .word").removeClass("heatmap-3");
$("#resultWordsHistory .words .word").removeClass("heatmap-4");
}
heatmapEnabled = !heatmapEnabled;
}
export function applyBurstHeatmap(){
$("#resultWordsHistory .heatmapLegend").removeClass('hidden');
let min = Math.min(...TestStats.burstHistory);
let max = Math.max(...TestStats.burstHistory);
// let step = (max - min) / 5;
// let steps = [
// {
// val: min,
// class: 'heatmap-0'
// },
// {
// val: min + (step * 1),
// class: 'heatmap-1'
// },
// {
// val: min + (step * 2),
// class: 'heatmap-2'
// },
// {
// val: min + (step * 3),
// class: 'heatmap-3'
// },
// {
// val: min + (step * 4),
// class: 'heatmap-4'
// },
// ];
let median = Misc.median(TestStats.burstHistory);
let adatm = [];
TestStats.burstHistory.forEach(burst => {
adatm.push(Math.abs(median - burst));
})
let step = Misc.mean(adatm);
// let step = Misc.stdDev(TestStats.burstHistory)/2;
let steps = [
{
val: 0,
class: 'heatmap-0'
},
{
val: median - (step * 1.5),
class: 'heatmap-1'
},
{
val: median - (step * 0.5),
class: 'heatmap-2'
},
{
val: median + (step * 0.5),
class: 'heatmap-3'
},
{
val: median + (step * 1.5),
class: 'heatmap-4'
},
];
$('#resultWordsHistory .words .word').each((index, word) => {
let wordBurstVal = parseInt($(word).attr('burst'));
let cls = '';
steps.forEach(step => {
if(wordBurstVal > step.val) cls = step.class;
})
$(word).addClass(cls);
})
}
export function highlightBadWord(index, showError) {
@ -902,9 +901,8 @@ $(".pageTest #copyWordsListButton").click(async (event) => {
}
});
$(".pageTest #toggleBurstHeatmap").click(async (event) => {
toggleBurstHeatmap();
UpdateConfig.setBurstHeatmap(!Config.burstHeatmap);
});
$(document).on("mouseleave", "#resultWordsHistory .words .word", (e) => {

58
src/js/test/weak-spot.js Normal file
View file

@ -0,0 +1,58 @@
import * as TestStats from "./test-stats";
// Changes how quickly it 'learns' scores - very roughly the score for a char
// is based on last 1/adjustRate occurrences. Make it larger to adjust faster.
// Should be between 0 and 1.
const adjustRate = 0.02;
// Choose the highest scoring word from this many random words. Higher values
// will choose words with more weak letters on average.
const wordSamples = 20;
// The score that every character starts on. The ideal value would be the
// average spacing in milliseconds, but since we don't know that at the start,
// pick something little high and it'll converge as the user types.
const defaultScore = 500;
// Score penatly (in milliseconds) for getting a letter wrong.
const incorrectPenalty = 5000;
let scores = {};
export function updateScore(char, isCorrect) {
let score = 0.0;
const timings = TestStats.keypressTimings.spacing.array;
if (timings.length > 0) {
score += timings[timings.length - 1];
}
if (!isCorrect) {
score += incorrectPenalty;
}
if (!(char in scores)) {
scores[char] = defaultScore;
}
// Keep an exponential moving average of the score over time.
scores[char] = score * adjustRate + scores[char] * (1 - adjustRate);
}
export function getWord(wordset) {
let highScore;
let randomWord;
for (let i = 0; i < wordSamples; i++) {
let newWord = wordset[Math.floor(Math.random() * wordset.length)];
let newScore = score(newWord);
if (i == 0 || newScore > highScore) {
randomWord = newWord;
highScore = newScore;
}
}
return randomWord;
}
function score(word) {
let total = 0.0;
for (const c of word) {
total += c in scores ? scores[c] : defaultScore;
}
return total / word.length;
}

View file

@ -1170,7 +1170,6 @@ label.checkbox {
border: none;
outline: none;
font-size: 1rem;
font-family: var(--font);
width: 100%;
border-radius: var(--roundness);
}
@ -1196,7 +1195,6 @@ label.checkbox {
border: none;
outline: none;
font-size: 1rem;
font-family: var(--font);
width: 100%;
border-radius: var(--roundness);
}
@ -3185,29 +3183,6 @@ key {
grid-auto-columns: 1fr;
gap: 0.5rem;
grid-area: tabs;
.tab {
will-change: color;
transition: 0.2s ease-in-out color;
outline: 0;
cursor: pointer;
padding: 0;
font-size: 1rem;
color: var(--sub-color);
text-align: left;
border: 0;
background: 0;
font-family: var(--font);
&:first-child {
margin-right: 0.5rem;
}
&.active,
&:hover {
color: var(--main-color);
}
}
}
.buttons {

View file

@ -108,6 +108,11 @@
"name": "poetry",
"type": "script",
"info": "Practice typing some beautiful prose."
},
{
"name": "weakspot",
"type": "script",
"info": "Focus on slow and mistyped letters."
}
]

View file

@ -3,6 +3,51 @@
"leftToRight": true,
"words": [
"this",
"let",
"const",
"async",
"await",
"NaN",
"undefined",
"typeof",
"prompt",
"else if",
"||",
"&&",
"i++",
"${i}",
"${j}",
"label",
"switch",
"case",
"use strict",
"assert",
"new Object()",
"delete",
"Object.assign()",
"Symbol()",
"toUpperCase()",
"toLowerCase()",
"toString()",
"Math.floor()",
"Math.ceil()",
"Math.round()",
"Math.trunc()",
"Math.max()",
"Math.pow()",
"Math.random()",
"indexOf()",
"isNaN()",
"Object.is()",
"parseInt()",
"parseFloat()",
"includes()",
"startsWith()",
"endsWith()",
"slice()",
"substring()",
"trim()",
"repeat()",
"function",
"if",
"var",

View file

@ -5613,7 +5613,6 @@
"kollektion",
"strejke",
"kæft",
"slave",
"bøf",
"alsidig",
"bizar",

View file

@ -8812,7 +8812,6 @@
"socialist",
"attracted",
"undertaking",
"slavery",
"notwithstanding",
"feasible",
"credibility",

View file

@ -976,7 +976,6 @@
"bar",
"offer",
"segment",
"slave",
"duck",
"instant",
"market",

View file

@ -6305,7 +6305,6 @@
"aeroplane",
"gaggle",
"vocare",
"slavey",
"slouch",
"unfurl",
"decorator",
@ -22632,7 +22631,6 @@
"autograph",
"thatch",
"toughness",
"antislavery",
"pleroma",
"zechariah",
"hausa",

View file

@ -18788,9 +18788,6 @@
"antiskepticism",
"antiskid",
"antiskidding",
"antislaveries",
"antislavery",
"antislaveryism",
"antisleep",
"antislickens",
"antislip",
@ -24745,7 +24742,6 @@
"aslaking",
"aslant",
"aslantwise",
"aslaver",
"asleep",
"aslop",
"aslope",
@ -38193,13 +38189,6 @@
"beslabber",
"beslap",
"beslash",
"beslave",
"beslaved",
"beslaver",
"beslavered",
"beslavering",
"beslavers",
"beslaves",
"beslaving",
"besleeve",
"beslime",
@ -44772,7 +44761,6 @@
"bondservant",
"bondservants",
"bondship",
"bondslave",
"bondsman",
"bondsmen",
"bondstone",
@ -106237,10 +106225,6 @@
"disenshrouded",
"disenshrouding",
"disenshrouds",
"disenslave",
"disenslaved",
"disenslaves",
"disenslaving",
"disensoul",
"disensure",
"disentail",
@ -122936,14 +122920,6 @@
"ensky",
"enskyed",
"enskying",
"enslave",
"enslaved",
"enslavedness",
"enslavement",
"enslavements",
"enslaver",
"enslavers",
"enslaves",
"enslaving",
"enslumber",
"ensmall",
@ -193999,7 +193975,6 @@
"jackshea",
"jacksie",
"jacksies",
"jackslave",
"jacksmelt",
"jacksmelts",
"jacksmith",
@ -242548,7 +242523,6 @@
"Nesiot",
"nesiote",
"Neskhi",
"neslave",
"Neslia",
"Nesogaea",
"Nesogaean",
@ -252024,8 +251998,6 @@
"nonskiers",
"nonskilled",
"nonskipping",
"nonslanderous",
"nonslaveholding",
"nonslip",
"nonslippery",
"nonslipping",
@ -303006,7 +302978,6 @@
"presignifying",
"presimian",
"preslaughter",
"preslavery",
"presleep",
"Presley",
"preslice",
@ -307335,10 +307306,6 @@
"proskomide",
"proslambanomene",
"proslambanomenos",
"proslave",
"proslaver",
"proslavery",
"proslaveryism",
"proslyted",
"proslyting",
"prosneusis",
@ -322451,11 +322418,6 @@
"reenrolling",
"reenrolls",
"reens",
"reenslave",
"reenslaved",
"reenslavement",
"reenslaves",
"reenslaving",
"reenter",
"reenterable",
"reentered",
@ -347745,7 +347707,6 @@
"semisirque",
"semisixth",
"semiskilled",
"semislave",
"semismelting",
"semismile",
"semisocial",
@ -357235,34 +357196,6 @@
"slaunchways",
"Slav",
"Slavdom",
"Slave",
"slaveborn",
"slaved",
"slaveholder",
"slaveholders",
"slaveholding",
"slaveholdings",
"slaveland",
"slaveless",
"slavelet",
"slavelike",
"slaveling",
"slavemonger",
"slaveowner",
"slaveownership",
"slavepen",
"slaver",
"slavered",
"slaverer",
"slaverers",
"slaveries",
"slavering",
"slaveringly",
"slavers",
"slavery",
"slaves",
"Slavey",
"slaveys",
"Slavi",
"Slavian",
"Slavic",
@ -416917,8 +416850,6 @@
"unenrobed",
"unenrolled",
"unenshrined",
"unenslave",
"unenslaved",
"unensnared",
"unensouled",
"unensured",
@ -427436,7 +427367,6 @@
"unslating",
"unslatted",
"unslaughtered",
"unslave",
"unslayable",
"unsleaved",
"unsleek",
@ -444242,7 +444172,6 @@
"whiteseam",
"whiteshank",
"whiteside",
"whiteslave",
"whitesmith",
"whitesmiths",
"whitespace",

View file

@ -246,6 +246,42 @@
"source": "Ramses Shaffy",
"length": 76,
"id": 40
},
{
"text": "De dood dient dood te blijven. Stil, verdrietig en ongelooflijk doodstil. Ik wil de vogels weer horen fluiten op de begraafplaats. Ik wil het geknisper van boekettencellofaan, het zingen van hitparadeliederen en het scanderen van slogans niet meer horen. Ik wil dat de dood terugkeert naar wat zij behoort te zijn: gruwelijk, onbegrijpelijk en afschuwelijk.",
"source": "Boudewijn Büch",
"length": 357,
"id": 41
},
{
"text": "Dames en heren, goedemorgen. Het volgende station is Rotterdam Centraal. U kunt hier overstappen op het metronetwerk van Rotterdam. U kunt hier overstappen voor de richting Woerden, voor Maassluis en voor Gouda - Utrecht Centraal. De Sprinter naar Maassluis vertrekt van spoor 3. Deze Sprinter rijdt verder naar Schiedam Centrum, Delft Zuid, Delft en Den Haag Centraal.",
"source": "Nederlandse Spoorwegen",
"length": 369,
"id": 42
},
{
"text": "In den beginne schiep God den hemel en de aarde. De aarde nu was woest en ledig, en duisternis was op den afgrond; en de Geest Gods zweefde op de wateren. En God zeide: Daar zij licht! en daar werd licht.",
"source": "Genesis 1:1-3",
"length": 204,
"id": 43
},
{
"text": "Laten wij dan de zaak eens van een andere zijde bekijken. Wie alleen maar bezorgd is dat hij leeft, vergeet door deze angstigheid gemakkelijk van het leven te genieten. Is het hem alleen maar om het leven te doen en denkt hij, als ik maar eenmaal het lieve leven heb, dan wendt hij zijn hele kracht niet aan om het leven te verbruiken d.w.z. ervan te genieten. Hoe moet men echter het leven gebruiken? Doordat men het gebruikt; zoals het licht dat men verbruikt als men het brandt. Men gebruikt het leven en daarom zichzelf, de levende, indien het en zichzelf verteert. Levensgenot is het leven verbruiken.",
"source": "Max Stirner",
"length": 606,
"id": 44
},
{
"text": "Een mens is tot niets \"geroepen\" en heeft geen \"taak\", geen \"bestemming\", net zomin als een plant of dier een \"roeping\" heeft. De bloem volgt de roeping om zich te vervolmaken, maar ze wendt al haar krachten aan om van de wereld zo goed zij kan te genieten en ze te verteren d.w.z. ze zuigt zoveel sappen uit de aarde, zoveel lucht uit de ether, zoveel licht van de zon op, als ze kan krijgen en kan bergen. De vogel leeft niet volgens zijn roeping, maar gebruikt zijn krachten zo goed als het gaat: hij grijpt kevers en zingt naar hartelust. De krachten van de vogels en bloemen zijn echter in vergelijking bij die van een mens gering en veel geweldiger zal een mens die zijn krachten aanwendt in de wereld ingrijpen, dan bloem en dier. Een roeping heeft hij niet, maar hij heeft krachten die zich uiten waar ze zijn omdat hun zijn alleen in hun uiten bestaat en net zomin onwerkzaam zouden kunnen blijven, zoals het leven dat, als het ook maar één seconde \"stil zou staan\", geen leven meer zou zijn. Nu zou men de mensen kunnen toeroepen: gebruik jullie kracht. Maar in deze imperatief zou dat de betekenis krijgen dat het de taak van de mens is om zijn kracht te gebruiken. Zo is het niet, iedereen gebruikt werkelijk veel meer zijn kracht zonder dat eerst als zijn roeping te beschouwen: iedereen gebruikt op elk ogenblik zoveel kracht als hij bezit. Men zegt wel eens van een overwonnene dat hij zijn krachten veel meer had moeten inspannen; maar men vergeet dat indien hij, op het moment van de nederlaag, de kracht had bezeten om zijn krachten (bv. lichaamskracht) in te spannen, hij het niet zou hebben nagelaten: was de moedeloosheid ook maar één minuut, dan was dat toch een minuutlange - krachteloosheid. De krachten laten zich weliswaar verscherpen en verveelvoudigen, met name door vijandelijke tegenstand of vriendschappelijke bijstand; maar waar men hun toepassing mist, kan men ook van hun afwezigheid verzekerd zijn. Men kan uit een steen vuur slaan, maar zonder de slag komt er niets uit; op dezelfde manier heeft ook een mens de \"aanstoot\" nodig.",
"source": "Max Stirner",
"length": 2095,
"id": 45
},
{
"text": "Als iets één keer gebeurt, is dat een incident. Als het in korte tijd twee keer plaatsvindt, is dat heel toevallig. Als het drie keer gebeurt, is er sprake van een patroon - en als een vierde geval vrijwel identiek is, dan is dat ronduit verdacht.",
"source": "Peter R. de Vries",
"length": 264,
"id": 46
}
]
}

View file

@ -776,7 +776,7 @@
"id": 128
},
{
"text": "Will betrachtete den Ort über das ruhige Wasser des Hafens hinweg. Zu einer anderen Zeit und unter anderen Umständen hätte er die ordentlich in Reih und Glied stehenden Häusern mit den riesigen schneebedeckten Bergen dahinter wahrscheinlich sehr schön gefunden.",
"text": "Will betrachtete den Ort über das ruhige Wasser des Hafens hinweg. Zu einer anderen Zeit und unter anderen Umständen hätte er die ordentlich in Reih und Glied stehenden Häuser mit den riesigen schneebedeckten Bergen dahinter wahrscheinlich sehr schön gefunden.",
"source": "Die Chroniken von Araluen Der Eiserne Ritter",
"length": 261,
"id": 130
@ -806,7 +806,7 @@
"id": 134
},
{
"text": "Außerdem war dar geheimnisvoll Fremde schmächtig. Er reichte dem Gastgeber gerade mal bis zur Schulter. Allerdings war er muskulös und trotz der grauen Haare schien er in ausgezeichneter körperlicher Verfassung zu sein. Und es lag etwas in seinen Augen - einen gewisse Selbstsicherheit und kühles Abwägen -, was jegliche Behauptung ein normaler reisender zu sein, Lügen strafte. Deparnieux rühmte sich zu wissen, wie ein Mann aussah, der daran gewöhnt war, Macht auszuüben, und dieser Mann erweckte ganz den Eindruck.",
"text": "Außerdem war der geheimnisvolle Fremde schmächtig. Er reichte dem Gastgeber gerade mal bis zur Schulter. Allerdings war er muskulös und trotz der grauen Haare schien er in ausgezeichneter körperlicher Verfassung zu sein. Und es lag etwas in seinen Augen - eine gewisse Selbstsicherheit und kühles Abwägen -, was jegliche Behauptung ein normaler reisender zu sein, Lügen strafte. Deparnieux rühmte sich zu wissen, wie ein Mann aussah, der daran gewöhnt war, Macht auszuüben, und dieser Mann erweckte ganz den Eindruck.",
"source": "Die Chroniken von Araluen Der eiserne Ritter",
"length": 517,
"id": 135
@ -828,12 +828,14 @@
"source": "Stephen Hawking",
"length": 141,
"id": 138
},{
"text": "Wenn du unsicher über deine Zukunft bist, mach weiter mit dem war vor dir liegt mit ganzem Herzen und Liebe, und das, was für dich bestimmt ist, wird dich finden.",
},
{
"text": "Wenn du unsicher über deine Zukunft bist, mach weiter mit dem was vor dir liegt mit ganzem Herzen und Liebe, und das, was für dich bestimmt ist, wird dich finden.",
"source": "Gurumayi Chidvilasananda",
"length": 162,
"id": 139
},{
},
{
"text": "Das Leben ist da, um gelebt zu werden und nicht um begriffen zu werden, oder sich vorgegebenen Muster zu fügen.",
"source": "Bruce Lee",
"length": 111,
@ -918,7 +920,7 @@
"id": 153
},
{
"text": "Es sagt viel über die Welt aus, mein Kind, sagt der Vater zum Knaben, dass die Dummen glücklich sind und die Schlauen Depressionen haben",
"text": "Es sagt viel über die Welt aus, mein Kind, sagt der Vater zum Knaben, dass die Dummen glücklich sind und die Schlauen Depressionen haben.",
"source": "Die Känguru Trilogie",
"length": 136,
"id": 154
@ -1308,7 +1310,7 @@
"id": 218
},
{
"text": "Was machte ich eigentlich hier draußen? Was war der Grund für diese Reise? Streifte ich bloß umher in irgendeiner Art von Drogenrausch oder war ich wirklich nach Las Vegas gekommen, um an einem Artikel zu arbeiten Wer sind diese Leute? Die Gesichter? Wo kommen sie her? Sie sehen aus, wie Karikaturen von Gebrauchtwagenhändlern aus Dallas, du großer Gott. Am Sonntagmorgen um halb fünf lungern höllisch viele von denen hier rum, klammern sich immer noch an den amerikanischen Traum. Die Vision vom großen Gewinner, der plötzlich aus dem frühmorgendlichen Chaos eines runtergekommen Las Vegas Casinos auftaucht … Nein, nein beruhige dich, lerne das Verlieren zu genießen.",
"text": "Was machte ich eigentlich hier draußen? Was war der Grund für diese Reise? Streifte ich bloß umher in irgendeiner Art von Drogenrausch oder war ich wirklich nach Las Vegas gekommen, um an einem Artikel zu arbeiten... Wer sind diese Leute? Die Gesichter? Wo kommen sie her? Sie sehen aus, wie Karikaturen von Gebrauchtwagenhändlern aus Dallas, du großer Gott. Am Sonntagmorgen um halb fünf lungern höllisch viele von denen hier rum, klammern sich immer noch an den amerikanischen Traum. Die Vision vom großen Gewinner, der plötzlich aus dem frühmorgendlichen Chaos eines runtergekommenen Las Vegas Casinos auftaucht... Nein, nein beruhige dich, lerne das Verlieren zu genießen.",
"source": "Fear and Loathing in Las Vegas",
"length": 671,
"id": 219
@ -1332,7 +1334,7 @@
"id": 222
},
{
"text": "Sie glauben, ich bin ein Verlierer, nur weil ich einen scheiß Job habe, den ich hasse? Eine Familie, die mich nicht respektiert? Eine Stadt, die den Tag verflucht, an dem ich geboren wurde? Gut, das ist vielleicht für sie ein Verlierer, aber ich will Ihnen mal was sagen: Jeden Morgen, wenn ich aufstehe, weiß ich: Es kann gar nicht besser werden, bis ich mich wieder schlafen lege. Also stehe ich auf, esse meinen wassergetränkten Seetang und meine noch gefrorenen Brötchen, steige in mein Auto mit durchgesessenen Sitzen, sechs ausstehenden Raten und ohne Benzin. Ich stürze mich in den Verkehr, nur um die Freude zu haben, ein paar billige Schuhe an die Hufe von versifften Leuten wie Sie zu drücken. Ich werde nie Football spielen, wie ich es mal wollte, ich werde nie von einer Superfrau gestreichelt werden, eigentlich dürfte ich nie wieder Auto fahren ohne Maske über dem Kopf. Aber ich bin kein Verlierer. Weil ich trotz alledem, genau wie jeder andere, der nie sein wird, was er mal sein wollte, mich doch da draußen rumtreibe und das bin, was ich nicht sein wollte: 40 Stunden pro Woche, lebenslang. Und die Tatsache, dass ich mir keine Kanone in den Mund stecke, Sie Pudding von einer Frau, macht mich zum Sieger!",
"text": "Sie glauben, ich bin ein Verlierer, nur weil ich einen scheiß Job habe, den ich hasse? Eine Familie, die mich nicht respektiert? Eine Stadt, die den Tag verflucht, an dem ich geboren wurde? Gut, das ist vielleicht für sie ein Verlierer, aber ich will Ihnen mal was sagen: Jeden Morgen, wenn ich aufstehe, weiß ich: Es kann gar nicht besser werden, bis ich mich wieder schlafen lege. Also stehe ich auf, esse meinen wassergetränkten Seetang und meine noch gefrorenen Brötchen, steige in mein Auto mit durchgesessenen Sitzen, sechs ausstehenden Raten und ohne Benzin. Ich stürze mich in den Verkehr, nur um die Freude zu haben, ein paar billige Schuhe an die Hufe von versifften Leuten wie Sie zu drücken. Ich werde nie Football spielen, wie ich es mal wollte, ich werde nie von einer Superfrau gestreichelt werden, eigentlich dürfte ich nie wieder Auto fahren ohne Maske über dem Kopf. Aber ich bin kein Verlierer, weil ich trotz alledem, genau wie jeder andere, der nie sein wird, was er mal sein wollte, mich doch da draußen rumtreibe und das bin, was ich nicht sein wollte: 40 Stunden pro Woche, lebenslang. Und die Tatsache, dass ich mir keine Kanone in den Mund stecke, Sie Pudding von einer Frau, macht mich zum Sieger!",
"source": "Eine schrecklich nette Familie",
"length": 1224,
"id": 223
@ -1378,6 +1380,606 @@
"source": "Albert Einstein",
"length": 129,
"id": 230
},
{
"text": "Während er las, verliebte ich mich in ihn, so wie man in den Schlaf gleitet: langsam zuerst und dann rettungslos.",
"source": "Das Schicksal ist ein mieser Verräter",
"length": 113,
"id": 231
},
{
"text": "Balsam ist sicherlich der beste Balsam für die Wunden einer enttäuschten Liebe.",
"source": "Jane Austen",
"length": 79,
"id": 232
},
{
"text": "Wer nicht an Magie glaubt, wird sie niemals entdecken.",
"source": "Roald Dahl",
"length": 54,
"id": 233
},
{
"text": "Wenn Wolken die Sonne verbergen, gibt es immer irgendwo einen Silberstreifen, der mich ermahnt, nicht aufzugeben.",
"source": "Matthew Quick, Silver Linings",
"length": 113,
"id": 234
},
{
"text": "Wenn es ein Buch gibt, das du wirklich lesen willst, aber das noch nicht geschrieben wurde, dann musste du es selbst schreiben.",
"source": "Toni Morrison",
"length": 127,
"id": 235
},
{
"text": "Wenn du etwas erreichen willst, lies so viel, wie du nur kannst.",
"source": "Roald Dahl",
"length": 64,
"id": 236
},
{
"text": "Du bist der, der schwach ist. Du wirst nie wissen, was Liebe ist. Oder Freundschaft. Und deswegen kannst du mir nur leidtun.",
"source": "Harry Potter und der Orden des Phönix",
"length": 124,
"id": 237
},
{
"text": "Es verlangt sehr viel Tapferkeit, sich seinen Feinden in den Weg zu stellen, aber noch wesentlich mehr noch, sich seinen Freunden in den Weg zu stellen.",
"source": "Harry Potter und der Stein der Weisen",
"length": 152,
"id": 238
},
{
"text": "Worte sind, meinen nicht so bescheidenen Meinung nach, unsere wohl unerschöpflichste Quelle der Magie, Harry. Sie können Schmerz sowohl zufügen als auch lindern.",
"source": "Harry Potter und die Heiligtümer des Todes",
"length": 161,
"id": 239
},
{
"text": "Jenny, ich weiß nicht, ob Mama Recht hatte oder ob Leutnant Dan Recht hatte. Ich weiß nicht, ob jeder von uns sein Schicksal hat oder nur zufällig dahintreibt wie ein Blutt im Wind. Aber ich denke, es stimmt vielleicht beides. Vielleicht passiert ja beides zur selben Zeit. Du fehlst mir so, Jenny.",
"source": "Forrest Gump",
"length": 299,
"id": 240
},
{
"text": "Das Leben ist wie eine Schachtel Pralinen. Man weiß nie, was man kriegt.",
"source": "Forrest Gump",
"length": 72,
"id": 241
},
{
"text": "Es gibt nichts Mächtigeres als die Liebe der Familie. Doch wenn daraus Wut wird, dann gibt es nichts Gefährlicheres.",
"source": "Fast and Furious",
"length": 116,
"id": 242
},
{
"text": "Ich habe mein Leben immer in Vierteilmeilenabschnitten gelebt. Aber Dinge ändern sich. Ich bin jetzt Vater. Ich werde immer in deinem Herzen sein.",
"source": "Fast and Furious",
"length": 146,
"id": 243
},
{
"text": "Erst wenn du jemanden ganz nah an dich ranlässt, weißt du wer du selbst bist. Ein Auto als Gegenleistung dafür, dass man weiß aus welchem Holz ein Typ geschnitzt ist, ist ein Preis, mit dem ich leben kann.",
"source": "Fast and Furious",
"length": 205,
"id": 244
},
{
"text": "Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt.",
"source": "Das Leben des Brian",
"length": 80,
"id": 245
},
{
"text": "Verspricht eine lustige Steinigung zu werden. Ist ein Einheimischer.",
"source": "Das Leben des Brian",
"length": 68,
"id": 246
},
{
"text": "Kopf hoch, Brian! Du weißt doch wie es heißt. Ja, es gibt Dinge im Leben, die sind nun mal nicht schön und das kann einen wirklich manchmal verrückt machen. Und dann passieren wieder Dinge, da schwörst und fluchst du nur. Und wenn du nun am Knorpel des Lebens rum kaust, sei nicht sauer deswegen. Nein, pfeif dir doch eins! Denn Pfeifen hilft dir, die Dinge auf einmal ganz anders zu sehen, verstehst du?",
"source": "Das Leben des Brian",
"length": 404,
"id": 247
},
{
"text": "Wenn du nicht weißt, wohin du gehst, wird dich jeden Weg dorthin bringen.",
"source": "Alice im Wunderland",
"length": 73,
"id": 248
},
{
"text": "Ich habe immer gedacht, die Zeit wäre ein Dieb, die mir alles stiehlt, was ich liebe. Aber jetzt weiß ich, dass sie geben, bevor sie nehmen, und jeder Tag ist ein Geschenk. Jede Stunde. Jede Minute. Jede Sekunde.",
"source": "Alice im Wunderland",
"length": 212,
"id": 249
},
{
"text": "Ein kluger Mann widerspricht seiner Frau nicht. Er wartet, bis sie es selbst tut.",
"source": "Casablanca",
"length": 81,
"id": 250
},
{
"text": "Wenn du nicht jetzt mit ihm gehst, wirst du es später bereuen. Vielleicht nicht heute, vielleicht nicht morgen, aber bald, und dann bis an dein Lebensende.",
"source": "Casablanca",
"length": 155,
"id": 251
},
{
"text": "Am erträglichsten lebt es sich ohne Regeln auf dieser Welt.",
"source": "Batman The Dark Knight",
"length": 59,
"id": 252
},
{
"text": "Bruce, du magst im Inneren noch immer der großartige Junge von früher sein, Aber was man im Inneren ist, zählt nicht. Das, was wir tun, zeigt, wer wir sind.",
"source": "Batman Begins",
"length": 156,
"id": 253
},
{
"text": "Am dunkelsten ist die Nacht vor der Dämmerung. Doch ich versprecht ihnen, die Dämmerung bricht an.",
"source": "Batman The Dark Knight",
"length": 98,
"id": 254
},
{
"text": "Nicht gleich auf den Kopf, das verwirrt das Opfer. Dann fühlt er nicht den nächsten Schlag.",
"source": "Batman The Dark Knight",
"length": 91,
"id": 255
},
{
"text": "Weil es das ist, was nötig ist. Weil die Wahrheit manchmal nicht gut genug ist. Manchmal verdienen die Menschen mehr. Manchmal verdienen die Menschen, dass ihr Vertrauen belohnt wird…",
"source": "Batman The Dark Knight",
"length": 183,
"id": 256
},
{
"text": "Alles, was euch interessiert, ist Geld. Diese Stadt verdient ein anderes Kaliber von Verbrechern und ich werde es ihnen geben. Es geht nicht um Geld, sondern darum eine Botschaft zu senden!",
"source": "Batman The Dark Knight",
"length": 189,
"id": 257
},
{
"text": "Ich bin ein läufiger Hund, ich jage nur fahrenden Autos hinterher. Ich wüsste gar nicht, was ich täte, wenn ich eins erwischen würde.",
"source": "Batman The Dark Knight",
"length": 133,
"id": 258
},
{
"text": "Wollen Sie wissen, wieso ich ein Messer benutze? Pistolen sind zu schnell. Man kann sonst die Gefühle und Regungen nicht richtig auskosten. In Ihren letzten Momenten zeigen die Menschen, wer sie wirklich sind, In gewisser Weise kannte ich ihre Freude also besser, als Sie sie jemals kannten. Wüssten sie gern, wer ein Feigling war?",
"source": "Batman The Dark Knight",
"length": 331,
"id": 259
},
{
"text": "Eigentlich sind alle Tage wundervoll. Bis auf die, die nicht ganz so wundervoll sind. Aber die sind auch wundervoll.",
"source": "Benjamin Blümchen",
"length": 116,
"id": 260
},
{
"text": "Dabei war es genau umgekehrt, wir wollen vom Universum bemerkt werden, wir wollen nicht, dass das Universum sich eine Bohne darum schert, wie es uns ergeht, nicht um die kollektive Idee eines Lebens, sondern um jeden Einzelnen von uns als Individuum.",
"source": "Das Schicksal ist ein Mieser Verräter",
"length": 250,
"id": 261
},
{
"text": "Es stimmt. Ich liebe dich, und es gehört nicht zu meiner Geschäftspolitik, mir einfach Freuden, wie das Aussprechen von Wahrheiten, zu versagen. Ich liebe dich, und ich weiß, dass Liebe nichts als ein Ruf in die Wüste ist und dass das Versagen unvermeidbar ist und dass wir alle Verdummte sind und dass ein Tag kommt, wenn all unsere Werke zu Staub zerfallen, eine Zeit, wenn sich niemand daran erinnert, dass es einst Kreaturen gab, die in selbstgebauten Maschinen geflogen sind, und ich weiß, dass die Sonne die einzige Erde, die wir je haben, irgendwann verschlucken wird, und ich liebe dich.",
"source": "Das Schicksal ist ein mieser Verräter",
"length": 595,
"id": 262
},
{
"text": "Augustus Waters starb acht Tage nach seiner Vorbeerdigung im Memorial Hospital auf der Intensivstation, als der Krebs, der ein Teil von ihm war, schließlich sein Herz anhielt, das auch ein Teil von ihm war.",
"source": "Das Schicksal ist ein mieser Verräter",
"length": 206,
"id": 263
},
{
"text": "Es kommt die Zeit, da wir alle tot sind. Wir alle. Es kommt die Zeit, da es keine Menschen mehr gibt, die sich erinnern können, dass je irgendwer von uns existiert hat oder dass unsere Spezies je irgendwas geleistet hat. Dann ist keiner mehr da, der sich an Aristoteles oder Kleopatra erinnert und erst recht nicht an dich. Alles, was wir getan oder gebaut, geschrieben, gedacht oder entdeckt haben, alles wird vergessen sein, und all das hier hat keine Bedeutung mehr. Vielleicht kommt diese Zeit bald, vielleicht erst in Millionen von Jahren, aber selbst, wenn wir den Kollaps unsere Sonne überleben sollten, überleben wir nicht für immer. Es gab eine Zeit, bevor die Organismen zu Bewusstsein kamen, und es wird eine Zeit danach geben. Und wenn es die Unausweichlichkeit des menschlichen Vergessens ist, die dir Angst macht, dann rate ich dir eins: Ignorier sie einfach. Das ist weiß Gott, was alle anderen machen.",
"source": "Das Schicksal ist ein mieser Verräter",
"length": 917,
"id": 264
},
{
"text": "Wenn du den Regenbogen sehen willst, musst du den Regen aushalten.",
"source": "Das Schicksal ist ein mieser Verräter",
"length": 66,
"id": 265
},
{
"text": "Es gibt nur eine Sache, die schlimmer ist, als an Krebs zu sterben - ein Kind zu haben, das an Krebs sterben wird.",
"source": "Das Schicksal ist ein mieser Verräter",
"length": 114,
"id": 266
},
{
"text": "Man kann sich nicht aussuchen, ob man verletzt wird auf dieser Welt, aber man kann mitbestimmen, von wem. Ich bin glücklich mit meiner Wahl. Und ich hoffe, sie auch.",
"source": "Das Schicksal ist ein mieser Verräter",
"length": 165,
"id": 267
},
{
"text": "Du bist so düster! Sicher, dass du nicht aus dem DC Universum kommst?",
"source": "Deadpool 2",
"length": 69,
"id": 268
},
{
"text": "Man muss kein Superheld sein, um das Mädchen zu kriegen. Das richtige Mädchen wird den Helden in dir zum Vorschein bringen.",
"source": "Deadpool 2",
"length": 123,
"id": 269
},
{
"text": "Wir werden über Frankreich abgesetzt, als Zivilisten getarnt. Und sobald wir auf feindlichem Gebiet sind, als Guerilla-Kampftruppe im Hinterhalt, haben wir nur noch ein Ziel und ein Ziel allein: Sie töten.",
"source": "Inglorious Basterds",
"length": 205,
"id": 270
},
{
"text": "Ich war nicht der Beste, weil ich schnell getötet habe. Ich war der Beste, weil die Menge mich liebte. Gewinne die Menge und du bekommst deine Freiheit.",
"source": "Gladiator",
"length": 152,
"id": 271
},
{
"text": "Der Tod lächelt einen Mann täglich an, doch alles was ein Mann machen kann ist zurückzulächeln.",
"source": "Gladiator",
"length": 95,
"id": 272
},
{
"text": "Die Menschen leiden mehr unter zu wenig Fantasie als unter zu viel.",
"source": "Greatest Showman",
"length": 67,
"id": 273
},
{
"text": "Niemand hat je etwas verändert, indem er so war wie alle anderen.",
"source": "Greatest Showman",
"length": 65,
"id": 274
},
{
"text": "Es ist nicht nötig von allen geliebt zu werden. Nur von ein paar wenigen, guten Menschen.",
"source": "Greatest Showman",
"length": 89,
"id": 275
},
{
"text": "Die edelste Kunst ist, andere glücklich zu machen.",
"source": "Greatest Showman",
"length": 50,
"id": 276
},
{
"text": "Mein Name ist Robert Neville, ich bin ein Überlebender in New Fork City. Ich sende auf allen Frequenzen. Ich bin jeden Tag am South Street Seaport um die Mittagszeit, wenn die Sonne am höchsten steht. Wenn ihr da draußen seid, wenn irgendjemand da draußen ist… ich kann Nahrung bieten, ich kann Unterkunft bieten, ich kann Schutz bieten… Wenn irgendjemand da draußen ist… irgendjemand… Bitte… Du bist nicht allein.",
"source": "I Am Legend",
"length": 414,
"id": 277
},
{
"text": "Die Welt ist stiller geworden. Du musst nur hinhören. Wenn wir hinhören, dann hören wir Gottes Plan.",
"source": "I Am Legend",
"length": 100,
"id": 278
},
{
"text": "Träume fühlen sich doch real an, während wir sie träumen? Erst wenn wir aufwachen, fällt uns auf, dass irgendetwas seltsam war.",
"source": "Inception",
"length": 127,
"id": 279
},
{
"text": "Oder wird aus Ihnen ein alter Mann, voller Bedauern, der allein auf den Tod wartet?",
"source": "Inception",
"length": 83,
"id": 280
},
{
"text": "Welches ist der widerstandsfähigste Parasit? Ein Bakterium, ein Virus, ein Darmwurm? Ein Gedanke! Resistent, hochansteckend. Wenn ein Gedanke einen Verstand erstmal infiziert hat, ist es fast unmöglich, ihn zu entfernen.",
"source": "Inception",
"length": 220,
"id": 281
},
{
"text": "Die Welt ändert sich so schnell, dass wir laufen müssen, um nicht zurückzubleiben.",
"source": "Jurassic Park",
"length": 82,
"id": 282
},
{
"text": "Einige der schlimmsten Dinge, die man sich überhaupt vorstellen kann, sind in bester Absicht getan worden.",
"source": "Jurassic Park III",
"length": 106,
"id": 283
},
{
"text": "Ihre Leute waren nur darauf konzentriert, ob sie es schaffen könnten. Ob sie es tun sollten, die Frage stellte sich keiner.",
"source": "Jurassic Park",
"length": 123,
"id": 284
},
{
"text": "Wenn wir einfach nur bei Seite treten und auf die Natur vertrauen, dann wird das Leben einen Weg finden.",
"source": "Jurassic Park",
"length": 104,
"id": 285
},
{
"text": "Wenn und die Evolutionsgeschichte eins gelehrt hat, dann das, dass das Leben sich nicht einsperren lässt. Das Leben bahnt sich seinen Weg, es erobert neue Territorien, es überwindet sämtliche Barrieren, ob schmerzlich oder gefährlich.",
"source": "Jurassic Park",
"length": 234,
"id": 286
},
{
"text": "Sollte man je meine Geschichte erzählen, soll man sagen, ich ging meinen Weg mit Giganten. Menschen vergehen wie Weizen im Wind, doch diese Namen vergehen nie.",
"source": "Troja",
"length": 159,
"id": 287
},
{
"text": "Krieg bedeutet, dass junge Männer sterben und alte Männer reden. Du weißt das. Schenke der Politik keine Beachtung.",
"source": "Troja",
"length": 115,
"id": 288
},
{
"text": "Die Götter beneiden uns. Sie beneiden uns, weil wir sterblich sind, weil jeder Augenblick unser letzter sein könnte. Alles ist so viel schöner, weil wir irgendwann sterben. Nie wirst du zauberhafter sein als in diesem Moment, nie wieder werden wir hier sein.",
"source": "Troja",
"length": 258,
"id": 289
},
{
"text": "Er hatte schwarzes Haar und schmale Lippen, und seine rechte Hand, an der keine Haut mehr war, glänzte vor Blut und nassen Muskeln. Noch bevor Stephanie richtig begriffen hatte, was Sache war zog Skulduggery schon seinen Revolver aus dem Mantel. Der Mann bewegte sich, als Schüsse durchs Zimmer hallten, trat zur Seite und wedelte mit der rechten Hand.",
"source": "Skulduggery Pleasant Der Gentleman mit der Feuerhand",
"length": 352,
"id": 290
},
{
"text": "Sie stolpert, und neben ihr bewegte sich etwas. Als sie sich umdrehte, sah sie einen zweiten Mann auf sich zukommen. Irgendetwas stimmte nicht mit ihm mit seiner Haut, mit seinem Gesicht es sah nicht echt au. Fast wie aus Papier. Sie versuchte, ihn wegzustoßen, doch es war, als boxe man in einen Luftsack. Eine Faust flog ihr entgegen, doch im Gegensatz zu seinem Körper war die Faust kompakt und kräftig, und er riss ihr den Kopf zurück. Sie strauchelte, und er wollte sie packen, doch dann war Skulduggery zur Stelle und schleuderte ihn weg.",
"source": "Skulduggery Pleasant Der Gentleman mit der Feuerhand",
"length": 546,
"id": 291
},
{
"text": "Das Leben ist ein Kreislauf Skulduggery, nicht wahr? Es wiederholt sich alles, das ist unser Schicksal. Du von meiner Gnade abhängig. Ich gnadenlos.",
"source": "Skulduggery Pleasant Der Gentleman mit der Feuerhand",
"length": 152,
"id": 292
},
{
"text": "Ich möchte dich etwas fragen: Lass uns mal so tun, nur für einen Augenblick, als lebten wir in deiner Welt, wo alles verrückt ist und die Gesichtslosen echt. Was versprichst du dir davon, wenn du sie rufst? Dass sie dir über den Kopf streicheln?",
"source": "Skulduggery Pleasant Der Gentleman mit der Feuerhand",
"length": 245,
"id": 293
},
{
"text": "Die Falle war ausgezeichnet. Ein richtiges Prachtstück. Damit eine Falle ihren Zweck erfüllt, muss sie eine wichtige Eigenschaft aufweisen, dieselbe, die auch für jeden Zaubertrick nötig ist: Sie muss ablenken. Während du dich auf eine Sache konzentrierst, passiert hinter deinem Rücken eine andere. Ich habe nicht einmal gemerkt, dass es eine Falle war, bis sie zuschnappte. Serpine kannte mich, und er wusste, wie ich auf bestimmte Reize reagieren würde. Er wusste zum Beispiel, dass ich, wenn er meine Frau und mein Kind vor meinen Augen ermorden würde, nie auf den Gedanken käme, dass der Dolch, nach dem ich greife, vergiftet sein könnte.",
"source": "Skulduggery Pleasant Der Gentleman mit der Feuerhand",
"length": 643,
"id": 294
},
{
"text": "Ich habe gerade gesehen, wie sich ein sehr guter Freud in eine Statue verwandelt hat, Tanith. Meritorius und Marwenna Crow, zwei der wenigen Menschen auf dieser Welt, vor denen ich Respekt hatte, wurden ermordet. Deshalb hast du recht, wenn du sagst, dass unsere Verbündeten umfallen wie Fliegen. Aber es stand von Anfang an fest, dass dies kein einfacher Kampf werden würde. Tote waren zu erwarten. Und weißt du, was wir tun? Wir machen einen Schritt über sie weg und gehen weiter, weil uns nichts anderes übrigbleibt. Jetzt werde ich Serpine ein für alle Mal stoppen, jeder, der begleiten möchte, ist herzlich willkommen. Wenn mich keiner begleite, macht das nicht den geringsten Unterschied. Ich gehe trotzdem. Serpine muss aufgehalten werden, alles andere spielt keine Rolles",
"source": "Skulduggery Pleasant Der Gentleman mit der Feuerhand",
"length": 779,
"id": 295
},
{
"text": "Wenn man 600 Dollar klaut, kann man einfach verschwinden, aber bei 600 Million, musst du ihnen verkaufen, dass es dich erwischt hat.",
"source": "Stirb langsam",
"length": 132,
"id": 296
},
{
"text": "Wenn sie dich anstarren, lass sie einfach starren. Wer etwas ganz Besonderes ist, muss sich nicht verstecken.",
"source": "Wunder",
"length": 109,
"id": 297
},
{
"text": " Sei gütig, denn alle Menschen, denen du begegnest, kämpfen einen schweren Kampf. Und wenn man erkennen will, wie Menschen sind, braucht man nichts weiter zu tun, als hinzusehen.",
"source": "Wunder",
"length": 178,
"id": 298
},
{
"text": "Wir alle sind die Summen dessen, woran wir uns erinnern. In uns tragen wir die Hoffnungen und Ängste derjenigen, die uns lieben. Und solange die Liebe und die Erinnerung in unserem Herzen lebendig bleiben, ist niemand jemals wahrhaftig vergessen und vergangen.",
"source": "Chroniken der Unterwelt City of Heatenly Fire",
"length": 260,
"id": 299
},
{
"text": "Ich weiß, ich hab dir mal gesagt, dass ich nicht wüsste, ob es einen Gott gibt oder nicht, aber dass wir so oder so auf uns allein gestellt wären. Doch das stimmt nicht: Mit dir zusammen bin ich nie allein.",
"source": "Chroniken der Unterwelt City of Lost Souls",
"length": 206,
"id": 300
},
{
"text": "Du würdest mich wirklich mögen, wenn du mich richtig kennenlernen würdest. Ich kenne mich seit Jahren und liebe mich.",
"source": "Skulduggery Pleasant Die Diablerie bittet zum Sterben",
"length": 117,
"id": 301
},
{
"text": "Mein Bruder ist ziemlich unverwüstlich. Ich habe schon drei Mal versucht ihn umzubringen, aber er bleibt einfach nicht liegen.",
"source": "Skulduggery Pleasant Der Gentleman mit der Feuerhand",
"length": 126,
"id": 302
},
{
"text": "Türen sind für Leute ohne Fantasie.",
"source": "Skulduggery Pleasant Der Gentleman mit der Feuerhand",
"length": 35,
"id": 303
},
{
"text": "Sie schuf nicht eine, sondern viele Geschichten. Geschichten innerhalb von Geschichten. Rätsel und falsche Wendungen und unwahre Enden, in Stein und Wachs und in Rauch.",
"source": "Das sternenlose Meer",
"length": 168,
"id": 304
},
{
"text": "Ich möchte, dass jeder dich trifft. Du bist meine Lieblingsperson aller Zeiten.",
"source": "Tote Mädchen lügen nicht",
"length": 79,
"id": 305
},
{
"text": "Manchmal behalten wir Geheimnisse für uns, um sie vor anderen Leuten zu verstecken. Manchmal bewahren wir sie, um diese Leute zu schützen.",
"source": "Tote Mädchen lügen nicht",
"length": 138,
"id": 306
},
{
"text": "Jeder hat was, was er verbergen will. Aber das klappt nicht immer.",
"source": "Tote Mädchen lügen nicht",
"length": 66,
"id": 307
},
{
"text": "Ich mag sie. Durch sie probierst du neue Sachen aus, das tut dir gut. Ich meins ernst du wirst als hättest du weniger Angst, wenn du bei ihr bist. Das ist schön und es macht mich auch irgendwie traurig.",
"source": "Tote Mädchen lügen nicht",
"length": 205,
"id": 308
},
{
"text": "Wir alle verbergen irgendwelche Dinge. Manchmal überleben wir dadurch, dass wir Geheimnisse verwahren. Denn in der High School kann dich ein Gerücht, ein Bild oder ein Vorfall für immer brandmarken.",
"source": "Tote Mädchen lügen nicht",
"length": 198,
"id": 309
},
{
"text": "Sie dringen in deinen Kopf ein. Leute erzählen Lügen über dich und andere Leute glauben das. Und es geht so weit, dass die Lügen genauso gut die Wahrheit sein könnten.",
"source": "Tote Mädchen lügen nicht",
"length": 167,
"id": 310
},
{
"text": "Wenn ich die Sache nicht ändern kann, dann schließe ich lieber damit ab.",
"source": "Tote Mädchen lügen nicht",
"length": 72,
"id": 311
},
{
"text": "Millionen sterben an Krankheiten, die wir heilen können. Millionen leben in Armut, obwohl es genug für alle gibt. Wir zerstören unsere Biosphäre, obwohl wir wissen, dass sie unsere einzige Heimat ist. Wir bedrohen uns gegenseitig mit Atomwaffen, auch wenn wir wissen, wohin das führen kann. Wir lieben Lebendiges, lassen aber massenhaftes Artensterben zu. Und dann der Ganze Rest Genozid, Folter, Versklavung, häusliche Gewalt bis hin zum Mord, Kindesmissbrauch, Schießereien an Schulen, Vergewaltigung, tagtäglich eine schier endlose Zahl skandalöser Gräueltaten. Wir leben mit all diesen Grausamkeiten und sind nicht mal erstaunt, wenn wir trotzdem unser Glück, sogar Liebe finden. Künstliche Intelligenzen sind da weniger gut geschützt.",
"source": "Maschinen wie ich",
"length": 741,
"id": 312
},
{
"text": "Werkseinstellungen ein modernes Synonym für Schicksal.",
"source": "Maschinen wie ich",
"length": 56,
"id": 313
},
{
"text": "Allmählich muss ich sagen, dass deine süße Naivität in Wahrheit hinreißende Idiotie ist. Du bist so was wie die niedliche Version eines Dorfdeppen.",
"source": "Dark Elements",
"length": 147,
"id": 314
},
{
"text": "Heiliger Müsliriegel. Ich gab mir alle Mühe, nicht abzudrehen, aber das hier war der Sensenmann. Und er hatte mich bereits erwartet.",
"source": "Dark Elements Sehnsuchtsvolle Berührung",
"length": 132,
"id": 315
},
{
"text": "Und dann, wenn Tage ins Land gegangen sind, haltet nach mir Ausschau. Vielleicht schreibe ich in den Wasserdampf am Spiegel, wenn ihr badet, oder spiele mit den Blättern vom Apfelbaum, wenn ihr im Garten draußen seid. Ich könnte in einen Traum schlüpfen. Besuch mein Grab, wenn du kannst, aber mach dir keine Vorwürfe, wenn nicht, oder wenn ihr umzieht und es dann zu weit weg ist. Im Sommer sieht es da hübsch aus. Du könntest ein Picknick mitnehmen und dich zu mir setzten. Das würde mir gefallen.",
"source": "Bevor ich sterbe",
"length": 499,
"id": 316
},
{
"text": "Er gibt mir Feuer. Lange Zeit sagen wir nichts, pusten nur unseren Rauch auf die Stadt da unten. Dann sagt er: \"Da unten könnte alles Mögliche passieren, und hier ober würde man es einfach nichts davon merken.\"",
"source": "Bevor ich sterbe",
"length": 210,
"id": 317
},
{
"text": "Kaum ist er weg, fehlt er mir schon. Wenn er nicht bei mir ist, kommt es mir so vor, als hätte ich ihn mir ausgedacht.",
"source": "Bevor ich sterbe",
"length": 118,
"id": 318
},
{
"text": "Vielleicht bin ich tot. Vielleicht wird da nie noch was sein. Die Lebenden in ihrer Welt weitermachen sich berühren, gehen. Und ich werde in dieser leeren Welt bleiben und lautlos gegen die Glasscheiben zwischen uns pochen.",
"source": "Bevor ich sterbe",
"length": 225,
"id": 319
},
{
"text": "Die Zeichen, die die Menschen setzen, sind viel zu oft Narben.",
"source": "Das Schicksal ist ein mieser Verräter",
"length": 62,
"id": 320
},
{
"text": "Menschen, die du liebst, werden dich wie helle Lichter in die andere Welt begleiten.",
"source": "Everflame Feuerprobe",
"length": 84,
"id": 321
},
{
"text": "Sei es richtig oder falsch, kämpfe für das, woran du glaubst.",
"source": "Du oder das ganze Leben",
"length": 61,
"id": 322
},
{
"text": "Manchmal müssen gute Menschen Dinge tun, die nicht gut sind.",
"source": "Du oder das ganze Leben",
"length": 60,
"id": 323
},
{
"text": "Zuerst ist man völlig betäubt und versucht, es auszublenden. Ich meine, man weiß, dass er fort ist und so, aber es ist, als stecke man in diesem Nebel fest. Dann wird das Leben irgendwie wieder zu m Alltag und man fügt sich darin. Irgendwann hört man auf, ständig daran zu denken und lebt einfach sein Leben weiter. Man hat gar keine andere Wahl.",
"source": "Du oder das ganze Leben",
"length": 346,
"id": 324
},
{
"text": "Ich möchte, dass ihr alle wisst, dass wir die erste Verteidigungslinie sind. Genau genommen sind wir die einzige Verteidigungslinie. Falls wir scheitern, wird es für die anderen wer immer das sein wird nicht mehr allzu viel zu tun geben. Was ich damit sagen will, ist, dass Versagen an dieser Stelle keine wirklich clevere Alternative ist. Wir dürfen nicht versagen. Hat das jeder verstanden? Versagen ist negativ, und wir tun uns auch auf lange Sicht keinen Gefallen damit, und ich glaube, ich habe jetzt den Faden verloren und weiß nicht mehr, was ich eigentlich sagen wollte. Aber ich weiß, womit ich angefangen habe, und das müsst ihr euch merken. Hat jemand meinen Hut gesehen?",
"source": "Skulduggery Pleasant Das Groteskerium kehrt zurück",
"length": 686,
"id": 325
},
{
"text": "Falls es schiefgeht, locke ich sie weg. Sobald die Luft rein ist, gehst du zum Wagen zurück. Wenn du mich in fünf Minuten nicht siehst, bin ich wahrscheinlich den Heldentod gestorben. Oh, und lass die Finger vom Autoradio. Ich habe es eben erst auf meinen Lieblingssender eingestellt und will nicht, dass du mir daran herumfummelst.",
"source": "Skulduggery Pleasant Das Groteskerium kehrt zurück",
"length": 332,
"id": 326
},
{
"text": "Letztendlich gibt es weder für die Realität noch für etwas derart Abstraktes wie Vernunft endgültige Beweise. Die Menschheit hat sich auf eine Norm geeinigt, um mit dem Irrsinn des Lebens klarzukommen. Alles, was davon abweicht, gilt als krank oder mangelhaft.",
"source": "Zwischen jetzt und nie geschehen",
"length": 260,
"id": 327
},
{
"text": "Todesfurcht ist nichts anderes als die Liebe zum Leben. Es ist ein Geschenk, auch wenn es sich hin und wieder wie ein Geißel auf deinem nackten Rücken anfühlt.",
"source": "Zwischen jetzt und nie geschehen",
"length": 159,
"id": 328
},
{
"text": "Wenn du mit der gleichen Kraft hasst, mit der du vergibst, dann gnade Gott deinen Feinden.",
"source": "Die Alchimistin",
"length": 90,
"id": 329
},
{
"text": "Verdammt, ich will keine von denen sein, die auf der Couch hocken und immer nur davon reden, was sie mal Großes tun wollen. Ich will es tun.",
"source": "Eine wie Alaska",
"length": 140,
"id": 330
}
]
}