13 Commits
0.6.0 ... 2.0.0

583 changed files with 14283 additions and 2673 deletions

10
.gitmodules vendored
View File

@@ -2,11 +2,15 @@
path = hotline.mjs path = hotline.mjs
url = https://git.svoboda.works/mirzaev/hotline.mjs url = https://git.svoboda.works/mirzaev/hotline.mjs
branch = stable branch = stable
[submodule "womb3-simplex.mjs"] [submodule "damper.mjs"]
path = womb3-simplex.mjs path = damper.mjs
url = https://git.svoboda.works/mirzaev/womb3-simplex.mjs url = https://git.svoboda.works/mirzaev/damper.mjs.git
branch = stable branch = stable
[submodule "icons"] [submodule "icons"]
path = icons path = icons
url = https://git.svoboda.works/mirzaev/icons url = https://git.svoboda.works/mirzaev/icons
branch = stable branch = stable
[submodule "womb3-simplex.mjs"]
path = womb3-simplex.mjs
url = https://git.svoboda.works/mirzaev/womb3-simplex.mjs
branch = stable

View File

@@ -1,13 +1,13 @@
{ {
"name": "kodorvan/perm", "name": "kodorvan/site",
"description": "Лендинг для Перми от Ксении", "description": "The kodorvan team main site",
"homepage": "https://git.svoboda.works/kodorvan/perm", "homepage": "https://git.svoboda.works/kodorvan/site",
"type": "site", "type": "site",
"keywords": [ "keywords": [
"minimal", "minimal",
"baza", "baza",
"landing", "landing",
"perm" "site"
], ],
"readme": "README.md", "readme": "README.md",
"license": "WTFPL", "license": "WTFPL",
@@ -20,17 +20,21 @@
} }
], ],
"support": { "support": {
"wiki": "https://git.svoboda.works/kodorvan/perm/wiki", "wiki": "https://git.svoboda.works/kodorvan/site/wiki",
"issues": "https://git.svoboda.works/kodorvan/perm/issues" "issues": "https://git.svoboda.works/kodorvan/site/issues"
}, },
"require": { "require": {
"php": "^8.5", "php": "^8.5",
"mirzaev/minimal": "^3.8", "ext-blake3": "^0.1",
"mirzaev/minimal": "^3.10.4",
"mirzaev/baza": "^3.4", "mirzaev/baza": "^3.4",
"mirzaev/languages": "^1", "mirzaev/languages": "^1",
"twig/twig": "^3.2", "twig/twig": "^3.2",
"twig/extra-bundle": "^3.7", "twig/extra-bundle": "^3.7",
"twig/intl-extra": "^3.10" "twig/intl-extra": "^3.10",
"phpmailer/phpmailer": "^7.0",
"mirzaev/record": "^2.2",
"svoboda/time": "^1.0"
}, },
"suggest": { "suggest": {
"mirzaev/files": "Easy working with files", "mirzaev/files": "Easy working with files",
@@ -39,12 +43,12 @@
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"kodorvan\\perm\\": "kodorvan/perm/system" "kodorvan\\site\\": "kodorvan/site/system"
} }
}, },
"autoload-dev": { "autoload-dev": {
"psr-4": { "psr-4": {
"kodorvan\\perm\\tests\\": "kodorvan/perm/tests" "kodorvan\\site\\tests\\": "kodorvan/site/tests"
} }
}, },
"scripts": { "scripts": {

583
composer.lock generated

File diff suppressed because it is too large Load Diff

1
damper.mjs Submodule

Submodule damper.mjs added at 81d208b964

View File

@@ -1,35 +1,43 @@
#!/bin/bash #!/bin/bash
git submodule update --init --recursive
if [ -d author/project ]; then if [ -d author/project ]; then
mv author/project author/perm mv author/project author/site
fi fi
if [ -d author ]; then if [ -d author ]; then
mv author kodorvan mv author kodorvan
fi fi
if [ -e kodorvan/perm/system/settings/*.sample ]; then for i in kodorvan/site/system/settings/*.sample; do
for i in kodorvan/perm/system/settings/*.sample; do echo $i;
cp "$i" "${i/.sample/}"; if [ ! -f "${i/.sample/}" ]; then
cp -n "$i" "${i/.sample/}";
echo ${i/.sample/};
fi
done done
if ! [ -d kodorvan/site/system/public/js/modules ]; then
mkdir kodorvan/site/system/public/js/modules -p
fi fi
if ! [ -d kodorvan/perm/system/public/js/modules ]; then if ! [ -L kodorvan/site/system/public/js/modules/damper.mjs ]; then
mkdir kodorvan/perm/system/public/js/modules -p ln -s ../../../../../../damper.mjs/damper.mjs kodorvan/site/system/public/js/modules/damper.mjs;
fi fi
if ! [ -L kodorvan/perm/system/public/js/modules/hotline.mjs ]; then if ! [ -L kodorvan/site/system/public/js/modules/hotline.mjs ]; then
ln -s ../../../../../../hotline.mjs/hotline.mjs kodorvan/perm/system/public/js/modules/hotline.mjs; ln -s ../../../../../../hotline.mjs/hotline.mjs kodorvan/site/system/public/js/modules/hotline.mjs;
fi fi
if ! [ -L kodorvan/perm/system/public/js/modules/womb3-simplex.mjs ]; then if ! [ -L kodorvan/site/system/public/js/modules/womb3-simplex.mjs ]; then
ln -s ../../../../../../womb3-simplex.mjs/womb3-simplex.mjs kodorvan/perm/system/public/js/modules/womb3-simplex.mjs; ln -s ../../../../../../womb3-simplex.mjs/womb3-simplex.mjs kodorvan/site/system/public/js/modules/womb3-simplex.mjs;
fi fi
if ! [ -L kodorvan/perm/system/public/js/modules/simplex-noise.mjs ]; then if ! [ -L kodorvan/site/system/public/js/modules/simplex-noise.mjs ]; then
ln -s ../../../../../../womb3-simplex.mjs/simplex-noise.mjs kodorvan/perm/system/public/js/modules/simplex-noise.mjs; ln -s ../../../../../../womb3-simplex.mjs/simplex-noise.mjs kodorvan/site/system/public/js/modules/simplex-noise.mjs;
fi fi
if ! [ -d kodorvan/perm/system/public/css/icons ]; then if ! [ -L kodorvan/site/system/public/css/icons ]; then
ln -s ../../../../../icons/css kodorvan/perm/system/public/css/icons; ln -s ../../../../../icons/css kodorvan/site/system/public/css/icons;
fi fi

View File

@@ -1,213 +0,0 @@
<?php
declare(strict_types=1);
namespace kodorvan\perm\controllers;
// Files of the project
use kodorvan\perm\controllers\core;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
/**
* Index
*
* @package kodorvan\perm\controllers
*
* @param array $errors Registry of errors
*
* @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
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
* Main page
*
* @return null
*/
public function index(): null
{
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Initializing the team workload
$this->view->workload = (string) ($_COOKIE['workload'] ?? rand(20, 80));
// Initializing services
$this->view->services = [
[
'class' => 'telegram voronka',
'title' => 'Телеграм воронка',
'icon_left' => '',
/* 'icon_center' => 'import', */
'icon_center' => 'crown',
'icon_right' => '',
'description' => <<<TXT
Поступательно запросит данные пользователя, скомпонует, запишет в базу данных и синхронизирует в CRM
<br><br>
Используя иммерсивные технологии и многофакторный сбор обеспечивает максимальное удержание пользователя
TXT,
'howto' => 'Направьте к нему клиентов и ждите новых заказов в вашей CRM, на сайте или в чате',
'buttons' => [
[
'icon' => 'comment',
'link' => ''
]
],
'theses' => [
[
'class' => 'yellow',
'characteristic' => '-80%',
'text' => 'НАГРУЗКА'
],
[
'class' => 'blue',
'colored' => true,
'characteristic' => '+5%',
'text' => 'КОНВЕРСИИ'
],
[
'class' => 'green',
'characteristic' => '0₽',
'text' => 'НИКАКОЙ АРЕНДЫ'
]
],
'background_image_src' => '/themes/default/images/telegram_voronka.png',
'background_image_alt' => 'Телеграм воронка КОДОРВАНЬ',
'cost' => '2000'
],
[
'class' => 'parser',
'title' => 'Парсер',
'icon_left' => '',
'icon_center' => 'search',
'icon_right' => '',
'description' => <<<TXT
Любая работа за компьютером может быть автоматизирована
<br><br>
Парсер берёт данные с сайтов через API, либо эмулируя пользователя, а так же из excel-документов, CRM и бухгалтерии, затем просчитывает, анализирует и записывает результат
TXT,
'howto' => 'Подключите источники и снизьте нагрузку на операторов, оптимизируйте процессы',
'extra' => [
'Wildberries',
'OZON',
'Yandex Market',
'Avito',
'CDEK',
'1C',
'Bitrix',
'Мой Склад'
],
'buttons' => [
[
'icon' => 'comment',
'link' => ''
]
],
'theses' => [
[
'class' => 'yellow',
'colored' => true,
'characteristic' => '-100%',
'text' => 'НАГРУЗКА'
],
[
'class' => 'cyan',
'icon' => 'infinity',
'text' => 'ВЕЧНАЯ ПОДДЕРЖКА'
],
[
'class' => 'green',
'icon' => 'play forwards',
'text' => 'РЕКОРД СКОРОСТИ'
]
],
'background_image_src' => '/themes/default/images/excel_small_compressed.jpg',
'background_image_alt' => 'Парсеры КОДОРВАНЬ',
'cost' => '3000'
],
[
'class' => 'calculator',
'title' => 'Калькулятор',
'icon_left' => '',
'icon_center' => 'calculator',
'icon_right' => '',
'description' => <<<TXT
Составление алгоритма обработки большого объёма данных с использованием нейросетей и грамотно выбранной сортировки
<br><br>
Оператор вводит данные, нажимает на кнопки, двигает ползунки и мгновенно получает точный результат вычислений
TXT,
'howto' => 'Настройте параметры в панели управления и в долгосрочной перспективе сэкономьте тысячи часов рабочего времени',
'extra' => [],
'buttons' => [
[
'icon' => 'comment',
'link' => ''
]
],
'theses' => [
[
'class' => 'yellow',
'characteristic' => '-95%',
'text' => 'НАГРУЗКА'
],
[
'class' => 'green',
'characteristic' => '-80%',
'text' => 'ОШИБОК ВЫЧИСЛЕНИЙ'
],
[
'class' => 'red',
'colored' => true,
'characteristic' => '+20%',
'text' => 'ОБУЧАЕМОСТЬ'
]
],
'background_image_src' => '/themes/default/images/tordv_compressed.jpg',
'background_image_alt' => 'Калькулятор КОДОРВАНЬ',
'cost' => '10 000'
]
];
// Sending the cookie with the team workload (1800 = 30min)
setcookie('workload', $this->view->workload, time() + 1800, '/');
// Render page
$page = $this->view->render('main/index.html');
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
// Exit (fail)
return null;
}
}

View File

@@ -1,15 +0,0 @@
const items = document.querySelectorAll(".accordion button");
function toggleAccordion() {
const itemToggle = this.getAttribute('aria-expanded');
for (i = 0; i < items.length; i++) {
items[i].setAttribute('aria-expanded', 'false');
}
if (itemToggle == 'false') {
this.setAttribute('aria-expanded', 'true');
}
}
items.forEach(item => item.addEventListener('click', toggleAccordion));

View File

@@ -1,19 +0,0 @@
document.addEventListener('DOMContentLoaded', function() {
const blocks = document.querySelectorAll('.block');
blocks.forEach(block => {
const question = block.querySelector('.question');
const answerCont = block.querySelector('.answercont');
question.addEventListener('click', function() {
// Просто переключаем текущий блок без влияния на другие
if (block.classList.contains('active')) {
answerCont.style.maxHeight = '0';
block.classList.remove('active');
} else {
answerCont.style.maxHeight = answerCont.scrollHeight + 'px';
block.classList.add('active');
}
});
});
});

View File

@@ -1,49 +0,0 @@
"use strict";
import("../modules/hotline.mjs").then((module) => {
// Imported the hotline.mjs module
// Initializing an instance of the hotline.mjs
const instance = new module.hotline(document.getElementById("wrap"));
// Initializing settings of the hotline instance
instance.alive = true;
instance.wheel = false;
instance.delta = 3;
instance.step = -0.5;
// Starting the hotline instance
instance.start();
});
import("../modules/womb3-simplex.mjs").then((module) => {
// Initializing the instance
const womb = new module.womb(document.getElementById("introdution_animation"));
womb.block = {
width: 40,
height: 40,
};
womb.init();
womb.generate(undefined, '#000');
// Initializing the process registers
let offset = 0;
let speed = 0.01;
// Starting the process
setInterval(function () {
womb.dump();
womb.generate((offset += speed), '#000');
}, 60);
// Initializing the resizing event processor
window.addEventListener(
"resize",
function (e) {
womb.init();
womb.dump();
womb.generate((offset += speed), '#000');
},
true
);
});

View File

@@ -1,67 +0,0 @@
@charset "UTF-8";
@media (prefers-color-scheme: default) {
:root {
--text-color: #fff;
--text-color-inverted: #000;
--button-background-color-inverted: #fff;
--button-background-color: #000;
--section-background-color-inverted: #fff;
--section-background-color: #000;
--background-color: #000;
--background-color-inverted: #fff;
--interface-top-background-color: var(--background-color, #000);
--interface-background-color: var(--background-color, #000);
--interface-bottom-background-color: var(--background-color, #000);
--red: red;
--white: #fff;
--blue: #0ea5e9;
--paper: var(--white);
}
}
@media (prefers-color-scheme: dark) {
:root {
--text-color: #fff;
--text-color-inverted: #000;
--button-background-color-inverted: #fff;
--button-background-color: #000;
--section-background-color-inverted: #fff;
--section-background-color: #fff;
--background-color: #000;
--background-color-inverted: #fff;
--interface-top-background-color: var(--background-color, #000);
--interface-background-color: var(--background-color, #000);
--interface-bottom-background-color: var(--background-color, #000);
--red: red;
--white: #fff;
--paper: var(--white);
}
}
@media (prefers-color-scheme: light) {
:root {
--text-color: #fff;
--text-color-inverted: #000;
--button-background-color-inverted: #fff;
--button-background-color: #000;
--section-background-color-inverted: #fff;
--section-background-color: #000;
--background-color: #000;
--background-color-inverted: #fff;
--interface-top-background-color: var(--background-color, #000);
--interface-background-color: var(--background-color, #000);
--interface-bottom-background-color: var(--background-color, #000);
--red: red;
--white: #fff;
--paper: var(--white);
}
}

View File

@@ -1,118 +0,0 @@
@charset "UTF-8";
.advantages {
margin: 0 auto;
width: 48rem;
> h2.title {
text-align: center;
font-size: 2.4rem;
font-family: "Bahnschrift";
margin: 0.1em 0 0.2em 0;
}
.accordion {
.accordion-item {
border-bottom: 1px solid #4d5974;
button[aria-expanded="true"] {
border-bottom: 1px solid #0ea5e9;
}
&:last-child {
border: none;
}
}
button {
position: relative;
display: block;
text-align: left;
width: 100%;
padding: 1em 0;
color: #7288a2;
font-size: 1.2rem;
font-family: "Bahnschrift";
font-weight: 400;
border: none;
background: none;
outline: none;
&:hover,
&:focus {
cursor: pointer;
color: #0ea5e9;
&::after {
cursor: pointer;
color: #0ea5e9;
border: 1px solid #0ea5e9;
}
}
.title {
padding: 1em 1.5em 1em 0;
}
.icon {
display: inline-block;
position: absolute;
top: 18px;
right: 0;
width: 22px;
height: 22px;
border: 1px solid;
border-radius: 22px;
&::before {
display: block;
position: absolute;
content: "";
top: 11px;
left: 6px;
width: 10px;
height: 2px;
background: currentColor;
}
&::after {
display: block;
position: absolute;
content: "";
top: 7px;
left: 10px;
width: 2px;
height: 10px;
background: currentColor;
}
}
}
}
button[aria-expanded="true"] {
color: #0ea5e9;
.icon {
&::after {
width: 0;
}
}
+ .accordion-content {
opacity: 1;
max-height: 9em;
transition: all 200ms linear;
will-change: opacity, max-height;
}
}
.accordion-content {
opacity: 0;
max-height: 0;
overflow: hidden;
transition: opacity 200ms linear, max-height 200ms linear;
will-change: opacity, max-height;
p {
align-items: left;
font-size: 1.05rem;
font-weight: 300;
font-family: "Bahnschrift";
margin: 2em 0;
}
}
}

View File

@@ -1,54 +0,0 @@
@charset "UTF-8";
section#company {
justify-self: end;
width: 160px;
padding: 1rem;
padding-bottom: unset;
display: flex;
flex-direction: column;
gap: 0.5rem;
font-family: "Bahnschrift";
> h4.name {
margin: unset;
display: block;
text-align: right;
font-weight: 600;
font-size: 1rem;
}
> p.column {
margin: unset;
display: inline-flex;
flex-direction: column;
text-align: right;
gap: 0.2em;
font-size: 0.8rem;
color: grey;
> span.row {
display: inline-flex;
justify-content: end;
font-weight: 400;
&:before {
margin-right: auto;
font-weight: 600;
color: #fff;
}
}
> span.tax {
&:before {
content: var(--company-tax) ":";
}
}
> span.identifier {
&:before {
content: var(--company-identifier) ":";
}
}
}
}

View File

@@ -1,54 +0,0 @@
@charset "UTF-8";
section#cookies {
--shadow: 4px 4px 10px 0px rgb(0 0 0 / 45%);
z-index: 3100;
right: var(--fixed-right, 2rem);
bottom: var(--fixed-bottom, 2rem);
position: fixed;
font-family: "Bahnschrift";
/* border: 1px solid #a8a8a847; */
border: 1px solid #fff;
/* border-right: unset;
border-bottom: unset; */
border-radius: 0.75rem;
color: #fff;
background-color: #000000b8;
background-color: #000000;
/* backdrop-filter: blur(3px); */
box-shadow: var(--shadow);
-webkit-box-shadow: var(--shadow);
-moz-box-shadow: var(--shadow);
transition: opacity 0.1s ease-out;
> div {
padding: 0.8rem 1.2rem 0.7rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> p {
margin: unset;
font-size: 1rem;
}
> small {
font-size: 0.8rem;
font-weight: 200;
color: #a6a69d;
}
}
> button {
top: -0.4rem;
right: -2rem;
position: absolute;
padding: unset;
padding-right: 0.1em;
cursor: pointer;
border: unset;
color: #f00;
background: unset;
}
}

View File

@@ -1,70 +0,0 @@
@charset "UTF-8";
section#cookies {
--shadow: 4px 4px 10px 0px rgb(0 0 0 / 45%);
z-index: var(--cookies-z-index, 6000);
right: var(--cookies-right, 2rem);
bottom: var(--cookies-bottom, 2rem);
position: fixed;
width: var(--cookies-width, 400px);
height: var(--cookies-height, 40px);
/* padding: 0.8rem 1.2rem 0.7rem; */
font-family: "Bahnschrift";
color: #fff;
transition: opacity 0.1s ease-out;
:is(> label[for="cookies"]:focus) {
opacity: 0;
}
+ div.cookies.background {
z-index: calc(var(--cookies-z-index, 6000) - 1);
right: var(--cookies-right, 2rem);
bottom: var(--cookies-bottom, 2rem);
position: fixed;
width: var(--cookies-width, 400px);
height: var(--cookies-height, 40px);
border: 1px solid #a8a8a847;
border-right: unset;
border-bottom: unset;
border-radius: 0.75rem;
background-color: #33323691;
backdrop-filter: blur(3px);
mix-blend-mode: screen;
box-shadow: var(--shadow);
-webkit-box-shadow: var(--shadow);
-moz-box-shadow: var(--shadow);
}
> div {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> p {
margin: unset;
font-size: 1rem;
}
> small {
font-size: 0.8rem;
font-weight: 200;
color: #a6a69d;
}
}
> label {
right: -20px;
top: -20px;
position: absolute;
padding: unset;
padding-right: 0.1em;
cursor: pointer;
border: unset;
color: #f00;
background: unset;
}
}

View File

@@ -1,172 +0,0 @@
@charset "UTF-8";
section#introdution {
position: relative;
width: 100%;
height: var(--introdution-height, 350px);
overflow: hidden;
background-color: #000;
+section.row {
--shadow: 0px -10px 60px 30px rgba(0, 0, 0, 0.6);
padding-top: 1rem;
box-shadow: var(--shadow);
-webkit-box-shadow: var(--shadow);
-moz-box-shadow: var(--shadow);
}
>div.information {
z-index: 200;
position: fixed;
width: 33rem;
display: flex;
flex-direction: column;
align-items: center;
cursor: default;
/* transform: perspective(35px) rotatex(1deg); */
>span#label {
--shadow: 0px 9px 8px 0px rgb(0 0 0 / 40%);
margin-top: -2em;
padding: 0.4em 0.8em 0.2em 1.2em;
display: flex;
justify-content: center;
align-items: center;
gap: 1em;
font-size: 1.2rem;
font-family: "Bahnschrift";
font-weight: 400;
border-radius: 1.125rem;
color: #aeb629;
border: 1px solid #e06a6a6e;
border-bottom: unset;
background-color: #472929a8;
backdrop-filter: blur(1.3px);
box-shadow: var(--shadow);
-webkit-box-shadow: var(--shadow);
-moz-box-shadow: var(--shadow);
/* transform: perspective(25px) rotatex(-1deg); */
>i.icon.code {
margin-bottom: 3px;
}
}
>h2#title {
margin: unset;
width: max-content;
padding: 0.2em 0.5em 0em;
font-family: Bahnschrift;
font-size: 2.6rem;
font-weight: 400;
color: #fff;
text-shadow:
0px 0px 4px #ffffff85,
0px 0px 9px #ffffff47;
>span.kodorvan {
color: #ffff00;
text-shadow:
0px 0px 4px #ffff00b5,
0px 0px 11px #ffff008a
}
}
>p#team {
margin: unset;
width: 100%;
/* height: 70px; */
box-sizing: border-box;
padding: 0.6em 1em;
text-align: center;
font-size: 1.2rem;
font-family: "Bahnschrift";
font-weight: 400;
border-radius: 0.75rem;
background-color: #fff;
>b {
color: #152bcb;
}
>strong {
color: #de1111;
}
}
>span {
position: absolute;
display: flex;
padding: 0.4em 0.8rem 0.3em;
font-size: 1.2rem;
font-family: "Bahnschrift";
font-weight: 400;
border-radius: 0.75rem;
background-color: #fff;
}
}
>div.background {
z-index: 100;
top: -5%;
left: -5%;
position: absolute;
width: 110%;
height: 110%;
animation-name: appearance;
animation-fill-mode: forwards;
animation-duration: 0.2s;
animation-delay: 1s;
animation-timing-function: ease-in;
filter: blur(1.8px) contrast(50);
>div.dots {
--dot-bg: black;
--dot-color: #00ff00;
--dot-size: 4px;
--dot-space: 7px;
z-index: -50;
position: absolute;
width: 100%;
height: 100%;
background:
linear-gradient(90deg,
var(--dot-bg) calc(var(--dot-space) - var(--dot-size)),
transparent 1%) center / var(--dot-space) var(--dot-space),
linear-gradient(var(--dot-bg) calc(var(--dot-space) - var(--dot-size)),
transparent 1%) center / var(--dot-space) var(--dot-space),
var(--dot-color);
mix-blend-mode: color-burn;
filter: contrast(5);
}
>video:only-of-type {
z-index: -100;
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
scale: 1.1;
filter: blur(5px);
}
>canvas#introdution_animation {
z-index: -100;
position: absolute;
width: 100%;
scale: 1.2;
filter: url(#blob) contrast(var(--contrast, 30));
}
}
}
@keyframes appearance {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

View File

@@ -1,27 +0,0 @@
@charset "UTF-8";
nav#links {
flex-grow: 1;
display: inline-flex;
justify-content: center;
gap: 1rem;
> a {
text-decoration: none;
font-family: "Geologica";
font-weight: 400;
font-size: 0.85rem;
color: #807f7f;
transition: color 0.1s ease-out;
&:is(:hover, :focus) {
color: #d5d5d5;
transition: color 0s;
}
&:active {
color: #4b4b4b;
transition: color 0s;
}
}
}

View File

@@ -1,41 +0,0 @@
@charset "UTF-8";
section#office {
height: 100%;
display: flex;
> div.map {
width: 250px;
height: 100%;
overflow: hidden;
border-radius: 0.75rem;
border: 1px solid #fff;
background-color: #0c110c;
> div.loading {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
filter: brigtless(0.8) blur(1px);
&:before {
margin-top: 50px;
position: absolute;
content: var(--map-loading, "Loading");
width: max-content;
text-align: center;
font-family: "Geologica";
font-style: normal;
font-weight: 400;
font-size: 0.6rem;
color: #533a3a;
}
> i.icon.loading.spinner {
color: #fff;
}
}
}
}

View File

@@ -1,482 +0,0 @@
@charset "UTF-8";
section#popular {
position: relative;
display: flex;
>div.title {
margin-top: 1rem;
margin-bottom: 1rem;
width: var(--width);
display: flex;
>div.column {
display: flex;
flex-direction: column;
&:is(.display) {
margin-top: auto;
height: min-content;
display: flex;
flex-direction: row;
border-radius: 1.125rem;
border: 2px solid #000;
background-color: #fff;
/* color: #fff;
background-color: #000; */
>span.amount {
margin-bottom: 0.1em;
display: flex;
justify-content: center;
align-items: center;
font-family: "Cascadia Code";
font-weight: 600;
}
>button {
--padding: 1rem;
box-sizing: border-box;
padding: var(--padding, 1rem);
cursor: pointer;
border: unset;
/* color: #fff; */
background: unset;
/* &:first-of-type:not(:only-of-type) {
padding-right: calc(var(--padding, 1rem) / 1.5);
}
&:last-of-type:not(:only-of-type) {
padding-left: calc(var(--padding, 1rem) / 1.5);
} */
}
}
&:last-of-type:not(:only-of-type) {
margin-left: auto;
}
>h3 {
margin: unset;
font-weight: 600;
font-size: 2rem;
}
}
}
>div.services {
--row-amount: 3;
--row-amount-protected: min(max(1, var(--row-amount, 1)), 4);
--gap: 1rem;
width: var(--width);
display: flex;
flex-flow: row wrap;
gap: var(--gap);
>article.service {
--service-width: max(250px, calc(var(--width) / var(--row-amount-protected, 2) - (var(--gap, 0px) * 0.5 * (var(--row-amount-protected, 2) - 1))));
--icon-background-color: #261d1b;
--background-color: #3f312e;
position: relative;
min-width: 250px;
width: var(--service-width);
min-height: 450px;
box-sizing: border-box;
padding: 1.2rem 0 0;
display: flex;
flex-direction: column;
align-items: center;
color: #fff;
transition: width 0.2s cubic-bezier(0.5, 0, 0, 1);
&:is(.telegram.voronka) {
--icon-background-color: #1a82b6;
--background-color: #27a6e6;
}
&:is(.parser) {
--icon-background-color: #996405;
/* --background-color: #fcfd1e; */
--background-color: #e58523;
}
&:is(.calculator) {
--icon-background-color: #a93737;
--background-color: #d24545;
}
>i.icon {
position: absolute;
margin-top: -1rem;
color: #000;
&:is(.left) {
justify-self: start;
}
&:is(.center) {
justify-self: center;
}
&:is(.right) {
justify-self: end;
}
&:is(.crown) {
top: 1.2em;
}
&:is(.search) {
top: 1em;
}
&:is(.file.document) {
top: 1em;
}
&:is(.calculator) {
top: 0.8em;
}
}
>div.head {
--border-height: 20px;
--border-gap: 0.4em;
z-index: 50;
position: relative;
width: 100%;
height: calc(2.6em + var(--border-height, 0px) - 0.75rem + var(--border-gap, 0px));
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: start;
/* text-shadow: 0px -0.03em 0.24em #000000b3, 0px -0.03em 1em #00000087; */
&:after {
z-index: -100;
position: absolute;
bottom: -0.75rem;
left: 0;
content: '';
width: 100%;
height: var(--border-height);
border-radius: 0.75rem 0.75rem 0 0;
background-color: var(--background-color);
}
>h4 {
z-index: 200;
margin: unset;
display: flex;
font-family: "Bahnschrift";
font-size: 1.4rem;
font-weight: 400;
color: #000;
}
}
>div.body {
--service-body-padding: 1rem;
/* --shadow: 0px 0.8em 40px 1.7em rgba(0, 0, 0, 0.4); */
z-index: 100;
position: relative;
flex-grow: 1;
width: 100%;
height: 100%;
box-sizing: border-box;
padding: var(--service-body-padding, 1rem);
display: flex;
flex-direction: column;
gap: 1em;
overflow: hidden;
border-radius: 0.75rem;
background-color: #130d0d;
/* box-shadow: var(--shadow);
-webkit-box-shadow: var(--shadow);
-moz-box-shadow: var(--shadow); */
>div.icon {
--diameter: 60px;
z-index: 500;
position: absolute;
justify-content: center;
align-items: center;
left: calc(var(--diameter) / -2.5);
margin-top: calc(var(--diameter) / -2.5);
width: var(--diameter);
height: var(--diameter);
display: flex;
border-radius: 100%;
background-color: var(--background-color);
&:before {
--border-size: 6px;
content: '';
margin: auto;
width: calc(100% - var(--border-size) * 2);
height: calc(100% - var(--border-size) * 2);
display: block;
border-radius: 100%;
background-color: var(--icon-background-color, #fff);
}
>i.icon {
position: absolute;
color: #fff;
* {
color: #fff;
}
}
}
>p {
margin: unset;
font-family: "Bahnschrift";
font-size: 0.8rem;
font-weight: 200;
&:is(.description) {
margin: unset;
flex-grow: 1;
font-size: 1rem;
color: #fff;
}
&:is(.howto) {
font-style: italic;
color: #dacfcf;
}
}
>div.extra {
--service-extra-gap: 1em;
--service-extra-animation-duration: 60s;
position: relative;
margin: 0 calc(var(--service-body-padding, 1rem) * -1);
height: 1em;
display: inline-flex;
font-family: 'Cascadia Code';
font-size: 0.7rem;
color: #8b8b8bcf;
>p {
position: absolute;
margin: unset;
min-width: var(--service-width);
width: max-content;
padding-left: var(--service-extra-gap, 1em);
word-break: keep-all;
display: inline-flex;
gap: var(--service-extra-gap, 1em);
animation-name: hotline;
animation-duration: var(--service-extra-animation-duration, 10s);
animation-iteration-count: infinite;
animation-timing-function: linear;
&:first-of-type {}
&:last-of-type {
animation-delay: calc(var(--service-extra-animation-duration, 10s) / -2);
}
}
}
>div.footer {
--service-footer-height: 60px;
width: 100%;
min-height: var(--service-footer-height, 70px);
height: fit-content;
display: flex;
gap: 1rem;
>div.buttons {
--footer-buttons-gap: 0.4rem;
min-width: var(--service-footer-height, 70px);
width: var(--service-footer-height, 70px);
box-sizing: border-box;
display: flex;
justify-content: center;
flex-flow: row wrap;
gap: var(--footer-buttons-gap, 0.4rem);
>a[type="button"] {
flex-grow: 1;
width: calc(50% - var(--footer-buttons-gap, 0.4rem) / 2);
height: calc(50% - var(--footer-buttons-gap, 0.4rem) / 2);
box-sizing: border-box;
padding: 0.4rem 0.4rem;
display: flex;
justify-content: center;
align-items: center;
border-radius: 0.75rem;
border: 1px solid #a0a0a096;
border-right: unset;
border-bottom: unset;
color: #fff;
background-color: #8b8b8b66;
backdrop-filter: blur(1px);
transition: filter 0.05s ease-in;
&:is(:only-of-type) {
height: 100%;
}
&:hover {
filter: brightness(1.3);
transition: filter 0s;
}
&:active {
filter: brightness(1) contrast(1.2);
transition: filter 0s;
}
>i.icon.comment {
margin-top: -0.3em;
}
}
}
>div.theses {
position: relative;
width: 100%;
box-sizing: border-box;
padding: 0.2em 0;
display: flex;
flex-direction: column;
justify-content: center;
gap: 0.2em;
font-family: 'Bahnschrift';
font-size: 0.9rem;
font-weight: 100;
>p {
margin: unset;
min-height: 0.9rem;
display: inline-flex;
gap: 0.4rem;
color: #cbcbcb;
&:is(.blue) {
&:is(.colored) {
color: #979aff;
}
>span.characteristic {
color: #6c7fff;
}
}
&:is(.green) {
&:is(.colored) {
color: #99ff90;
}
>span.characteristic {
color: #4bff3d;
}
}
&:is(.yellow) {
&:is(.colored) {
color: #fffa7f;
}
>span.characteristic {
color: #e0ff35;
}
}
&:is(.cyan) {
&:is(.colored) {
color: #caf4ff;
}
>span.characteristic {
color: #04efff;
}
}
&:is(.red) {
&:is(.colored) {
color: #ff6767;
}
>span.characteristic {
color: #ff4747;
}
}
>span.characteristic {
--characteristic-width: 2.5em;
position: relative;
width: var(--characteristic-width);
min-width: var(--characteristic-width);
display: flex;
justify-content: end;
text-align: right;
font-weight: 200;
>i {
margin: 0 auto;
align-self: center;
&:is(.infinity) {
margin-top: -0.2em;
}
&:is(.play.forwards) {
margin-top: -0.2em;
margin-left: calc(60% + 0.2em);
}
}
}
}
}
}
>img.background {
z-index: -100;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
scale: 1.1;
/* filter: blur(1.2px) brightness(0.25); */
filter: blur(1px) brightness(0.18) contrast(1.05);
&:is(.telegram.voronka) {
object-position: center;
}
}
}
>p.cost {
margin: unset;
margin-top: 0.2rem;
margin-right: 0.8rem;
width: 100%;
text-align: right;
font-family: 'Nunito';
font-size: 2rem;
font-weight: 600;
color: #000;
}
}
}
}
@keyframes hotline {
from {
/* transform: translateX(var(--service-width, 100%)); */
transform: translateX(100%);
}
to {
transform: translateX(-100%);
}
}

View File

@@ -1,90 +0,0 @@
@charset "UTF-8";
section#projects {
z-index: 1000;
padding-top: 2.5rem;
padding-bottom: 1rem;
/* transform: rotate3d(220, -777, -100, 385deg) scale(1.1); */
> h2.title {
font-size: 2.4rem;
font-family: "Bahnschrift";
margin: 0.1em 0 0.2em 0;
}
div.hotline {
width: 100vw;
height: 250px;
display: inline-flex;
gap: 15px;
cursor: grab;
&:active {
cursor: grabbing;
}
> :is(article, div) {
position: relative;
min-width: 220px;
max-width: 220px;
width: 220px;
height: 100%;
overflow: hidden;
border-radius: 0.75rem;
filter: contrast(1) brightness(1) saturate(1);
transition: filter 0.2s ease-out;
&:is(:hover, :focus) {
filter: contrast(1.2) brightness(0.8) saturate(0.6);
transition: filter 0s;
}
&:active {
filter: contrast(1.4) brightness(0.7) saturate(0.2);
transition: filter 0s;
}
&:is(.pechatalka) {
> img.background {
filter: blur(1.5px) brightness(0.8);
}
}
&:is(.understyle) {
> img.background {
object-position: bottom;
filter: blur(1px) brightness(0.8);
}
}
&:is(.surikov) {
> img.background {
object-position: bottom;
filter: blur(0.4px) brightness(0.8);
}
}
h4 {
position: absolute;
z-index: 50;
justify-self: center;
bottom: 0.4rem;
margin: unset;
padding: 0.4rem 1rem 0.3rem;
font-family: "Bahnschrift";
font-size: 1.2rem;
font-weight: 900;
color: #fff;
text-shadow: 2px 2px 3px #000;
}
img.background {
position: absolute;
top: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
}

View File

@@ -1,41 +0,0 @@
@charset "UTF-8";
section#shortcut {
> div {
width: var(--width);
display: flex;
flex-direction: row;
gap: 1rem;
> div.column {
display: flex;
flex-direction: column;
&:is(.statistics) {
width: 300px;
> p {
margin: unset;
margin-top: 0.8rem;
display: flex;
gap: 0.4rem;
font-family: "Cascadia Code";
font-weight: 600;
&:is(:first-of-type) {
margin-top: unset;
}
> span {
font-weight: 400;
}
+ small {
font-family: "Bahnschrift";
font-weight: 100;
}
}
}
}
}
}

View File

@@ -1,10 +0,0 @@
@import url('/css/fonts/fira.css');
@import url('/css/fonts/hack.css');
@import url('/css/fonts/dejavu.css');
@import url('/css/fonts/bahnschrift.css');
@font-face {
font-family: 'Commissioner';
src: url('/fonts/commissioner.ttf');
font-weight: 400;
}

View File

@@ -1,28 +0,0 @@
@charset "UTF-8";
footer {
z-index: 4000;
position: relative;
height: var(--footer-height, 200px);
padding: 1rem 10vw;
display: flex;
align-items: self-end;
color: #fff;
background-color: #000;
--shadow: 0px 0px 80px 25px rgba(0, 0, 0, 0.4);
box-shadow: var(--shadow);
-webkit-box-shadow: var(--shadow);
-moz-box-shadow: var(--shadow);
> div.column {
height: 100%;
display: flex;
flex-direction: column;
justify-content: end;
gap: 1rem;
&:is(:last-of-type:last-child) {
margin-left: auto;
}
}
}

View File

@@ -1,25 +0,0 @@
@charset "UTF-8";
@import url("https://fonts.googleapis.com/css2?family=Commissioner:wght@100;200;300;400;500;600;700;800;900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Cascadia+Code:ital,wght@0,200..700;1,200..700&family=Rubik:ital,wght@0,300..900;1,300..900&family=Wix+Madefor+Display:wght@400..800&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Geologica:wght@100..900&family=Pochaevsk&display=swap");
@import url('https://fonts.googleapis.com/css2?family=Alumni+Sans+Pinstripe:ital@0;1&family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap');
main {
--scroll-px-ten: calc(var(--scroll-px) / 10);
--scroll-px-hundred: calc(var(--scroll-px-ten) / 10);
--scroll-px-thousand: calc(var(--scroll-px-hundred) / 10);
margin-top: var(--menu-height);
display: flex;
flex-direction: column;
flex-grow: 1;
align-items: center;
transition: 0s;
overflow-x: hidden;
&:not(:has(*)) {
display: none;
}
}

View File

@@ -1,165 +0,0 @@
@charset "UTF-8";
main {
>section.row {
z-index: 500;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #fff;
>h2#title {
font-size: 2.4rem;
font-family: "Bahnschrift";
margin: 0.1em 0 0.2em 0;
>span {
color: #0ea5e9;
}
}
>p#description {
margin: unset;
text-align: center;
font-size: 1.2rem;
font-family: "Geologica";
font-weight: 400;
color: rgb(0, 0, 0, 0.6);
>span {
color: #0ea5e9;
font-weight: 800;
}
}
>p.description {
width: 40%;
}
>a#order {
padding: 0.5em 1.3em;
margin-top: 1rem;
display: flex;
align-items: center;
gap: 5px;
border-radius: 1.125em;
font-size: 1em;
font-family: "Geologica";
font-weight: 400;
text-decoration: none;
background-color: #0ea5e9;
color: #fff;
transition: 0.2s;
&:hover {
transform: scale(1.05);
}
}
>div#team {
margin-top: 1rem;
display: inline-flex;
justify-content: center;
align-items: center;
gap: 1rem;
>div#card {
padding: 0.6em 0.8em;
width: 180px;
height: 220px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
border-radius: 1.125rem;
box-shadow: 0px 0px 15px 0px rgba(14, 165, 233, 0.1);
background-color: #fff;
transition: ease 0.2s;
>img {
object-fit: cover;
width: 140px;
height: 140px;
border-radius: 100%;
}
>p {
margin: 1em 0 0;
font-size: 1.2em;
font-family: "Geologica";
font-weight: 900;
color: #000000;
}
>span {
font-size: 1em;
font-family: "Geologica";
font-weight: 400;
color: #0ea5e9;
}
}
}
>a#telegram {
padding: 0.5em 1.3em;
margin-top: 1rem;
display: flex;
align-items: center;
gap: 5px;
border-radius: 1.125em;
font-size: 1em;
font-family: "Geologica";
font-weight: 400;
text-decoration: none;
background-color: #0ea5e9;
color: #fff;
transition: 0.2s;
&:hover {
transform: scale(1.05);
}
>img {
width: 20px;
height: 20px;
}
}
}
>section.wrap {
position: relative;
overflow: hidden;
background-color: #fff;
>section.row {
z-index: 500;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: unset;
}
>div.net {
--dot-bg: #5a645a;
--dot-color: transparent;
--dot-color: transparent;
--dot-size: calc(110px + var(--scroll-px-hundred, 0px) * 2);
--dot-space: calc(var(--dot-size) + 1px);
z-index: -50;
position: absolute;
top: -30%;
width: 200%;
height: 200%;
background: linear-gradient(90deg, var(--dot-bg) calc(var(--dot-space) - var(--dot-size)), transparent 1%) center / var(--dot-space) var(--dot-space), linear-gradient(var(--dot-bg) calc(var(--dot-space) - var(--dot-size)), transparent 1%) center / var(--dot-space) var(--dot-space), var(--dot-color);
mask-image: linear-gradient(transparent, #fff, transparent);
transform: perspective(135px) rotateX(calc(6deg + var(--scroll-deg, 0deg) * -0.4)) skewY(6deg) rotateZ(-18deg);
transition: transform 0.08s linear, background 0.08s linear;
}
}
}
}

