Warning: Undefined array key 0 in /var/www/tgoop/function.php on line 65

Warning: Trying to access array offset on value of type null in /var/www/tgoop/function.php on line 65
375 - Telegram Web
Telegram Web
Ну что как у вас начался рабочий год? Лично у меня с сообщение от мака: "Братан, помнишь у тебя прога такая была, Docker, ну так вот, больше нет это на самом деле вирус". Обожаю разработку, ничего не трогал, а оно сломалось.

Я сначала думал, что это опять наши безопастники что-то нахуевертили после нового года. У нас давно уже ходили слухи о том, что нужно переходить на аналог под названием Colima.

Название прекрасное, разработчики судя по Github с Негерии, но жалко что не из СНГ, было бы гораздо вайбовее. Представьте аналог докера Colima и еще сделать аналог кубера под названием Gulag c оркестрацией контейтеров медом репрессии.
Недавно мне пришлось повозиться с системой написанной на node.js. Помните я много гадостей писал про Gradle. Что в нем много магии, у него странно работают кеши, что он жрет чудовищно много памяти. Ко мне пришло осознание, что я с жиру бесился. Gradle по сравнению c npm технология будущего. Фронтендеры, объясните мне, вы с этой херней как живете вообще?

Я вношу изменения в код, все собирается, все прекрасно. В определенный момент npm берет и говорит: а дальше я работать не буду! И нихера не помогает, я по гиту вижу, что изменений с последнего успешного запуска нет. Я и кеши чистил, и все папки с билдом удалял, и зависимости пытался скачать заново – вообще похую. Еще и сам npm рот топтал подсказывать что конкретно не так.

Ладно gradle жрет дофига, но он хотя бы работает и говорит что ему не нравится (ну почти всегда)!
Знаете вот это ощущение когда твой коллега слишком хорошо делает свою работу и это неожиданно становится твоей проблемой. Когда он затащил плагин, проверяющий зависимости каждого gradle модуля, с благой целью, чтобы в итоге сборка была быстрее. Ведь теперь у каждого модуля не будет ничего лишнего, это действительно круто. Правда у этого есть обратная сторона медали.

Если теперь чуть-чуть потрогать зависимости core модуля, тебе придется повысить скил во многих вещах. Прокачать знания разных типов зависимостей, прокачать внимательность и прокачать гланды, потому как от этих проверок ты мгновенно получишь за щеку при любой не стыковке. Пол дня уже вожусь с деревьями зависимостей, чтобы понять где я проебался
Я последнее время словил какой-то кризис связанный с правдой. Например, ты  хочешь быть более продуктивным и чувствовать себя лучше физически. Разумеется ты не полезешь сразу в научные статьи, потому что не потерял надежду на личную жизнь. Ты идешь смотреть популяризаторов науки, и тут начинается карусель безумия.

Смотришь одного, вроде все норм, ничего не продает и то, что он говорит даже вроде как логично. Затем смотришь другого, уже врача и оказывается, что первый все напутал и все вообще по-другому. Потом смотришь третьего и оказывается что этот врач вообще инфоциган, который продвигает свои БАДы, а первый просто питух. Ядрена, мать…

Ладно, а что если самому попытаться почитать исследования, например взять несколько метаанализов, вроде не должно быть супер сложно. Однако тут тоже не без приколов. Оказывается что исследование исследованию рознь. Есть хорошие с большой выборкой, есть не очень которые обманывают тебя через статистику. Из-за этого можно подтвердить любую точку зрения:

- А кофе полезный? Конечно полезный, 3 чашки в день для сердца вообще отлично…
- А кофе вредный? Конечно вредный, ты че дурачок, ты в себя черную жижу заливаешь, еще и сон потом плохой…

Штош, подумал я, хотя бы в IT нет такой проблемы. Ну тут сложно напиздеть, ведь все проверяется, любой код можно запустить, чтобы проверить что да, вот эта система действительно работает. Потом вспомнил что у нас есть такие вещи как чистый код, охрененная куча абстракций чтобы один и тот же код запускался одинаково, а еще у нас самый популярный язык это JS…
Поговорим про Go. Все таки нужно выходить на рамки канала который хихикает над Gradle и начать хихикать над другими языками. Ну так вот, наверняка многие тут его пробовали, или хотя бы видели синтаксис. После котлина синтаксис, кажется мягко говоря дермовый.

