0) { $myId = $fronters[0]["id"]; } else { $myId = "zdtsg"; } if ((isset($_GET["create"]) || isset($_GET["delete"])) && isset($parts[2])) { $account = array_values(array_filter($accounts, function ($i) use ($parts) { return $i["_name"] === $parts[2]; }))[0]; header("Content-Type: text/plain"); if (isset($_GET["create"])) { if (!(isset($_GET["amount"]) && is_numeric($_GET["amount"]) && (float)$_GET["amount"] < 9999 && (float)$_GET["amount"] > -9999)) { header("Location: /-/money/" . $parts[2]); die(); } if (!isset($_GET["description"])) $_GET["description"] = ""; $_GET["description"] = substr($_GET["description"], 0, 150); $ntfy = $GLOBALS["ColdHazeApp"]["ntfy"]; file_get_contents('https://' . $ntfy["server"] . '/' . $ntfy["topic"], false, stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => "Content-Type: text/plain\r\n" . "Title: " . formatPonypush((getMember($myId)["display_name"] ?? getMember($myId)["name"]) . " created a transaction to " . $account["name"] . " (" . ucfirst($account["owner"]) . ")") . "\r\n" . "Tags: bits\r\n" . "Authorization: Basic " . base64_encode($ntfy["user"] . ":" . $ntfy["password"]), 'content' => formatPonypush(($account["currency"] === "gbp" ? "£" : "€") . abs((float)$_GET["amount"]) . " were " . ((float)$_GET["amount"] >= 0 ? "added" : "removed") . " just now" . (trim($_GET["description"]) !== "" ? ": " . $_GET["description"] : "")) ] ])); if ((float)$_GET["amount"] !== 0.0) array_unshift($account["transactions"], [ "author" => $myId, "description" => $_GET["description"], "amount" => (float)$_GET["amount"], "date" => date('c') ]); $name = $account["_name"]; unset($account["_name"]); file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/money/" . $name . ".json", json_encode($account, JSON_PRETTY_PRINT)); } else { if (isset($_GET["id"]) && is_numeric($_GET["id"]) && isset($account["transactions"][(int)$_GET["id"]])) { $ntfy = $GLOBALS["ColdHazeApp"]["ntfy"]; file_get_contents('https://' . $ntfy["server"] . '/' . $ntfy["topic"], false, stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => "Content-Type: text/plain\r\n" . "Title: " . formatPonypush((getMember($myId)["display_name"] ?? getMember($myId)["name"]) . " deleted a transaction from " . $account["name"] . " (" . ucfirst($account["owner"]) . ")") . "\r\n" . "Tags: bits\r\n" . "Authorization: Basic " . base64_encode($ntfy["user"] . ":" . $ntfy["password"]), 'content' => formatPonypush(($account["currency"] === "gbp" ? "£" : "€") . abs((float)$account["transactions"][(int)$_GET["id"]]["amount"]) . " " . ((float)$account["transactions"][(int)$_GET["id"]]["amount"] >= 0 ? "advance" : "withdrawal") . " created by " . (getMemberWithoutSystem($account["transactions"][(int)$_GET["id"]]["author"])["display_name"] ?? getMemberWithoutSystem($account["transactions"][(int)$_GET["id"]]["author"])["name"]) . " " . timeAgo($account["transactions"][(int)$_GET["id"]]["date"])) ] ])); unset($account["transactions"][(int)$_GET["id"]]); $name = $account["_name"]; unset($account["_name"]); file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/money/" . $name . ".json", json_encode($account, JSON_PRETTY_PRINT)); } } header("Location: /-/money/" . $parts[2]); die(); } $rate = (float)trim(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/exchange.txt")); require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc'; $transactionMonths = []; foreach ($accounts as $account) { array_push($transactionMonths, ...array_map(function ($i) { return date('Y-m', strtotime($i["date"])); }, array_filter($account["transactions"], function ($i) { return !isset($i["initial"]) || !$i["initial"]; }))); } $months = [ ...[ "2022-12", "2022-11", "2022-10", "2022-09", "2022-08", "2022-07", "2022-06" ], ...array_values(array_filter(array_unique(array_reduce($transactionMonths, function ($a, $b) { return [...$a, $b]; }, [])), function ($i) { return $i !== date('Y-m'); })) ]; $monthlyCloudburst = []; $monthlyRaindrops = []; $bits = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/bits.json"), true); $projects = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/projects.json"), true); foreach ($bits["cloudburst"] as $month => $value) { $monthlyCloudburst[$month] = $value; } foreach ($bits["raindrops"] as $month => $value) { $monthlyRaindrops[$month] = $value; } foreach ($months as $month) { $gainedCloudburst = $monthlyCloudburst[$month] ?? 0; $gainedRaindrops = $monthlyRaindrops[$month] ?? 0; foreach ($accounts as $account) { foreach ($account["transactions"] as $transaction) { if (isset($transaction["initial"]) && $transaction["initial"]) continue; if (date('Y-m', strtotime($transaction["date"])) !== $month) continue; if ($account["owner"] === "raindrops") { $gainedRaindrops += $transaction["amount"]; } else { $gainedCloudburst += $transaction["amount"]; } } } $monthlyCloudburst[$month] = $gainedCloudburst; $monthlyRaindrops[$month] = $gainedRaindrops; } uksort($monthlyCloudburst, function ($k1, $k2) { return strtotime($k2) - strtotime($k1); }); uksort($monthlyRaindrops, function ($k1, $k2) { return strtotime($k2) - strtotime($k1); }); function getMonthlyEarnings(): array { global $monthlyRaindrops; global $monthlyCloudburst; return [ "cloudburst" => array_sum(array_values($monthlyCloudburst)) / count($monthlyCloudburst), "raindrops" => array_sum(array_values($monthlyRaindrops)) / count($monthlyRaindrops) ]; } ?>

