Personen: jede Rolle einzeln auf- und zuklappbar
Wunsch Filipe: "ich will ueberall die liste zu machen koennen und nur
aufmachen wenn ich sie sehen will."
Jede der vier Rollen klappt jetzt einzeln auf und zu. Das ERSETZT den
Sammelknopf von vorhin ("5 weitere zeigen") -- zwei Mechanismen
nebeneinander, die dasselbe verstecken, waeren eine Einladung zum
Missverstaendnis. Der Knopf oben rechts macht jetzt etwas anderes: alles
auf einmal ("Alle aufklappen" / "Alle zuklappen"), damit man bei vier
Rollen nicht viermal klicken muss.
Der entscheidende Unterschied zum Ausblenden: Die UEBERSCHRIFT mit der
Anzahl bleibt IMMER stehen, auch zugeklappt. Man sieht jederzeit, DASS es
einen Manager gibt -- nur nicht, welchen. Wer eine ganze Rolle spurlos
verschwinden laesst, haelt sie irgendwann fuer leer.
Und zugeklappt zaehlt genau eine Frage: Steckt da etwas Gesperrtes drin,
das ich sehen muesste? Deshalb steht am Manager auch zugeklappt
"1 gesperrt", in Warnfarbe.
Die Ueberschrift IST der Knopf, als echtes <button> -- ein eigener
kleiner Schalter daneben waere ein zweites Ziel fuer dieselbe Absicht,
und ein kleineres. Als Knopf-Element statt div mit Klick-Zuhoerer machen
Tastatur und Vorleseprogramme es ohne Zutun richtig.
Der Zustand wird JE ROLLE gemerkt, nicht als "alles auf/zu": Wer die
Creator zuklappt und die Scouts offen laesst, findet das nach dem Laden
genau so wieder.
30 Pruefungen. Darunter weiterhin der wichtigste: Zuklappen ist eine
ANSICHT, kein Recht -- Tili kann sich anmelden und normal arbeiten,
waehrend ihre Rolle zugeklappt ist, und der Server liefert unveraendert
alle sieben Personen.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 324 KiB After Width: | Height: | Size: 326 KiB |
@@ -1,10 +1,16 @@
|
||||
/* ===================================================================
|
||||
Pruefung: In der Personenliste steht standardmaessig nur DogFather,
|
||||
alle anderen kommen auf Knopfdruck dazu.
|
||||
Pruefung: Die Personenliste ist je Rolle auf- und zuklappbar.
|
||||
|
||||
Der wichtigste Punkt ist der letzte: Verstecken ist eine ANSICHT, kein
|
||||
Recht. Wer eingeklappt ist, hat unveraendert Zugang -- der Server darf
|
||||
davon gar nichts mitbekommen.
|
||||
Zwei Dinge sind dabei wichtiger als alles andere:
|
||||
|
||||
1. Die UEBERSCHRIFT mit der Anzahl bleibt immer stehen, auch
|
||||
zugeklappt. Das ist der Unterschied zum Ausblenden: Man sieht
|
||||
jederzeit, DASS es einen Manager gibt -- nur nicht, welchen. Wer
|
||||
eine ganze Rolle spurlos verschwinden laesst, haelt sie irgendwann
|
||||
fuer leer.
|
||||
|
||||
2. Zuklappen ist eine ANSICHT, kein Recht. Wer zugeklappt ist, hat
|
||||
unveraendert Zugang -- der Server bekommt davon gar nichts mit.
|
||||
=================================================================== */
|
||||
import { mkdtempSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
@@ -24,7 +30,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(
|
||||
await import("./index.js");
|
||||
await new Promise((r) => setTimeout(r, 700));
|
||||
const BASIS = "http://127.0.0.1:4187";
|
||||
setTimeout(() => { console.log("ABBRUCH"); process.exit(1); }, 180_000).unref?.();
|
||||
setTimeout(() => { console.log("ABBRUCH"); process.exit(1); }, 200_000).unref?.();
|
||||
|
||||
let fehler = 0;
|
||||
const ok = (b, t) => { console.log((b ? " ok " : " FEHL ") + t); if (!b) fehler++; };
|
||||
@@ -42,7 +48,6 @@ function anlegen(name, rolle, code, aktiv = 1) {
|
||||
const hash = scryptSync(code, salt, 64, { N: 32768, r: 8, p: 1, maxmem: 96 * 1024 * 1024 }).toString("hex");
|
||||
d.prepare("INSERT INTO personen (name, rolle, code_hash, code_salt, code_n, aktiv, erstellt) VALUES (?,?,?,?,?,?,?)")
|
||||
.run(name, rolle, hash, salt, 32768, aktiv, jetzt);
|
||||
return d.prepare("SELECT last_insert_rowid() AS id").get().id;
|
||||
}
|
||||
/* Genau die Aufstellung aus dem Bild vom 31.08.2026. */
|
||||
anlegen("Dogfather", "admin", "CODE-DOGI-0001");
|
||||
@@ -72,115 +77,136 @@ async function seiteFuer(kontext) {
|
||||
|
||||
const lesen = (seite) => seite.evaluate(() => ({
|
||||
namen: [...document.querySelectorAll(".person__name")].map((n) => n.textContent.replace(" (du)", "")),
|
||||
/* Die Abschnitte in der Reihenfolge, in der sie tatsächlich stehen --
|
||||
nicht in der, in der sie gemeint waren. */
|
||||
abschnitte: [...document.querySelectorAll(".gruppe")].map((g) => ({
|
||||
name: g.querySelector(".gruppe__name")?.textContent,
|
||||
zahl: g.querySelector(".gruppe__zahl")?.textContent,
|
||||
unter: g.querySelector(".gruppe__unter")?.textContent,
|
||||
auf: g.querySelector(".gruppe__kopf")?.getAttribute("aria-expanded"),
|
||||
knopf: g.querySelector(".gruppe__kopf")?.tagName,
|
||||
personen: [...g.querySelectorAll(".person__name")].map((n) => n.textContent.replace(" (du)", "")),
|
||||
})),
|
||||
knopfDa: !document.getElementById("rest-schalter")?.hidden,
|
||||
knopfText: document.getElementById("rest-schalter-text")?.textContent,
|
||||
auf: document.getElementById("rest-schalter")?.getAttribute("aria-expanded"),
|
||||
ueber: document.documentElement.scrollWidth - document.documentElement.clientWidth,
|
||||
}));
|
||||
|
||||
const klick = (seite, rolle) =>
|
||||
seite.locator(".gruppe__kopf", { hasText: new RegExp("^" + rolle) }).first().click();
|
||||
|
||||
const kontext = await browser.newContext({ viewport: { width: 1440, height: 1100 } });
|
||||
const konsole = [];
|
||||
const seite = await seiteFuer(kontext);
|
||||
seite.on("console", (m) => { if (m.type() === "error") konsole.push(m.text()); });
|
||||
seite.on("pageerror", (e) => konsole.push("pageerror: " + e.message));
|
||||
|
||||
console.log("\n1) Standardmäßig nur DogFather");
|
||||
console.log("\n1) Alle vier Überschriften stehen da – offen ist nur DogFather");
|
||||
{
|
||||
const r = await lesen(seite);
|
||||
console.log(" sichtbar:", r.namen.join(", "));
|
||||
console.log(" Knopf: ", r.knopfText);
|
||||
ok(r.namen.length === 2, `zwei Personen sichtbar (${r.namen.length})`);
|
||||
ok(r.abschnitte.length === 1 && r.abschnitte[0].name === "DogFather",
|
||||
`zugeklappt steht nur der DogFather-Abschnitt da (${r.abschnitte.map((a) => a.name).join(", ") || "keiner"})`);
|
||||
console.log(" ", r.abschnitte.map((a) => `${a.name}(${a.zahl},${a.auf === "true" ? "auf" : "zu"})`).join(" · "));
|
||||
|
||||
ok(r.abschnitte.length === 4, `vier Überschriften, auch zugeklappt (${r.abschnitte.length})`);
|
||||
ok(r.abschnitte.map((a) => a.name).join(",") === "DogFather,Manager,Scout,Creator",
|
||||
`Reihenfolge wie auf der Zugangsseite (${r.abschnitte.map((a) => a.name).join(", ")})`);
|
||||
ok(r.abschnitte.map((a) => a.zahl).join(",") === "2,1,2,2",
|
||||
`mit den Anzahlen (${r.abschnitte.map((a) => a.zahl).join(", ")})`);
|
||||
|
||||
ok(r.namen.length === 2, `aber nur zwei Personen sichtbar (${r.namen.length})`);
|
||||
ok(r.namen.includes("Dogfather") && r.namen.includes("VanVan"),
|
||||
`Dogfather und VanVan (${r.namen.join(", ")})`);
|
||||
ok(!r.namen.includes("Tili"), "kein Creator");
|
||||
ok(!r.namen.includes("Patrick"), "kein Scout");
|
||||
ok(r.knopfDa, "der Knopf ist da");
|
||||
/* Die ZAHL gehoert auf den Knopf -- "Alle zeigen" sagt nicht, wie
|
||||
viele man gerade nicht sieht. */
|
||||
ok(/5 weitere zeigen/.test(r.knopfText || ""), `mit der Anzahl (${r.knopfText})`);
|
||||
ok(/1 gesperrt/.test(r.knopfText || ""), "und dem Hinweis auf die gesperrte Person");
|
||||
ok(r.auf === "false", `aria-expanded=false (${r.auf})`);
|
||||
ok(r.abschnitte[0].auf === "true", `DogFather ist offen (${r.abschnitte[0].auf})`);
|
||||
ok(r.abschnitte.slice(1).every((a) => a.auf === "false"), "die anderen drei sind zu");
|
||||
|
||||
/* Als echtes <button>, damit Tastatur und Vorleseprogramme es ohne
|
||||
Zutun richtig machen. */
|
||||
ok(r.abschnitte.every((a) => a.knopf === "BUTTON"), "jede Überschrift ist ein echter Knopf");
|
||||
|
||||
/* Zugeklappt muss trotzdem auffallen, wenn dort etwas Gesperrtes liegt. */
|
||||
const manager = r.abschnitte.find((a) => a.name === "Manager");
|
||||
ok(/1 gesperrt/.test(manager?.unter || ""),
|
||||
`bei Manager steht die gesperrte Person dran ("${manager?.unter}")`);
|
||||
|
||||
ok(r.knopfDa && /Alle aufklappen/.test(r.knopfText || ""),
|
||||
`der Sammelknopf bietet alles an (${r.knopfText})`);
|
||||
}
|
||||
|
||||
console.log("\n2) Auf Knopfdruck kommen alle dazu");
|
||||
console.log("\n2) Jede Rolle einzeln auf und zu");
|
||||
{
|
||||
await klick(seite, "Scout");
|
||||
await seite.waitForTimeout(250);
|
||||
let r = await lesen(seite);
|
||||
console.log(" ", r.abschnitte.map((a) => `${a.name}=${a.auf === "true" ? "auf" : "zu"}`).join(" · "));
|
||||
ok(r.namen.includes("Patrick") && r.namen.includes("BananaStift"), "die Scouts stehen da");
|
||||
ok(!r.namen.includes("Tili"), "die Creator weiterhin nicht");
|
||||
ok(r.abschnitte.find((a) => a.name === "Creator").auf === "false", "Creator bleibt unberührt zu");
|
||||
|
||||
await klick(seite, "Scout");
|
||||
await seite.waitForTimeout(250);
|
||||
r = await lesen(seite);
|
||||
ok(!r.namen.includes("Patrick"), "dieselbe Überschrift klappt wieder zu");
|
||||
|
||||
/* "Überall" heisst überall -- auch DogFather. */
|
||||
await klick(seite, "DogFather");
|
||||
await seite.waitForTimeout(250);
|
||||
r = await lesen(seite);
|
||||
ok(r.namen.length === 0, `alles zu, keine Person sichtbar (${r.namen.length})`);
|
||||
ok(r.abschnitte.length === 4, "die vier Überschriften stehen trotzdem noch da");
|
||||
}
|
||||
|
||||
console.log("\n3) Der Sammelknopf klappt alles auf und wieder zu");
|
||||
{
|
||||
await seite.click("#rest-schalter");
|
||||
await seite.waitForTimeout(250);
|
||||
const r = await lesen(seite);
|
||||
console.log(" sichtbar:", r.namen.join(", "));
|
||||
ok(r.namen.length === 7, `alle sieben (${r.namen.length})`);
|
||||
ok(r.namen.includes("BanaStift"), "auch die gesperrte Person");
|
||||
ok(/Nur DogFather zeigen/.test(r.knopfText || ""), `Knopf bietet das Zuklappen an (${r.knopfText})`);
|
||||
ok(r.auf === "true", `aria-expanded=true (${r.auf})`);
|
||||
ok(/Alle zuklappen/.test(r.knopfText || ""), `Knopf bietet jetzt das Zuklappen an (${r.knopfText})`);
|
||||
ok(r.ueber <= 0, `nichts steht über (${r.ueber}px)`);
|
||||
|
||||
console.log(" Abschnitte:", r.abschnitte.map((a) => `${a.name}(${a.zahl})`).join(" → "));
|
||||
ok(r.abschnitte.length === 4, `vier Abschnitte (${r.abschnitte.length})`);
|
||||
ok(r.abschnitte.map((a) => a.name).join(",") === "DogFather,Manager,Scout,Creator",
|
||||
`Reihenfolge wie auf der Zugangsseite (${r.abschnitte.map((a) => a.name).join(", ")})`);
|
||||
ok(r.abschnitte.map((a) => a.zahl).join(",") === "2,1,2,2",
|
||||
`Anzahl je Rolle (${r.abschnitte.map((a) => a.zahl).join(", ")})`);
|
||||
|
||||
/* Der eigentliche Fehler von vorher: Der GESPERRTE Manager stand ganz
|
||||
unten unter den Creators, weil "aktiv" vor der Rolle sortierte. */
|
||||
/* Der Fehler von vorher: Der GESPERRTE Manager stand ganz unten unter
|
||||
den Creators, weil "aktiv" vor der Rolle sortierte. */
|
||||
const manager = r.abschnitte.find((a) => a.name === "Manager");
|
||||
ok(manager?.personen.includes("BanaStift"),
|
||||
`der gesperrte Manager steht bei den Managern (${manager?.personen.join(", ")})`);
|
||||
const creator = r.abschnitte.find((a) => a.name === "Creator");
|
||||
ok(!creator?.personen.includes("BanaStift"), "und nicht mehr bei den Creators");
|
||||
ok(creator?.personen.join(",") === "SpongBobSchwammKopf,Tili",
|
||||
`innerhalb der Rolle nach Namen (${creator?.personen.join(", ")})`);
|
||||
|
||||
/* Dieselben Zusatztexte wie auf der Zugangsseite -- wer sich eben
|
||||
angemeldet hat, findet hier dieselbe Sprache wieder. */
|
||||
ok(r.abschnitte[2]?.unter === "Eigene Pipeline & Kontakte",
|
||||
`Zusatztext wörtlich von der Zugangsseite ("${r.abschnitte[2]?.unter}")`);
|
||||
}
|
||||
|
||||
console.log("\n3) Der Zustand überlebt das Neuladen");
|
||||
console.log("\n4) Der Zustand überlebt das Neuladen – je Rolle einzeln");
|
||||
{
|
||||
/* Ein Knopf, den man nach jedem Laden neu druecken muss, ist keine
|
||||
Einstellung, sondern eine Zumutung. */
|
||||
await seite.reload({ waitUntil: "networkidle" });
|
||||
await seite.waitForTimeout(600);
|
||||
const r = await lesen(seite);
|
||||
ok(r.namen.length === 7, `nach dem Neuladen weiterhin alle (${r.namen.length})`);
|
||||
|
||||
await seite.click("#rest-schalter");
|
||||
/* Nur die Creator zuklappen. Es muss die EINZELNE Einstellung
|
||||
überleben, nicht bloss "alles auf" oder "alles zu". */
|
||||
await klick(seite, "Creator");
|
||||
await seite.waitForTimeout(250);
|
||||
await seite.reload({ waitUntil: "networkidle" });
|
||||
await seite.waitForTimeout(600);
|
||||
const z = await lesen(seite);
|
||||
ok(z.namen.length === 2, `und zugeklappt bleibt zugeklappt (${z.namen.length})`);
|
||||
await seite.waitForTimeout(700);
|
||||
const r = await lesen(seite);
|
||||
console.log(" ", r.abschnitte.map((a) => `${a.name}=${a.auf === "true" ? "auf" : "zu"}`).join(" · "));
|
||||
ok(!r.namen.includes("Tili"), "die zugeklappten Creator bleiben zu");
|
||||
ok(r.namen.includes("Patrick"), "die offenen Scouts bleiben offen");
|
||||
ok(r.abschnitte.find((a) => a.name === "Creator").auf === "false",
|
||||
"und der Zustand steht auch im aria-expanded");
|
||||
}
|
||||
|
||||
console.log("\n4) Verstecken ist eine Ansicht, kein Recht");
|
||||
console.log("\n5) Zuklappen ist eine Ansicht, kein Recht");
|
||||
{
|
||||
/* Der springende Punkt. Wer eingeklappt ist, muss unveraendert
|
||||
arbeiten koennen -- sonst waere aus einer Anzeigeeinstellung
|
||||
versehentlich eine Sperre geworden. */
|
||||
/* Der springende Punkt. Wer zugeklappt ist, muss unverändert arbeiten
|
||||
können -- sonst wäre aus einer Anzeigeeinstellung versehentlich eine
|
||||
Sperre geworden. */
|
||||
const a = await fetch(BASIS + "/workspace/api/anmelden", {
|
||||
method: "POST", headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ rolle: "creator", code: "CODE-TILI-0001" }), redirect: "manual" });
|
||||
ok(a.ok, `Tili kann sich anmelden, obwohl sie ausgeblendet ist (${a.status})`);
|
||||
ok(a.ok, `Tili kann sich anmelden, obwohl zugeklappt (${a.status})`);
|
||||
|
||||
const keks = (a.headers.getSetCookie?.() || []).map((c) => c.split(";")[0]).join("; ");
|
||||
const ich = await (await fetch(BASIS + "/workspace/api/ich", { headers: { cookie: keks } })).json();
|
||||
ok(ich.name === "Tili", `und ist ganz normal angemeldet (${ich.name})`);
|
||||
|
||||
/* Und der Server liefert weiterhin ALLE -- das Kuerzen passiert nur
|
||||
in der Anzeige. Waere es serverseitig, wuerde die naechste
|
||||
Auswertung stillschweigend Personen uebersehen. */
|
||||
/* Und der Server liefert weiterhin ALLE -- das Kürzen passiert nur in
|
||||
der Anzeige. Wäre es serverseitig, würde die nächste Auswertung
|
||||
stillschweigend Personen übersehen. */
|
||||
const dogiA = await fetch(BASIS + "/workspace/api/anmelden", {
|
||||
method: "POST", headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ rolle: "admin", code: "CODE-DOGI-0001" }), redirect: "manual" });
|
||||
@@ -196,13 +222,17 @@ await seite.waitForTimeout(300);
|
||||
await seite.screenshot({ path: "pruef-personen.png", fullPage: true });
|
||||
await kontext.close();
|
||||
|
||||
console.log("\n5) Auf dem Handy genauso");
|
||||
console.log("\n6) Auf dem Handy genauso");
|
||||
{
|
||||
const k = await browser.newContext({ viewport: { width: 390, height: 844 } });
|
||||
const s = await seiteFuer(k);
|
||||
const r = await lesen(s);
|
||||
ok(r.knopfDa, "der Knopf ist auch dort da");
|
||||
ok(r.ueber <= 0, `nichts steht über (${r.ueber}px)`);
|
||||
ok(r.abschnitte.length === 4, `vier Überschriften (${r.abschnitte.length})`);
|
||||
await klick(s, "Creator");
|
||||
await s.waitForTimeout(250);
|
||||
const n = await lesen(s);
|
||||
ok(n.namen.includes("Tili"), "auch dort lässt sich eine Rolle aufklappen");
|
||||
ok(n.ueber <= 0, `nichts steht über (${n.ueber}px)`);
|
||||
await k.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -194,3 +194,30 @@
|
||||
background: rgba(255, 154, 162, .1);
|
||||
}
|
||||
.schritt[data-gefahr="ja"]:focus-visible { outline-color: var(--warn); }
|
||||
|
||||
/* Die Rollen-Überschrift ist der Klappknopf. Sie sieht aus wie eine
|
||||
Überschrift und verhält sich wie ein Knopf – deshalb hier nur der
|
||||
Knopf-Rücksetzer und ein Zeiger, kein eigener Entwurf. */
|
||||
.gruppe__kopf--klappbar {
|
||||
width: 100%; text-align: left; cursor: pointer;
|
||||
font: inherit; color: inherit;
|
||||
background: none; border: 0;
|
||||
border-bottom: 1px solid transparent;
|
||||
border-image: linear-gradient(90deg, var(--rand-hell), transparent 70%) 1;
|
||||
transition: opacity var(--tempo);
|
||||
}
|
||||
.gruppe__kopf--klappbar:hover { opacity: .82; }
|
||||
.gruppe__kopf--klappbar:focus-visible {
|
||||
outline: 2px solid var(--akzent); outline-offset: 3px; border-radius: 4px;
|
||||
}
|
||||
/* Der Pfeil ganz nach rechts – dort sucht ihn die Hand. */
|
||||
.gruppe__kopf--klappbar .klapp-pfeil { margin-left: auto; color: var(--text-still); }
|
||||
.gruppe__kopf--klappbar:hover .klapp-pfeil { color: var(--akzent); }
|
||||
|
||||
/* Zugeklappt zählt nur eines: Steckt da etwas Gesperrtes drin, das man
|
||||
sehen müsste? Dann fällt der Zusatztext auf. */
|
||||
.gruppe__unter[data-warn="ja"] { color: var(--warn); }
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.gruppe__kopf--klappbar { transition: none; }
|
||||
}
|
||||
|
||||
@@ -319,10 +319,33 @@
|
||||
} catch { /* umgeleitet */ }
|
||||
}
|
||||
|
||||
const SPEICHER = 'dfw_personen_alle';
|
||||
/* ---------- Was aufgeklappt ist ------------------------------------------
|
||||
|
||||
Wunsch Filipe, 31.08.2026: "ich will überall die liste zu machen
|
||||
können und nur aufmachen wenn ich sie sehen will."
|
||||
|
||||
Also klappt JEDE Rolle einzeln auf und zu. Das ersetzt den vorherigen
|
||||
Sammelknopf ("5 weitere zeigen") -- zwei Mechanismen nebeneinander,
|
||||
die dasselbe verstecken, wären eine Einladung zum Missverständnis.
|
||||
|
||||
Die Überschrift mit der ANZAHL bleibt immer stehen, auch zugeklappt.
|
||||
Das ist der entscheidende Unterschied zum Ausblenden: Man sieht
|
||||
jederzeit, dass es vier Manager gibt -- man sieht nur nicht, welche.
|
||||
Wer eine ganze Rolle spurlos verschwinden lässt, hält sie irgendwann
|
||||
für leer.
|
||||
|
||||
Voreinstellung: DogFather offen, alles andere zu. */
|
||||
const SPEICHER = 'dfw_personen_offen';
|
||||
let alle = [];
|
||||
let alleZeigen = false;
|
||||
try { alleZeigen = localStorage.getItem(SPEICHER) === 'ja'; } catch { /* egal */ }
|
||||
let offen = new Set(['admin']);
|
||||
try {
|
||||
const g = JSON.parse(localStorage.getItem(SPEICHER) || 'null');
|
||||
if (Array.isArray(g)) offen = new Set(g);
|
||||
} catch { /* kaputt gespeichert = Voreinstellung */ }
|
||||
|
||||
function offenMerken() {
|
||||
try { localStorage.setItem(SPEICHER, JSON.stringify([...offen])); } catch { /* egal */ }
|
||||
}
|
||||
|
||||
/* Jede Rolle bekommt einen eigenen Abschnitt, in der Reihenfolge der
|
||||
ZUGANGSSEITE: DogFather, Manager, Scout, Creator. Die Zusatztexte
|
||||
@@ -342,54 +365,78 @@
|
||||
const ziel = $('liste');
|
||||
ziel.textContent = '';
|
||||
|
||||
const oben = alle.filter((p) => p.rolle === 'admin');
|
||||
const rest = alle.filter((p) => p.rolle !== 'admin');
|
||||
const sichtbar = alleZeigen ? alle : oben;
|
||||
|
||||
for (const abschnitt of ROLLEN_ABSCHNITTE) {
|
||||
const drin = sichtbar.filter((p) => p.rolle === abschnitt.rolle);
|
||||
if (!drin.length) continue;
|
||||
const vorhanden = ROLLEN_ABSCHNITTE
|
||||
.map((a) => ({ ...a, drin: alle.filter((p) => p.rolle === a.rolle) }))
|
||||
.filter((a) => a.drin.length);
|
||||
|
||||
for (const abschnitt of vorhanden) {
|
||||
const auf = offen.has(abschnitt.rolle);
|
||||
const block = document.createElement('section');
|
||||
block.className = 'gruppe';
|
||||
const kopf = document.createElement('div');
|
||||
kopf.className = 'gruppe__kopf';
|
||||
|
||||
/* Die Überschrift IST der Knopf. Ein eigener kleiner Schalter
|
||||
daneben wäre ein zweites Ziel für dieselbe Absicht -- und ein
|
||||
kleineres. Als <button> statt <div> mit Klick-Zuhörer, damit
|
||||
Tastatur und Vorleseprogramme es ohne Zutun richtig machen. */
|
||||
const kopf = document.createElement('button');
|
||||
kopf.type = 'button';
|
||||
kopf.className = 'gruppe__kopf gruppe__kopf--klappbar';
|
||||
kopf.setAttribute('aria-expanded', auf ? 'true' : 'false');
|
||||
|
||||
const h = document.createElement('h2');
|
||||
h.className = 'gruppe__name';
|
||||
h.textContent = abschnitt.name;
|
||||
|
||||
const zahl = document.createElement('span');
|
||||
zahl.className = 'gruppe__zahl';
|
||||
zahl.textContent = String(drin.length);
|
||||
zahl.textContent = String(abschnitt.drin.length);
|
||||
|
||||
const unter = document.createElement('span');
|
||||
unter.className = 'gruppe__unter';
|
||||
unter.textContent = abschnitt.unter;
|
||||
kopf.append(h, zahl, unter);
|
||||
/* Zugeklappt zählt der Zusatztext weniger als die Frage "ist da
|
||||
etwas Gesperrtes drin, das ich sehen müsste?". */
|
||||
const gesperrt = abschnitt.drin.filter((p) => !p.aktiv).length;
|
||||
unter.textContent = gesperrt
|
||||
? `${abschnitt.unter} · ${gesperrt} gesperrt`
|
||||
: abschnitt.unter;
|
||||
if (gesperrt) unter.dataset.warn = 'ja';
|
||||
|
||||
const pfeil = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
pfeil.setAttribute('viewBox', '0 0 24 24');
|
||||
pfeil.setAttribute('aria-hidden', 'true');
|
||||
pfeil.setAttribute('class', 'klapp-pfeil');
|
||||
const pfad = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
pfad.setAttribute('d', 'm6 9.5 6 6 6-6');
|
||||
pfeil.append(pfad);
|
||||
|
||||
kopf.append(h, zahl, unter, pfeil);
|
||||
kopf.addEventListener('click', () => {
|
||||
if (offen.has(abschnitt.rolle)) offen.delete(abschnitt.rolle);
|
||||
else offen.add(abschnitt.rolle);
|
||||
offenMerken();
|
||||
listeZeigen();
|
||||
});
|
||||
block.append(kopf);
|
||||
|
||||
for (const p of drin) block.append(zeile(p));
|
||||
if (auf) for (const p of abschnitt.drin) block.append(zeile(p));
|
||||
ziel.append(block);
|
||||
}
|
||||
|
||||
/* Ein Knopf für alle auf einmal -- bei vier Rollen viermal klicken zu
|
||||
müssen, nur um einmal alles zu sehen, wäre unnötige Arbeit. */
|
||||
const schalter = $('rest-schalter');
|
||||
schalter.hidden = rest.length === 0;
|
||||
if (!rest.length) return;
|
||||
|
||||
/* Die Zahl gehört auf den Knopf, nicht nur der Zustand. "Alle
|
||||
zeigen" sagt nicht, wie viele man gerade nicht sieht. */
|
||||
const gesperrt = rest.filter((p) => !p.aktiv).length;
|
||||
$('rest-schalter-text').textContent = alleZeigen
|
||||
? 'Nur DogFather zeigen'
|
||||
: `${rest.length} weitere zeigen`
|
||||
+ (gesperrt ? ` · ${gesperrt} gesperrt` : '');
|
||||
schalter.setAttribute('aria-expanded', alleZeigen ? 'true' : 'false');
|
||||
schalter.hidden = vorhanden.length < 2;
|
||||
const alleOffen = vorhanden.every((a) => offen.has(a.rolle));
|
||||
$('rest-schalter-text').textContent = alleOffen ? 'Alle zuklappen' : 'Alle aufklappen';
|
||||
schalter.setAttribute('aria-expanded', alleOffen ? 'true' : 'false');
|
||||
schalter.onclick = () => {
|
||||
if (alleOffen) offen.clear();
|
||||
else for (const a of vorhanden) offen.add(a.rolle);
|
||||
offenMerken();
|
||||
listeZeigen();
|
||||
};
|
||||
}
|
||||
|
||||
$('rest-schalter').addEventListener('click', () => {
|
||||
alleZeigen = !alleZeigen;
|
||||
try { localStorage.setItem(SPEICHER, alleZeigen ? 'ja' : 'nein'); } catch { /* egal */ }
|
||||
listeZeigen();
|
||||
});
|
||||
|
||||
async function laden() {
|
||||
const ziel = $('liste');
|
||||
try {
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -134,8 +134,8 @@
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/aufgaben.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/aufgaben.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/automation.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/automation.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -127,8 +127,8 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/automation.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/automation.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/bereich.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/bereich.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -98,8 +98,8 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/bereich.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/bereich.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/calls.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/calls.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -49,9 +49,9 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/ki.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/calls.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/ki.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/calls.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/content.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/content.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -153,8 +153,8 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/content.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/content.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/dateien.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/dateien.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -88,8 +88,8 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/dateien.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/dateien.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
type="image/webp" media="(max-width: 899px)" />
|
||||
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="gate">
|
||||
@@ -143,6 +143,6 @@
|
||||
</p>
|
||||
</main>
|
||||
|
||||
<script src="assets/js/gate.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/gate.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/kalender.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/kalender.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -94,8 +94,8 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kalender.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kalender.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/personen.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/personen.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -116,8 +116,8 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/personen.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/personen.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/profil.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/profil.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -127,8 +127,8 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/profil.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/profil.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/report.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/report.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -86,9 +86,9 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/ki.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/report.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/ki.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/report.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/scouting.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/scouting.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -124,8 +124,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/scouting.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/scouting.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -68,8 +68,8 @@
|
||||
</p>
|
||||
</main>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/start.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/start.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/startcheck.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/startcheck.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -65,9 +65,9 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/ki.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/startcheck.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/ki.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/startcheck.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/uebersicht.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/uebersicht.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/uebersicht.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="theme-color" content="#05070d" />
|
||||
<link rel="icon" href="assets/img/favicon.png" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/wissen.css?v=202608312313" />
|
||||
<link rel="stylesheet" href="assets/css/gate.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/start.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/aufgaben.css?v=202608312317" />
|
||||
<link rel="stylesheet" href="assets/css/wissen.css?v=202608312317" />
|
||||
</head>
|
||||
|
||||
<body class="start">
|
||||
@@ -170,8 +170,8 @@
|
||||
|
||||
</main>
|
||||
|
||||
<script src="assets/js/wahl.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wissen.js?v=202608312313" defer></script>
|
||||
<script src="assets/js/wahl.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/kopf.js?v=202608312317" defer></script>
|
||||
<script src="assets/js/wissen.js?v=202608312317" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user