mane
Mia Raindrops 3 months ago
parent c9de96328e
commit e72d0adbcd
Signed by: Mia Raindrops
GPG Key ID: EFBDC68435A574B7

@ -0,0 +1,19 @@
# TODO
- [ ] Make all pony heads the same size (square)
- [ ] Add a "similar pages" section in the navigation bar
----
- [x] <s>Remove "Sensitivity" item</s>
- [x] <s>Rename "Sexually active" to "Preemptive sexual consent"</s>
- [x] <s>Add romantic/sexual alignments</s>
- [x] <s>Aromantic/asexual (default), straight, gay/lesbian (pick automatically depending on gender), bi, pan</s>
- [x] <s>Leave some bits for potentially more options</s>
- [x] <s>Toggles for sexual polyamory, romantic polyamory, or both</s>
- [x] <s>Actually remove deprecated values</s>
- [x] <s>Allow caretakers for younger ponies (not just littles)</s>
- [x] <s>Redesign the "systems rules" page</s>
- [x] <s>Add Markdown support</s>
- [x] <s>Redesign the bitset calculator</s>
- [x] <s>Redesign the "front planner" page</s>

@ -0,0 +1,76 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/bitset.inc";
if (!isset($_GET["id"])) die();
if (isset($_GET["config"])) {
$data = [];
$keys = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/permitted.json"), true);
$proceed = false;
if (in_array($_GET["id"], array_keys($keys))) {
$proceed = true;
$fronters = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $keys[$_GET["id"]]["system"] . "/fronters.json"), true)["members"];
if (count($fronters) > 0) {
$fronter = $fronters[0];
$info = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/" . $fronter["id"] . ".json"), true);
$info = parseMetadata($info);
if (isset($info["birth"]["age"]) && $info["birth"]["age"] < 16 && $info["birth"]["age"] > 0) {
$proceed = false;
} else if (isset($info["birth"]["year"]) && $info["birth"]["year"] > 1900) {
if (!isset($info["birth"]["date"])) $info["birth"]["date"] = "01-01";
$age = (int)date('Y') - $info["birth"]["year"] + (strtotime(date('Y') . "-" . $info["birth"]["date"]) <= time() ? 0 : -1);
if ($age < 16) {
$proceed = false;
}
}
}
}
if ($proceed) {
$data = $keys[$_GET["id"]]["config"] ?? [];
}
} else {
$data = [
"success" => true,
"valid" => false,
"underage" => false,
"normal" => false
];
$keys = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/permitted.json"), true);
if (in_array($_GET["id"], array_keys($keys))) {
$data["valid"] = true;
$fronters = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/" . $keys[$_GET["id"]]["system"] . "/fronters.json"), true)["members"];
if (count($fronters) > 0) {
$fronter = $fronters[0];
$info = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/" . $fronter["id"] . ".json"), true);
$info = parseMetadata($info);
$data["normal"] = $info["sexually_active"];
if (isset($info["birth"]["age"]) && $info["birth"]["age"] < 16 && $info["birth"]["age"] > 0) {
$data["underage"] = true;
} else if (isset($info["birth"]["year"]) && $info["birth"]["year"] > 1900) {
if (!isset($info["birth"]["date"])) $info["birth"]["date"] = "01-01";
$age = (int)date('Y') - $info["birth"]["year"] + (strtotime(date('Y') . "-" . $info["birth"]["date"]) <= time() ? 0 : -1);
if ($age < 16) {
$data["underage"] = true;
}
}
}
}
}
die(json_encode($data));