Однако когда больше изучаешь историю и причины его создания, все встает на свои места. Изначально язык разрабатывался под конкретные проблемы гугла. Им нужно было сделать инструмент, который бы позволял очень быстро создавать CRUD при этом был простой как сапог и быстрый как алкаш за 5 минут до закрытия КБ.

Почему именно новый язык? С++ слишком сложный, Python слишком медленный, а Java перегруженная, долго стартует и жрет дохрена.

Помимо этого они хотели решить вот какую проблему. Вот представь, ты архитектор в огромной корпорации. Тебе нужно сделать так, чтобы несколько команд сделали свою часть работы. Однако огромная куча времени тратится на согласование и споры о том, что в этих системах стоит вынести в общий модуль, а что реализовать отдельно и как это общее должно работать.

Все кто работал в больших командах знает, что создать вот этот общий модуль, который устраивает всех это ебанись какая проблема. Нужно собрать требования, предложить прототип, и на этом этапе 100% найдется кто-то, кому все не нравится и нужно сделать по-другому.

Поэтому было бы круто иметь такой язык, который бы позволил сделать задачу быстро и при этом своим синтаксисом тебя заставлял бы делать все одинаково. Вместо того чтобы тратить время на встречи, пусть они один и тот же код тупо у себя реализуют как им нужно. Архитектор при этом не тратит время, на согласование всего и выслушивание жалоб обиженных.

В этом и проявляется вот этот допотопный синтаксис. Он специально сделан излишне упрощенным. Зайдя в любую кодовую базу на Go, ты увидишь одни и те же подходы и конструкции. Ну в частности проверку на ошибку, при вызове почти любой функции. Язык тебе просто не позволит написать код так, как не принято в языке.

Отсюда выходит и поддерживаемость решений. Ты пишешь код, да со страшным синтаксисом что глаза болят, но зато заходишь через 5 лет в этот же код и у тебя вообще никаких удивлений (нуу почти всегда…). Это сильно контрастирует c JS, где ты написал код, а через два месяца оказывается, что уже никто так не пишет и все к херам устарело.
Вы уже попробовали deepseek? Я осознал, что за все время существования канала, ни разу не писал про LLM. Ну так вот, если вдруг каким-то чудом вы миновали волну хайпа. Пацаны с Китая зарелизили модель которая, судя по бенчмаркам не уступает флагманской модели ChatGPT.

При этом это открытая модель. Пацаны, оказались настолько успешны, что приостановили регистрацию из кибератак.
Лично мне модель показалось весьма интересной, как минимум по двум причинам:

👉 К ней можно обращаться без VPN. Прям повеяло ветерком свободы, как будто опять в Казахстан съездил.
👉 Больше всего меня позабавил режим "DeepThink". Тут ничего нового, этот режим появился еще в модели o1 ChatGPT. Суть в том, что в модель добавляются токены "рассуждения". Однако если в o1 они скрыты в сервисе, то DeepSeek выдает их вместе с ответом.

Не знаю зачем было сделано именно так, вероятно, чтобы ты мог отслеживать как модель думает. Правда из-за этого иногда складывается ощущение, что задаешь вопросы шизофренику, который судорожно пытается найти ответ, разговаривая сам с собой.
Итак, Яндекс Музыка. Это крайне эмоциональная тема для меня, ведь я работал на этом проекте года 3 назад. Это кстати было мое первое выгорание, реальность с вертухи мне сняла розовые очки. Когда-то я думал, что во всех командах яндекса, просто нереального качества код, лучшие практики, гайдлайны, доки и т.д. Как говорил Торин: "Я никогда так не ошибался". Про мои впечатления от работы на этом проекте я пожалуй оставлю для другого поста.

Сейчас же сосредоточимся именно на приложении. У меня сложилось стойкое ощущение, что интерфейс яндекс музыки проектировал человек, который ненавидит музыку!

Плейлисты. Swipe to Dismiss базовая тема, чтобы удалить трек из плейлиста, есть во всех приложениях, является самым базовым жестом. В Я.Музыке отсутствует, хочешь удалить трек нажимай на 3 точки, подожди Bottom Sheet и только потом удаляешь. Далее, вот ты включил плейлист, потом на странице трека решил, что все таки не, трек уже не нравится пожалуй уберу его. Нажимаешь на три точки и видишь, что трек нельзя убрать из плейлиста, только добавить. Чтобы убрать трек во время прослушивания, ты выходишь из страницы трека, идешь в список, нажимаешь на три точки и т.д уже обсудили в начале абзаца.

