pizdets optimized

This commit is contained in:
Arsen Mirzaev Tatyano-Muradovich 2024-11-22 11:58:27 +07:00
parent 2effcfdf03
commit 1902967a70
230 changed files with 3243 additions and 792 deletions

2
.gitignore vendored
View File

@ -1,4 +1,2 @@
!.gitignore !.gitignore
composer.phar
composer.lock
vendor vendor

View File

@ -1,10 +1,11 @@
{ {
"name": "mirzaev/site-repression", "name": "mirzaev/site-repression",
"description": "", "description": "An article about how i was kidnapped by PMC Wagner operatives",
"readme": "README.md", "readme": "README.md",
"keywords": [ "keywords": [
"repression", "repression",
"site" "site",
"article"
], ],
"type": "site", "type": "site",
"homepage": "https://git.mirzaev.sexy/mirzaev/site-repression", "homepage": "https://git.mirzaev.sexy/mirzaev/site-repression",
@ -14,7 +15,7 @@
"name": "Arsen Mirzaev Tatyano-Muradovich", "name": "Arsen Mirzaev Tatyano-Muradovich",
"email": "arsen@mirzaev.sexy", "email": "arsen@mirzaev.sexy",
"homepage": "https://mirzaev.sexy", "homepage": "https://mirzaev.sexy",
"role": "Programmer" "role": "Victim"
} }
], ],
"support": { "support": {
@ -22,28 +23,16 @@
"issues": "https://git.mirzaev.sexy/mirzaev/site-repression/issues" "issues": "https://git.mirzaev.sexy/mirzaev/site-repression/issues"
}, },
"require": { "require": {
"php": "~8.3", "php": "~8.4",
"ext-sodium": "~8.3", "ext-sodium": "~8.4",
"mirzaev/minimal": "^2.2.0", "mirzaev/minimal": "^3.2.0",
"mirzaev/accounts": "~1.2.x-dev",
"mirzaev/arangodb": "^1.0.0",
"mirzaev/vk": "^4.0",
"triagens/arangodb": "~3.9.x-dev",
"twig/twig": "^3.4", "twig/twig": "^3.4",
"guzzlehttp/guzzle": "^7.5", "guzzlehttp/guzzle": "^7.5",
"ipinfo/ipinfo": "^3.0" "ipinfo/ipinfo": "^3.0"
}, },
"require-dev": {
"phpunit/phpunit": "~9.5"
},
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"mirzaev\\site\\repression\\": "mirzaev/site/repression/system" "mirzaev\\site\\repression\\": "mirzaev/site/repression/system"
} }
},
"autoload-dev": {
"psr-4": {
"mirzaev\\site\\repression\\tests\\": "mirzaev/site/repression/tests"
}
} }
} }

1687
composer.lock generated Executable file

File diff suppressed because it is too large Load Diff

53
examples/nginx/server.conf Executable file
View File

@ -0,0 +1,53 @@
server {
listen 80;
listen [::]:80;
server_name project;
# 301 302
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
listen 443 quic;
listen [::]:443 ssl;
listen [::]:443 quic;
server_name project;
http2 on;
http3 on;
quic_gso on;
quic_retry on;
add_header Alt-Svc 'h3=":$server_port"; ma=86400';
add_header x-quic 'h3';
root /var/www/project/mirzaev/site/repression/system/public;
index index.php;
keepalive_timeout 60;
include snippets/ssl-params.conf;
include snippets/ssl-mirzaev.conf;
include snippets/php8_4.conf;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|mp3|ogg|ogv|webm|htc|woff2|woff)$ {
expires 1M;
access_log off;
add_header Cache-Control "max-age=2629746, public";
}
location ~* \.(?:css|js)$ {
expires 1y;
access_log off;
add_header Cache-Control "max-age=31556952, public";
}
}

View File

@ -4,57 +4,78 @@ declare(strict_types=1);
namespace mirzaev\site\repression\controllers; namespace mirzaev\site\repression\controllers;
// Файлы проекта // Filtes of the project
use mirzaev\site\repression\views\manager; use mirzaev\site\repression\models\core as models,
use mirzaev\site\repression\models\core as models; mirzaev\site\repression\views\templater,
use mirzaev\site\repression\models\account_model as account; mirzaev\site\repression\models\enumerations\language;
use mirzaev\site\repression\models\session_model as session;
// Библиотека для ArangoDB // Framework for PHP
use ArangoDBClient\Document as _document; use mirzaev\minimal\core as minimal,
mirzaev\minimal\http\response,
// Фреймворк PHP mirzaev\minimal\controller;
use mirzaev\minimal\controller;
// Фреймворк ВКонтакте
use mirzaev\vk\core as vk;
use mirzaev\vk\robots\user as robot;
/** /**
* Ядро контроллеров * Core of controllers
* *
* @package mirzaev\site\repression\controllers * @package mirzaev\site\repression\controllers
*
* @param language $language Language
* @param response $response Response
* @param array $errors Registry of errors
*
* @method void __construct(minimal $core) Constructor
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/ */
class core extends controller class core extends controller
{ {
/** /**
* Переменные окружения * Language
*
* @var language $language Language
*/ */
protected robot $vk; protected language $language = language::en;
/** /**
* Переменные окружения * Response
*
* @see https://wiki.php.net/rfc/property-hooks (find a table about backed and virtual hooks)
*
* @var response $response Response
*/ */
protected array $variables = []; protected response $response {
// Read
get => $this->response ??= $this->request->response();
}
/** /**
* Конструктор * Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'session' => []
];
/**
* Constructor
*
* @param minimal $core Initialize a controller?
* *
* @return void * @return void
*/ */
public function __construct() { public function __construct(minimal $core) {
parent::__construct(); // For the extends system
parent::__construct(core: $core);
// Инициализация ядра моделей (соединение с базой данных...) // Инициализация ядра моделей (соединение с базой данных...)
new models(); new models();
// Инициализация журнала ошибок // Initializing of the language
$this->variables['errors'] = [ $this->language = language::{$_COOKIE["language"] ?? 'en'} ?? language::en;
'vk' => []
];
// Инициализация препроцессора представления // Initializing of preprocessor of views
$this->view = new manager; $this->view = new templater;
} }
} }

View File

@ -1,44 +0,0 @@
<?php
declare(strict_types=1);
namespace mirzaev\site\repression\controllers;
// Файлы проекта
use mirzaev\site\repression\controllers\core;
/**
* Контроллер ошибок
*
* @package mirzaev\site\repression\controllers
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class error_controller extends core
{
/**
* Страница с ошибкой
*
* @param array $parameters
*/
public function index(array $parameters = []): ?string
{
// Запись текста ошибки в переменную окружения
$this->variables['text'] = $parameters['text'] ?? null;
if (isset($parameters['code'])) {
// Получен код ошибки
// Запись кода ошибки в переменную окружения
$this->variables['code'] = $parameters['code'];
// Запись кода ответа
http_response_code($parameters['code']);
// Генерация представления
return $this->view->render(DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . 'index.html', $this->variables);
}
// Генерация представления
return $this->view->render(DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . ($parameters['code'] ?? 'index') . '.html', $this->variables);
}
}

View File

