<?xml version="1.0" encoding="utf-8"?>
<!-- 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
-->
<?xml-stylesheet type="text/xsl" href="https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/roller-ui/styles/rss.xsl" media="screen"?><rss version="2.0" 
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:atom="http://www.w3.org/2005/Atom" >
<channel>
  <title>aary</title>
  <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/</link>
    <atom:link rel="self" type="application/rss+xml" href="https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/feed/entries/rss?cat=%D0%96%D0%96" />
  <description></description>
  <language>en-us</language>
  <copyright>Copyright 2026</copyright>
  <lastBuildDate>Sun, 4 Oct 2026 18:27:51 +0000</lastBuildDate>
  <generator>Apache Roller 6.1.5</generator>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/keycloak</guid>
    <title>KeyCloak</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/keycloak</link>
    <pubDate>Sun, 4 Oct 2026 18:27:51 +0000</pubDate>
    <category>ЖЖ</category>
    <category>oidc</category>
<description>Установил KeyCloak. Говорят, что к нему можно подключить Gitlab. Надо подумать, что ещё можно подключить.</description>  </item>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%B1%D0%B0%D0%B1%D0%B0-%D0%B2%D0%B0%D0%BB%D1%8F-%D1%83%D0%BF%D0%BE%D1%80%D0%BE%D0%BB%D0%B0%D1%81%D1%82%D1%8C</guid>
    <title>Баба Валя упороласть...</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%B1%D0%B0%D0%B1%D0%B0-%D0%B2%D0%B0%D0%BB%D1%8F-%D1%83%D0%BF%D0%BE%D1%80%D0%BE%D0%BB%D0%B0%D1%81%D1%82%D1%8C</link>
    <pubDate>Sun, 27 Sep 2026 18:08:25 +0000</pubDate>
    <category>ЖЖ</category>
    <category>absnobalance</category>
<description>&lt;h1&gt;Сценарии, планы и их реализации&lt;/h1&gt;

&lt;h2&gt;Оглавление&lt;/h2&gt;

&lt;h3&gt;Основной текст&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Введение&lt;/li&gt;
&lt;li&gt;Два уровня выработки истины&lt;/li&gt;
&lt;li&gt;Гипотезы и сценарии&lt;/li&gt;
&lt;li&gt;Этап&lt;/li&gt;
&lt;li&gt;Действия&lt;/li&gt;
&lt;li&gt;Как это связано&lt;/li&gt;
&lt;li&gt;Параллельные действия&lt;/li&gt;
&lt;li&gt;Зачем это нужно&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Приложения&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Приложение 1. Термины действительности (игры)&lt;/li&gt;
&lt;li&gt;Приложение 2. Термины программы моделирования/симуляции&lt;/li&gt;
&lt;li&gt;Приложение 3. Сравнение и финалы&lt;/li&gt;
&lt;li&gt;Приложение 4. Как человек организует выбор варианта стратегии&lt;/li&gt;
&lt;li&gt;Приложение 5. Работа АВТ&lt;/li&gt;
&lt;li&gt;Приложение 6. Формализация АВТ в псевдокоде&lt;/li&gt;
&lt;li&gt;Приложение 7. Состояние модели&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h2 id=&quot;vvedenie&quot;&gt;Введение&lt;/h2&gt;
&lt;p&gt;Задача — выработать истину: набор правильных гипотез и соответствующих истине стратегии и тактики. Стратегия одна. Человек прорабатывает варианты стратегии заранее и записывает в виде сценариев. Человек создаёт несколько сценариев, потому что человек хочет сравнить разные гипотетические варианты стратегии между собой.&lt;/p&gt;
&lt;p&gt;Исходное описание действительности заранее прописывается человеком как состояние модели.&lt;/p&gt;

&lt;h2 id=&quot;dva-urovnya&quot;&gt;Два уровня выработки истины&lt;/h2&gt;
&lt;p&gt;Существуют два уровня выработки истины: стратегический и тактический.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Стратегический уровень&lt;/strong&gt; — уровень разума человека и помогающего человеку вырабатывать стратегию алгоритма.&lt;/p&gt;
&lt;p&gt;РЧ вырабатывает стратегию, для чего РЧ формирует стратегические гипотезы и создаёт сценарии для проверки стратегических гипотез. Стратегическая гипотеза, которая ведёт к выигрышной стратегии — правильная. Стратегическая гипотеза, которая ведёт к проигрышной стратегии — неправильная. Сценарий — продукт РЧ. Сценарий состоит из этапов.&lt;/p&gt;
&lt;p&gt;ПЧВСА помогает человеку обрабатывать сценарии, для чего ПЧВСА создаёт результаты этапов. ПЧВСА обрабатывает сценарии по этапам. ПЧВСА заказывает план у АВТ. ПЧВСА инициирует работу АВТ.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Тактический уровень&lt;/strong&gt; — уровень алгоритма выработки тактики для реализации этапа стратегии.&lt;/p&gt;
&lt;p&gt;АВТ создаёт планы — важно, как именно (это надо запрограммировать), потому что АВТ нужно сравнить планы между собой и выбрать лучший. План — последовательность моделируемых действий. АВТ вырабатывает тактику для этапа (ПЧВСА решает, для какого — для любого, для каждого, для указанного). АВТ создаёт всё: миры, граф, планы.&lt;/p&gt;
&lt;p&gt;Человек проверяет стратегические гипотезы. АВТ проверяет тактические гипотезы.&lt;/p&gt;
&lt;p&gt;Сценарий — это не стратегия. План — это не тактика.&lt;/p&gt;

&lt;h2 id=&quot;gipotezy-i-scenarii&quot;&gt;Гипотезы и сценарии&lt;/h2&gt;
&lt;p&gt;Пример стратегических гипотез.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Стратегическая гипотеза 0:&lt;/strong&gt; квест лучше выполнять, чем не выполнять.&lt;br&gt;
&lt;strong&gt;Антигипотеза 0:&lt;/strong&gt; квест лучше не выполнять.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Стратегическая гипотеза 1:&lt;/strong&gt; выполнять квест раньше — выгоднее, чем позже.&lt;br&gt;
&lt;strong&gt;Антигипотеза 1:&lt;/strong&gt; выполнять квест позже — выгоднее, чем раньше.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Стратегическая гипотеза 2:&lt;/strong&gt; два завода.&lt;br&gt;
&lt;strong&gt;Антигипотеза 2:&lt;/strong&gt; один завод.&lt;/p&gt;
&lt;p&gt;Стратегическая гипотеза 1 связана с гипотезой о минимизации момента получения бонуса. Стратегическая гипотеза 2 тоже связана с гипотезой о минимизации момента получения бонуса. Обе гипотезы связаны с гипотезой получения бонуса. Два завода быстрее вырабатывают топливо и уменьшают время до получения бонуса. Один завод медленнее вырабатывает топливо и увеличивает время до получения бонуса.&lt;/p&gt;
&lt;p&gt;Сценарии образуются из гипотез так: по каждой гипотезе берётся либо гипотеза, либо антигипотеза. Не все комбинации дают разные сценарии. Комбинации, которые дают одинаковые сценарии, сворачиваются в один. Например, если квест не выполняется, то не важно, один или два завода, и не важно, раньше или позже. Все такие комбинации дают один сценарий.&lt;/p&gt;
&lt;p&gt;Антигипотеза 0 сворачивает и отсекает три сценария как невозможные. Если квест не выполняем, не важно — один или два завода, и не важно — раньше или позже. Поэтому всего сценариев пять, а не восемь:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Квест не выполняем.&lt;/strong&gt;
&lt;ul&gt;&lt;li&gt;Этап 1: домики.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Два завода, потом домики.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Этап 1: первый завод, второй завод, домики.&lt;/li&gt;
&lt;li&gt;Этап 2: второй завод, домики.&lt;/li&gt;
&lt;li&gt;Этап 3: домики.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Один завод, потом домики.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Этап 1: один завод, домики.&lt;/li&gt;
&lt;li&gt;Этап 2: домики.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Домики, потом два завода.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Этап 1: домики, первый завод, второй завод.&lt;/li&gt;
&lt;li&gt;Этап 2: первый завод, второй завод, домики.&lt;/li&gt;
&lt;li&gt;Этап 3: второй завод, домики.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Домики, потом один завод.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Этап 1: домики, один завод.&lt;/li&gt;
&lt;li&gt;Этап 2: один завод, домики.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Промежуточные варианты (не раньше и не позже) не рассматриваются — это упрощение.&lt;/p&gt;
&lt;p&gt;Два завода сразу не построить — не хватит ресурсов. Заводы строятся поштучно. Между первым и вторым заводом проходит время. В это время можно строить домики. Возникает вариант: первый завод, домики, второй завод. Этот вариант не рассматривается, потому что он не оптимален ни по одному критерию: он хуже, чем «два завода, потом домики» (бонус позже), и хуже, чем «домики, потом два завода» (домики позже).&lt;/p&gt;

&lt;h2 id=&quot;etap&quot;&gt;Этап&lt;/h2&gt;
&lt;p&gt;Этап — это цели и приоритеты. Этап может иметь несколько целей. Цели приоритезированы: первая цель более важная, затем следующая цель и так далее. Только первую цель этапа обязательно нужно достичь — это условие завершения этапа.&lt;/p&gt;
&lt;p&gt;Пример этапа: «строительство завода» — построить завод, строить домики. Строительство завода и накопление ресурсов для строительства завода — приоритетнее, потому что строительство завода и накопление ресурсов указаны первой целью.&lt;/p&gt;
&lt;p&gt;Человек не пишет в сценарии мелкие моделируемые действия вроде «подождать». Это уровень АВТ.&lt;/p&gt;

&lt;h2 id=&quot;dejstviya&quot;&gt;Действия&lt;/h2&gt;
&lt;p&gt;Моделируемые действия мгновенные: они не занимают игрового времени и не продвигают его. Мгновение не путать с тактом, имеющим переменную длительность. Исключение — моделируемое действие «подождать»: оно не мгновенное, а продвигает игровое время на К тактов. «Подождать» входит в число моделируемых действий.&lt;/p&gt;
&lt;p&gt;Моделируемое действие — элементарная операция плана: обменять труд на сталь, построить домик, забрать бонус, подождать.&lt;/p&gt;

&lt;h2 id=&quot;kak-svyazano&quot;&gt;Как это связано&lt;/h2&gt;
&lt;p&gt;РЧ создаёт сценарии. ПЧВСА по сценарию порождает результаты этапов. Реализация сценария — совокупность результатов этапов. Один сценарий — одна реализация сценария.&lt;/p&gt;
&lt;p&gt;АВТ вырабатывает тактику для этапа. АВТ создаёт план для этапа. АВТ создаёт миры, граф и планы. План — путь в графе миров. Миры входят в планы.&lt;/p&gt;
&lt;p&gt;ПЧВСА создаёт результаты этапов. Реализация сценария хранит результаты этапов. Результаты этапов знают тактики своего этапа.&lt;/p&gt;
&lt;p&gt;Реализация сценария → результаты этапов → моделируемые действия (граф) + миры.&lt;/p&gt;
&lt;p&gt;Реализация сценария знает результат последнего этапа, для знания имеет указатель (кеш).&lt;/p&gt;
&lt;p&gt;Результат этапа знает наилучший план, для знания имеет указатель (кеш). План — маршрут в направленном ациклическом графе (НАГ).&lt;/p&gt;

&lt;h2 id=&quot;parallelnye&quot;&gt;Параллельные действия&lt;/h2&gt;
&lt;p&gt;Моделируемые действия могут выполняться параллельно. Например, во время выполнения квеста можно строить домики. Это возможно, если позволяют ресурсы и труд. Если труд уходит на энергию и топливо, домики не строятся. Если труда много — часть труда идёт на квест, часть труда на домики, — если так написано в сценарии. Может быть написано, что лишний труд надо тратить на науку или на добычу стали.&lt;/p&gt;
&lt;p&gt;Если параллельно делать нельзя, делаем то, что ведёт к достижению цели, потому что в случае невозможности параллельности приоритеты не нужны.&lt;/p&gt;

&lt;h2 id=&quot;zachem&quot;&gt;Зачем это нужно&lt;/h2&gt;
&lt;p&gt;Разделение на уровни позволяет отделить то, что задаёт человек, от того, что вычисляют алгоритмы. РЧ задаёт сценарий. АВТ ищет лучший план. ПЧВСА помогает человеку обрабатывать сценарии.&lt;/p&gt;
&lt;p&gt;Разделение на реализации сценариев и миры позволяет организовать сравнение. ПЧВСА сравнивает миры внутри реализации сценария, чтобы найти лучший мир. ПЧВСА принимает уже готовый лучший мир от каждой реализации сценария и сравнивает их между собой. ПЧВСА принимает состояние модели из лучшего мира.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;prilozhenie-1&quot;&gt;Приложение 1. Термины действительности (игры)&lt;/h2&gt;