Подкасты. Я в основном Я.Музыку использовал для подкастов. Вот кстати алгоритм как включить подкаст в приложении. Зайти на страницу подкаста, найти нужный выпуск, нажать на выпуск, подождать (ничего не происходит), нажать на стоп, нажать на плей. Выйти из подкаста, зайти обратно, выгрузить приложение, загрузить обратно, снова включить выпуск, вот теперь заработало. Я бы не психовал, если бы так не происходило каждый 2-3 раз. Мне когда рассказали про Apple Podcast, я так ахуел. Что оказывается можно просто нажать на выпуск и он сразу начинает играть, без ожидания кеширования, без задержек, без выгрузки приложения.

For kids. Вот этого прикола я вообще не понимаю. Неужели у большей части аудитории Я.Музыки есть дети? Почему эта вкладка насколько важная, что находится в основном меню? Ну я более чем уверен, что это один из дизайнеров решил так увеличить метрики по этому разделу. Ну вот кликов же больше стало, а значит популярность выше у раздела For kids. Разработчики запилили, все получили премии, а то что кликов стало больше, тупо потому что все часто промахиваются и заходят туда случайно, всем похеру.

Ну и вишенка на торте это Bottom Sheet для треков, который упоминал выше. Кто блять придумал загружать его каждый сука раз? Я ехал в лифте недавно, и все, я не мог вызвать это меню. Вот тупо ради интереса, берете приложение, включаете режим в самолете и вуаля, тупо пустой Bottom Sheet. Видимо в Яндексе настолько привыкли к Аркадии, что решили что пусть и в приложении без интернета нельзя менять состояния плейлистов. Действительно, там же потом в фоне нужно синхронизировать с беком, а это сложно. В конце концов не деревья же вращаем.
Итак, Astro Bot. Игрой года в 2024 году стал Astro Bot, и я не понимаю, как так вышло.

В чем суть, с релизом PS5 Sony выпустила мини игру ASTRO's PLAYROOM. Платформер про робота, который бегает по внутренностям консоли и знакомит тебя с ее преимуществами. Игра с довольно простыми механиками, приятной рисовкой и кучей логотипов Sony. Вот это самый забавный момент, зачем повсюду логотип Sony? Наверное, чтобы люди вдруг не подумали, что игра про xbox.

Короче, игра настолько всем понравилась, что Sony решила ее допилить и выпустить как полноценный продукт. И не прогадали, игра взлетела. Все от нее в восторге, у меня есть друзья, которые без ума от нее. Правда я не понимаю, почему? Я не говорю что игра плохая, нет. У нее приятный геймплей, она очень разнообразная и красивая, нооо игра года?

Мне когда про нее рассказали, я подумал, наверное, они добавили туда кучу новых механик и полноценный сюжет. Я вроде видел вырезки с Кратосом из God of War. Возможно вся игра это рефлексия Sony об эксклюзивах, которые выходили последние 10 лет?

Неть, это все тот же самый ASTRO's PLAYROOM, только теперь ты бегаешь не по консоли, а по разным планетам. На этом все: никаких новых механик или сюжета. Ну сюжет там есть, на уровне детских мультиков типа Даши Путешественницы.

Неужели у нас год выдался настолько скудным на релизы, что игрой года стал платформер. Ну объективно это сложно назвать AAA игрой, особенно в сравнении с Wukong или Helldivers 2.

Как мне кажется дело в ностальгии. Ну ведь правда, когда в нее играешь, впадаешь в детство. В детство, где у тебя нет забот, нет релизов, нет gradle… Ты не испытываешь эмоциональные перепады из-за сюжета как в том же God of War. При этом у тебя очень быстро меняются миры, эдакий тик-ток на уровне всей игры.

В целом я бы советовал ее пройти, но только нужно выполнить два условия, чтобы она действительно зашла:
👉 Вы должны быть выгоревшим в угли
👉 Начать ее проходить под новый год (в некоторых планетах, там прям подходящая атмосфера)
Удивительно, но одна из вещей, которая многих разрабов приводит в страх это любое упоминание графов на собесе. Я убежден, что задрачивать очень сложные алгоритмы поиска путей это пустая трата времени, если вы не на проекте логистики.

