2023-05-30 16:44:01 +03:00
|
|
|
|
|
|
|
<?php
|
|
|
|
|
|
|
|
ini_set('display_errors', '1');
|
|
|
|
ini_set('display_startup_errors', '1');
|
|
|
|
error_reporting(E_ALL);
|
|
|
|
|
|
|
|
class YGGwave {
|
|
|
|
|
|
|
|
public static function getSignals() {
|
|
|
|
|
|
|
|
$result = [];
|
|
|
|
|
|
|
|
if ($signals = file_get_contents('SIGNALS/YGGDRASIL.md')) {
|
|
|
|
|
|
|
|
foreach (explode(PHP_EOL, $signals) as $signal) {
|
|
|
|
|
|
|
|
if (preg_match('/\[(.*?)\]\((.*?)\)/ui', $signal, $data)) {
|
|
|
|
|
|
|
|
if (!empty($data[1]) && !empty($data[2])) {
|
|
|
|
|
|
|
|
if ($host = parse_url($data[2], PHP_URL_HOST)) {
|
|
|
|
|
2023-05-31 18:39:23 +03:00
|
|
|
$hash = crc32($data[2]);
|
2023-05-30 16:44:01 +03:00
|
|
|
|
|
|
|
$result[] = sprintf('<div style="top:%s%%;left:%s%%">%s</div>',
|
|
|
|
self::_getSignalPosition($hash),
|
2023-05-31 19:37:15 +03:00
|
|
|
self::_getSignalPosition($hash, true),
|
2023-05-30 16:44:01 +03:00
|
|
|
sprintf('<a target="_blank"
|
|
|
|
href="%s"
|
|
|
|
title="%s">%s</a>', htmlspecialchars($data[2]),
|
|
|
|
htmlentities($data[1]),
|
|
|
|
sprintf('<img src="/yggo/file.php?type=identicon&query=%s"
|
|
|
|
alt="%s"
|
|
|
|
style="%s" />', urlencode($host),
|
|
|
|
htmlentities($data[1]),
|
|
|
|
sprintf('background:#%s', substr(dechex($hash), 0, 6)))));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2023-06-04 18:56:29 +03:00
|
|
|
public static function getMetaKeywords() {
|
|
|
|
|
|
|
|
$keywords = [];
|
|
|
|
|
|
|
|
if ($signals = file_get_contents('SIGNALS/YGGDRASIL.md')) {
|
|
|
|
|
|
|
|
foreach (explode(PHP_EOL, $signals) as $signal) {
|
|
|
|
|
|
|
|
if (preg_match('/\[(.*?)\]\((.*?)\)/ui', $signal, $data)) {
|
|
|
|
|
2023-06-04 19:26:31 +03:00
|
|
|
if (!empty($data[1]) && !empty($data[2])) {
|
|
|
|
|
|
|
|
// Link description tags
|
|
|
|
if (preg_match_all('/[A-z0-9]{3,}/ui', $data[1], $matches)) {
|
|
|
|
|
|
|
|
foreach ($matches[0] as $keyword) {
|
|
|
|
|
|
|
|
$keyword = trim($keyword);
|
2023-06-05 11:53:52 +03:00
|
|
|
|
2023-06-04 19:26:31 +03:00
|
|
|
$keyword = mb_strtolower($keyword);
|
2023-06-05 11:53:52 +03:00
|
|
|
$keyword = htmlentities($keyword);
|
|
|
|
|
|
|
|
if (isset($keywords[$keyword])) {
|
|
|
|
$keywords[$keyword]++;
|
|
|
|
} else {
|
|
|
|
$keywords[$keyword] = 1;
|
|
|
|
}
|
2023-06-04 19:26:31 +03:00
|
|
|
}
|
|
|
|
}
|
2023-06-04 18:56:29 +03:00
|
|
|
|
2023-06-04 19:26:31 +03:00
|
|
|
// URI-based tags
|
2023-06-04 18:56:29 +03:00
|
|
|
if ($query = parse_url($data[2], PHP_URL_PATH)) {
|
|
|
|
|
|
|
|
foreach (explode('/', $query) as $keyword) {
|
|
|
|
|
|
|
|
$keyword = trim($keyword);
|
|
|
|
|
|
|
|
if (!empty($keyword)) {
|
|
|
|
|
|
|
|
$keyword = mb_strtolower($keyword);
|
2023-06-05 11:53:52 +03:00
|
|
|
$keyword = htmlentities($keyword);
|
|
|
|
|
|
|
|
if (isset($keywords[$keyword])) {
|
|
|
|
$keywords[$keyword]++;
|
|
|
|
} else {
|
|
|
|
$keywords[$keyword] = 1;
|
|
|
|
}
|
|
|
|
}
|
2023-06-04 18:56:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 11:53:52 +03:00
|
|
|
// Display keyword has count > n
|
|
|
|
$result = [];
|
|
|
|
foreach ($keywords as $keyword => $quantity) {
|
|
|
|
|
|
|
|
// if ($quantity > 1) @TODO
|
|
|
|
$result[] = $keyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
return implode(', ', $result);
|
2023-06-04 18:56:29 +03:00
|
|
|
}
|
|
|
|
|
2023-05-31 19:37:15 +03:00
|
|
|
private static function _getSignalPosition(int $hash, bool $reverse = false, int $padding = 20) {
|
2023-05-30 16:44:01 +03:00
|
|
|
|
2023-05-31 19:37:15 +03:00
|
|
|
$variant = $reverse ? array_reverse(str_split($hash, 2)) : str_split($hash, 2);
|
2023-05-30 16:44:01 +03:00
|
|
|
|
|
|
|
$version = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
2023-05-30 20:32:27 +03:00
|
|
|
if (!isset($variant[$version])) return rand($padding, 100 - $padding); // :)
|
2023-05-30 16:44:01 +03:00
|
|
|
|
2023-06-01 00:37:05 +03:00
|
|
|
$position = $variant[$version];
|
|
|
|
|
|
|
|
$version++;
|
2023-05-30 16:44:01 +03:00
|
|
|
|
|
|
|
} while ($position < $padding || $position > 100 - $padding);
|
|
|
|
|
|
|
|
return $position;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
?>
|
|
|
|
<!DOCTYPE html>
|
|
|
|
<html lang="en-US">
|
|
|
|
<head>
|
2023-05-31 15:17:55 +03:00
|
|
|
<title>YGGwave ~ The Radio Catalog</title>
|
2023-06-04 19:48:09 +03:00
|
|
|
<meta name="description" content="Open, Javascript-less Radio Hub https://github.com/YGGverse/YGGwave" />
|
2023-06-04 18:56:29 +03:00
|
|
|
<meta name="keywords" content="<?php echo YGGwave::getMetaKeywords() ?>" />
|
2023-05-30 16:44:01 +03:00
|
|
|
<meta charset="utf-8" />
|
|
|
|
<style>
|
|
|
|
|
2023-05-30 20:12:57 +03:00
|
|
|
@font-face {
|
|
|
|
font-family: 'ThasadithRegular';
|
|
|
|
src: url('./fonts/Thasadith/Thasadith-Regular.eot');
|
|
|
|
src: url('./fonts/Thasadith/Thasadith-Regular.eot?#iefix') format('embedded-opentype'),
|
|
|
|
url('./fonts/Thasadith/Thasadith-Regular.woff2') format('woff2'),
|
|
|
|
url('./fonts/Thasadith/Thasadith-Regular.woff') format('woff'),
|
|
|
|
url('./fonts/Thasadith/Thasadith-Regular.ttf') format('truetype');
|
|
|
|
}
|
|
|
|
|
2023-05-30 16:44:01 +03:00
|
|
|
* {
|
|
|
|
border: 0;
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
color: #fff;
|
|
|
|
text-decoration: none;
|
2023-05-30 20:12:57 +03:00
|
|
|
font-family: ThasadithRegular, Sans-serif;
|
2023-05-30 16:44:01 +03:00
|
|
|
font-weight: lighter;
|
2023-05-30 22:22:51 +03:00
|
|
|
transition: all .5s ease-in;
|
2023-05-30 16:44:01 +03:00
|
|
|
-moz-transition: all .5s ease-in;
|
|
|
|
-o-transition: all .5s ease-in;
|
2023-05-30 22:22:51 +03:00
|
|
|
-webkit-transition: all .5s ease-in;
|
2023-05-30 16:44:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
main {
|
|
|
|
position: absolute;
|
|
|
|
top: 0;
|
|
|
|
bottom: 0;
|
|
|
|
left: 0;
|
|
|
|
right: 0;
|
|
|
|
background-image: linear-gradient(to right top, #041b41, #003e68, #00658d, #008eac, #2ab8c6);
|
|
|
|
padding: 36px;
|
|
|
|
}
|
|
|
|
|
|
|
|
main > h1 > sup > a, main > h1 > sup > a:active, main > h1 > sup > a:visited {
|
|
|
|
opacity:0.8;
|
|
|
|
}
|
|
|
|
|
2023-05-30 16:55:25 +03:00
|
|
|
main p {
|
2023-05-30 20:12:57 +03:00
|
|
|
margin-left: 6px;
|
2023-05-30 16:55:25 +03:00
|
|
|
}
|
|
|
|
|
2023-05-30 16:44:01 +03:00
|
|
|
main > div > a, main > div > a:active, main > div > a:visited {
|
|
|
|
display: block;
|
|
|
|
padding: 4px;
|
|
|
|
width: 24px;
|
|
|
|
height: 24px;
|
|
|
|
border-radius: 50%;
|
|
|
|
border: 1px rgba(255, 255, 255, 0.36) solid;
|
|
|
|
}
|
|
|
|
|
|
|
|
main > div > a > img {
|
|
|
|
border-radius: 50%;
|
|
|
|
border: 2px rgba(255, 255, 255, 0.68) solid;
|
|
|
|
padding: 2px
|
|
|
|
}
|
|
|
|
|
|
|
|
main > div {
|
|
|
|
position: absolute;
|
|
|
|
opacity: 0.8;
|
|
|
|
}
|
|
|
|
|
|
|
|
main > div:hover {
|
|
|
|
opacity: 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<main>
|
2023-05-30 16:51:49 +03:00
|
|
|
<h1>YGGwave<sup><a href="https://github.com/YGGverse/YGGwave/tree/main/SIGNALS" style="color:#<?php echo substr(dechex(crc32(microtime())), 0, 6) ?>">~</a></sup></h1>
|
2023-05-31 15:17:55 +03:00
|
|
|
<p>the radio catalog</p>
|
2023-05-30 16:44:01 +03:00
|
|
|
<?php foreach (YGGwave::getSignals() as $signal) { ?>
|
|
|
|
<?php echo $signal ?>
|
|
|
|
<?php } ?>
|
|
|
|
</main>
|
|
|
|
</body>
|
|
|
|
</html>
|