@ -0,0 +1,169 @@
<?php
declare(strict_types=1);
namespace mirzaev\site\repression\controllers;
// Files of the project
use mirzaev\site\repression\controllers\core,
mirzaev\site\repression\models\views;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content;
// Framework for API of ipinfo.io
use ipinfo\ipinfo\IPinfo as ipinfo;
// Built-in libraries
use Exception as exception;
/**
* Index controller
*
* @package mirzaev\site\repression\controllers
*
* @method null index() Main page
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class index extends core
{
/**
* Main page
*
* @return null
*/
public function index(...$parameters): null
{
if (str_contains($this->request->headers['accept'], content::any->value)) {
// Request for any response
// Initializing joker
$this->view->joker = [
/* 'instasamka' => rand(1, 11), */
'southern' => rand(1, 3),
'vk' => (bool) rand(0, 1),
'whatsapp' => (bool) rand(0, 1),
'iphone' => (bool) rand(0, 1),
];
try {
// Initializing data for the creepy line that will appear on the screen when user click "I did not understand" in the site rules window
$data = (array) (new ipinfo(require '../settings/ipinfo.php'))->getDetails($_SERVER['cf-connecting-ip'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR']);
// Initializing the creepy line that will appear on the screen when user click "I did not understand" in the site rules window
$this->view->creepy = sprintf(
"%s, %s, %s, %s, %s, %s, %s, seen in extremist chats, seen in LGBTQ+ chats, anti-state activities, problems with studies, was in contact with a criminal group (2017), wears strange pants, suspect in the case of January 15, 2024 No. 2360501",
$data['continent']['name'],
$data['country_name'],
$data['city'],
$data['latitude'],
$data['longitude'],
$data['org'],
$data['ip']
);
} catch (exception $e) {
// Initializing data for the creepy line that will appear on the screen when user click "I did not understand" in the site rules window
$data = [];
// Initializing the creepy line that will appear on the screen when user click "I did not understand" in the site rules window
$this->view->creepy = 'check your DM';
}
// Validating values
$address = filter_var($this->request->headers['remote-addr'] ?? '', FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE);
$connecting = filter_var($this->request->headers['cf-connecting-ip'] ?? '', FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE);
$forwarded = filter_var($this->request->headers['x-forwarded-for'] ?? $this->request->headers['http-x-forwarded-for'] ?? '', FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE);
// Initializing last 10 unique views less than 5 minutes ago
$last = views::last(rows: 10, address: true, time: 300);
if (
($forwarded && array_search($forwarded, array_column($last, 'forwarded'), true) !== false)
or ($address && array_search($address, array_column($last, 'address'), true) !== false)
or ($connecting && array_search($connecting, array_column($last, 'connecting'), true) !== false)
) {
// Found a dublicate
} else {
// Not found a dublicate
// Validating other values
$useragent = $this->request->headers['user-agent'] ?? $this->request->headers['http-user-agent'] ?? null;
$referer = $this->request->headers['referer'] ?? $this->request->headers['http-referer'] ?? null;
$continent = $data['continent']['code'];
$country = $data['country'];
$country_name = $data['country_name'];
$region = $data['region'];
$city = $data['city'];
$latitude = $data['latitude'];
$longitude = $data['longitude'];
$organisation = $data['org'];
$flag = $data['country_flag']['emoji'];
$currency = $data['country_currency']['code'];
$timezone = $data['timezone'];
// Writing a view
views::write(
address: empty($address) ? null : "\"$address\"",
connecting: empty($connecting) ? null : "\"$connecting\"",
forwarded: empty($forwarded) ? null : "\"$forwarded\"",
useragent: !empty($useragent) && mb_strlen($useragent) < 512 ? "\"$useragent\"" : null,
referer: !empty($referer) && mb_strlen($referer) < 256 ? "\"$referer\"" : null,
continent: !empty($continent) && mb_strlen($continent) === 2 ? "\"$continent\"" : null,
country: !empty($country) && mb_strlen($country) < 64 ? "\"$country\"" : null,
country_name: !empty($country_name) && mb_strlen($country_name) < 32 ? "\"$country_name\"" : null,
region: !empty($region) && mb_strlen($region) < 32 ? "\"$region\"" : null,
city: !empty($city) && mb_strlen($city) < 32 ? "\"$city\"" : null,
latitute: filter_var((string) $latitude, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_NULL_ON_FAILURE),
longitude: filter_var((string) $longitude, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_NULL_ON_FAILURE),
organisation: !empty($organisation) && mb_strlen($organisation) < 128 ? "\"$organisation\"" : null,
flag: !empty($flag) && mb_strlen($flag) === 2 ? "\"$flag\"" : null,
currency: !empty($currency) && mb_strlen($currency) <= 3 ? "\"$currency\"" : null,
timezone: !empty($timezone) && mb_strlen($timezone) < 64 ? "\"$timezone\"" : null
);
// Deinitializing unnecessary variables
unset(
$last,
$useragent,
$referer,
$continent,
$country,
$country_name,
$region,
$city,
$latitude,
$longitude,
$organisation,
$flag,
$currency,
$timezone
);
}
// Deinitializing unnecessary variables
unset($address, $connecting, $forwarded);
// Initializing the counter of views
$this->view->views = views::statistics(rows: 1000000) + ['last' => views::last(rows: 10, address: true)];
// Deinitializing unnecessary variables
unset($last);
// Sending response
$this->response
->start()
->clean()
->sse()
->write($this->view->render(DIRECTORY_SEPARATOR . 'index.html'))
->validate($this->request)
?->body()
->end();
}
// Exit (success/fail)
return null;
}
}

View File

@ -1,71 +0,0 @@
<?php
declare(strict_types=1);
namespace mirzaev\site\repression\controllers;
// Файлы проекта
use mirzaev\site\repression\controllers\core,
mirzaev\site\repression\models\views;
// Фреймворк для сайта ipinfo.io
use ipinfo\ipinfo\IPinfo;
// Встроенные библиотеки
use exception;
/**
* Контроллер основной страницы
*
* @package mirzaev\site\repression\controllers
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class index_controller extends core
{
/**
* Главная страница
*
* @param array $parameters Параметры запроса
*/
public function index(array $parameters = []): ?string
{
// Инициализация шутника
$this->variables['troller'] = [
'instasamka' => rand(1, 11),
'southern' => rand(1, 3),
'vk' => (bool) rand(0, 1),
'whatsapp' => (bool) rand(0, 1),
'iphone' => (bool) rand(0, 1),
];
try {
// Запрос дополнительных данных
$data = (array) (new IPinfo(require '../settings/ipinfo.php'))->getDetails($_SERVER['cf-connecting-ip'] ?? $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR']);
// Генерация строки для запугивания пользователя
$this->variables['creepy'] = "{$data['continent']['name']}, {$data['country_name']}, {$data['city']}, {$data['latitude']}, {$data['longitude']}, {$data['org']}, {$data['ip']}, seen in extremist chats, seen in LGBTQ+ chats, anti-state activities, problems with studies, was in contact with a criminal group (2017), wears strange pants, suspect in the case of January 15, 2024 No. 2360501";
} catch (exception $e) {
// Инициализация заглушки дополнительных данных
$data = [];
// Инициализация заглушки строки для запугивания пользователя
$this->variables['creepy'] = 'check your DM';
}
// Запись просмотра
views::increase($data);
// Инициализация счётчика просмотров
$this->variables['views'] = [
'day' => views::day(),
'week' => views::week(),
'month' => views::month(),
'all' => views::all(),
'last' => views::last(10)
];
// Генерация представления
return $this->view->render(DIRECTORY_SEPARATOR . 'index.html', $this->variables);
}
}

View File

@ -0,0 +1,19 @@
,,,"Mozilla/5.0 (compatible; Google-InspectionTool/1.0;)",,"NA","US","United States","Oklahoma","Oklahoma City",354676,-975164,"AS15169 Google LLC","🇺🇸","USD","America/Chicago",1732246927
,"194.164.180.23","194.164.180.23","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Safari/537.36",,"EU","DE","Germany","Hesse","Frankfurt am Main",501038,86522,"AS215174 ProNow Tech CO. L.L.C","🇩🇪","EUR","Europe/Berlin",1732248193
,"66.249.81.162","66.249.81.162","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Safari/537.36 Chrome-Lighthouse",,"EU","NL","Netherlands","Groningen","Delfzijl",533300,69181,"AS15169 Google LLC","🇳🇱","EUR","Europe/Amsterdam",1732248832
,"66.249.81.167","66.249.81.167","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Safari/537.36 Chrome-Lighthouse",,"EU","NL","Netherlands","Groningen","Delfzijl",533300,69181,"AS15169 Google LLC","🇳🇱","EUR","Europe/Amsterdam",1732248839
,"66.102.9.76","66.102.9.76","Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",,"EU","FI","Finland","Kymenlaakso","Hamina",605697,271979,"AS15169 Google LLC","🇫🇮","EUR","Europe/Helsinki",1732248851
,"66.102.9.75","66.102.9.75","Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",,"EU","FI","Finland","Kymenlaakso","Hamina",605697,271979,"AS15169 Google LLC","🇫🇮","EUR","Europe/Helsinki",1732248859
,"74.125.212.107","74.125.212.107","Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",,"NA","US","United States","Iowa","Council Bluffs",412619,-958608,"AS15169 Google LLC","🇺🇸","USD","America/Chicago",1732248860
,"74.125.212.108","74.125.212.108","Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",,"NA","US","United States","Iowa","Council Bluffs",412619,-958608,"AS15169 Google LLC","🇺🇸","USD","America/Chicago",1732248869
,"74.125.212.109","74.125.212.109","Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",,"NA","US","United States","Iowa","Council Bluffs",412619,-958608,"AS15169 Google LLC","🇺🇸","USD","America/Chicago",1732248883
,"66.249.81.168","66.249.81.168","Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",,"EU","NL","Netherlands","Groningen","Delfzijl",533300,69181,"AS15169 Google LLC","🇳🇱","EUR","Europe/Amsterdam",1732248889
,"74.125.212.106","74.125.212.106","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Safari/537.36 Chrome-Lighthouse",,"NA","US","United States","Iowa","Council Bluffs",412619,-958608,"AS15169 Google LLC","🇺🇸","USD","America/Chicago",1732248892
,"66.249.81.166","66.249.81.166","Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",,"EU","NL","Netherlands","Groningen","Delfzijl",533300,69181,"AS15169 Google LLC","🇳🇱","EUR","Europe/Amsterdam",1732248895
,"195.234.62.12","195.234.62.12","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Safari/537.36",,"EU","DE","Germany","Hesse","Frankfurt am Main",500837,86440,"AS202422 G-Core Labs S.A.","🇩🇪","EUR","Europe/Berlin",1732249663
,"194.164.180.23","194.164.180.23","Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36",,"EU","DE","Germany","Hesse","Frankfurt am Main",501038,86522,"AS215174 ProNow Tech CO. L.L.C","🇩🇪","EUR","Europe/Berlin",1732249896
,"194.164.180.15","194.164.180.15","Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36",,"EU","DE","Germany","Hesse","Frankfurt am Main",501038,86522,"AS215174 ProNow Tech CO. L.L.C","🇩🇪","EUR","Europe/Berlin",1732250185
,"194.164.180.15","194.164.180.15","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Safari/537.36",,"EU","DE","Germany","Hesse","Frankfurt am Main",501038,86522,"AS215174 ProNow Tech CO. L.L.C","🇩🇪","EUR","Europe/Berlin",1732250492
,"185.253.23.85","185.253.23.85","Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36",,"EU","RU","Russia","Moscow","Moscow",557522,376156,"AS21030 Docker LTD","🇷🇺","RUB","Europe/Moscow",1732250743
,"185.253.23.85","185.253.23.85","Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36",,"EU","RU","Russia","Moscow","Moscow",557522,376156,"AS21030 Docker LTD","🇷🇺","RUB","Europe/Moscow",1732251093
,"109.248.213.45","109.248.213.45","Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36",,"AS","KZ","Kazakhstan","Karaganda","Karagandy",498019,731021,"AS203087 PE Fedinyak Sergey Vyacheslavovich","🇰🇿","KZT","Asia/Almaty",1732251404
1 Mozilla/5.0 (compatible; Google-InspectionTool/1.0;) NA US United States Oklahoma Oklahoma City 354676 -975164 AS15169 Google LLC 🇺🇸 USD America/Chicago 1732246927
2 194.164.180.23 194.164.180.23 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Safari/537.36 EU DE Germany Hesse Frankfurt am Main 501038 86522 AS215174 ProNow Tech CO. L.L.C 🇩🇪 EUR Europe/Berlin 1732248193
3 66.249.81.162 66.249.81.162 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Safari/537.36 Chrome-Lighthouse EU NL Netherlands Groningen Delfzijl 533300 69181 AS15169 Google LLC 🇳🇱 EUR Europe/Amsterdam 1732248832
4 66.249.81.167 66.249.81.167 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Safari/537.36 Chrome-Lighthouse EU NL Netherlands Groningen Delfzijl 533300 69181 AS15169 Google LLC 🇳🇱 EUR Europe/Amsterdam 1732248839
5 66.102.9.76 66.102.9.76 Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse EU FI Finland Kymenlaakso Hamina 605697 271979 AS15169 Google LLC 🇫🇮 EUR Europe/Helsinki 1732248851
6 66.102.9.75 66.102.9.75 Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse EU FI Finland Kymenlaakso Hamina 605697 271979 AS15169 Google LLC 🇫🇮 EUR Europe/Helsinki 1732248859
7 74.125.212.107 74.125.212.107 Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse NA US United States Iowa Council Bluffs 412619 -958608 AS15169 Google LLC 🇺🇸 USD America/Chicago 1732248860
8 74.125.212.108 74.125.212.108 Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse NA US United States Iowa Council Bluffs 412619 -958608 AS15169 Google LLC 🇺🇸 USD America/Chicago 1732248869
9 74.125.212.109 74.125.212.109 Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse NA US United States Iowa Council Bluffs 412619 -958608 AS15169 Google LLC 🇺🇸 USD America/Chicago 1732248883
10 66.249.81.168 66.249.81.168 Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse EU NL Netherlands Groningen Delfzijl 533300 69181 AS15169 Google LLC 🇳🇱 EUR Europe/Amsterdam 1732248889
11 74.125.212.106 74.125.212.106 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Safari/537.36 Chrome-Lighthouse NA US United States Iowa Council Bluffs 412619 -958608 AS15169 Google LLC 🇺🇸 USD America/Chicago 1732248892
12 66.249.81.166 66.249.81.166 Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse EU NL Netherlands Groningen Delfzijl 533300 69181 AS15169 Google LLC 🇳🇱 EUR Europe/Amsterdam 1732248895
13 195.234.62.12 195.234.62.12 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Safari/537.36 EU DE Germany Hesse Frankfurt am Main 500837 86440 AS202422 G-Core Labs S.A. 🇩🇪 EUR Europe/Berlin 1732249663
14 194.164.180.23 194.164.180.23 Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36 EU DE Germany Hesse Frankfurt am Main 501038 86522 AS215174 ProNow Tech CO. L.L.C 🇩🇪 EUR Europe/Berlin 1732249896
15 194.164.180.15 194.164.180.15 Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36 EU DE Germany Hesse Frankfurt am Main 501038 86522 AS215174 ProNow Tech CO. L.L.C 🇩🇪 EUR Europe/Berlin 1732250185
16 194.164.180.15 194.164.180.15 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Safari/537.36 EU DE Germany Hesse Frankfurt am Main 501038 86522 AS215174 ProNow Tech CO. L.L.C 🇩🇪 EUR Europe/Berlin 1732250492
17 185.253.23.85 185.253.23.85 Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36 EU RU Russia Moscow Moscow 557522 376156 AS21030 Docker LTD 🇷🇺 RUB Europe/Moscow 1732250743
18 185.253.23.85 185.253.23.85 Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36 EU RU Russia Moscow Moscow 557522 376156 AS21030 Docker LTD 🇷🇺 RUB Europe/Moscow 1732251093
19 109.248.213.45 109.248.213.45 Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML\, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36 AS KZ Kazakhstan Karaganda Karagandy 498019 731021 AS203087 PE Fedinyak Sergey Vyacheslavovich 🇰🇿 KZT Asia/Almaty 1732251404

View File

@ -4,151 +4,28 @@ declare(strict_types=1);
namespace mirzaev\site\repression\models; namespace mirzaev\site\repression\models;
// Фреймворк PHP // Framework for PHP
use mirzaev\minimal\model; use mirzaev\minimal\model;
// Фреймворк ArangoDB // Built-in libraries
use mirzaev\arangodb\connection as arangodb;
use exception; use exception;
/** /**
* Ядро моделей * Core of models
* *
* @package mirzaev\site\repression\models * @package mirzaev\site\repression\models
*
* @method void __construct() Constructor
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/ */
class core extends model class core extends model
{ {
/** /**
* Соединение с базой данных ArangoDB * Constructor
*/
protected static arangodb $arangodb;
/**
* Путь до файла с настройками подключения к базе данных ArangoDB
*/
final public const ARANGODB = '../settings/arangodb.php';
/**
* Конструктор
* *
* @param bool $initialize Инициализировать контроллер? * @return void
* @param ?arangodb $arangodb Инстанция соединения с базой данных ArangoDB
*/ */
public function __construct(bool $initialize = true, ?arangodb $arangodb = null) public function __construct() {}
{
if ($initialize) {
// Запрошена инициализация
if (isset($arangodb)) {
// Получена инстанция соединения с базой данных
// Запись и инициализация соединения с базой данных
$this->__set('arangodb', $arangodb);
} else {
// Не получена инстанция соединения с базой данных
// Инициализация соединения с базой данных по умолчанию
$this->__get('arangodb');
}
}
}
/**
* Записать свойство
*
* @param string $name Название
* @param mixed $value Значение
*/
public function __set(string $name, mixed $value = null): void
{
match ($name) {
'arangodb' => (function () use ($value) {
if ($this->__isset('arangodb')) {
// Свойство уже было инициализировано
// Выброс исключения (неудача)
throw new exception('Запрещено реинициализировать соединение с базой данных ($this->arangodb)', 500);
} else {
// Свойство ещё не было инициализировано
if ($value instanceof arangodb) {
// Передано подходящее значение
// Запись свойства (успех)
self::$arangodb = $value;
} else {
// Передано неподходящее значение
// Выброс исключения (неудача)
throw new exception('Соединение с базой данных ($this->arangodb) должен быть инстанцией mirzaev\arangodb\connection', 500);
}
}
})(),
default => parent::__set($name, $value)
};
}
/**
* Прочитать свойство
*
* @param string $name Название
*
* @return mixed Содержимое
*/
public function __get(string $name): mixed
{
return match ($name) {
'arangodb' => (function () {
if (!$this->__isset('db')) {
// Свойство не инициализировано
// Инициализация значения по умолчанию исходя из настроек
$this->__set('arangodb', new arangodb(require static::ARANGODB));
}
return self::$arangodb;
})(),
default => parent::__get($name)
};
}
/**
* Проверить свойство на инициализированность
*
* @param string $name Название
*/
public function __isset(string $name): bool
{
return match ($name) {
default => parent::__isset($name)
};
}
/**
* Удалить свойство
*
* @param string $name Название
*/
public function __unset(string $name): void
{
match ($name) {
default => parent::__isset($name)
};
}
/**
* Статический вызов
*
* @param string $name Название
* @param array $arguments Параметры
*/
public static function __callStatic(string $name, array $arguments): mixed
{
match ($name) {
default => throw new exception("Не найдено свойство или функция: $name", 500)
};
}
} }

View File

@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace mirzaev\site\repression\models\enumerations;
/**
* Types of languages by ISO 639-1 standart
*
* @package mirzaev\site\repression\models\enumerations
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
enum language
{
case en;
case ru;
/**
* Label
*
* Initialize label of the language
*
* @param language|null $language Language into which to translate
*
* @return string Translated label of the language
*
* @todo
* 1. More languages
* 2. Cases???
*/
public function label(?language $language = language::en): string
{
// Exit (success)
return match ($this) {
language::en => match ($language) {
language::en => 'English',
language::ru => 'Английский'
},
language::ru => match ($language) {
language::en => 'Russian',
language::ru => 'Русский'
}
};
}
}