Однако базовые алгоритмы обхода графа, как мне кажется стоит знать. Они бывают полезными на практике. Например, построить граф зависимостей на проекте или сделать закрашивание как в paint, придумать можно кучу всего. Помимо этого, алгоритмы обхода графа, это буквально самые простые алгоритмы которые есть. Запомнить их даже проще, чем бинарный поиск. Поэтому погнали…

Думаю что такое граф объяснять не нужно. Есть точки соединенные линиями. Точки это вершины, линии это ребра. Есть куча видов графов, но сейчас достаточно запомнить только вершины и ребра. Обход графа это просто алгоритм, чтобы посетить все вершины графа в определенном порядке. Есть два основных способа как это сделать:

👉 поиск в глубину
👉 поиск в ширину

Отличаются они лишь тем, какую структуру данных вы используете, чтобы организовать список вершин.

Если же это поиск в глубину, вы используете стек. Алгоритм такой, идем в первую вершину, кладем всех соседей в стек. Затем берем из стека элемент и повторяем процедуру:
def dfs(graph, start):
visited = set()
visited.add(start)

stack = [start]
while stack:
vertex = stack.pop()
for neighbor in graph[vertex]:
if neighbor not in visited:
visited.add(neighbor)
stack.append(neighbor)


Если же это поиск в ширину, то все, то же самое, только для списка используем очередь:
def bfs(graph, start):
visited = set()
visited.add(start)
queue = deque(start)

while queue:
vertex = queue.popleft()
for neighbor in graph[vertex]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)


Давайте на примере конкретного графа, представим, что у нас есть твое генеалогическое древо:
    Ты
/ \
Папа Папа

Ладно, ладно, ну вы сами знали на кого, подписывались, смотрите пример в картинке...

Нафига два разных алгоритма? Разные обходы нужны для разных целей. DFS хорошо подходит для поиска циклов: условие if neighbor not in visited в блоке else мы попадем только если у графа есть цикл. BFS же вроде как подходит для поиска кротчайшего пути, но я на практике такую штуку не реализовывал.
Друзья которые работают в Яндексе страшно возмущены этим видео. Абсолютная чушь и клевета. Ведь на самом деле на обед дают 875 рублей, а не 800
Forwarded from KNADCORE (Max Kreslavsky)
This media is not supported in your browser
VIEW IN TELEGRAM
Собеседование в Яндекс
Вот почему в телеграмме так всрато работает комментирование реплаев? Каждый раз на это попадаю, что отправляется два разных сообщения
Вы знакомы с таким понятием как сверх ценная идея? Это некоторое суждение, которое возникает у человека в результате жизненных обстоятельств, при этом сопровождаемое очень сильными эмоциями. В результате суждение становится доминирующим в сознании, человек становится как бы одержим этой идеей.

Сверх ценная идея по сути защитный механизм для психики. Очень просто все делить на черное и белое. Ведь чтобы видеть полутона, нужно прикладывать усилия. Другими словами эти суждения довольно часто крайне однобокие, а следовательно ошибочны. Из-за вот этой однобокости искажается первоначальный смысл того, что лежит в основе сверх ценной идеи.

Вот например идея бодипозитива, которая изначально была направлена то, чтобы люди принимали свое тело и не пытаясь его изменить. Ну типо, вот у тебя есть шрам на лице, или инвалидность, т.е те вещи ну которые довольно сложно исправить. Идея в том, что важно себя принять таким и не дискриминировать других за их особенности. Суть в том, чтобы избавится от комплексов.

Однако со временем, эта идея переросла в: "я забью хер на диету, ведь у меня не хватает морально волевых качеств, и я горжусь этим"! Идея, что нужно принимать себя превратилась в пропаганду ожирения.

Вот на этом моменте вы наверное думаете: философ хуев, нахера мне это нужно в канале про разработку? А я это вот к чему, markdown – это сверх ценная идея!

Подход для разметки документа, который задумывался для упрощения. Подход, который позволяет накидать документ без всяких превью. Все это превратилось в то, что я теперь должен скачать и запустить докер с node.js (привет npm), для проверки, что моя дока нормально отображается!