View File

@@ -1,47 +0,0 @@
@charset "UTF-8";
:root {
--width: max(1050px, 55vw);
--menu-height: 70px;
--introdution-height: min(350px, 35vh);
--gap: min(12px, 1rem);
--fixed-right: 3rem;
--fixed-bottom: 2rem;
--fixed-left: 3rem;
--telegram-diameter: 50px;
--cookies-z-index: 6000;
--cookies-right: var(--fixed-right);
--cookies-bottom: var(--fixed-bottom);
--cookies-width: 24rem;
--cookies-height: 4rem;
font-family: "Commissioner";
font-family: "Share Tech Mono";
font-family: "Montserrat";
font-family: "Alumni Sans Pinstripe";
font-family: "DejaVu";
font-family: "Fira";
font-family: "Hack";
font-family: "Nunito", "DejaVu", sans-serif;
text-decoration: none;
outline: none;
border: none;
transition: 0.1s ease-out;
}
body {
margin: unset;
width: 100vw;
overflow-x: hidden;
background-color: #f7fafc;
}
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1000px" height="1000px" viewBox="0 0 1000 1000" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 53.2 (72643) - https://sketchapp.com -->
<title>Artboard</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="99.2583404%" id="linearGradient-1">
<stop stop-color="#2AABEE" offset="0%"></stop>
<stop stop-color="#229ED9" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Artboard" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle id="Oval" fill="url(#linearGradient-1)" cx="500" cy="500" r="500"></circle>
<path d="M226.328419,494.722069 C372.088573,431.216685 469.284839,389.350049 517.917216,369.122161 C656.772535,311.36743 685.625481,301.334815 704.431427,301.003532 C708.567621,300.93067 717.815839,301.955743 723.806446,306.816707 C728.864797,310.92121 730.256552,316.46581 730.922551,320.357329 C731.588551,324.248848 732.417879,333.113828 731.758626,340.040666 C724.234007,419.102486 691.675104,610.964674 675.110982,699.515267 C668.10208,736.984342 654.301336,749.547532 640.940618,750.777006 C611.904684,753.448938 589.856115,731.588035 561.733393,713.153237 C517.726886,684.306416 492.866009,666.349181 450.150074,638.200013 C400.78442,605.66878 432.786119,587.789048 460.919462,558.568563 C468.282091,550.921423 596.21508,434.556479 598.691227,424.000355 C599.00091,422.680135 599.288312,417.758981 596.36474,415.160431 C593.441168,412.561881 589.126229,413.450484 586.012448,414.157198 C581.598758,415.158943 511.297793,461.625274 375.109553,553.556189 C355.154858,567.258623 337.080515,573.934908 320.886524,573.585046 C303.033948,573.199351 268.692754,563.490928 243.163606,555.192408 C211.851067,545.013936 186.964484,539.632504 189.131547,522.346309 C190.260287,513.342589 202.659244,504.134509 226.328419,494.722069 Z" id="Path-3" fill="#FFFFFF"></path>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,4 +0,0 @@
<?php
// Initializing default theme for the views templater
define('THEME', 'default');

View File

@@ -1,30 +0,0 @@
<!DOCTYPE html>
<html lang="ru">
<head>
{% use '/themes/default/head.html' with title as head_title, meta as head_meta, css as head_css %}
{% block title %}
{{ block('head_title') }}
{% endblock %}
{% block meta %}
{{ block('head_meta') }}
{% endblock %}
{{ block('head_css') }}
{% block css %}
{% endblock %}
</head>
<body>
{% block body %}
{% endblock %}
{% include '/themes/default/js.html' %}
{% block js %}
{% endblock %}
</body>
</html>

View File

@@ -1,11 +0,0 @@
<style>
:root {
--company-identifier: "{{ language.name == 'ru' or true ? 'ОГРН' : 'ID' }}";
--company-tax: "{{ language.name == 'ru' or true ? 'ИНН' : 'TAX' }}";
}
</style>
<section id="company">
<h4 class="name">ИП Мирзаев</h4>
<p class="column"><span class="tax row">271103176488</span><span class="identifier row">322270000004691</span></p>
</section>

View File

@@ -1,7 +0,0 @@
<section id="cookies" class="unselectable">
<div>
<p>ИСПОЛЬЗУЕТСЯ ТЕХНОЛОГИЯ COOKIES</p>
<small>№152-ФЗ «О персональных данных»</small>
</div>
<button onclick="setTimeout(() => this.parentElement.remove(), 200); this.parentElement.style.opacity = 0"><i class="icon close small"></i></button>
</section>

View File

@@ -1,7 +0,0 @@
<nav id="links" class="unselectable">
<a href="/offer">ПУБЛИЧНАЯ ОФЕРТА</a>
<a href="https://ru.wikipedia.org/wiki/WTFPL">ЛИЦЕНЗИЯ</a>
<a href="https://t.me/kodorvan">КОДОРВАНЬ</a>
<a href="https://t.me/blog_mirzaev_sexy">МИРЗАЕВ</a>
<a href="https://git.svoboda.works/kodorvan">РЕПОЗИТОРИЙ</a>
</nav>

View File

@@ -1,13 +0,0 @@
<style>
:root {
--map-loading: "Загрузка карты";
}
</style>
<section id="office">
<div class="map">
<div class="loading">
<i class="icon loading spinner animated"></i>
</div>
</div>
</section>

View File

@@ -1,21 +0,0 @@
{% block css %}
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/company.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/links.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/office.css" />
{% endblock %}
{% block body %}
<footer>
<div class="column">
{% include '/themes/default/elements/office.html' %}
{% include '/themes/default/elements/links.html' %}
</div>
<div class="column">
{% include '/themes/default/elements/company.html' %}
</div>
</footer>
{% endblock %}
{% block js %}
{% endblock %}

View File

@@ -1,26 +0,0 @@
{% block title %}
<title>{% if head.title != empty %}{{ head.title }}{% else %}perm by kodorvan{% endif %}</title>
{% endblock %}
{% block meta %}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% for meta in head.metas %}
<meta {% for name, value in meta.attributes %}{{ name }}="{{ value }}" {% endfor %}>
{% endfor %}
{% endblock %}
{% block css %}
{% for element in css %}
<link type="text/css" rel="stylesheet" {% if element.href %} href="{{ element.href }}" {% endif %} />
{% endfor %}
<link type="text/css" rel="stylesheet" href="/themes/default/css/fonts.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/system.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/header.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/main.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/aside.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/footer.css" />
<style id="theme">
@import url('/themes/default/css/themes/default/colorscheme.css');
</style>
{% endblock %}