&lt;p&gt;Термины упорядочены так, чтобы каждый термин ссылался только на определённые ранее.&lt;/p&gt;

&lt;h3 id=&quot;dejstvitelnost&quot;&gt;Действительность&lt;/h3&gt;
&lt;p&gt;Действительность — исходное описание. Действительность отражена в программе (человеком) в виде исходного состояния модели. Исходное состояние модели — одно, глобальное, неизменяемое.&lt;/p&gt;

&lt;h3 id=&quot;sostoyanie-dejstvitelnosti&quot;&gt;Состояние действительности&lt;/h3&gt;
&lt;p&gt;Состояние действительности — набор строений, накопления на складе, запасы в строениях. Всё целые числа.&lt;/p&gt;

&lt;h3 id=&quot;rch&quot;&gt;РЧ&lt;/h3&gt;
&lt;p&gt;РЧ — разум человека.&lt;/p&gt;

&lt;h3 id=&quot;igrovoj-period&quot;&gt;Игровой период&lt;/h3&gt;
&lt;p&gt;Игровой период — 6 часов игрового времени. Далее используется формулировка «игровой период (6 часов)». Игровой период — фиксированная величина. Игровой период не зависит от населения. Игровое время считается в игровых периодах, не в тактах. За 1 игровой период всё население даёт весь труд этого периода. 1 такт = 1 игровой период / (население / 1 млн). Население — целое число (млн жителей). Длительность такта — вещественная. Округлять её не нужно. Такт пересчитывается при изменении населения. В действительности население меняется при постройке домика и при бомбардировке. В модели население меняется только при постройке домика. Это происходит в момент моделируемого действия, не во время «подождать». Значит, на протяжении одного «подождать» длительность такта постоянна. После постройки домика длительность такта уменьшается, потому что население выросло. За 1 такт труд прирастает на 1. Неизвестно, какой именно миллион жителей даёт этот 1 труд — это условность. «Подождать» продвигает время на К тактов.&lt;/p&gt;

&lt;h3 id=&quot;realnoe-dejstvie&quot;&gt;Реальное действие&lt;/h3&gt;
&lt;p&gt;Реальное действие — действие, совершаемое в действительности. Занимает реальное время. Гипотетически есть, но мы о них не говорим. Термин нужен для понимания человеком. См. раздел «О терминах, абстрагирующих другие термины».&lt;/p&gt;

&lt;h3 id=&quot;bombardirovka&quot;&gt;Бомбардировка&lt;/h3&gt;
&lt;p&gt;Бомбардировка — событие в действительности. Бомбардировка разрушает строения: домики, заводы, электростанции, шахты, заводы ракетного топлива. Бомбардировка уменьшает население. В текущей модели не учитывается.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;prilozhenie-2&quot;&gt;Приложение 2. Термины программы моделирования/симуляции&lt;/h2&gt;

&lt;p&gt;Термины упорядочены так, чтобы каждый термин ссылался только на определённые ранее.&lt;/p&gt;

&lt;h3&gt;О терминах, абстрагирующих другие термины&lt;/h3&gt;

&lt;p&gt;В этом приложении есть три термина, которые не описывают отдельные сущности, а абстрагируют по два других термина. Это «Действие», «Финал» и «Гипотеза».&lt;/p&gt;

&lt;p&gt;Моделирующая система сложна: она описывает и действительность, и модель, и разные уровни планирования. Одни и те же понятия на разных уровнях имеют разный смысл. Например, действие в действительности и действие в модели — не одно и то же. Финал сценария и финал плана — не одно и то же. Гипотеза о стратегии и гипотеза о тактике — не одно и то же.&lt;/p&gt;

&lt;p&gt;Чтобы не смешивать эти разные смыслы, вводятся абстрагирующие термины. Они нужны для понимания человеком. Если удалить абстрагирующий термин, возникнет вопрос, почему конкретный термин называется именно так, а не иначе, и чем он отличается от другого конкретного термина.&lt;/p&gt;

&lt;p&gt;Абстрагирующие термины не заменяются конкретными в тексте определений. Если заменить абстрактный термин на конкретный там, где он абстрагирует два других, получится либо круг, либо бессмыслица. Например: «Моделируемое действие — конкретизация абстракции „Моделируемое действие“» — бессмыслица. «Стратегический финал — термин, абстрагирующий два других: стратегический финал и тактический финал» — круг.&lt;/p&gt;

&lt;p&gt;Поэтому абстрагирующие термины остаются в тексте и используются там, где нужно говорить о двух конкретных терминах вместе или где нужно показать их общую природу.&lt;/p&gt;

&lt;p&gt;Если абстрагирующий термин сейчас нигде не используется, его всё равно нужно оставить на будущее. Возможность его использования есть. В любой момент может появиться место, где потребуется сказать о двух конкретных терминах вместе. Без абстрагирующего термина придётся либо вводить его заново, либо переписывать определения. И то, и другое хуже, чем оставить термин в тексте заранее.&lt;/p&gt;

&lt;h3 id=&quot;sostoyanie-modeli&quot;&gt;Состояние модели&lt;/h3&gt;
&lt;p&gt;Состояние модели — представление состояния действительности в программе. Набор строений, накопления на складе, запасы в строениях. Всё целые числа. К запасам в строениях прилагается буфер дробной части: он хранит дробную часть прироста, которая ещё не стала целой единицей. Буфер вещественный. Если такое состояние модели уже существует — АВТ не создаёт его, а переиспользует. Флагов в состоянии модели нет: флаги — артефакты алгоритма, они хранятся в мире.&lt;/p&gt;

&lt;h3 id=&quot;gipoteza&quot;&gt;Гипотеза&lt;/h3&gt;
&lt;p&gt;Гипотеза — термин, абстрагирующий два других: стратегическую гипотезу и тактическую гипотезу.&lt;/p&gt;
&lt;p&gt;Термин нужен для понимания человеком. См. раздел «О терминах, абстрагирующих другие термины».&lt;/p&gt;
&lt;p&gt;Сам термин «гипотеза» используется в двух местах:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;В термине «Истина»: истина — набор правильных гипотез, стратегии и тактики. Здесь имеются в виду и стратегические, и тактические гипотезы вместе.&lt;/li&gt;
&lt;li&gt;В термине «Кеширование гипотез»: механизм общий для человека и АВТ. Кешируются и стратегические, и тактические гипотезы. Абстрактный термин позволяет говорить о них вместе.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;strategicheskaya-gipoteza&quot;&gt;Стратегическая гипотеза&lt;/h3&gt;
&lt;p&gt;Стратегическая гипотеза — утверждение о выгодности варианта стратегии. Антигипотеза — противоположное утверждение. Стратегическая гипотеза формулируется РЧ. Стратегическая гипотеза, которая ведёт к выигрышной стратегии — правильная. Стратегическая гипотеза, которая ведёт к проигрышной стратегии — неправильная.&lt;/p&gt;

&lt;h3 id=&quot;takticheskaya-gipoteza&quot;&gt;Тактическая гипотеза&lt;/h3&gt;
&lt;p&gt;Тактическая гипотеза — утверждение о выгодности варианта способа превращения цели в моделируемые действия. Антигипотеза — противоположное утверждение. Тактическая гипотеза формулируется АВТ. Тактическая гипотеза, которая ведёт к выигрышной тактике — правильная. Тактическая гипотеза, которая ведёт к проигрышной тактике — неправильная.&lt;/p&gt;

&lt;h3 id=&quot;istina&quot;&gt;Истина&lt;/h3&gt;
&lt;p&gt;Истина — набор правильных гипотез, стратегии и тактики. Правильная гипотеза — та, которая ведёт к лучшему результату по критерию сравнения. Стратегия — победитель сравнения сценариев. Тактика — победитель сравнения планов.&lt;/p&gt;

&lt;h3 id=&quot;strategiya&quot;&gt;Стратегия&lt;/h3&gt;
&lt;p&gt;Стратегия — вариант действий, который ведёт к лучшему результату по критерию сравнения. Стратегия одна для действительности.&lt;/p&gt;

&lt;h3 id=&quot;taktika&quot;&gt;Тактика&lt;/h3&gt;
&lt;p&gt;Тактика — лучший вариант реализации этапа стратегии. Из планов выбираем лучший по результатам сравнения. Тактика одна для этапа.&lt;/p&gt;

&lt;h3 id=&quot;cel&quot;&gt;Цель&lt;/h3&gt;
&lt;p&gt;Цель — то, что должно быть достигнуто на этапе. Цель формулируется человеком в сценарии.&lt;/p&gt;

&lt;h3 id=&quot;prioritet&quot;&gt;Приоритет&lt;/h3&gt;
&lt;p&gt;Приоритет — указание, какая цель важнее, если целей несколько. Приоритет формулируется человеком в сценарии.&lt;/p&gt;

&lt;h3 id=&quot;etap&quot;&gt;Этап&lt;/h3&gt;
&lt;p&gt;Этап — цели и приоритеты. Этап может иметь несколько целей. Цели приоритезированы. Только первая цель этапа обязательно должна быть достигнута — это условие завершения этапа. Этап состоит из целей и приоритетов и владеет ими.&lt;/p&gt;
&lt;p&gt;Исключение — последний этап. У последнего этапа есть цель (строить домики), но условие завершения этапа внешнее: не «построить определённое число домиков», а условие остановки симуляции. Последний этап завершается, когда все миры достигли стратегического финала. АВТ планирует для последнего этапа так же, как для остальных: строит планы, сравнивает, выбирает лучший. Разница только в том, что тактический финал последнего этапа совпадает со стратегическим финалом — то есть с условием остановки симуляции.&lt;/p&gt;
&lt;p&gt;Последняя цель — та, что в списке целей этапа идёт последней (не пустая). Приоритет определяет порядок достижения. После достижения последней цели этапа сценарий продолжает выполнять последнюю цель до конца симуляции. Если последняя цель — «построить завод», а завод уже построен, сценарий строит домики, если есть ресурсы; иначе ждёт.&lt;/p&gt;

&lt;h3 id=&quot;scenarij&quot;&gt;Сценарий&lt;/h3&gt;
&lt;p&gt;Сценарий — продукт РЧ. Сценарий — цепочка этапов. Человек создаёт сценарий, потому что человек хочет сравнить разные гипотетические варианты стратегии между собой. Стратегия одна, и человек прорабатывает стратегию заранее. Сценарий состоит из этапов и владеет ими.&lt;/p&gt;
&lt;p&gt;Сценарий недействителен, если не может достичь стратегического финала. Недействительный сценарий не участвует в сравнении. Если все сценарии недействительны, человек должен пересмотреть сценарии или гипотезы.&lt;/p&gt;

&lt;h3 id=&quot;final&quot;&gt;Финал&lt;/h3&gt;
&lt;p&gt;Финал — термин, абстрагирующий два других: стратегический финал и тактический финал.&lt;/p&gt;
&lt;p&gt;Термин нужен для понимания человеком. См. раздел «О терминах, абстрагирующих другие термины».&lt;/p&gt;

&lt;h3 id=&quot;strategicheskij-final&quot;&gt;Стратегический финал&lt;/h3&gt;
&lt;p&gt;Стратегический финал — условие завершения сценария. Стратегический финал — два условия одновременно: флаг из_руды, домик построен. Домик построен — на последнем этапе построен хотя бы один домик. Снос домиков в модели не рассматривается. Поэтому условие равносильно: счётчик домиков, построенных на текущем этапе, больше нуля. Последний этап определяется проверкой: текущий этап == Последний_этап(Сценарий). Отдельный флаг последний_шаг не нужен. Флаг из_руды и текущий этап — артефакты алгоритма, хранятся в мире, не в состоянии модели.&lt;/p&gt;
&lt;p&gt;Флаг из_руды — признак того, что склад опустел по стали, товарам, энергии и труду. Топливо, КР и наука не входят в проверку: топливо — цель квеста, не тратится на домики; КР и наука в текущей модели не используются для покупки ресурсов и исследований. Эти ресурсы не влияют на строительство домиков.&lt;/p&gt;
&lt;p&gt;Склад может опустеть по труду: труд тратится на обмены, и после действия труд может быть равен нулю. Отдельного «строительства из руды» нет: строительство всегда идёт со склада, ресурсы сначала попадают на склад, потом тратятся. Флаг из_руды отмечает момент, когда запасы стали, товаров, энергии и труда на складе исчерпались на последнем этапе сценария. Флаг сбрасывается при получении бонуса: бонус пополняет склад, и запасы снова становятся непустыми. Флаг устанавливается снова, когда склад опять опустеет. К моменту финала флаг установлен — значит, склад опустел и больше не пополняется бонусом.&lt;/p&gt;
&lt;p&gt;Как условие стратегического финала флаг из_руды означает: к моменту финала сценарий исчерпал запасы стали, товаров, энергии и труда, накопленные изначально или полученные бонусом. После этого момента дальнейшее продолжение не добавляет различий между сценариями: поведение одинаково. Сравниваются различия в населении и количестве моделируемых действий, накопленные к этому моменту. Именно поэтому флаг из_руды — условие финала: он отмечает точку, после которой сценарии перестают различаться дальнейшим поведением, и сравнение возможно только по накопленному.&lt;/p&gt;