@ -18,6 +18,7 @@ if (in_array($toplevel, ["editor", "icons", "species", "uploads"])) {
header("Location: /?error=" . $lang["app"]["file"]) and die();
}
} elseif ($toplevel === "") {
$pageFile = $_SERVER['DOCUMENT_ROOT'] . "/pages/home.inc";
require_once $_SERVER['DOCUMENT_ROOT'] . "/pages/home.inc";
} else {
if ($toplevel === "-") {
@ -25,12 +26,14 @@ if (in_array($toplevel, ["editor", "icons", "species", "uploads"])) {
$toplevel = explode("/", $pagename)[0];
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $toplevel . ".inc")) {
$pageFile = $_SERVER['DOCUMENT_ROOT'] . "/pages/" . $toplevel . ".inc";
require_once $_SERVER['DOCUMENT_ROOT'] . "/pages/" . $toplevel . ".inc";
} else {
header("Location: /?error=" . $lang["app"]["page"] . " " . strip_tags($pagename)) and die();
}
} else if ($toplevel === "api") {
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $toplevel . ".inc")) {
$pageFile = $_SERVER['DOCUMENT_ROOT'] . "/pages/" . $toplevel . ".inc";
require_once $_SERVER['DOCUMENT_ROOT'] . "/pages/" . $toplevel . ".inc";
}
} else if ($toplevel === "cloudburst" || $toplevel === "raindrops") {
@ -50,6 +53,7 @@ if (in_array($toplevel, ["editor", "icons", "species", "uploads"])) {
die();
}
$pageFile = $_SERVER['DOCUMENT_ROOT'] . "/pages/page.inc";
require_once $_SERVER['DOCUMENT_ROOT'] . "/pages/page.inc";
} else {
if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/pages/" . $toplevel . ".inc")) {
@ -63,9 +67,11 @@ if (in_array($toplevel, ["editor", "icons", "species", "uploads"])) {
}, json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/gdapd/members.json"), true)), "unknown-rd"];
if ((in_array($toplevel, $namesCloudburst) || in_array($toplevel, $namesRaindrops)) && $toplevel !== "unknown") {
$pageFile = $_SERVER['DOCUMENT_ROOT'] . "/pages/page.inc";
require_once $_SERVER['DOCUMENT_ROOT'] . "/pages/page.inc";
} else {
global $toplevel;
$pageFile = $_SERVER['DOCUMENT_ROOT'] . "/includes/short.inc";
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/short.inc";
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 493 KiB

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 KiB

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 807 KiB

After

Width:  |  Height:  |  Size: 807 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 KiB

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 KiB

After

Width:  |  Height:  |  Size: 462 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 KiB

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1021 KiB

After

Width:  |  Height:  |  Size: 1021 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 KiB

After

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 KiB

After

Width:  |  Height:  |  Size: 483 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 658 KiB

After

Width:  |  Height:  |  Size: 658 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

@ -127,6 +127,7 @@ let filesToCache = [
"/app/fronters/profiles/hpwyq.png",
"/app/fronters/profiles/irxyh.png",
"/app/fronters/profiles/jhemc.png",
"/app/fronters/profiles/jjzcb.png",
"/app/fronters/profiles/jlpjf.png",
"/app/fronters/profiles/jmasq.png",
"/app/fronters/profiles/jnbae.png",
@ -137,6 +138,7 @@ let filesToCache = [
"/app/fronters/profiles/kzfjn.png",
"/app/fronters/profiles/lllfw.png",
"/app/fronters/profiles/lqahp.png",
"/app/fronters/profiles/lqolg.png",
"/app/fronters/profiles/lyotd.png",
"/app/fronters/profiles/lzlaq.png",
"/app/fronters/profiles/mglyq.png",
@ -179,6 +181,7 @@ let filesToCache = [
"/app/fronters/profiles/ughya.png",
"/app/fronters/profiles/uhfic.png",
"/app/fronters/profiles/uicxr.png",
"/app/fronters/profiles/umbyl.png",
"/app/fronters/profiles/vahcl.png",
"/app/fronters/profiles/vaxyy.png",
"/app/fronters/profiles/vncoa.png",
@ -230,8 +233,10 @@ let filesToCache = [
"/assets/uploads/pt-applebloom.png",
"/assets/uploads/pt-babsseed.png",
"/assets/uploads/pt-blueberrycloud.png",
"/assets/uploads/pt-cinnamonfire.png",
"/assets/uploads/pt-cloudydreams.png",
"/assets/uploads/pt-coral.png",
"/assets/uploads/pt-cozyglow.png",
"/assets/uploads/pt-dahlia.png",
"/assets/uploads/pt-duskrainbow.png",
"/assets/uploads/pt-floralorchid.png",

@ -119,15 +119,15 @@ body {
}
.dropdown-menu {
background-color: #222;
background-color: #222 !important;
}
.dropdown-item:hover {
background-color: rgba(255, 255, 255, .1);
background-color: rgba(255, 255, 255, .1) !important;
}
.dropdown-item:active, .dropdown-item:focus {
background-color: rgba(255, 255, 255, .2);
background-color: rgba(255, 255, 255, .2) !important;
}
.dropdown-item {
@ -135,16 +135,16 @@ body {
}
.dropdown-icon {
filter: invert(1);
filter: invert(1) !important;
}
.dropdown-toggle .dropdown-icon {
opacity: .5;
transition: 200ms opacity;
opacity: .5; !important;
transition: 200ms opacity !important;
}
.dropdown-toggle:hover .dropdown-icon, .dropdown-toggle:active .dropdown-icon, .dropdown-toggle:focus .dropdown-icon {
opacity: .75;
opacity: .75 !important;
}
dd {
@ -596,7 +596,7 @@ peh-muted {
}
.dropdown-toggle::after {
margin-bottom: -3px;
margin-bottom: -3px !important;
}
.navbar-nav {
@ -621,10 +621,27 @@ peh-muted {
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-columns: repeat(5, 1fr);
text-align: center;
}
#member-details.member-details-loggedIn {
border-radius: 0;
padding-bottom: 0 !important;
}
#member-details-2 {
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
padding: 10px 20px;
text-align: center;
display: grid;
grid-template-columns: repeat(3, 1fr);
background: rgba(255, 255, 255, .1);
border: 1px solid transparent;
border-top: none;
}
.navbar-collapse.show {
z-index: 99999;
}
@ -646,6 +663,27 @@ peh-muted {
grid-template-columns: repeat(2, 1fr) !important;
text-align: left;
}
#member-details-2 {
grid-template-columns: repeat(2, 1fr) !important;
text-align: left;
}
.member-detail-desktop {
display: none !important;
}
.member-detail-mobile {
display: initial !important;
}
}
.member-detail-desktop {
display: initial;
}
.member-detail-mobile {
display: none;
}
.linked-card {

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because it is too large Load Diff

@ -367,14 +367,6 @@ 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["leader"] ?? false) && $isLoggedIn) {
$badges[] = [
"id" => "leader",

@ -4,27 +4,23 @@ function parseBitset ($bitset) {
$bin = str_repeat("0", 48 - strlen(decbin($bitset))) . decbin($bitset);
$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";
$sexuallyActive = substr($bin, 13, 1) !== "0";
$ageRegressor = substr($bin, 12, 1) !== "0";
$leader = substr($bin, 11, 1) !== "0";
$persecutor = substr($bin, 10, 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";
$polyamorous1 = substr($bin, 18, 1) !== "0";
$polyamorous2 = substr($bin, 19, 1) !== "0";
$species1 = substr($bin, 33, 4);
$species2 = substr($bin, 37, 4);
$species3 = substr($bin, 41, 4);
$alignment1 = substr($bin, 41, 4);
$alignment2 = substr($bin, 20, 4);
$species1 = match ($species1) {
"0001" => "earth",
@ -48,46 +44,57 @@ function parseBitset ($bitset) {
default => null,
};
$species3 = match ($species3) {
"0001" => "earth",
"0010" => "unicorn",
"0011" => "pegasus",
"0100" => "alicorn",
"0101" => "batpony",
"0110" => "crystal",
"0111" => "changeling",
$alignment1 = match ($alignment1) {
"0000" => "aroace",
"0001" => "hetero",
"0010" => "homo",
"0011" => "bi",
"0100" => "pan",
default => null,
};
if ($little === 1) {
$ageRegressor = true;
$little = 0;
}
$alignment2 = match ($alignment2) {
"0000" => "aroace",
"0001" => "hetero",
"0010" => "homo",
"0011" => "bi",
"0100" => "pan",
default => null,
};
if ($little === 1) $little = 0;
return [
'shared_memory' => $sharedMemory,
'median' => $median,
'median' => false,
'protector' => $protector,
'fictive' => $fictive,
'little' => $little,
'not_talking' => $notTalking,
'host' => $host,
'not_talking' => false,
'host' => false,
'robot' => $robot,
'magic' => $magic,
'sensitivity' => $sensitivity,
'magic' => 0,
'sensitivity' => 0,
'food' => $food,
'plush' => $plush,
'nonverbal' => $nonverbal,
'less_frequent' => $lessFrequent,
'age_spells' => $age,
'age_regressor' => $ageRegressor,
'age_spells' => false,
'age_regressor' => false,
'leader' => $leader,
'persecutor' => $persecutor,
'sexually_active' => $sexuallyActive,
'polyamorous' => [
'romantic' => $polyamorous1,
'sexual' => $polyamorous2
],
'alignment' => [
'romantic' => $alignment1,
'sexual' => $alignment2
],
'species' => array_filter([
$species1,
$species2,
$species3
$species2
], function ($i) {
return isset($i);
})

@ -1,40 +1,32 @@
<?php global $isLoggedIn; global $metadata; global $memberData; global $lang; global $pages; ?>
<?php global $isLoggedIn; global $metadata; global $memberData; global $lang; global $pages; $pronouns = getMemberPronouns($memberData['pronouns']); ?>
<div id="member-details" class="<?= $isLoggedIn ? 'member-details-loggedIn' : '' ?>" style="<?php if (!$isLoggedIn): ?>grid-template-columns: repeat(3, 1fr);<?php endif; ?> background-color: <?= isset($memberData["color"]) ? '#' . $memberData["color"] . "33" : "transparent" ?>; margin-left: -20px; margin-right: -20px;">
<div>
<b><?= $lang["details"]["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.'>" . $lang["details"]["food_states"][0] . "</span>",
1 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"])) . " can&apos;t eat fish or meat.'>" . $lang["details"]["food_states"][1] . "</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.'>" . $lang["details"]["food_states"][2] . "</span>",
3 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", getMemberPronouns($memberData['pronouns'])["subjective"])) . " can eat all foods, meat and fish included.'>" . $lang["details"]["food_states"][3] . "</span>",
0 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", $pronouns["possessive_det"])) . " species indicates that " . str_replace("'", "&apos;", $pronouns["subjective"]) . ' ' . ($pronouns["third"] ? "doesn&apos;t" : "don&apos;t") . " need to eat food, therefore " . str_replace("'", "&apos;", $pronouns["subjective"]) . " can eat all foods.'>" . $lang["details"]["food_states"][0] . "</span>",
1 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", $pronouns["subjective"])) . " can&apos;t eat fish or meat.'>" . $lang["details"]["food_states"][1] . "</span>",
2 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", $pronouns["subjective"])) . " can&apos;t eat meat, but can eat fish.'>" . $lang["details"]["food_states"][2] . "</span>",
3 => "<span data-bs-toggle='tooltip' title='" . ucfirst(str_replace("'", "&apos;", $pronouns["subjective"])) . " can eat all foods, meat and fish included.'>" . $lang["details"]["food_states"][3] . "</span>",
} ?>
</div>
<div>
<b><?= $lang["details"]["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.'>" . $lang["details"]["memory_states"][0] . "</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.'>" . $lang["details"]["memory_states"][1] . "</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.'>" . $lang["details"]["memory_states"][2] . "</span>",
0 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst($pronouns["subjective"])) . ($pronouns["third"] ? " doesn&apos;t directly share" : " don&apos;t directly share") . " memory with " . str_replace("'", "&apos;", $pronouns["possessive_det"]) . " headmates, but is able to (slowly) query it if that is needed.'>" . $lang["details"]["memory_states"][0] . "</span>",
1 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst($pronouns["subjective"])) . ($pronouns["third"] ? " doesn&apos;t directly shares" : " don&apos;t directly share") . " all memories with " . str_replace("'", "&apos;", $pronouns["possessive_det"]) . " headmates, but may be able to share certain memories and/or share memories at will.'>" . $lang["details"]["memory_states"][1] . "</span>",
2 => "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst($pronouns["subjective"])) . ($pronouns["third"] ? " shares" : " share") . " all memories with " . str_replace("'", "&apos;", $pronouns["possessive_det"]) . " headmates.'>" . $lang["details"]["memory_states"][2] . "</span>",
} ?>
</div>
<?php if ($isLoggedIn): ?>
<div>
<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.'>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 if ($metadata["birth"]["age"] === -1): $age = abs(log(0)); // => INF ?>
<?= "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst($pronouns["subjective"])) . " never age" . str_replace("'", "&apos;", $pronouns["third"] ? "s" : "") . " and " . str_replace("'", "&apos;", $pronouns["third"] ? "doesn't" : "don't") . " have a defined age, making " . str_replace("'", "&apos;", $pronouns["object"]) . " pretty much eternal.'>Eternal</span>" ?>
<?php elseif ($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 else: $age = $metadata["birth"]["age"]; ?>
<?= "<span data-bs-toggle='tooltip' title='" . str_replace("'", "&apos;", ucfirst($pronouns["subjective"])) . str_replace("'", "&apos;", $pronouns["third"] ? " doesn't" : " don't") . " age like the body does, making " . str_replace("'", "&apos;", $pronouns["object"]) . " stay " . $metadata["birth"]["age"] . " years old for " . str_replace("'", "&apos;", $pronouns["possessive_det"]) . " entire life.'>" . $metadata["birth"]["age"] . "* years old</span>" ?>
<?php endif; ?>
<?php else: ?>
<?php if ($metadata["birth"]["year"] <= 1900): ?>
@ -47,7 +39,8 @@
$birthdate = $metadata["birth"]["year"] . "-" . $metadata["birth"]["date"];
}
$age = floor((time() - strtotime($birthdate)) / 31557600);
$age = (int)date('Y') - $metadata["birth"]["year"] + (strtotime(date('Y') . "-" . $metadata["birth"]["date"]) <= time() ? 0 : -1);
$age2 = floor((time() - strtotime($birthdate)) / 31557600);
$birthday = "as time passes";
if (isset($metadata["birth"]["date"]) && trim($metadata["birth"]["date"]) !== "" && $metadata["birth"]["date"] !== "01-01") {
@ -55,7 +48,7 @@
}
?>
<?= "<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>" ?>
<?= "<span data-bs-toggle='tooltip' title='$age2 with the old algorithm | " . str_replace("'", "&apos;", ucfirst($pronouns["subjective"])) . " age" . str_replace("'", "&apos;", $pronouns["third"] ? "s" : "") . " like the body does, making " . str_replace("'", "&apos;", $pronouns["object"]) . " stay " . $age . " years old for now, having this age change $birthday.'>" . $age . " years old</span>" ?>
<?php endif; ?>
<?php endif; ?>
</div>
@ -76,4 +69,75 @@
-
<?php endif; ?>
</div>
</div>
</div>
<?php if ($isLoggedIn): ?>
<div id="member-details-2" style="background-color: <?= isset($memberData["color"]) ? '#' . $memberData["color"] . "33" : "transparent" ?>; margin-left: -20px; margin-right: -20px;">
<?php if ((isset($age) && $age >= 16 && $metadata["little"] === 0) || (!isset($age) && $metadata["little"] === 0)): ?>
<div>
<b>Sexual consent:</b><span class="member-small-separator"><br></span>
<?php if ($metadata["sexually_active"]): ?>
<span title="Consent is assumed when having sex with <?= $pronouns["object"] ?>, however <?= $pronouns["subjective"] ?> may ask to not have sex at the moment and such request must be honored." data-bs-toggle="tooltip">Preemptive</span>
<?php else: ?>
<span title="Consent is absolutely required every time when having sex with <?= $pronouns["object"] ?>." data-bs-toggle="tooltip">Required</span>
<?php endif; ?>
</div>
<div>
<b><span class="member-detail-desktop">Sexual alignment</span><span class="member-detail-mobile">Sex. algn.</span>:</b><span class="member-small-separator"><br></span>
<?php switch ($metadata["alignment"]["sexual"]) {
case "aroace":
echo "Asexual";
break;
case "hetero":
echo "Straight";
break;
case "homo":
echo $pronouns["subjective"] === "she" ? "Lesbian" : ($pronouns["subjective"] === "he" ? "Gay" : "Homosexual");
break;
case "bi":
echo "Bisexual";
break;
case "pan":
echo "Pansexual";
break;
} ?><?php if ($metadata["polyamorous"]["sexual"]): ?> (poly)<?php endif; ?>
</div>
<?php else: ?>
<div>
<style>
#member-details-2 {
grid-template-columns: 2fr 1fr;
}
</style>
<div style="display: flex; align-items: center; justify-content: center; height: 100%;opacity:.5;">This member is too young to have a sexual relationship.</div>
</div>
<?php endif; ?>
<div>
<b><span class="member-detail-desktop">Romantic alignment</span><span class="member-detail-mobile">Rom. algn.</span>:</b><span class="member-small-separator"><br></span>
<?php switch ($metadata["alignment"]["romantic"]) {
case "aroace":
echo "Aromantic";
break;
case "hetero":
echo "Heteroromantic";
break;
case "homo":
echo $pronouns["subjective"] === "she" ? "Lesbiromantic" : ($pronouns["subjective"] === "he" ? "Gay" : "Homoromantic");
break;
case "bi":
echo "Biromantic";
break;
case "pan":
echo "Panromantic";
break;
} ?><?php if ($metadata["polyamorous"]["romantic"]): ?> (poly)<?php endif; ?>
</div>
<!--<div>
<b>Item 4:</b><span class="member-small-separator"><br></span>
Value 4
</div>
<div>
<b>Item 5:</b><span class="member-small-separator"><br></span>
Value 5
</div>-->
</div>
<?php endif; ?>

@ -1,5 +1,6 @@
<?php
global $pageFile;
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.inc";
?>
@ -16,7 +17,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/functions.inc";
global $lang; global $pages;
?>
© <?= date("Y") ?> <a href="https://equestria.horse" target="_blank" class="text-muted"><?= $lang["footer"]["copyright"] ?></a> · version 2.<?= $version["build"] ?>.<?= hexdec(substr($version["hash"], 0, 4)) ?>.<?= $version["revision"] ?><br>
© <?= date("Y") ?> <a href="https://equestria.horse" target="_blank" class="text-muted"><?= $lang["footer"]["copyright"] ?></a> · version 2.<?= $version["build"] ?>.<?= $version["revision"] ?> · node <?= strtoupper(dechex(fileinode($pageFile))) ?><br>
<a href="/-/debug" class="text-muted" style="text-decoration: none;"><?= $lang["footer"]["update"] ?> <?= trim(timeAgo($refresh["timestamp"], $lang["_french"])) ?> (<?php if (time() - $refresh["timestamp"] > 360): ?><?= $lang["footer"]["no_update"] ?><?= $lang["footer"]["separator"] ?>; <?php endif; ?><?= date('D j M, G:i:s T', (int)$refresh["timestamp"]) ?><?= $lang["footer"]["separator"] ?>; <?= $lang["footer"]["took"] ?> <?= round($refresh["duration"] * 1000) ?> ms, <?= count($refresh["restored"]) > 0 ? (count($refresh["restored"]) > 1 ? $lang["footer"]["failures"][0] . count($refresh["restored"]) . $lang["footer"]["failures"][1] : $lang["footer"]["failure"]) : $lang["footer"]["no_failure"] ?>)</a>
<br><br><br><br><br>
</div>

@ -20,69 +20,6 @@
<b>This member's metadata needs an update.</b> It still uses the old JSON metadata system instead of the new 24bit integer-based system. Contact a developer to request an update. (only administrators can see this; file: <code><?= $_SERVER['DOCUMENT_ROOT'] ?>/includes/data/metadata/<?= $memberID ?>.json</code>)
</div>
<?php endif; ?>
<div class="alert alert-dark">
<details>
<summary>Private administrator information</summary>
<ul style="margin-bottom:0;">
<li><b>ID:</b> <code><?= $memberID ?></code> (<code><?= $systemID . "/" . $memberID ?></code>, <?= $memberData["name"] ?>)</li>
<li><b>Files:</b>
<ul>
<li><code><?= $_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$memberID.json" ?></code> (<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$memberID.json") ? filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$memberID.json") . " bytes" : "not found" ?>)</li>
<li><code><?= $_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID.html" ?></code> (<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID.html") ? filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID.html") . " bytes" : "not found" ?>)</li>
<li><code><?= $_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID-private.html" ?></code> (<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID-private.html") ? filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$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>
<li><b>Pronouns:</b> <?= implode(", ", getPronounsFromMark($memberData['pronouns'])) ?></li>
<li><b>Pronouns usage:</b> <ul><?php
foreach (getMemberPronouns($memberData['pronouns']) as $type => $usage) {
if (is_string($usage) && $type !== "color") {
echo("<li><b>" . $type . ":</b> " . $usage . "</li>");
}
}
?></ul></li>
<li><b>Color:</b> <span style="border:1px solid rgba(255, 255, 255, .5);background-color:#<?= $memberData["color"] ?? "ffffff" ?>;display:inline-block;width:16px;height:16px;border-radius:5px;vertical-align: middle;filter: invert(1) hue-rotate(180deg);"></span> <span style="vertical-align: middle;"><code>#<?= $memberData["color"] ?? "ffffff" ?></code></span>
<li><b>Bitset:</b><?php if (isset($metadata["bitset"])): ?> <code><?= str_repeat("0", 48 - strlen(decbin($metadata["bitset"]))) . decbin($metadata["bitset"]) ?></code> (0x<?= str_repeat("0", 12 - strlen(dechex($metadata["bitset"]))) . dechex($metadata["bitset"]) ?>, <?= $metadata["bitset"] ?>)</li><?php else: ?> <span class="text-warning" style="filter:invert(1) hue-rotate(180deg);">Not using bitset; please update.</span><?php endif; ?>
<li><b>Reduced name:</b> <?= getMiniName($memberData["display_name"] ?? $member["name"]) ?></li>
<li><b>Shared memory access:</b> <code><?= $metadata["shared_memory"] ?></code> (<?= $metadata["shared_memory"] === 2 ? "Full direct access" : ($metadata["shared_memory"] === 0 ? "No direct access" : "Partial direct access") ?>)</li>
<li><b>Protector:</b> <code><?= $metadata["protector"] ? "1" : "0" ?></code> (<?= $metadata["protector"] ? "Yes" : "No" ?>)</li>
<li><b>Little:</b> <code><?= $metadata["little"] ?></code> (<?= $metadata["little"] === 2 ? "Is a little" : ($metadata["little"] === 1 ? "Is an age regressor" : ($metadata["little"] === 3 ? "Not a little, but younger" : "No")) ?>)</li>
<li><b>Relations count:</b> <code><?= count($metadata["marefriends"]) + count($metadata["sisters"]) ?></code></li>
<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/score.inc"; $score = calculateScore($metadata, $memberData["display_name"] ?? $memberData["name"]); ?>
<li>
<b>Score breakdown:</b> <code><?= $score["total"] ?></code>
<ul><?php
foreach ($metadata as $type => $usage) {
if (is_string($usage)) {
echo("<li><b>" . $type . ":</b> " . $usage . "</li>");
} else if (is_array($usage)) {
if (count($usage) === 0) {
echo("<li><b>" . $type . ":</b> []</li>");
} else {
echo("<li><b>" . $type . ":</b><ul>");
foreach ($usage as $key => $item) {
if (is_string($item)) {
echo("<li><b>" . $key . ":</b> " . $item . "</li>");
} else {
echo("<li><b>" . $key . ":</b> " . json_encode($item, JSON_UNESCAPED_SLASHES) . "</li>");
}
}
echo("</ul></li>");
}
} else {
echo("<li><b>" . $type . ":</b> " . json_encode($usage, JSON_UNESCAPED_SLASHES) . "</li>");
}
}
?></ul></li>
</ul>
</details>
</div>
<?php endif; ?>
<?php if ($travelling[$memberID]['travelling'] && !$travelling[$memberID]['equestria']): ?>
<div class="alert alert-primary">

@ -196,18 +196,7 @@ 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];
return $ordered;
}
}

@ -0,0 +1,34 @@
<?php
$_SERVER['DOCUMENT_ROOT'] = "../..";
foreach (array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata"), function ($i) { return !str_starts_with($i, "."); }) as $file) {
$data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$file"), true);
echo("$file\n");
if (!isset($data["bitset"])) {
die(" No bitset?? wtf\n");
} else {
$bits = str_split(substr(str_repeat("0", 48), 0, 48 - strlen(decbin($data["bitset"]))) . decbin($data["bitset"]));
echo(" Old:\n");
echo(" " . str_replace("+", "\e[92m1\e[39m", str_replace("-", "\e[31m0\e[39m", implode("", str_replace("0", "-", str_replace("1", "+", $bits))))) . "\n");
echo(" XXXXXXXXXX X XXXXXX X XX XXXX X\n");
$bitsOld = implode("", $bits);
foreach ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 18, 19, 20, 21, 22, 23, 26, 31, 32, 41, 42, 43, 44, 47] as $bit) {
$bits[$bit] = "0";
}
echo(" New:\n");
echo(" " . str_replace("+", "\e[92m1\e[39m", str_replace("-", "\e[31m0\e[39m", implode("", str_replace("0", "-", str_replace("1", "+", $bits))))) . "\n");
echo(" XXXXXXXXXX X XXXXXX X XX XXXX X\n");
echo(" Changed " . levenshtein($bitsOld, implode("", $bits)) . " bit(s)\n");
echo(" Backup made in " . substr($file, 0, -5) . "-old.json\n");
copy($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$file", $_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/" . substr($file, 0, -5) . "-old.json");
$data["bitset"] = bindec(implode("", $bits));
echo(" Saved to " . $file . "\n");
file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$file", json_encode($data));
}
}