View File

@@ -1,14 +0,0 @@
{% block css %} {% endblock %} {% block body %}
<header>
<div>
<a href="https://perm.kodorvan.tech" id="logotype" class="unselectable">
<h4>КОДОРВАНЬ</h4>
<small>реальных программистов</small>
</a>
<nav id="menu" class="unselectable">
<a href="#">лёха не забудь сюда кнопки добавить</a>
</nav>
</div>
</header>
{% endblock %} {% block js %} {% endblock %}

View File

@@ -1,9 +0,0 @@
{% block js %}
{% for element in js %}
<script
{% if element.src %}src="{{ element.src }}" {% endif %}
{% if element.type %}type="{{ element.type }}" {% endif %}>
{{ element.innerText }}
</script>
{% endfor %}
{% endblock %}

View File

@@ -1,62 +0,0 @@
<section class="advantages">
<h2 class="title unselectable">Преимущества</h2>
<div class="accordion">
<div class="accordion-item">
<button id="accordion-button-1" aria-expanded="false">
<span class="title ">Техническое задание</span>
<span class="icon" aria-hidden="true"></span>
</button>
<div class="accordion-content">
<p>Четкое описание всех требований и функционала проекта.</p>
</div>
</div>
<div class="accordion-item">
<button id="accordion-button-2" aria-expanded="false">
<span class="title">Хостинг на нашем сервере</span>
<span class="icon" aria-hidden="true"></span>
</button>
<div class="accordion-content">
<p>Проект может быть размещен на нашем сервере или перенесен на другой по желанию клиента.</p>
</div>
</div>
<div class="accordion-item">
<button id="accordion-button-3" aria-expanded="false">
<span class="title">Безопасность и приватность</span>
<span class="icon" aria-hidden="true"></span>
</button>
<div class="accordion-content">
<p>Код зашифрован, проект полностью приватный и защищен от несанкционированного доступа.</p>
</div>
</div>
<div class="accordion-item">
<button id="accordion-button-4" aria-expanded="false">
<span class="title">Бесплатная поддержка</span>
<span class="icon" aria-hidden="true"></span>
</button>
<div class="accordion-content">
<p>Помощь и консультация после запуска проекта.</p>
</div>
</div>
<div class="accordion-item">
<button id="accordion-button-5" aria-expanded="false">
<span class="title">Персонализированный подход</span>
<span class="icon" aria-hidden="true"></span>
</button>
<div class="accordion-content">
<p>Учет уникальных потребностей и пожеланий клиента.</p>
</div>
</div>
</div>
</section>