&lt;h3 id=&quot;takticheskij-final&quot;&gt;Тактический финал&lt;/h3&gt;
&lt;p&gt;Тактический финал — условие завершения плана. Тактический финал — цель этапа достигнута. План считается завершённым, когда цель этапа достигнута. Для последнего этапа тактический финал совпадает со стратегическим финалом.&lt;/p&gt;

&lt;h3 id=&quot;dejstvie&quot;&gt;Действие&lt;/h3&gt;
&lt;p&gt;Действие — абстракция. То, что изменяет состояние или продвигает время. Большинство моделируемых действий мгновенные: изменяют состояние, но не продвигают время. «Подождать» — не мгновенное: продвигает время. Только Приложение 2.&lt;/p&gt;
&lt;p&gt;Термин нужен для понимания человеком. См. раздел «О терминах, абстрагирующих другие термины».&lt;/p&gt;

&lt;h3 id=&quot;modeliruemoe-dejstvie&quot;&gt;Моделируемое действие&lt;/h3&gt;
&lt;p&gt;Моделируемое действие — конкретизация абстракции «Действие». Создаётся программой. Моделируемые действия делятся на два вида:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Мгновенные. Большинство действий. Не продвигают время и не занимают такты.&lt;/li&gt;
&lt;li&gt;«Подождать». Не мгновенное. Продвигает время на К тактов, где К — параметр моделируемого действия.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Параметр «подождать» задаётся в тактах, потому что труд дискретизирован в тактах: за 1 такт начисляется 1 труд. Запасы в строениях при этом накапливаются за игровые периоды: K тактов = K × длительность_такта игровых периодов. Моделируемым действием при сравнении считается только то, что изменило состояние. Если ресурсы закончились — ждать. Если ресурсы не могут появиться — сценарий недействителен. Ресурсы не могут появиться, если население равно нулю: тогда труд не производится, обмены невозможны, ресурсы не восстанавливаются. В текущей модели население не умирает, поэтому эта проверка не срабатывает.&lt;/p&gt;

&lt;h3 id=&quot;takt&quot;&gt;Такт&lt;/h3&gt;
&lt;p&gt;Такт — часть игрового периода, зависящая от населения. 1 такт = 1 игровой период / (население / 1 млн).&lt;/p&gt;
&lt;p&gt;Население — целое число (млн жителей). Население_млн — целое (550, 551 и так далее). Длительность такта — вещественная (1/550, 1/551 и так далее). Округлять длительность такта не нужно: она используется только для перевода тактов в игровое время при обновлении запасов.&lt;/p&gt;
&lt;p&gt;Такт нужен только для дискретизации труда: за 1 такт прибавляется 1 труд целым числом. За К тактов прибавляется К труда. Всё остальное (запасы в строениях, игровое время, длительность этапа) считается в игровых периодах, не в тактах. Непрерывное начисление труда привело бы к дробным значениям, что усложнило бы учёт и округление.&lt;/p&gt;
&lt;p&gt;Такт пересчитывается при изменении населения. В модели население меняется только при постройке домика. Это происходит в момент моделируемого действия, не во время «подождать». Значит, на протяжении одного «подождать» длительность такта постоянна. После постройки домика длительность такта уменьшается, потому что население выросло. За 1 такт труд прирастает на 1. «Подождать» продвигает время на К тактов. Население разное в разных мирах. Как следствие — длительность такта разная в разных реализациях сценария (в реализации сценария есть оптимальный мир).&lt;/p&gt;

&lt;h3 id=&quot;mir&quot;&gt;Мир&lt;/h3&gt;
&lt;p&gt;Мир — отличается от другого мира одним моделируемым действием, и этим же действием миры присоединяются к графу. Начальному состоянию модели соответствует нулевой мир. В нулевом мире задаётся начальное реальное время. Мир отличается от нулевого мира планом (путём из моделируемых действий). Мир ссылается на состояние модели.&lt;/p&gt;
&lt;p&gt;Мир всегда новый. Состояние модели может переиспользоваться.&lt;/p&gt;
&lt;p&gt;В мире хранятся артефакты алгоритма: флаг из_руды, количество домиков, построенных на текущем этапе, текущий этап, длительность такта. Флаги — артефакты алгоритма, они не входят в состояние модели, потому что в действительности их нет.&lt;/p&gt;

&lt;h3 id=&quot;plan&quot;&gt;План&lt;/h3&gt;
&lt;p&gt;План — последовательность моделируемых действий. План — маршрут в направленном ациклическом графе (НАГ). План — путь в графе миров. План содержит моделируемые действия и ссылается на миры. План соотносится со сценарием так же, как тактика со стратегией.&lt;/p&gt;

&lt;h3 id=&quot;realizaciya-plana&quot;&gt;Реализация плана&lt;/h3&gt;
&lt;p&gt;Реализация плана — миры одного маршрута (одного плана) и моделируемые действия между ними. Реализация плана не хранится, а выводится, используя имеющуюся информацию, если это потребуется. Выводится она для любого плана, если возникнет потребность. Хранится только тактика — лучший план. Реализация лучшего плана выводится из графа и маршрута лучшего плана.&lt;/p&gt;

&lt;h3 id=&quot;graf-modeliruemyh-dejstvij&quot;&gt;Граф моделируемых действий&lt;/h3&gt;
&lt;p&gt;Граф моделируемых действий — структура, связывающая моделируемые действия. Как следствие — связывающая миры. АВТ создаёт новые состояния модели и новые миры. Из одного состояния можно совершить разные моделируемые действия. Каждое моделируемое действие ведёт в новое состояние. Граф направленный ациклический (НАГ). Циклов нет: снос домика не возвращает ресурсы (ресурсы теряются), значит вернуться в прошлое состояние нельзя. Граф владеет моделируемыми действиями (рёбрами), использует миры (узлы).&lt;/p&gt;

&lt;h3 id=&quot;avt&quot;&gt;АВТ&lt;/h3&gt;
&lt;p&gt;АВТ — алгоритм выработки тактики для реализации этапа стратегии. АВТ создаёт всё: миры, граф, планы, состояния модели. Если такое состояние модели уже существует — АВТ не создаёт его, а переиспользует. АВТ создаёт планы — важно, как именно (это надо запрограммировать), потому что АВТ нужно сравнить планы между собой и выбрать лучший. АВТ вырабатывает тактику для этапа (ПЧВСА решает, для какого — для любого, для каждого, для указанного).&lt;/p&gt;
&lt;p&gt;АВТ порождает все перестановки моделируемых действий внутри цели. АВТ отсекает ветки, которые не ведут к цели. Эвристики для отсечения: эвристика 1 (независимые моделируемые действия) и эвристика 3 (блокирующее раньше).&lt;/p&gt;

&lt;h3 id=&quot;pchvsa&quot;&gt;ПЧВСА&lt;/h3&gt;
&lt;p&gt;ПЧВСА — помогающий человеку вырабатывать стратегию алгоритм. ПЧВСА помогает человеку обрабатывать сценарии, для чего ПЧВСА создаёт результаты этапов. Результат этапа — следствие обработки сценария при помощи ПЧВСА и часть реализации сценария. ПЧВСА обрабатывает сценарии по этапам. Чтобы подобрать тактику на сценарии, ПЧВСА должен подобрать тактики на каждом этапе. ПЧВСА заказывает план у АВТ. ПЧВСА инициирует работу АВТ.&lt;/p&gt;

&lt;h3 id=&quot;rezultat-etapa&quot;&gt;Результат этапа&lt;/h3&gt;
&lt;p&gt;Результат этапа знает тактику своего этапа (как кеш). Тактика — лучший план для этого этапа. Результат этапа знает результаты применения тактики (тоже как кеш). Результат этапа — на момент окончания этапа. Результат этапа владеет графом моделируемых действий и мирами. План — маршрут в направленном ациклическом графе (НАГ). Реализация плана для лучшего плана выводится из графа и маршрута лучшего плана по запросу.&lt;/p&gt;

&lt;h3 id=&quot;realizaciya-scenariya&quot;&gt;Реализация сценария&lt;/h3&gt;
&lt;p&gt;Реализация сценария — совокупность результатов этапов. Реализация сценария содержит результаты всех этапов сценария, не только последнего. Реализация сценария указывает на сценарий — исходный сценарий, из которого построена эта реализация. Реализация сценария знает результат последнего этапа, для знания имеет указатель (кеш).&lt;/p&gt;
&lt;p&gt;Реализацию сценария можно построить по сценарию. Реализацию сценария строит ПЧВСА.&lt;/p&gt;

&lt;h3 id=&quot;sravnenie&quot;&gt;Сравнение&lt;/h3&gt;
&lt;p&gt;Сравнение — сопоставление миров или реализаций сценариев по критериям.&lt;/p&gt;
&lt;p&gt;АВТ сравнивает миры внутри одного этапа одного сценария. ПЧВСА сравнивает реализации сценариев между собой.&lt;/p&gt;
&lt;p&gt;Сравнивать нужно в одном времени. Время равно, если время отличается меньше, чем на величину максимального такта среди сравниваемых миров.&lt;/p&gt;
&lt;p&gt;Максимальный такт — максимальная длительность такта среди тех миров, которые сравниваются. Если АВТ сравнивает миры одного этапа одного сценария, максимальный такт берётся среди этих миров. Если ПЧВСА сравнивает реализации сценариев, максимальный такт берётся среди всех миров, которые входят в сравниваемые реализации.&lt;/p&gt;
&lt;p&gt;Главный критерий — население. Население — главный критерий, потому что от него зависит скорость выработки труда. Чем больше население, тем быстрее копится труд, тем быстрее строятся домики. Второстепенный критерий — количество моделируемых действий. Количество действий важно только при равном населении. Меньше действий — лучше, потому что это эффективнее. Все сравниваемые величины — целые числа. Критерий лексикографический: сначала население, потом моделируемые действия.&lt;/p&gt;

&lt;h3 id=&quot;keshirovanie-gipotez&quot;&gt;Кеширование гипотез&lt;/h3&gt;
&lt;p&gt;Кеширование гипотез — механизм, общий для человека и АВТ. Гипотезу можно проверить один раз и затем пользоваться результатом проверки, если сохраняются условия, при которых гипотеза проверялась.&lt;/p&gt;
&lt;p&gt;Условие — характеристика ситуации, при которой гипотеза проверялась. Условие — набор проверок над состоянием модели. Проверка — это логическое выражение, которое либо истинно, либо ложно.&lt;/p&gt;
&lt;p&gt;Примеры проверок:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Качественная: «склад пуст», «склад не пуст», «достаточно стали на домик», «достаточно товаров на домик», «достаточно энергии на домик».&lt;/li&gt;
&lt;li&gt;Числовая: «население &amp;gt; 550 млн», «сталь на складе &amp;gt; 100».&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Условие считается совпадающим, если все проверки дают тот же результат, что и в сохранённом условии. Точные числа не сравниваются. Сравниваются результаты проверок.&lt;/p&gt;
&lt;p&gt;Результат проверки гипотезы — вывод о том, какой вариант выгоднее при данных условиях.&lt;/p&gt;
&lt;p&gt;Результат сохраняется в кеше вместе с набором проверок и их результатами.&lt;/p&gt;

&lt;h3 id=&quot;trebovanie-k-imenam&quot;&gt;Требование к именам&lt;/h3&gt;
&lt;p&gt;Все имена переменных, функций, типов и структур в псевдокоде и в коде — на русском языке и кириллицей. Латинские буквы в именах не используются. Единственное исключение — синтаксические ключевые слова языка программирования (например, &lt;code&gt;fn&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;), если язык их требует.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;prilozhenie-3&quot;&gt;Приложение 3. Сравнение и финалы&lt;/h2&gt;