View File

@ -0,0 +1,91 @@
<?php
declare(strict_types=1);
namespace mirzaev\site\repression\models\interfaces;
// Files of the project
use mirzaev\site\repression\models\traits\csv as csv_trait;
/**
* CSV
*
* Comma-Separated Values by RFC 4180
*
* @see https://tools.ietf.org/html/rfc4180
*
* @used-by csv_trait
* @package mirzaev\site\repression\models\interfaces
*
* @var string FILE Path to the database file
*
* @method void static write() Write to the database file
* @method array|null static read() Read from the database file
* @method string|false static serialize() Preparing data for writing to the database
* @method array|false static deserialize() Preparing data from the database to processing
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
interface csv
{
/**
* File
*
* @var string FILE Path to the database file
*/
public const string FILE = DATABASE . DIRECTORY_SEPARATOR . 'database.csv';
/**
* Write
*
* Write to the database file
*
* @return void
*/
public static function write(): void;
/**
* Read
*
* Read from the start of the database file
*
* @param int $rows Amount of rows for reading
*
* @return array|null Readed records
*/
public static function read(int $rows = 1): ?array;
/**
* Last
*
* Read from the end of the database file
*
* @param int $rows Amount of rows for reading
*
* @return array|null Readed records
*/
public static function last(int $rows = 1): ?array;
/**
* Serialize
*
* Preparing data for writing to the database
*
* @param array $parameters Values for serializing
*
* @return string|false Serialized data
*/
public static function serialize(array $parameters): string|false;
/**
* Deserialize
*
* Preparing data from the database to processing
*
* @param string $row Record for deserializing
*
* @return array|false Serialized data
*/
public static function deserialize(string $row): array|false;
}