Обычный markdown слишком просто, давайте затащим docusaurus, в котором есть еще 50 вариантов прикольных элементов. В итоге идешь в доку ожидая только markdown файлы, а там какие-то файлы верстки, и уже даже какой-то реакт компонент. Мы с каждым днем все дальше от бога…
Недавно я накидал пост, про свое недовольство npm. Разумеется сразу получил в ответ, что версия node не та, что это я не разобрался, чтобы я про это пошел жаловаться своим отчимам. Вот как же все привыкли сразу гневно реагировать на критику инструментов которые используют.

Во-первых, это уже готовый проект, все что я хочу, это добавить пару фичей, сбилдить это все, запихать в докер и больше с этим не связываться. Но система сборки, которая мне должна помогать вставлять палки в колеса.

Во-вторых, версия у меня прям та, которая прям написана в проекте. Помимо этого используется corepack, который сам устанавливает нужные версии pnpm и т.д.

В прошлый раз кстати, все починились старым добрым: снести нахер репозиторий, склонировать заново, добавить в него мои изменения и запустить. В это раз все заработало, почему? Я не знаю, но я завидую фротендерам, они живут в чудесном мире, где все еще есть магия.

Однако на этом моя эпопея не закончилась. Локально у меня все заработало, я даже смог настроить дебагер, чтобы все проверить. Запушил я это все на CI, и теперь оно сломалось там. Без какой-либо внятной ошибки. Опять то же самое, ошибка есть, но где я не скажу…
Вот такой лог у меня есть:

n8n-editor-ui:build:  ELIFECYCLE  Command failed with exit code 1.
n8n-editor-ui:build: ERROR: command finished with error: command (/builds/sme-tools/n8n/packages/editor-ui) /usr/bin/pnpm run build exited (1)
n8n-editor-ui#build: command (/builds/sme-tools/n8n/packages/editor-ui) /usr/bin/pnpm run build exited (1)
Tasks: 17 successful, 18 total
Cached: 0 cached, 18 total
Time: 4m40.712s
Failed: n8n-editor-ui#build
ERROR run failed: command exited (1)
 ELIFECYCLE  Command failed with exit code 1.


Дамы и господа, ваши догадки, что тут сломалось?
Типизация о которой вы не знали

Я так уж вышло сейчас на работе имею дело с разными языками. Это мне отчасти нравится тем, что узнаешь штуки, которые есть в других языках, о которых ты даже не догадывался. Сегодня хочу рассказать про типизацию

Есть два варианта типизации номинальная и структурная.

📜 В номинальной типизации совместимость типов определяется именем. Есть класс A и класс B и есть функция, которая принимает входным параметром класс A. Даже если класс A и класс B полностью совпадают по полям и методам, все равно при попытке вызвать функцию с объектом класса B компилятор пошлет вас лесом.
class A(val name: String)
class B(val name: String)

fun some(named: A){ /* ... */ }

some(A("Igor")) // тут все норм
some(B("Igor")) // тут уже идем лесом

Мы в java и kotlin всегда используем номинальную типизацию, у нас тупо нет выбора. Однако есть и другой вариант.

🩻 В структурной же типизации все намного гибче. Мы можем указать, что в функцию мы хотим объект, у которого есть поле name. И далее мы можем вызывать эту функцию с вообще каким угодно объектом, главное, чтобы у него было нужное поле
type A = { name: string, age: number };
type B = { name: string };

function some(named: { name: string }){ /* ... */ }

const userA: A = { name: "Igor", age: 30 };
const userB: B = { name: "Igor" };

some(userA)
some(userB)

Такой вариант типизации есть в python, typescript и в go на уровне интерфейсов. При этом если ты попытаешься подсунуть объект, который не удовлетворяет условиям, компиляция не пройдет.

Из плюсов мы получаем, что не нужно плодить кучу разных интерфейсов, чтобы привести несколько объектов к одному типу. Или создавать класс тупо ради того, чтобы передать один объект в метод вместо 4-х. Также очень удобно использовать такое в либах. Ты просто указал структуру, а клиент уже может создавать свои классы, или забить и не создавать.

Из минусов – сложность. Если же в номинальной типизации все однозначно, то при структурной можно уже запутаться где ты там чего передаешь.

По мне так, структурная типизация ощущается более продвинутой, однако джуны бы сошли с ума.
Как вы могли понять по последним постам, у меня большие проблемы с npm, ведь в плане фронтенда я дурачок.