&lt;h3&gt;Общий момент сравнения&lt;/h3&gt;
&lt;p&gt;Миры разной длины: один заканчивается раньше, другой позже. Мир не останавливается, когда достиг последней цели. Мир продолжает работать до общего момента сравнения.&lt;/p&gt;
&lt;p&gt;Общий момент сравнения — когда последний мир достиг стратегического финала. На уровне АВТ — когда последний план достиг тактического финала. На уровне ПЧВСА — когда последняя реализация сценария достигла стратегического финала. Этот же момент — условие остановки симуляции. Симуляция останавливается, когда все миры достигли стратегического финала. Мир, который достиг стратегического финала раньше, продолжает строить домики до общего момента.&lt;/p&gt;
&lt;p&gt;В этот момент у каждого мира своё население и своё количество моделируемых действий.&lt;/p&gt;
&lt;p&gt;Проверка финала — это условие остановки, а не отсечение. Отсечение планов происходит по другим причинам: невозможность выполнить моделируемое действие, нарушение порядка блокировки, эквивалентность другому плану.&lt;/p&gt;

&lt;h3&gt;Связь финалов с целями этапов&lt;/h3&gt;
&lt;p&gt;Разные этапы могут иметь разные цели. Тактический финал зависит от цели этапа.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Для этапа с целью «построить завод» тактический финал — завод построен.&lt;/li&gt;
&lt;li&gt;Для этапа с целью «строить домики» тактический финал совпадает со стратегическим финалом — условием остановки симуляции.&lt;/li&gt;
&lt;li&gt;Для этапа с целью «копить топливо» тактический финал — накоплено 160 топлива.&lt;/li&gt;
&lt;li&gt;Для этапа с целью «забрать бонус» тактический финал — бонус забран.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h2 id=&quot;prilozhenie-4&quot;&gt;Приложение 4. Как человек организует выбор варианта стратегии&lt;/h2&gt;

&lt;h3&gt;Постановка задачи&lt;/h3&gt;
&lt;p&gt;Человек хочет выработать стратегию. Стратегия одна. Человек прорабатывает варианты стратегии заранее и записывает в виде сценариев. Человек создаёт несколько сценариев, потому что хочет сравнить разные гипотетические варианты стратегии между собой.&lt;/p&gt;

&lt;h3&gt;Шаги&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Шаг 1. Формулировка стратегических гипотез.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Человек формулирует стратегические гипотезы о выгодности вариантов стратегии.&lt;/p&gt;
&lt;p&gt;Пример гипотез:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Стратегическая гипотеза 0: квест лучше выполнять, чем не выполнять.&lt;/li&gt;
&lt;li&gt;Стратегическая гипотеза 1: выполнять квест раньше — выгоднее, чем позже.&lt;/li&gt;
&lt;li&gt;Стратегическая гипотеза 2: два завода выгоднее одного.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Шаг 2. Создание сценариев.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Человек создаёт сценарии для проверки стратегических гипотез.&lt;/p&gt;
&lt;p&gt;Сценарий — цепочка этапов. Этап — цели и приоритеты.&lt;/p&gt;
&lt;p&gt;Из гипотез образуются сценарии: по каждой гипотезе берётся либо гипотеза, либо антигипотеза. Не все комбинации дают разные сценарии. Комбинации, которые дают одинаковые сценарии, сворачиваются в один. Например, если квест не выполняется, то не важно, один или два завода, и не важно, раньше или позже. Все такие комбинации дают один сценарий.&lt;/p&gt;
&lt;p&gt;Пример: пять сценариев из трёх гипотез.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Шаг 3. Сравнение сценариев.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Сценарии разной длины: один заканчивается раньше, другой позже. Сценарий не останавливается, когда достиг последней цели. Сценарий продолжает работать до общего момента сравнения.&lt;/p&gt;
&lt;p&gt;Общий момент сравнения — когда последний сценарий достиг стратегического финала. Стратегический финал — флаг из_руды, домик построен. Сценарий, который достиг стратегического финала раньше, продолжает строить домики до общего момента.&lt;/p&gt;
&lt;p&gt;В этот момент у каждого сценария своё население и своё количество моделируемых действий.&lt;/p&gt;
&lt;p&gt;Сравниваем население и моделируемые действия в этот момент.&lt;/p&gt;
&lt;p&gt;Главный критерий — население. Второстепенный критерий — количество моделируемых действий. Все сравниваемые величины — целые числа. Критерий лексикографический: сначала население, потом моделируемые действия. Меньше моделируемых действий — лучше.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Шаг 4. Выбор лучшего сценария.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Лучший сценарий — это истинная стратегия.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Шаг 5. Проверка гипотез.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Стратегическая гипотеза, которая ведёт к выигрышной стратегии — правильная.&lt;br&gt;
Стратегическая гипотеза, которая ведёт к проигрышной стратегии — неправильная.&lt;/p&gt;
&lt;p&gt;Истина — набор правильных гипотез и соответствующих истине стратегии и тактики.&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;prilozhenie-5&quot;&gt;Приложение 5. Работа АВТ&lt;/h2&gt;

&lt;h3&gt;Как работает АВТ&lt;/h3&gt;
&lt;p&gt;Сценарий задаёт цели с приоритетами. АВТ превращает цели в моделируемые действия. Это можно делать разными способами.&lt;/p&gt;

&lt;h3&gt;Как АВТ ищет истинную тактику&lt;/h3&gt;
&lt;p&gt;АВТ ищет истинную тактику так же, как человек ищет истинную стратегию.&lt;/p&gt;
&lt;p&gt;Человек ищет стратегию среди сценариев.&lt;br&gt;
АВТ ищет тактику среди планов.&lt;/p&gt;
&lt;p&gt;Человек формулирует стратегические гипотезы о порядке этапов и создаёт сценарии.&lt;br&gt;
АВТ формулирует тактические гипотезы о порядке моделируемых действий и создаёт планы.&lt;/p&gt;
&lt;p&gt;Человек сравнивает сценарии по результатам.&lt;br&gt;
АВТ сравнивает планы по результатам.&lt;/p&gt;
&lt;p&gt;Человек выбирает лучший сценарий — это истинная стратегия.&lt;br&gt;
АВТ выбирает лучший план — это истинная тактика.&lt;/p&gt;

&lt;h3&gt;Как АВТ порождает тактические гипотезы&lt;/h3&gt;
&lt;p&gt;АВТ порождает тактические гипотезы о способах превращения цели в моделируемые действия.&lt;/p&gt;
&lt;p&gt;Тактическая гипотеза — утверждение о выгодности варианта способа.&lt;br&gt;
Антигипотеза — противоположное утверждение.&lt;/p&gt;
&lt;p&gt;АВТ порождает все перестановки моделируемых действий внутри цели. Отсечение — см. раздел «Ограничение перебора».&lt;/p&gt;

&lt;h3&gt;Как АВТ строит пары планов&lt;/h3&gt;
&lt;p&gt;АВТ строит пару планов: один с гипотезой, один с антигипотезой.&lt;/p&gt;
&lt;p&gt;План с гипотезой — маршрут в графе моделируемых действий, где порядок моделируемых действий соответствует гипотезе.&lt;br&gt;
План с антигипотезой — маршрут, где порядок моделируемых действий соответствует антигипотезе.&lt;/p&gt;
&lt;p&gt;Пока цель этапа не достигнута, выполняются действия из перестановки. После достижения цели этапа мир переходит к действию по умолчанию. Действие по умолчанию — это то, что делает мир до наступления общего момента сравнения.&lt;/p&gt;

&lt;h3&gt;Как АВТ сравнивает планы&lt;/h3&gt;
&lt;p&gt;Планы разной длины: один заканчивается раньше, другой позже.&lt;/p&gt;
&lt;p&gt;Сравнение в одном времени: все планы доходят до момента, когда последний из них закончился.&lt;/p&gt;
&lt;p&gt;В этот момент у каждого плана своё население и своё количество моделируемых действий.&lt;/p&gt;
&lt;p&gt;Сравниваем население и моделируемые действия в этот момент.&lt;/p&gt;
&lt;p&gt;Два мира сравнимы по времени, если время отличается меньше, чем на величину максимального такта.&lt;/p&gt;
&lt;p&gt;Главный критерий — население. Второстепенный критерий — количество моделируемых действий. Все сравниваемые величины — целые числа. Критерий лексикографический: сначала население, потом моделируемые действия. Меньше моделируемых действий — лучше.&lt;/p&gt;
&lt;p&gt;План с лучшим результатом становится тактикой.&lt;/p&gt;

&lt;h3&gt;Ограничение перебора&lt;/h3&gt;
&lt;p&gt;АВТ не перебирает все моделируемые действия. АВТ работает в рамках целей этапа. Цели этапа заданы сценарием с приоритетами. Цели заданы снаружи по отношению к АВТ. АВТ не придумывает цели верхнего уровня, а только разбивает и уточняет их.&lt;/p&gt;
&lt;p&gt;АВТ порождает гипотезы только о порядке моделируемых действий внутри цели. Количество способов ограничено числом перестановок моделируемых действий внутри цели.&lt;/p&gt;
&lt;p&gt;АВТ отсекает ветки, которые не ведут к цели.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Эвристика 1:&lt;/strong&gt; моделируемые действия независимы, если не меняют одни и те же ресурсы и не конкурируют за труд. Конкуренция за труд — только если труда не хватает на оба моделируемых действия сразу. В текущей модели конкуренция за труд не проверяется. Предполагается, что труда хватает на все обмены. Если в будущем труда будет не хватать, эвристика 1 должна учитывать конкуренцию.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Эвристика 3:&lt;/strong&gt; блокирующее раньше. Если моделируемое действие A блокирует моделируемое действие B, A надо делать раньше.&lt;/p&gt;
&lt;p&gt;В текущей модели эвристика 3 не применяется: все цели этапов содержат либо одно действие, либо несколько независимых обменов. Число перестановок для цели «построить завод» — 6, потому что обмены независимы и не блокируют друг друга. Эвристика 3 понадобится, когда появятся цели с зависимыми действиями.&lt;/p&gt;

&lt;h3&gt;Проверка после действия&lt;/h3&gt;
&lt;p&gt;Проверка после моделируемого действия: проверять, если после моделируемого действия ресурс ниже целевого уровня или ресурс увеличился. Не проверять, если после моделируемого действия ресурс выше или равен целевому и ресурс уменьшился.&lt;/p&gt;

&lt;h3&gt;Действие по умолчанию&lt;/h3&gt;
&lt;p&gt;Действие по умолчанию — то, что делает мир после достижения цели этапа, пока не наступит общий момент сравнения. В текущей модели действие по умолчанию — строить домики, если есть ресурсы, иначе ждать. Это одинаково для всех целей и всех этапов: после достижения любой цели мир продолжает строить домики. Если в будущем появятся другие цели, действие по умолчанию может зависеть от сценария.&lt;/p&gt;

&lt;h3&gt;Кеширование гипотез&lt;/h3&gt;
&lt;p&gt;АВТ кеширует тактические гипотезы так же, как человек кеширует стратегические гипотезы. См. Приложение 2, термин «Кеширование гипотез».&lt;/p&gt;

&lt;h3&gt;Как это работает на целях&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Цель «построить завод»&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Завод требует 100 стали, 500 товаров, 1000 энергии. Строительство завода всегда последнее. Перестановки — только для обменов. Три обмена дают 6 перестановок.&lt;/p&gt;
&lt;p&gt;Зависит от запасов на складе и в производстве.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Цель «копить топливо»&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Топливо производится из энергии. Энергия производится из труда. Топливо копится на складе.&lt;/p&gt;
&lt;p&gt;Способы: покупать энергию частями или сразу; покупать топливо частями или сразу.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Цель «строить домики»&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Моделируемое действие — построить несколько домиков. Количество ограничено запасом на складе. Запас может быть дан изначально или получен бонусом.&lt;/p&gt;
&lt;p&gt;Способы:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Копить ресурсы, потом строить пачкой.&lt;/li&gt;
&lt;li&gt;Строить по одному по мере накопления.&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h2 id=&quot;prilozhenie-6&quot;&gt;Приложение 6. Формализация АВТ в псевдокоде&lt;/h2&gt;