View File

@@ -1,24 +0,0 @@
<section id="comand" class="container">
<h2 id="title" class="unselectable">Разработчики</h2>
<p id="description" class="unselectable">
Более <span>12 лет</span> разработки в различных IT сферах
</p>
<div id="team">
<div id="card">
<img src="themes/test/images/avatar/123.jpg" alt="Арсен" />
<p class="unselectable">Арсен</p>
<span class="unselectable">Программист</span>
</div>
<div id="card">
<img src="themes/test/images/avatar/123.jpg" alt="Ксения" />
<p class="unselectable">Ксения</p>
<span class="unselectable">Coder</span>
</div>
<div id="card">
<img src="themes/test/images/avatar/123.jpg" alt="Альгиз" />
<p class="unselectable">Альгиз</p>
<span class="unselectable">Нроcетка и крипта</span>
</div>
</div>
</section>

View File

@@ -1,17 +0,0 @@
<section id="contacts" class="row unselectable">
<h2 id="title">Связатьcя с нами</h2>
<p id="description">Готовы обсудить ваш проект? Напишите нам!</p>
<a id="telegram" class="unselectable" href="https://t.me/kodorvan?direct">
<img src="themes/default/images/icons/telegram.svg" alt="">
<span>Telegram</span>
</a>
</section>
<!-- Готовы обсудить проект
заменить на
что-то связанное с конструктором заказа
написать о том что будет посчитана цена, составлено ТЗ, сроки
влепить что есть рассрочка, оплата по СБП, работа с юр лицами
поэтапная оплата и возможность индивидуального чего-нибудь -->