Money tracker

The Ponycule money tracker is deprecated and will be removed. Data currently in the money tracker will be moved to individual accounts on a dedicated money tracking application that Equestria.dev will not have control over.

£ · €

As of · €1.00 = £


Cloudburst System (£, earning £/month)

Show monthly earnings $value): ?>
: ">£
$account): if ($account["owner"] === "cloudburst"): ?> ">

Default · % interests
Max balance: (% used)
No maximum balance
$minimumCloudburst) { $part2 = ($allAccounts - $minimumCloudburst) / $allAccounts; $part1 = 1 - $part2; $difference = $allAccounts - $minimumCloudburst; } else { $part1 = 1; $part2 = 0; $difference = $minimumCloudburst - $allAccounts; } ?>

">£ $minimumCloudburst): ?> (%) $minimumCloudburst ? "over" : "under" ?> the minimum

" style="width: 100%;">

%">
0): $months = ceil($missing / getMonthlyEarnings()["cloudburst"]); ?>
Costs £ · Missing £ · Can afford it in (in month 1 ? "s" : "" ?>)
You can afford it now, this will take you to the minimum.
You can afford it now, this will take you £ above the minimum.

Raindrops System (, earning €/month)

Show monthly earnings $value): ?>
: ">€
$account): if ($account["owner"] === "raindrops"): ?> ">

Default · % interests
Max balance: (% used)
No maximum balance
$minimumRaindrops) { $part2 = ($allAccounts - $minimumRaindrops) / $allAccounts; $part1 = 1 - $part2; $difference = $allAccounts - $minimumRaindrops; } else { $part1 = 1; $part2 = 0; $difference = $minimumRaindrops - $allAccounts; } ?>

">€ $minimumRaindrops): ?> (%) $minimumRaindrops ? "over" : "under" ?> the minimum

" style="width: 100%;">

%">
0): $months = ceil($missing / getMonthlyEarnings()["raindrops"]); ?>
Costs € · Missing € · Can afford it in (in month 1 ? "s" : "" ?>)
You can afford it now, this will take you to the minimum.
You can afford it now, this will take you € above the minimum.

· (default) " style="float:right;margin-top:5px;vertical-align:middle;opacity:1 !important; ">Back

Maximum balance: (% used)No maximum balance
Interests: % interestsNone

" style="filter: invert(1); margin-right: 10px; height: 32px; width: 32px;">
Add new transaction
$transaction): $member = getMemberWithoutSystem($transaction["author"]) ?? getMemberWithoutSystem("zdtsg"); ?>
" style="border-radius: 999px; width: 32px; height: 32px; margin-right: 10px;">
 "> : rounded-pill">Initial amount