&lt;h3&gt;Вход АВТ&lt;/h3&gt;
&lt;pre&gt;
Вход:
    Этап — цели и приоритеты
    Начальное_состояние — состояние модели, время
    Сценарий — сценарий, к которому относится этап

Выход:
    Граф — граф моделируемых действий
    Лучший_план — маршрут в графе миров
&lt;/pre&gt;

&lt;h3&gt;Структуры данных&lt;/h3&gt;
&lt;pre&gt;
Состояние_модели:
    строения: {шахт, электростанций, заводов, топливных}
    склад: {сталь, товары, энергия, топливо, труд, КР, наука}
    запасы: {сталь_в_шахте, энергия_в_станциях, товары_в_заводах, топливо_в_топливных}
    буферы: {сталь, энергия, товары, топливо}
    население: целое (млн жителей)

Мир:
    состояние_модели: Состояние_модели
    время: вещественное (игровые периоды)
    длительность_такта: вещественное (игровые периоды)
    артефакты: {флаг_из_руды, домиков_на_этапе, текущий_этап}

Моделируемое_действие:
    тип: {обменять_сталь, обменять_товары, обменять_энергию, обменять_топливо,
          построить_домик, построить_завод, забрать_бонус, подождать}
    параметры: {единиц, тактов}

Граф_моделируемых_действий:
    узлы: список Миров
    рёбра: список (Мир_откуда, Моделируемое_действие, Мир_куда)

План:
    маршрут: список Миров (путь в графе)
    время_финала: вещественное (игровые периоды)
&lt;/pre&gt;

&lt;h3&gt;Построение графа&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Построить_граф(Этап, Начальное_состояние, Сценарий):

    Текущая_цель = Первая_цель_этапа(Этап)
    Действия = Действия_ведущие_к_цели(Текущая_цель, Начальное_состояние)
    Перестановки = Все_перестановки(Действия)

    Граф = Создать_пустой_граф()
    Граф.узлы.добавить(Создать_мир(Начальное_состояние, время=0))

    Планы = []
    ДЛЯ КАЖДОЙ перестановки В Перестановки:
        План = Построить_план(перестановка, Граф, Сценарий)
        ЕСЛИ План ≠ пусто:
            Планы.добавить(План)

    Общий_момент = МАКСИМУМ(план.время_финала ДЛЯ КАЖДОГО плана В Планы)

    ДЛЯ КАЖДОГО плана В Планы:
        Продолжить_план(план, Общий_момент, Граф, Сценарий)

    Планы = Отсечь_ветки(Планы)
    Лучший_план = Выбрать_лучший(Планы, Общий_момент)

    ВЕРНУТЬ {граф: Граф, лучший_план: Лучший_план}
&lt;/pre&gt;

&lt;h3&gt;Действия, ведущие к цели&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Действия_ведущие_к_цели(Цель, Состояние):
    # Для цели «построить завод» — три обмена: сталь, товары, энергия.
    # Само строительство завода не входит в перестановки: оно всегда последнее.
    # Для цели «копить топливо» — обмен энергии и обмен топлива.
    # Для цели «строить домики» — одно действие: построить домик.
    ВЕРНУТЬ Список_действий(Цель)
&lt;/pre&gt;

&lt;h3&gt;Построение плана&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Построить_план(перестановка, Граф, Сценарий):

    Текущий_мир = Граф.узлы[0]
    Маршрут = [Текущий_мир]

    ДЛЯ КАЖДОГО действия В перестановке:
        ПОКА НЕ Можно_выполнить(действие, Текущий_мир):
            Ждать = подождать(тактов=1)
            Новый_мир = Применить(Ждать, Текущий_мир, Сценарий)
            Граф.узлы.добавить(Новый_мир)
            Граф.рёбра.добавить((Текущий_мир, Ждать, Новый_мир))
            Маршрут.добавить(Новый_мир)
            Текущий_мир = Новый_мир
        Новый_мир = Применить(действие, Текущий_мир, Сценарий)
        Граф.узлы.добавить(Новый_мир)
        Граф.рёбра.добавить((Текущий_мир, действие, Новый_мир))
        Маршрут.добавить(Новый_мир)
        Текущий_мир = Новый_мир

    ПОКА НЕ Достигнут_финал(Текущий_мир, Сценарий):
        ЕСЛИ Цель_этапа_достигнута(Текущий_мир, Сценарий):
            Следующий_этап(Текущий_мир, Сценарий)
        Действие = Выбрать_действие_по_умолчанию(Текущий_мир)
        Новый_мир = Применить(Действие, Текущий_мир, Сценарий)
        Граф.узлы.добавить(Новый_мир)
        Граф.рёбра.добавить((Текущий_мир, Действие, Новый_мир))
        Маршрут.добавить(Новый_мир)
        Текущий_мир = Новый_мир

    ВЕРНУТЬ {маршрут: Маршрут, время_финала: Текущий_мир.время}
&lt;/pre&gt;

&lt;h3&gt;Продолжение плана до общего момента&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Продолжить_план(план, Общий_момент, Граф, Сценарий):

    Текущий_мир = план.маршрут[конец]

    ПОКА Текущий_мир.время &lt;/pre&gt;

&lt;h3&gt;Создание мира&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Создать_мир(Начальное_состояние, время):
    Мир = {}
    Мир.состояние_модели = Копировать(Начальное_состояние)
    Мир.время = время
    Мир.длительность_такта = 1 / Мир.состояние_модели.население
    Мир.артефакты = {флаг_из_руды: ложь, домиков_на_этапе: 0, текущий_этап: 1}
    ВЕРНУТЬ Мир
&lt;/pre&gt;

&lt;h3&gt;Проверка возможности действия&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Можно_выполнить(действие, мир):
    ЕСЛИ действие.тип == обменять_сталь:
        ВЕРНУТЬ мир.склад.труд &amp;gt;= действие.параметры.единиц * 7 И
                мир.запасы.сталь_в_шахте &amp;gt;= действие.параметры.единиц
    ЕСЛИ действие.тип == обменять_товары:
        ВЕРНУТЬ мир.склад.труд &amp;gt;= действие.параметры.единиц И
                мир.запасы.товары_в_заводах &amp;gt;= действие.параметры.единиц
    ЕСЛИ действие.тип == обменять_энергию:
        ВЕРНУТЬ мир.склад.труд &amp;gt;= действие.параметры.единиц И
                мир.запасы.энергия_в_станциях &amp;gt;= действие.параметры.единиц
    ЕСЛИ действие.тип == обменять_топливо:
        ВЕРНУТЬ мир.склад.энергия &amp;gt;= действие.параметры.единиц И
                мир.запасы.топливо_в_топливных &amp;gt;= действие.параметры.единиц
    ЕСЛИ действие.тип == построить_домик:
        ВЕРНУТЬ мир.склад.сталь &amp;gt;= 4 И
                мир.склад.товары &amp;gt;= 12 И
                мир.склад.энергия &amp;gt;= 19
    ЕСЛИ действие.тип == построить_завод:
        ВЕРНУТЬ мир.склад.сталь &amp;gt;= 100 И
                мир.склад.товары &amp;gt;= 500 И
                мир.склад.энергия &amp;gt;= 1000
    ЕСЛИ действие.тип == забрать_бонус:
        ВЕРНУТЬ Квест_выполнен(мир)
    ЕСЛИ действие.тип == подождать:
        ВЕРНУТЬ истина
&lt;/pre&gt;

&lt;h3&gt;Применение действия&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Применить(действие, мир, Сценарий):

    Новый_мир = Копировать(мир)

    ЕСЛИ действие.тип == обменять_сталь:
        Новый_мир.запасы.сталь_в_шахте -= действие.параметры.единиц
        Новый_мир.склад.сталь += действие.параметры.единиц
        Новый_мир.склад.труд -= действие.параметры.единиц * 7
    ЕСЛИ действие.тип == обменять_товары:
        Новый_мир.запасы.товары_в_заводах -= действие.параметры.единиц
        Новый_мир.склад.товары += ОКРУГЛИТЬ_ВНИЗ(действие.параметры.единиц * 1.5)
        Новый_мир.склад.труд -= действие.параметры.единиц
    ЕСЛИ действие.тип == обменять_энергию:
        Новый_мир.запасы.энергия_в_станциях -= действие.параметры.единиц
        Новый_мир.склад.энергия += действие.параметры.единиц * 3
        Новый_мир.склад.труд -= действие.параметры.единиц
    ЕСЛИ действие.тип == обменять_топливо:
        Новый_мир.запасы.топливо_в_топливных -= действие.параметры.единиц
        Новый_мир.склад.топливо += ОКРУГЛИТЬ_ВНИЗ(действие.параметры.единиц * 0.2)
        Новый_мир.склад.энергия -= действие.параметры.единиц
    ЕСЛИ действие.тип == построить_домик:
        Новый_мир.склад.сталь -= 4
        Новый_мир.склад.товары -= 12
        Новый_мир.склад.энергия -= 19
        # Население хранится в миллионах жителей.
        Новый_мир.состояние_модели.население += 2
        Новый_мир.артефакты.домиков_на_этапе += 1
        Новый_мир.длительность_такта = 1 / Новый_мир.состояние_модели.население
    ЕСЛИ действие.тип == построить_завод:
        Новый_мир.склад.сталь -= 100
        Новый_мир.склад.товары -= 500
        Новый_мир.склад.энергия -= 1000
        Новый_мир.состояние_модели.строения.топливных += 1
    ЕСЛИ действие.тип == забрать_бонус:
        Новый_мир.склад.КР += 45
        Новый_мир.склад.труд += 300
        Новый_мир.склад.наука += 500
        Новый_мир.склад.сталь += 550
        Новый_мир.склад.товары += 1400
        Новый_мир.склад.энергия += 1200
    ЕСЛИ действие.тип == подождать:
        игровое_время = действие.параметры.тактов * Новый_мир.длительность_такта
        Новый_мир.время += игровое_время
        Новый_мир = Обновить_запасы(Новый_мир, действие.параметры.тактов, игровое_время)

    Обновить_флаги(действие, Новый_мир, Сценарий)

    ВЕРНУТЬ Новый_мир
&lt;/pre&gt;

&lt;h3&gt;Обновление запасов&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Обновить_запасы(мир, тактов, игровое_время):

    # За 1 такт население даёт 1 труд
    мир.склад.труд += тактов

    # Прибавить к буферам прирост за прошедшее игровое время
    мир.буферы.сталь += игровое_время * мир.строения.шахт * 100
    мир.буферы.энергия += игровое_время * мир.строения.электростанций * 100
    мир.буферы.товары += игровое_время * мир.строения.заводов * 100
    мир.буферы.топливо += игровое_время * мир.строения.топливных * 100

    # Перенести целую часть буфера в запас
    целая = ЦЕЛАЯ_ЧАСТЬ(мир.буферы.сталь)
    мир.буферы.сталь -= целая
    мир.запасы.сталь_в_шахте += целая

    целая = ЦЕЛАЯ_ЧАСТЬ(мир.буферы.энергия)
    мир.буферы.энергия -= целая
    мир.запасы.энергия_в_станциях += целая

    целая = ЦЕЛАЯ_ЧАСТЬ(мир.буферы.товары)
    мир.буферы.товары -= целая
    мир.запасы.товары_в_заводах += целая

    целая = ЦЕЛАЯ_ЧАСТЬ(мир.буферы.топливо)
    мир.буферы.топливо -= целая
    мир.запасы.топливо_в_топливных += целая

    # Ограничить запасы
    мир.запасы.сталь_в_шахте = МИН(мир.строения.шахт * 100, мир.запасы.сталь_в_шахте)
    мир.запасы.энергия_в_станциях = МИН(мир.строения.электростанций * 100, мир.запасы.энергия_в_станциях)
    мир.запасы.товары_в_заводах = МИН(мир.строения.заводов * 100, мир.запасы.товары_в_заводах)
    мир.запасы.топливо_в_топливных = МИН(мир.строения.топливных * 100, мир.запасы.топливо_в_топливных)

    ВЕРНУТЬ мир
&lt;/pre&gt;

&lt;h3&gt;Проверка финала&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Достигнут_финал(мир, Сценарий):
    ЕСЛИ мир.артефакты.флаг_из_руды И
       Домик_построен(мир, Сценарий):
        ВЕРНУТЬ истина
    ИНАЧЕ:
        ВЕРНУТЬ ложь

АЛГОРИТМ Домик_построен(мир, Сценарий):
    ЕСЛИ мир.артефакты.домиков_на_этапе &amp;gt; 0 И
       мир.артефакты.текущий_этап == Последний_этап(Сценарий):
        ВЕРНУТЬ истина
    ИНАЧЕ:
        ВЕРНУТЬ ложь
