summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/ai.php311
-rw-r--r--includes/backup.php31
-rw-r--r--includes/banner.php73
-rw-r--r--includes/bitset.php41
-rw-r--r--includes/edit-private.php147
-rw-r--r--includes/edit.php41
-rw-r--r--includes/footer.php33
-rw-r--r--includes/functions.php29
-rw-r--r--includes/header.php153
-rw-r--r--includes/init.php18
-rw-r--r--includes/keywords.php18
-rw-r--r--includes/member.php140
-rw-r--r--includes/member/hierarchy.php30
-rw-r--r--includes/pages.json162
-rw-r--r--includes/planner.php614
-rw-r--r--includes/refresh.php56
-rw-r--r--includes/score.php13
-rw-r--r--includes/search.php529
-rw-r--r--includes/short.php7
-rw-r--r--includes/subsysbanner.php15
-rw-r--r--includes/subsysedit.php29
-rw-r--r--includes/sysbanner.php43
-rw-r--r--includes/sysedit.php29
-rw-r--r--includes/system/history.php97
-rw-r--r--includes/system/subsystem.php32
-rw-r--r--includes/travelling.php17
-rw-r--r--includes/wakeup.php114
27 files changed, 1942 insertions, 880 deletions
diff --git a/includes/ai.php b/includes/ai.php
new file mode 100644
index 0000000..8f5f7ba
--- /dev/null
+++ b/includes/ai.php
@@ -0,0 +1,311 @@
+<?php
+
+global $memberData;
+global $metadata;
+global $systemCommonName;
+global $system;
+
+$profile = [
+ hexdec(substr(md5($memberData["id"]), 0, 1)),
+ hexdec(substr(sha1($memberData["id"]), 0, 1)),
+ hexdec(substr(md5(strrev($memberData["id"])), 0, 1)),
+ hexdec(substr(sha1(strrev($memberData["id"])), 0, 1)),
+ hexdec(substr(md5(strtoupper($memberData["id"])), 0, 1)),
+ hexdec(substr(sha1(strtoupper($memberData["id"])), 0, 1)),
+ hexdec(substr(md5(strtoupper(strrev($memberData["id"]))), 0, 1)),
+ hexdec(substr(sha1(strtoupper(strrev($memberData["id"]))), 0, 1)),
+];
+
+if (!function_exists("component")) {
+ function component(int $parts, int $num, int $index = 0): bool {
+ global $profile;
+
+ $item = round(15 / $parts);
+ $split = (int)round($profile[$index] / $item);
+
+ return $split === $num;
+ }
+}
+
+if (!function_exists("shouldHaveAn")) {
+ function shouldHaveAn(string $str): bool {
+ if (in_array(substr(strtolower($str), 0, 1), ["a", "e", "i", "o", "u", "y", "h"])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
+if (!function_exists("getSpeciesName")) {
+ function getSpeciesName(string $species, bool $canHaveMareSuffix = false): string {
+ global $metadata;
+
+ return match ($species) {
+ "earth" => $metadata["robot"] ?
+ "robot earth pony" :
+ (!$metadata["plush"] ? "earth pony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") :
+ "earth pony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"),
+ "alicorn" => $metadata["robot"] ?
+ "robot alicorn" :
+ (!$metadata["plush"] ? "alicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") :
+ "alicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"),
+ "crystal" => $metadata["robot"] ?
+ "robot crystal pony" :
+ (!$metadata["plush"] ? "crystal pony" :
+ "crystal pony plush"),
+ "pegasus" => $metadata["robot"] ?
+ "robot pegasus" :
+ (!$metadata["plush"] ? "pegasus" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") :
+ "pegasus" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"),
+ "batpony" => $metadata["robot"] ?
+ "robot batpony" :
+ (!$metadata["plush"] ? "batpony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") :
+ "batpony" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"),
+ "unicorn" => $metadata["robot"] ?
+ "robot unicorn" :
+ (!$metadata["plush"] ? "unicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") :
+ "unicorn" . (component(2, 2) && $canHaveMareSuffix ? " mare" : "") . " plush"),
+ default => $species . "_" . $metadata["robot"]
+ };
+ }
+}
+
+if (!function_exists("listing")) {
+ function listing(array $list): string {
+ $out = "";
+
+ foreach (array_values($list) as $index => $value) {
+ $mem = getSystemMember(explode("/", $value)[0], explode("/", $value)[1]);
+ $value = "<a href='/" . $mem["name"] . "'>" . getMiniName($mem["display_name"] ?? $mem["name"]) . "</a>";
+
+ if ($index === 0) {
+ $out = $value;
+ } else if ($index < count(array_values($list)) - 1) {
+ $out .= ", " . $value;
+ } else {
+ $out .= " and " . $value;
+ }
+ }
+
+ return $out;
+ }
+}
+
+$iam = 0;
+$multipleNames = count(explode("/", $memberData["display_name"])) > 1;
+
+$otherNames = explode("/", $memberData["display_name"]);
+array_shift($otherNames);
+
+if ($memberData["name"] === "scootaloo" && ((int)date('N') - 1) % 2 === 0) {
+ $metadata["marefriends"] = array_reverse($metadata["marefriends"]);
+}
+
+?>
+
+<!-- Intro -->
+<p>
+<?php if (component(4, 1)): ?>
+ Hello,
+<?php elseif (component(4, 2)): ?>
+ Hi,
+<?php elseif (component(4, 3)): ?>
+ Hey,
+<?php else: ?>
+ Hey there!</p><p>
+<?php endif; ?>
+
+<!-- Name -->
+<?= component(3, 2, 2) ? (component(4, 4) ? "My name is" : "my name is") : (component(3, 1, 2) ? "I am" : "I'm") ?> <?= explode("/", $memberData["display_name"] ?? $memberData["name"])[0] ?><?= $multipleNames && component(2, 1, 4) ? " (or " . implode("/", $otherNames) . ")" : "" ?>,
+
+<!-- Role -->
+<?= component(2, 2, 1) ? "I'm " : "I am " ?><?php $iam++; ?>
+<?php if ($metadata["host"]): ?>the most common fronter
+<?php elseif ($metadata["protector"]): ?>a protector
+<?php else: ?><?= component(2, 2, 0) ? "part" : "a member" ?> <?php endif; ?>
+of the <a href="/<?= $system ?>"><?= $systemCommonName ?></a>,<?php if (isset($metadata["median"])): ?>
+ <?php if ($metadata["little"] > 0): $source = getMember($metadata["median"]); ?><?php $iam++; ?><?= component(2, 2, 2) ? "I'm " : "I am " ?><?php $iam++; ?><?= component(2, 2, 4) ? "an age regressed version of" : "age regressed from" ?> <a href="/<?= $source["name"] ?>"><?= getMiniName($source["display_name"] ?? $source["name"]) ?></a>,<?php endif; ?>
+<?php endif; ?> <?= ($iam >= 3) ? "and" : (component(2, 2, 1) ? "I'm" : "I am") ?><?php $iam++; ?>
+
+<!-- Species -->
+<?php if ($iam >= 3 && component(2, 1, 4)): ?>also <?php endif; ?>
+<?php if (count($metadata["species"]) === 2): ?>
+<?= component(2, 1) ? "both " : "" ?>a<?= shouldHaveAn(getSpeciesName($metadata["species"][0])) ? "n" : "" ?> <?= getSpeciesName($metadata["species"][0]) ?> and a<?= shouldHaveAn(getSpeciesName($metadata["species"][1])) ? "n" : "" ?> <?= getSpeciesName($metadata["species"][1], true) ?>
+<?php elseif (count($metadata["species"]) === 3): ?>
+a<?= shouldHaveAn(getSpeciesName($metadata["species"][0])) ? "n" : "" ?> <?= getSpeciesName($metadata["species"][0]) ?>, a<?= shouldHaveAn(getSpeciesName($metadata["species"][1])) ? "n" : "" ?> <?= getSpeciesName($metadata["species"][1]) ?> and a<?= shouldHaveAn(getSpeciesName($metadata["species"][2])) ? "n" : "" ?> <?= getSpeciesName($metadata["species"][2], true) ?>
+<?php else: ?>
+a<?= shouldHaveAn(getSpeciesName($metadata["species"][0])) ? "n" : "" ?> <?= getSpeciesName($metadata["species"][0], true) ?><?php endif; ?><?php if ($iam >= 3 && component(2, 2, 4)): ?> too<?php endif; ?><!-- Pronouns --><?php if (isset($memberData["pronouns"]) && $memberData["pronouns"] !== "she/her"): ?>
+, <?= component(3, 1, 3) ? "I use " . $memberData["pronouns"] . " pronouns" : (component(3, 2, 3) ? "my pronouns are " . $memberData["pronouns"] : "I go with " . $memberData["pronouns"]) ?>
+<?php endif; ?>.
+
+</p>
+
+<p>
+<!-- Shared memory -->
+<?php $iamFacts = 0; $factGiven = false; if ($metadata["shared_memory"] === 1): ?>
+ <?php $factGiven = true;
+ if (component(3, 1, 4)): ?>
+ Depending on the circumstances, I may not share memories with my headmates
+ <?php elseif (component(3, 2, 4)): ?>
+ I may not share memories with my headmates depending on the circumstances
+ <?php else: ?>
+ I sometimes <?= component(2, 2, 1) ? "don't" : "do not" ?> share memories with my headmates
+ <?php endif; ?>
+<?php elseif ($metadata["shared_memory"] === 0): ?>
+ <?php $factGiven = true;
+ if (component(3, 1, 4)): ?>
+ I <?= component(2, 2, 1) ? "don't" : "do not" ?> share memories with my headmates
+ <?php elseif (component(3, 2, 4)): ?>
+ I <?= component(2, 2, 1) ? "don't" : "do not" ?> have access to my headmates' memories
+ <?php else: ?>
+ I <?= component(2, 2, 1) ? "can't" : "cannot" ?> have access to my headmates' memories
+ <?php endif; ?>
+<?php endif; ?>
+
+<!-- Fictive -->
+<?php if ($metadata["fictive"]): ?>
+ <?php if (component(3, 1, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; ?> a fictive
+ <?php elseif (component(3, 2, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; ?> from Equestria
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ I come from Equestria
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+<!-- Less frequent -->
+<?php if ($metadata["less_frequent"]): ?>
+ <?php if (component(3, 1, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; ?> fronting less often
+ <?php elseif (component(3, 2, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; ?> less often at front
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ I like to front less often
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+<!-- Non verbal IRL -->
+<?php if ($metadata["nonverbal"]): ?>
+ <?php if (component(3, 1, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; ?> nonverbal in real life
+ <?php elseif (component(3, 2, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; ?> not talking in real life
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ I don't talk in real life
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+<!-- Age regression -->
+<?php if ($metadata["little"] === 1): ?>
+ <?php if (component(3, 1, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ an age regressor
+ <?php elseif (component(3, 2, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ capable of age regression
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ I can age regress
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+<!-- Younger -->
+<?php if ($metadata["little"] === 3): ?>
+ <?php if (component(3, 1, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ younger than the body is
+ <?php elseif (component(3, 2, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ younger but not enough to be considered a little
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ I feel <?= component(2, 2, 5) ? "kinda" : "kind of" ?> younger than my headmates
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+<!-- Age spells -->
+<?php if ($metadata["age_spells"] && $metadata["little"] !== 1 && !(isset($metadata["median"]) && $metadata["little"] > 0)): ?>
+ <?php if (component(3, 1, 4)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ affected by spells to make me feel younger
+ <?php elseif (component(3, 2, 4)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ affected by age spells
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ age regression spells can affect me
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+<!-- Little -->
+<?php if ($metadata["little"] === 2): ?>
+ <?php if (component(3, 1, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ a lot younger than the body is
+ <?php elseif (component(3, 2, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ a little
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ I feel a lot younger than my headmates
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+</p>
+
+<p>
+
+<!-- Marefriends -->
+<?php $factGiven = false; $iamFacts = 0; if (count($metadata["marefriends"]) > 0): ?>
+ <?php if (component(4, 1, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ <?php if (count($metadata["marefriends"]) > 1): ?>in relationships with<?php else: ?>in a relationship with<?php endif; ?> <?= listing($metadata["marefriends"]) ?>
+ <?php elseif (component(4, 2, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?php endif; ?>
+ <?php if (count($metadata["marefriends"]) > 1): ?>My marefriends are<?php else: ?>My marefriend is<?php endif; ?> <?= listing($metadata["marefriends"]) ?>
+ <?php elseif (component(4, 3, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?php endif; ?>
+ <?= listing($metadata["marefriends"]) ?> <?php if (count($metadata["marefriends"]) > 1): ?>are my marefriends<?php else: ?>is my marefriend<?php endif; ?>
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ I love <?= listing($metadata["marefriends"]) ?>
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+<!-- Sisters -->
+<?php if (count($metadata["sisters"]) > 0): ?>
+ <?php if (component(4, 1, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ <?php if (count($metadata["sisters"]) > 1): ?>in relationships with<?php else: ?>in a relationship with<?php endif; ?> <?= listing($metadata["sisters"]) ?>
+ <?php elseif (component(4, 2, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?php endif; ?>
+ <?= $factGiven ? "my" : "My"?><?php if (count($metadata["sisters"]) > 1): ?> sisters are<?php else: ?> sister is<?php endif; ?> <?= listing($metadata["sisters"]) ?>
+ <?php elseif (component(4, 3, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?php endif; ?>
+ <?= listing($metadata["sisters"]) ?> <?php if (count($metadata["sisters"]) > 1): ?>are my sisters<?php else: ?>is my sister<?php endif; ?>
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ <?php if ($factGiven): ?>
+ I also love <?= listing($metadata["sisters"]) ?> as sister<?php if (count($metadata["sisters"]) > 1): ?>s<?php endif; ?>
+ <?php else: ?>
+ <?= listing($metadata["sisters"]) ?> <?php if (count($metadata["sisters"]) > 1): ?>are my family<?php else: ?>is my family<?php endif; ?>
+ <?php endif; ?>
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+<!-- Caretakers -->
+<?php if (count($metadata["caretakers"]) > 0): ?>
+ <?php if (component(4, 1, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?= component(2, 2, 0) ? "I'm" : "I am" ?><?php $iamFacts++; endif; ?>
+ being taken care of by <?= listing($metadata["caretakers"]) ?>
+ <?php elseif (component(4, 2, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?php endif; ?>
+ <?= $factGiven ? "the" : "The"?><?php if (count($metadata["caretakers"]) > 1): ?> mares who take care of me are<?php else: ?> mare who takes care of me is<?php endif; ?> <?= listing($metadata["caretakers"]) ?>
+ <?php elseif (component(4, 3, 5)): ?><?= $factGiven ? " and" : ""?>
+ <?php if ($iamFacts > 0): ?><?php else: ?><?php endif; ?>
+ <?= listing($metadata["caretakers"]) ?> <?php if (count($metadata["caretakers"]) > 1): ?>are my caretakers<?php else: ?>is my caretaker<?php endif; ?>
+ <?php else: ?><?= $factGiven ? " and" : ""?>
+ <?php if ($factGiven): ?>
+ I like having <?= listing($metadata["caretakers"]) ?> take care of me
+ <?php else: ?>
+ <?= listing($metadata["caretakers"]) ?> take care of me
+ <?php endif; ?>
+ <?php endif; ?>
+<?php $factGiven = true; endif; ?>
+
+</p> \ No newline at end of file
diff --git a/includes/backup.php b/includes/backup.php
index 18ed6a4..ad09617 100644
--- a/includes/backup.php
+++ b/includes/backup.php
@@ -1,5 +1,6 @@
<?php
+echo(" Scanning...\n");
$root = array_filter(scandir("data"), function ($i) {
return !str_starts_with($i, ".");
});
@@ -11,19 +12,22 @@ $data = [
foreach ($root as $file) {
if ($file === "backup.poniesbackup" || $file === "backup.ponieskey" || $file === "encrypted" || str_ends_with($file, ".poniesbackup")) continue;
+ echo(" /$file\n");
if (is_dir("data/$file")) {
foreach (array_filter(scandir("data/$file"), function ($i) {
return !str_starts_with($i, ".");
}) as $dirfile) {
- if ($dirfile === "backup.poniesbackup" || $dirfile === "backup.ponieskey" || $dirfile === "encrypted" || str_ends_with($dirfile, ".poniesbackup")) continue;
+ if ($dirfile === "backup.poniesbackup" || $dirfile === "backup.ponieskey" || $dirfile === "encrypted" || $dirfile === "oldactions" || str_ends_with($dirfile, ".poniesbackup")) continue;
+ echo(" /$dirfile/$file\n");
$files[] = [
"dir" => $file,
"file" => $dirfile
];
}
} else {
+ echo(" /$file\n");
$files[] = [
"dir" => "",
"file" => $file
@@ -31,7 +35,9 @@ foreach ($root as $file) {
}
}
+echo(" Reading files...\n");
foreach ($files as $file) {
+ echo(" /$file[dir]/$file[file]\n");
$file["mime"] = mime_content_type("data/$file[dir]/$file[file]");
$file["checksum"] = [
sha1_file("data/$file[dir]/$file[file]"),
@@ -48,6 +54,7 @@ function pkcs7_pad($data, $size) {
}
if (!file_exists("./data/backup.ponieskey")) {
+ echo(" Reading encryption key...\n");
$key = openssl_random_pseudo_bytes(512);
$iv = openssl_random_pseudo_bytes(16);
file_put_contents("./data/backup.ponieskey", base64_encode(json_encode([
@@ -55,27 +62,41 @@ if (!file_exists("./data/backup.ponieskey")) {
"key" => bin2hex($key)
])));
} else {
+ echo(" Creating encryption key...\n");
$key_raw = json_decode(base64_decode(file_get_contents("./data/backup.ponieskey")), true);
$key = hex2bin($key_raw["key"]);
$iv = hex2bin($key_raw["iv"]);
}
+echo(" Encrypting...\n");
$payload = json_encode($data);
$encrypted = openssl_encrypt(pkcs7_pad($payload, 16), 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
+echo(" Writing backup...\n");
file_put_contents("./data/backup.poniesbackup", $encrypted);
@mkdir("./data/encrypted");
$id = str_replace(":", "-", date('c'));
copy("./data/backup.poniesbackup", "./data/encrypted/" . $id . ".poniesbackup");
+echo(" Uploading to servers...\n");
+
+echo(" bridlewood... upload\n");
exec("scp ./data/encrypted/" . $id . ".poniesbackup fedora@bridlewood.equestria.dev:/opt/ponies");
-exec('ssh fedora@bridlewood.equestria.dev bash -c "cd /opt/ponies; ls -tp | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"');
+echo(" bridlewood... cleaning up\n");
+exec('ssh fedora@bridlewood.equestria.dev bash /opt/clean.sh');
+echo(" canterlot... upload\n");
exec("scp ./data/encrypted/" . $id . ".poniesbackup root@canterlot.equestria.dev:/opt/ponies");
-exec('ssh root@canterlot.equestria.dev bash -c "cd /opt/ponies; ls -tp | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"');
+echo(" canterlot... cleaning up\n");
+exec('ssh root@canterlot.equestria.dev bash /opt/clean.sh');
-copy("./data/encrypted/" . $id . ".poniesbackup", "/opt/ponies/" . $id . ".poniesbackup");
-exec('bash -c "cd /opt/ponies; ls -tp | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"');
+if (file_exists("/opt/ponies")) {
+ echo(" zephyrheights... copy\n");
+ copy("./data/encrypted/" . $id . ".poniesbackup", "/opt/ponies/" . $id . ".poniesbackup");
+ echo(" zephyrheights... cleaning up\n");
+ exec('bash -c "cd /opt/ponies; ls -tp | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"');
+}
+echo(" Cleaning up...\n");
unlink("./data/encrypted/" . $id . ".poniesbackup"); \ No newline at end of file
diff --git a/includes/banner.php b/includes/banner.php
index 2582b63..213863a 100644
--- a/includes/banner.php
+++ b/includes/banner.php
@@ -2,69 +2,9 @@
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/session.php"; global $isLoggedIn;
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/pronouns.php";
+require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php";
$travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling.json"), true);
-if (!function_exists("getMiniName")) {
- function getMiniName(string $name) {
- $parts = explode(" ", $name);
-
- if (strlen($parts[0]) > 3 && !str_ends_with($parts[0], "e") && $parts[0] !== "Filly") {
- if (str_contains($parts[0], "/")) {
- return explode("/", $parts[0])[0];
- } else {
- return $parts[0];
- }
- } else {
- return $name;
- }
- }
-}
-
-if (!function_exists("getSystemMember")) {
- function getSystemMember(string $system, string $id) {
- $systemID = $system;
-
- $members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-members.json"), true);
- $member = null;
-
- foreach ($members as $m) {
- if ($m["id"] === $id) $member = $m;
- }
-
- return $member;
- }
-}
-
-if (!function_exists("timeAgo")) {
- function timeAgo($time): string {
- if (!is_numeric($time)) {
- $time = strtotime($time);
- }
-
- $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
- $lengths = array("60", "60", "24", "7", "4.35", "12", "100");
-
- $now = time();
-
- $difference = $now - $time;
- if ($difference <= 10 && $difference >= 0) {
- return $tense = "now";
- } elseif ($difference > 0) {
- $tense = "ago";
- } else {
- $tense = "later";
- }
-
- for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
- $difference /= $lengths[$j];
- }
-
- $difference = round($difference);
-
- $period = $periods[$j] . ($difference >1 ? "s" :'');
- return "{$difference} {$period} {$tense}";
- }
-}
function _header_getMember(string $id, $system) {
$members = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-members.json"), true);
@@ -106,6 +46,7 @@ function _header_getSubsystemFromMember(array $member) {
function getMemberBannerData(string $id, string $system, bool $french = false) {
global $subsystems;
global $travelling;
+ global $isLoggedIn;
$subsystems = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$system-subsystems.json"), true) ?? [];
@@ -381,6 +322,14 @@ function getMemberBannerData(string $id, string $system, bool $french = false) {
];
}
+ if (($metadata["sexually_active"] ?? false) && !$french && $isLoggedIn) {
+ $badges[] = [
+ "id" => "sexually_active",
+ "color" => "d6a833",
+ "html" => '<span data-bs-toggle="tooltip" data-bs-html="true" title="<b>Sexually active</b><br>' . ucfirst(getMemberPronouns($member['pronouns'])["subjective"]) . ' ' . (getMemberPronouns($member['pronouns'])["third"] ? "is" : "are") . ' doing sexual acts and would pleasure ' . getMemberPronouns($member['pronouns'])["possessive_det"] . ' marefriend·s IRL if ' . ucfirst(getMemberPronouns($member['pronouns'])["subjective"]) . ' had the chance." class="badge rounded-pill" style="background-color:#d68f33;">Sexually active</span>'
+ ];
+ }
+
if ($metadata["protector"] ?? false) {
$badges[] = [
"id" => "protector",
@@ -423,7 +372,7 @@ function getMemberBannerData(string $id, string $system, bool $french = false) {
];
}
- if (($metadata["little"] ?? 0) === 1) {
+ if (($metadata["age_regressor"] ?? false)) {
if ($metadata["regression"] !== null && $metadata["regression"] !== false) {
$regression = _header_getMember($metadata["regression"], $system);
$badges[] = [
diff --git a/includes/bitset.php b/includes/bitset.php
index 2e5a645..1d026e5 100644
--- a/includes/bitset.php
+++ b/includes/bitset.php
@@ -3,24 +3,26 @@
function parseBitset ($bitset) {
$bin = str_repeat("0", 48 - strlen(decbin($bitset))) . decbin($bitset);
- $sharedMemory = bindec(substr($bin, 8 + 16, 2));
- $median = substr($bin, 10 + 16, 1) !== "0";
- $little = bindec(substr($bin, 11 + 16, 2));
+ $sharedMemory = bindec(substr($bin, 24, 2));
+ $median = substr($bin, 26, 1) !== "0";
+ $little = bindec(substr($bin, 27, 2));
$food = bindec(substr($bin, 16, 2));
$nonverbal = substr($bin, 15, 1) !== "0";
$lessFrequent = substr($bin, 14, 1) !== "0";
- $magic = bindec(substr($bin, 2 + 16, 3));
- $sensitivity = bindec(substr($bin, 5 + 16, 3));
- $protector = substr($bin, 13 + 16, 1) !== "0";
- $fictive = substr($bin, 14 + 16, 1) !== "0";
- $notTalking = substr($bin, 15 + 16, 1) !== "0";
- $host = substr($bin, 16 + 16, 1) !== "0";
- $robot = substr($bin, 29 + 16, 1) !== "0";
- $plush = substr($bin, 30 + 16, 1) !== "0";
- $age = substr($bin, 31 + 16, 1) !== "0";
- $species1 = substr($bin, 17 + 16, 4);
- $species2 = substr($bin, 21 + 16, 4);
- $species3 = substr($bin, 25 + 16, 4);
+ $sexuallyActive = substr($bin, 13, 1) !== "0";
+ $ageRegressor = substr($bin, 12, 1) !== "0";
+ $magic = bindec(substr($bin, 18, 3));
+ $sensitivity = bindec(substr($bin, 21, 3));
+ $protector = substr($bin, 29, 1) !== "0";
+ $fictive = substr($bin, 30, 1) !== "0";
+ $notTalking = substr($bin, 31, 1) !== "0";
+ $host = substr($bin, 32, 1) !== "0";
+ $robot = substr($bin, 45, 1) !== "0";
+ $plush = substr($bin, 46, 1) !== "0";
+ $age = substr($bin, 47, 1) !== "0";
+ $species1 = substr($bin, 33, 4);
+ $species2 = substr($bin, 37, 4);
+ $species3 = substr($bin, 41, 4);
$species1 = match ($species1) {
"0001" => "earth",
@@ -52,6 +54,11 @@ function parseBitset ($bitset) {
default => null,
};
+ if ($little === 1) {
+ $ageRegressor = true;
+ $little = 0;
+ }
+
return [
'shared_memory' => $sharedMemory,
'median' => $median,
@@ -68,6 +75,8 @@ function parseBitset ($bitset) {
'nonverbal' => $nonverbal,
'less_frequent' => $lessFrequent,
'age_spells' => $age,
+ 'age_regressor' => $ageRegressor,
+ 'sexually_active' => $sexuallyActive,
'species' => array_filter([
$species1,
$species2,
@@ -88,6 +97,8 @@ function parseMetadata ($metadata) {
$m["regression"] = $metadata["regression"] ?? null;
$m["caretakers"] = $metadata["caretakers"] ?? [];
$m["median"] = $metadata["median"] ?? null;
+ $m["birth"] = $metadata["birth"] ?? null;
+ $m["heat"] = $metadata["heat"] ?? null;
} else {
$m = $metadata;
}
diff --git a/includes/edit-private.php b/includes/edit-private.php
new file mode 100644
index 0000000..58e9ed5
--- /dev/null
+++ b/includes/edit-private.php
@@ -0,0 +1,147 @@
+<?php global $system; global $systemCommonName; global $systemID; global $member; global $memberData; global $memberCommonName; global $memberID; $title = "Editing " . $memberCommonName . " (private page) · " . $systemCommonName; require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
+
+if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "-" . $memberID . "-metadata.json")) {
+ $metadata = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "-" . $memberID . "-metadata.json"), true));
+}
+
+?>
+
+<br>
+<div class="container">
+ <script>
+ window.currentMemberData = JSON.parse(atob(`<?= base64_encode(json_encode(getMemberBannerData($memberID, $systemID))) ?>`));
+ </script>
+ <div id="member-banner"></div>
+ <script src="/app/banner.js"></script><script>refreshBanner()</script>
+ <br>
+
+ <p class="text-muted" id="page-content">
+ <span id="editor-save-status" class="text-muted">Saved</span> · <span id="editor-size"><?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html") ? strlen(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html")) : "0" ?></span> bytes · <a href="/<?= $memberData["name"] ?>">View page</a>
+ </p>
+
+ <!--suppress HtmlFormInputWithoutLabel -->
+ <textarea id="page-editor">
+ <?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html") ? file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html") : "" ?>
+ </textarea>
+
+ <script src="/assets/editor/editor.js"></script>
+ <script>
+ let editor;
+ ClassicEditor
+ .create( document.querySelector( '#page-editor' ), {
+ toolbar: [
+ 'undo', 'redo', '|', 'removeFormat', '|', 'heading', '|', 'fontSize', 'fontColor', 'fontBackgroundColor', 'alignment', '|', 'bold', 'italic', 'underline', 'strikethrough', '|', 'subscript', 'superscript', '|', 'code', '|', 'outdent', 'indent', '|', 'bulletedList', 'numberedList', '|', 'link', 'imageUpload', 'mediaEmbed', 'blockQuote', 'insertTable', 'codeBlock', '|', 'horizontalLine'
+ ]
+ } )
+
+ .then( newEditor => {
+ editor = newEditor;
+ } )
+ .catch( error => {
+ console.error( error );
+ } );
+ </script>
+ <style>
+ :root {
+ --ck-color-base-background: transparent;
+ }
+
+ .ck-toolbar {
+ filter: invert(1);
+ }
+
+ .ck-tooltip__text {
+ color: white !important;
+ }
+
+ .ck-dropdown__panel {
+ background: #ddd !important;
+ }
+
+ .ck-color-grid__tile {
+ filter: invert(1);
+ }
+
+ .ck-balloon-rotator {
+ background-color: #ccc !important;
+ }
+
+ .ck-balloon-panel {
+ filter: invert(1);
+ }
+ </style>
+ <script>
+ let lastSavedData = editor.getData();
+ let lastFetchedData = editor.getData();
+ let timeSinceLastModified = 0;
+ let saving = false;
+
+ async function save() {
+ let data = editor.getData();
+ document.getElementById("editor-save-status").innerHTML = "Saving...";
+ document.getElementById("editor-save-status").classList.remove("text-danger");
+ document.getElementById("editor-save-status").classList.remove("text-muted");
+ document.getElementById("editor-save-status").classList.remove("text-warning");
+ document.getElementById("editor-save-status").classList.add("text-primary");
+ saving = true;
+
+ try {
+ await window.fetch("/api/save-private?system=<?= $systemID ?>&member=<?= $memberID ?>", {
+ method: "POST",
+ body: JSON.stringify({ content: data })
+ });
+ document.getElementById("editor-save-status").innerHTML = "Saved";
+ document.getElementById("editor-save-status").classList.remove("text-danger");
+ document.getElementById("editor-save-status").classList.add("text-muted");
+ document.getElementById("editor-save-status").classList.remove("text-warning");
+ document.getElementById("editor-save-status").classList.remove("text-primary");
+ lastSavedData = data;
+ saving = false;
+ } catch (e) {
+ console.error(e);
+ document.getElementById("editor-save-status").innerHTML = "Failed to save";
+ document.getElementById("editor-save-status").classList.add("text-danger");
+ document.getElementById("editor-save-status").classList.remove("text-muted");
+ document.getElementById("editor-save-status").classList.remove("text-warning");
+ document.getElementById("editor-save-status").classList.remove("text-primary");
+ }
+ }
+
+ document.onclick = async () => {
+ if (saving) return;
+
+ if (editor.getData() !== lastSavedData) {
+ await save();
+ }
+ }
+
+ setInterval(async () => {
+ if (saving) return;
+
+ document.getElementById("editor-size").innerHTML = editor.getData().length;
+
+ if (editor.getData() !== lastSavedData) {
+ document.getElementById("editor-save-status").innerHTML = "Modified";
+ document.getElementById("editor-save-status").classList.remove("text-danger");
+ document.getElementById("editor-save-status").classList.remove("text-muted");
+ document.getElementById("editor-save-status").classList.add("text-warning");
+ document.getElementById("editor-save-status").classList.remove("text-primary");
+
+ if (editor.getData() !== lastFetchedData) {
+ lastFetchedData = editor.getData();
+ timeSinceLastModified = 0;
+ } else {
+ timeSinceLastModified++;
+ }
+
+ if (timeSinceLastModified > 20) {
+ await save();
+ }
+ } else {
+ timeSinceLastModified = 0;
+ }
+ }, 100)
+ </script>
+</div>
+
+<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php'; ?> \ No newline at end of file
diff --git a/includes/edit.php b/includes/edit.php
index 85382a0..5bbd38a 100644
--- a/includes/edit.php
+++ b/includes/edit.php
@@ -1,36 +1,9 @@
-<?php global $system; global $systemCommonName; global $systemID; global $member; global $memberData; global $memberCommonName; global $memberID; $title = "Editing " . $memberCommonName . " · " . $systemCommonName; require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
+<?php global $system; global $systemCommonName; global $systemID; global $member; global $memberData; global $memberCommonName; global $memberID; $title = "Editing " . $memberCommonName . " (public page) · " . $systemCommonName; require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
-function timeAgo($time): string {
- if (!is_numeric($time)) {
- $time = strtotime($time);
- }
-
- $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
- $lengths = array("60", "60", "24", "7", "4.35", "12", "100");
-
- $now = time();
-
- $difference = $now - $time;
- if ($difference <= 10 && $difference >= 0) {
- return $tense = "now";
- } elseif ($difference > 0) {
- $tense = "ago";
- } else {
- $tense = "later";
- }
-
- for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
- $difference /= $lengths[$j];
- }
-
- $difference = round($difference);
-
- $period = $periods[$j] . ($difference >1 ? "s" :'');
- return "{$difference} {$period} {$tense}";
+if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "-" . $memberID . "-metadata.json")) {
+ $metadata = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "-" . $memberID . "-metadata.json"), true));
}
-$metadata = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "-" . $memberID . "-metadata.json"), true));
-
?>
<br>
@@ -42,8 +15,8 @@ $metadata = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'
<script src="/app/banner.js"></script><script>refreshBanner()</script>
<br>
- <p class="text-muted">
- <span id="editor-save-status">Saved</span> · <span id="editor-size"><?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-disclaimers.html") ? strlen(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-disclaimers.html")) : "0" ?></span> bytes
+ <p class="text-muted" id="page-content">
+ <span id="editor-save-status" class="text-muted">Saved</span> · <span id="editor-size"><?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html") ? strlen(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html")) : "0" ?></span> bytes · <a href="/<?= $memberData["name"] ?>">View page</a>
</p>
<!--suppress HtmlFormInputWithoutLabel -->
@@ -166,10 +139,6 @@ $metadata = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'
}
} else {
timeSinceLastModified = 0;
- document.getElementById("editor-save-status").innerHTML = "Saved";
- document.getElementById("editor-save-status").classList.add("text-muted");
- document.getElementById("editor-save-status").classList.remove("text-warning");
- document.getElementById("editor-save-status").classList.remove("text-primary");
}
}, 100)
</script>
diff --git a/includes/footer.php b/includes/footer.php
index 4592b8e..720881a 100644
--- a/includes/footer.php
+++ b/includes/footer.php
@@ -1,35 +1,6 @@
<?php
-if (!function_exists("timeAgo")) {
- function timeAgo($time): string {
- if (!is_numeric($time)) {
- $time = strtotime($time);
- }
-
- $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
- $lengths = array("60", "60", "24", "7", "4.35", "12", "100");
-
- $now = time();
-
- $difference = $now - $time;
- if ($difference <= 10 && $difference >= 0) {
- return $tense = "now";
- } elseif ($difference > 0) {
- $tense = "ago";
- } else {
- $tense = "later";
- }
-
- for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
- $difference /= $lengths[$j];
- }
-
- $difference = round($difference);
-
- $period = $periods[$j] . ($difference >1 ? "s" :'');
- return "{$difference} {$period} {$tense}";
- }
-}
+require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php";
?>
@@ -58,5 +29,7 @@ if (!function_exists("timeAgo")) {
})
</script>
+<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/search.php"; ?>
+
</body>
</html> \ No newline at end of file
diff --git a/includes/functions.php b/includes/functions.php
index db4a8df..1a2bf4c 100644
--- a/includes/functions.php
+++ b/includes/functions.php
@@ -7,7 +7,7 @@ if (!function_exists("getMiniName")) {
function getMiniName(string $name) {
$parts = explode(" ", $name);
- if (strlen($parts[0]) > 3 && !str_ends_with($parts[0], "e") && $parts[0] !== "Filly") {
+ if (strlen($parts[0]) > 3 && !str_ends_with($parts[0], "e") && $parts[0] !== "Filly" && $parts[0] !== "Windy") {
if (str_contains($parts[0], "/")) {
return explode("/", $parts[0])[0];
} else {
@@ -19,6 +19,23 @@ if (!function_exists("getMiniName")) {
}
}
+if (!function_exists("withCaretakersDown")) {
+ function withCaretakersDown(array $ordered): array {
+ $caretakersNo = [];
+ $caretakersYes = [];
+
+ foreach ($ordered as $item) {
+ if ($item["_metadata"]["little"] === 2) {
+ $caretakersYes[] = $item;
+ } else {
+ $caretakersNo[] = $item;
+ }
+ }
+
+ return [...$caretakersNo, ...$caretakersYes];
+ }
+}
+
if (!function_exists("getSystemMember")) {
function getSystemMember(string $system, string $id) {
$systemID = $system;
@@ -61,7 +78,7 @@ if (!function_exists("showMembersFromList")) {
<a href="/' . $member['name'] . '" style="text-decoration:none !important;filter:none !important;"><div class="hpd-item-card" style="background-color:rgba(255, 255, 255, .1);border:1px solid ' . (isset($member['color']) ? "#" . $member['color'] . "55" : "transparent") . ';outline-color:' . (isset($member['color']) ? "#" . $member['color'] . "55" : "transparent") . ';border-radius:10px;text-align:center;display:flex;align-items:center;justify-content:center;padding:5px;"><div>
<img alt="" src="' . $member['avatar_url'] . '" style="border-radius:999px;background-color:rgba(0, 0, 0, .25);height:48px;display:block;margin-left:auto;margin-right:auto;">
<div style="text-decoration:none;color:white;margin-top:5px;">' . ($member['display_name'] ?? $member['name']) . '</div>
-<div style="text-decoration:none !important;color:black !important;"><code style="text-decoration:none !important;color:white !important;">' . ($member['travelling'] ? "+" . ($member['proxy_tags'][0]['prefix'] ?? "&nbsp;") : ($member['proxy_tags'][0]['prefix'] ?? "&nbsp;")) . '</code></div>
+<div style="text-decoration:none !important;color:black !important;"><code style="text-decoration:none !important;color:white !important;">' . (isset($member['travelling']) && $member['travelling'] ? "+" . ($member['proxy_tags'][0]['prefix'] ?? "&nbsp;") : ($member['proxy_tags'][0]['prefix'] ?? "&nbsp;")) . '</code></div>
</div></div></a>');
}}
}
@@ -114,13 +131,13 @@ if (!function_exists("showSystem")) {
$i["system"] = $id;
return $i;
}, array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$id-members.json"), true), function ($i) use ($travelling) {
- return !$travelling[$i['id']]['travelling'];
+ return !(isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']);
})), ...array_map(function ($i) use ($id) {
$i["travelling"] = true;
$i["system"] = ($id === "gdapd" ? "ynmuc" : "gdapd");
return $i;
}, array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($id === "gdapd" ? "ynmuc" : "gdapd") . "-members.json"), true), function ($i) use ($travelling) {
- return $travelling[$i['id']]['travelling'];
+ return isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling'];
}))], $id));
echo('</div>
@@ -162,7 +179,7 @@ if (!function_exists("timeAgo")) {
$time = strtotime($time);
}
- $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
+ $periods = ["sec.", "mn.", "hr.", "d.", "wk.", "mo.", "y.", "ages"];
$lengths = array("60", "60", "24", "7", "4.35", "12", "100");
$now = time();
@@ -182,7 +199,7 @@ if (!function_exists("timeAgo")) {
$difference = round($difference);
- $period = $periods[$j] . ($difference >1 ? "s" :'');
+ $period = $periods[$j];
return "{$difference} {$period} {$tense}";
}
}
diff --git a/includes/header.php b/includes/header.php
index 1f71aa5..91d0aee 100644
--- a/includes/header.php
+++ b/includes/header.php
@@ -1,4 +1,6 @@
-<?php global $title;
+<?php global $title; global $pages;
+
+$pages = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/pages.json"), true);
function error($errno, $errstr, $file, $line) {
echo('
@@ -226,6 +228,10 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
}
}
+ .member-small-only {
+ display: none;
+ }
+
@media (max-width: 767px) {
#member-card {
grid-template-columns: 1fr !important;
@@ -248,6 +254,14 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
grid-template-columns: 1fr !important;
text-align: left;
}
+
+ .member-small-separator {
+ display: none;
+ }
+
+ .member-small-only {
+ display: inline-block;
+ }
}
#page-content a {
@@ -583,6 +597,35 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
left: -10px;
}
+ .tree-l1 .tree-l0-separator {
+ border-bottom: none !important;
+ }
+
+ .tree-l2-separator {
+ display: inline-block;
+ width: 20px;
+ margin-left: 35px;
+ border-bottom: 1px solid white;
+ border-left: 1px solid white;
+ height: 26px;
+ position: relative;
+ top: -12px;
+ left: -10px;
+ }
+
+ .tree-l2 .tree-l1-separator {
+ width: 30px;
+ }
+
+ .tree-l2 .tree-l0-separator {
+ width: 30px;
+ }
+
+ .tree-l2 .tree-inner {
+ position: relative;
+ left: -10px;
+ }
+
.tree-inner {
display: inline-block;
}
@@ -633,7 +676,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
display: grid;
- grid-template-columns: repeat(4, 1fr);
+ grid-template-columns: repeat(6, 1fr);
text-align: center;
}
@@ -643,7 +686,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
@media (max-width: 991px) {
div#member-details.member-details-loggedIn {
- grid-template-columns: repeat(2, 1fr) !important;
+ grid-template-columns: repeat(3, 1fr) !important;
text-align: center;
}
@@ -655,7 +698,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
@media (max-width: 767px) {
div#member-details.member-details-loggedIn {
- grid-template-columns: 1fr !important;
+ grid-template-columns: repeat(2, 1fr) !important;
text-align: left;
}
}
@@ -698,29 +741,29 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/">
<img src="/assets/icons/home.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Home</span>
+ <span style="vertical-align: middle;"><?= $pages["home"]["name"] ?></span>
</a></li>
<li><a class="dropdown-item" href="/-/disclaimers">
<img src="/assets/icons/disclaimers.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Disclaimers</span>
+ <span style="vertical-align: middle;"><?= $pages["disclaimers"]["name"] ?></span>
</a></li>
<li><a class="dropdown-item" href="/-/relations">
<img src="/assets/icons/relations.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Relations</span>
+ <span style="vertical-align: middle;"><?= $pages["relations"]["name"] ?></span>
</a></li>
<li><a class="dropdown-item" href="/-/terminology">
<img src="/assets/icons/terminology.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Terminology</span>
+ <span style="vertical-align: middle;"><?= $pages["terminology"]["name"] ?></span>
</a></li>
<li><hr class="dropdown-divider"></li>
<li><h5 class="dropdown-header">Tools</h5></li>
<li><a class="dropdown-item" href="/-/parser">
<img src="/assets/icons/parser.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Message parser</span>
+ <span style="vertical-align: middle;"><?= $pages["parser"]["name"] ?></span>
</a></li>
<li><a class="dropdown-item" href="/-/prefix">
<img src="/assets/icons/prefix.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Prefix generator</span>
+ <span style="vertical-align: middle;"><?= $pages["prefix"]["name"] ?></span>
</a></li>
</ul>
</li>
@@ -733,21 +776,32 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/-/emergency">
<img src="/assets/icons/emergency.svg" alt="" style="width:24px;vertical-align: middle;">
- <span class="text-danger" style="vertical-align: middle;"><b>Emergency alert</b></span>
+ <span class="text-danger" style="vertical-align: middle;"><b><?= $pages["emergency"]["name"] ?></b></span>
</a></li>
<?php
$frontCloudburst = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-fronters.json"), true)["members"];
$frontRaindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-fronters.json"), true)["members"];
- if (isset($_GET['pleasure']) || (
+ if (isset($_GET['pleasure']) || (isset($frontRaindrops[0]) && isset($frontCloudburst[0]) && (
((int)date('H') >= 20 || (int)date('H') < 6) &&
- $frontCloudburst[0]["id"] === "erknz" &&
- $frontRaindrops[0]["id"] === "qbzxm"
- )): ?>
+ ($frontCloudburst[0]["id"] === "erknz" &&
+ $frontRaindrops[0]["id"] === "qbzxm") ||
+ ($frontCloudburst[0]["id"] === "zzise" &&
+ $frontRaindrops[0]["id"] === "tfbob") ||
+ ($frontCloudburst[0]["id"] === "vncoa" &&
+ $frontRaindrops[0]["id"] === "qraku")
+ ))): ?>
<li><a class="dropdown-item" href="/-/pleasure" <?= isset($_GET['pleasure']) ? 'style="opacity: .5;"' : '' ?>>
<img src="/assets/icons/pleasure.svg" alt="" style="width:24px;vertical-align: middle;">
- <span class="text-success" style="vertical-align: middle;"><b>Pleasure alert</b></span>
+ <span class="text-success" style="vertical-align: middle;"><b><?= $pages["pleasure"]["name"] ?></b></span>
+ </a></li>
+ <?php endif; ?>
+
+ <?php if (isset($_GET['wakeup']) || (int)date('H') >= 20 || (int)date('H') < 8): ?>
+ <li><a class="dropdown-item" href="/-/wakeup" <?= isset($_GET['wakeup']) ? 'style="opacity: .5;"' : '' ?>>
+ <img src="/assets/icons/wakeup.svg" alt="" style="width:24px;vertical-align: middle;">
+ <span class="text-info" style="vertical-align: middle;"><b><?= $pages["wakeup"]["name"] ?></b></span>
</a></li>
<?php endif; ?>
<li><hr class="dropdown-divider"></li>
@@ -755,56 +809,36 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
<li><h5 class="dropdown-header">Applications</h5></li>
<li><a class="dropdown-item" href="/-/dashboard">
<img src="/assets/icons/dashboard.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Dashboard</span>
+ <span style="vertical-align: middle;"><?= $pages["dashboard"]["name"] ?></span>
</a></li>
<li><a class="dropdown-item" href="/-/fronting">
<img src="/assets/icons/fronting.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Front planner</span>
- </a></li>
- <!--<li><a class="dropdown-item" href="/-/actions">
- <img src="/assets/icons/actions.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Actions database</span>
+ <span style="vertical-align: middle;"><?= $pages["fronting"]["name"] ?></span>
</a></li>
- <li><a class="dropdown-item" href="/-/rules">
- <img src="/assets/icons/rules.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Systems rules</span>
+ <li><a class="dropdown-item" href="/-/docs">
+ <img src="/assets/icons/docs.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
+ <span style="vertical-align: middle;"><?= $pages["docs"]["name"] ?></span>
</a></li>
- <li><a class="dropdown-item" href="/-/nicknames">
- <img src="/assets/icons/nicknames.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Relationships nicknames</span>
- </a></li>
- <li><a class="dropdown-item" href="/-/together">
- <img src="/assets/icons/together.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Watch Together</span>
- </a></li>-->
<li><a class="dropdown-item" href="/-/travelling">
<img src="/assets/icons/travel.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">System travels manager</span>
- </a></li>
- <!--<li><a class="dropdown-item" href="/-/splitting">
- <img src="/assets/icons/form.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Members by splitting date</span>
+ <span style="vertical-align: middle;"><?= $pages["travelling"]["name"] ?></span>
</a></li>
- <li><a class="dropdown-item" href="/-/bitset">
- <img src="/assets/icons/bitset.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Bitset calculator</span>
- </a></li>-->
<li><hr class="dropdown-divider"></li>
<li><h5 class="dropdown-header">Debugging</h5></li>
<li><a class="dropdown-item" href="/-/debug">
<img src="/assets/icons/debug.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Data updater debugging</span>
+ <span style="vertical-align: middle;"><?= $pages["debug"]["name"] ?></span>
</a></li>
<li><a class="dropdown-item" href="/-/score">
<img src="/assets/icons/score.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Score system testing</span>
+ <span style="vertical-align: middle;"><?= $pages["score"]["name"] ?></span>
</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="/-/logout">
<img src="/assets/icons/logout.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
- <span style="vertical-align: middle;">Logout</span>
+ <span style="vertical-align: middle;"><?= $pages["logout"]["name"] ?></span>
</a></li>
</ul>
</li>
@@ -829,8 +863,8 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
</a></li>
<?php
- $subsystems = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-subsystems.json"), true);
- $subsystemsNotMember = array_values(array_filter($subsystems, function ($i) {
+ $subsystems1 = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-subsystems.json"), true);
+ $subsystemsNotMember = array_values(array_filter($subsystems1, function ($i) {
return $i["source_type"] !== "member";
}));
@@ -846,8 +880,8 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
<?php endif; ?>
<li><hr class="dropdown-divider"></li>
<li><h5 class="dropdown-header">Members</h5></li>
- <?php foreach (scoreOrder(withTravelers(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true), "ynmuc"), "ynmuc") as $member): if ($member['name'] !== "unknown" && $member['name'] !== "fusion"): ?>
- <li><a class="dropdown-item" href="/cloudburst/<?= $member['name'] ?>">
+ <?php foreach (scoreOrder(withTravelers(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true), "ynmuc"), "ynmuc") as $member): if ($member['name'] !== "unknown" && $member['name'] !== "fusion" && $member['name'] !== "new"): ?>
+ <li><a class="dropdown-item" href="/<?= $member['name'] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" alt="" style="width:24px;vertical-align: middle;">
<span style="vertical-align: middle;"><?= $member['display_name'] ?? $member['name'] ?></span>
</a></li>
@@ -864,10 +898,27 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ical/main.php";
<img src="/assets/icons/about.svg" class="dropdown-icon" alt="" style="width:24px;vertical-align: middle;">
<span style="vertical-align: middle;">About us</span>
</a></li>
+ <?php
+
+ $subsystems1 = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-subsystems.json"), true);
+ $subsystemsNotMember = array_values(array_filter($subsystems1, function ($i) {
+ return $i["source_type"] !== "member";
+ }));
+
+ if (count($subsystemsNotMember) > 0): ?>
+ <li><hr class="dropdown-divider"></li>
+ <li><h5 class="dropdown-header">Subsystems</h5></li>
+ <?php foreach ($subsystemsNotMember as $subsystem): $ssData = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-subsystem-" . $subsystem['source'] . ".json"), true); ?>
+ <li><a class="dropdown-item" href="/raindrops/-/subsystem/<?= $subsystem['source'] ?>">
+ <img src="/assets/uploads/ss-<?= $subsystem['source'] ?>.png" alt="" style="border-radius:5px;width:24px;vertical-align: middle;">
+ <span style="vertical-align: middle;"><?= $ssData['name'] ?? $subsystem['source'] ?></span>
+ </a></li>
+ <?php endforeach; ?>
+ <?php endif; ?>
<li><hr class="dropdown-divider"></li>
<li><h5 class="dropdown-header">Members</h5></li>
- <?php foreach (scoreOrder(withTravelers(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true), "gdapd"), "gdapd") as $member): if ($member['name'] !== "unknown" && $member['name'] !== "fusion"): ?>
- <li><a class="dropdown-item" href="/raindrops/<?= $member['name'] ?>">
+ <?php foreach (scoreOrder(withTravelers(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true), "gdapd"), "gdapd") as $member): if ($member['name'] !== "unknown" && $member['name'] !== "fusion" && $member['name'] !== "new"): ?>
+ <li><a class="dropdown-item" href="/<?= $member['name'] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" alt="" style="width:24px;vertical-align: middle;">
<span style="vertical-align: middle;"><?= $member['display_name'] ?? $member['name'] ?></span>
</a></li>
diff --git a/includes/init.php b/includes/init.php
new file mode 100644
index 0000000..71d7def
--- /dev/null
+++ b/includes/init.php
@@ -0,0 +1,18 @@
+<?php
+
+global $title;
+global $toplevel;
+global $pages;
+
+$pages = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/pages.json"), true);
+require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/session.php"; global $isLoggedIn;
+
+if (in_array($toplevel, array_keys($pages))) {
+ $title = $pages[$toplevel]["name"];
+
+ if ($pages[$toplevel]["admin"]) {
+ if (!$isLoggedIn) header("Location: /-/login/?return=$toplevel") and die();
+ }
+} else {
+ $title = $toplevel;
+} \ No newline at end of file
diff --git a/includes/keywords.php b/includes/keywords.php
index 4d6afaf..270d905 100644
--- a/includes/keywords.php
+++ b/includes/keywords.php
@@ -7,7 +7,7 @@ function getKeyWords() {
foreach ($actions as $action) {
$base = strtolower($action["name"]);
- $addKeywords = $action["keywords"];
+ $addKeywords = $action["keywords"] ?? [];
$keywords = [
$base,
ucfirst($base),
@@ -44,7 +44,7 @@ function getKeyWords() {
foreach ($toys as $toy) {
$base = strtolower($toy["name"]);
- $addKeywords = $toy["keywords"];
+ $addKeywords = $toy["keywords"] ?? [];
$keywords = [
$base,
ucfirst($base),
@@ -82,17 +82,27 @@ function getKeyWords() {
$keywords = [];
foreach ($pages as $page) {
foreach ($page["keywords"] as $keyword) {
- $keywords[$keyword] = $page["link"];
+ $keywords[] = [
+ "keyword" => $keyword,
+ "link" => $page["link"]
+ ];
}
}
+ uasort($keywords, function ($a, $b) {
+ return strlen($b["keyword"]) - strlen($a["keyword"]);
+ });
+
return $keywords;
}
function replaceKeyWords(string $input): string {
$keywords = getKeyWords();
- foreach ($keywords as $keyword => $url) {
+ foreach ($keywords as $data) {
+ $keyword = $data["keyword"];
+ $url = $data["link"];
+
$input = str_replace($keyword, "<a href='$url'>$keyword</a>", $input);
}
diff --git a/includes/member.php b/includes/member.php
index f8050b0..d0120d5 100644
--- a/includes/member.php
+++ b/includes/member.php
@@ -10,35 +10,6 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
$travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling.json"), true);
-function timeAgo($time): string {
- if (!is_numeric($time)) {
- $time = strtotime($time);
- }
-
- $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
- $lengths = array("60", "60", "24", "7", "4.35", "12", "100");
-
- $now = time();
-
- $difference = $now - $time;
- if ($difference <= 10 && $difference >= 0) {
- return $tense = "now";
- } elseif ($difference > 0) {
- $tense = "ago";
- } else {
- $tense = "later";
- }
-
- for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
- $difference /= $lengths[$j];
- }
-
- $difference = round($difference);
-
- $period = $periods[$j] . ($difference >1 ? "s" :'');
- return "{$difference} {$period} {$tense}";
-}
-
if ($memberData["name"] !== "unknown" && $memberData["name"] !== "fusion") {
$metadata = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "-" . $memberID . "-metadata.json"), true));
}
@@ -78,44 +49,83 @@ if ($memberData["name"] === "fusion") {
<div id="member-banner"></div>
<div id="member-details" class="<?= $isLoggedIn ? 'member-details-loggedIn' : '' ?>" style="<?php if (!$isLoggedIn): ?>grid-template-columns: repeat(3, 1fr);<?php endif; ?> border-color: <?= isset($memberData["color"]) ? '#' . $memberData["color"] : "transparent" ?>">
<div>
- <b>Food:</b>
+ <b>Food:</b><span class="member-small-separator"><br></span>
<?= match ($metadata["food"]) {
- 0 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"])) . " species indicates that " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"]) . ' ' . (getMemberPronouns($memberData["pronouns"])["third"] ? "doesn&apos;t" : "don&apos;t") . " need to eat food, therefore " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"]) . " can eat all foods.'>Doesn't need</span>",
- 1 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"])) . " can&apos;t eat fish or meat.'>Can't eat animals</span>",
- 2 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"])) . " can&apos;t eat meat, but can eat fish.'>Can't eat meat</span>",
- 3 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"])) . " can eat all foods, meat and fish included.'>No restrictions</span>",
+ 0 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"])) . " species indicates that " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"]) . ' ' . (getMemberPronouns($memberData["pronouns"])["third"] ? "doesn&apos;t" : "don&apos;t") . " need to eat food, therefore " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"]) . " can eat all foods.'>Not needed</span>",
+ 1 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"])) . " can&apos;t eat fish or meat.'>Not animals</span>",
+ 2 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"])) . " can&apos;t eat meat, but can eat fish.'>Not meat</span>",
+ 3 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"])) . " can eat all foods, meat and fish included.'>All</span>",
} ?>
</div>
<div>
- <b>Memory access:</b>
+ <b>Shared memory:</b><span class="member-small-separator"><br></span>
<?= match ($metadata["shared_memory"]) {
- 0 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " doesn&apos;t directly share" : " don&apos;t directly share") . " memory with " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " headmates, but is able to (slowly) query it if that is needed.'>No direct access</span>",
- 1 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " doesn&apos;t directly shares" : " don&apos;t directly share") . " all memories with " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " headmates, but may be able to share certain memories and/or share memories at will.'>Partial direct access</span>",
- 2 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " shares" : " share") . " all memories with " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " headmates.'>Full direct access</span>",
+ 0 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " doesn&apos;t directly share" : " don&apos;t directly share") . " memory with " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " headmates, but is able to (slowly) query it if that is needed.'>None</span>",
+ 1 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " doesn&apos;t directly shares" : " don&apos;t directly share") . " all memories with " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " headmates, but may be able to share certain memories and/or share memories at will.'>Partial</span>",
+ 2 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " shares" : " share") . " all memories with " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " headmates.'>Full</span>",
} ?>
</div>
<div>
- <b>Magic:</b>
+ <b>Magic:</b><span class="member-small-separator"><br></span>
<?= match ($metadata["magic"]) {
- 0 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " is unable to use magic at all.'>Can't use magic</span>",
- 1 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can use magic in rare cases, such as when somepony else is pouring magic into " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["object"]) . " or when a physical event occurs.'>Can use magic in some cases</span>",
- 2 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can cast spells using " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " horn.'>Can use a horn</span>",
- 3 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can cast spells using " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " wings.'>Can use wings</span>",
- 4 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can cast spells using both " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " horn and wings.'>Can use a horn and wings</span>",
- 5 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can cast spells using another part of " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body that is neither a horn or wings.'>Can cast spells</span>",
+ 0 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " is unable to use magic at all.'>None</span>",
+ 1 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can use magic in rare cases, such as when somepony else is pouring magic into " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["object"]) . " or when a physical event occurs.'>In some cases</span>",
+ 2 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can cast spells using " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " horn.'>Horn</span>",
+ 3 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can cast spells using " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " wings.'>Wings</span>",
+ 4 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can cast spells using both " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " horn and wings.'>Horn and wings</span>",
+ 5 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " can cast spells using another part of " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body that is neither a horn or wings.'>Yes</span>",
} ?>
</div>
<?php if ($isLoggedIn): ?>
<div>
- <b>Sensitivity:</b>
+ <b>Sensitivity:</b><span class="member-small-separator"><br></span>
<?= match ($metadata["sensitivity"]) {
- 0 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " does" : " do") . " not have sensitive spots on " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body.'>Not sensitive</span>",
- 1 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " may have (a) sensitive spot·s on " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body.'>May be sensitive</span>",
- 2 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " has" : " have") . " (a) sensitive spot·s on " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body, and playing with it/them will make " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["object"]) . " feel affectionate: extremely safe and cared for.'>Affectionately sensitive</span>",
- 3 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " has" : " have") . " (a) sensitive spot·s on " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body, and playing with it/them will make " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["object"]) . " feel sexually pleasured.'>Sexually sensitive</span>",
+ 0 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " does" : " do") . " not have sensitive spots on " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body.'>None</span>",
+ 1 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " may have (a) sensitive spot·s on " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body.'>Maybe</span>",
+ 2 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " has" : " have") . " (a) sensitive spot·s on " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body, and playing with it/them will make " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["object"]) . " feel affectionate: extremely safe and cared for.'>Affectionate</span>",
+ 3 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " has" : " have") . " (a) sensitive spot·s on " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body, and playing with it/them will make " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["object"]) . " feel sexually pleasured.'>Sexual</span>",
4 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . (getMemberPronouns($memberData["pronouns"])["third"] ? " has" : " have") . " (a) sensitive spot·s on " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " body, and playing with it/them will make " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["object"]) . " feel affectionate or sexually pleasured.'>Affectionate and sexual</span>",
} ?>
</div>
+ <div>
+ <b>Age:</b><span class="member-small-separator"><br></span>
+ <?php if (!isset($metadata["birth"]["year"])): ?>
+ <?php if ($metadata["birth"]["age"] <= 0): ?>
+ -
+ <?php else: ?>
+ <?= "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . str_replace("'", "&apos;", getMemberPronouns($memberData["pronouns"])["third"] ? " doesn't" : " don't") . " age like the body does, making " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["object"]) . " stay " . $metadata["birth"]["age"] . " years old for " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["possessive_det"]) . " entire life.'>" . $metadata["birth"]["age"] . "* years old</span>" ?>
+ <?php endif; ?>
+ <?php else: ?>
+ <?php if ($metadata["birth"]["year"] <= 2000): ?>
+ -
+ <?php else: ?>
+ <?php
+
+ $birthdate = $metadata["birth"]["year"] . date('-m-d');
+ if (isset($metadata["birth"]["date"]) && trim($metadata["birth"]["date"]) !== "" && $metadata["birth"]["date"] !== "01-01") {
+ $birthdate = $metadata["birth"]["year"] . "-" . $metadata["birth"]["date"];
+ }
+
+ $age = floor((time() - strtotime($birthdate)) / 31557600);
+ $birthday = "as time passes";
+
+ if (isset($metadata["birth"]["date"]) && trim($metadata["birth"]["date"]) !== "" && $metadata["birth"]["date"] !== "01-01") {
+ $birthday = "every " . date('F jS', strtotime(date('Y') . "-" . $metadata["birth"]["date"]));
+ }
+
+ ?>
+ <?= "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst(getMemberPronouns($memberData['pronouns'])["subjective"])) . " age" . str_replace("'", "&apos;", getMemberPronouns($memberData["pronouns"])["third"] ? "s" : "") . " like the body does, making " . str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["object"]) . " stay " . $age . " years old for now, having this age change $birthday.'>" . $age . " years old</span>" ?>
+ <?php endif; ?>
+ <?php endif; ?>
+ </div>
+ <div>
+ <b>Birthday:</b><span class="member-small-separator"><br></span>
+ <?php if (isset($metadata["birth"]["date"]) && trim($metadata["birth"]["date"]) !== "" && $metadata["birth"]["date"] !== "01-01"): ?>
+ <?= date('F jS', strtotime(date('Y') . "-" . $metadata["birth"]["date"])) ?>
+ <?php else: ?>
+ -
+ <?php endif; ?>
+ </div>
<?php endif; ?>
</div>
</div>
@@ -141,6 +151,7 @@ if ($memberData["name"] === "fusion") {
<ul>
<li><code><?= $_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-metadata.json" ?></code> (<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-metadata.json") ? filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-metadata.json") . " bytes" : "not found" ?>)</li>
<li><code><?= $_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-content.html" ?></code> (<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-content.html") ? filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-content.html") . " bytes" : "not found" ?>)</li>
+ <li><code><?= $_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html" ?></code> (<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html") ? filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html") . " bytes" : "not found" ?>)</li>
</ul>
</li>
<li><b>Date added:</b> <?= date('l j F Y', strtotime($memberData["created"])) ?> (<?= timeAgo($memberData["created"]) ?>, <code><?= $memberData["created"] ?></code>)</li>
@@ -189,6 +200,12 @@ if ($memberData["name"] === "fusion") {
?></ul></li>
</ul>
+
+ <br>
+ <div style="filter:invert(0);" class="alert alert-warning">
+ <b>AI-generated page:</b>
+ <?php require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/ai.php"; ?>
+ </div>
</details>
</div>
<?php endif; ?>
@@ -197,6 +214,14 @@ if ($memberData["name"] === "fusion") {
<?= getMiniName($memberData["display_name"] ?? $memberData["name"]) ?> is visiting the <?= $systemID === "ynmuc" ? "Raindrops System" : "Cloudburst System" ?> since <?= timeAgo($travelling[$memberID]["history"][count($travelling[$memberID]["history"]) - 1]["start"]) ?>, therefore <?= getMemberPronouns($memberData["pronouns"])["subjective"] ?> <?= getMemberPronouns($memberData["pronouns"])["third"] ? "is" : "are" ?> currently not in the <?= $systemCommonName ?>.
</div>
<?php endif; ?>
+ <?php if ($memberData["name"] === "new"): ?>
+ <div class="alert alert-secondary">
+ <p>Hello there!</p>
+ <p>I'm currently a new headmate slowly figuring myself out.</p>
+ <p>Give me some time to figure myself out and see this page change as I find new stuff about my identity. Don't be too worried if I accidentally get pushed to front, it's something that can happen sometimes.</p>
+ <span>Thanks!</span>
+ </div>
+ <?php endif; ?>
<div id="page-content">
<?php if ($memberData["name"] === "unknown"): ?>
@@ -222,9 +247,20 @@ if ($memberData["name"] === "fusion") {
</div>
<?php else: ?>
<?php global $isLoggedIn; if ($isLoggedIn): ?>
- <small style="opacity:.5;display:block;">(<a href="/-/edit/<?= $system ?>/<?= $memberData['name'] ?>">edit</a>)</small>
+ <small style="opacity:.5;display:block;">(edit: <a href="/-/edit/<?= $system ?>/<?= $memberData['name'] ?>">public</a>, <a href="/-/edit-private/<?= $system ?>/<?= $memberData['name'] ?>">private</a>)</small>
+ <?php endif; ?>
+
+ <?php if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html") && $isLoggedIn): ?>
+ <?= file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-private.html") ?>
+ <hr>
+ <?php endif; ?>
+
+ <?php if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-content.html")): ?>
+ <?= file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-content.html") ?>
+ <?php else: ?>
+ <p class="text-muted">This page is automatically generated and may not be 100% accurate.</p>
+ <?php require $_SERVER['DOCUMENT_ROOT'] . "/includes/ai.php"; ?>
<?php endif; ?>
- <?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-content.html") ? file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$memberID-content.html") : "<i>This page is empty.</i>" ?>
<?php endif; ?>
</div>
</div>
diff --git a/includes/member/hierarchy.php b/includes/member/hierarchy.php
index 39045b3..301bd1c 100644
--- a/includes/member/hierarchy.php
+++ b/includes/member/hierarchy.php
@@ -10,36 +10,6 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
$travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling.json"), true);
-function timeAgo($time): string
-{
- if (!is_numeric($time)) {
- $time = strtotime($time);
- }
-
- $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
- $lengths = array("60", "60", "24", "7", "4.35", "12", "100");
-
- $now = time();
-
- $difference = $now - $time;
- if ($difference <= 10 && $difference >= 0) {
- return $tense = "now";
- } elseif ($difference > 0) {
- $tense = "ago";
- } else {
- $tense = "later";
- }
-
- for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths) - 1; $j++) {
- $difference /= $lengths[$j];
- }
-
- $difference = round($difference);
-
- $period = $periods[$j] . ($difference > 1 ? "s" : '');
- return "{$difference} {$period} {$tense}";
-}
-
$metadata = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "-" . $memberID . "-metadata.json"), true));
$allMembers = scoreOrder(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $systemID . "-members.json"), true), $systemID);
diff --git a/includes/pages.json b/includes/pages.json
new file mode 100644
index 0000000..4fc023b
--- /dev/null
+++ b/includes/pages.json
@@ -0,0 +1,162 @@
+{
+ "actions": {
+ "name": "Actions database",
+ "short": "Actions",
+ "admin": true
+ },
+ "api": {
+ "name": "API",
+ "short": null,
+ "admin": false
+ },
+ "app": {
+ "name": "Mobile application",
+ "short": null,
+ "admin": false
+ },
+ "bitset": {
+ "name": "Bitset calculator",
+ "short": "Bitset",
+ "admin": true
+ },
+ "byfront": {
+ "name": "Members by last fronted",
+ "short": "Last fronts",
+ "admin": true
+ },
+ "dashboard": {
+ "name": "Dashboard",
+ "short": null,
+ "admin": true
+ },
+ "debug": {
+ "name": "Data updater debugging",
+ "short": null,
+ "admin": false
+ },
+ "demo": {
+ "name": "Demo interface",
+ "short": null,
+ "admin": false
+ },
+ "docs": {
+ "name": "Documents",
+ "short": "Docs",
+ "admin": true
+ },
+ "disclaimers": {
+ "name": "Disclaimers",
+ "short": null,
+ "admin": false
+ },
+ "edit": {
+ "name": "Editor",
+ "short": null,
+ "admin": true
+ },
+ "edit-private": {
+ "name": "Editor (private)",
+ "short": null,
+ "admin": true
+ },
+ "emergency": {
+ "name": "Emergency alert",
+ "short": null,
+ "admin": true
+ },
+ "fronting": {
+ "name": "Front planner",
+ "short": null,
+ "admin": true
+ },
+ "home": {
+ "name": "Home",
+ "short": null,
+ "admin": false
+ },
+ "login": {
+ "name": "Login",
+ "short": null,
+ "admin": false
+ },
+ "logout": {
+ "name": "Logout",
+ "short": null,
+ "admin": false
+ },
+ "nicknames": {
+ "name": "Relations nicknames",
+ "short": "Nicknames",
+ "admin": true
+ },
+ "page": {
+ "name": "Member/system page",
+ "short": null,
+ "admin": false
+ },
+ "parser": {
+ "name": "Message parser",
+ "short": null,
+ "admin": false
+ },
+ "pleasure": {
+ "name": "Pleasure alert",
+ "short": null,
+ "admin": true
+ },
+ "prefix": {
+ "name": "Prefix generator",
+ "short": null,
+ "admin": false
+ },
+ "relations": {
+ "name": "Relations",
+ "short": null,
+ "admin": false
+ },
+ "rules": {
+ "name": "Systems rules",
+ "short": "Rules",
+ "admin": true
+ },
+ "score": {
+ "name": "Score system testing",
+ "short": null,
+ "admin": true
+ },
+ "splitting": {
+ "name": "Members by splitting date",
+ "short": "Splits",
+ "admin": true
+ },
+ "terminology": {
+ "name": "Terminology",
+ "short": null,
+ "admin": false
+ },
+ "together": {
+ "name": "Watch Together",
+ "short": "Together",
+ "admin": true
+ },
+ "together-dev": {
+ "name": "Watch Together (dev)",
+ "short": null,
+ "admin": true
+ },
+ "toys": {
+ "name": "Toys database",
+ "short": "Toys",
+ "admin": true
+ },
+ "travelling": {
+ "name": "System travels manager",
+ "short": null,
+ "admin": true
+ },
+ "wakeup": {
+ "name": "Wake-up alert",
+ "short": null,
+ "admin": true
+ }
+} \ No newline at end of file
diff --git a/includes/planner.php b/includes/planner.php
index 64d87e4..8644b25 100644
--- a/includes/planner.php
+++ b/includes/planner.php
@@ -12,90 +12,18 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php";
$cloudburst = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-planner.json"), true);
$raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-planner.json"), true);
-?>
-
-<h2>Front planner</h2>
-<table id="planner">
- <tbody>
- <tr class="planner-day">
- <td colspan="4" id="planner-header-0">Today</td>
- <?php
-
- if (!$cloudburst[date('Y-m-d')]) $cloudburst[date('Y-m-d')] = [];
- $dayCloudburst = $cloudburst[date('Y-m-d')];
- if (!$raindrops[date('Y-m-d')]) $raindrops[date('Y-m-d')] = [];
- $dayRaindrops = $raindrops[date('Y-m-d')];
-
- $index = 0;
- $lengthCloudburst = count($dayCloudburst);
- $lengthRaindrops = count($dayRaindrops);
- $biggest = max($lengthCloudburst, $lengthRaindrops);
-
- ?>
- </tr>
- <tr class="planner-header">
- <td colspan="2">Cloudburst System</td>
- <td colspan="2">Raindrops System</td>
- </tr>
- <?php for ($i = 0; $i <= $biggest; $i++): ?>
- <tr class="planner-member">
- <?php if (isset($dayCloudburst[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <td class="planner-link">
- <?php $member = getSystemMember("ynmuc", $dayCloudburst[$index]); ?>
- <a class="member-link" onclick="openEditFronter('cloudburst', <?= $index ?>, '<?= date('Y-m-d') ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayCloudburst)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('cloudburst', 0);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- <?php if (isset($dayRaindrops[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <?php $member = getSystemMember("gdapd", $dayRaindrops[$index]); ?>
- <td class="planner-link">
- <a class="member-link" onclick="openEditFronter('raindrops', <?= $index ?>, '<?= date('Y-m-d') ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayRaindrops)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('raindrops', 0);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- </tr>
- <?php $index++; endfor; ?>
- <tr class="planner-day planner-end-of-day">
- <td colspan="4">
- <?php if (count($dayCloudburst) > 0 && count($dayRaindrops) > 0): ?>
- <?= getMiniName(getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["display_name"] ?? getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["name"]) ?> will sleep with <?= getMiniName(getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["display_name"] ?? getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["name"]) ?>
- <?php else: ?>
- Unable to calculate who will sleep with who
- <?php endif; ?>
- </td>
- </tr>
- <tr class="planner-separator"></tr>
-
+function day($display, $diff): void { global $cloudburst; global $raindrops; ?>
+ <?php if (!isset($display)) {
+ $display = date('l', time() + (86400 * $diff));
+ }?>
<tr class="planner-day" id="planner-header-1">
- <td colspan="4">Tomorrow</td>
+ <td colspan="4"><?= $display ?></td>
<?php
- if (!$cloudburst[date('Y-m-d', time() + 86400)]) $cloudburst[date('Y-m-d', time() + 86400)] = [];
- $dayCloudburst = $cloudburst[date('Y-m-d', time() + 86400)];
- if (!$raindrops[date('Y-m-d', time() + 86400)]) $raindrops[date('Y-m-d', time() + 86400)] = [];
- $dayRaindrops = $raindrops[date('Y-m-d', time() + 86400)];
+ if (!isset($cloudburst[date('Y-m-d', time() + (86400 * $diff))])) $cloudburst[date('Y-m-d', time() + (86400 * $diff))] = [];
+ $dayCloudburst = $cloudburst[date('Y-m-d', time() + (86400 * $diff))];
+ if (!isset($raindrops[date('Y-m-d', time() + (86400 * $diff))])) $raindrops[date('Y-m-d', time() + (86400 * $diff))] = [];
+ $dayRaindrops = $raindrops[date('Y-m-d', time() + (86400 * $diff))];
$index = 0;
$lengthCloudburst = count($dayCloudburst);
@@ -115,12 +43,16 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
<?= $index + 1 ?>
</td>
<td class="planner-link">
- <?php $member = getSystemMember("ynmuc", $dayCloudburst[$index]); ?>
- <a class="member-link" onclick="openEditFronter('cloudburst', <?= $index ?>, '<?= date('Y-m-d', time() + 86400) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
+ <?php $member = getMemberWithoutSystem($dayCloudburst[$index]); ?>
+ <?php if ($member["name"] === "fusion"): ?>
+ <a class="member-link" onclick="openEditFronter('cloudburst', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * $diff)) ?>')"><img src="/assets/logo/logo.png" style="width:24px;"> <span class="text-muted merge-desktop">Multiple merged members</span><span class="text-muted merge-mobile">Merge</span></a>
+ <?php else: ?>
+ <a class="member-link" onclick="openEditFronter('cloudburst', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * $diff)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
+ <?php endif; ?>
</td>
<?php elseif ($index === count($dayCloudburst)): ?>
<td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('cloudburst', 1);" class="planner-add-link">
+ <a href="#" onclick="addFronter('cloudburst', <?= $diff ?>);" class="planner-add-link">
<img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
<span class="planner-add-text">Add new fronter</span>
</a>
@@ -132,13 +64,17 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
<td class="planner-member-id">
<?= $index + 1 ?>
</td>
- <?php $member = getSystemMember("gdapd", $dayRaindrops[$index]); ?>
+ <?php $member = getMemberWithoutSystem($dayRaindrops[$index]); ?>
<td class="planner-link">
- <a class="member-link" onclick="openEditFronter('raindrops', <?= $index ?>, '<?= date('Y-m-d', time() + 86400) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
+ <?php if ($member["name"] === "fusion"): ?>
+ <a class="member-link" onclick="openEditFronter('raindrops', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * $diff)) ?>')"><img src="/assets/logo/logo.png" style="width:24px;"> <span class="text-muted merge-desktop">Multiple merged members</span><span class="text-muted merge-mobile">Merge</span></a>
+ <?php else: ?>
+ <a class="member-link" onclick="openEditFronter('raindrops', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * $diff)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
+ <?php endif; ?>
</td>
<?php elseif ($index === count($dayRaindrops)): ?>
<td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('raindrops', 1);" class="planner-add-link">
+ <a href="#" onclick="addFronter('raindrops', <?= $diff ?>);" class="planner-add-link">
<img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
<span class="planner-add-text">Add new fronter</span>
</a>
@@ -151,368 +87,27 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
<tr class="planner-day planner-end-of-day">
<td colspan="4">
<?php if (count($dayCloudburst) > 0 && count($dayRaindrops) > 0): ?>
- <?= getMiniName(getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["display_name"] ?? getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["name"]) ?> will sleep with <?= getMiniName(getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["display_name"] ?? getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["name"]) ?>
+ <?= getMiniName(getMemberWithoutSystem($dayCloudburst[count($dayCloudburst) - 1])["display_name"] ?? getMemberWithoutSystem($dayCloudburst[count($dayCloudburst) - 1])["name"]) ?> will sleep with <?= getMiniName(getMemberWithoutSystem($dayRaindrops[count($dayRaindrops) - 1])["display_name"] ?? getMemberWithoutSystem($dayRaindrops[count($dayRaindrops) - 1])["name"]) ?>
<?php else: ?>
Unable to calculate who will sleep with who
<?php endif; ?>
</td>
</tr>
<tr class="planner-separator"></tr>
+<?php
+}
+?>
- <tr class="planner-day" id="planner-header-2">
- <td colspan="4"><?= date('l', time() + (86400 * 2)) ?></td>
- <?php
-
- if (!$cloudburst[date('Y-m-d', time() + (86400 * 2))]) $cloudburst[date('Y-m-d', time() + (86400 * 2))] = [];
- $dayCloudburst = $cloudburst[date('Y-m-d', time() + (86400 * 2))];
- if (!$raindrops[date('Y-m-d', time() + (86400 * 2))]) $raindrops[date('Y-m-d', time() + (86400 * 2))] = [];
- $dayRaindrops = $raindrops[date('Y-m-d', time() + (86400 * 2))];
-
- $index = 0;
- $lengthCloudburst = count($dayCloudburst);
- $lengthRaindrops = count($dayRaindrops);
- $biggest = max($lengthCloudburst, $lengthRaindrops);
-
- ?>
- </tr>
- <tr class="planner-header">
- <td colspan="2">Cloudburst System</td>
- <td colspan="2">Raindrops System</td>
- </tr>
- <?php for ($i = 0; $i <= $biggest; $i++): ?>
- <tr class="planner-member">
- <?php if (isset($dayCloudburst[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <td class="planner-link">
- <?php $member = getSystemMember("ynmuc", $dayCloudburst[$index]); ?>
- <a class="member-link" onclick="openEditFronter('cloudburst', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 2)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayCloudburst)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('cloudburst', 2);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- <?php if (isset($dayRaindrops[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <?php $member = getSystemMember("gdapd", $dayRaindrops[$index]); ?>
- <td class="planner-link">
- <a class="member-link" onclick="openEditFronter('raindrops', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 2)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayRaindrops)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('raindrops', 2);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- </tr>
- <?php $index++; endfor; ?>
- <tr class="planner-day planner-end-of-day">
- <td colspan="4">
- <?php if (count($dayCloudburst) > 0 && count($dayRaindrops) > 0): ?>
- <?= getMiniName(getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["display_name"] ?? getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["name"]) ?> will sleep with <?= getMiniName(getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["display_name"] ?? getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["name"]) ?>
- <?php else: ?>
- Unable to calculate who will sleep with who
- <?php endif; ?>
- </td>
- </tr>
- <tr class="planner-separator"></tr>
-
- <tr class="planner-day">
- <td colspan="4" id="planner-header-3"><?= date('l', time() + (86400 * 3)) ?></td>
- <?php
-
- if (!$cloudburst[date('Y-m-d', time() + (86400 * 3))]) $cloudburst[date('Y-m-d', time() + (86400 * 3))] = [];
- $dayCloudburst = $cloudburst[date('Y-m-d', time() + (86400 * 3))];
- if (!$raindrops[date('Y-m-d', time() + (86400 * 3))]) $raindrops[date('Y-m-d', time() + (86400 * 3))] = [];
- $dayRaindrops = $raindrops[date('Y-m-d', time() + (86400 * 3))];
-
- $index = 0;
- $lengthCloudburst = count($dayCloudburst);
- $lengthRaindrops = count($dayRaindrops);
- $biggest = max($lengthCloudburst, $lengthRaindrops);
-
- ?>
- </tr>
- <tr class="planner-header">
- <td colspan="2">Cloudburst System</td>
- <td colspan="2">Raindrops System</td>
- </tr>
- <?php for ($i = 0; $i <= $biggest; $i++): ?>
- <tr class="planner-member">
- <?php if (isset($dayCloudburst[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <td class="planner-link">
- <?php $member = getSystemMember("ynmuc", $dayCloudburst[$index]); ?>
- <a class="member-link" onclick="openEditFronter('cloudburst', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 3)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayCloudburst)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('cloudburst', 3);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- <?php if (isset($dayRaindrops[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <?php $member = getSystemMember("gdapd", $dayRaindrops[$index]); ?>
- <td class="planner-link">
- <a class="member-link" onclick="openEditFronter('raindrops', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 3)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayRaindrops)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('raindrops', 3);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- </tr>
- <?php $index++; endfor; ?>
- <tr class="planner-day planner-end-of-day">
- <td colspan="4">
- <?php if (count($dayCloudburst) > 0 && count($dayRaindrops) > 0): ?>
- <?= getMiniName(getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["display_name"] ?? getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["name"]) ?> will sleep with <?= getMiniName(getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["display_name"] ?? getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["name"]) ?>
- <?php else: ?>
- Unable to calculate who will sleep with who
- <?php endif; ?>
- </td>
- </tr>
- <tr class="planner-separator"></tr>
-
- <tr class="planner-day">
- <td colspan="4" id="planner-header-4"><?= date('l', time() + (86400 * 4)) ?></td>
- <?php
-
- if (!$cloudburst[date('Y-m-d', time() + (86400 * 4))]) $cloudburst[date('Y-m-d', time() + (86400 * 4))] = [];
- $dayCloudburst = $cloudburst[date('Y-m-d', time() + (86400 * 4))];
- if (!$raindrops[date('Y-m-d', time() + (86400 * 4))]) $raindrops[date('Y-m-d', time() + (86400 * 4))] = [];
- $dayRaindrops = $raindrops[date('Y-m-d', time() + (86400 * 4))];
-
- $index = 0;
- $lengthCloudburst = count($dayCloudburst);
- $lengthRaindrops = count($dayRaindrops);
- $biggest = max($lengthCloudburst, $lengthRaindrops);
-
- ?>
- </tr>
- <tr class="planner-header">
- <td colspan="2">Cloudburst System</td>
- <td colspan="2">Raindrops System</td>
- </tr>
- <?php for ($i = 0; $i <= $biggest; $i++): ?>
- <tr class="planner-member">
- <?php if (isset($dayCloudburst[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <td class="planner-link">
- <?php $member = getSystemMember("ynmuc", $dayCloudburst[$index]); ?>
- <a class="member-link" onclick="openEditFronter('cloudburst', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 4)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayCloudburst)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('cloudburst', 4);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- <?php if (isset($dayRaindrops[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <?php $member = getSystemMember("gdapd", $dayRaindrops[$index]); ?>
- <td class="planner-link">
- <a class="member-link" onclick="openEditFronter('raindrops', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 4)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayRaindrops)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('raindrops', 4);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- </tr>
- <?php $index++; endfor; ?>
- <tr class="planner-day planner-end-of-day">
- <td colspan="4">
- <?php if (count($dayCloudburst) > 0 && count($dayRaindrops) > 0): ?>
- <?= getMiniName(getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["display_name"] ?? getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["name"]) ?> will sleep with <?= getMiniName(getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["display_name"] ?? getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["name"]) ?>
- <?php else: ?>
- Unable to calculate who will sleep with who
- <?php endif; ?>
- </td>
- </tr>
- <tr class="planner-separator"></tr>
-
- <tr class="planner-day">
- <td colspan="4" id="planner-header-5"><?= date('l', time() + (86400 * 5)) ?></td>
- <?php
-
- if (!$cloudburst[date('Y-m-d', time() + (86400 * 5))]) $cloudburst[date('Y-m-d', time() + (86400 * 5))] = [];
- $dayCloudburst = $cloudburst[date('Y-m-d', time() + (86400 * 5))];
- if (!$raindrops[date('Y-m-d', time() + (86400 * 5))]) $raindrops[date('Y-m-d', time() + (86400 * 5))] = [];
- $dayRaindrops = $raindrops[date('Y-m-d', time() + (86400 * 5))];
-
- $index = 0;
- $lengthCloudburst = count($dayCloudburst);
- $lengthRaindrops = count($dayRaindrops);
- $biggest = max($lengthCloudburst, $lengthRaindrops);
-
- ?>
- </tr>
- <tr class="planner-header">
- <td colspan="2">Cloudburst System</td>
- <td colspan="2">Raindrops System</td>
- </tr>
- <?php for ($i = 0; $i <= $biggest; $i++): ?>
- <tr class="planner-member">
- <?php if (isset($dayCloudburst[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <td class="planner-link">
- <?php $member = getSystemMember("ynmuc", $dayCloudburst[$index]); ?>
- <a class="member-link" onclick="openEditFronter('cloudburst', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 5)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayCloudburst)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('cloudburst', 5);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- <?php if (isset($dayRaindrops[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <?php $member = getSystemMember("gdapd", $dayRaindrops[$index]); ?>
- <td class="planner-link">
- <a class="member-link" onclick="openEditFronter('raindrops', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 5)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayRaindrops)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('raindrops', 5);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- </tr>
- <?php $index++; endfor; ?>
- <tr class="planner-day planner-end-of-day">
- <td colspan="4">
- <?php if (count($dayCloudburst) > 0 && count($dayRaindrops) > 0): ?>
- <?= getMiniName(getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["display_name"] ?? getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["name"]) ?> will sleep with <?= getMiniName(getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["display_name"] ?? getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["name"]) ?>
- <?php else: ?>
- Unable to calculate who will sleep with who
- <?php endif; ?>
- </td>
- </tr>
- <tr class="planner-separator"></tr>
-
- <tr class="planner-day">
- <td colspan="4" id="planner-header-6"><?= date('l', time() + (86400 * 6)) ?></td>
- <?php
-
- if (!$cloudburst[date('Y-m-d', time() + (86400 * 6))]) $cloudburst[date('Y-m-d', time() + (86400 * 6))] = [];
- $dayCloudburst = $cloudburst[date('Y-m-d', time() + (86400 * 6))];
- if (!$raindrops[date('Y-m-d', time() + (86400 * 6))]) $raindrops[date('Y-m-d', time() + (86400 * 6))] = [];
- $dayRaindrops = $raindrops[date('Y-m-d', time() + (86400 * 6))];
-
- $index = 0;
- $lengthCloudburst = count($dayCloudburst);
- $lengthRaindrops = count($dayRaindrops);
- $biggest = max($lengthCloudburst, $lengthRaindrops);
-
- ?>
- </tr>
- <tr class="planner-header">
- <td colspan="2">Cloudburst System</td>
- <td colspan="2">Raindrops System</td>
- </tr>
- <?php for ($i = 0; $i <= $biggest; $i++): ?>
- <tr class="planner-member">
- <?php if (isset($dayCloudburst[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <td class="planner-link">
- <?php $member = getSystemMember("ynmuc", $dayCloudburst[$index]); ?>
- <a class="member-link" onclick="openEditFronter('cloudburst', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 6)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayCloudburst)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('cloudburst', 6);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- <?php if (isset($dayRaindrops[$index])): ?>
- <td class="planner-member-id">
- <?= $index + 1 ?>
- </td>
- <?php $member = getSystemMember("gdapd", $dayRaindrops[$index]); ?>
- <td class="planner-link">
- <a class="member-link" onclick="openEditFronter('raindrops', <?= $index ?>, '<?= date('Y-m-d', time() + (86400 * 6)) ?>')"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- </td>
- <?php elseif ($index === count($dayRaindrops)): ?>
- <td class="planner-add-inner planner-link" colspan="2">
- <a href="#" onclick="addFronter('raindrops', 6);" class="planner-add-link">
- <img src="/assets/icons/add.svg" alt="" class="planner-add-icon">
- <span class="planner-add-text">Add new fronter</span>
- </a>
- </td>
- <?php else: ?>
- <td colspan="2" class="planner-empty"></td>
- <?php endif; ?>
- </tr>
- <?php $index++; endfor; ?>
- <tr class="planner-day planner-end-of-day">
- <td colspan="4">
- <?php if (count($dayCloudburst) > 0 && count($dayRaindrops) > 0): ?>
- <?= getMiniName(getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["display_name"] ?? getSystemMember("ynmuc", $dayCloudburst[count($dayCloudburst) - 1])["name"]) ?> will sleep with <?= getMiniName(getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["display_name"] ?? getSystemMember("gdapd", $dayRaindrops[count($dayRaindrops) - 1])["name"]) ?>
- <?php else: ?>
- Unable to calculate who will sleep with who
- <?php endif; ?>
- </td>
- </tr>
- <tr class="planner-separator"></tr>
+<h2>Front planner</h2>
+<table id="planner">
+ <tbody>
+ <?php day("Today", 0) ?>
+ <?php day("Tomorrow", 1) ?>
+ <?php day(null, 2) ?>
+ <?php day(null, 3) ?>
+ <?php day(null, 4) ?>
+ <?php day(null, 5) ?>
+ <?php day(null, 6) ?>
</tbody>
</table>
@@ -637,6 +232,20 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
cursor: pointer !important;
}
+ .merge-mobile {
+ display: none;
+ }
+
+ @media (max-width: 768px) {
+ .merge-desktop {
+ display: none;
+ }
+
+ .merge-mobile {
+ display: inline;
+ }
+ }
+
</style>
<!--suppress JSUnresolvedVariable, JSUnresolvedFunction -->
@@ -703,7 +312,12 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
index: id
}
- document.getElementById("edit-fronter-name").innerText = names[fronting[system][date][id]] ?? fronting[system][date][id];
+ if (fronting[system][date][id] === "lzlaq" || fronting[system][date][id] === "irxyh") {
+ document.getElementById("edit-fronter-name").innerText = "merged members";
+ } else {
+ document.getElementById("edit-fronter-name").innerText = names[fronting[system][date][id]] ?? fronting[system][date][id];
+ }
+
document.getElementById("edit-fronter-date").innerText = display;
document.getElementById("edit-fronter-pos").innerText = ordinal(id + 1);
document.getElementById("edit-fronter-system").innerText = system === "cloudburst" ? "Cloudburst System" : "Raindrops System";
@@ -756,11 +370,15 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
window.currentWorkingDate = date;
document.getElementById("new-fronter-date").innerText = display;
document.getElementById("new-fronter-system").innerText = system === "cloudburst" ? "Cloudburst System" : "Raindrops System";
- document.getElementById("list-" + system).style.display = "";
- document.getElementById("list-" + (system === "cloudburst" ? "raindrops" : "cloudburst")).style.display = "none";
+ window.addSystem = system === "raindrops" ? "gdapd" : "ynmuc";
+
+ document.getElementById("list").style.display = "block";
+ document.getElementById("search-results").style.display = "none";
+ document.getElementById("search").value = "";
let modal = new bootstrap.Modal(document.getElementById('new-fronter'));
modal.show();
+ document.getElementById("search").focus();
}
function confirmFronterAdd(system, id) {
@@ -799,6 +417,11 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
});
}
+ function viewFronterPage() {
+ let id = fronting[window.selectedFronting["system"] === "ynmuc" ? "cloudburst" : "raindrops"][window.selectedFronting["date"]][window.selectedFronting["index"]];
+ location.href = "/" + id;
+ }
+
function moveFronterUp() {
Array.from(document.getElementsByClassName("edit-fronter-link")).forEach((i) => {
i.classList.add("disabled");
@@ -812,7 +435,7 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
}
</script>
-<div class="modal fade" id="new-fronter" data-bs-backdrop="static" data-bs-keyboard="false">
+<div class="modal" id="new-fronter" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
@@ -824,24 +447,25 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
<div class="modal-body">
<p class="text-muted">Adding for the <span id="new-fronter-system">n/a</span></p>
- <div class="list-group" id="list-raindrops">
- <?php foreach (scoreOrder(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true), "gdapd") as $member): ?>
- <a onclick="confirmFronterAdd('gdapd', '<?= $member['id'] ?>');" class="new-fronter-link member-link list-group-item list-group-item-action" href="#"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- <?php endforeach; ?>
- </div>
+ <input type="text" placeholder="Search for a pony..." class="form-control" style="margin-bottom:15px;color:white;background:#111;border-color:#222;" id="search">
- <div class="list-group" id="list-cloudburst">
- <?php foreach (scoreOrder(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true), "ynmuc") as $member): ?>
- <a onclick="confirmFronterAdd('ynmuc', '<?= $member['id'] ?>');" class="new-fronter-link member-link list-group-item list-group-item-action" href="#"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
- <?php endforeach; ?>
+ <div id="list">
+ <div class="list-group">
+ <?php foreach (scoreOrderGlobal() as $member): ?>
+ <a id="list-pony-<?= $member['id'] ?>" onclick="confirmFronterAdd(window.addSystem, '<?= $member['id'] ?>');" class="new-fronter-link member-link list-group-item list-group-item-action" href="#"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?><peh-schedule-add></peh-schedule-add></a>
+ <?php endforeach; $member = getSystemMember("gdapd", "irxyh") ?>
+ <a onclick="confirmFronterAdd(window.addSystem, 'irxyh');" class="new-fronter-link member-link list-group-item list-group-item-action" href="#"><img src="/assets/logo/logo.png" style="width:24px;"> <span class="text-muted">Multiple merged members</span></a>
+ </div>
</div>
+
+ <div id="search-results" class="list-group"></div>
</div>
</div>
</div>
</div>
-<div class="modal fade" id="edit-fronter" data-bs-backdrop="static" data-bs-keyboard="false">
+<div class="modal" id="edit-fronter" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
@@ -866,6 +490,10 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
<img src="/assets/icons/down.svg" style="width:24px;filter:invert(1);vertical-align: middle;">
<span style="vertical-align: middle;">Move down</span>
</a>
+ <a class="list-group-item list-group-item-action edit-fronter-link" onclick="viewFronterPage();">
+ <img src="/assets/icons/page.svg" style="width:24px;filter:invert(1);vertical-align: middle;">
+ <span style="vertical-align: middle;">View page</span>
+ </a>
</div>
</div>
@@ -873,6 +501,80 @@ $raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/include
</div>
</div>
+<script src="/assets/editor/fuse.js"></script>
+<!--suppress JSUnresolvedFunction -->
+<script>
+ window.poniesList = JSON.parse(atob(`<?= base64_encode(json_encode(array_values(scoreOrderGlobal()))) ?>`));
+
+ const fuse = new Fuse(window.poniesList, {
+ includeScore: true,
+ keys: [
+ {
+ name: 'name',
+ weight: 1
+ },
+ {
+ name: 'display_name',
+ weight: 1
+ },
+ {
+ name: 'id',
+ weight: 0.7
+ },
+ {
+ name: 'species',
+ weight: 0.5
+ }
+ ]
+ })
+
+ function search(event) {
+ if (event.key === "Enter") {
+ return;
+ }
+
+ let query = document.getElementById("search").value;
+ let results = fuse.search(query).map((i) => {
+ return {
+ id: i.item.id,
+ score: i.score
+ };
+ });
+
+ let unfiltered = results;
+
+ results = results.filter((i) => {
+ return i.score < 0.7;
+ });
+
+ console.log("Before:", unfiltered, "After:", results);
+
+ document.getElementById("list").style.display = "none";
+ document.getElementById("search-results").style.display = "block";
+ document.getElementById("search-results").innerHTML = "";
+
+ for (let result of results) {
+ document.getElementById("search-results").innerHTML += document.getElementById("list-pony-" + result.id).outerHTML;
+ }
+
+ console.log(results);
+
+ if (query.trim() === "") {
+ document.getElementById("list").style.display = "block";
+ document.getElementById("search-results").style.display = "none";
+ }
+ }
+
+ document.getElementById("search").onchange = document.getElementById("search").onkeyup = document.getElementById("search").onkeydown = search;
+
+ document.getElementById("search").addEventListener("keydown", (event) => {
+ if (event.key === "Enter") {
+ document.querySelector("#search-results .new-fronter-link").click();
+ event.preventDefault();
+ }
+ });
+</script>
+
<?php
file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-planner.json", json_encode($cloudburst));
diff --git a/includes/refresh.php b/includes/refresh.php
index 320af54..8f9da79 100644
--- a/includes/refresh.php
+++ b/includes/refresh.php
@@ -3,12 +3,43 @@
$app = json_decode(file_get_contents("./app.json"), true);
$start = microtime(true);
@mkdir("./data");
+@mkdir("./data/backup");
$files = [];
$restored = [];
$times = [];
$currentOpStart = microtime(true);
+file_put_contents("./data/backup/actions_" . date('Y-m-d_H-i-s') . ".json", @file_get_contents("./data/actions.json"));
+file_put_contents("./data/backup/toys_" . date('Y-m-d_H-i-s') . ".json", @file_get_contents("./data/toys.json"));
+
+exec('bash -c "cd /nas/web/ponies.equestria.horse/includes/data/backup; ls -tp toys_* | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"');
+exec('bash -c "cd /nas/web/ponies.equestria.horse/includes/data/backup; ls -tp actions_* | grep -v \'/$\' | tail -n +20 | xargs -I {} rm -- {}"');
+
+$times["important_backup"] = microtime(true) - $currentOpStart;
+
+$currentOpStart = microtime(true);
+$documents = array_map(function ($i) {
+ return [
+ "id" => substr($i, 0, -5),
+ ...(json_decode(file_get_contents("./data/docs/" . $i), true) ?? [])
+ ];
+}, array_filter(scandir("./data/docs"), function ($i) {
+ return !str_starts_with($i, ".") && str_ends_with($i, ".json");
+}));
+
+$deletable = array_values(array_filter($documents, function ($i) {
+ return strip_tags($i["contents"]) === "/delete";
+}));
+
+foreach ($deletable as $item) {
+ if (time() - $item["last"]["date"] > 86400) {
+ unlink("./data/docs/" . $item["id"] . ".json");
+ }
+}
+$times["docs_cleanup"] = microtime(true) - $currentOpStart;
+
+$currentOpStart = microtime(true);
foreach (array_filter(scandir("./data"), function ($i) {
return !str_starts_with($i, ".") && $i !== "backup" && is_file("./data/" . $i);
}) as $file) {
@@ -41,7 +72,19 @@ function getSystem(string $id) {
echo(" Switches\n");
$currentOpStart = microtime(true);
- file_put_contents("./data/$id-switches.json", file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/switches"));
+
+ echo(" Part 1/3\n");
+ $switches1 = json_decode(file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/switches"), true);
+ $oldest = $switches1[count($switches1) - 1]["timestamp"];
+
+ echo(" Part 2/3\n");
+ $switches2 = json_decode(file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/switches?before=$oldest"), true);
+ $oldest = $switches2[count($switches2) - 1]["timestamp"];
+
+ echo(" Part 3/3\n");
+ $switches3 = json_decode(file_get_contents("https://pluralkit.equestria.dev/v2/systems/$id/switches?before=$oldest"), true);
+
+ file_put_contents("./data/$id-switches.json", json_encode([...$switches1, ...$switches2, ...$switches3], JSON_PRETTY_PRINT));
$times["system-switches-$id"] = microtime(true) - $currentOpStart;
}
@@ -99,14 +142,21 @@ function isJson($string): bool {
}
foreach ($files as $file) {
- if (trim(file_get_contents("./data/" . $file)) === "" || (isJson(trim(file_get_contents("./data/" . $file))) && isset(json_decode(trim(file_get_contents("./data/" . $file)), true)["message"]))) {
+ if (trim(file_get_contents("./data/" . $file)) === "" || (isJson(trim(file_get_contents("./data/" . $file))) && isset(json_decode(trim(file_get_contents("./data/" . $file)), true)["message"])) && !str_ends_with($file, ".html")) {
$restored[] = $file;
copy("./data/backup/" . $file, "./data/" . $file);
}
}
$times["restore"] = microtime(true) - $currentOpStart;
-require_once "./backup.php";
+echo("Backing up...\n");
+
+if (date('i') === "00") {
+ require_once "./backup.php";
+ echo("Backup completed\n");
+} else {
+ echo("Backup skipped\n");
+}
$time = array_sum($times);
echo("Completed in " . $time . " seconds.\n");
diff --git a/includes/score.php b/includes/score.php
index e0d0d62..cd8c389 100644
--- a/includes/score.php
+++ b/includes/score.php
@@ -13,7 +13,11 @@ function calculateScore($metadata, $name) {
$relations = (count($metadata["marefriends"]) * ($metadata["little"] ? 1 : 2)) + count($metadata["sisters"]);
$scoreRelations = $relations * 50;
- $score = $scoreHost + $scoreFictive + $scoreLittle + $scoreNotTalking + $scoreProtector + $scoreSharedMemory + $scoreRelations + $scoreSpecies + $scoreName + $scoreMedian;
+ $scoreAdd = 0;
+ if ($name === "Cloudy Dreams") $scoreAdd += 250;
+ if ($name === "Scoots/Mia") $scoreAdd -= 495;
+
+ $score = $scoreHost + $scoreFictive + $scoreLittle + $scoreNotTalking + $scoreProtector + $scoreSharedMemory + $scoreRelations + $scoreSpecies + $scoreName + $scoreMedian + $scoreAdd;
return [
"host" => $scoreHost,
@@ -26,6 +30,7 @@ function calculateScore($metadata, $name) {
"shared_memory" => $scoreSharedMemory,
"relations" => $scoreRelations,
"species" => $scoreSpecies,
+ "additional" => $scoreAdd,
"total" => $score
];
}
@@ -33,7 +38,7 @@ function calculateScore($metadata, $name) {
function scoreOrder($members, $system) {
$ordered = [];
foreach ($members as $member) {
- if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && !str_ends_with($member["name"], "-travelling")) {
+ if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling") && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($member["system"] ?? $system) . "-$member[id]-metadata.json")) {
$systemID = $member["system"] ?? $system;
$member["_metadata"] = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-$member[id]-metadata.json"), true));
@@ -52,7 +57,7 @@ function scoreOrder($members, $system) {
function scoreOrderGlobal() {
$ordered = [];
foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true) as $member) {
- if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && !str_ends_with($member["name"], "-travelling")) {
+ if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling") && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-$member[id]-metadata.json")) {
$member["_system"] = "gdapd";
$member["_metadata"] = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-$member[id]-metadata.json"), true));
$member["_score"] = calculateScore(parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-$member[id]-metadata.json"), true)), $member["display_name"] ?? $member["name"]);
@@ -60,7 +65,7 @@ function scoreOrderGlobal() {
}
}
foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true) as $member) {
- if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && !str_ends_with($member["name"], "-travelling")) {
+ if ($member["name"] !== "unknown" && $member["name"] !== "fusion" && $member["name"] !== "new" && !str_ends_with($member["name"], "-travelling") && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-$member[id]-metadata.json")) {
$member["_system"] = "ynmuc";
$member["_metadata"] = parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-$member[id]-metadata.json"), true));
$member["_score"] = calculateScore(parseMetadata(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-$member[id]-metadata.json"), true)), $member["display_name"] ?? $member["name"]);
diff --git a/includes/search.php b/includes/search.php
new file mode 100644
index 0000000..037b6de
--- /dev/null
+++ b/includes/search.php
@@ -0,0 +1,529 @@
+<div id="global-search-container" style="display: none; position: fixed; z-index: 99999999;background-color: rgba(0, 0, 0, .75); inset: 0; backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); align-items: center; justify-content: center;">
+ <div id="global-search-box" style="background: rgba(50, 50, 50, .5); color: white; backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); border-radius: 15px; width: 768px; max-width: 90vw;">
+ <div id="global-search-input-container" onclick="document.getElementById('global-search-input').focus();" style="cursor:text;padding: 10px 50px; font-size: 22px; border: 1px solid rgba(100, 100, 100, .5); border-top-left-radius: 15px; border-top-right-radius: 15px; width: 768px; max-width: 90vw;">
+ <span onchange="globalSearchPlaceholder(); globalSearch();" onkeyup="globalSearchPlaceholder(); globalSearch();" onkeydown="globalSearchPlaceholder(); globalSearch();" type="text" id="global-search-input" style="display:inline-block; background: transparent; color: white; border: none;" spellcheck="false" contenteditable="true"></span><span id="global-search-placeholder" style="opacity:.5;">Website Search</span><span id="global-search-autocomplete" style="opacity:.5;"></span><span id="global-search-action" style="opacity:.5;font-size:16px;"></span>
+ </div>
+ <div id="global-search-results" style="border-bottom-left-radius: 15px; border-bottom-right-radius: 15px; border-top-style: none; border-right: 1px solid rgba(100, 100, 100, .5); border-bottom: 1px solid rgba(100, 100, 100, .5); border-left: 1px solid rgba(100, 100, 100, .5); width: 768px; max-width: 90vw; height: 400px; max-height: calc(90vh - 60px);">
+ <div id="global-search-intro" style="display: flex; align-items: center; justify-content: center; height: 100%; text-align: center;">
+ <div style="opacity: .5;">
+ <img src="/assets/logo/logo.png" style="width: 64px; height: 64px; margin-bottom: 10px;">
+ <p>Start typing to search for something on the entire website.</p>
+ </div>
+ </div>
+ <div id="global-search-list" style="overflow: auto; display: flex; align-items: center; justify-content: center; height: 100%; text-align: center;"></div>
+ </div>
+ </div>
+</div>
+
+<script src="/assets/editor/fuse.js"></script>
+
+<!--suppress JSUnresolvedFunction -->
+<script>
+ const pages_list = JSON.parse(atob(`<?php
+
+ $base = array_values(array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/pages"), function ($i) {
+ return !str_starts_with($i, ".") && $i !== "page.php" && $i !== "api.php" && $i !== "demo.php" && $i !== "logout.php" && $i !== "edit.php" && $i !== "edit-private.php" && $i !== "app.php" && !str_ends_with($i, ".bak.php") && !str_ends_with($i, ".old.php") && !str_ends_with($i, "-dev.php");
+ }));
+ $list = array_values(array_filter(array_map(function ($i) {
+ global $pages;
+ global $isLoggedIn;
+
+ if (in_array(substr($i, 0, strlen($i) - 4), array_keys($pages)) && $pages[substr($i, 0, strlen($i) - 4)]["admin"] && !$isLoggedIn) {
+ return null;
+ } else {
+ return [
+ 'name' => in_array(substr($i, 0, strlen($i) - 4), array_keys($pages)) ? $pages[substr($i, 0, strlen($i) - 4)]["name"] : substr($i, 0, strlen($i) - 4),
+ 'description' => in_array(substr($i, 0, strlen($i) - 4), array_keys($pages)) ? ($pages[substr($i, 0, strlen($i) - 4)]["short"] ?? $pages[substr($i, 0, strlen($i) - 4)]["name"]) : substr($i, 0, strlen($i) - 4),
+ 'url' => "/-/" . substr($i, 0, strlen($i) - 4),
+ 'icon' => "/assets/icons/" . (file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/icons/" . substr($i, 0, strlen($i) - 4) . ".svg") ? substr($i, 0, strlen($i) - 4) : "") . ".svg",
+ 'invert' => true
+ ];
+ }
+ }, $base), function ($i) {
+ return isset($i);
+ }));
+
+ echo(base64_encode(json_encode($list)));
+
+ ?>`));
+ const pages = new Fuse(pages_list, {
+ includeScore: true,
+ keys: [
+ {
+ name: 'name',
+ weight: 0.7
+ },
+ {
+ name: 'description',
+ weight: 0.5
+ },
+ {
+ name: 'url',
+ weight: 0.2
+ }
+ ]
+ })
+
+ const ponies_list = JSON.parse(atob(`<?php
+
+ $base = array_values(scoreOrderGlobal());
+ $list = array_map(function ($i) {
+ return [
+ 'name' => $i["display_name"] ?? $i["name"],
+ 'description' => file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$i[_system]-$i[id]-content.html") ? strip_tags(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$i[_system]-$i[id]-content.html")) : "",
+ 'url' => '/' . $i["name"],
+ 'icon' => "/assets/uploads/pt" . (file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($i['name']) . ".png") ? "-" . $i['name'] : "") . ".png",
+ 'invert' => false
+ ];
+ }, $base);
+
+ echo(base64_encode(json_encode($list)));
+
+ ?>`));
+ const ponies = new Fuse(ponies_list, {
+ includeScore: true,
+ keys: [
+ {
+ name: 'name',
+ weight: 1
+ },
+ {
+ name: 'description',
+ weight: 0.7
+ },
+ {
+ name: 'url',
+ weight: 0.5
+ }
+ ]
+ })
+
+ const toys_list = JSON.parse(atob(`<?php
+
+ global $isLoggedIn;
+
+ if ($isLoggedIn) {
+ $base = array_values(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/toys.json"), true));
+ $list = array_map(function ($i) {
+ return [
+ 'name' => $i["name"],
+ 'description' => $i["description"],
+ 'icon' => "/assets/icons/toys.svg",
+ 'url' => "/-/toys/$i[id]",
+ 'invert' => true
+ ];
+ }, $base);
+
+ echo(base64_encode(json_encode($list)));
+ } else {
+ echo(base64_encode(json_encode([])));
+ }
+
+ ?>`));
+ const toys = new Fuse(toys_list, {
+ includeScore: true,
+ keys: [
+ {
+ name: 'name',
+ weight: 1
+ },
+ {
+ name: 'description',
+ weight: 0.7
+ },
+ {
+ name: 'url',
+ weight: 0.5
+ }
+ ]
+ })
+
+ const actions_list = JSON.parse(atob(`<?php
+
+ global $isLoggedIn;
+
+ if ($isLoggedIn) {
+ $base = array_values(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/actions.json"), true));
+ $list = array_map(function ($i) {
+ return [
+ 'name' => $i["name"],
+ 'description' => $i["description"],
+ 'icon' => "/assets/icons/actions.svg",
+ 'url' => "/-/actions/$i[id]",
+ 'invert' => true
+ ];
+ }, $base);
+
+ echo(base64_encode(json_encode($list)));
+ } else {
+ echo(base64_encode(json_encode([])));
+ }
+
+ ?>`));
+ const actions = new Fuse(actions_list, {
+ includeScore: true,
+ keys: [
+ {
+ name: 'name',
+ weight: 1
+ },
+ {
+ name: 'description',
+ weight: 0.7
+ },
+ {
+ name: 'url',
+ weight: 0.5
+ }
+ ]
+ })
+
+ const documents_list = JSON.parse(atob(`<?php
+
+ global $isLoggedIn;
+
+ if ($isLoggedIn) {
+ $base = array_values(array_map(function ($i) {
+ return [
+ "id" => substr($i, 0, -5),
+ ...(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $i), true) ?? [])
+ ];
+ }, array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs"), function ($i) {
+ return !str_starts_with($i, ".") && str_ends_with($i, ".json");
+ })));
+ $list = array_map(function ($i) {
+ return [
+ 'name' => $i["name"],
+ 'content' => strip_tags($i["contents"]),
+ 'category' => $i["category"],
+ 'icon' => "/assets/icons/docs.svg",
+ 'url' => "/-/docs/$i[id]",
+ 'invert' => true
+ ];
+ }, $base);
+
+ echo(base64_encode(json_encode($list)));
+ } else {
+ echo(base64_encode(json_encode([])));
+ }
+
+ ?>`));
+ const documents = new Fuse(documents_list, {
+ includeScore: true,
+ keys: [
+ {
+ name: 'name',
+ weight: 1
+ },
+ {
+ name: 'category',
+ weight: 0.7
+ },
+ {
+ name: 'content',
+ weight: 0.4
+ },
+ {
+ name: 'url',
+ weight: 0.5
+ }
+ ]
+ })
+
+ window.shiftPresses = 0;
+ window.searchBoxOpen = false;
+ window.lastKnownSearchQuery = null;
+
+ function toggleGlobalSearch() {
+ window.shiftPresses = 0;
+ console.log("Search!");
+
+ if (document.getElementById("global-search-container").style.display === "none") {
+ document.getElementById("global-search-container").style.display = "flex";
+ document.getElementById("global-search-list").style.display = "none";
+ document.getElementById("global-search-intro").style.display = "flex";
+ document.getElementById("global-search-input").focus();
+ document.getElementById("global-search-input").value = "";
+ window.searchBoxOpen = true;
+ } else if (document.getElementById("global-search-container").style.display === "flex") {
+ document.getElementById("global-search-container").style.display = "none";
+ window.searchBoxOpen = false;
+ }
+ }
+
+ function globalSearchPlaceholder() {
+ if (document.getElementById("global-search-input").innerText === "") {
+ document.getElementById("global-search-placeholder").style.display = "";
+ document.getElementById("global-search-autocomplete").innerText = "";
+ document.getElementById("global-search-action").innerText = "";
+ } else {
+ document.getElementById("global-search-placeholder").style.display = "none";
+ }
+ }
+
+ function globalSearchAutocomplete(firstResult) {
+ let querySearch = document.getElementById("global-search-input").innerText.toLowerCase();
+ let firstResultSearch = firstResult.name.toLowerCase();
+ let isAutocomplete = true;
+
+ if (firstResultSearch.length > querySearch.length) {
+ let count = 0;
+
+ for (let i = 0; i < querySearch.length; i++) {
+ if (querySearch.substring(i, i + 1) === firstResultSearch.substring(i, i + 1)) {
+ count++;
+ } else {
+ isAutocomplete = false;
+ }
+ }
+
+ if (isAutocomplete) {
+ document.getElementById("global-search-autocomplete").innerText = firstResult.name.substring(count);
+ document.getElementById("global-search-action").innerText = " — View page";
+ } else {
+ document.getElementById("global-search-autocomplete").innerText = "";
+ document.getElementById("global-search-action").innerText = " — " + firstResult.name;
+ }
+ } else {
+ document.getElementById("global-search-autocomplete").innerText = "";
+ document.getElementById("global-search-action").innerText = "";
+ }
+ }
+
+ function globalSearch() {
+ let query = document.getElementById("global-search-input").innerText.trim();
+
+ if (query !== lastKnownSearchQuery) {
+ window.lastKnownSearchQuery = query;
+ } else {
+ return;
+ }
+
+ let results, scores;
+ let categories = [];
+ console.log("Query:", query);
+
+ if (query.trim() === "") {
+ document.getElementById("global-search-list").style.display = "none";
+ document.getElementById("global-search-intro").style.display = "flex";
+ return;
+ } else {
+ document.getElementById("global-search-list").style.display = "block";
+ document.getElementById("global-search-intro").style.display = "none";
+ }
+
+ results = ponies.search(query).map((i) => {
+ i.item.score = i.score;
+ return i.item;
+ });
+ scores = results.map((i) => { return i.score; });
+ let results_ponies = {
+ category: {
+ name: "Ponies",
+ id: "ponies"
+ },
+ average: scores.length > 0 ? scores.reduce((a, b) => { return a + b; }) / results.length : 1,
+ results
+ };
+
+ results = pages.search(query).map((i) => {
+ i.item.score = i.score;
+ return i.item;
+ });
+ scores = results.map((i) => { return i.score; });
+ let results_pages = {
+ category: {
+ name: "Pages",
+ id: "pages"
+ },
+ average: scores.length > 0 ? scores.reduce((a, b) => { return a + b; }) / results.length : 1,
+ results
+ };
+
+ results = actions.search(query).map((i) => {
+ i.item.score = i.score;
+ return i.item;
+ });
+ scores = results.map((i) => { return i.score; });
+ let results_actions = {
+ category: {
+ name: "Actions",
+ id: "actions"
+ },
+ average: scores.length > 0 ? scores.reduce((a, b) => { return a + b; }) / results.length : 1,
+ results
+ };
+
+ results = documents.search(query).map((i) => {
+ i.item.score = i.score;
+ return i.item;
+ });
+ scores = results.map((i) => { return i.score; });
+ let results_documents = {
+ category: {
+ name: "Documents",
+ id: "docs"
+ },
+ average: scores.length > 0 ? scores.reduce((a, b) => { return a + b; }) / results.length : 1,
+ results
+ };
+
+ results = toys.search(query).map((i) => {
+ i.item.score = i.score;
+ return i.item;
+ });
+ scores = results.map((i) => { return i.score; });
+ let results_toys = {
+ category: {
+ name: "Toys",
+ id: "toys"
+ },
+ average: scores.length > 0 ? scores.reduce((a, b) => { return a + b; }) / results.length : 1,
+ results
+ };
+
+ window.allSearchResults = [];
+ categories.push(results_ponies, results_pages, results_documents, results_actions, results_toys);
+ categories = categories.sort((a, b) => {
+ return a.average - b.average;
+ }).filter((i) => i.results.length > 0);
+
+ console.log(categories);
+
+ index = -1;
+ document.getElementById("global-search-list").innerHTML = categories.map((i) => `
+ <div class="global-search-category">
+ <div class="global-search-category-header">${i.category.name}</div>
+ <div class="global-search-category-items">
+ ${i.results.map((j) => { index++; allSearchResults.push(j); return `
+ <a href="${j.url}" class="global-search-item ${index === 0 ? 'selected' : ''}" id="global-search-item-${index}">
+ <img src="${j.icon}" class="global-search-item-icon" ${j['invert'] ? 'style="filter:invert(1) brightness(5);"' : ""}>
+ <span class="global-search-item-title">${j.name}</span>
+ </a>
+ ` }).join("")}
+ </div>
+ </div>
+ `).join("");
+
+ globalSearchAutocomplete(allSearchResults[0]);
+
+ console.log("=================================");
+ }
+
+ document.onkeydown = (event) => {
+ if (window.searchBoxOpen) {
+ console.log(event);
+
+ if (event.key === "Escape") {
+ if (document.getElementById("global-search-input").innerText.trim() === "") {
+ toggleGlobalSearch();
+ } else {
+ document.getElementById("global-search-input").innerText = "";
+ globalSearch();
+ }
+ }
+
+ if (event.key === "ArrowDown") {
+ let id = parseInt(document.querySelector(".global-search-item.selected").id.split("-")[3]);
+
+ if (document.getElementById("global-search-item-" + (id + 1)) !== null) {
+ document.getElementById("global-search-item-" + id).classList.remove("selected");
+ document.getElementById("global-search-item-" + (id + 1)).classList.add("selected");
+ document.getElementById("global-search-item-" + (id + 1)).scrollIntoView({
+ block: "center",
+ inline: "center"
+ });
+
+ globalSearchAutocomplete(allSearchResults[id + 1]);
+ }
+
+ event.preventDefault();
+ }
+
+ if (event.key === "ArrowUp") {
+ let id = parseInt(document.querySelector(".global-search-item.selected").id.split("-")[3]);
+
+ if (document.getElementById("global-search-item-" + (id - 1)) !== null) {
+ document.getElementById("global-search-item-" + id).classList.remove("selected");
+ document.getElementById("global-search-item-" + (id - 1)).classList.add("selected");
+ document.getElementById("global-search-item-" + (id - 1)).scrollIntoView({
+ block: "center",
+ inline: "center"
+ });
+
+ globalSearchAutocomplete(allSearchResults[id - 1]);
+ }
+
+ event.preventDefault();
+ }
+
+ if (event.key === "Enter") {
+ document.querySelector(".global-search-item.selected").click();
+
+ event.preventDefault();
+ }
+ }
+
+ if (event.key === "Shift") {
+ window.shiftPresses++;
+ }
+
+ if ((event.code === "Space" && event.ctrlKey) || window.shiftPresses === 2) {
+ toggleGlobalSearch();
+ }
+ }
+
+ document.getElementById("global-search-container").onclick = (event) => {
+ if (event.target === document.getElementById("global-search-container")) toggleGlobalSearch();
+ }
+
+ setInterval(() => {
+ window.shiftPresses = 0;
+ }, 500);
+</script>
+
+<style>
+ .global-search-category {
+ text-align: left;
+ padding: 10px 20px;
+ }
+
+ .global-search-category-header {
+ font-size: 12px;
+ opacity: .5;
+ margin-bottom: 5px;
+ margin-top: 10px;
+ }
+
+ .global-search-item-icon {
+ vertical-align: middle;
+ width: 24px;
+ height: 24px;
+ margin-right: 5px;
+ }
+
+ .global-search-item-title {
+ vertical-align: middle;
+ }
+
+ .global-search-item {
+ text-decoration: none;
+ display: block;
+ color: white !important;
+ border-radius: 10px;
+ padding: 3px 5px;
+ height: 32px;
+ }
+
+ .global-search-item:hover, .global-search-item:focus, .global-search-item.selected {
+ background-color: rgba(255, 255, 255, .1);
+ }
+
+ .global-search-item:active {
+ background-color: rgba(255, 255, 255, .2);
+ }
+
+ #global-search-container * {
+ outline: none !important;
+ }
+</style> \ No newline at end of file
diff --git a/includes/short.php b/includes/short.php
index dec0e09..59b3cae 100644
--- a/includes/short.php
+++ b/includes/short.php
@@ -11,7 +11,12 @@ $members = scoreOrderGlobal();
$list = [
"rd" => "/raindrops",
"cb" => "/cloudburst",
- "minty" => "/cloudy"
+ "minty" => "/cloudydreams",
+ "cloudy" => "/cloudydreams",
+ "zipp" => "/zippstorm",
+ "babs" => "/babsseed",
+ "frost" => "/frostcrystals",
+ "violet" => "/violetdawn"
];
foreach ($members as $member) {
diff --git a/includes/subsysbanner.php b/includes/subsysbanner.php
index e36d0b5..7788155 100644
--- a/includes/subsysbanner.php
+++ b/includes/subsysbanner.php
@@ -24,7 +24,7 @@ $fronters = array_map(function ($item) {
<div style="height:max-content;display:grid;grid-template-columns: repeat(4, 1fr);" id="member-card">
<span>
<b>Fronter:</b>
- <?php if (in_array($fronters[0], getSubsystemByID($subsystemID)["members"])): $member = getMember($fronters[0]); ?>
+ <?php if (in_array($fronters[0], $subsystem["members"])): $member = getMember($fronters[0]); ?>
<a class="member-link" href="/<?= $member["name"] ?>"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
<?php else: ?>
<span class="text-muted">N/A</span>
@@ -33,11 +33,12 @@ $fronters = array_map(function ($item) {
<span>
<?php
- $arr = array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-switches.json"), true), function ($i) use ($subsystemID) {
- return in_array($i["members"][0], getSubsystemByID($subsystemID)["members"]);
+ $subsystem = getSubsystemByID($subsystemID);
+ $arr = array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-switches.json"), true), function ($i) use ($subsystem) {
+ return isset($i["members"][0]) && in_array($i["members"][0], $subsystem["members"]);
});
sort($arr);
- $previousID = $arr[in_array($fronters[0], getSubsystemByID($subsystemID)["members"]) ? 1 : 0]["members"][0];
+ $previousID = $arr[in_array($fronters[0], $subsystem["members"]) ? 1 : 0]["members"][0];
$member = null;
foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-members.json"), true) as $members) {
@@ -48,13 +49,13 @@ $fronters = array_map(function ($item) {
}
?>
- <b>Last Fronter: </b><a class="member-link" href="/<?= $member["name"] ?>"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
+ <b>Last fronter: </b><a class="member-link" href="/<?= $member["name"] ?>"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? $member["name"]) ?></a>
</span>
<span>
- <b>Members:</b> <?= count(getSubsystemByID($subsystemID)["members"]) ?>
+ <b>Members:</b> <?= count($subsystem["members"]) ?>
</span>
<span>
- <b>Parent System:</b> <a class="member-link" href="/<?= $system ?>"><img style="width:24px;border-radius:5px;" src="/assets/uploads/<?= $system ?>.png"> <?= getMiniName($systemCommonName) ?></a>
+ <b>Parent system:</b> <a class="member-link" href="/<?= $system ?>"><img style="width:24px;border-radius:5px;" src="/assets/uploads/<?= $system ?>.png"> <?= getMiniName($systemCommonName) ?></a>
</span>
</div>
</div>
diff --git a/includes/subsysedit.php b/includes/subsysedit.php
index 274814e..e6aa9ca 100644
--- a/includes/subsysedit.php
+++ b/includes/subsysedit.php
@@ -1,34 +1,5 @@
<?php global $system; global $systemCommonName; global $systemID; global $subsystem; global $subsystemData; global $subsystemCommonName; global $subsystemID; $title = "Editing " . $subsystemCommonName . " · " . $systemCommonName; require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
-function timeAgo($time): string {
- if (!is_numeric($time)) {
- $time = strtotime($time);
- }
-
- $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
- $lengths = array("60", "60", "24", "7", "4.35", "12", "100");
-
- $now = time();
-
- $difference = $now - $time;
- if ($difference <= 10 && $difference >= 0) {
- return $tense = "now";
- } elseif ($difference > 0) {
- $tense = "ago";
- } else {
- $tense = "later";
- }
-
- for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
- $difference /= $lengths[$j];
- }
-
- $difference = round($difference);
-
- $period = $periods[$j] . ($difference >1 ? "s" :'');
- return "{$difference} {$period} {$tense}";
-}
-
?>
<br>
diff --git a/includes/sysbanner.php b/includes/sysbanner.php
index 3a2b8c1..45c1c16 100644
--- a/includes/sysbanner.php
+++ b/includes/sysbanner.php
@@ -16,8 +16,8 @@ $travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includ
<div style="padding:10px 10px 10px 20px;text-align:center;">
<div style="display: grid; grid-template-columns: 1fr;height:100%;grid-template-rows: max-content max-content 1fr;">
<h3 style="height:max-content;"><?= $systemCommonName ?></h3>
- <div style="height:max-content;display:grid;grid-template-columns: repeat(5, 1fr);" id="member-card">
- <span>
+ <div style="height:max-content;display:grid;grid-template-columns: repeat(4, 1fr);" id="member-card">
+ <!--<span>
<b><abbr title="Most common fronter" data-bs-toggle="tooltip">MCF</abbr>: </b><?php
$foundHost = false;
@@ -25,7 +25,7 @@ $travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includ
$members = array_filter(scoreOrder(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-members.json"), true), $systemID), function ($i) use ($travelling) {
global $hostGoneTravelling;
- if ($travelling[$i['id']]['travelling']) $hostGoneTravelling = true;
+ if ($travelling[$i['id']]['travelling'] && $i["_metadata"]["host"]) $hostGoneTravelling = true;
return true;
});
foreach ($members as $member) {
@@ -40,15 +40,28 @@ $travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includ
?>
- </span>
+ </span>-->
<span>
- <?php $member = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-fronters.json"), true)["members"][0]; ?>
- <b>Fronter: </b><a class="member-link" href="/<?= $member["name"] ?>"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . resolveMember($member['name']) : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? ($member["name"] === "fusion" ? "<peh-muted>More than one</peh-muted>" : $member["name"])) ?></a>
+ <?php $fronters = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-fronters.json"), true); ?>
+ <b>Fronter: </b>
+ <?php if (isset($fronters["members"][0])): ?>
+ <?php $member = $fronters["members"][0]; ?>
+ <a class="member-link" href="/<?= $member["name"] ?>"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . resolveMember($member['name']) : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? ($member["name"] === "fusion" ? "<peh-muted>More than one</peh-muted>" : $member["name"])) ?></a>
+ <?php if (isset($fronters["members"][1])): ?>
+ <?php $member2 = $fronters["members"][1]; ?>
+ <br>(with
+ <a class="member-link" href="/<?= $member2["name"] ?>"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . resolveMember($member2['name']) : "" ?>.png" style="width:24px;"> <?= getMiniName($member2["display_name"] ?? ($member2["name"] === "fusion" ? "<peh-muted>More than one</peh-muted>" : $member2["name"])) ?></a>)
+ <?php else: ?>-<?php endif; ?>
+ <?php else: ?>-<?php endif; ?>
</span>
<span>
+ <b>Last fronter: </b>
<?php
- $previousID = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-switches.json"), true)[1]["members"][0];
+ $previous = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-switches.json"), true)[1]["members"];
+
+ if (isset($previous[0])):
+ $previousID = $previous[0];
$member = null;
foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-members.json"), true) as $members) {
@@ -59,7 +72,21 @@ $travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includ
}
?>
- <b>Last fronter: </b><a class="member-link" href="/<?= $member["name"] ?>"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? ($member["name"] === "fusion" ? "<peh-muted>More than one</peh-muted>" : $member["name"])) ?></a>
+ <a class="member-link" href="/<?= $member["name"] ?>"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= getMiniName($member["display_name"] ?? ($member["name"] === "fusion" ? "<peh-muted>More than one</peh-muted>" : $member["name"])) ?></a>
+ <?php if (isset($previous[1])):
+ $previousID = $previous[1];
+ $member2 = null;
+
+ foreach (json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-members.json"), true) as $members) {
+ if ($members["id"] === $previousID) {
+ $member2 = $members;
+ break;
+ }
+ } ?>
+ <br>(with
+ <a class="member-link" href="/<?= $member2["name"] ?>"><img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . resolveMember($member2['name']) : "" ?>.png" style="width:24px;"> <?= getMiniName($member2["display_name"] ?? ($member2["name"] === "fusion" ? "<peh-muted>More than one</peh-muted>" : $member2["name"])) ?></a>)
+ <?php else: ?>-<?php endif; ?>
+ <?php else: ?>-<?php endif; ?>
</span>
<span>
<?php
diff --git a/includes/sysedit.php b/includes/sysedit.php
index 91ebbe1..0eca518 100644
--- a/includes/sysedit.php
+++ b/includes/sysedit.php
@@ -1,34 +1,5 @@
<?php global $system; global $systemCommonName; global $systemID; $title = "Editing " . $systemCommonName; require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
-function timeAgo($time): string {
- if (!is_numeric($time)) {
- $time = strtotime($time);
- }
-
- $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
- $lengths = array("60", "60", "24", "7", "4.35", "12", "100");
-
- $now = time();
-
- $difference = $now - $time;
- if ($difference <= 10 && $difference >= 0) {
- return $tense = "now";
- } elseif ($difference > 0) {
- $tense = "ago";
- } else {
- $tense = "later";
- }
-
- for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
- $difference /= $lengths[$j];
- }
-
- $difference = round($difference);
-
- $period = $periods[$j] . ($difference >1 ? "s" :'');
- return "{$difference} {$period} {$tense}";
-}
-
?>
<br>
diff --git a/includes/system/history.php b/includes/system/history.php
index 1f04bb7..a13a3e1 100644
--- a/includes/system/history.php
+++ b/includes/system/history.php
@@ -19,7 +19,9 @@ function getMember(string $id) {
<div class="container" id="page-content">
<?php
- $switches = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-switches.json"), true);
+ $switches = array_values(array_filter(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-switches.json"), true), function ($i) {
+ return isset($i["members"][0]);
+ }));
uksort($switches, function ($a, $b) {
if (isset($b["timestamp"]) && isset($a["timestamp"])) {
return strtotime($b["timestamp"]) - strtotime($a["timestamp"]);
@@ -101,13 +103,15 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches1);
$fronters[] = [
- "member" => $switches2[0] ? $switches2[0]["members"][0] : ($switches3[0] ? $switches3[0]["members"][0] : ($switches4[0] ? $switches4[0]["members"][0] : ($switches5[0] ? $switches5[0]["members"][0] : ($switches6[0] ? $switches6[0]["members"][0] : ($switches7[0] ? $switches7[0]["members"][0] : ($switches8[0] ? $switches8[0]["members"][0] : ($switches9[0] ? $switches9[0]["members"][0] : $switches10[0]["members"][0]))))))),
- "date" => strtotime($switches2[0] ? $switches2[0]["timestamp"] : ($switches3[0] ? $switches3[0]["timestamp"] : ($switches4[0] ? $switches4[0]["timestamp"] : ($switches5[0] ? $switches5[0]["timestamp"] : ($switches6[0] ? $switches6[0]["timestamp"] : ($switches7[0] ? $switches7[0]["timestamp"] : ($switches8[0] ? $switches8[0]["timestamp"] : ($switches9[0] ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))))))
+ "member" => isset($switches2[0]) ? (isset($switches2[0]["members"]) && isset($switches2[0]["members"][0]) ? $switches2[0]["members"][0] : null) : (isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][0]) ? $switches3[0]["members"][0] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][0]) ? $switches4[0]["members"][0] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]))))))),
+ "member2" => isset($switches2[0]) ? (isset($switches2[0]["members"]) && isset($switches2[0]["members"][1]) ? $switches2[0]["members"][1] : null) : (isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][1]) ? $switches3[0]["members"][1] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][1]) ? $switches4[0]["members"][1] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]))))))),
+ "date" => strtotime(isset($switches2[0]) ? $switches2[0]["timestamp"] : (isset($switches3[0]) ? $switches3[0]["timestamp"] : (isset($switches4[0]) ? $switches4[0]["timestamp"] : (isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))))))
];
$fronters = array_unique($fronters, SORT_REGULAR);
@@ -122,6 +126,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
@@ -131,13 +139,15 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches2);
$fronters[] = [
- "member" => $switches3[0] ? $switches3[0]["members"][0] : ($switches4[0] ? $switches4[0]["members"][0] : ($switches5[0] ? $switches5[0]["members"][0] : ($switches6[0] ? $switches6[0]["members"][0] : ($switches7[0] ? $switches7[0]["members"][0] : ($switches8[0] ? $switches8[0]["members"][0] : ($switches9[0] ? $switches9[0]["members"][0] : $switches10[0]["members"][0])))))),
- "date" => strtotime($switches3[0] ? $switches3[0]["timestamp"] : ($switches4[0] ? $switches4[0]["timestamp"] : ($switches5[0] ? $switches5[0]["timestamp"] : ($switches6[0] ? $switches6[0]["timestamp"] : ($switches7[0] ? $switches7[0]["timestamp"] : ($switches8[0] ? $switches8[0]["timestamp"] : ($switches9[0] ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))))))
+ "member" => isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][0]) ? $switches3[0]["members"][0] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][0]) ? $switches4[0]["members"][0] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0])))))),
+ "member2" => isset($switches3[0]) ? (isset($switches3[0]["members"]) && isset($switches3[0]["members"][1]) ? $switches3[0]["members"][1] : null) : (isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][1]) ? $switches4[0]["members"][1] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1])))))),
+ "date" => strtotime(isset($switches3[0]) ? $switches3[0]["timestamp"] : (isset($switches4[0]) ? $switches4[0]["timestamp"] : (isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))))))
];
$fronters = array_unique($fronters, SORT_REGULAR);
@@ -152,6 +162,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
@@ -161,13 +175,15 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches3);
$fronters[] = [
- "member" => $switches4[0] ? $switches4[0]["members"][0] : ($switches5[0] ? $switches5[0]["members"][0] : ($switches6[0] ? $switches6[0]["members"][0] : ($switches7[0] ? $switches7[0]["members"][0] : ($switches8[0] ? $switches8[0]["members"][0] : ($switches9[0] ? $switches9[0]["members"][0] : $switches10[0]["members"][0]))))),
- "date" => strtotime($switches4[0] ? $switches4[0]["timestamp"] : ($switches5[0] ? $switches5[0]["timestamp"] : ($switches6[0] ? $switches6[0]["timestamp"] : ($switches7[0] ? $switches7[0]["timestamp"] : ($switches8[0] ? $switches8[0]["timestamp"] : ($switches9[0] ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))))
+ "member" => isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][0]) ? $switches4[0]["members"][0] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]))))),
+ "member2" => isset($switches4[0]) ? (isset($switches4[0]["members"]) && isset($switches4[0]["members"][1]) ? $switches4[0]["members"][1] : null) : (isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]))))),
+ "date" => strtotime(isset($switches4[0]) ? $switches4[0]["timestamp"] : (isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))))
];
$fronters = array_unique($fronters, SORT_REGULAR);
@@ -182,6 +198,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
@@ -191,13 +211,15 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches4);
$fronters[] = [
- "member" => $switches5[0] ? $switches5[0]["members"][0] : ($switches6[0] ? $switches6[0]["members"][0] : ($switches7[0] ? $switches7[0]["members"][0] : ($switches8[0] ? $switches8[0]["members"][0] : ($switches9[0] ? $switches9[0]["members"][0] : $switches10[0]["members"][0])))),
- "date" => strtotime($switches5[0] ? $switches5[0]["timestamp"] : ($switches6[0] ? $switches6[0]["timestamp"] : ($switches7[0] ? $switches7[0]["timestamp"] : ($switches8[0] ? $switches8[0]["timestamp"] : ($switches9[0] ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))))
+ "member" => isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][0]) ? $switches5[0]["members"][0] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0])))),
+ "member2" => isset($switches5[0]) ? (isset($switches5[0]["members"]) && isset($switches5[0]["members"][1]) ? $switches5[0]["members"][1] : null) : (isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1])))),
+ "date" => strtotime(isset($switches5[0]) ? $switches5[0]["timestamp"] : (isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))))
];
$fronters = array_unique($fronters, SORT_REGULAR);
@@ -212,6 +234,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
@@ -221,13 +247,15 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches5);
$fronters[] = [
- "member" => $switches6[0] ? $switches6[0]["members"][0] : ($switches7[0] ? $switches7[0]["members"][0] : ($switches8[0] ? $switches8[0]["members"][0] : ($switches9[0] ? $switches9[0]["members"][0] : $switches10[0]["members"][0]))),
- "date" => strtotime($switches6[0] ? $switches6[0]["timestamp"] : ($switches7[0] ? $switches7[0]["timestamp"] : ($switches8[0] ? $switches8[0]["timestamp"] : ($switches9[0] ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))
+ "member" => isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][0]) ? $switches6[0]["members"][0] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]))),
+ "member2" => isset($switches6[0]) ? (isset($switches6[0]["members"]) && isset($switches6[0]["members"][1]) ? $switches6[0]["members"][1] : null) : (isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]))),
+ "date" => strtotime(isset($switches6[0]) ? $switches6[0]["timestamp"] : (isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))))
];
$fronters = array_unique($fronters, SORT_REGULAR);
@@ -242,6 +270,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
@@ -251,13 +283,15 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches6);
$fronters[] = [
- "member" => $switches7[0] ? $switches7[0]["members"][0] : ($switches8[0] ? $switches8[0]["members"][0] : ($switches9[0] ? $switches9[0]["members"][0] : $switches10[0]["members"][0])),
- "date" => strtotime($switches7[0] ? $switches7[0]["timestamp"] : ($switches8[0] ? $switches8[0]["timestamp"] : ($switches9[0] ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))
+ "member" => isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][0]) ? $switches7[0]["members"][0] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0])),
+ "member2" => isset($switches7[0]) ? (isset($switches7[0]["members"]) && isset($switches7[0]["members"][1]) ? $switches7[0]["members"][1] : null) : (isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1])),
+ "date" => strtotime(isset($switches7[0]) ? $switches7[0]["timestamp"] : (isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])))
];
$fronters = array_unique($fronters, SORT_REGULAR);
@@ -272,6 +306,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
@@ -281,13 +319,15 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches7);
$fronters[] = [
- "member" => $switches8[0] ? $switches8[0]["members"][0] : ($switches9[0] ? $switches9[0]["members"][0] : $switches10[0]["members"][0]),
- "date" => strtotime($switches8[0] ? $switches8[0]["timestamp"] : ($switches9[0] ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))
+ "member" => isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][0]) ? $switches8[0]["members"][0] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0]),
+ "member2" => isset($switches8[0]) ? (isset($switches8[0]["members"]) && isset($switches8[0]["members"][1]) ? $switches8[0]["members"][1] : null) : (isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1]),
+ "date" => strtotime(isset($switches8[0]) ? $switches8[0]["timestamp"] : (isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"]))
];
$fronters = array_unique($fronters, SORT_REGULAR);
@@ -302,6 +342,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
@@ -311,13 +355,15 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches8);
$fronters[] = [
- "member" => $switches9[0] ? $switches9[0]["members"][0] : $switches10[0]["members"][0],
- "date" => strtotime($switches9[0] ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])
+ "member" => isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][0]) ? $switches9[0]["members"][0] : null) : $switches10[0]["members"][0],
+ "member2" => isset($switches9[0]) ? (isset($switches9[0]["members"]) && isset($switches9[0]["members"][1]) ? $switches9[0]["members"][1] : null) : $switches10[0]["members"][1],
+ "date" => strtotime(isset($switches9[0]) ? $switches9[0]["timestamp"] : $switches10[0]["timestamp"])
];
$fronters = array_unique($fronters, SORT_REGULAR);
@@ -332,6 +378,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
@@ -341,12 +391,14 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches9);
$fronters[] = [
- "member" => $switches10[0] ? $switches10[0]["members"][0] : getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][0],
+ "member" => isset($switches10[0]) ? $switches10[0]["members"][0] : getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][0],
+ "member2" => isset($switches10[0]) && isset($switches10[0]["members"]) && isset($switches10[0]["members"][1]) ? $switches10[0]["members"][1] : (isset(getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][1]) ? getSwitchBefore($switches9[count($switches9) - 1]["id"])["members"][1] : null),
"date" => strtotime($switches10[0] ? $switches10[0]["timestamp"] : getSwitchBefore($switches9[count($switches9) - 1]["id"])["timestamp"])
];
@@ -362,6 +414,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
@@ -371,6 +427,7 @@ function getMember(string $id) {
$fronters = array_map(function ($i) {
return [
"member" => $i["members"][0],
+ "member2" => $i["members"][1] ?? null,
"date" => strtotime($i["timestamp"])
];
}, $switches10);
@@ -387,6 +444,10 @@ function getMember(string $id) {
<a class="member-link" href="/<?= $member["name"] ?>">
<img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member['name']) . ".png") ? "-" . $member['name'] : "" ?>.png" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?>
</a>
+ <?php if (isset($fronter["member2"])): $member2 = getMember($fronter["member2"]); ?>
+ (with <a class="member-link" href="/<?= $member2["name"] ?>">
+ <img src="/assets/uploads/pt<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/uploads/pt-" . resolveMember($member2['name']) . ".png") ? "-" . $member2['name'] : "" ?>.png" style="width:24px;"> <?= $member2["display_name"] ?? $member2["name"] ?></a>)
+ <?php endif; ?>
</span>
</div>
<?php endforeach; ?>
diff --git a/includes/system/subsystem.php b/includes/system/subsystem.php
index 14d1b2a..372ad08 100644
--- a/includes/system/subsystem.php
+++ b/includes/system/subsystem.php
@@ -73,38 +73,12 @@ function getSubsystemByID(string $id) {
return $subsystem;
}
-function timeAgo($time): string {
- if (!is_numeric($time)) {
- $time = strtotime($time);
- }
-
- $periods = ["second", "minute", "hour", "day", "week", "month", "year", "age"];
- $lengths = array("60", "60", "24", "7", "4.35", "12", "100");
-
- $now = time();
-
- $difference = $now - $time;
- if ($difference <= 10 && $difference >= 0) {
- return $tense = "now";
- } elseif ($difference > 0) {
- $tense = "ago";
- } else {
- $tense = "later";
- }
-
- for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
- $difference /= $lengths[$j];
- }
-
- $difference = round($difference);
-
- $period = $periods[$j] . ($difference >1 ? "s" :'');
- return "{$difference} {$period} {$tense}";
-}
-
if (getSubsystemByID($subsystemID) === null) header("Location: /?error=Invalid subsystem ID") and die();
$subsystemData = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/$systemID-subsystem-$subsystemID.json"), true);
+global $subsystem;
+$subsystem = getSubsystemByID($subsystemID);
+
$title = $subsystemData["name"] . " · " . $systemCommonName; require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/header.php';
?>
diff --git a/includes/travelling.php b/includes/travelling.php
index bb24172..b74c826 100644
--- a/includes/travelling.php
+++ b/includes/travelling.php
@@ -1,13 +1,20 @@
<?php
$travelling = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling.json"), true);
+
+$json_cloudburst = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true);
+$json_raindrops = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true);
+
+if (!isset($json_cloudburst)) $json_cloudburst = [];
+if (!isset($json_raindrops)) $json_raindrops = [];
+
$members = [...array_map(function ($i) {
$i["_system"] = "ynmuc";
return $i;
-}, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/ynmuc-members.json"), true)), ...array_map(function ($i) {
+}, $json_cloudburst), ...array_map(function ($i) {
$i["_system"] = "gdapd";
return $i;
-}, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd-members.json"), true))];
+}, $json_raindrops)];
foreach ($members as $member) {
if (!isset($travelling[$member["id"]])) {
@@ -26,15 +33,15 @@ function withTravelers(array $members, string $system): array {
$i['system'] = $system;
return $i;
}, array_filter($members, function ($i) use ($travelling) {
- return !$travelling[$i['id']]['travelling'];
+ return !(isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling']);
})),
...array_filter(array_map(function ($i) use ($system) {
$i['system'] = $system === "gdapd" ? "ynmuc" : "gdapd";
return $i;
}, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . ($system === "gdapd" ? "ynmuc" : "gdapd") . "-members.json"), true)), function ($i) use ($travelling) {
- return $travelling[$i['id']]['travelling'];
+ return isset($travelling[$i['id']]) && $travelling[$i['id']]['travelling'];
})
];
}
-file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling.json", json_encode($travelling, JSON_PRETTY_PRINT)); \ No newline at end of file
+file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/travelling.json", utf8_encode(json_encode($travelling, JSON_PRETTY_PRINT))); \ No newline at end of file
diff --git a/includes/wakeup.php b/includes/wakeup.php
new file mode 100644
index 0000000..587e705
--- /dev/null
+++ b/includes/wakeup.php
@@ -0,0 +1,114 @@
+<h2>Wake-up alert
+ <details style="display: inline-block;font-size:12px;">
+ <summary class="text-muted" style="opacity:.5;"></summary>
+ <label><input id="test-mode" type="checkbox"> Test Mode</label> · <label><input id="fake-requests" type="checkbox"> Fake Requests</label>
+ </details>
+</h2>
+
+<span data-bs-toggle="modal" data-bs-target="#turn-on" id="btn-on" style="background: #7f0000;font-size: 48px;padding: 10px 50px;border-radius: 10px;width: max-content;display: block;margin-left: auto;margin-right: auto;cursor: pointer;">Turn <b>ON</b></span>
+<span onclick="disableAlert()" id="btn-off" style="display:none;background: #007f0b;font-size: 48px;padding: 10px 50px;border-radius: 10px;width: max-content;margin-left: auto;margin-right: auto;cursor: pointer;">Turn <b>OFF</b></span>
+<p style="text-align:center;margin-top:10px;">Sending next notification <b><span id="next-notification">never</span></b></p>
+
+<style>
+ .modal-header {
+ border-bottom: 1px solid #353738;
+ }
+
+ .modal-content {
+ border: 1px solid rgba(255, 255, 255, .2);
+ background-color: #111;
+ }
+
+ .btn-close {
+ filter: invert(1);
+ }
+</style>
+
+<div class="modal fade" id="turn-on">
+ <div class="modal-dialog">
+ <div class="modal-content">
+
+ <div class="modal-header">
+ <h4 class="modal-title">Somepony will be awoken.</h4>
+ <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
+ </div>
+
+ <div class="modal-body">
+ <button onclick="enableAlert();" data-bs-dismiss="modal" class="btn btn-success" style="font-size:20px;font-weight:bold;display:block;width:100%;">I wish to proceed.</button>
+
+ <hr>
+
+ <div class="alert alert-warning">
+ This alert system is designed to emit sudden alerts, and may surprise somecreature if e.g. they are sleeping. Keep that in mind.
+ </div>
+
+ <p>
+ <b>Disclaimer:</b> This is NOT an emergency alert system, use the "Emergency alert" option is you need immediate help and comfort.
+ </p>
+ <p>
+ © <?= date('Y') ?> Equestria.dev
+ </p>
+ </div>
+ </div>
+ </div>
+</div>
+
+<script>
+ window.alertInterval = null;
+ window.alertIntervalCounter = 15;
+
+ function sendNotification() {
+ window.alertIntervalCounter = -1;
+
+ if (document.getElementById("test-mode").checked) {
+ document.getElementById("next-notification").innerText = "now";
+ if (document.getElementById("fake-requests").checked) {
+ window.alertIntervalCounter = 15;
+ document.getElementById("next-notification").innerText = "15 seconds";
+ } else {
+ window.fetch("/api/wakeup").then(() => {
+ window.alertIntervalCounter = 15;
+ document.getElementById("next-notification").innerText = "15 seconds";
+ })
+ }
+ } else {
+ document.getElementById("next-notification").innerText = "now";
+ if (document.getElementById("fake-requests").checked) {
+ window.alertIntervalCounter = 15;
+ document.getElementById("next-notification").innerText = "15 seconds";
+ } else {
+ window.fetch("/api/wakeup-real").then(() => {
+ window.alertIntervalCounter = 15;
+ document.getElementById("next-notification").innerText = "15 seconds";
+ })
+ }
+ }
+ }
+
+ function enableAlert() {
+ sendNotification();
+ document.getElementById("btn-on").style.display = "none";
+ document.getElementById("btn-off").style.display = "block";
+ document.getElementById("test-mode").disabled = true;
+ document.getElementById("fake-requests").disabled = true;
+
+ window.alertInterval = setInterval(() => {
+ window.alertIntervalCounter--;
+
+ if (window.alertIntervalCounter === 0) {
+ sendNotification();
+ } else if (window.alertIntervalCounter > -1) {
+ document.getElementById("next-notification").innerText = window.alertIntervalCounter + " second" + (window.alertIntervalCounter > 1 ? "s" : "");
+ }
+ }, 1000);
+ }
+
+ function disableAlert() {
+ clearInterval(window.alertInterval);
+ document.getElementById("next-notification").innerText = "never";
+ document.getElementById("btn-on").style.display = "block";
+ document.getElementById("btn-off").style.display = "none";
+ document.getElementById("test-mode").disabled = false;
+ document.getElementById("fake-requests").disabled = false;
+ }
+</script> \ No newline at end of file