@ -78,7 +78,71 @@ if ($memberData["name"] === "fusion") {
</div>
<?php else: ?>
<?php global $isLoggedIn; if ($isLoggedIn): ?>
<small style="opacity:.5;display:block;">(edit: <a href="/-/metadata/<?= $system ?>/<?= $memberData['name'] ?>">metadata</a>, <a href="/-/edit/<?= $system ?>/<?= $memberData['name'] ?>">public</a>, <a href="/-/edit-private/<?= $system ?>/<?= $memberData['name'] ?>">private</a>)</small>
<details>
<summary style="list-style: none;">
<small style="opacity:.5;display:block;">(edit: <a href="/-/metadata/<?= $system ?>/<?= $memberData['name'] ?>">metadata</a>, <a href="/-/edit/<?= $system ?>/<?= $memberData['name'] ?>">public</a>, <a href="/-/edit-private/<?= $system ?>/<?= $memberData['name'] ?>">private</a>)</small>
</summary>
<div class="alert alert-dark">
<ul style="margin-bottom:0;">
<li><b>ID:</b> <code><?= $memberID ?></code> (<code><?= $systemID . "/" . $memberID ?></code>, <?= $memberData["name"] ?>)</li>
<li><b>Files:</b>
<ul>
<li><code><?= $_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$memberID.json" ?></code> (<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$memberID.json") ? filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/$memberID.json") . " bytes" : "not found" ?>)</li>
<li><code><?= $_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID.html" ?></code> (<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID.html") ? filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID.html") . " bytes" : "not found" ?>)</li>
<li><code><?= $_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID-private.html" ?></code> (<?= file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID-private.html") ? filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$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>
<li><b>Pronouns:</b> <?= implode(", ", getPronounsFromMark($memberData['pronouns'])) ?></li>
<li><b>Pronouns usage:</b> <ul><?php
foreach (getMemberPronouns($memberData['pronouns']) as $type => $usage) {
if (is_string($usage) && $type !== "color") {
echo("<li><b>" . $type . ":</b> " . $usage . "</li>");
}
}
?></ul></li>
<li><b>Color:</b> <span style="border:1px solid rgba(255, 255, 255, .5);background-color:#<?= $memberData["color"] ?? "ffffff" ?>;display:inline-block;width:16px;height:16px;border-radius:5px;vertical-align: middle;filter: invert(1) hue-rotate(180deg);"></span> <span style="vertical-align: middle;"><code>#<?= $memberData["color"] ?? "ffffff" ?></code></span>
<li><b>Bitset:</b><?php if (isset($metadata["bitset"])): ?> <code><?= str_repeat("0", 48 - strlen(decbin($metadata["bitset"]))) . decbin($metadata["bitset"]) ?></code> (0x<?= str_repeat("0", 12 - strlen(dechex($metadata["bitset"]))) . dechex($metadata["bitset"]) ?>, <?= $metadata["bitset"] ?>)</li><?php else: ?> <span class="text-warning" style="filter:invert(1) hue-rotate(180deg);">Not using bitset; please update.</span><?php endif; ?>
<li><b>Reduced name:</b> <?= getMiniName($memberData["display_name"] ?? $member["name"]) ?></li>
<li><b>Shared memory access:</b> <code><?= $metadata["shared_memory"] ?></code> (<?= $metadata["shared_memory"] === 2 ? "Full direct access" : ($metadata["shared_memory"] === 0 ? "No direct access" : "Partial direct access") ?>)</li>
<li><b>Protector:</b> <code><?= $metadata["protector"] ? "1" : "0" ?></code> (<?= $metadata["protector"] ? "Yes" : "No" ?>)</li>
<li><b>Little:</b> <code><?= $metadata["little"] ?></code> (<?= $metadata["little"] === 2 ? "Is a little" : ($metadata["little"] === 1 ? "Is an age regressor" : ($metadata["little"] === 3 ? "Not a little, but younger" : "No")) ?>)</li>
<li><b>Relations count:</b> <code><?= count($metadata["marefriends"]) + count($metadata["sisters"]) ?></code></li>
<?php require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/score.inc"; $score = calculateScore($metadata, $memberData["display_name"] ?? $memberData["name"]); ?>
<li>
<b>Score breakdown:</b> <code><?= $score["total"] ?></code>
<ul><?php
foreach ($metadata as $type => $usage) {
if (is_string($usage)) {
echo("<li><b>" . $type . ":</b> " . $usage . "</li>");
} else if (is_array($usage)) {
if (count($usage) === 0) {
echo("<li><b>" . $type . ":</b> []</li>");
} else {
echo("<li><b>" . $type . ":</b><ul>");
foreach ($usage as $key => $item) {
if (is_string($item)) {
echo("<li><b>" . $key . ":</b> " . $item . "</li>");
} else {
echo("<li><b>" . $key . ":</b> " . json_encode($item, JSON_UNESCAPED_SLASHES) . "</li>");
}
}
echo("</ul></li>");
}
} else {
echo("<li><b>" . $type . ":</b> " . json_encode($usage, JSON_UNESCAPED_SLASHES) . "</li>");
}
}
?></ul></li>
</ul>
</div>
</details>
<?php endif; ?>
<?php if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/content/$memberID-private.html") && $isLoggedIn): ?>

@ -53,13 +53,6 @@ $navigation_admin = [
"name" => $lang["navigation"]["apps"],
"minimal" => false,
"items" => [
[
"name" => $pages["dashboard"]["name"][$lang["_name"]],
"icon" => "/assets/icons/dashboard.svg",
"invert" => true,
"link" => "/-/dashboard",
"stepped" => null
],
[
"name" => $pages["about"]["name"][$lang["_name"]],