PageSourceSearch

https://egorod.online/post/19010

html egorod.online collected 2026-10-06 07:03:51 UTC 21,673 bytes, 212 lines download raw bytes

1<!DOCTYPE html>
2<html lang="ru">
3<head>
4  <meta charset="UTF-8">
5  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
6  <!-- interactive-widget пока понимает только Chromium. WebKit пишет console-warning
7       уже при разборе meta, поэтому расширяем viewport динамически лишь в Chromium.
8       На Safari остаются штатные 100dvh + visualViewport-фолбэки интерфейса. -->
9  
9<script>
10    (function () {
11      var ua = navigator.userAgent || '';
12      var brands = navigator.userAgentData && navigator.userAgentData.brands || [];
13      var chromium = brands.some(function (item) {
14        return /Chromium|Google Chrome|Microsoft Edge|Opera|Samsung Internet/i.test(item.brand || '');
15      }) || /(?:HeadlessChrome|Chrome|Chromium|EdgA?|OPR|SamsungBrowser)\//i.test(ua);
16      var iosWebKitShell = /(?:CriOS|EdgiOS|OPiOS)\//i.test(ua);
17      if (!chromium || iosWebKitShell) return;
18      var viewport = document.querySelector('meta[name="viewport"]');
19      if (viewport) viewport.content += ', interactive-widget=resizes-content';
20    })();
21  </script>
21
22  <!-- Google Analytics 4 (gtag.js). Домены разрешены в CSP (server.js). Заодно
23       служит верификацией сайта в Google Search Console (метод «через Google Аналитику»). -->
vendor: 66 bytes, lines 23-24
23
24  <script async src="https://www.googletagmanager.com/gtag/js?id=
24G-MSW59V95TS
vendor: 14 bytes, lines 24-25
24"></script>
25  
25<script>
26    
vendor: 139 bytes, lines 26-29
26window.dataLayer = window.dataLayer || [];
27    function gtag(){dataLayer.push(arguments);}
28    gtag('js', new Date());
29    gtag('config', '
29G-MSW59V95TS
vendor: 6 bytes, lines 29-30
29');
30  
30</script>
30
31  <meta name="yandex-verification" content="34ee94bded6afa75" />
32  <!-- PWA: установка на экран без магазинов (инструкции — страница #/app) -->
33  <link rel="manifest" href="/manifest.webmanifest">
34  <!-- theme-color задаётся ДИНАМИЧЕСКИ ниже (анти-FOUC скрипт) и при переключении темы
35       (ThemeToggle.toggle) — красит системную плашку/строку под фактическую тему.
36       Значение здесь — фолбэк на случай отключённого JS (тёмный фон боот-экрана). -->
37  <meta name="theme-color" id="theme-color-meta" content="#111817">
38  <!-- Иконки вкладки: .ico для легаси/краулеров (стучат прямо в /favicon.ico),
39       SVG-вектор (браузеры предпочтут его — резкий на любом DPI), PNG-фолбэк 32px.
40       Все три генерит scripts/gen-icons.mjs. -->
41  <link rel="icon" href="/favicon.ico" sizes="32x32">
42  <link rel="icon" type="image/svg+xml" href="/icons/favicon.svg">
43  <link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32.png">
44  <link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">
45  <!-- iOS splash-заставки: убирают белую вспышку при запуске установленного приложения
46       с иконки. iOS требует точного совпадения по размеру устройства; набор — под
47       актуальные iPhone (портрет). Картинки генерит scripts/gen-icons.mjs. -->
48  <link rel="apple-touch-startup-image" media="screen and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/icons/splash-1290x2796.png">
49  <link rel="apple-touch-startup-image" media="screen and (device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/icons/splash-1179x2556.png">
50  <link rel="apple-touch-startup-image" media="screen and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/icons/splash-1284x2778.png">
51  <link rel="apple-touch-startup-image" media="screen and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/icons/splash-1170x2532.png">
52  <link rel="apple-touch-startup-image" media="screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/icons/splash-1125x2436.png">
53  <link rel="apple-touch-startup-image" media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/icons/splash-1242x2688.png">
54  <link rel="apple-touch-startup-image" media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/icons/splash-828x1792.png">
55  <link rel="apple-touch-startup-image" media="screen and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/icons/splash-1242x2208.png">
56  <link rel="apple-touch-startup-image" media="screen and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/icons/splash-750x1334.png">
57  <link rel="apple-touch-startup-image" media="screen and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/icons/splash-640x1136.png">
58  <meta name="mobile-web-app-capable" content="yes">
59  <meta name="apple-mobile-web-app-capable" content="yes">
60  <meta name="apple-mobile-web-app-title" content="Егород">
61  <!-- default (а НЕ black-translucent): контент не заезжает под статус-бар iOS, часы не
62       наезжают на шапку. black-translucent к тому же красил часы белым поверх светлой темы
63       (нечитаемо). Верхний safe-area всё равно подстрахован в CSS (#content на мобиле). -->
64  <meta name="apple-mobile-web-app-status-bar-style" content="default">
65  <!-- Android-оболочки (включая Telegram/системный WebView и некоторые ярлыки на
66       рабочем столе) не всегда честно отдают `display-mode: standalone`. Помечаем
67       платформу ДО загрузки CSS: это позволяет отключить известные проблемные
68       композитные декорации без ожидания основного JS и без вспышки фона. -->
69  
69<script>
70    try {
71      var uaPlatform = navigator.userAgentData && navigator.userAgentData.platform || '';
72      if (/Android/i.test((navigator.userAgent || '') + ' ' + uaPlatform)) {
73        document.documentElement.setAttribute('data-platform', 'android');
74      }
75    } catch (e) { /* без маркера останется обычный безопасный CSS-фолбэк */ }
76  </script>
76
77  <!-- Режим производительности — настройка ЭТОГО устройства. Ставим маркер до CSS,
78       чтобы экономный режим не успевал сначала создать тяжёлые анимации/слои. Значения
79       и эвристика синхронизированы с Utils.resolvePerformanceMode(). -->
80  
80<script>
81    (function () {
82      var mode = 'auto';
83      try {
84        var saved = localStorage.getItem('egor_performance_mode');
85        if (saved === 'auto' || saved === 'full' || saved === 'lite') mode = saved;
86      } catch (e) { /* приватный режим — остаётся Автоматически */ }
87      var android = document.documentElement.dataset.platform === 'android';
88      // deviceMemory/hardwareConcurrency приблизительны и нередко отсутствуют либо
89      // завышены в System WebView. Поэтому безопасный режим — дефолт для Android как
90      // класса compositor; владелец исправного устройства может явно выбрать full.
91      var resolved = mode === 'lite' || (mode === 'auto' && android) ? 'lite' : 'full';
92      document.documentElement.setAttribute('data-performance-mode', mode);
93      document.documentElement.setAttribute('data-performance', resolved);
94    })();
95  </script>
95
96  <!-- Тема (светлая/тёмная) — выставляем атрибут ДО загрузки CSS/скриптов, иначе
97       при перезагрузке страница на миг мигнёт светлой темой (FOUC). Источник
98       истины дублируется в Utils.getTheme() (public/js/utils.js) для переключателя. -->
99  
99<script>
100    (function () {
101      try {
102        var t = localStorage.getItem('egor_theme');
103        if (t !== 'light' && t !== 'dark') {
104          t = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
105        }
106        document.documentElement.setAttribute('data-theme', t);
107        // Системная плашка (Android PWA / строка заголовка десктопного PWA) под тему.
108        // Значения совпадают с --bg светлой (#f0f5f3) и тёмной (#111817) палитр CSS (theme-city.css).
109        var mc = document.getElementById('theme-color-meta');
110        if (mc) mc.setAttribute('content', t === 'dark' ? '#111817' : '#f0f5f3');
111      } catch (e) { /* приватный режим — остаёмся на светлой по умолчанию */ }
112    })();
113  </script>
113
114  <!-- Telegram Mini App SDK: грузим ТОЛЬКО когда страница открыта как Mini App (Telegram
115       передаёт initData маркером tgWebAppData в hash) — чтобы не тянуть telegram.org обычным
116       веб-посетителям. Готовность SDK App._maybeTelegramMiniApp дожидается перед чтением initData. -->
117  
117<script>
118    try {
119      if (/tgWebApp/.test(location.hash) || window.TelegramWebviewProxy) {
120        var tg = document.createElement('script');
121        tg.src = 'https://telegram.org/js/telegram-web-app.js';
122        document.head.appendChild(tg);
123      }
124    } catch (e) { /* не критично — без SDK Mini App просто не активируется */ }
125  </script>
125
126  <!-- Точный литерал title ниже и закрывающий тег head — якоря серверного инжекта
127       OG-мета в /post/:id (server.js). Форму не менять.
128       description ниже — БАЗОВЫЙ фолбэк: renderShell снимает его и ставит per-route
129       свой (ровно один тег). Нужен на случай отдачи index.html в обход renderShell
130       (nginx-статика/офлайн-заглушка SW) — краулер не должен видеть страницу без description. -->
131  <title>Егор Третьяков — слово на Площади Егорода</title>
132  <link rel="preconnect" href="https://fonts.googleapis.com">
133  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
134  <!-- Только реально используемые начертания: Playfair выкинут (не применялся нигде),
135       веса 900 не используются. Меньше render-blocking веса шрифтов → быстрее FCP. -->
136  <link href="https://fonts.googleapis.com/css2?family=Golos+Text:wght@400;500;600;700;800&display=swap" rel="stylesheet">
137  <link rel="stylesheet" href="/css/app.bundle.css?v=3e8458edb032">
138
139  <!-- Yandex.Metrika counter -->
140  
140<script type="text/javascript">
141      (function(m,e,t,r,i,k,a){
142          m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
143          m[i].l=1*new Date();
144          for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
145          k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
146      })(window, document,'script','https://mc.yandex.ru/metrika/tag.js?id=110291079', 'ym');
147
148      ym(110291079, 'init', {ssr:true, webvisor:false, clickmap:true, ecommerce:"dataLayer", referrer: document.referrer, url: location.href, accurateTrackBounce:true, trackLinks:true});
149  </script>
149
150  <noscript><div><img src="https://mc.yandex.ru/watch/110291079" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
151  <!-- /Yandex.Metrika counter -->
152  <!-- Редизайн «Город» (DESIGN.md): оболочка, затем слой токенов — ПОСЛЕДНИМ, поверх всех прежних тем. -->
153<script>window.__EGOR_LOCALE__={"enabled":true,"locale":"ru","site":"egorod"}</script>
153
154<link rel="canonical" href="https://egorod.online/post/19010"><link rel="alternate" type="application/rss+xml" title="Площадь Егород" href="https://egorod.online/feed.xml"><meta name="robots" content="index,follow,max-image-preview:large"><meta name="application-name" content="Егород"><meta property="og:type" content="article"><meta property="og:site_name" content="Егород"><meta property="og:title" content="Егор Третьяков — слово на Площади Егорода"><meta property="og:description" content="Мне хотелось разукрасить доску, которую заставили сделать на трудах (это слишком простой проект для меня) и я решил взять за образ легенду м что-то смешное из мемов..."><meta name="description" content="Мне хотелось разукрасить доску, которую заставили сделать на трудах (это слишком простой проект для меня) и я решил взять за образ легенду м что-то смешное из мемов..."><meta property="og:url" content="https://egorod.online/post/19010"><meta property="og:locale" content="ru_RU"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Егор Третьяков — слово на Площади Егорода"><meta name="twitter:description" content="Мне хотелось разукрасить доску, которую заставили сделать на трудах (это слишком простой проект для меня) и я решил взять за образ легенду м что-то смешное из мемов..."><meta property="og:image" content="https://egorod.online/uploads/posts/cb13fe06-8f49-4384-b6c0-a428a55cf44a.webp"><meta name="twitter:image" content="https://egorod.online/uploads/posts/cb13fe06-8f49-4384-b6c0-a428a55cf44a.webp">
154<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"SocialMediaPosting","headline":"Мне хотелось разукрасить доску, которую заставили сделать на трудах (это слишком простой проект для меня) и я…","articleBody":"Мне хотелось разукрасить доску, которую заставили сделать на трудах (это слишком простой проект для меня) и я решил взять за образ легенду м что-то смешное из мемов...","datePublished":"2026-10-06T07:03:29.000Z","url":"https://egorod.online/post/19010","mainEntityOfPage":"https://egorod.online/post/19010","image":"https://egorod.online/uploads/posts/cb13fe06-8f49-4384-b6c0-a428a55cf44a.webp","author":{"@type":"Person","name":"Егор Третьяков","url":"https://egorod.online/profile/11526"},"publisher":{"@type":"Organization","name":"Егород","logo":{"@type":"ImageObject","url":"https://egorod.online/icons/icon-512.png"}}},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Площадь Егорода","item":"https://egorod.online/"},{"@type":"ListItem","position":2,"name":"Мне хотелось разукрасить доску, которую заставили…","item":"https://egorod.online/post/19010"}]}]}</script>
154</head>
155<body>
156  <a href="#content" class="skip-link" data-shell-i18n="app.skip_to_content" data-shell-en="Skip to content">К содержимому</a>
157
158  <!-- Boot-экран: чистый HTML/CSS (JS ещё не загружен), снимается App._dismissBoot()
159       после первого рендера. Эмблема + вордмарк + индетерминантный прогресс-бар. -->
160  <div id="boot" role="status" aria-label="Егород загружается" data-shell-aria="app.boot_loading" data-shell-aria-en="Egorod is loading">
161    <div class="boot-inner">
162      <div class="boot-emblem">
163        <img src="/brand/emblem.png?v=2" width="60" height="83" alt="" aria-hidden="true" draggable="false" style="object-fit:contain">
164      </div>
165      <div class="boot-word" data-shell-brand>Егород</div>
166      <div class="boot-bar"><span></span></div>
167      <div class="boot-caption" data-shell-i18n="app.boot_caption" data-shell-en="The Chancellery is preparing your presence…">Канцелярия готовит присутствие…</div>
168    </div>
169  </div>
170
171  <!-- Верхняя панель (DESIGN.md §4.1) — рисует Topbar из Sidebar.render. -->
172  <header id="topbar" class="topbar"></header>
173
174  <div id="app">
175    <div id="sidebar"></div>
176    <div id="main">
177      <div id="content" role="main" aria-label="Основное содержимое" tabindex="-1"><article><h1>Егор Третьяков — слово на Площади Егорода</h1><p><img src="https://egorod.online/uploads/posts/cb13fe06-8f49-4384-b6c0-a428a55cf44a.webp" alt="Иллюстрация к слову: Мне хотелось разукрасить доску, которую заставили сделать н…" loading="lazy"></p><div>Мне хотелось разукрасить доску, которую заставили сделать на трудах (это слишком простой проект для меня) и я решил взять за образ легенду м что-то смешное из мемов...</div><p>Автор: <a href="/profile/11526">Егор Третьяков</a></p><nav><a href="/">Площадь Егорода</a></nav></article></div>
178      <!-- Общий подвал (DESIGN.md): правовые ссылки, канал и © — внизу по центру страницы. -->
179      <footer id="site-footer" class="site-footer"></footer>
180    </div>
181    <div id="right-panel"></div>
182  </div>
183
184  <div id="modal-overlay" class="modal-overlay hidden"></div>
185  <div id="modal-container"></div>
186
187  <!-- aria-live: тосты — главный канал фидбека (успех/ошибка действия). Контейнер
188       вежливо озвучивает добавленные узлы; узлы-ошибки повышаются до role="alert"
189       (ассертивно) в Utils.showToast. -->
190  <div id="toast-container" aria-live="polite" aria-atomic="false"></div>
191
192  <!-- Баннер потери связи: показывается классом .visible из SocketClient при разрыве
193       Socket.io и прячется при восстановлении. Чтобы Беседы/Огород не «замирали» молча. -->
194  <div id="connection-banner" role="status" aria-live="polite">
195    <span class="connection-banner-dot"></span>
196    <span data-connection-text data-shell-i18n="connection.lost" data-shell-en="Connection to the Chancellery was lost. Reconnecting…">Связь с Канцелярией прервана. Восстанавливаем…</span>
197  </div>
198
199  <!-- defer: скрипты грузятся параллельно, исполняются по порядку после парса DOM
200       (быстрее первый рендер на холодном кэше/мобильных). App.init() в app.js
201       срабатывает последним, когда DOM уже разобран. -->
202  
202<script defer src="/socket.io/socket.io.js"></script>
202
203  
203<script defer src="/js/app.bundle.js?v=3e8458edb032"></script>
203
204  <!-- Плавающий виджет Бесед: в dev идёт после всего chats-чанка; в production
205       оболочка остаётся в ядре, список доставляется по первому открытию, а полный
206       ChatsPage — только при выборе конкретной беседы. -->
207  <!-- В dev UsersPage объявляется до App; методы обращаются к App только после App.init().
208       В production файл исключается из ядра и доставляется маршрутами Народа/Кварталов. -->
209  <!-- channels/videos/games — вне MVP-скоупа, не подключаем: содержат неэкранированные
210       URL-поля (XSS), недостижимы из UI. Вернуть со страницы вместе с фиксом safeUrl. -->
211</body>
212</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.