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]>
701 lines
33 KiB
JavaScript
701 lines
33 KiB
JavaScript
/* =====================================================================
|
||
WAS DER SERVER SAGT, IN SÄTZEN — 19.09.2026
|
||
|
||
Filipe: „keine kryptischen oder technischen Fehlermeldungen, sondern
|
||
klare Aussagen darüber, was passiert ist und wie man das Problem
|
||
lösen kann."
|
||
|
||
---------------------------------------------------------------------
|
||
DAS PROBLEM, NACHGEMESSEN
|
||
|
||
Der Server antwortet im Fehlerfall mit `{ fehler: "…" }`. Darin
|
||
stehen ZWEI verschiedene Dinge, und sie sehen von außen gleich aus:
|
||
|
||
1. MASCHINENKENNUNGEN — `nicht_verfuegbar`, `nicht_gefunden`,
|
||
`ungueltig`. Sie sind fürs Protokoll gedacht, nicht für Augen.
|
||
Gezählt am 19.09.2026: 43 verschiedene, an 1 300 Stellen.
|
||
2. FERTIGE SÄTZE — z. B. „Woran hast du das gemerkt? Ein Satz
|
||
genügt – ohne ihn ist es beim Gespräch nur noch ein Gefühl."
|
||
Die sind genau richtig so und sollen unverändert durch.
|
||
|
||
An 75 Stellen in der Oberfläche stand `textContent = d.fehler` —
|
||
ungefiltert. Wer beim Hochladen einer Datei Pech hatte, las also
|
||
wörtlich `nicht_verfuegbar` auf dem Bildschirm. Ein Mensch ohne
|
||
Vorwissen weiß dann nicht einmal, ob er selbst etwas falsch gemacht
|
||
hat.
|
||
|
||
---------------------------------------------------------------------
|
||
DREI AUSGÄNGE, NICHT ZWEI
|
||
|
||
Das ist dieselbe Regel wie überall im Haus — eine Auskunft, die ihre
|
||
Frage nicht beantworten kann, muss das SAGEN und darf nicht schweigen:
|
||
|
||
BEKANNTE KENNUNG → ihr Satz aus der Tabelle unten.
|
||
UNBEKANNTE KENNUNG → der Ersatzsatz des Aufrufers. Sie wird NIE
|
||
angezeigt. Eine neue Kennung, die noch
|
||
niemand übersetzt hat, ist ein Fehler im
|
||
Haus — nicht etwas, das der Benutzer
|
||
ausbaden soll.
|
||
FERTIGER SATZ → unverändert durch.
|
||
|
||
Woran „Kennung" erkannt wird: nur Kleinbuchstaben, Ziffern und
|
||
Unterstriche, kein Leerzeichen. Ein deutscher Satz hat immer
|
||
Leerzeichen und Großbuchstaben; eine Kennung nie. Die Unterscheidung
|
||
ist damit nicht geraten, sondern entschieden.
|
||
|
||
---------------------------------------------------------------------
|
||
UND WARUM DIE TABELLE NICHT ALTERN KANN
|
||
|
||
Eine von Hand gepflegte Liste ist im Haus schon zweimal teuer
|
||
geworden (die abgeschriebene Spaltenliste, die feste Umbruchschwelle).
|
||
Deshalb steht daneben `pruef-meldungen.mjs`: Sie liest ALLE
|
||
Kennungen aus dem Server und wird rot, sobald eine hier fehlt.
|
||
Wer morgen eine neue erfindet, kann sie nicht vergessen.
|
||
===================================================================== */
|
||
(function () {
|
||
'use strict';
|
||
|
||
/* Zu jeder Kennung ein Satz, der zwei Dinge tut: sagen, WAS ist —
|
||
und, wo es etwas zu tun gibt, was der nächste Schritt ist.
|
||
|
||
KEIN „Fehler 400". Keine Zahl, kein englisches Wort, keine
|
||
Entschuldigung ohne Inhalt. */
|
||
var SAETZE = {
|
||
/* ---- Die drei häufigsten ------------------------------------- */
|
||
nicht_verfuegbar:
|
||
'Der Server antwortet gerade nicht. Nichts wurde gespeichert – '
|
||
+ 'versuch es in einer Minute noch einmal.',
|
||
nicht_gefunden:
|
||
'Das gibt es nicht mehr. Wahrscheinlich hat es jemand gelöscht – '
|
||
+ 'lade die Seite neu.',
|
||
ungueltig:
|
||
'Mit der Eingabe stimmt etwas nicht. Sieh die Felder noch einmal durch.',
|
||
/* Die Kachelfarbe im Chat. Der Fall entsteht nur, wenn die
|
||
Auswahl aelter ist als die Farbliste -- etwa weil die Seite seit
|
||
gestern offen liegt. Deshalb sagt der Satz, was zu tun ist, und
|
||
nicht, was schiefging. */
|
||
unbekannte_kachel:
|
||
'Diese Farbe gibt es nicht mehr. Lade die Seite neu und such dir '
|
||
+ 'eine aus der Liste aus.',
|
||
|
||
/* ---- Anmeldung und Zugang ------------------------------------ */
|
||
nicht_angemeldet:
|
||
'Du bist nicht mehr angemeldet. Melde dich noch einmal an.',
|
||
zu_viele_versuche:
|
||
'Zu viele Versuche hintereinander. Warte einen Moment, dann geht es wieder.',
|
||
/* Nicht „etwas Älteres ist offen" — es geht um die Bestätigung des
|
||
eigenen ALTERS beim ersten Anmelden. Beim ersten Hinsehen hatte
|
||
ich es falsch verstanden; der Blick in workspace.js:4864 hat es
|
||
geklärt. */
|
||
alter_offen:
|
||
'Bitte bestätige zuerst dein Alter, dann geht es weiter.',
|
||
eigener_code:
|
||
'Das ist dein eigener Zugang – den kannst du hier nicht neu vergeben.',
|
||
fremde_herkunft:
|
||
'Das wurde aus Sicherheitsgründen abgelehnt. Lade die Seite neu '
|
||
+ 'und versuch es noch einmal.',
|
||
|
||
/* ---- Darf ich das? ------------------------------------------- */
|
||
nicht_erlaubt: 'Das darfst du hier nicht ändern.',
|
||
nur_leitung: 'Das kann nur DogFather oder die rechte Hand.',
|
||
nur_gruender: 'Das kann nur, wer das Gespräch angelegt hat.',
|
||
hier_nicht: 'An dieser Stelle geht das nicht – abgestimmt wird auf der Wunschliste.',
|
||
gesperrt: 'Dafür ist die Abstimmung zu.',
|
||
geschlossen: 'Der Fall ist abgeschlossen. Hier kann nichts mehr dazukommen.',
|
||
nicht_dran: 'Du bist gerade nicht dran – warte auf die Antwort.',
|
||
leitung_meldet_nicht:
|
||
'Diesen Weg gibt es für das Team. Du liest die Meldungen, du schreibst sie nicht.',
|
||
umgezogen:
|
||
'Diese Seite ist umgezogen. Lade sie neu, dann bist du am richtigen Ort.',
|
||
|
||
/* ---- Da fehlt oder stimmt etwas ------------------------------ */
|
||
unvollstaendig: 'Da fehlt noch etwas. Die offenen Stellen sind markiert.',
|
||
leer: 'Da steht noch nichts drin.',
|
||
betreff_fehlt: 'Der Betreff fehlt noch.',
|
||
text_zu_kurz: 'Der Text ist zu kurz – ein ganzer Satz genügt.',
|
||
zu_lang: 'Das ist zu lang. Kürze es etwas.',
|
||
unbrauchbar: 'Damit kann der Server nichts anfangen. Prüf die Eingabe.',
|
||
unbekannte_stufe:
|
||
'Diese Auswahl kennt der Server nicht. Lade die Seite neu.',
|
||
unbekanntes_zeichen:
|
||
'Dieses Zeichen gibt es nicht. Lade die Seite neu.',
|
||
keine_datumsspalte:
|
||
'In der Datei fehlt eine Spalte mit dem Datum. Ohne sie lässt sich nichts zuordnen.',
|
||
keine_zuordnung:
|
||
'Die Zeilen lassen sich niemandem zuordnen. Prüf die Überschriften in der Datei.',
|
||
|
||
/* ---- Gab es schon / gibt es nicht ---------------------------- */
|
||
schon_da: 'Das gibt es schon.',
|
||
schon_uebernommen: 'Das hat schon jemand übernommen.',
|
||
schon_entschieden: 'Darüber wurde bereits entschieden.',
|
||
zurueckgenommen: 'Die Nachricht wurde zurückgenommen.',
|
||
nichts_zu_aendern: 'Es gab nichts zu ändern – es steht schon so da.',
|
||
nichts_zu_speichern:'Es gab nichts zu speichern.',
|
||
/* ---- AUFGABEN VERTEILEN (21.09.2026) -------------------------
|
||
Sechzehn Kennungen kamen mit workspace-zuteilung.js dazu, und
|
||
keine hatte einen Satz -- `pruef-meldungen` hat sie am selben
|
||
Tag gefunden. Ohne sie haette auf dem Bildschirm woertlich
|
||
"nicht_zugeteilt" gestanden.
|
||
|
||
DIE SAETZE SAGEN, WAS JETZT GEHT, nicht nur was schiefging.
|
||
"Das ging nicht" schickt einen Menschen zurueck an den Anfang;
|
||
"da war jemand schneller -- sie ist schon vergeben" sagt ihm,
|
||
dass er nichts falsch gemacht hat. */
|
||
ungueltige_aufgabe: 'Diese Aufgabe kennt das System nicht. Lade die Seite neu.',
|
||
keine_person: 'Da war niemand ausgewählt. Such eine Person aus und schick es noch einmal ab.',
|
||
gibt_es_nicht: 'Das gibt es nicht mehr. Lade die Seite neu.',
|
||
nicht_zugeteilt: 'Diese Aufgabe ist nicht dir zugeteilt – deshalb kannst du sie hier nicht annehmen.',
|
||
schon_erledigt: 'Die Aufgabe ist schon erledigt. Da ist nichts mehr zu tun.',
|
||
grund_fehlt: 'Schreib bitte kurz dazu, warum – ein Satz reicht.',
|
||
grund_zu_lang: 'Der Grund ist zu lang. Ein, zwei Sätze genügen.',
|
||
kein_pool: 'Diese Aufgabe ist niemandem zum Übernehmen freigegeben.',
|
||
schon_vergeben: 'Da war jemand schneller – die Aufgabe ist schon übernommen.',
|
||
ungueltiger_zustand:'Dieser Schritt passt gerade nicht. Lade die Seite neu, dann siehst du den aktuellen Stand.',
|
||
abgelehnt: 'Du hast diese Aufgabe abgelehnt. Wenn du sie doch machen willst, sag kurz Bescheid.',
|
||
darf_nicht_bewerten:'Rückmeldung geben dürfen nur DogFather und die Hände.',
|
||
ungueltige_bewertung:'Diese Rückmeldung kennt das System nicht. Lade die Seite neu.',
|
||
text_fehlt: 'Zu „Verbesserungsmöglichkeiten“ gehört ein Satz – sonst weiß niemand, was gemeint ist.',
|
||
text_zu_lang: 'Der Text ist zu lang. Kürze ihn etwas.',
|
||
noch_nicht_erledigt:'Rückmeldung gibt es erst, wenn die Aufgabe fertig ist.',
|
||
/* 22.09.2026: Seit die Modis sich keine Aufgaben mehr selbst geben,
|
||
kann dieser Weg abgelehnt werden. Erreichen tut ihn kaum jemand
|
||
— der Knopf „Neue Aufgabe" steht für sie gar nicht erst da —,
|
||
aber ein Tab von gestern reicht.
|
||
DER SATZ NENNT KEINE ROLLEN. Wer ihn liest, soll wissen, wie es
|
||
bei IHM weitergeht, nicht, wer über ihm steht. */
|
||
kanal_unbekannt:
|
||
'Diesen Account gibt es nicht. Wähl einen aus der Liste — oder lass das Feld auf „Aus dem Link erkennen“.',
|
||
nur_leitung_legt_an:
|
||
'Aufgaben werden dir zugeteilt – anlegen kannst du hier keine. '
|
||
+ 'Wenn du eine Idee hast, sag kurz Bescheid.',
|
||
|
||
/* 24.09.2026: Bis heute lief dieser Fall ueber dieselbe 404 wie
|
||
„geloescht" -- und auf dem Bildschirm stand „lade die Seite
|
||
neu". An einer Person, die es sehr wohl gibt, macht das nur
|
||
ratlos: Neuladen aendert nichts. Der Satz sagt deshalb, WORAN
|
||
es liegt, und nennt keine Rolle, ueber die der Leser nichts
|
||
entscheiden kann. */
|
||
rolle_ohne_katalog:
|
||
'Aus diesem Katalog bekommt diese Person keine Aufgaben. '
|
||
+ 'Wähl jemand anderen – oder leg ihr die Aufgabe von Hand an.',
|
||
|
||
/* ---- Die Reaction (28.09.2026) --------------------------------
|
||
Jede Kennung, die der Server schicken kann, bekommt hier einen
|
||
Satz. Ein Maschinenwort auf dem Bildschirm ist kein Fehler des
|
||
Servers -- es ist einer der Oberflaeche, und pruef-meldungen
|
||
zaehlt sie mit. */
|
||
nur_host:
|
||
'Das dürfen nur DogFather und die rechte Hand – '
|
||
+ 'die beiden führen die Sendung.',
|
||
video_unklar:
|
||
'Aus dieser Adresse lässt sich kein YouTube-Video lesen. '
|
||
+ 'Füg die Adresse aus der Adresszeile ein oder die Kennung.',
|
||
beginn_vorbei:
|
||
'Der Beginn liegt in der Vergangenheit. Wähl einen Zeitpunkt, '
|
||
+ 'der noch kommt – sonst zählt der Countdown ins Minus.',
|
||
stand_unbekannt:
|
||
'Diesen Zustand gibt es nicht. Möglich sind: zu, Vorbereitung, auf Sendung.',
|
||
kein_video:
|
||
'Ohne Video keine Sendung. Trag erst ein YouTube-Video ein.',
|
||
/* NICHT „geschlossen". Das Wort gab es schon -- fuer einen
|
||
abgeschlossenen Hilfe-Fall -- und ein zweiter Eintrag mit
|
||
demselben Schluessel gewinnt einfach: Ab dem Tag stand in der
|
||
Hilfe „Der Saal ist zu", und niemand haette den Zusammenhang
|
||
gesehen. Ein Wort, ein Satz. */
|
||
saal_zu:
|
||
'Der Saal ist zu. Sobald DogFather aufmacht, geht es hier weiter.',
|
||
person_unklar:
|
||
'Diese Person kenne ich nicht. Wähl jemanden aus der Liste.',
|
||
host_ist_kein_gast:
|
||
'Du führst die Sendung – du bist schon im Bild.',
|
||
gaeste_voll:
|
||
'Es sind schon zwei Gäste dabei. Nimm erst jemanden heraus.',
|
||
layout_unbekannt:
|
||
'Diese Anordnung gibt es nicht.',
|
||
laeuft_noch:
|
||
'Die Sendung läuft gerade. Beende sie zuerst — mitten im Live '
|
||
+ 'zurückzusetzen würde allen das Video wegnehmen.',
|
||
satz_unbekannt:
|
||
'Diesen Münzsatz gibt es nicht. Wähl einen aus der Liste — '
|
||
+ '„Eigenes Zeichen“ geht erst, wenn du eines hochgeladen hast.',
|
||
person_unbekannt:
|
||
'Diese Person gibt es hier nicht. Wähl jemanden aus der Liste '
|
||
+ 'oder lass das Feld leer.',
|
||
kameragroesse_unklar:
|
||
'Diese Größe gibt es nicht. Möglich sind 0,6-fach bis 2-fach.',
|
||
ecke_unklar:
|
||
'Diese Ecke gibt es nicht. Möglich sind oben/unten und links/rechts.',
|
||
tempo_unklar:
|
||
'Diese Geschwindigkeit gibt es nicht. Möglich sind 0,5 bis 2-fach.',
|
||
schon_im_bild:
|
||
'Das läuft gerade schon. Ein Umschalter braucht zwei verschiedene Videos – '
|
||
+ 'sonst passiert beim Drücken nichts.',
|
||
|
||
/* ---- Die Werbeeinblendung (29.09.2026) --------------------
|
||
Alle Listen stehen in `reaktion-tabellen.js`. Hier stehen sie
|
||
als WORTE, nicht als Werte: „0,7-fach bis 2-fach" liest sich,
|
||
„[0.7,1,1.4,2]" nicht. Wandert eine Liste, wandert der Satz
|
||
mit -- dafuer gibt es keine Automatik, aber `pruef-reaktion`
|
||
merkt wenigstens, wenn ein Wort ganz ohne Satz dasteht. */
|
||
bannerart_unklar:
|
||
'Diese Art gibt es nicht. Möglich sind: aus, Laufband und Wechsel.',
|
||
bannertempo_unklar:
|
||
'Diese Dauer gibt es nicht. Möglich sind 8, 12, 16, 24 und 40 Sekunden.',
|
||
eckenplatz_unklar:
|
||
'Diesen Platz gibt es nicht. Möglich sind oben und unten, '
|
||
+ 'jeweils links, mittig oder rechts — oder gar keiner.',
|
||
eckengroesse_unklar:
|
||
'Diese Größe gibt es nicht. Möglich sind 0,7-fach bis 2-fach.',
|
||
ecke_belegt:
|
||
'Auf diesem Platz steht schon das andere Bild. Zwei Bilder auf '
|
||
+ 'derselben Ecke lägen übereinander — nimm einen der fünf anderen Plätze.',
|
||
banner_voll:
|
||
'Mehr als acht Botschaften werden nicht gelesen. Lösch eine, '
|
||
+ 'dann ist wieder Platz.',
|
||
bild_unklar:
|
||
'Dieses Bild gibt es nicht. Möglich sind: ohne Bild, der Husky '
|
||
+ 'und der Häkelhase.',
|
||
richtung_unklar:
|
||
'Diese Richtung gibt es nicht. Eine Botschaft geht nach oben oder nach unten.',
|
||
/* ---- Die Gestaltung der Spendenkarten --------------------- */
|
||
stufen_fehlen:
|
||
'Da ist keine Stufenleiter angekommen. Lade die Seite neu und versuch es noch einmal.',
|
||
keine_stufe:
|
||
'Mindestens eine Stufe muss es geben – sonst erscheint bei einer Spende gar nichts.',
|
||
zu_viele_stufen:
|
||
'Mehr als sechs Stufen werden unübersichtlich. Nimm eine weg, dann geht es.',
|
||
stufe_betrag_unklar:
|
||
'Bei einer Stufe ergibt die Zahl keinen Sinn. Schreib sie in Dogen, '
|
||
+ 'zum Beispiel 0,1 oder 2,5.',
|
||
stufe_name_fehlt:
|
||
'Jede Stufe braucht einen Namen – er steht auf der Karte.',
|
||
stufe_doppelt:
|
||
'Zwei Stufen fangen bei derselben Zahl an. Dann wäre nicht entschieden, welche gilt.',
|
||
vorlage_unbekannt:
|
||
'Dieses Zeichen gibt es nicht. Wähl eines aus der Liste.',
|
||
farbe_unklar:
|
||
'Diese Farbe verstehe ich nicht. Nimm den Farbwähler.',
|
||
groesse_unklar:
|
||
'Diese Größe geht nicht. Möglich ist 1 bis 2,5 – kleiner wäre auf der Karte nicht mehr zu lesen. '
|
||
+ 'Für den Stream kannst du die Tafel über ihre Adresse kleiner stellen.',
|
||
kein_bild:
|
||
'Das ist kein Bild. Erlaubt sind JPG, PNG und WebP.',
|
||
bild_zu_gross:
|
||
'Das Bild ist zu groß. Erlaubt sind 3 MB.',
|
||
|
||
kein_zweites:
|
||
'Es liegt kein zweites Video bereit. Trag eins unter „Sendung“ ein, '
|
||
+ 'dann kannst du hin und her wechseln.',
|
||
betrag_unklar:
|
||
'Diese Zahl ergibt keinen Sinn. Schreib sie in Dogen, '
|
||
+ 'zum Beispiel 0,5 oder 2,5.',
|
||
name_fehlt:
|
||
'Ohne Namen keine Karte – er steht ja darauf.',
|
||
nicht_offen:
|
||
'Diese Meldung wartet nicht mehr – jemand hat sie schon entschieden.',
|
||
|
||
/* ---- Moderation im Live-Chat --------------------------------
|
||
Die Sätze sagen WARUM und, wo es einen gibt, den anderen Weg.
|
||
„Das darfst du nicht" allein lässt jemanden suchen; „dafür gibt
|
||
es den Treff" beendet die Sache. */
|
||
nur_moderation:
|
||
'Das können nur DogFather, seine Hände und die Modis.',
|
||
massnahme_unbekannt:
|
||
'Diese Maßnahme gibt es nicht. Möglich sind: stumm und aus der Sendung.',
|
||
nicht_gegen_team:
|
||
'Gegen jemanden aus dem Team geht das hier nicht. '
|
||
+ 'Wenn wirklich etwas ist, gehört das zu „Personen & Zugänge“.',
|
||
dauer_unklar:
|
||
'Eine Stummschaltung geht höchstens eine Stunde. '
|
||
+ 'Für länger nimm die Maßnahmen im Treff – die haben eine Begründung und eine Frist.',
|
||
eigener_beitrag:
|
||
'Deinen eigenen Beitrag musst du nicht melden – du kannst ihn wegnehmen.',
|
||
aus_der_sendung:
|
||
'Du bist aus dieser Sendung genommen. Das gilt nur für heute.',
|
||
stumm_geschaltet:
|
||
'Du bist gerade stumm geschaltet. Zusehen geht weiter – '
|
||
+ 'in ein paar Minuten kannst du wieder schreiben.',
|
||
treff_massnahme:
|
||
'Im Treff läuft gerade eine Maßnahme gegen dich. '
|
||
+ 'Solange sie läuft, bist du bei der Reaction nicht dabei.',
|
||
sendest_nicht:
|
||
'Kamera und Mikro schaltet nur, wer gerade sendet – '
|
||
+ 'der Host oder ein Gast auf der Bühne.',
|
||
nichts_zu_tun:
|
||
'Da war nichts zu schalten.',
|
||
chatmodus_unbekannt:
|
||
'Diese Chat-Stufe gibt es nicht. Möglich sind: offen, Team, zu.',
|
||
chat_nur_team:
|
||
'Gerade schreibt nur das Team. Gleich geht der Chat wieder auf.',
|
||
chat_zu:
|
||
'Der Chat ist gerade zu. Sobald DogFather ihn wieder aufmacht, '
|
||
+ 'geht es hier weiter.',
|
||
liste_voll:
|
||
'Die Warteschlange ist voll. Nimm erst etwas heraus – '
|
||
+ 'mehr überblickt im Live sowieso niemand.',
|
||
liste_doppelt:
|
||
'Dieses Video steht schon in der Warteschlange.',
|
||
liste_leer:
|
||
'Die Warteschlange ist leer. Häng erst etwas an, '
|
||
+ 'dann gibt es ein Nächstes.',
|
||
nicht_in_der_liste:
|
||
'Dieser Eintrag steht nicht mehr in der Warteschlange – '
|
||
+ 'vielleicht hat ihn jemand anderes gerade genommen.',
|
||
zu_schnell:
|
||
'Das war viel auf einmal. Warte eine Minute – danach geht es weiter.',
|
||
nicht_dabei:
|
||
'Die Person sitzt gerade nicht im Saal. Ohne sie lässt sich '
|
||
+ 'keine Verbindung aufbauen.',
|
||
|
||
eintrag_nicht_gefunden: 'Den Eintrag gibt es nicht mehr. Lade die Seite neu.',
|
||
aufgabe_nicht_gefunden: 'Die Aufgabe gibt es nicht mehr. Lade die Seite neu.',
|
||
keine_fassung: 'Dazu gibt es noch keine gespeicherte Fassung.',
|
||
keine_daten: 'Dazu gibt es noch keine Daten.',
|
||
kein_protokoll: 'Dazu gibt es kein Protokoll.',
|
||
kein_block: 'Diesen Bereich gibt es nicht mehr. Lade die Seite neu.',
|
||
kein_hakt:
|
||
'Daraus lässt sich kein Schritt machen – dafür müsste der Punkt auf '
|
||
+ '„Da hakt es“ stehen.',
|
||
|
||
/* ---- Erst das andere zu Ende -------------------------------- */
|
||
uebergang_offen:
|
||
'Es läuft schon ein Übergang. Schließ den erst ab.',
|
||
zu_viele_offen:
|
||
'Du hast schon mehrere Meldungen offen. Warte, bis eine davon beantwortet ist.',
|
||
nur_gruppe_oder_kanal:
|
||
'Das geht nur in einer Gruppe oder einem Kanal, nicht im Zweiergespräch.',
|
||
|
||
/* ---- MATERIAL ZUM POSTEN (22.09.2026) ------------------------
|
||
Die Kennungen stammen aus workspace-material.js. Hier steht
|
||
KEINE Anzahl daneben: Der erste Entwurf sagte "Acht
|
||
Kennungen" und war beim naechsten Auftrag still falsch.
|
||
|
||
DER WICHTIGSTE SATZ IST „schon_genommen" — und er ist bewusst
|
||
KEIN Fehler. Wer ihn liest, hat nichts falsch gemacht; jemand
|
||
war ein paar Sekunden schneller. Stünde dort „Das hat nicht
|
||
geklappt", würde derselbe Mensch es dreimal versuchen und
|
||
dreimal dasselbe lesen.
|
||
|
||
„nur_team_stellt_ein" erreicht im Normalfall niemand: Der
|
||
Kasten zum Bereitstellen steht gar nicht erst da, wenn jemand
|
||
nicht darf. Der Satz sagt deshalb, was STATTDESSEN geht, und
|
||
zählt nicht auf, wer mehr darf. */
|
||
nur_team_stellt_ein:
|
||
'Hier stellt das Team die Bilder und Videos ein. Du kannst dir '
|
||
+ 'nehmen, was dasteht.',
|
||
schon_genommen:
|
||
'Da war jemand schneller – das ist schon vergeben. Such dir ein '
|
||
+ 'anderes aus, damit nichts zweimal gepostet wird.',
|
||
nicht_genommen:
|
||
'Dieses Bild gehört dir nicht. Nimm dir eines aus „Zum Mitnehmen“, '
|
||
+ 'dann kannst du es laden.',
|
||
art_nicht_erlaubt:
|
||
'Das geht hier nicht – es nimmt nur Bilder (JPG, PNG, WebP, GIF, '
|
||
+ 'AVIF) und Videos (MP4, MOV, WebM).',
|
||
datei_fehlt:
|
||
'Da war keine Datei dabei. Such erst ein Bild oder Video aus.',
|
||
datei_zu_gross:
|
||
'Die Datei ist zu groß. Mehr als 60 MB gehen nicht – ein kürzerer '
|
||
+ 'Ausschnitt oder eine kleinere Auflösung hilft.',
|
||
datei_weg:
|
||
'Die Datei liegt nicht mehr da. Sag DogFather Bescheid, dann '
|
||
+ 'stellt er sie neu ein.',
|
||
/* GEAENDERT AM 22.09.2026, WEIL DER SATZ NICHT MEHR STIMMTE.
|
||
Er lautete: „wegnehmen kann es nur, wer es hergegeben hat."
|
||
Seit die Hände und DogFather fremde Stücke bearbeiten und
|
||
entfernen dürfen, ist das schlicht falsch — und hätte jemanden
|
||
losgeschickt, den Einsteller zu suchen, obwohl neben ihm jemand
|
||
sitzt, der es in zwei Sekunden kann.
|
||
|
||
Er nennt bewusst keine Rollennamen: Wer darf, entscheidet der
|
||
Server, und diese Datei lädt jeder herunter. */
|
||
nicht_deins:
|
||
'Das darfst du hier nicht ändern. Sag kurz DogFather oder einer '
|
||
+ 'der Hände Bescheid — sie können jedes Stück bearbeiten und '
|
||
+ 'entfernen.',
|
||
|
||
/* ---- SICH BEWERBEN STATT SELBST NEHMEN (22.09.2026) ---------
|
||
Filipe: „die modis und linke hand sollen da nichts uebernehmen
|
||
koennen von aufgaben ... ich will dass die sich fuer aufgaben
|
||
bewerben koennen."
|
||
|
||
DER WICHTIGSTE SATZ IST „erst_bewerben" — und er ist keine
|
||
Absage, sondern ein Wegweiser. Wer dort „Das darfst du nicht"
|
||
läse, hielte sich für ausgeschlossen; tatsächlich gibt es einen
|
||
Weg, er führt nur über jemanden. */
|
||
erst_bewerben:
|
||
'Diese Aufgabe kannst du dir nicht selbst nehmen – aber du kannst '
|
||
+ 'dich dafür bewerben. DogFather oder die rechte Hand sagen dir '
|
||
+ 'dann Bescheid.',
|
||
du_entscheidest_selbst:
|
||
'Du entscheidest hier selbst, wer was macht – trag dich einfach ein, '
|
||
+ 'statt dich zu bewerben.',
|
||
schon_beworben:
|
||
'Du hast dich schon beworben. Sobald jemand darüber entschieden hat, '
|
||
+ 'siehst du es hier.',
|
||
schon_zugeteilt:
|
||
'Die Aufgabe hast du schon – du musst dich nicht bewerben. Nimm sie '
|
||
+ 'an oder sag ab, wenn es gerade nicht passt.',
|
||
keine_bewerbung:
|
||
'Dazu liegt gerade keine Bewerbung vor. Vielleicht hat sie jemand '
|
||
+ 'zurückgezogen – lade die Seite neu.',
|
||
nicht_an_dich_selbst:
|
||
'Dich selbst kannst du hier nicht eintragen. Bewirb dich dafür, dann '
|
||
+ 'entscheiden DogFather oder die rechte Hand.',
|
||
|
||
/* ---- Bewerbung auf eine Vorlage (23.09.2026) ----------------
|
||
Filipe: „die modis sollen bei all diesen voschlägen auch nur
|
||
bewerben können."
|
||
|
||
Beide Sätze sagen, was JETZT zu tun ist. „Geht nicht" allein
|
||
lässt jemanden vor einem Knopf stehen, der nichts tut. */
|
||
liegt_schon_bei_dir:
|
||
'Diese Aufgabe liegt schon auf deinem Brett – du musst dich nicht '
|
||
+ 'noch einmal dafür bewerben.',
|
||
vorlage_weg:
|
||
'Diese Vorlage gibt es nicht mehr. Die Bewerbung läuft ins Leere – '
|
||
+ 'lade die Seite neu, dann siehst du, was jetzt zur Wahl steht.',
|
||
person_weg:
|
||
'Dieser Zugang ist inzwischen abgeschaltet. Eine Aufgabe dorthin '
|
||
+ 'würde niemand mehr sehen.',
|
||
|
||
/* ---- Zeitraum und vergebene Stücke (22.09.2026) ------------- */
|
||
schon_im_umlauf:
|
||
'Das hat sich schon jemand genommen und postet es vielleicht '
|
||
+ 'gerade. Ändern lässt es sich deshalb nicht mehr — stell lieber '
|
||
+ 'ein neues Stück ein.',
|
||
datum_unbrauchbar:
|
||
'Mit dem Datum kann ich nichts anfangen. Nimm den Kalender im '
|
||
+ 'Feld, dann passt das Format von allein.',
|
||
fenster_verkehrt:
|
||
'Das Ende liegt vor dem Anfang. Dreh die beiden Daten um — oder '
|
||
+ 'lass eins davon leer, wenn es nur nach einer Seite begrenzt ist.',
|
||
|
||
/* ---- Dauerhafte Aufgaben (30.09.2026) ----------------------
|
||
Der Satz sagt, WARUM es nicht geht, und WER es beenden kann.
|
||
„Geht nicht" allein laesst einen an der eigenen Bedienung
|
||
zweifeln. */
|
||
dauerhafte_aufgabe:
|
||
'Das ist eine dauerhafte Aufgabe — sie wird nicht fertig, sie '
|
||
+ 'gehört dazu. Wenn sie nicht mehr gelten soll, kann DogFather '
|
||
+ 'oder die rechte Hand sie beenden.'
|
||
};
|
||
|
||
/* Sieht das wie eine Maschinenkennung aus?
|
||
Nur Kleinbuchstaben, Ziffern, Unterstriche — und kein Leerzeichen.
|
||
Ein Satz aus dem Server hat immer beides nicht. */
|
||
function istKennung(t) {
|
||
return typeof t === 'string' && t.length > 0 && /^[a-z0-9_]+$/.test(t);
|
||
}
|
||
|
||
/** Aus dem, was der Server schickt, einen Satz machen.
|
||
*
|
||
* @param {string|undefined} fehler was in `{ fehler: … }` stand
|
||
* @param {string} [ersatz] Satz für den Fall, dass nichts
|
||
* passt. Er soll zur Stelle
|
||
* passen („Anlegen hat nicht
|
||
* geklappt."), nicht allgemein
|
||
* sein.
|
||
* @returns {string} immer ein lesbarer Satz, nie eine Kennung.
|
||
*/
|
||
window.sagWas = function (fehler, ersatz) {
|
||
var standard = ersatz || 'Das hat nicht geklappt. Versuch es noch einmal.';
|
||
if (!fehler || typeof fehler !== 'string') return standard;
|
||
if (SAETZE[fehler]) return SAETZE[fehler];
|
||
/* UNBEKANNTE KENNUNG: der Ersatzsatz, niemals die Kennung selbst.
|
||
Sie taucht dafür in der Konsole auf — damit sie jemandem
|
||
auffällt, der sie beheben kann, statt dem, der sie nicht
|
||
versteht. */
|
||
if (istKennung(fehler)) {
|
||
try { console.warn('[meldung] Kennung ohne Satz:', fehler); } catch (e) { /* egal */ }
|
||
return standard;
|
||
}
|
||
/* Ein fertiger Satz aus dem Server — unverändert durch. */
|
||
return fehler;
|
||
};
|
||
|
||
/* Für die Prüfung, damit sie gegen DIESE Tabelle vergleicht und
|
||
nicht gegen eine abgeschriebene zweite. */
|
||
window.sagWas.SAETZE = SAETZE;
|
||
})();
|
||
|
||
/* =====================================================================
|
||
WENN DIE SEITE GAR NICHT ERST LÄDT — window.ladefehler()
|
||
|
||
Filipe, 19.09.2026: „Ladezustände … Es darf keine Sackgassen geben."
|
||
|
||
---------------------------------------------------------------------
|
||
WAS GEMESSEN WURDE (20.09.2026)
|
||
|
||
Jede Seite beginnt mit demselben Block:
|
||
|
||
try {
|
||
const a = await hole('/workspace/api/ich');
|
||
...
|
||
} catch { return; }
|
||
|
||
Das `catch { return; }` steht auf 13 von 21 Seiten. Fällt das Netz
|
||
aus -- Aufzug, U-Bahn, ein Funkloch --, wirft `fetch`, der Block
|
||
bricht ab, und die Seite bleibt stehen. Für immer.
|
||
|
||
Dabei steht auf ihr meistens schon etwas: „Übersicht wird geladen …",
|
||
„Bibliothek wird geladen …", `aria-busy="true"`. Dieser Satz wird nie
|
||
ersetzt. Gemessen: **0 von 32** Stellen setzen `aria-busy` im
|
||
Fehlerfall zurück.
|
||
|
||
Im Code steht an einer einzigen Stelle (`start.js`) der richtige
|
||
Satz dazu: „Ein Platzhalter, der nie ersetzt wird, ist eine Lüge mit
|
||
Fortschrittsanzeige." Genau das ist es -- und es galt überall außer
|
||
dort.
|
||
|
||
---------------------------------------------------------------------
|
||
UND ES GAB KEINEN WEG ZURÜCK
|
||
|
||
Gesucht über alle 21 Seiten: **kein einziger** „Nochmal versuchen".
|
||
Wer einen Ladefehler hatte, konnte nur F5 drücken -- und auf den 13
|
||
stummen Seiten wusste er nicht einmal, dass es etwas zu wiederholen
|
||
gäbe.
|
||
|
||
---------------------------------------------------------------------
|
||
WAS DIESE FUNKTION TUT
|
||
|
||
Sie sucht alles, was gerade „lädt" (`[aria-busy="true"]`), und
|
||
ersetzt es durch drei Dinge: was los ist, was das für den Nutzer
|
||
bedeutet, und einen Knopf, der es noch einmal versucht.
|
||
|
||
Findet sie keinen solchen Kasten, baut sie einen -- eine Seite ohne
|
||
Ladeanzeige (chat, steckbrief) soll nicht leer bleiben.
|
||
|
||
AUFRUF:
|
||
} catch { ladefehler(); return; }
|
||
} catch { ladefehler({ nochmal: laden }); return; }
|
||
===================================================================== */
|
||
(function () {
|
||
'use strict';
|
||
|
||
window.ladefehler = function ladefehler(o) {
|
||
o = o || {};
|
||
const satz = o.satz
|
||
|| 'Die Seite konnte gerade nicht geladen werden.';
|
||
const grund = o.grund
|
||
|| 'Meistens liegt es am Netz – im Aufzug, in der Bahn, im Funkloch.';
|
||
|
||
/* ALLES, WAS GERADE „LAEDT". Abgeleitet, nicht aufgezaehlt: Wer
|
||
morgen einen Ladeplatzhalter einbaut, ist damit automatisch
|
||
abgedeckt. */
|
||
let kaesten = [...document.querySelectorAll('[aria-busy="true"]')];
|
||
if (!kaesten.length) {
|
||
/* Keine Ladeanzeige auf dieser Seite -- dann eine bauen, statt
|
||
den Menschen vor eine leere Seite zu setzen. */
|
||
const ziel = document.querySelector('main') || document.body;
|
||
const kasten = document.createElement('div');
|
||
kasten.className = 'ladefehler';
|
||
ziel.prepend(kasten);
|
||
kaesten = [kasten];
|
||
}
|
||
|
||
for (const k of kaesten) {
|
||
/* AUS „BESCHAEFTIGT" WIRD „FERTIG". Sonst meldet ein
|
||
Vorleseprogramm die Flaeche fuer immer als ladend -- und das
|
||
ist schlimmer als gar keine Ansage. */
|
||
k.setAttribute('aria-busy', 'false');
|
||
k.textContent = '';
|
||
k.classList.add('ladefehler');
|
||
|
||
const eins = document.createElement('p');
|
||
eins.className = 'ladefehler__satz';
|
||
eins.textContent = satz;
|
||
k.append(eins);
|
||
|
||
const zwei = document.createElement('p');
|
||
zwei.className = 'ladefehler__grund';
|
||
zwei.textContent = grund;
|
||
k.append(zwei);
|
||
|
||
const knopf = document.createElement('button');
|
||
knopf.type = 'button';
|
||
knopf.className = 'knopf knopf--klein ladefehler__knopf';
|
||
knopf.textContent = 'Nochmal versuchen';
|
||
knopf.addEventListener('click', () => {
|
||
knopf.disabled = true;
|
||
knopf.textContent = 'wird geladen …';
|
||
/* DEN KASTEN SELBST WEGRAEUMEN (20.09.2026).
|
||
Gemessen: Auf `start.html` blieb er nach einem erfolgreichen
|
||
Wiederholen stehen -- `laden()` baut nur seine eigenen
|
||
Bereiche neu auf und weiss von ihm nichts. Ein Fehlerkasten
|
||
ueber einer Seite, die gerade wieder funktioniert, ist
|
||
schlimmer als gar keiner: Er behauptet einen Zustand, der
|
||
vorbei ist. */
|
||
const weg = () => {
|
||
for (const alt of document.querySelectorAll('.ladefehler')) {
|
||
alt.textContent = '';
|
||
alt.classList.remove('ladefehler');
|
||
if (!alt.id && !alt.className) alt.remove();
|
||
}
|
||
};
|
||
/* Wer eine eigene Ladefunktion mitgibt, spart das Neuladen der
|
||
ganzen Seite -- das ist schneller und behaelt die Stelle, an
|
||
der man war. Ohne sie bleibt der ehrliche Notnagel. */
|
||
if (typeof o.nochmal === 'function') {
|
||
Promise.resolve().then(o.nochmal).then(weg).catch(() => location.reload());
|
||
} else {
|
||
location.reload();
|
||
}
|
||
});
|
||
k.append(knopf);
|
||
/* Nur EIN Kasten bekommt den Knopf -- fuenf Knoepfe
|
||
nebeneinander, die dasselbe tun, sind Rauschen. */
|
||
break;
|
||
}
|
||
|
||
/* Die uebrigen Ladeanzeigen aufraeumen: Sie duerfen nicht weiter
|
||
„wird geladen …" behaupten, waehrend daneben der Fehler steht.
|
||
Genau diese Doppelung hat die Pruefung an sieben Stellen
|
||
gefunden. */
|
||
for (const k of kaesten.slice(1)) {
|
||
k.setAttribute('aria-busy', 'false');
|
||
k.textContent = '';
|
||
}
|
||
|
||
/* UND DIE PLATZHALTER OHNE `aria-busy`. Nicht jede Ladeanzeige
|
||
traegt das Merkmal -- auf `start.html` steht im Ring schlicht
|
||
„wird geladen" in einem <span>. Gesucht wird deshalb nach dem,
|
||
was der Mensch LIEST, nicht nach dem, was im Quelltext
|
||
markiert ist. */
|
||
for (const e of document.querySelectorAll('span, p, div')) {
|
||
if (e.children.length) continue;
|
||
if (!/^\s*(wird geladen|einen Moment)/i.test(e.textContent || '')) continue;
|
||
if (e.closest('.ladefehler')) continue;
|
||
e.textContent = '–';
|
||
}
|
||
};
|
||
})();
|
||
|
||
/* =====================================================================
|
||
WEICHES ROLLEN — ABER NICHT GEGEN DEN WILLEN DES NUTZERS
|
||
|
||
`scrollIntoView({ behavior: 'smooth' })` rollt IMMER weich. Die
|
||
Einstellung „Animationen reduzieren" im Betriebssystem schaltet das
|
||
NICHT ab -- der Browser tut sie hier schlicht nicht.
|
||
|
||
Wer das eingestellt hat, hat es meist wegen Schwindel oder Migräne
|
||
getan. Eine Seite, die ihm trotzdem unter den Augen wegrollt, ist
|
||
für ihn nicht unschön, sondern unbenutzbar.
|
||
|
||
Gemessen am 20.09.2026: 15 Stellen rollen weich, ZWEI davon fragen
|
||
vorher (`checkliste.js`, `kopf.js`). Das Haus kannte die richtige
|
||
Form also -- sie stand nur an dreizehn Stellen nicht.
|
||
|
||
Deshalb hier EINMAL, statt dreizehnmal in Kopie.
|
||
===================================================================== */
|
||
window.sanft = function sanft() {
|
||
try {
|
||
return window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
||
? 'auto' : 'smooth';
|
||
} catch {
|
||
/* Kein matchMedia (sehr alt) -- dann lieber ohne Bewegung. Wer
|
||
nicht fragen kann, soll nicht annehmen. */
|
||
return 'auto';
|
||
}
|
||
};
|