View File

@ -0,0 +1,135 @@
<?php
declare(strict_types=1);
namespace mirzaev\site\repression\models\traits;
// Files of the project
use mirzaev\site\repression\models\interfaces\csv as csv_interface;
// Built-in libraries
use exception;
/**
* CSV
*
* Comma-Separated Values by RFC 4180
*
* @see https://tools.ietf.org/html/rfc4180
*
* @uses csv_interface
* @package mirzaev\arming_bot\models\traits
*
* @var protected readonly _document|null $document An instance of the ArangoDB document
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
trait csv
{
/**
* Read
*
* Read from the start of the database file
*
* @param int $rows Amount of rows for reading
* @param array &$errors Buffer of errors
*
* @return array|null Readed records
*/
public static function read(int $rows = 0, &$errors = []): ?array
{
try {
// Initializing the buffer of readed records
$records = [];
// Opening the file with views records
$file = fopen(static::FILE, 'c+');
while (--$rows >= 0 && ($row = fgets($file, 4096)) !== false) {
// Iterating over rows (records)
// Deserealizing record
$deserialized = static::deserialize($row);
if ($deserialized) {
// Deserialized record
// Writing to the buffer of readed records
$records[] = $deserialized;
}
}
// Closing file with views records
fclose($file);
// Exit (success)
return $records;
} catch (exception $e) {
// Write to the buffer of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
// Writing to the log of errors
/* log::write(type::ERRORS, "[{$_SERVER['REMOTE_ADDR']}] " . (empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? '' : "[{$_SERVER['HTTP_X_FORWARDED_FOR']}] ") . $e->getMessage()); */
}
// Exit (fail)
return null;
}
/**
* Serialize
*
* Preparing data for writing to the database
*
* @param array $parameters Values for serializing
* @param bool $created Add date of creating at the end?
*
* @return string|false Serialized data
*/
public static function serialize(array $parameters, bool $created = true): string|false
{
// Declaring the buffer of serialized values
$serialized = '';
// Sanitizing values
foreach ($parameters as $value) $serialized .= ',' . preg_replace('/(?<=[^^])"(?=[^$])/', '""', preg_replace('/(?<=[^^]),(?=[^$])/', '\,', $value ?? ''));
// Writing date of creating to the buffer of serialized values
if ($created) $serialized .= ',' . time();
// Trimming excess first comma in the buffer of serialized values
$serialized = mb_substr($serialized, 1, mb_strlen($serialized));
// Exit (success/fail)
return empty($serialized) ? false : $serialized;
}
/**
* Deserialize
*
* Preparing data from the database to processing
*
* @param string $row Record for deserializing
*
* @return array|false Serialized data
*/
public static function deserialize(string $row): array|false
{
// Separating row by commas
preg_match_all('/(?:^|,)(?=[^"]|(")?)"?((?(1)[^"]*|[^,"]*))"?(?=,|$)/', $row, $matches);
// Converting double quotes to single quotes
foreach ($matches[2] as &$match)
if (empty($match = preg_replace('/[\n\r]/', '', preg_replace('/""/', '"', preg_replace('/\\\,/', ',', trim((string) $match, '"'))))))
$match = null;
// Exit (success/fail)
return empty($matches[2]) ? false : $matches[2];
}
}

View File

@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
namespace mirzaev\site\repression\models\traits;
// Built-in libraries
use Exception as exception,
Generator as generator;
/**
* File
*
* @package mirzaev\site\repression\models\traits
*
* @method generator|null
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
trait file
{
/**
* Read
*
* @param resource $file Pointer to the file (fopen())
* @param int $offset Offset of rows for start reading
* @param int $rows Amount of rows for reading
* @param int $position Initial cursor position on a row
* @param int $step Reading step
* @param array &$errors Buffer of errors
*
* @return generator|null|false
*/
private static function read($file, int $offset = 0, int $rows = 500, int $position = 0, int $step = 1, &$errors = []): generator|null|false
{
try {
while ($offset-- > 0) {
do {
// Iterate over symbols of the row
// The end (or the beginning) of the file reached (success)
if (feof($file)) break;
// Moving the cursor to next position on the row
fseek($file, $position += $step, SEEK_END);
// Reading a character of the row
$character = fgetc($file);
// Is the character a carriage return? (end or start of the row)
} while ($character !== PHP_EOL);
}
while ($rows-- > 0) {
// Reading rows
// Initializing of the buffer of row
$row = '';
// Initializing the character buffer to generate $row
$character = '';
do {
// Iterate over symbols of the row
// The end (or the beginning) of the file reached (success)
if (feof($file)) break;
// Building the row
$row = $step > 0 ? $row . $character : $character . $row;
// Moving the cursor to next position on the row
fseek($file, $position += $step, SEEK_END);
// Reading a character of the row
$character = fgetc($file);
// Is the character a carriage return? (end or start of the row)
} while ($character !== PHP_EOL);
// Exit (success)
yield empty($row) ? null : $row;
}
// Exit (success)
return null;
} catch (exception $e) {
// Write to the buffer of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
// Write to the log of errors
/* log::write(type::ERRORS, "[{$_SERVER['REMOTE_ADDR']}] " . (empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? '' : "[{$_SERVER['HTTP_X_FORWARDED_FOR']}] ") . $e->getMessage()); */
}
// Exit (fail)
return false;
}
}

View File