View File

@@ -1,30 +0,0 @@
<section id="description" class="row">
<p class="unselectable"><strong>Создание сайта</strong>, <strong>разработка чат-бота телеграм</strong>, <strong>написание парсера</strong>, <strong>подключение воронки</strong>, а так же разработка любой сложности калькулятора, интернет-магазина (маркетплейса) и полноценной CRM с нуля <strong>в Перми</strong></p>
<ul class="table unselectable">
<li>
<span class="bad"><i class="icon close small"></i>Не копируем проекты по шаблонам</span>
<span class="good"><i class="icon check small"></i><strong>Пишем код с нуля</strong> с использованием наших <strong>уникальных технологий</strong>, которые позволяют сокращать сроки разработки и преумножить качество проекта</span>
</li>
<li>
<span class="bad"><i class="icon close small"></i>Не перепродаём проекты другим заказчикам</span>
<span class="good"><i class="icon check small"></i><strong>Репозиторий и код проекта полностью передаются заказчику</strong> под нашу публичную репутацию, либо под патент или договор о неразглашении (NDA)</span>
</li>
<li>
<span class="bad"><i class="icon close small"></i>Не навязываем дополнительные услуги</span>
<span class="good"><i class="icon check small"></i><strong>Бесплатный сервер</strong> на время разработки, <strong>бесплатная установка на сервер заказчика</strong> и <strong>бесплатная техподдержка</strong></span>
</li>
<li>
<span class="bad"><i class="icon close small"></i>Не создаём зависимость от нашей команды</span>
<span class="good"><i class="icon check small"></i>Документируем код, пишем инструкции и разрабатываем систему вики-страниц на английском языке для <strong>длительной поддержки проекта</strong></span>
</li>
<li>
<span class="bad"><i class="icon close small"></i>Не вводим в заблуждение сложной терминологией</span>
<span class="good"><i class="icon check small"></i>Процесс работы можно наблюдать в реальном времени на нашем сайте, чтобы убедиться, что <strong>мы честно отрабатываем поставленную задачу</strong></span>
</li>
</ul>
<!-- <strong class="partners unselectable">Мы мотивированы сотрудничать на <span>постоянной основе</span>, поэтому <span>работаем на результат</span></strong> -->
</section>
<!-- , либо реально выгодная аренда сервера у нас по самой низкой цене на рынке и максимально эффективной техподдержкой с бесплатными бекапами и оперативной установкой критических обновлений безопасности -->

View File

@@ -1,27 +0,0 @@
<section id="introdution" class="row">
<div class="information">
<span id="label">
<i class="icon code slash"></i>
<span class="unselectable">ПРОФЕССИОНАЛЫ</span>
</span>
<h2 id="title" class="unselectable">КОМАНДА <span class="kodorvan">КОДОРВАНЬ</span></h2>
<p id="team" class="unselectable"><b>Чистый код</b>, авангардный дизайн, глубокий SEO,</br> безопасность, реальные сроки и свои сервера в <strong>Перми</strong></br>по <b>честной цене</b> и с <b>вечной техподдержкой</b></p>
</div>
<div class="background" style="opacity: 0">
<div class="dots"></div>
<canvas id="introdution_animation"></canvas>
<svg style="position: absolute">
<defs>
<filter id="blob">
<feGaussianBlur in="SourceGraphic" stdDeviation="12" result="blur"></feGaussianBlur>
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="blob"></feColorMatrix>
</filter>
</defs>
</svg>
</div>
</section>

View File

@@ -1,167 +0,0 @@
{% macro service(class, title, icon_left, icon_center, icon_right, description, howto, extra, buttons, theses, background_image_src, background_image_alt, cost) %}
<article class="service{% if class is not empty %} {{ class }}{% endif %}">
{% if icon_left is not empty %}<i class="icon left {{ icon_left }}"></i>{% endif %}
{% if icon_center is not empty %}
<link type="text/css" rel="stylesheet" href="/css/icons/{{ icon_center|replace({' ': '_'}) }}.css" />
<i class="icon center {{ icon_center }}"></i>
{% endif %}
{% if icon_right is not empty %}<i class="icon right {{ icon_right }}"></i>{% endif %}
{% if icon_center2222 is not empty %}
<link type="text/css" rel="stylesheet" href="/css/icons/{{ icon_center|replace({' ': '_'}) }}.css" />
<div class="icon">
<i class="icon center {{ icon_center }}"></i>
</div>
{% endif %}
<div class="head">
<h4>{{ title is empty ? 'Разработка' : title }}</h4>
</div>
<div class="body">
{% if description is not empty %}
<p class="description">{{ description|raw }}</p>
{% endif %}
{% if howto is not empty %}
<p class="howto">{{ howto|raw }}</p>
{% endif %}
{% if extra is not empty %}
<div class="extra">
<p>
{% for text in extra %}
<span>{{ text }}</span>
{% endfor %}
</p>
<p>
{% for text in extra %}
<span>{{ text }}</span>
{% endfor %}
</p>
</div>
{% endif %}
<div class="footer">
{% if theses is not empty %}
<div class="buttons">
{% for button in buttons %}
{% set icon = button.icon ?? 'close' %}
<link type="text/css" rel="stylesheet" href="/css/icons/{{ button.icon|replace({' ': '_'}) }}.css" />
<a type="button" href="{{ button.href }}"><i class="icon {{ button.icon }}"></i></a>
{% endfor %}
</div>
{% endif %}
{% if theses is not empty %}
<div class="theses">
{% for thesis in theses %}
<p{% if thesis.class is not empty %} class="{{ thesis.class }}{% if thesis.colored is true %} colored{% endif %}"{% endif %}>
{% if thesis.icon is not empty %}
<span class="characteristic">
<link type="text/css" rel="stylesheet" href="/css/icons/{{ thesis.icon|replace({' ': '_'}) }}.css" />
<i class="icon {{ thesis.icon }}"></i>
</span>
{% elseif thesis.characteristic is not empty %}
<span class="characteristic">{{ thesis.characteristic }}</span>
{% endif %}
{{ thesis.text }}
</p>
{% endfor %}
</div>
{% endif %}
</div>
{% if background_image_src is not empty and background_image_alt is not empty %}
<img class="background" src="{{ background_image_src }}" alt="{{ background_image_alt }}" ondragstart="return false;"/>
{% endif %}
</div>
{% if cost is not empty %}
<p class="cost">ОТ <span>{{ cost }}₽</span></p>
{% endif %}
</article>
{% endmacro service %}
<section id="popular" class="row unselectable">
<div class="title unselectable">
<div class="column">
<h3>Популярные заказы</h3>
<span>Готовые оптимизированные пакеты услуг со скидками</span>
</div>
<div class="column display">
<button class="plus">
<i class="icon plus"></i>
</button>
<span class="amount">3</span>
<button class="minus">
<i class="icon minus"></i>
</button>
</div>
</div>
<div class="services">
{% for service in services %}
{{
_self.service(
class: service.class,
title: service.title,
icon_left: service.icon_left,
icon_center: service.icon_center,
icon_right: service.icon_right,
description: service.description,
howto: service.howto,
extra: service.extra,
buttons: service.buttons,
theses: service.theses,
background_image_src: service.background_image_src,
background_image_alt: service.background_image_alt,
cost: service.cost
)
}}
{% endfor %}
</div>
<script>
let popular = document.getElementById("popular");
let services = popular?.querySelector('div[class="services"]');
let amount = popular.querySelector(
'div.title>div[class="column display"]>span[class="amount"]'
);
if (services instanceof HTMLElement) {
let plus = popular.querySelector(
'div.title>div[class="column display"]>button[class="plus"]'
);
plus.addEventListener("click", (event) => {
let old =
+getComputedStyle(services).getPropertyValue("--row-amount") || 1;
let value = old + 1;
if (value > 4) value = 4;
else if (value < 1) value = 1;
services.style.setProperty("--row-amount", value);
amount.innerText = value;
});
let minus = popular.querySelector(
'div.title>div[class="column display"]>button[class="minus"]'
);
minus.addEventListener("click", (event) => {
let old =
+getComputedStyle(services).getPropertyValue("--row-amount") || 1;
let value = old - 1;
if (value > 4) value = 4;
else if (value < 1) value = 1;
services.style.setProperty("--row-amount", value);
amount.innerText = value;
});
}
</script>
</section>