&lt;/pre&gt;

&lt;h3&gt;Обновление флагов&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Обновить_флаги(действие, мир, Сценарий):
    ЕСЛИ Склад_пуст(мир) И мир.артефакты.текущий_этап == Последний_этап(Сценарий) И
       НЕ мир.артефакты.флаг_из_руды:
        мир.артефакты.флаг_из_руды = истина

    ЕСЛИ действие.тип == забрать_бонус:
        мир.артефакты.флаг_из_руды = ложь

АЛГОРИТМ Склад_пуст(мир):
    # Топливо, КР и наука не входят в проверку.
    # Топливо — цель квеста, не тратится на домики.
    # КР в текущей модели не используются для покупки ресурсов.
    # Наука в текущей модели не используется для исследований.
    # Эти ресурсы не влияют на строительство домиков.
    ЕСЛИ мир.склад.сталь == 0 И
       мир.склад.товары == 0 И
       мир.склад.энергия == 0 И
       мир.склад.труд == 0:
        ВЕРНУТЬ истина
    ИНАЧЕ:
        ВЕРНУТЬ ложь
&lt;/pre&gt;

&lt;h3&gt;Действие по умолчанию&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Выбрать_действие_по_умолчанию(мир):
    ЕСЛИ Есть_ресурсы_на_домик(мир):
        ВЕРНУТЬ построить_домик
    ИНАЧЕ:
        ВЕРНУТЬ подождать(тактов=1)

АЛГОРИТМ Есть_ресурсы_на_домик(мир):
    ЕСЛИ мир.склад.сталь &amp;gt;= 4 И
       мир.склад.товары &amp;gt;= 12 И
       мир.склад.энергия &amp;gt;= 19:
        ВЕРНУТЬ истина
    ИНАЧЕ:
        ВЕРНУТЬ ложь
&lt;/pre&gt;

&lt;h3&gt;Вход на этап&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Вход_на_этап(мир, Сценарий):
    мир.артефакты.домиков_на_этапе = 0

АЛГОРИТМ Следующий_этап(мир, Сценарий):
    мир.артефакты.текущий_этап += 1
    Вход_на_этап(мир, Сценарий)
&lt;/pre&gt;

&lt;h3&gt;Отсечение веток&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Отсечь_ветки(Планы):

    Отсечённые = []

    ДЛЯ КАЖДОГО плана В Планы:
        ЕСЛИ Есть_эквивалентный_план(плана, Отсечённые):
            ПРОДОЛЖИТЬ
        # В текущей модели эвристика 3 не применяется: все цели содержат независимые действия.
        # Проверка Нарушает_порядок_блокировки не используется.
        # Она понадобится, когда появятся цели с зависимыми действиями.
        ЕСЛИ НЕ Прошёл_проверку_после_действия(плана):
            ПРОДОЛЖИТЬ
        Отсечённые.добавить(плана)

    ВЕРНУТЬ Отсечённые
&lt;/pre&gt;

&lt;h3&gt;Эквивалентность планов&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Есть_эквивалентный_план(план, Список_планов):
    # План считается эквивалентным, если у него такое же конечное состояние модели
    # и такое же время финала, как у одного из уже отобранных планов.
    ДЛЯ КАЖДОГО отобранного В Список_планов:
        ЕСЛИ Состояния_равны(план.маршрут[конец].состояние_модели,
                              отобранного.маршрут[конец].состояние_модели) И
           план.время_финала == отобранного.время_финала:
            ВЕРНУТЬ истина
    ВЕРНУТЬ ложь
&lt;/pre&gt;

&lt;h3&gt;Проверка после действия&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Прошёл_проверку_после_действия(план):

    ДЛЯ КАЖДОГО перехода В план.маршрут:
        Мир_до = переход.откуда
        Мир_после = переход.куда
        Ресурсы_из_условия = Ресурсы_цели(план.этап)

        ДЛЯ КАЖДОГО ресурса В Ресурсы_из_условия:
            Значение_до = Мир_до.склад[ресурс]
            Значение_после = Мир_после.склад[ресурс]
            Целевой_уровень = Целевой_уровень(ресурс, план.этап)

            # Проверка: если ресурс упал ниже целевого и не восстановится — план отсекается.
            ЕСЛИ Значение_после &lt;/pre&gt;

&lt;h3&gt;Сравнение планов&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Выбрать_лучший(Планы, Общий_момент):

    # Проверка: все планы должны иметь время финала, отличающееся от общего момента
    # не больше, чем на максимальный такт среди планов.
    Максимальный_такт = МАКСИМУМ(1 / план.маршрут[конец].состояние_модели.население
                                  ДЛЯ КАЖДОГО плана В Планы)

    Лучший_план = пусто

    ДЛЯ КАЖДОГО плана В Планы:
        ЕСЛИ АБС(план.время_финала - Общий_момент) &amp;gt; Максимальный_такт:
            ПРОДОЛЖИТЬ
        ЕСЛИ Лучший_план == пусто:
            Лучший_план = план
            ПРОДОЛЖИТЬ
        Результат = Результат_на_момент(план, Общий_момент)
        Лучший_результат = Результат_на_момент(Лучший_план, Общий_момент)
        ЕСЛИ Результат.население &amp;gt; Лучший_результат.население:
            Лучший_план = план
        ИНАЧЕ ЕСЛИ Результат.население == Лучший_результат.население:
            ЕСЛИ Результат.количество_действий &lt;/pre&gt;

&lt;h3&gt;Кеширование гипотез&lt;/h3&gt;
&lt;pre&gt;
АЛГОРИТМ Кешировать_гипотезу(гипотеза, условие):
    ЕСЛИ Условие_совпадает(условие, кеш.условие):
        ВЕРНУТЬ кеш.результат
    ИНАЧЕ:
        Результат = Проверить_гипотезу(гипотеза, условие)
        кеш.сохранить(условие, Результат)
        ВЕРНУТЬ Результат
&lt;/pre&gt;

&lt;hr&gt;

&lt;h2 id=&quot;prilozhenie-7&quot;&gt;Приложение 7. Состояние модели&lt;/h2&gt;

&lt;p&gt;Состояние модели — набор строений, накопления на складе, запасы в строениях. Всё целые числа.&lt;/p&gt;
&lt;p&gt;Запасы в строениях накапливаются пропорционально 100 единиц за игровой период (6 часов). Скорость накопления не зависит от населения и от длительности такта. Она зависит только от игрового времени, которое прошло.&lt;/p&gt;

&lt;h3&gt;Строения&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Шахта&lt;/strong&gt; — накапливает возможности добыть сталь. 100 единиц за игровой период (6 часов). Запас 100.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Электростанция&lt;/strong&gt; — накапливает возможности произвести энергию. 100 единиц за игровой период (6 часов). Запас 100. В начале 4 штуки.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Завод&lt;/strong&gt; — накапливает возможности произвести товары. 100 единиц за игровой период (6 часов). Запас 100. В начале 5 штук.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Завод ракетного топлива&lt;/strong&gt; — накапливает возможности конвертировать условные единицы в топливо. 100 единиц за игровой период (6 часов). Запас 100. В начале 0 штук.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Склад&lt;/h3&gt;
&lt;p&gt;Склад хранит сталь, товары, энергию, топливо, труд, КР, науку. Весь склад ограничен, но ограничение высокое, и в расчётах считается, что его нет.&lt;/p&gt;
&lt;p&gt;КР — кредиты. Кредиты хранятся на складе. Кредиты используются для покупки ресурсов (описание покупки — за рамками текущей модели).&lt;/p&gt;
&lt;p&gt;Наука — ресурс, который хранится на складе. Наука используется для исследований (описание исследований — за рамками текущей модели).&lt;/p&gt;

&lt;h3&gt;Обмены&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Шахта: ты вводишь число единиц заказа. Списывается 7 труда за 1 единицу заказа. Зачисляется 1 сталь за 1 единицу заказа.&lt;/li&gt;
&lt;li&gt;Завод: ты вводишь число единиц заказа. Списывается 1 труд за 1 единицу заказа. Зачисляется 1.5 товара за 1 единицу заказа. Округление результата вниз.&lt;/li&gt;
&lt;li&gt;Электростанция: ты вводишь число единиц заказа. Списывается 1 труд за 1 единицу заказа. Зачисляется 3 энергии за 1 единицу заказа.&lt;/li&gt;
&lt;li&gt;Завод ракетного топлива: ты вводишь число единиц заказа. Списывается 1 энергия за 1 единицу заказа. Зачисляется 0.2 топлива за 1 единицу заказа. Округление результата вниз.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Домик&lt;/h3&gt;
&lt;p&gt;Домик на 2 миллиона жителей требует 4 стали, 12 товаров, 19 энергии.&lt;/p&gt;

&lt;h3 id=&quot;zavod-raketnogo-topliva&quot;&gt;Завод ракетного топлива&lt;/h3&gt;
&lt;p&gt;Завод ракетного топлива требует 100 стали, 500 товаров, 1000 энергии.&lt;/p&gt;

&lt;h3&gt;Квест&lt;/h3&gt;
&lt;p&gt;Квест — накопить 160 топлива на складе. За выполнение квеста правительство выдаёт бонус: 45 КР, 300 труда, 500 науки, 550 стали, 1400 товаров, 1200 энергии. Бонус забирается отдельным моделируемым действием.&lt;/p&gt;

&lt;h3&gt;Население&lt;/h3&gt;
&lt;p&gt;Население хранится в миллионах жителей. Население даёт труд: 1 миллион жителей даёт 1 труд за 1 игровой период (6 часов игрового времени). За 1 такт население даёт 1 труд. Такт нужен только для дискретизации труда: 1 труд целым числом за 1 такт. Всё остальное считается в игровых периодах. Длительность такта пересчитывается при изменении населения: 1 такт = 1 игровой период / население (в млн).&lt;/p&gt;

&lt;h3&gt;Пример&lt;/h3&gt;
&lt;p&gt;В начале: 550 миллионов жителей, 322 стали на складе, 0 товаров, 25 энергии, 96 топлива, 0 труда. Одна шахта, четыре электростанции, пять заводов, ноль заводов ракетного топлива.&lt;/p&gt;
</description>  </item>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D0%BB-eclipse-%D0%B8-web-development</guid>
    <title>Установил Eclipse и Web Development Tools (WDT)</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D0%BB-eclipse-%D0%B8-web-development</link>
    <pubDate>Sat, 19 Sep 2026 08:25:44 +0000</pubDate>
    <category>ЖЖ</category>
    <category>java</category>
<description>Теоретически, это должно позволять отлаживать web-приложения.
Практически я только научился запускать и останавливать второй веб-сервер изнутри IDE, и только.

Ну, конечно, ещё наверное хорошо, что там проект отображается и визарды есть... Но я их пока не освоил.</description>  </item>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D0%BB-lemmy-ibis-wiki</guid>
    <title>ibis.wiki - собрал, установил, настроил, ... заполнил?</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D0%BB-lemmy-ibis-wiki</link>
    <pubDate>Fri, 12 Jun 2026 16:07:36 +0000</pubDate>
    <category>ЖЖ</category>
<description>&lt;h2&gt;2026-09-29&lt;/h2&gt;

