Anfuehrungszeichen: 199 falsche Schlusszeichen im sichtbaren Text
Deutsch oeffnet mit „ und schliesst mit “. An 199 Stellen, die ein
Mensch liest, stand als Schlusszeichen ein GERADES " -- „Nächstes"
statt „Nächstes“. Auf sechzehn oeffentlichen Seiten, in vierzig
Dateien des Workspace und in zwoelf Servermodulen, die Texte
verschicken.
Auf dem Bildschirm sieht man den Unterschied sofort. Beim Schreiben
nicht: Das gerade " liegt auf der Tastatur, die anderen nicht.
WARUM EIN ERSTER ANLAUF ZURUECKGENOMMEN WURDE
Ein gerades " ist an vielen Stellen SYNTAX und kein Schriftzeichen --
Grenze einer Zeichenkette, Grenze eines HTML-Attributs, Zeichen in
einem regulaeren Ausdruck. Wer stumpf ersetzt, macht aus
„<a href="https://… ein kaputtes Attribut
/^["'„»\s]+|["'“«.\s]+$/ einen kaputten Ausdruck
"… nichts „mal " + "eben …" eine kaputte Zeichenkette
DIE UNTERSCHEIDUNG LAEUFT AN MERKMALEN, NICHT AN EINER LISTE
< > = dazwischen -> HTML-Marke oder Attribut
endet auf Leerzeichen -> die Zeichenkette hoert hier auf, der
Satz geht in der naechsten Zeile weiter.
Ein deutsches Schlusszeichen steht NIE
hinter einem Leerzeichen.
Rueckstrich mittendrin -> regulaerer Ausdruck
${ ohne } -> mitten in einem Ausdruck
Eine Liste erlaubter Ausnahmen waere die naechste, die niemand
pflegt. Zwoelf Stellen bleiben dadurch stehen, alle zwoelf einzeln
angesehen und alle zwoelf zu Recht -- dort steht das richtige
Schlusszeichen ohnehin weiter unten im Satz.
Fuenf davon waren allerdings ECHTE Fehler HINTER dem Link
(`…>HasiDog</a>".`) -- die erste Regel hatte nur das Attribut
gesehen, nicht den Satz danach. Gezielt nachgezogen.
Ein maskiertes `\"` in workspace-vorlagen.js (28 Hooks) wird zu “ --
ohne Rueckstrich, denn “ begrenzt nichts.
KOMMENTARE BLEIBEN, WIE SIE SIND. Dort liest es niemand ausser mir;
eine Wache, die auch Kosmetik anmahnt, wird weggeklickt. Beim ersten
Messen fielen ausserdem acht Stellen aus buehne.html faelschlich an,
weil `/* */` in HTML (in <style> und <script>) nicht ausgeblendet
war -- jetzt schon.
DIE WACHE DAZU
pruef-struktur prueft es ab sofort mit derselben Regel: 322 Dateien
mit sichtbarem Text, 0 Funde, und die zwoelf bewussten Ausnahmen
werden GEZAEHLT und genannt (erlaubt: 12). Eine Ausnahme, die niemand
sieht, waechst -- und irgendwann steht der echte Fall darin.
GEPRUEFT
pruef-struktur 59 -> 68 Pruefungen, 0 Fehler
node --check auf allen geaenderten JS-Dateien
nachgemessen: 199 geaendert, 12 mit Grund stehen geblieben
gruen geblieben: bewerbung-aufgaben 163, nachwuchs 262,
reaktion 421, support 63, content 45, terminregel 35, treff 85
Und nachgesehen, ob eine Pruefung noch die alte Schreibweise
ERWARTET: 13 Fundstellen, alle dreizehn nur Text in ihrer eigenen
Ausgabe, keine einzige ein Vergleich mit dem Seitentext.
GEGENPROBE: In reaktion.html ein Schlusszeichen zurueckgedreht ->
„workspace/reaktion.html:546 „Nächstes"", mit Datei und Zeile. Und
die Erkennung einzeln gegen HTML-Attribut, fortgesetzte
Zeichenkette, regulaeren Ausdruck und eingesetzten Wert geprueft.
Stempel gesetzt: workspace 670 Verweise in 45 Dateien, oeffentlich
554 in 48 Seiten.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
+121
-1
@@ -28,7 +28,7 @@
|
||||
werden. Eine Pruefung, die immer bestaetigt, bestaetigt nichts. */
|
||||
|
||||
import { readFileSync, readdirSync, existsSync, statSync } from "node:fs";
|
||||
import { join, dirname, resolve } from "node:path";
|
||||
import { sep, join, dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { brotliCompressSync, constants } from "node:zlib";
|
||||
|
||||
@@ -772,6 +772,126 @@ console.log(`\n=== Laedt jedes Server-Modul? ===`);
|
||||
Deshalb wird es hier gesucht, statt darauf zu warten, dass es wieder
|
||||
jemanden trifft. Gemeint ist nur das TAGESDATUM; ein Zeitstempel
|
||||
(`erstellt`) darf und soll UTC sein. */
|
||||
console.log(`\n=== Das deutsche Schlusszeichen ===`);
|
||||
/* ===================================================================
|
||||
AM 01.10.2026 NACHGEMESSEN: 199 Stellen, die ein Mensch liest,
|
||||
schlossen ein deutsches Anfuehrungszeichen mit einem GERADEN " --
|
||||
auf sechzehn oeffentlichen Seiten, in vierzig Dateien des
|
||||
Workspace und in zwoelf Servermodulen, die Texte verschicken.
|
||||
|
||||
Deutsch oeffnet mit \u201E und schliesst mit \u201C. Auf dem
|
||||
Bildschirm sieht man den Unterschied sofort; beim Schreiben nicht,
|
||||
denn das gerade " liegt auf der Tastatur und die anderen nicht.
|
||||
Ohne Wache sind es in vier Wochen wieder zwanzig.
|
||||
|
||||
WAS BEWUSST STEHEN BLEIBT -- und warum die Regel so und nicht
|
||||
einfacher ist: Ein gerades " ist an vielen Stellen SYNTAX und kein
|
||||
Schriftzeichen. Es begrenzt eine Zeichenkette, ein HTML-Attribut
|
||||
oder steht in einem regulaeren Ausdruck. Ein erster Anlauf, der
|
||||
stumpf ersetzte, musste zurueckgenommen werden.
|
||||
|
||||
Die Unterscheidung laeuft an Merkmalen, nicht an einer Liste von
|
||||
Ausnahmen:
|
||||
< > = dazwischen -> HTML-Marke oder Attribut
|
||||
endet auf Leerzeichen -> die Zeichenkette hoert hier auf, der
|
||||
Satz geht in der naechsten Zeile weiter. Ein deutsches
|
||||
Schlusszeichen steht NIE hinter einem Leerzeichen.
|
||||
Rueckstrich mittendrin -> regulaerer Ausdruck
|
||||
${ ohne } -> mitten in einem Ausdruck
|
||||
=================================================================== */
|
||||
{
|
||||
const AUF = "\u201E"; /* „ */
|
||||
const ZU = "\u201C"; /* “ */
|
||||
/* Zusammengesetzt und nicht ausgeschrieben: Sonst zeigte diese
|
||||
Datei sich beim naechsten Lauf selbst an. */
|
||||
const suche = new RegExp(AUF + '([^' + ZU + AUF + '"`\n]{1,140})"', "g");
|
||||
|
||||
const warumNicht = (innen) => {
|
||||
if (/[<>=]/.test(innen)) return "HTML-Marke oder Attribut";
|
||||
if (innen.endsWith(" ")) return "Satz geht in der naechsten Zeile weiter";
|
||||
if (innen.replace(/\\+$/, "").includes("\\")) return "regulaerer Ausdruck";
|
||||
if ((innen.match(/\$\{/g) || []).length !== (innen.match(/\}/g) || []).length) {
|
||||
return "offener Ausdruck";
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/* WAS EIN MENSCH LIEST: die oeffentlichen Seiten, der Workspace und
|
||||
die Servermodule, die Texte verschicken. Pruef- und Messdateien
|
||||
schreiben nur in meine Konsole -- dort waere es Kosmetik, und
|
||||
eine Wache, die auch Kosmetik anmahnt, wird weggeklickt. */
|
||||
const sammeln = (ordner, tiefe = 0) => {
|
||||
const raus = [];
|
||||
for (const e of readdirSync(ordner, { withFileTypes: true })) {
|
||||
if (e.name === "node_modules" || e.name.startsWith(".")) continue;
|
||||
const voll = join(ordner, e.name);
|
||||
if (e.isDirectory()) { if (tiefe < 4) raus.push(...sammeln(voll, tiefe + 1)); continue; }
|
||||
if (/\.(js|mjs|html|css)$/.test(e.name)) raus.push(voll);
|
||||
}
|
||||
return raus;
|
||||
};
|
||||
const dateien = [
|
||||
...sammeln(join(SERVER, "..", "workspace")),
|
||||
...sammeln(join(SERVER, "..", "assets")),
|
||||
...readdirSync(join(SERVER, "..")).filter((n) => n.endsWith(".html"))
|
||||
.map((n) => join(SERVER, "..", n)),
|
||||
...readdirSync(SERVER).filter((n) => n.startsWith("workspace-") && n.endsWith(".js"))
|
||||
.map((n) => join(SERVER, n)),
|
||||
];
|
||||
ok(dateien.length > 100, `${dateien.length} Dateien mit sichtbarem Text angesehen`);
|
||||
|
||||
const falsch = [];
|
||||
const stehenGelassen = [];
|
||||
for (const pfad of dateien) {
|
||||
const art = pfad.slice(pfad.lastIndexOf("."));
|
||||
let text = readFileSync(pfad, "utf8")
|
||||
.replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, " "))
|
||||
.replace(/<!--[\s\S]*?-->/g, (m) => m.replace(/[^\n]/g, " "));
|
||||
if (art === ".js" || art === ".mjs") {
|
||||
text = text.replace(/^\s*\/\/.*$/gm, "");
|
||||
}
|
||||
/* Der Pfad AB DER WURZEL des Projekts -- ein abgeschnittener
|
||||
Pfad ist eine Meldung, der man nicht folgen kann. */
|
||||
const kurz = pfad.split(sep).join("/").split("/DogiHompage/").pop();
|
||||
for (const t of text.matchAll(suche)) {
|
||||
const zeile = text.slice(0, t.index).split("\n").length;
|
||||
const nein = warumNicht(t[1]);
|
||||
if (nein) stehenGelassen.push(`${kurz}:${zeile} (${nein})`);
|
||||
else falsch.push(`${kurz}:${zeile} ${AUF}${t[1].slice(0, 40)}"`);
|
||||
}
|
||||
}
|
||||
ok(falsch.length === 0,
|
||||
falsch.length
|
||||
? `schliessen ein deutsches Anfuehrungszeichen mit einem geraden ":\n `
|
||||
+ falsch.slice(0, 15).join("\n ")
|
||||
+ (falsch.length > 15 ? `\n ... und ${falsch.length - 15} weitere` : "")
|
||||
: `kein sichtbarer Text schliesst mit einem geraden " (${dateien.length} Dateien)`);
|
||||
|
||||
/* DIE AUSNAHMEN WERDEN GEZAEHLT UND GENANNT. Eine Ausnahme, die
|
||||
niemand sieht, waechst -- und irgendwann steht der echte Fall
|
||||
darin und faellt nicht mehr auf. */
|
||||
ok(stehenGelassen.length <= 12,
|
||||
`${stehenGelassen.length} Stellen bleiben mit Grund stehen`
|
||||
+ ` (erlaubt: 12) — ${stehenGelassen.slice(0, 3).join(", ") || "—"}`);
|
||||
|
||||
/* ---- GEGENPROBEN ------------------------------------------------ */
|
||||
const findet = (code) => {
|
||||
const treffer = [...code.matchAll(new RegExp(suche.source, "g"))];
|
||||
return treffer.filter((t) => !warumNicht(t[1])).length;
|
||||
};
|
||||
ok(findet(`Er sagte ${AUF}hallo".`) === 1,
|
||||
"Gegenprobe: ein gerades Schlusszeichen faellt auf");
|
||||
ok(findet(`Er sagte ${AUF}hallo${ZU}.`) === 0, " das richtige NICHT");
|
||||
ok(findet(`${AUF}<a href="x">y</a>`) === 0,
|
||||
" ein HTML-Attribut ist kein Schlusszeichen");
|
||||
ok(findet(`"… nichts ${AUF}mal " + "eben …"`) === 0,
|
||||
" und die Begrenzung einer Zeichenkette, die weitergeht, auch nicht");
|
||||
ok(findet('/^["\'' + AUF + '»\\s]+|["]/') === 0,
|
||||
" ein regulaerer Ausdruck ebenfalls nicht");
|
||||
ok(findet(AUF + "${a.titel}\"") === 1,
|
||||
" ein eingesetzter Wert dagegen schon");
|
||||
}
|
||||
|
||||
console.log(`\n=== Ruft ein Modul etwas, das es nie eingefuehrt hat? ===`);
|
||||
/* ===================================================================
|
||||
AM 01.10.2026 SELBST GEBAUT UND FAST AUSGELIEFERT.
|
||||
|
||||
@@ -178,7 +178,7 @@ export function resuemeeVon(antworten, punkte, felder, vorher = null, einordnung
|
||||
kopf = unklarP === n
|
||||
? "Diesmal konntest du zu fast allem nichts sagen. Das ist eine ehrliche "
|
||||
+ "Antwort – und beim nächsten Mal weißt du vermutlich mehr."
|
||||
: `Alle ${n} Fragen dieser Runde stehen auf „Läuft". Das ist selten, und `
|
||||
: `Alle ${n} Fragen dieser Runde stehen auf „Läuft“. Das ist selten, und `
|
||||
+ "es ist kein Zufall – irgendwas machst du gerade richtig.";
|
||||
} else if (!haktP.length) {
|
||||
kopf = `Nichts hakt gerade. ${waechstP.length === 1 ? "Eine Sache wächst" : `${waechstP.length} Sachen wachsen`} `
|
||||
@@ -276,7 +276,7 @@ export function resuemeeVon(antworten, punkte, felder, vorher = null, einordnung
|
||||
+ "einem Menschen, wie es steht – das ist alles, und es reicht.";
|
||||
} else if (haktP.length) {
|
||||
team = themaFeld && themaN > 1
|
||||
? `Wahrscheinlich bist du damit nicht allein: „${feldName(themaFeld.schluessel)}" `
|
||||
? `Wahrscheinlich bist du damit nicht allein: „${feldName(themaFeld.schluessel)}“ `
|
||||
+ "hakt selten nur bei einem. Es in der Runde anzusprechen löst es oft "
|
||||
+ "für mehrere auf einmal."
|
||||
: "Eine Sache, die bei dir hakt, hakt selten nur bei dir. Wer sie ausspricht, "
|
||||
@@ -305,9 +305,9 @@ export function resuemeeVon(antworten, punkte, felder, vorher = null, einordnung
|
||||
sagt, welches von beidem es ist -- daran hängt, ob man mit
|
||||
einer Sache spricht oder mit einem Thema. */
|
||||
satz: themaN > 1
|
||||
? satz(`Wenn du nur an einer Stelle hinschaust, dann hier: „${feldName(themaFeld.schluessel)}" `
|
||||
? satz(`Wenn du nur an einer Stelle hinschaust, dann hier: „${feldName(themaFeld.schluessel)}“ `
|
||||
+ `– da stehen ${themaN} der Haken beieinander. Das ist selten Zufall`)
|
||||
: satz(`Wenn du nur an einer Stelle hinschaust, dann hier: „${feldName(themaFeld.schluessel)}"`),
|
||||
: satz(`Wenn du nur an einer Stelle hinschaust, dann hier: „${feldName(themaFeld.schluessel)}“`),
|
||||
/* DIE TITEL NUR, WENN ES MEHRERE SIND (22.09.2026).
|
||||
Bei genau einem stand er zweimal untereinander: einmal hier
|
||||
und gleich darunter als "Dein naechster Schritt". Im Bild
|
||||
|
||||
@@ -332,7 +332,7 @@ callRouter.post("/workspace/api/calls/:id/protokoll", gleicheHerkunft, (req, res
|
||||
INSERT INTO aufgaben
|
||||
(titel, beschreibung, status, prioritaet, creator_id, verantwortlich_id, frist, erstellt, erstellt_von)
|
||||
VALUES (?,?,'offen','mittel',?,?,?,?,?)`).run(
|
||||
t.titel, `Aus dem Gespräch „${termin.titel}"`,
|
||||
t.titel, `Aus dem Gespräch „${termin.titel}“`,
|
||||
termin.creator_id, termin.teilnehmer_id ?? termin.creator_id,
|
||||
t.frist, jetzt(), req.person.id).lastInsertRowid);
|
||||
d.prepare("INSERT INTO protokoll_aufgaben (protokoll_id, aufgabe_id) VALUES (?,?)")
|
||||
@@ -348,7 +348,7 @@ callRouter.post("/workspace/api/calls/:id/protokoll", gleicheHerkunft, (req, res
|
||||
INSERT INTO termine
|
||||
(titel, beschreibung, art, beginn, dauer_min, ort, creator_id, teilnehmer_id, erstellt, erstellt_von, haus)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?)`).run(
|
||||
termin.titel, `Folgetermin zu „${termin.titel}"`, termin.art, nb, dauer,
|
||||
termin.titel, `Folgetermin zu „${termin.titel}“`, termin.art, nb, dauer,
|
||||
termin.ort, termin.creator_id, termin.teilnehmer_id, jetzt(), req.person.id,
|
||||
/* Ein Folgetermin erbt das Haus SEINES Vorgaengers und nicht
|
||||
das der Adresse: Wer ihn ansetzt, verlaengert etwas, das
|
||||
|
||||
@@ -333,8 +333,8 @@ export function darfSchreiben(person, bereich) {
|
||||
const hat = stufeVon(person);
|
||||
if (!stufeReicht(hat, noetig)) {
|
||||
return noetig === "dabei"
|
||||
? `Ab „${STUFEN_NAME.dabei}" kannst du hier schreiben – das ist nach ${DABEI_TAGE} Tagen so weit.`
|
||||
: `Ab „${STUFEN_NAME.stamm}" kannst du hier etwas einstellen – nach ${STAMM_TAGE} Tagen `
|
||||
? `Ab „${STUFEN_NAME.dabei}“ kannst du hier schreiben – das ist nach ${DABEI_TAGE} Tagen so weit.`
|
||||
: `Ab „${STUFEN_NAME.stamm}“ kannst du hier etwas einstellen – nach ${STAMM_TAGE} Tagen `
|
||||
+ `und ${STAMM_BEITRAEGE} eigenen Beiträgen.`;
|
||||
}
|
||||
return null;
|
||||
@@ -1023,7 +1023,7 @@ treffRouter.post("/workspace/api/treff/mitmachen/:id/uebernehmen", gleicheHerkun
|
||||
VALUES ('talente','empfohlen',?,?,?,'mittel','offen',?,?,?,?)`)
|
||||
.run(
|
||||
`${wer?.name ?? "Jemand"} hat sich im Rudel gemeldet`,
|
||||
`Aus „Mitmachen": ${String(e.titel ?? "")}\n\n${String(e.text ?? "")}`.trim(),
|
||||
`Aus „Mitmachen“: ${String(e.titel ?? "")}\n\n${String(e.text ?? "")}`.trim(),
|
||||
/* Der TAG in Ortszeit (01.10.2026), der Zeitstempel in UTC. */
|
||||
heuteLokal(), e.erstellt_von, nun, req.person.id, "Das Rudel");
|
||||
protokolliere("treff_talent", { personId: req.person.id, ip: echteIp(req),
|
||||
|
||||
@@ -86,65 +86,65 @@ const BEREICH_PUNKTE = {};
|
||||
export const CONTENT_IDEEN = [
|
||||
/* ---- Wert (70 %) ---------------------------------------------------- */
|
||||
{ schluessel: "das-haette-ich-am-anfang-gern-gewusst", titel: "Das hätte ich am Anfang gern gewusst",
|
||||
hook: "„Ich hab drei Monate gebraucht, um das zu kapieren – du brauchst 30 Sekunden.\"",
|
||||
hook: "„Ich hab drei Monate gebraucht, um das zu kapieren – du brauchst 30 Sekunden.“",
|
||||
format: "Talking Head", saeule: "Wert", stufe: "anfaenger",
|
||||
text: "Ein Fehler, den du selbst gemacht hast, und was du heute anders machst. "
|
||||
+ "Konkret bleiben: ein Fehler, eine Lösung. Wer drei Dinge sagt, sagt nichts." },
|
||||
{ schluessel: "mein-setup-fuer-unter-100", titel: "Mein Setup für unter 100 €",
|
||||
hook: "„Alle sagen, du brauchst teure Technik. Hier ist meins für 87 Euro.\"",
|
||||
hook: "„Alle sagen, du brauchst teure Technik. Hier ist meins für 87 Euro.“",
|
||||
format: "Zeigen & Erklären", saeule: "Wert", stufe: "anfaenger",
|
||||
text: "Was du wirklich benutzt, mit Preisen. Ehrlich sein, wo es hakt – "
|
||||
+ "das ist der Teil, den niemand sonst zeigt." },
|
||||
{ schluessel: "drei-einstellungen-die-sofort-was-bringe", titel: "Drei Einstellungen, die sofort was bringen",
|
||||
hook: "„Wenn dein Stream unscharf aussieht, liegt es an einer davon.\"",
|
||||
hook: "„Wenn dein Stream unscharf aussieht, liegt es an einer davon.“",
|
||||
format: "Bildschirmaufnahme", saeule: "Wert", stufe: "fort",
|
||||
text: "Nicht mehr als drei. Jede in unter 15 Sekunden erklärt, mit Vorher/Nachher." },
|
||||
{ schluessel: "was-ich-in-einer-woche-gelernt-habe", titel: "Was ich in einer Woche gelernt habe",
|
||||
hook: "„Sieben Tage, eine Erkenntnis – die hier hat alles verändert.\"",
|
||||
hook: "„Sieben Tage, eine Erkenntnis – die hier hat alles verändert.“",
|
||||
format: "Talking Head", saeule: "Wert", stufe: "anfaenger",
|
||||
text: "Rückblick auf eine echte Woche. Funktioniert nur mit einer konkreten Zahl "
|
||||
+ "oder einem konkreten Moment." },
|
||||
{ schluessel: "antwort-auf-die-frage-die-immer-kommt", titel: "Antwort auf die Frage, die immer kommt",
|
||||
hook: "„Das werde ich jeden Tag gefragt – hier einmal in Ruhe.\"",
|
||||
hook: "„Das werde ich jeden Tag gefragt – hier einmal in Ruhe.“",
|
||||
format: "Talking Head", saeule: "Wert", stufe: "fort",
|
||||
text: "Aus dem Chat sammeln, welche Frage sich wiederholt. Die Antwort einmal "
|
||||
+ "gut aufnehmen und immer wieder verwenden." },
|
||||
{ schluessel: "so-bereite-ich-einen-stream-vor", titel: "So bereite ich einen Stream vor",
|
||||
hook: "„Zwei Stunden vor LIVE mache ich immer dasselbe.\"",
|
||||
hook: "„Zwei Stunden vor LIVE mache ich immer dasselbe.“",
|
||||
format: "Vlog", saeule: "Wert", stufe: "fort",
|
||||
text: "Der Ablauf hinter der Sendung. Zeigt Verlässlichkeit und gibt Anfängern "
|
||||
+ "eine Vorlage." },
|
||||
{ schluessel: "fehler-die-ich-bei-anderen-sehe", titel: "Fehler, die ich bei anderen sehe",
|
||||
hook: "„Bitte mach das nicht – ich sehe es jeden Tag.\"",
|
||||
hook: "„Bitte mach das nicht – ich sehe es jeden Tag.“",
|
||||
format: "Talking Head", saeule: "Wert", stufe: "profi",
|
||||
text: "Niemanden bloßstellen. Das Verhalten beschreiben, nicht die Person." },
|
||||
|
||||
/* ---- Community (20 %) ------------------------------------------------ */
|
||||
{ schluessel: "der-beste-moment-aus-dem-letzten-live", titel: "Der beste Moment aus dem letzten LIVE",
|
||||
hook: "„Das ist gestern passiert, und ich rede immer noch davon.\"",
|
||||
hook: "„Das ist gestern passiert, und ich rede immer noch davon.“",
|
||||
format: "Zusammenschnitt", saeule: "Community", stufe: "anfaenger",
|
||||
text: "Ein Ausschnitt, keine Zusammenfassung. Wer alles zeigt, zeigt nichts." },
|
||||
{ schluessel: "ich-beantworte-eure-kommentare", titel: "Ich beantworte eure Kommentare",
|
||||
hook: "„Ihr habt gefragt – jetzt rede ich.\"",
|
||||
hook: "„Ihr habt gefragt – jetzt rede ich.“",
|
||||
format: "Talking Head", saeule: "Community", stufe: "anfaenger",
|
||||
text: "Drei bis fünf echte Kommentare, sichtbar eingeblendet. Auch die kritischen." },
|
||||
{ schluessel: "danke-an-die-die-immer-da-sind", titel: "Danke an die, die immer da sind",
|
||||
hook: "„Ihr seid seit dem ersten Stream dabei. Das hier ist für euch.\"",
|
||||
hook: "„Ihr seid seit dem ersten Stream dabei. Das hier ist für euch.“",
|
||||
format: "Talking Head", saeule: "Community", stufe: "fort",
|
||||
text: "Namen nennen, wenn die Leute einverstanden sind. Sonst allgemein bleiben – "
|
||||
+ "aber ehrlich." },
|
||||
{ schluessel: "eine-entscheidung-bei-der-ihr-mitredet", titel: "Eine Entscheidung, bei der ihr mitredet",
|
||||
hook: "„Ich kann mich nicht entscheiden. Ihr habt 24 Stunden.\"",
|
||||
hook: "„Ich kann mich nicht entscheiden. Ihr habt 24 Stunden.“",
|
||||
format: "Umfrage", saeule: "Community", stufe: "fort",
|
||||
text: "Echte Wahl, keine Scheinfrage. Das Ergebnis danach auch wirklich umsetzen." },
|
||||
|
||||
/* ---- Eigenwerbung (10 %) --------------------------------------------- */
|
||||
{ schluessel: "wann-und-wo-ich-streame", titel: "Wann und wo ich streame",
|
||||
hook: "„Immer dienstags und donnerstags – und ich fange pünktlich an.\"",
|
||||
hook: "„Immer dienstags und donnerstags – und ich fange pünktlich an.“",
|
||||
format: "Kurzclip", saeule: "Eigenwerbung", stufe: "anfaenger",
|
||||
text: "Fester Sendeplan als eigener Clip. Wiederholbar, sobald sich etwas ändert." },
|
||||
{ schluessel: "was-diese-woche-ansteht", titel: "Was diese Woche ansteht",
|
||||
hook: "„Drei Sachen, und eine davon habe ich noch nie gemacht.\"",
|
||||
hook: "„Drei Sachen, und eine davon habe ich noch nie gemacht.“",
|
||||
format: "Kurzclip", saeule: "Eigenwerbung", stufe: "anfaenger",
|
||||
text: "Vorschau auf die Woche. Kurz halten, sonst wird es eine Ankündigung "
|
||||
+ "statt einer Einladung." },
|
||||
@@ -168,81 +168,81 @@ export const CONTENT_IDEEN = [
|
||||
|
||||
/* ---- Wert (70 %) ---- */
|
||||
{ schluessel: "vorher-nachher-an-meinem-kanal", titel: "Vorher / Nachher an meinem Kanal",
|
||||
hook: "„So sah mein Stream vor drei Monaten aus. Und so heute.\"",
|
||||
hook: "„So sah mein Stream vor drei Monaten aus. Und so heute.“",
|
||||
format: "Vorher / Nachher", saeule: "Wert", stufe: "anfaenger",
|
||||
text: "Zwei Ausschnitte nebeneinander, dazwischen die eine Sache, die du geändert hast. "
|
||||
+ "Das Format funktioniert, weil der Zuschauer den Unterschied SIEHT und nicht glauben muss." },
|
||||
{ schluessel: "drei-sachen-die-dir-keiner-sagt", titel: "Drei Sachen, die dir keiner sagt",
|
||||
hook: "„Drei Sachen über Streaming, die dir keiner sagt – die dritte hat mich am meisten gekostet.\"",
|
||||
hook: "„Drei Sachen über Streaming, die dir keiner sagt – die dritte hat mich am meisten gekostet.“",
|
||||
format: "Nummerierte Liste", saeule: "Wert", stufe: "fort",
|
||||
text: "Eine Zahl im Aufhänger verspricht ein Ende – deshalb bleiben Leute dran. "
|
||||
+ "Die stärkste Nummer kommt zuletzt, und sie wird im Aufhänger angekündigt." },
|
||||
{ schluessel: "ich-teste-was-alle-empfehlen", titel: "Ich teste, was alle empfehlen",
|
||||
hook: "„Jeder empfiehlt das. Ich habe es zwei Wochen gemacht – hier ist das Ergebnis.\"",
|
||||
hook: "„Jeder empfiehlt das. Ich habe es zwei Wochen gemacht – hier ist das Ergebnis.“",
|
||||
format: "Selbstversuch", saeule: "Wert", stufe: "fort",
|
||||
text: "Ein verbreiteter Ratschlag, von dir selbst überprüft, mit Zahlen davor und danach. "
|
||||
+ "Widerspruch zieht Aufmerksamkeit – aber nur, wenn du wirklich getestet hast." },
|
||||
{ schluessel: "so-lese-ich-meine-zahlen", titel: "So lese ich meine Zahlen",
|
||||
hook: "„Diese eine Zahl sagt mir mehr als die Zuschauerzahl.\"",
|
||||
hook: "„Diese eine Zahl sagt mir mehr als die Zuschauerzahl.“",
|
||||
format: "Bildschirm & Erklären", saeule: "Wert", stufe: "profi",
|
||||
text: "Zeig deine eigene Auswertung: durchschnittliche Verweildauer, Anteil neuer Zuschauer, "
|
||||
+ "Wiederkehrer. Erklär, was du daraufhin geändert hast. Wenige machen das – deshalb wirkt es." },
|
||||
{ schluessel: "die-erste-sekunde-entscheidet", titel: "Die erste Sekunde entscheidet",
|
||||
hook: "„Sag das in Sekunde eins – oder der Zuschauer ist weg.\"",
|
||||
hook: "„Sag das in Sekunde eins – oder der Zuschauer ist weg.“",
|
||||
format: "Zerlegung", saeule: "Wert", stufe: "profi",
|
||||
text: "Nimm ein eigenes Video auseinander: Was hast du in Sekunde eins gesagt, was würdest du "
|
||||
+ "heute sagen? Über 70 Prozent entscheiden in den ersten drei Sekunden. Zeig beides." },
|
||||
{ schluessel: "mein-ablauf-als-vorlage", titel: "Mein Ablauf als Vorlage zum Mitnehmen",
|
||||
hook: "„Hier ist der Ablauf, nach dem ich jeden Stream fahre. Nimm ihn.\"",
|
||||
hook: "„Hier ist der Ablauf, nach dem ich jeden Stream fahre. Nimm ihn.“",
|
||||
format: "Zeigen & Weitergeben", saeule: "Wert", stufe: "meister",
|
||||
text: "Etwas herzugeben, das bei dir funktioniert, kostet nichts und bringt Vertrauen. "
|
||||
+ "Meisterschaft zeigt sich daran, dass es auch ohne dich funktioniert." },
|
||||
{ schluessel: "was-hundert-streams-mir-beigebracht-h", titel: "Was hundert Streams mir beigebracht haben",
|
||||
hook: "„Hundert Streams. Drei Sachen sind übrig geblieben.\"",
|
||||
hook: "„Hundert Streams. Drei Sachen sind übrig geblieben.“",
|
||||
format: "Rückblick", saeule: "Wert", stufe: "meister",
|
||||
text: "Kein Best-of, sondern das, was du heute anders machst als am Anfang. "
|
||||
+ "Wer lange dabei ist, hat den einen Vorteil, den niemand abkürzen kann." },
|
||||
|
||||
/* ---- Community (20 %) ---- */
|
||||
{ schluessel: "ein-insider-den-nur-ihr-versteht", titel: "Ein Insider, den nur ihr versteht",
|
||||
hook: "„Wenn du weißt, was das bedeutet, bist du schon länger dabei.\"",
|
||||
hook: "„Wenn du weißt, was das bedeutet, bist du schon länger dabei.“",
|
||||
format: "Kurzclip", saeule: "Community", stufe: "anfaenger",
|
||||
text: "Ein Spruch, ein Emote, ein Moment aus dem Stream. Wer ihn versteht, fühlt sich zugehörig – "
|
||||
+ "und wer nicht, will dazugehören. Beides hilft." },
|
||||
{ schluessel: "eure-clips-mein-kommentar", titel: "Eure Clips, mein Kommentar",
|
||||
hook: "„Ihr habt das aufgenommen. Ich sag euch, was da wirklich los war.\"",
|
||||
hook: "„Ihr habt das aufgenommen. Ich sag euch, was da wirklich los war.“",
|
||||
format: "Reaction", saeule: "Community", stufe: "fort",
|
||||
text: "Clips, die Zuschauer selbst geschnitten haben, mit deinem Kommentar. "
|
||||
+ "Das belohnt die, die mitmachen – und wer belohnt wird, macht weiter." },
|
||||
{ schluessel: "die-regel-die-ihr-euch-gewuenscht-hab", titel: "Die Regel, die ihr euch gewünscht habt",
|
||||
hook: "„Ihr habt gefragt, ich habe es geändert. Ab heute gilt:\"",
|
||||
hook: "„Ihr habt gefragt, ich habe es geändert. Ab heute gilt:“",
|
||||
format: "Talking Head", saeule: "Community", stufe: "profi",
|
||||
text: "Eine Änderung, die aus der Community kam, mit Nennung derer, die sie angestoßen haben. "
|
||||
+ "Mitreden zu dürfen ist der stärkste Grund zu bleiben." },
|
||||
{ schluessel: "wir-machen-das-zusammen", titel: "Wir machen das zusammen",
|
||||
hook: "„Wenn wir das diese Woche schaffen, mache ich Folgendes:\"",
|
||||
hook: "„Wenn wir das diese Woche schaffen, mache ich Folgendes:“",
|
||||
format: "Gemeinsames Ziel", saeule: "Community", stufe: "profi",
|
||||
text: "Ein Ziel mit Frist und einer Belohnung, die du wirklich einlöst. "
|
||||
+ "Ein Versprechen, das nicht gehalten wird, kostet mehr als es gebracht hat." },
|
||||
{ schluessel: "mein-moderator-stellt-sich-vor", titel: "Mein Moderator stellt sich vor",
|
||||
hook: "„Ihr kennt den Namen. Hier ist der Mensch dahinter.\"",
|
||||
hook: "„Ihr kennt den Namen. Hier ist der Mensch dahinter.“",
|
||||
format: "Interview", saeule: "Community", stufe: "meister",
|
||||
text: "Wer im Chat für Ordnung sorgt, bekommt ein Gesicht. Das schützt ihn – "
|
||||
+ "gegen einen Namen schimpft man leichter als gegen einen Menschen." },
|
||||
|
||||
/* ---- Eigenwerbung (10 %) ---- */
|
||||
{ schluessel: "dreissig-minuten-vorher", titel: "30 Minuten vorher",
|
||||
hook: "„In einer halben Stunde geht es los – und heute passiert Folgendes:\"",
|
||||
hook: "„In einer halben Stunde geht es los – und heute passiert Folgendes:“",
|
||||
format: "Ankündigung", saeule: "Eigenwerbung", stufe: "anfaenger",
|
||||
text: "Ein kurzes Video 30 bis 60 Minuten vor dem Start. Es bündelt die, die ohnehin kommen "
|
||||
+ "wollten – und ein voller Start zieht neue Zuschauer nach. Eine Sache nennen, nicht drei." },
|
||||
{ schluessel: "warum-ich-heute-live-gehe", titel: "Warum ich heute live gehe",
|
||||
hook: "„Heute ist ein Grund da, und der ist nicht ‚weil Dienstag ist‘.\"",
|
||||
hook: "„Heute ist ein Grund da, und der ist nicht ‚weil Dienstag ist‘.“",
|
||||
format: "Talking Head", saeule: "Eigenwerbung", stufe: "fort",
|
||||
text: "Ein Anlass macht aus einem Termin ein Ereignis. Auch ein kleiner reicht: "
|
||||
+ "ein neues Spiel, ein Gast, eine offene Frage von letzter Woche." },
|
||||
{ schluessel: "mein-kanal-in-fuenfzehn-sekunden", titel: "Mein Kanal in fünfzehn Sekunden",
|
||||
hook: "„Fünfzehn Sekunden, dann weißt du, ob das hier für dich ist.\"",
|
||||
hook: "„Fünfzehn Sekunden, dann weißt du, ob das hier für dich ist.“",
|
||||
format: "Kurzvorstellung", saeule: "Eigenwerbung", stufe: "profi",
|
||||
text: "Für wen, worum, wann. Fest angeheftet, damit neue Zuschauer nicht raten müssen. "
|
||||
+ "Alle paar Monate neu drehen – ein Kanal von vor einem Jahr bist du nicht mehr." },
|
||||
|
||||
@@ -93,7 +93,7 @@ const EINLEITUNG = {
|
||||
},
|
||||
modi: {
|
||||
was: "Schön, dass du da bist. Hier findest du alles für deinen Tag.",
|
||||
dazu: "Unter „Aufgaben\" steht, was gerade für dich dran ist — du "
|
||||
dazu: "Unter „Aufgaben“ steht, was gerade für dich dran ist — du "
|
||||
+ "nimmst an, was du schaffst, und sagst ab, was nicht geht. Eine "
|
||||
+ "Absage ist völlig in Ordnung, schreib einfach kurz warum.",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user