View File

@@ -1,11 +0,0 @@
<section id="products" class="row">
<div class="title">
<h3>Готовые проекты</h3>
<p>Готовые решения для переработки под свою идею</p>
</div>
<article class="product">
<div class="image">
</div>
</article>
</section>

View File

@@ -1,48 +0,0 @@
<section id="projects" class="row unselectable">
<div id="wrap" class="hotline unselectable">
<article class="pechatalka">
<h4>ПЕЧАТАЛКА</h4>
<img class="background" src="/themes/default/images/projects/pechatalka.gif" alt="pechatalka" ondragstart="return false;"/>
</article>
<article class="understyle">
<h4>under.style</h4>
<img class="background" src="/themes/default/images/projects/understyle.png" alt="under.style" ondragstart="return false;"/>
</article>
<article class="surikov">
<h4>Музей-библиотека имени Сурикова</h4>
<img class="background" src="/themes/default/images/projects/surikov.png" alt="surikov" ondragstart="return false;"/>
</article>
<article class="pechatalka">
<h4>ПЕЧАТАЛКА</h4>
<img class="background" src="/themes/default/images/projects/pechatalka.gif" alt="pechatalka" ondragstart="return false;"/>
</article>
<article class="understyle">
<h4>under.style</h4>
<img class="background" src="/themes/default/images/projects/understyle.png" alt="under.style" ondragstart="return false;"/>
</article>
<article class="surikov">
<h4>Музей-библиотека имени Сурикова</h4>
<img class="background" src="/themes/default/images/projects/surikov.png" alt="surikov" ondragstart="return false;"/>
</article>
<article class="pechatalka">
<h4>ПЕЧАТАЛКА</h4>
<img class="background" src="/themes/default/images/projects/pechatalka.gif" alt="pechatalka" ondragstart="return false;"/>
</article>
<article class="understyle">
<h4>under.style</h4>
<img class="background" src="/themes/default/images/projects/understyle.png" alt="under.style" ondragstart="return false;"/>
</article>
<article class="surikov">
<h4>Музей-библиотека имени Сурикова</h4>
<img class="background" src="/themes/default/images/projects/surikov.png" alt="surikov" ondragstart="return false;"/>
</article>
</div>
</section>

View File

@@ -1,35 +0,0 @@
<section id="services" class="container ">
<h2 id="title">Предоставляемые услуги</h2>
<div id="service">
<div id="card">
<div class="text">
<p class="title">Телеграм-боты под ключ</p>
<span class="discription">Создаем Telegram-ботов для продаж, поддержки клиентов и автоматизации
бизнес-процессов. Рассматриваем разработку мини-приложений в Telegram: магазин, сервисы, игры и полноценные
платформы</span>
</div>
<a href="https://t.me/kodorvan?direct">Запустить бота за 7 дней</a>
</div>
<div id="card">
<div class="text">
<p class="title">Разработка сайта</p>
<span class="discription">Разработаем сайт любой сложности — от одностраничных лендингов до многофункциональных интернет-магазинов и представительных корпоративных сайтов. Каждый
проект будет современным и адаптивным</span>
</div>
<a href="https://t.me/kodorvan?direct">Заказать сайт</a>
</div>
<div id="card">
<div class="text">
<p class="title"> API-интеграции под ключ</p>
<span class="discription">Настраиваем надежное и безопасное взаимодействие вашего сайта или бота с любыми внешними сервисами. Интеграция с платежными системами, CRM, Telegram, базами данных и другими системами, чтобы автоматизировать бизнес-процессы.</span>
</div>
<a href="https://t.me/kodorvan?direct">Подключить</a>
</div>
</div>
</section>

View File

@@ -1,11 +0,0 @@
<section id="shortcut" class="row">
<div class="row">
<div class="statistics column">
<p>Репозитории:<span>{{ projects ?? 98 }}</span></p>
<small class="unselectable">Наши разработки + проекты заказчиков</small>
<p>Просмотры:<span>{{ month ?? '304 258' }}</span></p>
<small class="unselectable">За последние 30 дней</small>
</div>
</div>
</section>

View File

@@ -1,3 +0,0 @@
<section id="workload" class="row">
<p><i class="icon coffe"></i>Загруженность команды: <span class="{{ workload < 51 ? 'small' : (workload < 71 ? 'medium' : 'heavy')}}">{{ workload }}%<small class="unselectable">Обновлено 5 минут назад</small></span></p>
</section>

View File

@@ -1,60 +0,0 @@
{% extends "/themes/default/index.html" %}
{% block css %}
{{ parent() }}
<link type="text/css" rel="stylesheet" href="/css/icons/code_slash.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/coffe.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/telegram.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/close.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/check.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/eye.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/loading_spinner.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/close.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/plus.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/minus.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/server.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/trend.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/terminal.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/list_tree.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/gift.css" />
<link type="text/css" rel="stylesheet" href="/css/icons/phone.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/pages/index.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/introdution.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/workload.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/shortcut.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/popular.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/projects.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/server.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/description.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/telegram.css" />
<link type="text/css" rel="stylesheet" href="/themes/default/css/elements/cookies.css" />
{% endblock %}
{% block main %}
{% include '/themes/default/main/elements/introdution.html' %}
<section class="wrap row">
<div class="net"></div>
{% include '/themes/default/main/elements/workload.html' %}
{% include '/themes/default/main/elements/shortcut.html' %}
{% include '/themes/default/main/elements/popular.html' %}
{% include '/themes/default/main/elements/projects.html' %}
</section>
{% include '/themes/default/main/elements/server.html' %}
{% include '/themes/default/main/elements/description.html' %}
{% include '/themes/default/elements/telegram.html' %}
{% include '/themes/default/elements/cookies.html' %}
{% endblock %}
{% block js %}
{{ parent() }}
<script src="/js/modules/hotline.mjs" type="module"></script>
<script src="/js/modules/womb3-simplex.mjs" type="module"></script>
<script src="/js/pages/main.js" defer></script>
<script src="/js/modules/service.js" defer></script>
<script src="/js/modules/advantages.js" defer></script>
{% endblock %}

View File