Собрал версию Ibis.wiki 0.3.3 из исходных текстов, пропатчил:
&lt;br&gt;
&lt;pre&gt;&lt;b&gt;~/rust/ibis/Nutomic&lt;/b&gt;$ git diff
&lt;b&gt;diff --git a/crates/federate/src/validate.rs b/crates/federate/src/validate.rs&lt;/b&gt;
&lt;b&gt;index a6709f1..35d2edd 100644&lt;/b&gt;
&lt;b&gt;--- a/crates/federate/src/validate.rs&lt;/b&gt;
&lt;b&gt;+++ b/crates/federate/src/validate.rs&lt;/b&gt;
@@ -6,7 +6,7 @@ use std::sync::LazyLock;
 pub fn validate_article_title(title: &amp;amp;str) -&amp;gt; BackendResult&amp;lt;()&amp;gt; {
     #[expect(clippy::expect_used)]
     static TITLE_REGEX: LazyLock&amp;lt;Regex&amp;gt; =
-        LazyLock::new(|| Regex::new(r&amp;quot;^[a-zA-Z0-9-. ()]{3,100}$&amp;quot;).expect(&amp;quot;compile regex&amp;quot;));
+        LazyLock::new(|| Regex::new(r&amp;quot;^[\p{L}\p{N}\-. ()_]{3,100}$&amp;quot;).expect(&amp;quot;compile regex&amp;quot;));
     if !TITLE_REGEX.is_match(title) {
         return Err(anyhow!(&amp;quot;Invalid title&amp;quot;).into());
     }
&lt;/pre&gt;
&lt;br&gt;
Задеплоил

&lt;hr&gt;
&lt;h2&gt;2026-06-12&lt;/h2&gt;

Установил версию 0.3.0 из контейнера с докерхаба
&lt;br&gt;
&lt;br&gt;
Однако счастья это пока не принесло.
&lt;br&gt;
&lt;br&gt;
В частности, в ibis.wiki нельзя называть страницы русскими буквами. Это печально.
</description>  </item>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D1%81%D0%BE%D0%B1%D1%80%D0%B0%D0%BB-heritrix-3-%D1%87%D0%B5%D1%80%D0%B5%D0%B7-gitlab</guid>
    <title>Собрал Heritrix 3 через GitLab CI</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D1%81%D0%BE%D0%B1%D1%80%D0%B0%D0%BB-heritrix-3-%D1%87%D0%B5%D1%80%D0%B5%D0%B7-gitlab</link>
    <pubDate>Fri, 15 May 2026 04:08:16 +0000</pubDate>
    <category>ЖЖ</category>
    <category>gitlab</category>
<description>Немало времени на это потратил. И на перенастройку самого Heritrix3.
Оказалось, что нельзя пытаться заблокировать скачивание robots.txt,
потому что это обязательный ритуал у Heritrix3, он их с каждого сайта качает первыми.
&lt;br&gt;
&lt;br&gt;
В этот раз HEAD/master (3.14.1+), а не 3.10 как в прошлый. Впрочем, разница незаметна.
Теперь контейнеры делаются через Dockerfile + docker-compose.yml
&lt;br&gt;
&lt;br&gt;
Предыдущая запись была 9 апреля, эта 15 мая. Получается, что больше месяца времени на это потратил.</description>  </item>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%BF%D0%BE%D0%BF%D1%80%D0%BE%D0%B1%D0%BE%D0%B2%D0%B0%D0%BB-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%B2%D0%B0%D1%82%D1%8C-%D0%B1%D0%B4-%D0%BF%D1%80%D0%B8-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D0%B8</guid>
    <title>Попробовал создавать БД при помощи Liquibase 5.0.2</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%BF%D0%BE%D0%BF%D1%80%D0%BE%D0%B1%D0%BE%D0%B2%D0%B0%D0%BB-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%B2%D0%B0%D1%82%D1%8C-%D0%B1%D0%B4-%D0%BF%D1%80%D0%B8-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D0%B8</link>
    <pubDate>Thu, 9 Apr 2026 20:45:32 +0000</pubDate>
    <category>ЖЖ</category>
<description>&lt;p&gt;Технический отчёт за сегодня&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Настройка развёртывания приложения&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Устранена ошибка сборки, связанная с несуществующей версией родительского POM Spring Boot.&lt;/li&gt;
  &lt;li&gt;Настроен Tomcat Manager API для удалённого деплоя WAR-файла через HTTP-запросы.&lt;/li&gt;
  &lt;li&gt;Решена проблема доступа к Manager API (403), вызванная ограничениями по IP в конфигурации контекста Tomcat.&lt;/li&gt;
  &lt;li&gt;Создан скрипт предварительной инициализации контейнера для копирования стандартной конфигурации Tomcat и веб-приложения Manager.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. Подключение к базе данных&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Настроена сетевая связанность между Docker-контейнером Tomcat и сервером PostgreSQL на хосте.&lt;/li&gt;
  &lt;li&gt;Исправлены синтаксические ошибки в конфигурации pg_hba.conf, приводившие к отказу в подключении.&lt;/li&gt;
  &lt;li&gt;Зафиксирована подсеть Docker в compose.yaml для обеспечения стабильного IP-адреса контейнера и корректной аутентификации в БД.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;3. Управление схемой базы данных&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Подключена и настроена миграционная система Liquibase.&lt;/li&gt;
  &lt;li&gt;Созданы файлы миграций для автоматического развёртывания таблиц пользователей и ролей.&lt;/li&gt;
  &lt;li&gt;Реализована проверка актуальности схемы БД при запуске приложения с перенаправлением на инструкции по обновлению в случае несоответствия.&lt;/li&gt;
  &lt;li&gt;Добавлено логирование статуса выполнения миграций.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;4. Система аутентификации и авторизации&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Настроена Spring Security с хранением учётных записей в базе данных PostgreSQL.&lt;/li&gt;
  &lt;li&gt;Реализована публичная страница регистрации новых пользователей.&lt;/li&gt;
  &lt;li&gt;Создана административная панель с возможностью просмотра списка пользователей и блокировки/разблокировки учётных записей.&lt;/li&gt;
  &lt;li&gt;Реализовано автоматическое создание учётной записи администратора при первом запуске либо через веб-форму мастера установки, либо через переменные окружения.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;5. Мастер первоначальной настройки&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Разработан контроллер, выполняющий проверку готовности окружения (наличие БД, версия СУБД, состояние схемы, наличие администратора).&lt;/li&gt;
  &lt;li&gt;Создан набор информационных страниц с пошаговыми инструкциями для устранения типовых проблем (отсутствие подключения к БД, необходимость обновления СУБД, запуск миграций и др.).&lt;/li&gt;
  &lt;li&gt;Обеспечено блокирование доступа к страницам мастера после завершения настройки.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;6. Доработка интерфейса и навигации&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Скорректированы ссылки в шаблонах для корректной работы с контекстом приложения.&lt;/li&gt;
  &lt;li&gt;Устранены ошибки в Thymeleaf-выражениях, вызывавшие исключения при отсутствии активного профиля Spring.&lt;/li&gt;
  &lt;li&gt;Актуализировано содержимое главной страницы в соответствии с предметной областью.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;7. Оптимизация и диагностика&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Выявлена и решена проблема длительного запуска Tomcat, связанная со сканированием TLD в JAR-файлах.&lt;/li&gt;
  &lt;li&gt;Добавлены инструкции по точечному отключению сканирования TLD через контекстный XML-файл.&lt;/li&gt;
  &lt;li&gt;Рассмотрены рекомендации по улучшению аутентификации в PostgreSQL с использованием SSL-сертификатов и по управлению ограничениями доступа для пользователей.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Результаты&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Приложение успешно развёртывается и работает в целевой среде.&lt;/li&gt;
  &lt;li&gt;Обеспечена возможность самостоятельной настройки окружения администратором без ручного вмешательства в конфигурационные файлы.&lt;/li&gt;
  &lt;li&gt;Реализован базовый функционал управления пользователями и ролями.&lt;/li&gt;
&lt;/ul&gt;</description>  </item>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B8%D0%BB-heritrix-3-10-0</guid>
    <title>Настроил Heritrix 3.10.0 и OpenWayback</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B8%D0%BB-heritrix-3-10-0</link>
    <pubDate>Tue, 7 Apr 2026 20:33:21 +0000</pubDate>
    <category>ЖЖ</category>
<description>&lt;span&gt;Отчёт о настройке системы веб-архивации&lt;/span&gt;&lt;h3&gt;&lt;span&gt;1. Цель работы&lt;/span&gt;&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Настроить полный цикл сбора и последующего воспроизведения веб-контента:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Запустить и сконфигурировать краулер для выборочного скачивания сайтов.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Обеспечить передачу собранных данных в систему воспроизведения архивных копий.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Настроить фильтрацию: скачивать только нужные сайты, но при этом подхватывать все внешние ресурсы (стили, скрипты, изображения, файлы книг), необходимые для корректного отображения страниц.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Исключить нежелательный переход на посторонние сайты по обычным гиперссылкам.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Проверить работоспособность всей цепочки и выявить оптимальные настройки.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;span&gt;2. Используемые компоненты&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;&lt;span&gt;Краулер&lt;/span&gt;&lt;/strong&gt;&lt;span&gt; – программа для сбора веб-страниц и файлов.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;&lt;span&gt;Система воспроизведения архивов&lt;/span&gt;&lt;/strong&gt;&lt;span&gt; – для просмотра сохранённых копий.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;&lt;span&gt;Контейнеризация&lt;/span&gt;&lt;/strong&gt;&lt;span&gt; – для изолированного запуска компонентов на выделенном сервере.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;&lt;span&gt;Рабочая станция&lt;/span&gt;&lt;/strong&gt;&lt;span&gt; – для подготовки конфигураций и анализа логов.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;span&gt;3. Выполненные этапы&lt;/span&gt;&lt;/h3&gt;&lt;h4&gt;&lt;span&gt;3.1. Развёртывание и начальная настройка&lt;/span&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Краулер и система воспроизведения запущены в отдельных контейнерах на серверной машине.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Настроен общий том (директория) для обмена собранными архивными файлами между краулером и системой воспроизведения.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Организована сетевая доступность между компонентами.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;&lt;span&gt;3.2. Настройка краулера (базовый режим)&lt;/span&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Подготовлен минимальный рабочий конфигурационный файл, позволяющий краулеру запускаться и обрабатывать указанный начальный адрес.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;В процессе отладки были устранены ошибки, связанные с аутентификацией веб-интерфейса краулера и правами на запись в рабочие каталоги.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;&lt;span&gt;3.3. Организация рекурсивного обхода сайта&lt;/span&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Изначально краулер скачивал только главную страницу и не переходил по внутренним ссылкам.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Путём корректировки правил обхода («scope») удалось настроить бесконечную глубину перехода по ссылкам внутри целевого сайта.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Достигнуто стабильное скачивание сотен внутренних страниц (количество обработанных URL выросло с единиц до тысяч).&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;&lt;span&gt;3.4. Ограничение области сканирования&lt;/span&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;В конфигурацию добавлены правила, запрещающие переход на посторонние домены по обычным гиперссылкам.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Это предотвратило «уход» краулера во внешний интернет и позволило сфокусироваться на целевом сайте.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;&lt;span&gt;3.5. Разрешение внешних ресурсов (стили, скрипты, картинки)&lt;/span&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Обнаружено, что при ограничении доменов перестали скачиваться необходимые элементы оформления (CSS, JavaScript, изображения), которые физически расположены на других сайтах.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Разработана комбинация правил:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Список разрешённых доменов для таких ресурсов задан в отдельном файле.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Включена проверка «родительской страницы» – внешний ресурс скачивается только если на него есть ссылка с уже принятой страницы целевого сайта.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;В результате стили и скрипты стали корректно сохраняться в архив, что обеспечивает правильное отображение страниц при воспроизведении.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;&lt;span&gt;3.6. Настройка скачивания файлов (книг, документов)&lt;/span&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;В конфигурацию добавлено правило, принимающее любые ссылки на файлы с типичными расширениями (PDF, EPUB, FB2, DJVU, DOC и др.) независимо от их домена.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Это позволило автоматически собирать все книжные и архивные файлы, на которые есть ссылки со страниц целевого сайта.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;&lt;span&gt;3.7. Отладка синтаксиса правил&lt;/span&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;В ходе работы выяснились особенности синтаксиса, используемого правилами фильтрации.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;После нескольких итераций был найден рабочий вариант записи префиксов, обеспечивающий корректное распознавание доменов.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Лишние, неиспользуемые правила удалены для упрощения конфигурации.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;&lt;span&gt;3.8. Проверка целостности данных&lt;/span&gt;&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Выполнен анализ логов краулера, подтверждающий, что скачиваются как страницы целевого сайта, так и внешние стили, скрипты, а также файлы книг.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Через интерфейс системы воспроизведения подтверждена возможность просмотра сохранённых страниц (со стилями) и доступа к скачанным файлам.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;span&gt;4. Достигнутые результаты&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;&lt;span&gt;Стабильная работа краулера&lt;/span&gt;&lt;/strong&gt;&lt;span&gt;: система запускается, обрабатывает тысячи URL, не «падает» и не уходит на посторонние сайты.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;&lt;span&gt;Полное воспроизведение страниц&lt;/span&gt;&lt;/strong&gt;&lt;span&gt;: архивные копии отображаются с оригинальными стилями и оформлением.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;&lt;span&gt;Автоматический сбор внешних файлов&lt;/span&gt;&lt;/strong&gt;&lt;span&gt;: все ссылки на книги, документы и архивы, встречающиеся на целевых страницах, сохраняются в архив.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;&lt;span&gt;Гибкая настройка&lt;/span&gt;&lt;/strong&gt;&lt;span&gt;: правила фильтрации легко дополнять новыми типами файлов или разрешёнными доменами.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;strong&gt;&lt;span&gt;Прозрачность работы&lt;/span&gt;&lt;/strong&gt;&lt;span&gt;: все действия логируются, что позволяет отслеживать поведение краулера и выявлять возможные проблемы.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;span&gt;5. Замечания и рекомендации&lt;/span&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Для обеспечения полноты архива периодически следует проверять, не появились ли на сайте ссылки на новые типы ресурсов (например, аудио, видео), и при необходимости расширять список разрешённых расширений.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;При значительном росте объёма архива рекомендуется рассмотреть использование внешнего индексатора (например, CDX-сервера) для ускорения поиска и масштабирования.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;В случае изменения структуры внешних ресурсов (смена домена CDN) потребуется обновить список разрешённых доменов.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Все конфигурационные файлы и сценарии запуска целесообразно хранить в системе контроля версий для воспроизводимости.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;span&gt;6. Вывод&lt;/span&gt;&lt;/h3&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;В результате проделанной работы создана полностью функционирующая система веб-архивации, которая:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;собирает контент с заданного сайта, включая все необходимые внешние ресурсы и файлы;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;ограничивает обход только нужными доменами, не допуская бесконечного блуждания по интернету;&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;сохраняет собранные данные в формате, пригодном для последующего просмотра через интерфейс архивной системы.&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class=&quot;ds-markdown-paragraph&quot;&gt;&lt;span&gt;Настройки могут быть повторно использованы для любых других сайтов с минимальными правками (замена целевого домена и, при необходимости, списка внешних ресурсов).&lt;/span&gt;&lt;/p&gt;</description>  </item>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D0%BB-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B8%D0%BB-apache-archiva-2</guid>
    <title>Установил/настроил Apache Archiva 2.2.10</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%B8%D0%BB-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B8%D0%BB-apache-archiva-2</link>
    <pubDate>Fri, 3 Apr 2026 07:04:08 +0000</pubDate>
    <category>ЖЖ</category>
<description>&lt;h2&gt;✅ Сборка из исходников&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Успешно выполнена полная сборка Apache Archiva 2.2.10 из официального Git-репозитория по релизному тегу&lt;/li&gt;
  &lt;li&gt;Сгенерирован целевой артефакт: &lt;code&gt;archiva-webapp-2.2.10.war&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Все 68 модулей проекта прошли компиляцию и тестирование зависимостей без критических сбоев&lt;/li&gt;
  &lt;li&gt;Настроено стабильное разрешение артефактов через внутренний Maven-репозиторий&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;✅ Исправление JavaUtils (совместимость с современными JRE)&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Выявлена причина падений персистентного слоя: устаревший парсер версий в &lt;code&gt;org.jpox.util.JavaUtils&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Переписана логика сравнения версий: устранено затенение переменных, добавлена корректная обработка формата &lt;code&gt;major.minor.patch&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Патч применён к библиотеке JPOX 1.1.9, пересобран и опубликован в локальном репозитории&lt;/li&gt;
  &lt;li&gt;Обеспечена стабильная работа JDO-слоя на актуальных версиях Java (17+)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;✅ Настройка mail.jar&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Устранены конфликты класслоадеров: почтовая библиотека вынесена в общий classpath сервера приложений&lt;/li&gt;
  &lt;li&gt;Настроен JNDI-ресурс &lt;code&gt;javax.mail.Session&lt;/code&gt; для корректной работы почтовых уведомлений Archiva&lt;/li&gt;
  &lt;li&gt;Обеспечена совместимость с современными API активации и предотвращён дублирующий класс-лоадинг из WEB-INF&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;✅ Конфигурация Tomcat 9 и деплой через Manager API&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Развёрнут и оптимизирован Tomcat 9 с настройкой пулов соединений и политик безопасности&lt;/li&gt;
  &lt;li&gt;Сконфигурированы JNDI-ресурсы для подключения к PostgreSQL и инициализации контекста приложения&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Освоен удалённый деплой через Tomcat Manager API:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;Настроен безопасный доступ к управляющему REST-интерфейсу&lt;/li&gt;
      &lt;li&gt;Реализована автоматическая выгрузка, обновление и откат WAR-артефактов без ручного вмешательства&lt;/li&gt;
      &lt;li&gt;Интегрирована проверка статуса развёртывания и логирование операций деплоя&lt;/li&gt;
      &lt;li&gt;Процесс полностью автоматизирован и готов к интеграции с CI/CD-конвейерами&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;✅ Настройка сборочного и клиентского окружения&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Подготовлена стандартизированная среда разработки: JDK, Maven, Git, системные зависимости&lt;/li&gt;
  &lt;li&gt;Настроен защищённый канал передачи артефактов между сборочным узлом и сервером приложений&lt;/li&gt;
  &lt;li&gt;Документирован полный цикл поставки: от клонирования кода до рабочего экземпляра в production-подобной среде&lt;/li&gt;
  &lt;li&gt;Обеспечена полная воспроизводимость процесса на любых совместимых хостах&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;📋 Итоговые артефакты и готовность&lt;/h2&gt;
&lt;pre&gt;
Сборка:
  - Исходный код: официальный релизный тег 2.2.10
  - Патч JPOX: применён, собран и зафиксирован в артефакторее
  - WAR-файл: archiva-webapp-2.2.10.war (готов к публикации)

Инфраструктура:
  - Сервер приложений: Tomcat 9 с настроенными JNDI-ресурсами
  - СУБД: PostgreSQL с выделенной схемой и пользователем для Archiva
  - Деплой: автоматизирован через Tomcat Manager REST API
&lt;/pre&gt;

&lt;h2&gt;🎯 Готовность к следующему этапу&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Работает автоматический деплой актуальной сборки через Manager API&lt;/li&gt;
  &lt;li&gt;Настроен веб-интерфейс, аутентификации и управления репозиториями&lt;/li&gt;
  &lt;li&gt;Протестирована интеграция с внешними хранилищами и системами сборки&lt;/li&gt;
  &lt;li&gt;Настройкы политики хранения, резервного копирования и мониторинга&lt;/li&gt;
&lt;/ol&gt;
</description>  </item>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%BF%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D0%BB-tightblog</guid>
    <title>Поставил TightBlog</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%BF%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D0%BB-tightblog</link>
    <pubDate>Sat, 28 Mar 2026 04:40:31 +0000</pubDate>
    <category>ЖЖ</category>
<description>  1. Технические достижения
  &lt;ul&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Запуск TightBlog 4.2.0&lt;/strong&gt; на Java 25, PostgreSQL с SSL, исправлены проблемы:&lt;/p&gt;
    &lt;ul&gt;
     &lt;li&gt;&lt;p&gt;Десериализация пароля: &lt;code&gt;@JsonProperty&lt;/code&gt; перенесены на сеттеры в &lt;code&gt;UserCredentials.java&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
     &lt;li&gt;&lt;p&gt;Схема БД: &lt;code&gt;password_hash&lt;/code&gt; в &lt;code&gt;weblogger_user&lt;/code&gt; снят &lt;code&gt;NOT NULL&lt;/code&gt; (двухэтапное сохранение: INSERT с NULL → UPDATE с хешем). Также исправлены &lt;code&gt;date_updated&lt;/code&gt; и &lt;code&gt;publish_time&lt;/code&gt; в &lt;code&gt;weblog_entry&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
     &lt;li&gt;&lt;p&gt;Фиды (Atom): исправлен шаблон &lt;code&gt;entries-atom.html:37&lt;/code&gt; (замена &lt;code&gt;updateTime&lt;/code&gt; на &lt;code&gt;dateUpdated&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
     &lt;li&gt;&lt;p&gt;Добавлен заголовок &lt;code&gt;Content-Disposition: inline&lt;/code&gt; для отображения в браузере.&lt;/p&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Роутинг&lt;/strong&gt; работает: &lt;code&gt;/aary/feed&lt;/code&gt; перенаправляется на &lt;code&gt;/tb-ui/rendering/feed/aary&lt;/code&gt; через &lt;code&gt;RequestMappingFilter&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Feedbro&lt;/strong&gt; (расширение Firefox) успешно читает локальный фид, решая проблему внешней валидации.&lt;/p&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;2. Понимание архитектуры TightBlog&lt;/h3&gt;
  &lt;ul&gt;
   &lt;li&gt;&lt;p&gt;Таблица &lt;code&gt;user_weblog_role&lt;/code&gt; была переименована из &lt;code&gt;roller_permission&lt;/code&gt; в 2015 году, семантика изменена с «права» на «роль». Это наследие Roller, но TightBlog упростил модель.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;Миграции БД перешли от Velocity-генерации к прямым SQL-файлам (Flyway). Это снизило универсальность (только PostgreSQL), но повысило прозрачность и управляемость.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;В TightBlog несколько блогов на пользователя поддерживаются, хотя в UI Roller эта функция могла отсутствовать.&lt;/p&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;3. Ключевые концепции, выработанные в диалоге&lt;/h3&gt;
  &lt;ul&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Плоские категории vs теги&lt;/strong&gt;: категории — рубрикация, теги — кросс-тематический поиск. В TightBlog категории не иерархичны.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Фиды&lt;/strong&gt;: Atom 1.0 + JSON Feed + ActivityPub (последние — для гибкости). Обнаружение фидов через &lt;code&gt;&amp;lt;link rel=&amp;quot;alternate&amp;quot;&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Мультиязычность&lt;/strong&gt; в фидах возможна через отдельные фиды по языкам или через атрибут &lt;code&gt;xml:lang&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Поиск&lt;/strong&gt;: без ИИ — использовать обратный индекс, ранжирование по доверенному кругу (организации, подписки), группировку по источникам, уточняющие вопросы.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Приватность и обнаружение&lt;/strong&gt;: нужен баланс между «кругами доверия» и шлюзами наружу. Организация как единица доверия может сертифицировать ключи, управлять доступом, модерацией.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Теги как сообщества&lt;/strong&gt;: теги становятся точками входа, имеют свои фиды, модерацию, могут быть scoped по организациям.&lt;/p&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;4. Уроки из истории&lt;/h3&gt;
  &lt;ul&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;«Мой Круг»&lt;/strong&gt; показал, что неявные круги друзей сложны в UX и не обеспечивают рост. Ваша модель «Планет» с явным членством и уставом может быть понятнее.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Провалы XMPP, Matrix, RetroShare&lt;/strong&gt; связаны с тем, что они решали технические задачи, забывая о массовом пользователе: сложный старт, отсутствие обнаружения, привязка к серверу, метаданные открыты.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Успешные системы&lt;/strong&gt; (Email, DNS) работают потому, что владельцы идентичностей заинтересованы поддерживать свои записи.&lt;/p&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;5. Предложения для будущего движка&lt;/h3&gt;
  &lt;ul&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Прогрессивная децентрализация&lt;/strong&gt;: начать с централизованного приложения, затем добавить свой домен, федерацию, P2P.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Организация как КА&lt;/strong&gt; (центр сертификации): выдаёт сертификаты участникам, публикует каталог, управляет модерацией.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Теги как службы&lt;/strong&gt;: каждый тег может иметь правила модерации, фид, уровень доступа (публичный/только для участников).&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Идентичность&lt;/strong&gt;: &lt;code&gt;did:web:org:user&lt;/code&gt; — портативная, с возможностью миграции.&lt;/p&gt;&lt;/li&gt;
   &lt;li&gt;&lt;p&gt;&lt;strong&gt;Поиск&lt;/strong&gt;: контекстный, с приоритетом доверенного круга, группировкой по источникам, опциональными шлюзами наружу.&lt;/p&gt;&lt;/li&gt;
  &lt;/ul&gt;
</description>  </item>
  <item>
    <guid isPermaLink="true">https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%BC%D0%B5%D1%81%D1%82%D0%BE-%D0%B4%D0%BB%D1%8F-%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8-%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2</guid>
    <title>Место для публикации текстов</title>
    <dc:creator>aary</dc:creator>
    <link>https://xn--90aepkp.xn--e1aqbccjfc.xn--p1acf/aary/entry/%D0%BC%D0%B5%D1%81%D1%82%D0%BE-%D0%B4%D0%BB%D1%8F-%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8-%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2</link>
    <pubDate>Thu, 19 Mar 2026 16:20:49 +0000</pubDate>
    <category>ЖЖ</category>
<description>Здесь я буду писать свои мысли. Пока, наверное, на тему создания &amp;quot;схемы технологических работ&amp;quot;. Можно подписаться (если есть чем читать подписки).</description>  </item>
</channel>
</rss>