@ -4,225 +4,491 @@ declare(strict_types=1);
namespace mirzaev\site\repression\models; namespace mirzaev\site\repression\models;
// Фреймворк ArangoDB // Files of the project
use mirzaev\arangodb\collection, use mirzaev\site\repression\models\interfaces\csv as csv_interface,
mirzaev\arangodb\document; mirzaev\site\repression\models\traits\csv as csv_trait,
mirzaev\site\repression\models\traits\file;
// Библиотека для ArangoDB // Built-in libraries
use ArangoDBClient\Document as _document;
// Встроенные библиотеки
use exception; use exception;
/** /**
* Счётчик просмотров * Counter of views
* *
* @package mirzaev\site\repression\models * @package mirzaev\site\repression\models
*
* @var string FILE Path to the datavase file
*
* @method
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/ */
class views extends core class views extends core implements csv_interface
{ {
/** use csv_trait, file {
* Коллекция csv_trait::read insteadof file;
*/ file::read as protected file;
final public const COLLECTION = 'views'; }
/** /**
* Увеличить счётчик посещений используя данные пользователя из запроса * File
* *
* @param ?array $data Дополнительные данные пользователя * @var string FILE Path to the database file
*
* @return bool Записано в базу данных?
*/ */
public static function increase(?array $data = null, array &$errors = []): bool final public const string FILE = DATABASE . DIRECTORY_SEPARATOR . 'views.csv';
{
/**
* Write
*
* Write request data to the views registry
*
* @param string|null $address
* @param string|null $connecting
* @param string|null $forwarded
* @param string|null $useragent
* @param string|null $referer
* @param string|null $continent
* @param string|null $country
* @param string|null $country_name
* @param string|null $region
* @param string|null $city
* @param string|float|null $latitute
* @param string|float|null $longitude
* @param string|null $organisation
* @param string|null $flag
* @param string|null $currency
* @param string|null $timezone
* @param array &$errors Buffer of errors
*
* @return void
*/
public static function write(
?string $address = null,
?string $connecting = null,
?string $forwarded = null,
?string $useragent = null,
?string $referer = null,
?string $continent = null,
?string $country = null,
?string $country_name = null,
?string $region = null,
?string $city = null,
string|float|null $latitute = null,
string|float|null $longitude = null,
?string $organisation = null,
?string $flag = null,
?string $currency = null,
?string $timezone = null,
&$errors = []
): void {
try { try {
if (collection::init(static::$arangodb->session, self::COLLECTION)) // Initializing registry of rows before
if ($_SERVER['HTTP_USER_AGENT'] === 'nginx-ssl early hints') return null; $before = [];
else if (document::write(static::$arangodb->session, self::COLLECTION, [
'ip' => $_SERVER['REMOTE_ADDR'] ?? null, if (file_exists(static::FILE) && filesize(static::FILE) > 0) {
'cf-connecting-ip' => $_SERVER['cf-connecting-ip'] ?? null, // File exists and not empty
'x-forwarded-for' => $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null,
'referer' => $_SERVER['HTTP_REFERER'] ?? null, // Opening the file with views records
'useragent' => $_SERVER['HTTP_USER_AGENT'] ?? null $file = fopen(static::FILE, 'c+');
] + ($data ?? []))) return true;
else throw new exception('Не удалось создать аккаунт'); while (($row = fgets($file, 4096)) !== false) {
else throw new exception('Не удалось инициализировать коллекцию'); // Iterating over rows
// Writing the registry of rows before
$before[] = $row;
}
// Closing the file with views records
fclose($file);
}
// Deinitializing unnecessary variables
unset($row);
// Opening the file with views records
$file = fopen(static::FILE, 'c');
if (flock($file, LOCK_EX)) {
// The file was locked
// Clearing the file
ftruncate($file, 0);
// Serializing values
$serialized = static::serialize([
$address,
$connecting,
$forwarded,
$useragent,
$referer,
$continent,
$country,
$country_name,
$region,
$city,
$latitute,
$longitude,
$organisation,
$flag,
$currency,
$timezone
]);
// Writing to the buffer for insertion to the views registry
if (count($before)) $serialized = trim(implode("", $before)) . "\n" . $serialized;
// Writing a new record to the views registry
fwrite($file, $serialized);
// Applying changes
fflush($file);
// Unlocking the file
flock($file, LOCK_UN);
}
// Deinitializing unnecessary variables
unset($serialized, $record, $before);
// Closing the file with views records
fclose($file);
// Writing to the log
/* log::write(type::FILE, "[CREATE] $domain $ip $port"); */
} catch (exception $e) { } catch (exception $e) {
// Запись в реестр ошибок // Write to the buffer of errors
$errors[] = [ $errors[] = [
'text' => $e->getMessage(), 'text' => $e->getMessage(),
'file' => $e->getFile(), 'file' => $e->getFile(),
'line' => $e->getLine(), 'line' => $e->getLine(),
'stack' => $e->getTrace() 'stack' => $e->getTrace()
]; ];
// Write to the log of errors
/* log::write(type::ERRORS, "[{$_SERVER['REMOTE_ADDR']}] " . (empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? '' : "[{$_SERVER['HTTP_X_FORWARDED_FOR']}] ") . $e->getMessage()); */
}
} }
/**
* Search
*
* Search for a record by IP-address
*
* @param string|null $address IP-address
* @param int $rows Amount of rows for reading
* @param array &$errors Buffer of errors
*
* @return array|null Found view record
*/
public static function search(?string $address, int $rows = 0, &$errors = []): ?array
{
try {
// Opening the file with views records
$file = fopen(static::FILE, 'c+');
while ($rows-- > 0 && ($row = fgets($file, 4096)) !== false) {
// Iterating over rows (records)
// Deserealizing record
$deserialized = static::deserialize($row);
if ($deserialized) {
// Deserialized record
// Initializing values of the view data
$record = array_combine([
'address',
'connecting',
'forwarded',
'useragent',
'referer',
'continent',
'country',
'country_name',
'region',
'city',
'latitute',
'longitude',
'organisation',
'flag',
'currency',
'timezone',
'created',
], $deserialized);
if (match ($address) {
$record['address'], $record['connecting'], $record['forwarded'] => true,
default => false
}) {
// View found by IP-address
// Closing the file with views records
fclose($file);
// Exit (success)
return $record;
}
// Deinitializing unnecessary variables
unset($row, $deserialized, $record);
}
}
// Closing file with views records
fclose($file);
} catch (exception $e) {
// Write to the buffer of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
// Writing to the log of errors
/* log::write(type::ERRORS, "[{$_SERVER['REMOTE_ADDR']}] " . (empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? '' : "[{$_SERVER['HTTP_X_FORWARDED_FOR']}] ") . $e->getMessage()); */
}
// Exit (fail)
return null;
}
/**
* Statistics
*
* Generate statistics on views (day, week, month, total)
*
* @param bool $day Statistics on views per day
* @param bool $week Statistics on views per week
* @param bool $month Statistics on views per month
* @param bool $total Total statistics on views
* @param int $rows Amount of rows for reading
* @param array &$errors Buffer of errors
*
* @return array|false Counters of views (only those that were requested)
*/
public static function statistics(
bool $day = true,
bool $week = true,
bool $month = true,
bool $total = true,
int $rows = 1,
&$errors = []
): array|false {
try {
// Initializing counters
$counters = [];
switch (true) {
case $day:
$counters['day'] = 0;
$counters['week'] = 0;
$counters['month'] = 0;
$counters['total'] = 0;
}
// Opening the file with views records
$file = fopen(static::FILE, 'c+');
while ($rows-- > 0 && ($row = fgets($file, 4096)) !== false) {
// Iterating over rows (records)
// Deserealizing record
$deserialized = static::deserialize($row);
if ($deserialized) {
// Deserialized record
// Initializing value of the view data
$created = $deserialized[16];
// Increasing counters
switch (true) {
case $day && $created >= time() - 86400:
++$counters['day'];
case $week && $created >= time() - 604800:
++$counters['week'];
case $month && $created >= time() - 2592000:
++$counters['month'];
case $total:
++$counters['total'];
}
}
}
// Deinitializing unnecessary variables
unset($row, $deserialized, $created);
// Closing file with views records
fclose($file);
// Exit (success)
return $counters;
} catch (exception $e) {
// Write to the buffer of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
// Writing to the log of errors
/* log::write(type::ERRORS, "[{$_SERVER['REMOTE_ADDR']}] " . (empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? '' : "[{$_SERVER['HTTP_X_FORWARDED_FOR']}] ") . $e->getMessage()); */
}
// Exit (fail)
return false; return false;
} }
public static function day(array &$errors = []): ?int /**
* Last
*
* Recursively reads unique records by IP-address
*
* @param int $rows Amount of rows for reading (pool)
* @param bool $address Filter by uniqueness by IP-address? (forwarded ?? address ?? connecting)
* @oaram int|false $time Filter by elapsed time
* @param array &$errors Buffer of errors
*
* @return array|null Readed records
*/
public static function last(int $rows = 1, bool $address = false, int|false $time = false, &$errors = []): ?array
{ {
try { try {
if (collection::init(static::$arangodb->session, self::COLLECTION)) // Initializing the buffer of readed records
return collection::search(static::$arangodb->session, sprintf( $records = [];
<<<AQL
return COUNT_DISTINCT( // Initializing the file with views records
FOR d IN %s if (!file_exists(static::FILE)) touch(static::FILE);
FILTER d.created >= %d
RETURN d['x-forwarded-for'] // Opening the file with views records
) $file = fopen(static::FILE, 'r');
AQL,
views::COLLECTION, // Initializing offset of rows for readint
time() - 86400 $offset = 0;
));
else throw new exception('Не удалось инициализировать коллекцию'); // Continuing reading
offset:
foreach (static::file(file: $file, offset: $offset, rows: $rows, position: 0, step: -1) as $row) {
// Iterating over rows backwards (rows from the end)
if ($row === null) {
// The end of the file reached
// Deinitializing unnecessary variables
unset($row, $deserialized, $offset);
// Closing file with views records
fclose($file);
// Exit (success)
return $records;
}
// Deserealizing record
$deserialized = static::deserialize($row);
if ($deserialized) {
// Deserialized record
$record = array_combine([
'address',
'connecting',
'forwarded',
'useragent',
'referer',
'continent',
'country',
'country_name',
'region',
'city',
'latitute',
'longitude',
'organisation',
'flag',
'currency',
'timezone',
'created',
], $deserialized);
if ($time) {
// Requested filtering by elapsed time
if (time() - $record['created'] > $time) {
// Not enough time has passed yet
// Skipping iteration
continue;
}
}
if ($address) {
// Requested filtering by unique IP-address
// Declaring buffer of dublicate index
$dublicate = null;
if (
($record['forwarded'] && ($dublicate = array_search($record['forwarded'], array_column($records, 'forwarded'), true)) !== false)
or ($record['address'] && ($dublicate = array_search($record['address'], array_column($records, 'address'), true)) !== false)
or ($record['connecting'] && ($dublicate = array_search($record['connecting'], array_column($records, 'connecting'), true)) !== false)
) {
// Found a dublicate
if ($record['created'] > $records[$dublicate]['created']) {
// The record is newer than the dublicate (probably useless because the file is read from the end)
// Replacing the dublicate with the record
$records[$dublicate] = $record;
}
// Skipping iteration
continue;
}
}
// Writing to the buffer of readed records
$records[] = $record;
}
}
// Deinitializing unnecessary variables
unset($row, $deserialized);
if (count($records) < $rows) {
// Fewer unique rows were read than requested
// Writing offset for reading
$offset += $rows;
// Continuing reading (enter to the recursion)
goto offset;
}
// Deinitializing unnecessary variables
unset($offset);
// Closing file with views records
fclose($file);
// Exit (success)
return $records;
} catch (exception $e) { } catch (exception $e) {
// Запись в реестр ошибок // Write to the buffer of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
return null;
}
public static function week(array &$errors = []): ?int
{
try {
if (collection::init(static::$arangodb->session, self::COLLECTION))
return collection::search(static::$arangodb->session, sprintf(
<<<AQL
return COUNT_DISTINCT(
FOR d IN %s
FILTER d.created >= %d
RETURN d['x-forwarded-for']
)
AQL,
views::COLLECTION,
time() - 604800
));
else throw new exception('Не удалось инициализировать коллекцию');
} catch (exception $e) {
// Запись в реестр ошибок
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
return null;
}
public static function month(array &$errors = []): ?int
{
try {
if (collection::init(static::$arangodb->session, self::COLLECTION))
return collection::search(static::$arangodb->session, sprintf(
<<<AQL
return COUNT_DISTINCT(
FOR d IN %s
FILTER d.created >= %d
RETURN d['x-forwarded-for']
)
AQL,
views::COLLECTION,
time() - 2592000
));
else throw new exception('Не удалось инициализировать коллекцию');
} catch (exception $e) {
// Запись в реестр ошибок
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
return null;
}
public static function all(array &$errors = []): ?int
{
try {
if (collection::init(static::$arangodb->session, self::COLLECTION))
return collection::search(static::$arangodb->session, sprintf(
<<<AQL
return COUNT_DISTINCT(
FOR d IN %s
RETURN d['x-forwarded-for']
)
AQL,
views::COLLECTION
));
else throw new exception('Не удалось инициализировать коллекцию');
} catch (exception $e) {
// Запись в реестр ошибок
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
return null;
}
public static function last(int $amount = 10, array &$errors = []): ?array
{
try {
if (collection::init(static::$arangodb->session, self::COLLECTION)) {
// Инициализирована коллекция
// Поиск последних просмотров
$response = @collection::search(static::$arangodb->session, sprintf(
<<<AQL
FOR ip in (
FOR d IN views
SORT d.created DESC
RETURN DISTINCT d['x-forwarded-for'] == null ? d.ip : d['x-forwarded-for']
)
LIMIT 10
RETURN (
FOR d IN views
SORT d.created DESC
FILTER d['x-forwarded-for'] == ip || d.ip == ip
LIMIT 1
RETURN d
)
AQL,
views::COLLECTION,
$amount
));
// Инициализация буфера обработанных последних просмотров
$buffer = [];
// Универсализация
if ($response instanceof _document) $response = [$response];
// Обработка последних просмотров
foreach ($response ?? [] as $view) $buffer[] = $view->getAll()[0];
return $buffer;
} else throw new exception('Не удалось инициализировать коллекцию');
} catch (exception $e) {
// Запись в реестр ошибок
$errors[] = [ $errors[] = [
'text' => $e->getMessage(), 'text' => $e->getMessage(),
'file' => $e->getFile(), 'file' => $e->getFile(),
'line' => $e->getLine(), 'line' => $e->getLine(),
'stack' => $e->getTrace() 'stack' => $e->getTrace()
]; ];
// Writing to the log of errors
/* log::write(type::ERRORS, "[{$_SERVER['REMOTE_ADDR']}] " . (empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? '' : "[{$_SERVER['HTTP_X_FORWARDED_FOR']}] ") . $e->getMessage()); */
} }
// Exit (fail)
return null; return null;
} }
} }

View File

@ -4,28 +4,31 @@ declare(strict_types=1);
namespace mirzaev\site\repression; namespace mirzaev\site\repression;
use mirzaev\minimal\core; // Framework for PHP
use mirzaev\minimal\router; use mirzaev\minimal\core,
mirzaev\minimal\route;
// Enabling debugging
ini_set('error_reporting', E_ALL); ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1); ini_set('display_errors', 1);
ini_set('display_startup_errors', 1); ini_set('display_startup_errors', 1);
// Initializing system parameters of the project
define('INDEX', __DIR__);
define('ROOT', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR);
define('VIEWS', realpath('..' . DIRECTORY_SEPARATOR . 'views')); define('VIEWS', realpath('..' . DIRECTORY_SEPARATOR . 'views'));
define('STORAGE', realpath('..' . DIRECTORY_SEPARATOR . 'storage')); define('STORAGE', realpath('..' . DIRECTORY_SEPARATOR . 'storage'));
define('INDEX', __DIR__); define('DATABASE', realpath('..' . DIRECTORY_SEPARATOR . 'database'));
// Автозагрузка // Initializing dependencies
require __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; require ROOT . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
// Инициализация маршрутизатора // Initializing core
$router = new router; $core = new core(namespace: __NAMESPACE__);
// Запись маршрутов // Initializing routes
$router->write('/', 'index', 'index'); $core->router
->write('/', new route('index', 'index'), 'GET');
// Инициализация ядра // Handling request
$core = new core(namespace: __NAMESPACE__, router: $router); $core->start();
// Обработка запроса
echo $core->start();

0
mirzaev/site/repression/system/public/js/account.js Normal file → Executable file
View File

0
mirzaev/site/repression/system/public/js/bloodchaos.js Normal file → Executable file
View File

0
mirzaev/site/repression/system/public/js/hollow.js Normal file → Executable file
View File

0
mirzaev/site/repression/system/public/js/perlin.js Normal file → Executable file
View File

View File

0
mirzaev/site/repression/system/public/robots.txt Normal file → Executable file
View File

0
mirzaev/site/repression/system/public/sitemap.xml Normal file → Executable file
View File

View File

@ -31,6 +31,7 @@
border: none; border: none;
color: var(--text); color: var(--text);
font-family: commissioner, Roboto, sans-serif; font-family: commissioner, Roboto, sans-serif;
-webkit-tap-highlight-color: transparent;
transition: 0.1s ease-out; transition: 0.1s ease-out;
} }
@ -87,46 +88,26 @@ body {
margin: 0; margin: 0;
position: relative; position: relative;
width: 100vw; width: 100vw;
height: 100%; /* height: 100%; */
padding-top: var(--padding-vertical); padding-top: var(--padding-vertical);
padding-bottom: var(--padding-vertical); padding-bottom: var(--padding-vertical);
overflow-x: clip; overflow-x: hidden;
background-color: black; background-color: black;
} }
body> :is(article, section)[data-layer] { .column {
position: fixed;
width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
transition: 0.2s ease-out;
}
body>article[data-layer] {
position: absolute;
}
body>section[data-layer]>canvas.shell {
position: fixed;
width: 100%;
}
body>section[data-layer]>canvas.shell {
box-shadow: -1px 1px 47px 20px rgba(0, 0, 0, 1);
-webkit-box-shadow: -1px 1px 47px 20px rgba(0, 0, 0, 1);
-moz-box-shadow: -1px 1px 47px 20px rgba(0, 0, 0, 1);
/* outline: 10vw solid; */
filter: url("#blob");
} }
body>aside { body>aside {
z-index: 500; z-index: 500;
} }
body>article { body>main {
position: relative !important; position: relative !important;
margin: 0 auto !important; margin: 0 auto !important;
width: 800px !important; width: min(800px, 90vw);
border-radius: 10px; border-radius: 10px;
background-color: var(--background-dark); background-color: var(--background-dark);
} }
@ -135,7 +116,7 @@ body> :last-child {
margin-bottom: 20vh !important; margin-bottom: 20vh !important;
} }
body>article>div#cover { body>main>div#cover {
z-index: 6000; z-index: 6000;
height: 300px; height: 300px;
display: flex; display: flex;
@ -143,17 +124,17 @@ body>article>div#cover {
border-radius: 10px 10px 0 0; border-radius: 10px 10px 0 0;
} }
body>article>div#cover>img { body>main>div#cover>img {
width: 100%; width: 100%;
/* object-fit: cover; /* object-fit: cover;
object-position: top; */ object-position: top; */
} }
body>article>header { body>main>header {
z-index: 5000; z-index: 5000;
top: 0; top: 0;
position: sticky; position: sticky;
height: 80px; min-height: 80px;
overflow: hidden; overflow: hidden;
clip-path: border-box; clip-path: border-box;
border-radius: 0px 0px 10px 10px; border-radius: 0px 0px 10px 10px;
@ -161,31 +142,35 @@ body>article>header {
} }
body>article>header>section { body>main>header>section {
position: relative; position: relative;
height: 100%; min-height: 80px;
display: flex; display: flex;
justify-content: center;
align-items: center;
filter: blur(2.2px) contrast(30); filter: blur(2.2px) contrast(30);
background: #750000; background: #750000;
} }
body>article>header>section>h1 { body>main>header>section>h1 {
font-size: 2.5rem; margin: 0.4rem 2rem;
margin: auto; font-size: min(2.5rem, 8vw);
text-align: center; text-align: center;
font-weight: normal;
color: red; color: red;
} }
body>article>header>section>canvas#title { body>main>header>section>canvas#title {
z-index: -5000; z-index: -5000;
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
body>article>main, body>main>article,
body>section.block { body>section.block {
z-index: 1000; z-index: 1000;
position: relative;
background-color: var(--background-light); background-color: var(--background-light);
} }
@ -193,38 +178,38 @@ body>section.block {
box-sizing: border-box; box-sizing: border-box;
border-radius: 10px; border-radius: 10px;
margin: 20px auto 0; margin: 20px auto 0;
width: 800px; width: min(800px, 90vw);
padding: 30px 50px; padding: 30px 50px;
display: block; display: block;
} }
body>article>main { body>main>article {
padding-top: 10px; padding-top: 10px;
border-radius: 0 0 10px 10px; border-radius: 0 0 10px 10px;
} }
body>article>main>section { body>main>article>section {
position: relative; position: relative;
margin: 30px 50px; margin: 30px 50px;
} }
body>article>main>section>p.digression { body>main>article>section>p.digression {
margin-left: 30px; margin-left: 30px;
color: var(--grey-dark); color: var(--grey-dark);
} }
body>article>main>section>p.digression * { body>main>article>section>p.digression * {
color: var(--grey-dark); color: var(--grey-dark);
} }
body>article>main>section#assault>img#wet_bebra { body>main>article>section#assault>img#wet_bebra {
width: 200px; width: 200px;
float: right; float: right;
shape-outside: polygon(68px 202px, 200px 197px, 158px 173px, 159px 50px, 192px 25px, 165px 0px, 56px 3px, 41px 27px, 56px 42px, 112px 47px, 103px 68px, 97px 116px, 58px 120px, 40px 169px, 6px 186px); shape-outside: polygon(68px 202px, 200px 197px, 158px 173px, 159px 50px, 192px 25px, 165px 0px, 56px 3px, 41px 27px, 56px 42px, 112px 47px, 103px 68px, 97px 116px, 58px 120px, 40px 169px, 6px 186px);
clip-path: polygon(208px 199px, 162px 170px, 162px 54px, 194px 21px, 155px -4px, 48px 7px, 54px 43px, 103px 51px, 91px 114px, 56px 116px, 45px 165px, -1px 186px, 51px 201px, 153px 202px); clip-path: polygon(208px 199px, 162px 170px, 162px 54px, 194px 21px, 155px -4px, 48px 7px, 54px 43px, 103px 51px, 91px 114px, 56px 116px, 45px 165px, -1px 186px, 51px 201px, 153px 202px);
} }
body>article>main>section#assault>img#scary { body>main>article>section#assault>img#scary {
margin-left: -20px; margin-left: -20px;
padding-right: 10px; padding-right: 10px;
width: 200px; width: 200px;
@ -233,7 +218,7 @@ body>article>main>section#assault>img#scary {
clip-path: polygon(208px 91px, 181px 75px, 203px 22px, 140px 1px, 58px 1px, -8px 112px, 55px 173px, 70px 201px, 136px 201px, 139px 176px, 175px 152px); clip-path: polygon(208px 91px, 181px 75px, 203px 22px, 140px 1px, 58px 1px, -8px 112px, 55px 173px, 70px 201px, 136px 201px, 139px 176px, 175px 152px);
} }
body>article>main>section#car>img#crying_bebra { body>main>article>section#car>img#crying_bebra {
margin-left: -20px; margin-left: -20px;
width: 200px; width: 200px;
float: left; float: left;
@ -241,7 +226,7 @@ body>article>main>section#car>img#crying_bebra {
clip-path: polygon(22px 169px, 44px 200px, 122px 207px, 165px 192px, 173px 151px, 187px 141px, 188px 108px, 169px 103px, 178px 52px, 150px 12px, 86px -7px, 41px 33px, 19px 67px); clip-path: polygon(22px 169px, 44px 200px, 122px 207px, 165px 192px, 173px 151px, 187px 141px, 188px 108px, 169px 103px, 178px 52px, 150px 12px, 86px -7px, 41px 33px, 19px 67px);
} }
body>article>main>section#car>img#chill_bebra { body>main>article>section#car>img#chill_bebra {
margin-right: -20px; margin-right: -20px;
width: 200px; width: 200px;
float: right; float: right;
@ -249,7 +234,7 @@ body>article>main>section#car>img#chill_bebra {
clip-path: polygon(11px 126px, -6px 194px, 71px 199px, 179px 181px, 204px 90px, 175px 32px, 118px -5px, 60px 27px, 80px 102px, 52px 124px, 54px 60px, 16px 58px, -1px 83px); clip-path: polygon(11px 126px, -6px 194px, 71px 199px, 179px 181px, 204px 90px, 175px 32px, 118px -5px, 60px 27px, 80px 102px, 52px 124px, 54px 60px, 16px 58px, -1px 83px);
} }
body>article>main>section#car>img#just { body>main>article>section#car>img#just {
margin-left: -20px; margin-left: -20px;
padding-right: 10px; padding-right: 10px;
width: 200px; width: 200px;
@ -258,7 +243,7 @@ body>article>main>section#car>img#just {
clip-path: polygon(-6px 171px, 76px 170px, 106px 201px, 165px 198px, 193px 159px, 206px 81px, 180px 26px, 129px -5px, 63px 15px, 32px 51px, 29px 124px); clip-path: polygon(-6px 171px, 76px 170px, 106px 201px, 165px 198px, 193px 159px, 206px 81px, 180px 26px, 129px -5px, 63px 15px, 32px 51px, 29px 124px);
} }
body>article>main>section#car>img#evil_bebra { body>main>article>section#car>img#evil_bebra {
margin-top: 30px; margin-top: 30px;
margin-right: -25px; margin-right: -25px;
width: 200px; width: 200px;
@ -267,7 +252,7 @@ body>article>main>section#car>img#evil_bebra {
clip-path: polygon(193px 197px, 161px 10px, 92px -8px, 19px 46px, 23px 138px, 7px 168px, 21px 196px); clip-path: polygon(193px 197px, 161px 10px, 92px -8px, 19px 46px, 23px 138px, 7px 168px, 21px 196px);
} }
body>article>main>section#deal>img#marta_with_broken_heart { body>main>article>section#deal>img#marta_with_broken_heart {
margin-top: 30px; margin-top: 30px;
margin-right: -15px; margin-right: -15px;
width: 200px; width: 200px;
@ -276,7 +261,7 @@ body>article>main>section#deal>img#marta_with_broken_heart {
clip-path: polygon(199px 146px, 204px 26px, 125px -1px, 65px -7px, -7px 96px, 19px 169px, 62px 195px, 150px 199px); clip-path: polygon(199px 146px, 204px 26px, 125px -1px, 65px -7px, -7px 96px, 19px 169px, 62px 195px, 150px 199px);
} }
body>article>main>section#deal>img#two_bebras { body>main>article>section#deal>img#two_bebras {
margin-top: 50px; margin-top: 50px;
margin-right: -10px; margin-right: -10px;
width: 200px; width: 200px;
@ -285,7 +270,7 @@ body>article>main>section#deal>img#two_bebras {
clip-path: polygon(215px 104px, 132px -2px, 108px 22px, 33px 40px, 20px 114px, -6px 127px, 20px 201px, 177px 179px); clip-path: polygon(215px 104px, 132px -2px, 108px 22px, 33px 40px, 20px 114px, -6px 127px, 20px 201px, 177px 179px);
} }
body>article>main>section#deal>img#fuck { body>main>article>section#deal>img#fuck {
margin-left: -20px; margin-left: -20px;
width: 200px; width: 200px;
float: left; float: left;
@ -293,7 +278,7 @@ body>article>main>section#deal>img#fuck {
clip-path: polygon(25px 194px, 100px 207px, 180px 190px, 171px 142px, 188px 90px, 179px 46px, 152px 5px, 75px -7px, 6px 56px, 28px 144px); clip-path: polygon(25px 194px, 100px 207px, 180px 190px, 171px 142px, 188px 90px, 179px 46px, 152px 5px, 75px -7px, 6px 56px, 28px 144px);
} }
body>article>main>section#friendship>img#no_comments { body>main>article>section#friendship>img#no_comments {
margin-top: 50px; margin-top: 50px;
margin-right: 0px; margin-right: 0px;
width: 200px; width: 200px;
@ -302,7 +287,7 @@ body>article>main>section#friendship>img#no_comments {
clip-path: polygon(208px 115px, 200px 41px, 145px -7px, 69px 13px, 46px 44px, -10px 58px, 39px 78px, 48px 141px, 46px 187px, 121px 201px, 192px 191px); clip-path: polygon(208px 115px, 200px 41px, 145px -7px, 69px 13px, 46px 44px, -10px 58px, 39px 78px, 48px 141px, 46px 187px, 121px 201px, 192px 191px);
} }
body>article>main>section#friendship>img#nu_tipa { body>main>article>section#friendship>img#nu_tipa {
margin-top: 100px; margin-top: 100px;
margin-right: 0px; margin-right: 0px;
width: 200px; width: 200px;
@ -311,22 +296,22 @@ body>article>main>section#friendship>img#nu_tipa {
clip-path: polygon(179px 142px, 176px 117px, 195px 100px, 163px 87px, 153px 26px, 91px -12px, 11px 39px, 1px 197px, 181px 203px, 172px 157px); clip-path: polygon(179px 142px, 176px 117px, 195px 100px, 163px 87px, 153px 26px, 91px -12px, 11px 39px, 1px 197px, 181px 203px, 172px 157px);
} }
body>article>main>section>img { body>main>article>section>img {
width: 100%; width: 100%;
height: 200px; height: 200px;
object-fit: cover; object-fit: cover;
border-radius: 3px; border-radius: 3px;
} }
body>article>main>section#conclusion { body>main>article>section#conclusion {
margin-bottom: 50px; margin-bottom: 50px;
} }
body>article>main>section#conclusion>h2 { body>main>article>section#conclusion>h2 {
margin-bottom: 20px; margin-bottom: 20px;
} }
body>article>main>section#conclusion>a>img { body>main>article>section#conclusion>a>img {
margin-top: 30px; margin-top: 30px;
margin-right: -4%; margin-right: -4%;
height: 300px; height: 300px;
@ -335,71 +320,87 @@ body>article>main>section#conclusion>a>img {
clip-path: polygon(136px 80px, 122px 10px, 92px 30px, 66px 36px, 36px 32px, 36px 91px, 55px 141px, 34px 145px, 32px 181px, 41px 189px, 81px 208px, 28px 264px, 47px 287px, 81px 295px, 155px 266px, 162px 232px, 180px 212px, 179px 180px, 196px 174px, 191px 152px, 146px 157px, 145px 135px, 161px 110px, 165px 92px); clip-path: polygon(136px 80px, 122px 10px, 92px 30px, 66px 36px, 36px 32px, 36px 91px, 55px 141px, 34px 145px, 32px 181px, 41px 189px, 81px 208px, 28px 264px, 47px 287px, 81px 295px, 155px 266px, 162px 232px, 180px 212px, 179px 180px, 196px 174px, 191px 152px, 146px 157px, 145px 135px, 161px 110px, 165px 92px);
} }
body>article>main>section>h2:before { body>article>section>h2:before {
margin-right: 10px; margin-right: 10px;
} }
body>article>main>section#assault>h2:before { body>main>article>section#assault>h2:before {
content: '🤕'; content: '🤕';
} }
body>article>main>section#reasons>h2:before { body>main>article>section#reasons>h2:before {
content: '😼'; content: '😼';
} }
body>article>main>section#car>h2:before { body>main>article>section#car>h2:before {
content: '😵'; content: '😵';
} }
body>article>main>section#deal>h2:before { body>main>article>section#deal>h2:before {
content: '🤝'; content: '🤝';
} }
body>article>main>section#friendship>h2:before { body>main>article>section#friendship>h2:before {
content: '🥳'; content: '🥳';
} }
body>article>main>section#court>h2:before { body>main>article>section#court>h2:before {
content: '😥'; content: '😥';
} }
body>article>main>section#return>h2:before { body>main>article>section#return>h2:before {
content: '🥱'; content: '🥱';
} }
body>article>main>section#conclusion>h2:before { body>main>article>section#conclusion>h2:before {
content: '🤟'; content: '🤟';
} }
body>article>main>section>p+p, body>main>article>section>p+p,
body>article>main>section>p>small+small { body>main>article>section>p>small+small {
margin-top: 10px; margin-top: 10px;
} }
body>article>main>section>h2 { body>main>article>section>h2 {
font-size: 1.8rem; font-size: 1.8rem;
} }
body>article>main>section>h2+h3 { body>main>article>section>h2+h3 {
margin-top: 3px; margin-top: 3px;
} }
body>article>main>section> :is(h2, h3) { body>main>article>section> :is(h2, h3) {
margin-bottom: 0px; margin-bottom: 0px;
line-height: 35px; line-height: 35px;
} }
body>article>main>section> :is(h2, h3)+p { body>main>article>section> :is(h2, h3)+p {
margin-top: 15px; margin-top: 15px;
} }
body>article>main>section>p:last-of-type { body>main>article>section>p:last-of-type {
margin-bottom: 20px; margin-bottom: 20px;
} }
body>article>footer { body>canvas#background {
z-index: -1000;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
box-shadow: -1px 1px 47px 20px rgba(0, 0, 0, 1);
-webkit-box-shadow: -1px 1px 47px 20px rgba(0, 0, 0, 1);
-moz-box-shadow: -1px 1px 47px 20px rgba(0, 0, 0, 1);
/* outline: 10vw solid; */
filter: url("#blob");
transition: 0s;
}
body>main>footer {
z-index: 3000; z-index: 3000;
} }
@ -410,11 +411,12 @@ body>section#contacts>section {
body>section#contacts>section#author { body>section#contacts>section#author {
margin-top: 20px; margin-top: 20px;
margin-bottom: 35px; margin-bottom: 35px;
align-items: center;
gap: 2rem;
} }
body>section#contacts>section#author>section#avatar { body>section#contacts>section#author>section#avatar {
margin-left: 10px; margin-left: 10px;
margin-right: 25px;
position: relative; position: relative;
max-width: 100px; max-width: 100px;
max-height: 100px; max-height: 100px;
@ -579,6 +581,7 @@ body>section#license>p>span:last-of-type {
} }
body>section#license>img { body>section#license>img {
z-index: 1000;
position: absolute; position: absolute;
right: -65px; right: -65px;
bottom: -50px; bottom: -50px;
@ -593,8 +596,10 @@ body>svg#navalny2 {
} }
body>section#navalny { body>section#navalny {
width: 800px; --height: min(200px, 30vw);
height: 190px; z-index: 500;
width: min(800px, 90vw);
height: calc(var(--height));
padding: unset; padding: unset;
cursor: pointer; cursor: pointer;
-webkit-transform: translateZ(0); -webkit-transform: translateZ(0);
@ -610,6 +615,7 @@ body>section#navalny {
-webkit-backdrop-filter: saturate(100%) hue-rotate(230deg) blur(22px); -webkit-backdrop-filter: saturate(100%) hue-rotate(230deg) blur(22px);
backdrop-filter: saturate(100%) hue-rotate(230deg) blur(22px); backdrop-filter: saturate(100%) hue-rotate(230deg) blur(22px);
background-color: rgba(0, 3, 210, 0.05); background-color: rgba(0, 3, 210, 0.05);
clip-path: polygon(0px 0px, 0 var(--height), 100% var(--height), 100% 0px);
} }
body>section#navalny:hover { body>section#navalny:hover {
@ -621,77 +627,42 @@ body>section#navalny:hover {
@media (max-width: 840px) { @media (max-width: 840px) {
body { body {
padding-top: unset; padding-top: 5vw;
padding-bottom: 20px; padding-bottom: 5vw;
} }
body>article>header { body>main>header {
position: relative; position: relative;
} }
body>article { body>main>header>section>h1 {
width: 100% !important; padding: 0 15%;
}
body>main {
margin: unset; margin: unset;
border-radius: unset;
} }
body>article>div#cover, body>main>article {
body>article>main {
border-radius: unset;
}
body>article>main {
box-shadow: 1px 6px 11px 3px rgba(0, 0, 0, 0.6); box-shadow: 1px 6px 11px 3px rgba(0, 0, 0, 0.6);
-webkit-box-shadow: 1px 6px 11px 3px rgba(0, 0, 0, 0.6); -webkit-box-shadow: 1px 6px 11px 3px rgba(0, 0, 0, 0.6);
-moz-box-shadow: 1px 6px 11px 3px rgba(0, 0, 0, 0.6); -moz-box-shadow: 1px 6px 11px 3px rgba(0, 0, 0, 0.6);
} }
body>section.block { body>main>section.block {
width: calc(100% - 40px) !important; width: calc(100% - 40px) !important;
margin-left: 20px !important; margin-left: 20px !important;
margin-right: 20px !important; margin-right: 20px !important;
} }
mask#NAVALNY>text { body>section#contacts>section#author {
font-size: calc(5rem - (5rem - 17vw)) !important;
transform: translate(0, 120px) !important;
}
}
@media (max-width: 710px) {
body>article>header {
height: calc(140px + (110px - 20vw));
}
body>article>header>section>h1 {
padding: 0 10vw;
}
}
@media (max-width: 690px) {
body>section#contacts>section {
flex-direction: column; flex-direction: column;
} }
body>section#contacts>section#author>section#avatar {
margin-left: auto;
margin-right: auto;
margin-bottom: 25px;
position: relative;
max-width: 120px;
max-height: 120px;
width: 120px;
height: 120px;
flex-shrink: 0;
clip-path: circle(60px);
}
body>section#contacts>section#author>section#name { body>section#contacts>section#author>section#name {
text-align: center; text-align: center;
} }
}
@media (max-width: 600px) {
body>section.block#views>h3 { body>section.block#views>h3 {
display: block; display: block;
text-align: center; text-align: center;
@ -710,10 +681,9 @@ body>section#navalny:hover {
body>section.block#views>section:last-of-type { body>section.block#views>section:last-of-type {
width: 100%; width: 100%;
} }
}
@media (max-width: 430px) { mask#NAVALNY>text {
body>article>header>section>h1 { font-size: 18vw !important;
padding: 0 5vw; transform: translate(0, 60px) !important;
} }
} }

View File

@ -17,7 +17,7 @@ section.popup>div.wrap {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20px; gap: 20px;
border-radius: 2px; border-radius: 0.75rem;
background-color: var(--background-light); background-color: var(--background-light);
} }

View File

Before

Width:  |  Height:  |  Size: 950 B

After

Width:  |  Height:  |  Size: 950 B

View File

Before

Width:  |  Height:  |  Size: 229 KiB

After

Width:  |  Height:  |  Size: 229 KiB

View File

Before

Width:  |  Height:  |  Size: 552 B

After

Width:  |  Height:  |  Size: 552 B

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 995 B

After

Width:  |  Height:  |  Size: 995 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 968 B

After

Width:  |  Height:  |  Size: 968 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 944 B

After

Width:  |  Height:  |  Size: 944 B

View File

Before

Width:  |  Height:  |  Size: 972 B

After

Width:  |  Height:  |  Size: 972 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 836 B

After

Width:  |  Height:  |  Size: 836 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Some files were not shown because too many files have changed in this diff Show More