@@ -0,0 +1,197 @@
<?php
declare(strict_types=1);
namespace kodorvan\site\controllers;
// Files of the project
use kodorvan\site\controllers\core,
kodorvan\site\models\superpack as model;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\method,
mirzaev\minimal\http\enumerations\status;
// Baza database
use mirzaev\baza\database,
mirzaev\baza\column,
mirzaev\baza\record,
mirzaev\baza\enumerations\encoding,
mirzaev\baza\enumerations\type;
/**
* Offer
*
* @package kodorvan\site\controllers
*
* @param array $errors Registry of errors
*
* @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 article extends core
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
* Page: superpack
*
* @return null
*/
public function index(string $urn): null
{
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Initializing the superpack
$superpack = new model()->read(filter: fn(record $record) => $record->urn === $urn && $record->active === 1);
if ($superpack instanceof model) {
// Initialized the superpack
// Render page
$page = $this->view->render(
'pages/article.html',
[
'uri' => 'https://' . DOMAIN . "/superpack/$urn",
'article' => [
'urn' => $superpack->urn,
'head' => [
'title' => $superpack->title
],
'body' => [
'html' => $superpack->html
]
],
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
} else {
// Not initialized the superpack
}
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
// Exit (fail)
return null;
}
/**
* Page: superpack
*
* @return null
*/
public function create(
?string $identifier = null,
?string $urn = null,
?string $title = null,
?string $html = null,
?string $text = null,
string|int|float|null $supercost = null
): null {
if ($this->request->method === method::get) {
// GET
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Render page
$page = $this->view->render(
'pages/system/superpack/create.html',
[
'uri' => 'https://' . DOMAIN . "/system/superpack/create",
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
} else if ($this->request->method === method::put) {
// PUT
// Initializing the superpack
$superpack = new model()->read(filter: fn(record $record) => $record->urn === $urn);
if ($superpack instanceof model) {
// The superpack is already created
} else {
// The superpack is not already created
// Sanitizing
$urn = preg_replace('/[^\w\d\-.]+/', '', $urn);
$title = preg_replace('/[^\w\d\s\-.,!]+/u', '', $title);
$supercost = (float) preg_replace('/[^\d.]+/', '', $supercost);
// Creating the superpack
$superpack = new model()->write(
urn: $urn,
title: $title,
html: $html,
text: $text,
supercost: $supercost
);
if ($superpack instanceof record) {
// Created the superpack
// Sending response
$this->response
->start()
->clean()
->sse()
->json([
'redirect' => "/superpack/$urn"
])
->validate($this->request)
?->body()
->end();
}
}
}
// Exit (fail)
return null;
}
}

View File

@@ -2,11 +2,11 @@
declare(strict_types=1); declare(strict_types=1);
namespace kodorvan\perm\controllers; namespace kodorvan\site\controllers;
// Files of the project // Files of the project
use kodorvan\perm\views\templater, use kodorvan\site\views\templater,
kodorvan\perm\models\core as models; kodorvan\site\models\core as models;
// Library for languages support // Library for languages support
use mirzaev\languages\language; use mirzaev\languages\language;
@@ -20,7 +20,7 @@ use mirzaev\minimal\core as minimal,
/** /**
* Controllers core * Controllers core
* *
* @package kodorvan\perm\controllers * @package kodorvan\site\controllers
* *
* @param language $language Language * @param language $language Language
* @param response $response Response * @param response $response Response

View File

@@ -0,0 +1,289 @@
<?php
declare(strict_types=1);
namespace kodorvan\site\controllers;
// Files of the project
use kodorvan\site\controllers\core;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
/**
* Index
*
* @package kodorvan\site\controllers
*
* @param array $errors Registry of errors
*
* @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
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
* Main page
*
* @return null
*/
public function index(): null
{
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Initializing the team workload
$this->view->workload = (string) ($_COOKIE['workload'] ?? rand(20, 80));
// Initializing superpacks
$this->view->superpacks = [
[
'class' => 'site direct',
'icon_center' => 'crown',
'image' => [
'src' => '/themes/' . THEME . '/images/site_example.jpg',
'alt' => 'Сайт для рекламы'
],
'title' => 'Лендинг',
'description' => 'Сайт для рекламной компании',
'features' => [
[
'icon' => 'template',
'text' => 'Авангардный дизайн'
],
[
'icon' => '',
'text' => 'Продумана каждая деталь'
],
[
'icon' => 'list-tree',
'text' => 'Глубокий SEO'
],
/* [
'icon' => 'document',
'text' => 'Юридическая броня'
], */
[
'icon' => 'bell',
'text' => 'Регистрация в Роскомнадзор'
]
],
'deal' => [
'cost' => '30 000',
'text' => 'ПОЛНАЯ СТОИМОСТЬ'
],
'button' => [
'class' => 'request',
'text' => 'ВЫБРАТЬ',
'label' => 'Кнопка для заказа'
]
],
[
'class' => 'voronka',
'icon_center' => 'crown',
'image' => [
'src' => '/themes/' . THEME . '/images/telegram_voronka.png',
'alt' => 'Воронка в Телеграм'
],
'title' => 'Воронка',
/* 'description' => '', */
'features' => [
[
'icon' => 'phone',
'text' => 'Сбор данных'
],
[
'icon' => 'copy',
'text' => 'Синхронизация с CRM'
],
[
'icon' => 'track',
'text' => 'Аналитика всех этапов'
],
/* [
'icon' => '',
'text' => 'Повышение конверсий'
], */
[
'icon' => 'style',
'text' => 'Иммерсивные техники'
],
[
'icon' => 'smile',
'text' => 'Никакой аренды'
]
],
'deal' => [
'cost' => '10 000',
'text' => 'ПОЛНАЯ СТОИМОСТЬ'
],
'button' => [
'class' => 'request',
'text' => 'ВЫБРАТЬ',
'label' => 'Кнопка для заказа'
]
],
[
'class' => 'ai assistent telegram',
'icon_center' => '',
'image' => [
'src' => '/themes/' . THEME . '/images/telegram_voronka.png',
'alt' => 'Воронка в Телеграм'
],
'title' => 'ИИ-ассистент',
'description' => 'Личный консультант',
'features' => [
[
'icon' => 'assign',
'text' => 'Самообучение',
],
[
'icon' => 'performance',
'text' => 'Индивидуальная настройка'
],
[
'icon' => 'extension',
'text' => 'Актуализация базы данных'
],
[
'icon' => '',
'text' => 'Передовая ИИ-модель'
],
[
'icon' => 'smile',
'text' => 'Никакой аренды'
]
],
'deal' => [
'cost' => '15 000',
'text' => 'ПОЛНАЯ СТОИМОСТЬ'
],
'button' => [
'class' => 'request',
'text' => 'ВЫБРАТЬ',
'label' => 'Кнопка для заказа'
]
],
[
'class' => 'marketplace',
'icon_center' => 'crown',
'image' => [
'src' => '/themes/' . THEME . '/images/site_example.jpg',
'alt' => 'Сайт для рекламы'
],
'title' => 'Маркетплейс',
'description' => 'Бюджет разработки >2млн',
'features' => [
[
'icon' => 'trophy',
'text' => 'Чистый код, без конструкторов'
],
[
'icon' => 'template',
'text' => 'Индивидуальный дизайн'
],
/* [
'icon' => 'import',
'text' => 'Годовая подписка на обновления'
], */
[
'icon' => 'extension',
'text' => 'Подключение к Мой Склад'
],
[
'icon' => 'performance',
'text' => 'Физический сервер с личным администратором'
]
],
'article' => <<<HTML
Изначально проект создавался как чат-робот Telegram с Web App, где по нажатию на кнопку пользователь попадал в мини-приложение, автоматически авторизовавшись через мессенджер.<br>
<br>
Там он видел весь каталог товаров с категориями, ценами, фильтрами и умным поиском. Всего за 2 минуты он проходил все этапы: наполнял корзину товарами, заполнял адрес доставки (в первый раз) и оплачивал через СБП! Сессия сохраняла данные между устройствами (смартфон и компьютер). Была проведена огромная аналитическая работа с фокус-группами и сбором статистики. Каждый элемент на экране размещён очень обоснованно.<br>
<br>
После оплаты приложение автоматически закрывается и пользователь возвращается в чат с роботом, где он видит список купленных товаров, статус заказа, оплаченный счёт, а так же подтверждение от оператора. Операторам в чат прилетает заказ с кнопкой "написать покупателю" прямо в Telegram!<br>
<br>
Сейчас мы развиваем проект как полноценный сайт, оставляя поддержку версии для мессенджеров.<br>
<br>
В покупку лицензии включена стоимость разработки индивидуального дизайна<br>
<br>
После покупки вам нужно будет оплачивать размещение проекта на наших серверах - так мы гарантируем сохранность нашего кода, а вы экономите сотни тысяч рублей на системном администраторе, бекапах, юридических заморочках с роскомнадзором (берём ответственность на себя) и постоянным масштабированием. Цена небольшая, особенно учитывая, что туда входит наша постоянная тех. поддержка<br>
<br>
Не берём никаких процент с продаж!<br>
<br>
По желанию добавляем или удаляем функции, а критические обновления безопасности устанавливаем бесплатно. В случае проблем, тех.работ или утечек оповещаем моментально.
HTML,
'deal' => [
'cost' => '120 000',
'text' => 'ВЕЧНАЯ ЛИЦЕНЗИЯ НА КОД'
],
'button' => [
'class' => 'deal blue',
'text' => 'ВЫБРАТЬ',
'label' => 'Кнопка выбора суперпака для калькулятора'
]
],
];
// Sending the cookie with the team workload (1800 = 30min)
/* setcookie('workload', $this->view->workload, time() + 1800, '/'); */
// Initializing contacts data
$this->view->integrations = [
'Вайлдберриз' => 'wildberries',
'ОЗОН' => 'ozon',
'Мой Склад' => 'moy_sklad',
'1С Предприятие' => '1c',
'Битрикс 24' => 'bitrix24',
'ВКонтакте' => 'vk',
'МАКС' => 'max',
'Авито' => 'avito',
'YClients' => 'yclients',
'ЮКасса' => 'yookassa',
'OpenAI' => 'openai',
/* 'yandex_direct', */
'Яндекс Директ' => 'yandex_market',
];
// Render page
$page = $this->view->render(
'pages/index.html',
[
'uri' => 'https://' . DOMAIN,
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
// Exit (fail)
return null;
}
}

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace kodorvan\site\controllers;
// Files of the project
use kodorvan\site\controllers\core;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
/**
* Offer
*
* @package kodorvan\site\controllers
*
* @param array $errors Registry of errors
*
* @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 offer extends core
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
* Page: offer
*
* @return null
*/
public function index(): null
{
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Render page
$page = $this->view->render(
'pages/offer.html',
[
'uri' => 'https://' . DOMAIN . '/offer',
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
// Exit (fail)
return null;
}
}

View File

@@ -0,0 +1,258 @@
<?php
declare(strict_types=1);
namespace kodorvan\site\controllers;
// Files of the project
use kodorvan\site\controllers\core;
// PHP framework
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\method,
mirzaev\minimal\http\enumerations\status;
// Mail server
use PHPMailer\PHPMailer\PHPMailer as mail,
PHPMailer\PHPMailer\SMTP as smtp,
PHPMailer\PHPMailer\Exception as mail_exception;
/**
* Index
*
* @package kodorvan\site\controllers
*
* @param array $errors Registry of errors
*
* @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 project extends core
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
* Page: constructor
*
* @return null
*/
public function constructor(): null
{
if ($this->request->method === method::get) {
// GET
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Initializing the project constructor data
$this->view->calculator = [
'architectures' => [
'site' => 'Сайт',
'chat_robot' => 'Чат-робот',
'program' => 'Программа',
'game' => 'Видеоигра',
'script' => 'Скрипт, парсер, макрос',
'module' => 'Модуль, плагин, расширение',
],
'purposes' => [
'funnel' => 'Воронка (обработка пользователя)',
'contacts' => 'Контакты (сбор данных)',
'ai' => 'Внедрение ИИ',
'archive' => 'Архив (галерея, библиотека, реестр)',
'crm' => 'Индивидуальная CRM',
'landing' => 'Лендинг (посадочная страница)',
'marketplace' => 'Маркетплейс, магазин, витрина',
'saas' => 'SaaS проект',
'search' => 'Поиск и анализ',
'calculate' => 'Вычисления (калькулятор)',
'individual' => 'Индивидуальная разработка',
],
'integrations' => [
'one_c' => '1C',
'bitrix24' => 'Битрикс24',
'moy_sklad' => 'Мой Склад',
'mail' => 'Почта',
'excel' => 'Excel',
'ozon' => 'OZON',
'wildberries' => 'Wildberries',
'yandex_market' => 'Яндекс Маркет',
'avito' => 'Авито',
'vk' => 'ВКонтакте',
'max' => 'МАКС',
'telegram' => 'Телеграм',
'neural_networks' => 'Нейросети'
]
];
// Render page
$page = $this->view->render(
'pages/project/calculator.html',
[
'uri' => 'https://' . DOMAIN . "/project/calculator",
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
}
// Exit (fail)
return null;
}
/**
* Request the project by calculator
*
* @return null
*/
public function request(string $request): null
{
// Debugging
date_default_timezone_set('Asia/Yekaterinburg');
$jornal = JOURNAL . '/requests.txt';
file_put_contents($jornal, "\n\n\n\n", FILE_APPEND);
file_put_contents($jornal, '[' . date('Y.m.d H:i:s') . '] Заказ с сайта: ' . DOMAIN . "\n", FILE_APPEND);
file_put_contents($jornal, print_r($request, true) . "\n", FILE_APPEND);
file_put_contents($jornal, print_r($this->request->files, true) . "\n", FILE_APPEND);
if ($this->request->method === method::put) {
// PUT
// Initializing the project identifier (temporary solution)
$identifier = blake3($request, 20);
// Initializing the project storage path
$path = STORAGE . DIRECTORY_SEPARATOR . 'projects' . DIRECTORY_SEPARATOR . $identifier;
// Initializing the project storage directory in the storage
if (!file_exists($path)) mkdir($path, 0775, true);
// Declaring the project storage files registry
$files = [];
foreach ($this->request->files as $file) {
// Iterating over files
// Initializing the file destination path
$destination = $path . DIRECTORY_SEPARATOR . $file['name'];
// Writing the file into the project storage
copy($file['tmp_name'], $destination);
// Writing the file destination path into the project storage files registry
$files[$file['name']] = $destination;
}
// Decoding the request JSON argument
$request = json_decode(json: $request, associative: true, depth: 5);
// Initializing the mail server
$mail = new mail(true);
try {
// Writing the mail server parameters
/* $mail->SMTPDebug = smtp::DEBUG_SERVER; */
$mail->setLanguage('ru');
$mail->CharSet = mail::CHARSET_UTF8;
$mail->isSMTP();
$mail->Host = MAIL['host'];
$mail->SMTPAuth = true;
$mail->Username = MAIL['sender']['mail'];
$mail->Password = MAIL['sender']['password'];
$mail->SMTPSecure = mail::ENCRYPTION_SMTPS;
$mail->Port = 465;
$mail->setFrom(MAIL['sender']['mail'], MAIL['sender']['name']);
$mail->addAddress(MAIL['receiver']['mail'], MAIL['receiver']['name']);
// The message
$mail->isHTML(true);
$mail->Subject = empty($request['project']['name']) ? 'Заказ' : 'Заказ: ' . $request['project']['name'];
$mail->Body = $this->view->render('messages/request.html', $request);
/* $mail->AltBody = 'This is the body in plain text for non-HTML mail clients'; */
// Attachments
foreach ($files as $name => $file) {
// Iterating of project storage files registry
// Writing the attachment into the message
$mail->addAttachment($file, $name);
}
// Sending the message
$mail->send();
} catch (mail_exception $exception) {
file_put_contents($jornal, '[' . date('Y.m.d H:i:s') . "] ПИЗДЕЦ\n", FILE_APPEND);
file_put_contents($jornal, '[' . date('Y.m.d H:i:s') . ']' . $exception->getMessage() . "\n", FILE_APPEND);
try {
// Initializing the mail server
$mail = new mail(true);
$mail->setLanguage('ru');
$mail->CharSet = mail::CHARSET_UTF8;
$mail->isSMTP();
$mail->Host = MAIL['host'];
$mail->SMTPAuth = true;
$mail->Username = MAIL['sender']['mail'];
$mail->Password = MAIL['sender']['password'];
$mail->SMTPSecure = mail::ENCRYPTION_SMTPS;
$mail->Port = 465;
$mail->setFrom(MAIL['sender']['mail'], MAIL['sender']['name']);
$mail->addAddress(MAIL['receiver']['mail'], MAIL['receiver']['name']);
// The message
$mail->isHTML(true);
$mail->Subject = empty($request['project']['name']) ? 'Заказ без документов' : 'Заказ без документов: ' . $request['project']['name'];
$mail->Body = $this->view->render('messages/request.html', $request);
// Sending the message
$mail->send();
} catch (mail_exception $exception) {
file_put_contents($jornal, '[' . date('Y.m.d H:i:s') . "] ПОВТОРНЫЙ ПИЗДЕЦ\n", FILE_APPEND);
file_put_contents($jornal, '[' . date('Y.m.d H:i:s') . ']' . $exception->getMessage() . "\n", FILE_APPEND);
}
}
// Sending response
$this->response
->start()
->clean()
->sse()
->json(['errors' => []])
->validate($this->request)
?->body()
->end();
// Exit (success)
return null;
}
// Exit (fail)
return null;
}
}

View File

@@ -0,0 +1,197 @@
<?php
declare(strict_types=1);
namespace kodorvan\site\controllers;
// Files of the project
use kodorvan\site\controllers\core,
kodorvan\site\models\superpack as model;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\method,
mirzaev\minimal\http\enumerations\status;
// Baza database
use mirzaev\baza\database,
mirzaev\baza\column,
mirzaev\baza\record,
mirzaev\baza\enumerations\encoding,
mirzaev\baza\enumerations\type;
/**
* Offer
*
* @package kodorvan\site\controllers
*
* @param array $errors Registry of errors
*
* @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 superpack extends core
{
/**
* Errors
*
* @var array $errors Registry of errors
*/
protected array $errors = [
'system' => []
];
/**
* Page: superpack
*
* @return null
*/
public function index(string $urn): null
{
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Initializing the superpack
$superpack = new model()->read(filter: fn(record $record) => $record->urn === $urn && $record->active === 1);
if ($superpack instanceof model) {
// Initialized the superpack
// Render page
$page = $this->view->render(
'pages/article.html',
[
'uri' => 'https://' . DOMAIN . "/superpack/$urn",
'article' => [
'urn' => $superpack->urn,
'head' => [
'title' => $superpack->title
],
'body' => [
'html' => $superpack->html
]
],
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
} else {
// Not initialized the superpack
}
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
// Exit (fail)
return null;
}
/**
* Page: superpack
*
* @return null
*/
public function create(
?string $identifier = null,
?string $urn = null,
?string $title = null,
?string $html = null,
?string $text = null,
string|int|float|null $supercost = null
): null {
if ($this->request->method === method::get) {
// GET
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
// Request for HTML response
// Render page
$page = $this->view->render(
'pages/system/superpack/create.html',
[
'uri' => 'https://' . DOMAIN . "/system/superpack/create",
'smartphone' => $this->request->smartphone,
'tablet' => $this->request->tablet
]
);
// Sending response
$this->response
->start()
->clean()
->sse()
->write($page)
->validate($this->request)
?->body()
->end();
// Deinitializing rendered page
unset($page);
// Exit (success)
return null;
}
} else if ($this->request->method === method::put) {
// PUT
// Initializing the superpack
$superpack = new model()->read(filter: fn(record $record) => $record->urn === $urn);
if ($superpack instanceof model) {
// The superpack is already created
} else {
// The superpack is not already created
// Sanitizing
$urn = preg_replace('/[^\w\d\-.]+/', '', $urn);
$title = preg_replace('/[^\w\d\s\-.,!]+/u', '', $title);
$supercost = (float) preg_replace('/[^\d.]+/', '', $supercost);
// Creating the superpack
$superpack = new model()->write(
urn: $urn,
title: $title,
html: $html,
text: $text,
supercost: $supercost
);
if ($superpack instanceof record) {
// Created the superpack
// Sending response
$this->response
->start()
->clean()
->sse()
->json([
'redirect' => "/superpack/$urn"
])
->validate($this->request)
?->body()
->end();
}
}
}
// Exit (fail)
return null;
}
}

View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace kodorvan\perm\models; namespace kodorvan\site\models;
// Framework for PHP // Framework for PHP
use mirzaev\minimal\model, use mirzaev\minimal\model,
@@ -14,7 +14,7 @@ use exception;
/** /**
* Models core * Models core
* *
* @package kodorvan\perm\models * @package kodorvan\site\models
* *
* @method void __construct() Constructor * @method void __construct() Constructor
* *

View File

@@ -0,0 +1,215 @@
<?php
declare(strict_types=1);
namespace kodorvan\site\models;
// Files of the project
use kodorvan\site\models\core;
// Baza database
use mirzaev\baza\database,
mirzaev\baza\column,
mirzaev\baza\record,
mirzaev\baza\enumerations\encoding,
mirzaev\baza\enumerations\type;
// Active Record pattern
use mirzaev\record\interfaces\record as record_interface,
mirzaev\record\traits\record as record_trait;
// Svoboda time
use svoboda\time\statement as svoboda;
// Built-in libraries
use Exception as exception,
LogicException as exception_logic,
RuntimeException as exception_runtime;
/**
* Project
*
* @package kodorvan\site\models
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class superpack extends core implements record_interface
{
use record_trait;
/**
* File
*
* @var string $file Path to the database file
*/
protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'superpacks.baza';
/**
* Database
*
* @var database $database The database
*/
public protected(set) database $database;
/**
* Serialized
*
* @var bool $serialized Is the implementator object serialized?
*/
private bool $serialized = true;
/**
* Constructor
*
* @method record|null $record The record
*
* @return void
*/
public function __construct(?record $record = null)
{
// Initializing the database
$this->database = new database()
->encoding(encoding::utf8)
->columns(
new column('identifier', type::long_long_unsigned),
/* new column('account', type::long_long_unsigned), */
new column('urn', type::string, ['length' => 64]),
new column('title', type::string, ['length' => 128]),
new column('html', type::string, ['length' => 8192]),
new column('text', type::string, ['length' => 8192]),
new column('supercost', type::float),
new column('active', type::char),
new column('updated', type::integer_unsigned),
new column('created', type::integer_unsigned)
)
->connect($this->file);
// Initializing the record
$record instanceof record and $this->record = $record;
}
/**
* Write
*
* @throws exception_logic when failed to process project integration
*
* @param int $account The account identifier
* @param string $urn URN
* @param string $title Title
* @param string|null $html Content (HTML)
* @param string|null $html Content (text)
* @param int|float|null $supercost Cost
* @param int $active Is the record active?
*
* @return record|false The record, if created
*/
public function write(
/* int $account, */
string $urn,
string $title,
?string $html = null,
?string $text = null,
int|float|null $supercost = null,
bool $active = true,
): record|false {
if (!empty($html) || !empty($text)) {
// Initializing the record
$record = $this->database->record(
$this->database->count() + 1,
/* $account, */
$urn,
$title,
(string) $html,
(string) $text,
(float) $supercost,
(int) $active,
svoboda::timestamp(),
svoboda::timestamp()
);
// Writing the record into the database
$created = $this->database->write($record);
// Exit (success)
return $created ? $record : false;
}
// Exit (fail)
return false;
}
/**
* Serialize
*
* @return self The instance from which the method was called (fluent interface)
*/
public function serialize(): self
{
if ($this->serialized) {
// The record implementor is serialized
// Exit (fail)
throw new exception_runtime('The record implementor is already serialized');
}
// Serializing the record parameters
$this->record->active = (int) $this->record->active;
// Writing the status of serializing
$this->serialized = true;
// Exit (success)
return $this;
}
/**
* Deserialize
*
* @return self The instance from which the method was called (fluent interface)
*/
public function deserialize(): self
{
if (!$this->serialized) {
// The record implementor is deserialized
// Exit (fail)
throw new exception_runtime('The record implementor is already deserialized');
}
// Deserializing the record parameters
$this->record->active = (bool) $this->record->active;
// Writing the status of serializing
$this->serialized = false;
// Exit (success)
return $this;
}
/**
* Account
*
* Search for the account
*
* @return account|null The account
*/
/* public function account(): ?account
{
// Search for the account
$account = new account()->read(filter: fn(record $record) => $record->identifier === $this->account && $record->active === 1);
if ($account instanceof account) {
// Found the account account
// Deserializing the record
$account->deserialize();
// Exit (success)
return $account;
}
// Exit (fail)
return null;
} */
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Akony';
src: url("/fonts/akony/AKONY.ttf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,31 @@
@charset "UTF-8";
@font-face {
font-family: 'ALS Schlange';
src: url("/fonts/als_schlange/alsschlangesans-thin.otf");
font-weight: 100;
}
@font-face {
font-family: 'ALS Schlange';
src: url("/fonts/als_schlange/alsschlangesans-light.otf");
font-weight: 200;
}
@font-face {
font-family: 'ALS Schlange';
src: url("/fonts/als_schlange/alsschlangesans.otf");
font-weight: 400;
}
@font-face {
font-family: 'ALS Schlange';
src: url("/fonts/als_schlange/alsschlangesans-bold.otf");
font-weight: 600;
}
@font-face {
font-family: 'ALS Schlange';
src: url("/fonts/als_schlange/alsschlangesans-black.otf");
font-weight: 800;
}

View File

@@ -0,0 +1,50 @@
@charset "UTF-8";
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-ExtraLight.woff2");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Light.woff2");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-SemiLight.woff2");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Regular.woff2");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Regular.woff2");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-SemiBold.woff2");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Cascadia Code';
src: url("/fonts/cascadia_code/CascadiaCode-Bold.woff2");
font-weight: 700;
font-style: normal;
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Commissioner';
src: url('/fonts/commissioner.ttf');
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Compacta';
src: url("/fonts/compacta/compacta_lt_light_compress.otf");
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Eitai';
src: url("/fonts/eitai/eitai.otf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,37 @@
@charset "UTF-8";
@font-face {
font-family: 'Golos';
src: url("/fonts/golos/Golos-Text_VF.ttf");
font-weight: 400 900;
}
/* @font-face {
font-family: 'Golos';
src: url("/fonts/golos/Golos-Text_Regular.ttf");
font-weight: 400;
}
@font-face {
font-family: 'Golos';
src: url("/fonts/golos/Golos-Text_Medium.ttf");
font-weight: 500;
}
@font-face {
font-family: 'Golos';
src: url("/fonts/golos/Golos-Text_DemiBold");
font-weight: 600;
}
@font-face {
font-family: 'Golos';
src: url("/fonts/golos/Golos-Text_Bold");
font-weight: 700;
}
@font-face {
font-family: 'Golos';
src: url("/fonts/golos/Golos-Text_Black.ttf");
font-weight: 800;
} */

View File

@@ -0,0 +1,15 @@
@charset "UTF-8";
@font-face {
font-family: 'GOST';
src: url("/fonts/gost/GOST 2.304-81 type A.ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'GOST';
src: url("/fonts/gost/GOST 2.304-81 type B.ttf");
font-weight: 400;
font-style: normal;
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Industry';
src: url("/fonts/industry/Industry-Bold_RUS.ttf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,63 @@
@charset "UTF-8";
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-LightCondensed.ttf");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-LightCondensed.ttf");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-LightCondensed.ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-RegularCondensed.ttf");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-RegularCondensed.ttf");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-Bold.ttf");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-BoldCondensed.ttf");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-BlackCondensed.ttf");
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: 'MT Sans';
src: url("/fonts/mt_sans/MTSans-BlackExtended.ttf");
font-weight: 900;
font-style: normal;
}

View File

@@ -0,0 +1,64 @@
@charset "UTF-8";
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-ExtraLight.ttf");
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Light.ttf");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Regular.ttf");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Regular.ttf");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Medium.ttf");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Bold.ttf");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-ExtraBold.ttf");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Black.ttf");
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: 'Nunito';
src: url("/fonts/nunito/Nunito-Black.ttf");
font-weight: 900;
font-style: normal;
}

View File

@@ -0,0 +1,8 @@
@charset "UTF-8";
@font-face {
font-family: 'Palui';
src: url("/fonts/palui/PaluiSPDemo-Bold.otf");
font-weight: normal;
font-style: normal;
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Slifted';
src: url("/fonts/slifted/slifted.otf");
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Strogo';
src: url("/fonts/strogo/Strogo-Regular.ttf");
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Urban Slavic';
src: url("/fonts/urban_slavic/UrbanSlavic.otf");
}

View File

@@ -0,0 +1,6 @@
@charset "UTF-8";
@font-face {
font-family: 'Vredina';
src: url("/fonts/vredina/SAVredina-ThinUltraCondensed.woff");
}

Binary file not shown.

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