Однако если у вас есть желание увидеть как работает профи фронтенда, почитайте канал «Джун на фронте».

Его автор Юрий, 2 года вкатывался в IT и все же смог. Теперь пилит интеграции для Web3 и пытается в инди-хакинг.

Если вам нравится следить за чужими ошибками и мемами то заглядывайте: @divatoz
Итак, я обещал истории своих проебов за прошлый год. Решил так, разделю истории на разные посты и пойдем по нарастающей, т.е от слабого проеба к тяжелому.

Первая история, это история о потерянном времени. Вероятнее всего вы заметили, что за последние пару лет у нас бум в области LLM. Чуть ли не каждую неделю выходит новая модель и уже проще найти гетеросексуальность у разработчиков npm, чем компанию, которая их не использует.

На фоне всего этого возникла такая идея. На CI у нас переодически падают пайплайны, и нет никакой статистики по причине падания. Где-то памяти не хватило, где-то тесты упали, где-то компиляция не прошла и еще куча всяких причин. Сам Gitlab ведет себя как уставший уролог, его особо не парит почему у тебя там что-то упало.

Поэтому мы посидели, подумали, а что если во время падения пайплайна, отправлять логи в нашу LLM? Она будет класcифицировать проблему по логам, а также выдавать совет разрабу, что делать с упавшей Job. Ну чтобы и разрабам не пришлось лишний раз в логи заходить, да и у нас более подробная статистика будет.

Почему сразу не пойти в API OpenAI? Ну в крупной компании безопастники могут прописать с вертухи за такое. Задача была интересна исключительно по тому, что мне хотелось руками потрогать LLM. Ресурсов у нас было мало, а мозгов еще меньше, поэтому мы решили взять самую мелкую модель из тех, что есть в open source. На тот момент это была Gemma-2b от гугла.

Разумеется сервис решили делать на Python. Я взял Fast api, чтобы быстро накидать сервис и либу от Hugging face для работы с моделями. С либами все шло довольно быстро. Однако большую часть времени я потратил на косплей админа линукса и на возьню с poetry (npm мира python). Да пока еще не было системы сборки, которая бы меня не расстроила(

Иии эта фигня вообще не взлетела. Я потратил довольно много времени: на разворачивание сервиса, на интеграцию модели, на администирование linux, на подбор адекватного промта, который хотя бы иногда советовал что-то адекватное. В результате я получил только опыт и мудрость суть которой – мелкие модели работают крайне паршиво для таких задач.

Дальше расскажу как бы я делал такую штуку сейчас, набив шишки.
Итак, как бы я сейчас делал задачу с классификацией ошибок на МР.

1️⃣ Я бы сразу пошел выбивать ресурсы, чтобы сразу развернуть модель побольше. Большая Llama от Meta на 70B или недавно вышедший deep-seek, прекрасные варианты. Если же компания в которой я работаю, такого не позволяет сделать, договорился бы об отправке логов в Open AI или тот же Deep Seek. В таком случае правда пришлось бы очищать данные, чтобы что-то лишнее не утекло.

2️⃣ Сделал бы другую архитектуру. У нас было сделано так, что мы собираем данные в одной из Job на CI и отправляем в наш сервис. И вот так лучше не делать, лучше не вмешиваться интеграциями внутрь пайплайна. Как нужно было сделать: либо завязаться на вебхуки Gitlab, чтобы он сам нас дергал при падении. Если же вебхуки отключены, раз в условные 10 минут собирать все МРы через Gitlab API и анализировать пачкой по очереди.

3️⃣ Не парился бы с самописным сервисом. Сейчас я бы взял бы какой-нибудь n8n и накидал прототип на нем. Уже после, если бы идея себя оправдала, задумался бы о написании своего сервиса. Развернуть n8n у себя это день если есть готовая инфра, или неделя если ее нужно еще поднимать. Вы примерно сколько бы и потратили на деплой своего сервиса.

И главный проеб! Я не придумал никаких метрик в начале, чтобы понять, а решение вообще стоит того? Сейчас бы я начал со сбора хоть каких-то метрик, хотя бы считать реакции на коментах к МРу.
Мальчик: ждет 14 февраля чтобы сделать подарок своей половинке

Мужчина: ждет 14 февраля чтобы узнать, что будет с ключевой ставкой
2025/07/06 05:57:46
Back to Top
HTML Embed Code: