<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>обучение и базы знаний</title><generator>teletype.in</generator><description><![CDATA[Эффективное обучение и личные картотеки. Научный взгляд 🔬
подкаст https://music.yandex.ru/album/35116811]]></description><image><url>https://img1.teletype.in/files/c4/0d/c40d1750-5e94-4707-9e71-632656722f10.png</url><title>обучение и базы знаний</title><link>https://teletype.in/@zakirov_edtech</link></image><link>https://teletype.in/@zakirov_edtech?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/zakirov_edtech?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/zakirov_edtech?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sun, 11 Oct 2026 23:09:01 GMT</pubDate><lastBuildDate>Sun, 11 Oct 2026 23:09:01 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/i37cCgPLnbT</guid><link>https://teletype.in/@zakirov_edtech/i37cCgPLnbT?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/i37cCgPLnbT?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>Практика использования персональных баз знаний и Obsidian в самообразовании XXI в.</title><pubDate>Sat, 07 Jun 2025 15:42:09 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/29/0f/290f1cc4-b462-48c9-9bad-e10ab1a70b7a.png"></media:content><description><![CDATA[<img src="https://img4.teletype.in/files/7e/24/7e2433b0-4a23-4b94-9779-19866135af89.png"></img>Написана научная работа в Институте Образования ТГУ. Информация и выводы не претендуют на достоверность, тем более научное поле совсем не исследовано. Научная работа предназначена для новичков, которые хотят ознакомиться со сферой управления персональными знаниями и для тех, кто хочет ознакомиться с программой Obsidian. Полная версия по ссылке]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="zwAa"><em>Написана научная работа в Институте Образования ТГУ. Информация и выводы не претендуют на достоверность, тем более научное поле совсем не исследовано. Научная работа предназначена для новичков, которые хотят ознакомиться со сферой управления персональными знаниями и для тех, кто хочет ознакомиться с программой Obsidian. Полная версия по <a href="https://docs.google.com/document/d/1XKDlmPNk4JcxeI0caiuJdkYxweIwS5gW/edit?usp=sharing&ouid=106160181512071754677&rtpof=true&sd=true" target="_blank">ссылке</a></em></p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <figure id="t1M3" class="m_column">
      <img src="https://img4.teletype.in/files/7e/24/7e2433b0-4a23-4b94-9779-19866135af89.png" width="1200" />
      <figcaption>Программы для ведения заметок</figcaption>
    </figure>
  </section>
  <p id="Iwra"><strong>Ниже можно ознакомиться с введением научной работы ⬇ ⬇ ⬇</strong></p>
  <p id="CxKX">В 2004 г. Анжело Маравита и Ацуси Ирики провели исследование, в ходе которого было установлено, что мозг приматов и человека, регулярно использующих инструменты, начинает воспринимать их как часть тела . Данное открытие позволяет предположить, что современные цифровые инструменты, заменившие традиционные орудия труда, также интегрируются в когнитивные процессы.</p>
  <p id="foWS">Человек в доцифровую эпоху уже обладал инструментами, позволяющими экстернализировать собственные идеи и размышления: глиняные таблички, береста, краски, бумага, перо, ручки. Подобный примитивный набор современным людям кажется недостаточным: мы храним на серверных установках столько информации, сколько никогда не уместилось бы в рукописном виде. Однако человеку в эпоху бумажных технологий хватало данного инструментария, чтобы открывать и исследовать мир.</p>
  <p id="dWEN">Сегодня нужен принципиально отличающийся подход к обработке накопленных массивов знаний человечества. Информационные технологии кардинально изменили традиционные методы самообразования, самоанализа и личностного развития. Человеку в цифровую эпоху недостаточно ручки и бумаги, так как информационный шум не позволит получить результаты форсированно – данная практика потребует большого количества времени. Использование цифровых помощников не просто рекомендация, а необходимость в условиях конкуренции за знания.</p>
  <p id="PiGu">Однако стремительный рост объема данных и развитие искусственного интеллекта требуют новых подходов к обработке знаний. Петиция о рисках ИИ, подписанная ведущими разработчиками, подчеркивает важность осмысленного управления информацией . В условиях глобального информационного взрыва XXI в. актуальной становится проблема трансформации информации в персонифицированные знания . Особую значимость этот вопрос приобретает в контексте современного образования, где возрастает роль “самонавыков”.</p>
  <p id="9CYE">В 2023 г. автором был опробован метод Zettelkasten (буквальный перевод с нем. “ящик для заметок”) Никласа Лумана, известного немецкого социолога, что позволило зафиксировать положительные эффекты от использования цифровых инструментов для создания персональных баз знаний (далее ПБЗ). С этого момента началось личное знакомство с культурой knowledge management (авторский перевод с англ. “культура управления персональными и корпоративными знаниями”). Использование программы Obsidian продемонстрировало такие преимущества, как улучшение запоминания, глубины проработки материала и генерации новых идей.</p>
  <p id="WEpK">Изучение данной программы, широко распространенного инструмента для организации персональных информационных хранилищ, позволило сформулировать закономерный вопрос: каковы причины ее относительно низкой популярности? В ходе взаимодействия были выявлены многочисленные когнитивные преимущества применения системы персональных баз знаний. К их числу относятся: интенсификация аналитических процессов, повышение качества усвоения информации, углубленная проработка материала, усиление концентрации внимания, улучшение мнемических функций, а также стимуляция генерации новых идей. Перечисленные эффекты представляют собой лишь часть положительных эффектов от использования данной методики.</p>
  <p id="MOcT">Несмотря на растущую популярность персонализированных систем управления знаниями, остается неясным, как использование данных инструментов для управления персонифицированными базами знаний коррелирует с объективными показателями эффективности самообразования, если такие существуют (скорость усвоения информации, глубина понимания, креативность выводов).</p>
  <p id="AkYP"><strong>Актуальность исследования обусловлена:</strong></p>
  <ol id="RZsM">
    <li id="jo6s">Необходимостью адаптации человека к новой образовательной, информационной и цифровой реальности, так как наблюдается высокая конкуренция за знания;</li>
    <li id="1hRG">Ростом вовлеченности взрослого населения в самообразование (по данным НИУ ВШЭ, с 21% в 2015 году до 37% в 2019 году) ;</li>
    <li id="Yi8B">Возможным потенциалом концепции управления персональными знаниями в рамках использования цифровых инструментов;</li>
    <li id="YnEs">Отсутствием эмпирических данных о влиянии ПБЗ на эффективность самообразования (научная актуальность).</li>
  </ol>
  <p id="7GtQ"><strong>Проблема исследования:</strong> противоречие между феноменом использования ПБЗ как инструмента самообразования и недостаточной изученностью эффективности данного метода обучения.</p>
  <p id="zMlZ"><strong>Цель исследования: </strong>проанализировать и обосновать роль персональных баз знаний как инструмента когнитивной оптимизации самообразования в условиях цифровой трансформации.</p>
  <p id="9xXQ"><strong>Объект исследования:</strong> персональные базы знаний в эпоху бумажных и цифровых технологий.</p>
  <p id="UQCq"><strong>Задачи научной работы:</strong></p>
  <ul id="btrE">
    <li id="DvRw">Рассмотреть предпосылки зарождения тенденции к непрерывному самообразованию;</li>
    <li id="FKt7">Проанализировать поисковые запросы и доказать популярность концепции ведения персональных баз знаний;</li>
    <li id="fR90">Провести исследование исторических предпосылок, предопределяющих современное состояние концепции управления знаниями на примере творческих личностей и ключевых исторических событий;</li>
    <li id="7ok4">Используя междисциплинарный подход, показать, какие существуют преимущества использования персональных баз знаний в рамках цифровых инструментов;</li>
    <li id="MMlI">Представить кейс с описанием конкретного практического примера применения такого инструмента, как Obsidian, для самообразования в рамках практики использования персонифицированных баз знаний.</li>
  </ul>
  <p id="R8DF"><strong>Теоретические методы исследования:</strong> анализ научной литературы.</p>
  <p id="Se8H"><strong>Эмпирические методы исследования: </strong>кейс-стади, анализ поисковых запросов, наблюдение, сравнительный анализ (приложение А).</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/S4DvC3IHKae</guid><link>https://teletype.in/@zakirov_edtech/S4DvC3IHKae?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/S4DvC3IHKae?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>Понимание/запоминание иностранных языков</title><pubDate>Tue, 11 Mar 2025 13:52:57 GMT</pubDate><category>learning</category><description><![CDATA[<img src="https://img3.teletype.in/files/a2/e3/a2e39cba-db3c-4c5d-8233-c6305a540aca.png"></img>Telegram-канал | Наш подкаст]]></description><content:encoded><![CDATA[
  <p id="OKpl" data-align="right"><strong><em><a href="https://t.me/ed_knowledgebase" target="_blank">Telegram-канал</a> </em>|<em> <a href="https://edknowledge.mave.digital" target="_blank">Наш подкаст</a></em></strong></p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="HIJe">Про мнемонику и процесс запоминания будет огромный отдельный разговор, а пока поговорим про сложные субстанции: понимание незнакомых слов, которые нельзя визуализировать</p>
  </section>
  <figure id="DRBA" class="m_original">
    <img src="https://img3.teletype.in/files/a2/e3/a2e39cba-db3c-4c5d-8233-c6305a540aca.png" width="547" />
    <figcaption>Какой fabric</figcaption>
  </figure>
  <p id="3f8s">Ключевая проблема в запоминании: <strong>это невозможность представить объект и визуализировать его</strong>. Иностранные незнакомые слова, математические формулы, химические уравнения, философские идеи – все это сложно представить в образах и к тому же сложно связать с чем-то. Это классическая история, описанная в учебниках по мнемонике 📐</p>
  <h3 id="fmxc">МФА (метод фонетических ассоциаций) решает проблему запоминания таких сложных символов. Как это работает?</h3>
  <figure id="GTtU" class="m_column">
    <img src="https://img1.teletype.in/files/c1/23/c1230c69-e0cd-4d43-ba3f-7463029b5295.png" width="579" />
    <figcaption>Факторы запоминания</figcaption>
  </figure>
  <p id="7uHP"><strong>Look = лук </strong>звучание на русском (это типичный пример запоминания). Представляете себе картинку, как из-за лука щиплет глаза <strong>--&gt;</strong> отсюда перевод <em>&quot;смотреть&quot;</em>. В следующий раз, когда попадается слово, главное удачно его произнести</p>
  <p id="Kfxs"><strong>Successfully </strong>--&gt; cложнее запоминать. Созвучных слов никаких нет, но тут вам на ум приходит какой-нибудь ваш локальный мем с этим словом. В общем: у вас есть определенная связанная история. Вспоминаете ее и проговариваете слово. <br />Еще вариант: понимание правил словообразования. Если вы знаете значение слова <em>&quot;success&quot;</em>, не затруднит и дать толкование слову<em> &quot;successfully&quot;</em>. Это логическое мышление, про него я рассказывал в выпуске подкаста <a href="https://edknowledge.mave.digital/ep-8" target="_blank"><strong>&quot;Не выучить, а запомнить термины. Основы логики&quot;</strong></a></p>
  <blockquote id="J0mH">Ключевой момент тут: <strong>это связывание</strong>. Вы связываете незнакомые символы со знакомым образом. Таким образом, незнакомый раннее набор символов превращается в конкретный образ. Как это функционирует с точки зрения когнитивных мозговых процессов – до конца не понятно</blockquote>
  <section style="background-color:hsl(hsl(263, 48%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="5m9t"><strong>⚠ Задача:</strong> остановиться на слове, которое не знаете, и вдумчиво, внимательно его разобрать (с чем связано, какие ассоциации, в каком контексте употребляется)</p>
  </section>
  <p id="JMk5">Очевидно, что запоминание vocabulary – это далеко даже не половина от изучения нового языка. Это сложный и многогранный процесс, но в данном посте пока разобрали только техники запоминания. <strong>Отдельные вопросы:</strong></p>
  <ul id="d7dT">
    <li id="Vi4p">разговорный иностранный</li>
    <li id="TlhX">мышление на иностранным языке</li>
    <li id="qr9E">флеш-карточки</li>
    <li id="9Jnl">регулярность</li>
    <li id="aeFC">иностранная среда</li>
  </ul>
  <p id="KgY6"><strong><em>Ссылки на научные материалы в telegram-канале ⬇</em></strong></p>
  <hr />
  <p id="ZGGT"><a href="https://t.me/ed_knowledgebase" target="_blank">Telegram-канал &quot;Обучение и базы знаний&quot;</a></p>
  <p id="8xTQ"><a href="https://edknowledge.mave.digital" target="_blank">Подкаст &quot;Обучение и базы знаний&quot;</a></p>
  <p id="gjjQ"><a href="http://second-brain.ru" target="_blank">Дружественное сообщество Second brain</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/qOTifC9ddKc</guid><link>https://teletype.in/@zakirov_edtech/qOTifC9ddKc?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/qOTifC9ddKc?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>Storage in Obsidian under the scalpel #1</title><pubDate>Thu, 06 Feb 2025 06:34:03 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/50/dc/50dcd8ca-eb25-4809-aa68-b924c4547162.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/65/2c/652c7f97-b41d-4b73-aa4b-836620dfa395.png"></img>Автор хранилища: Sebastian Dubois]]></description><content:encoded><![CDATA[
  <p id="YsmN" data-align="right"><em>Автор хранилища: <a href="https://www.dsebastien.net/personal-knowledge-management-at-scale-analyzing-8-000-notes-and-64-000-links/" target="_blank">Sebastian Dubois</a></em></p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h3 id="J58O" data-align="center"><strong>Общая статистика:</strong></h3>
    <p id="xYho" data-align="center"><em>8000 заметок<br />64000 ссылок-связей<br />2,8 млн. слов = эквивалент 32 книг<br />3 года работы в Obsidian</em></p>
  </section>
  <figure id="oyHQ" class="m_column">
    <img src="https://img3.teletype.in/files/65/2c/652c7f97-b41d-4b73-aa4b-836620dfa395.png" width="1217" />
    <figcaption>graph Obsidian</figcaption>
  </figure>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="ifFr"><strong>Первоначальная цель:</strong> создание надежного &quot;второго мозга&quot; для личных нужд<br /><strong>Результат:</strong> БЗ используется для создания контента, проведения исследований и применения бизнес-решений</p>
  </section>
  <blockquote id="PF24">Дело в том, что я всегда хотел иметь единый источник достоверной информации для всего своего контента и идей. Но мне потребовалось много времени, чтобы этого добиться. За последние несколько лет моя система сильно выросла, и теперь я полагаюсь на неё каждый день во всём</blockquote>
  <p id="GOdB"><strong>Плотность ссылок существенно варьируется в зависимости от типа заметки:</strong></p>
  <ul id="0KrK">
    <li id="0bOf">MOC: 90,1 ссылки на заметку</li>
    <li id="UHYj">Опубликованные статьи: 6.3 ссылки на заметку</li>
    <li id="AQlH">Литературные заметки: 5.4 ссылки на заметку</li>
    <li id="seUN">Обычные заметки: 2,9 ссылки на заметку</li>
  </ul>
  <p id="LhdY"><strong>Ключевые разделы включают:</strong></p>
  <ul id="GSXs">
    <li id="amt5">Постоянные заметки (1458 заметок, 413 тысяч слов)</li>
    <li id="or3R">Литературные заметки (2227 примечаний, 169 тысяч слов)</li>
    <li id="JFq4">MOC (118 заметок)</li>
    <li id="ViQy">Люди (635 заметок, 81 тысяча слов)</li>
    <li id="ZLJr">Цитаты (1741 заметка, 169 тысяч слов)</li>
  </ul>
  <p id="RUQu">Под литературными заметками автор вряд ли имеет в виду 1 заметка = 1 книга (как с MOC). Речь о всех заметках, связанных с прочитанной литературой. Постоянные заметки – скорее всего аналог &quot;вечнозелёных заметок&quot;. Интересное авторское решение: это заметки о людях + связанные с ним цитаты</p>
  <blockquote id="V9Av">Я очень люблю цитаты, но мне также нравится связывать идеи с людьми, которые их придумали. Поэтому у меня так много заметок о людях</blockquote>
  <hr />
  <h3 id="8WrZ" data-align="center"><strong>Automation and Templates</strong></h3>
  <ul id="TGzV">
    <li id="Iqp9">27 шаблонов</li>
    <li id="eqF3">Автоматическое перемещение заметок на основа тегов (Плагин Auto note mover)</li>
    <li id="ArZV">Автоматизация резервного копирования</li>
    <li id="rxrH">Автоматическая генерация статистики</li>
  </ul>
  <p id="SYEp">Для такого огромного хранилища есть существенная потребность в корректно настроенном резервном копировании и в доступе к актуальной статистике</p>
  <p id="ujHr">1. Шаблоны для всех типов контента для обеспечения единообразия: для каждого основного типа заметок есть отдельный шаблон (например, периодические заметки, заметки о встречах, литературные заметки, цитаты и т. д.)</p>
  <p id="bTuj">2. Автоматическая сортировка для упрощения работы с контентом: я использую плагин для автоматической сортировки заметок по тегам</p>
  <p id="yiYu">3. Специальная папка «Ресурсы» для всех вложений (1309 файлов, ~700 МБ): я не хочу думать о том, куда помещать вложения. Все они попадают в одну папку «Вложения». Чтобы найти их, я просто ориентируюсь на ссылки в соответствующих заметках</p>
  <hr />
  <h3 id="ko1N" data-align="center"><strong>System Architecture and structure</strong></h3>
  <p id="1rtE">Автор использует Obsidian в качестве инструмента для размышления (TfT) и единого источника истины (SSOT). По-русски: абсолютно любый мысленный процесс, касающихся любых жизненных сфер, происходит у автора в Obsidian</p>
  <p id="EcKX">Автор хранилища использует PARA-метод Тьяго Форте для организации папок. <a href="https://notes.dsebastien.net/30+Areas/33+Permanent+notes/33.02+Content/Johnny+Decimal+system?ref=dsebastien.net" target="_blank">Десятичная система Джонни</a> помогает поддерживать порядок в папках + Zettelkasten.</p>
  <p id="hTpF"><strong>3 принципа:</strong></p>
  <ol id="1TkL">
    <li id="R97H">Структура (PARA + Десятичная система Джонни)</li>
    <li id="i3hz">Автоматизация (про шаблоны раннее)</li>
    <li id="CVLP">Критерии для сохранения информации</li>
  </ol>
  <blockquote id="bKvF">В-третьих, и это самое важное, у меня есть реальная система. Я не собираю информацию бездумно. Я знаю о своих целях, приоритетах и о том, как я хочу, чтобы информация превращалась в знания, которые я могу использовать. Вся информация, которую я собираю, попадает в воронку, независимо от источника, и оказывается в моей интегрированной среде для мышления. Всё остальное считается временным</blockquote>
  <hr />
  <h3 id="rRqe" data-align="center"><strong>Выводы</strong></h3>
  <p id="JCBG">Несмотря на &quot;деревянность&quot; и излишнюю структурированность хранилища (чего стоит только автоматическое тегирование заметок) очевидно, что персональная база знаний полностью соответствует ожиданиям пользователя и полностью удовлетворяет его потребности. В очередной раз приходим к тому, что нет универсального решения в управлении личными знаниями</p>
  <blockquote id="A8TB">Один из важнейших уроков заключался в том, что лучшая техническая архитектура — это зачастую самая простая архитектура, способная справиться со сложностью вашего сценария использования. Хотя было заманчиво создавать сложные схемы автоматизации и организации, сочетание обычных текстовых файлов, простых структур папок и автоматизированной организации на основе тегов оказалось на удивление надёжным и удобным в обслуживании</blockquote>
  <hr />
  <p id="MQB9">✔ Telegram-канал <a href="https://t.me/ed_knowledgebase" target="_blank">Обучение и базы знаний</a></p>
  <p id="Vc81"><em>✔ Telegram-канал <a href="https://t.me/second_brain_ru" target="_blank">Second Brain</a> про управление личными знаниями</em></p>
  <p id="yPMq"><em>✔ Telegram-канал <a href="https://t.me/obsidianrus" target="_blank">Pro Obsidian</a> про Obsidian и заметковедение</em></p>
  <p id="2PJ9"><em>✔ Официальный <a href="https://second-brain.ru/" target="_blank">сайт</a> сообщества Second Brain</em></p>
  <p id="N8ZQ">✔ Youtube-канал <a href="https://www.youtube.com/@second-brain" target="_blank">Second brain</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/Lu6u_3M6FTq</guid><link>https://teletype.in/@zakirov_edtech/Lu6u_3M6FTq?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/Lu6u_3M6FTq?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>Designer and functional habit tracker in Obsidian | установка и настройка</title><pubDate>Mon, 03 Feb 2025 07:43:47 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/d6/16/d61690d6-6bc1-4858-8788-d52f3795ec7d.png"></media:content><category>Obsidian</category><description><![CDATA[<img src="https://img3.teletype.in/files/ab/06/ab06f49c-6206-425c-b746-0e5c927e95e0.jpeg"></img>Автор: Шейн Тиммонс]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="8ogJ"><strong>Автор:</strong> <a href="https://stimmons.substack.com/p/building-a-powerful-habit-tracker" target="_blank">Шейн Тиммонс</a></p>
  </section>
  <p id="nfpN">На сайте автора, где была подробная инструкция, перестали работать ссылки, поэтому пришлось искать способы реализации это трекера привычек у других пользователей</p>
  <figure id="isO8" class="m_column">
    <img src="https://img4.teletype.in/files/30/e2/30e2dffe-4143-4274-9e25-8191142aa466.png" width="2000" />
    <figcaption>Habit Tracker in Obsidian</figcaption>
  </figure>
  <h3 id="cXoG" data-align="center"><strong>Инструкция</strong></h3>
  <p id="6ghA">Все, что нужно для создания трекера привычек – это плагин Datacore и код трекера. Так как плагина нет в сторонних плагинах в Obsidian, придется устанавливать его вручную на своих страх и риск ❕</p>
  <p id="geS3">1. Скачиваем плагин <strong>BRAT </strong>из сторонних плагинов в Obsidian. Он нам нужен для установки плагина Datacore</p>
  <figure id="3UlY" class="m_column">
    <img src="https://img4.teletype.in/files/b6/1f/b61f7c5a-2088-40bc-9329-3123aac0d71e.png" width="1375" />
    <figcaption>BRAT-плагин</figcaption>
  </figure>
  <p id="cNff">2. Вызываем панель команд в Obsidian <strong>(CTRL + P)</strong>. Прописываем: <em><strong>BRAT: Plugins</strong>... </em>Выбираем<em> <strong>Add a beta plugin for testing</strong></em></p>
  <figure id="3qWg" class="m_column">
    <img src="https://img3.teletype.in/files/27/31/2731e213-687a-43bf-98dc-3a0f385344df.png" width="1182" />
    <figcaption>BRAT-плагин</figcaption>
  </figure>
  <p id="bCBu">3. В открывшемся окне вставляем ссылку на github c плагином <strong>Datacore</strong>: <a href="https://github.com/blacksmithgu/datacore" target="_blank">https://github.com/blacksmithgu/datacore</a>. Так мы установим и включим плагин</p>
  <figure id="MDvB" class="m_column">
    <img src="https://img4.teletype.in/files/bd/a2/bda2ecab-e818-43b2-8dc9-fc6a0d788e85.png" width="1128" />
    <figcaption>BRAT-плагин</figcaption>
  </figure>
  <p id="1kQM">4. Создаем пустую заметку, называем ее, как удобно. Вставляем код ⬇</p>
  <pre id="SahX">&#x60;&#x60;&#x60;datacorejsx
// Constants and color configuration
const HABITS = [
  { id: &#x27;Reading&#x27;, emoji: &#x27;📚&#x27;, label: &#x27;Reading&#x27;, defaultDuration: 25, unit: &#x27;minutes&#x27;, monthlyGoal: 1000 },
  { id: &#x27;Writing&#x27;, emoji: &#x27;✍️&#x27;, label: &#x27;Writing&#x27;, defaultDuration: 30, unit: &#x27;minutes&#x27; },
  { id: &#x27;Money&#x27;, emoji: &#x27;💰&#x27;, label: &#x27;Money&#x27;, defaultDuration: 10, unit: &#x27;dollars&#x27;, monthlyGoal: 2000 },
  { id: &#x27;Workout&#x27;, emoji: &#x27;🧘‍♂️&#x27;, label: &#x27;Workout&#x27;, defaultDuration: 30, unit: &#x27;minutes&#x27; }
];</pre>
  <pre id="9OVD">const GOALS = {
  perfectDays: {
    monthly: 20,
    yearly: 250
  }
};</pre>
  <pre id="Ld5n">const DAYS = [&#x27;Sun&#x27;, &#x27;Mon&#x27;, &#x27;Tue&#x27;, &#x27;Wed&#x27;, &#x27;Thu&#x27;, &#x27;Fri&#x27;, &#x27;Sat&#x27;];</pre>
  <pre id="VP2H">const COLORS = {
  primary: &#x27;var(--interactive-accent)&#x27;,
  secondary: &#x27;var(--background-secondary)&#x27;,
  hoverState: &#x27;var(--interactive-accent-hover)&#x27;,
  textPrimary: &#x27;var(--text-normal)&#x27;,
  textLight: &#x27;var(--text-on-accent)&#x27;,
  progressBar: {
    low: &#x27;var(--interactive-accent)&#x27;,
    medium: &#x27;var(--interactive-accent)&#x27;,
    high: &#x27;var(--interactive-accent)&#x27;,
    gradient: {
      start: &#x27;var(--interactive-accent)&#x27;,
      end: &#x27;var(--interactive-accent-hover)&#x27;
    }
  }
};</pre>
  <pre id="qgON">// Utility Functions
const formatMetricValue = (value, habit) =&gt; {
  if (value === null || value === undefined) return &#x27;0&#x27;;</pre>
  <pre id="lnEd">  switch(habit.unit) {
    case &#x27;minutes&#x27;:
      return value === 1 ? &#x27;1 Minute&#x27; : &#x60;${value} Minutes&#x60;;
    case &#x27;dollars&#x27;:
      return &#x60;$${Number(value).toLocaleString()}&#x60;;
    case &#x27;rupees&#x27;:
      return &#x60;Rs. ${Number(value).toLocaleString()}&#x60;;
    default:
      return value;
  }
};</pre>
  <pre id="HrKl">const calculateTrendPercentage = (current, previous) =&gt; {
  if (previous === 0) return current &gt; 0 ? 100 : 0;
  return ((current - previous) / previous) * 100;
};</pre>
  <pre id="zhvw">// Moved getCompletionColor to top level
const getCompletionColor = (percentage) =&gt; {
  if (percentage &gt;= 75) return COLORS.progressBar.high;
  if (percentage &gt;= 50) return COLORS.progressBar.medium;
  return COLORS.progressBar.low;
};</pre>
  <pre id="yC8C">// Base Components
const CircularProgress = ({ value, size, color = &#x27;var(--interactive-accent)&#x27; }) =&gt; {
  const strokeWidth = 4;
  const radius = (size - strokeWidth * 2) / 2;
  const circumference = 2 * Math.PI * radius;
  const progress = ((100 - value) / 100) * circumference;</pre>
  <pre id="dECq">  return (
    &lt;svg
      width={size}
      height={size}
      viewBox={&#x60;0 0 ${size} ${size}&#x60;}
      style={{
        transform: &#x27;rotate(-90deg)&#x27;,
        overflow: &#x27;visible&#x27;
      }}
    &gt;
      &lt;circle
        cx={size / 2}
        cy={size / 2}
        r={radius}
        stroke=&quot;var(--background-modifier-border)&quot;
        strokeWidth={strokeWidth}
        fill=&quot;none&quot;
      /&gt;
      &lt;circle
        cx={size / 2}
        cy={size / 2}
        r={radius}
        stroke={color}
        strokeWidth={strokeWidth}
        strokeDasharray={circumference}
        strokeDashoffset={progress}
        fill=&quot;none&quot;
        style={{
          transition: &#x27;stroke-dashoffset 0.5s ease&#x27;,
          transformOrigin: &#x27;center&#x27;
        }}
      /&gt;
    &lt;/svg&gt;
  );
};</pre>
  <pre id="XvRE">// Additional Base Components
const TrendIndicator = ({ current, previous }) =&gt; {
  const trend = calculateTrendPercentage(current, previous);
  let color = &#x27;var(--text-normal)&#x27;;
  let indicator = &#x27;→&#x27;;</pre>
  <pre id="k0cT">  if (trend &gt; 0) {
    color = &#x27;var(--color-green)&#x27;;
    indicator = &#x27;↑&#x27;;
  } else if (trend &lt; 0) {
    color = &#x27;var(--color-red)&#x27;;
    indicator = &#x27;↓&#x27;;
  }</pre>
  <pre id="RXZQ">  return (
    &lt;span style={{ color }}&gt;
      {indicator} {Math.abs(trend).toFixed(1)}%
    &lt;/span&gt;
  );
};</pre>
  <pre id="120h">const TimeInput = ({
  entry,
  habitId,
  editingTime,
  setEditingTime,
  updateHabitDuration,
  getHabitStatus,
  getHabitDuration
}) =&gt; {
  const duration = getHabitDuration(entry, habitId);
  const isEditing = editingTime?.entryPath === entry.$path &amp;&amp; editingTime?.habitId === habitId;</pre>
  <pre id="JbYu">  if (!getHabitStatus(entry, habitId)) return null;</pre>
  <pre id="fiQ7">  if (isEditing) {
    return (
      &lt;input
        type=&quot;number&quot;
        defaultValue={duration}
        min=&quot;0&quot;
        style={{
          width: &#x27;60px&#x27;,
          padding: &#x27;2px&#x27;,
          fontSize: &#x27;0.9em&#x27;,
          textAlign: &#x27;center&#x27;
        }}
        onBlur={(e) =&gt; updateHabitDuration(entry, habitId, e.target.value)}
        autoFocus
      /&gt;
    );
  }</pre>
  <pre id="x9Eg">  return (
    &lt;span
      onClick={() =&gt; setEditingTime({ entryPath: entry.$path, habitId })}
      style={{ cursor: &#x27;pointer&#x27;, fontSize: &#x27;0.8em&#x27; }}
    &gt;
      {formatMetricValue(duration, HABITS.find(h =&gt; h.id === habitId))}
    &lt;/span&gt;
  );
};</pre>
  <pre id="SasW">const ProgressBar = ({ value, max, color = &#x27;var(--interactive-accent)&#x27; }) =&gt; {
  const percentage = Math.min((value / max) * 100, 100);
  return (
    &lt;div style={{
      width: &#x27;100%&#x27;,
      height: &#x27;4px&#x27;,
      backgroundColor: &#x27;var(--background-modifier-border)&#x27;,
      borderRadius: &#x27;4px&#x27;,
      overflow: &#x27;hidden&#x27;
    }}&gt;
      &lt;div style={{
        width: &#x60;${percentage}%&#x60;,
        height: &#x27;100%&#x27;,
        backgroundColor: color,
        transition: &#x27;width 0.3s ease&#x27;
      }} /&gt;
    &lt;/div&gt;
  );
};</pre>
  <pre id="pR1Z">const StyledCard = ({ children, extraStyles = {} }) =&gt; (
  &lt;div style={{
    backgroundColor: &#x27;var(--background-primary)&#x27;,
    borderRadius: &#x27;12px&#x27;,
    boxShadow: &#x27;0 2px 8px rgba(0, 0, 0, 0.1)&#x27;,
    padding: &#x27;24px&#x27;,
    transition: &#x27;all 0.2s ease&#x27;,
    &#x27;:hover&#x27;: {
      boxShadow: &#x27;0 4px 12px rgba(0, 0, 0, 0.15)&#x27;,
      transform: &#x27;translateY(-2px)&#x27;
    },
    ...extraStyles
  }}&gt;
    {children}
  &lt;/div&gt;
);</pre>
  <pre id="dugM">const ActionButton = ({ icon, label, onClick, isActive, extraStyles = {} }) =&gt; (
  &lt;button
    onClick={onClick}
    style={{
      padding: &#x27;12px 24px&#x27;,
      borderRadius: &#x27;8px&#x27;,
      border: &#x27;none&#x27;,
      backgroundColor: isActive ? COLORS.primary : COLORS.secondary,
      color: isActive ? COLORS.textLight : COLORS.textPrimary,
      display: &#x27;flex&#x27;,
      alignItems: &#x27;center&#x27;,
      gap: &#x27;8px&#x27;,
      cursor: &#x27;pointer&#x27;,
      transition: &#x27;all 0.2s ease&#x27;,
      fontSize: &#x27;16px&#x27;,
      fontWeight: &#x27;500&#x27;,
      &#x27;:hover&#x27;: {
        transform: &#x27;translateY(-1px)&#x27;,
        backgroundColor: COLORS.primary,
        color: COLORS.textLight,
        boxShadow: &#x27;0 2px 4px rgba(0, 0, 0, 0.2)&#x27;
      },
      ...extraStyles
    }}
  &gt;
    &lt;span style={{ fontSize: &#x27;20px&#x27; }}&gt;{icon}&lt;/span&gt;
    {label &amp;&amp; &lt;span&gt;{label}&lt;/span&gt;}
  &lt;/button&gt;
);</pre>
  <pre id="niaC">const NavigationControls = ({
  selectedDate,
  navigateDate,
  activeView,
  setActiveView
}) =&gt; (
  &lt;div style={{
    display: &#x27;flex&#x27;,
    flexDirection: &#x27;column&#x27;,
    gap: &#x27;24px&#x27;
  }}&gt;
    &lt;div style={{
      display: &#x27;flex&#x27;,
      gap: &#x27;16px&#x27;,
      alignItems: &#x27;center&#x27;,
      justifyContent: &#x27;center&#x27;,
      background: COLORS.secondary,
      padding: &#x27;8px 16px&#x27;,
      borderRadius: &#x27;12px&#x27;,
      boxShadow: &#x27;var(--shadow-s)&#x27;
    }}&gt;
      &lt;ActionButton
        icon=&quot;←&quot;
        onClick={() =&gt; navigateDate(-1)}
        extraStyles={{
          backgroundColor: COLORS.primary,
          color: COLORS.textLight
        }}
      /&gt;
      &lt;div style={{
        fontWeight: &#x27;bold&#x27;,
        fontSize: &#x27;24px&#x27;,
        minWidth: &#x27;240px&#x27;,
        textAlign: &#x27;center&#x27;,
        fontFamily: &#x27;var(--font-interface)&#x27;,
        background: &#x27;var(--background-primary)&#x27;,
        padding: &#x27;8px 16px&#x27;,
        borderRadius: &#x27;8px&#x27;,
        boxShadow: &#x27;var(--shadow-s)&#x27;
      }}&gt;
        {selectedDate.toFormat(&#x27;MMMM dd, yyyy&#x27;)}
      &lt;/div&gt;
      &lt;ActionButton
        icon=&quot;→&quot;
        onClick={() =&gt; navigateDate(1)}
        extraStyles={{
          backgroundColor: COLORS.primary,
          color: COLORS.textLight
        }}
      /&gt;
    &lt;/div&gt;
  &lt;/div&gt;
);</pre>
  <pre id="N4fM">const CalendarView = ({
  selectedDate,
  sortedNotes,
  getHabitStatus,
  calculateCompletedHabits,
  updateHabit,
  getHabitDuration,
  editingTime,
  setEditingTime,
  updateHabitDuration
}) =&gt; {
  const dates = [];
  let currentDate = selectedDate;</pre>
  <pre id="Uk8e">  // Show last 7 days (today and previous 6 days)
  for (let i = 0; i &lt; 7; i++) {
    dates.push(currentDate.minus({ days: i }));
  }</pre>
  <pre id="Vvvy">  const notesMap = new Map(sortedNotes.map(note =&gt; [note.$name, note]));
  const today = dc.luxon.DateTime.now().startOf(&#x27;day&#x27;);</pre>
  <pre id="4yu1">  return (
    &lt;div style={{
      width: &#x27;100%&#x27;,
      overflow: &#x27;hidden&#x27;,
      padding: &#x27;8px 4px&#x27;
    }}&gt;
      &lt;div style={{
        display: &#x27;flex&#x27;,
        gap: &#x27;12px&#x27;,
        overflowX: &#x27;auto&#x27;,
        paddingBottom: &#x27;12px&#x27;,
        WebkitOverflowScrolling: &#x27;touch&#x27;,
        scrollbarWidth: &#x27;none&#x27;,
        msOverflowStyle: &#x27;none&#x27;,
        &#x27;::-webkit-scrollbar&#x27;: {
          display: &#x27;none&#x27;
        }
      }}&gt;
        {dates.map((date) =&gt; {
          const dateStr = date.toFormat(&#x27;yyyy-MM-dd&#x27;);
          const entry = notesMap.get(dateStr);
          const isSelected = date.hasSame(selectedDate, &#x27;day&#x27;);
          const isToday = date.hasSame(today, &#x27;day&#x27;);</pre>
  <pre id="151V">          return (
            &lt;div style={{
              flex: &#x27;0 0 320px&#x27;,
              maxWidth: &#x27;320px&#x27;
            }}&gt;
              &lt;CalendarDayCard
                key={dateStr}
                date={date}
                entry={entry}
                getHabitStatus={getHabitStatus}
                calculateCompletedHabits={calculateCompletedHabits}
                isSelected={isSelected}
                isToday={isToday}
                updateHabit={updateHabit}
                getHabitDuration={getHabitDuration}
                editingTime={editingTime}
                setEditingTime={setEditingTime}
                updateHabitDuration={updateHabitDuration}
              /&gt;
            &lt;/div&gt;
          );
        })}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</pre>
  <pre id="3Ggl">const CalendarDayCard = ({
  date,
  entry,
  getHabitStatus,
  calculateCompletedHabits,
  isSelected,
  isToday,
  updateHabit,
  getHabitDuration,
  editingTime,
  setEditingTime,
  updateHabitDuration
}) =&gt; {
  const completedCount = calculateCompletedHabits(entry);
  const completionPercentage = entry ? Math.round((completedCount / HABITS.length) * 100) : 0;</pre>
  <pre id="utbQ">  return (
    &lt;div style={{
      padding: &#x27;12px&#x27;,
      borderRadius: &#x27;16px&#x27;,
      backgroundColor: &#x27;var(--background-primary)&#x27;,
      color: COLORS.textPrimary,
      boxShadow: &#x27;var(--shadow-s)&#x27;,
      border: isSelected ? &#x60;2px solid ${COLORS.primary}&#x60; : &#x27;1px solid var(--background-modifier-border)&#x27;,
      transition: &#x27;all 0.3s cubic-bezier(0.4, 0, 0.2, 1)&#x27;,
      display: &#x27;flex&#x27;,
      flexDirection: &#x27;column&#x27;,
      gap: &#x27;8px&#x27;,
      minHeight: &#x27;168px&#x27;
    }}&gt;
      &lt;div style={{
        display: &#x27;flex&#x27;,
        justifyContent: &#x27;space-between&#x27;,
        alignItems: &#x27;center&#x27;,
        backgroundColor: COLORS.secondary,
        padding: &#x27;8px 12px&#x27;,
        borderRadius: &#x27;10px&#x27;
      }}&gt;
        &lt;span style={{
          fontSize: &#x27;1em&#x27;,
          fontWeight: &#x27;600&#x27;,
          color: COLORS.textPrimary
        }}&gt;
          {DAYS[date.weekday % 7]}
        &lt;/span&gt;
        &lt;span style={{
          fontWeight: &#x27;500&#x27;,
          fontSize: &#x27;0.9em&#x27;,
          color: COLORS.textPrimary
        }}&gt;
          {date.toFormat(&#x27;MM-dd&#x27;)}
        &lt;/span&gt;
      &lt;/div&gt;</pre>
  <pre id="F3tD">      {entry &amp;&amp; (
        &lt;&gt;
          &lt;div style={{
            display: &#x27;grid&#x27;,
            gridTemplateColumns: &#x27;repeat(auto-fit, minmax(120px, 1fr))&#x27;,
            gap: &#x27;8px&#x27;,
            flex: 1,
            padding: &#x27;2px&#x27;
          }}&gt;
            {HABITS.map(habit =&gt; {
              const isCompleted = getHabitStatus(entry, habit.id);
              const duration = getHabitDuration(entry, habit.id);</pre>
  <pre id="aE6Z">              return (
                &lt;div
                  key={habit.id}
                  onClick={() =&gt; updateHabit(entry, habit.id)}
                  style={{
                    display: &#x27;flex&#x27;,
                    flexDirection: &#x27;column&#x27;,
                    alignItems: &#x27;center&#x27;,
                    justifyContent: &#x27;center&#x27;,
                    gap: &#x27;4px&#x27;,
                    backgroundColor: isCompleted ? COLORS.primary : COLORS.secondary,
                    borderRadius: &#x27;10px&#x27;,
                    cursor: &#x27;pointer&#x27;,
                    padding: &#x27;12px&#x27;,
                    width: &#x27;100%&#x27;,
                    minHeight: &#x27;80px&#x27;,
                    transition: &#x27;all 0.2s ease&#x27;
                  }}
                &gt;
                  &lt;span style={{
                    fontSize: &#x27;24px&#x27;,
                    marginBottom: &#x27;4px&#x27;
                  }}&gt;
                    {habit.emoji}
                  &lt;/span&gt;
                  &lt;span style={{
                    fontSize: &#x27;0.95em&#x27;,
                    fontWeight: &#x27;600&#x27;,
                    color: isCompleted ? COLORS.textLight : COLORS.textPrimary,
                    letterSpacing: &#x27;0.2px&#x27;,
                    textAlign: &#x27;center&#x27;,
                    lineHeight: &#x27;1.2&#x27;
                  }}&gt;
                    {habit.label}
                  &lt;/span&gt;
                  {isCompleted &amp;&amp; duration &amp;&amp; (
                    &lt;span style={{
                      fontSize: &#x27;0.75em&#x27;,
                      fontWeight: &#x27;600&#x27;,
                      color: isCompleted ? COLORS.textLight : COLORS.textPrimary,
                      textAlign: &#x27;center&#x27;
                    }}&gt;
                      {formatMetricValue(duration, habit)}
                    &lt;/span&gt;
                  )}
                &lt;/div&gt;
              );
            })}
          &lt;/div&gt;</pre>
  <pre id="Rb3T">          &lt;div style={{
            marginTop: &#x27;auto&#x27;,
            display: &#x27;flex&#x27;,
            flexDirection: &#x27;column&#x27;,
            gap: &#x27;4px&#x27;
          }}&gt;
            &lt;ProgressBar
              value={completedCount}
              max={HABITS.length}
              color={getCompletionColor(completionPercentage)}
            /&gt;
            &lt;div style={{
              textAlign: &#x27;right&#x27;,
              fontSize: &#x27;0.8em&#x27;,
              fontWeight: &#x27;600&#x27;,
              color: getCompletionColor(completionPercentage)
            }}&gt;
              {completionPercentage}%
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/&gt;
      )}
    &lt;/div&gt;
  );
};</pre>
  <pre id="MwwL">const MetricCard = ({ habit, current, previous, ytdTotal }) =&gt; {
  const trend = calculateTrendPercentage(current, previous);
  const formattedTotal = formatMetricValue(current, habit);
  const formattedYTD = formatMetricValue(ytdTotal, habit);</pre>
  <pre id="coun">  return (
    &lt;div style={{
      backgroundColor: &#x27;var(--background-primary)&#x27;,
      borderRadius: &#x27;16px&#x27;,
      padding: &#x27;24px&#x27;,
      boxShadow: &#x27;var(--shadow-s)&#x27;,
      display: &#x27;flex&#x27;,
      flexDirection: &#x27;column&#x27;,
      gap: &#x27;16px&#x27;
    }}&gt;
      &lt;div style={{
        display: &#x27;flex&#x27;,
        alignItems: &#x27;center&#x27;,
        gap: &#x27;12px&#x27;
      }}&gt;
        &lt;div style={{
          fontSize: &#x27;32px&#x27;,
          backgroundColor: COLORS.secondary,
          borderRadius: &#x27;12px&#x27;,
          padding: &#x27;12px&#x27;,
          display: &#x27;flex&#x27;,
          alignItems: &#x27;center&#x27;,
          justifyContent: &#x27;center&#x27;
        }}&gt;
          {habit.emoji}
        &lt;/div&gt;
        &lt;div&gt;
          &lt;h3 style={{ margin: 0 }}&gt;{habit.label}&lt;/h3&gt;
          &lt;div style={{
            color: &#x27;var(--text-muted)&#x27;,
            fontSize: &#x27;0.9em&#x27;
          }}&gt;
            Last 30 Days
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;</pre>
  <pre id="ugLX">      &lt;div style={{
        display: &#x27;grid&#x27;,
        gridTemplateColumns: &#x27;repeat(2, 1fr)&#x27;,
        gap: &#x27;16px&#x27;
      }}&gt;
        &lt;div style={{
          backgroundColor: COLORS.secondary,
          padding: &#x27;16px&#x27;,
          borderRadius: &#x27;12px&#x27;,
          textAlign: &#x27;center&#x27;
        }}&gt;
          &lt;div style={{ fontSize: &#x27;0.9em&#x27;, color: &#x27;var(--text-muted)&#x27; }}&gt;Current&lt;/div&gt;
          &lt;div style={{
            fontSize: &#x27;1.4em&#x27;,
            fontWeight: &#x27;bold&#x27;,
            marginTop: &#x27;4px&#x27;
          }}&gt;
            {formattedTotal}
          &lt;/div&gt;
        &lt;/div&gt;</pre>
  <pre id="MDk8">        &lt;div style={{
          backgroundColor: COLORS.secondary,
          padding: &#x27;16px&#x27;,
          borderRadius: &#x27;12px&#x27;,
          textAlign: &#x27;center&#x27;
        }}&gt;
          &lt;div style={{ fontSize: &#x27;0.9em&#x27;, color: &#x27;var(--text-muted)&#x27; }}&gt;YTD&lt;/div&gt;
          &lt;div style={{
            fontSize: &#x27;1.4em&#x27;,
            fontWeight: &#x27;bold&#x27;,
            marginTop: &#x27;4px&#x27;
          }}&gt;
            {formattedYTD}
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;</pre>
  <pre id="UWUa">      &lt;div style={{
        display: &#x27;flex&#x27;,
        alignItems: &#x27;center&#x27;,
        justifyContent: &#x27;space-between&#x27;,
        backgroundColor: COLORS.secondary,
        padding: &#x27;12px 16px&#x27;,
        borderRadius: &#x27;12px&#x27;
      }}&gt;
        &lt;span&gt;Trend&lt;/span&gt;
        &lt;TrendIndicator current={current} previous={previous} /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</pre>
  <pre id="YvlB">const TrendsView = ({ trends }) =&gt; {
  const monthlyProgress = (trends.currentMonth.perfectDays / GOALS.perfectDays.monthly) * 100;
  const yearlyProgress = (trends.yearToDate.perfectDays / GOALS.perfectDays.yearly) * 100;</pre>
  <pre id="YJKe">  return (
    &lt;div style={{
      padding: &#x27;24px&#x27;,
      display: &#x27;flex&#x27;,
      flexDirection: &#x27;column&#x27;,
      gap: &#x27;32px&#x27;
    }}&gt;
      &lt;div style={{
        display: &#x27;grid&#x27;,
        gridTemplateColumns: &#x27;repeat(auto-fit, minmax(280px, 1fr))&#x27;,
        gap: &#x27;24px&#x27;
      }}&gt;
        &lt;div style={{
          backgroundColor: &#x27;var(--background-primary)&#x27;,
          borderRadius: &#x27;16px&#x27;,
          padding: &#x27;24px&#x27;,
          display: &#x27;flex&#x27;,
          alignItems: &#x27;center&#x27;,
          gap: &#x27;24px&#x27;,
          boxShadow: &#x27;var(--shadow-s)&#x27;
        }}&gt;
          &lt;CircularProgress value={monthlyProgress} size={100} color={COLORS.primary} /&gt;
          &lt;div&gt;
            &lt;h3 style={{ margin: &#x27;0 0 8px 0&#x27;, color: &#x27;var(--text-normal)&#x27; }}&gt;Monthly Goal&lt;/h3&gt;
            &lt;div style={{ fontSize: &#x27;1.2em&#x27;, fontWeight: &#x27;bold&#x27;, color: &#x27;var(--text-normal)&#x27; }}&gt;
              {trends.currentMonth.perfectDays}/{GOALS.perfectDays.monthly} Perfect Days
            &lt;/div&gt;
            &lt;div style={{ color: &#x27;var(--text-muted)&#x27; }}&gt;
              {monthlyProgress.toFixed(1)}% Complete
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;</pre>
  <pre id="XGF7">        &lt;div style={{
          backgroundColor: &#x27;var(--background-primary)&#x27;,
          borderRadius: &#x27;16px&#x27;,
          padding: &#x27;24px&#x27;,
          display: &#x27;flex&#x27;,
          alignItems: &#x27;center&#x27;,
          gap: &#x27;24px&#x27;,
          boxShadow: &#x27;var(--shadow-s)&#x27;
        }}&gt;
          &lt;CircularProgress value={yearlyProgress} size={100} color={COLORS.progressBar.high} /&gt;
          &lt;div&gt;
            &lt;h3 style={{ margin: &#x27;0 0 8px 0&#x27;, color: &#x27;var(--text-normal)&#x27; }}&gt;Yearly Goal&lt;/h3&gt;
            &lt;div style={{ fontSize: &#x27;1.2em&#x27;, fontWeight: &#x27;bold&#x27;, color: &#x27;var(--text-normal)&#x27; }}&gt;
              {trends.yearToDate.perfectDays}/{GOALS.perfectDays.yearly} Perfect Days
            &lt;/div&gt;
            &lt;div style={{ color: &#x27;var(--text-muted)&#x27; }}&gt;
              {yearlyProgress.toFixed(1)}% Complete
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;</pre>
  <pre id="Y4ql">        &lt;div style={{
          backgroundColor: &#x27;var(--background-primary)&#x27;,
          borderRadius: &#x27;16px&#x27;,
          padding: &#x27;24px&#x27;,
          display: &#x27;flex&#x27;,
          alignItems: &#x27;center&#x27;,
          gap: &#x27;24px&#x27;,
          boxShadow: &#x27;var(--shadow-s)&#x27;
        }}&gt;
          &lt;div style={{
            width: &#x27;100px&#x27;,
            height: &#x27;100px&#x27;,
            display: &#x27;flex&#x27;,
            alignItems: &#x27;center&#x27;,
            justifyContent: &#x27;center&#x27;,
            fontSize: &#x27;48px&#x27;,
            backgroundColor: &#x27;var(--background-secondary)&#x27;,
            borderRadius: &#x27;50%&#x27;
          }}&gt;
            🔥
          &lt;/div&gt;
          &lt;div&gt;
            &lt;h3 style={{ margin: &#x27;0 0 8px 0&#x27;, color: &#x27;var(--text-normal)&#x27; }}&gt;Current Streak&lt;/h3&gt;
            &lt;div style={{ fontSize: &#x27;1.2em&#x27;, fontWeight: &#x27;bold&#x27;, color: &#x27;var(--text-normal)&#x27; }}&gt;
              {trends.last30Days.perfectDays} Days
            &lt;/div&gt;
            &lt;div style={{ color: &#x27;var(--text-muted)&#x27; }}&gt;
              Last 30 Days
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;</pre>
  <pre id="l6I8">      &lt;div style={{
        display: &#x27;grid&#x27;,
        gridTemplateColumns: &#x27;repeat(auto-fit, minmax(300px, 1fr))&#x27;,
        gap: &#x27;24px&#x27;
      }}&gt;
        {HABITS.map(habit =&gt; (
          &lt;MetricCard
            key={habit.id}
            habit={habit}
            current={trends.last30Days.habitMetrics[habit.id].total}
            previous={trends.last30Days.habitMetrics[habit.id].previousPeriodTotal}
            ytdTotal={trends.yearToDate.habitMetrics[habit.id].total}
          /&gt;
        ))}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</pre>
  <pre id="SVNE">const HistoricalView = ({
  sortedNotes,
  currentPage,
  setCurrentPage,
  updateHabit,
  getHabitStatus,
  getHabitDuration,
  editingTime,
  setEditingTime,
  updateHabitDuration,
  calculateCompletedHabits
}) =&gt; {
  const itemsPerPage = 20;
  const totalPages = Math.ceil(sortedNotes.length / itemsPerPage);
  const startIndex = currentPage * itemsPerPage;
  const displayNotes = sortedNotes.slice(startIndex, startIndex + itemsPerPage);</pre>
  <pre id="FWEt">  return (
    &lt;div style={{
      padding: &#x27;24px&#x27;,
      backgroundColor: COLORS.secondary,
      borderRadius: &#x27;12px&#x27;,
      marginTop: &#x27;24px&#x27;
    }}&gt;
      &lt;h3 style={{ margin: &#x27;0 0 20px 0&#x27; }}&gt;Historical Data&lt;/h3&gt;</pre>
  <pre id="iviA">      &lt;div style={{
        width: &#x27;100%&#x27;,
        overflow: &#x27;auto&#x27;,
        borderRadius: &#x27;12px&#x27;,
        boxShadow: &#x27;var(--shadow-s)&#x27;,
        backgroundColor: &#x27;var(--background-primary)&#x27;
      }}&gt;
        &lt;table style={{
          width: &#x27;100%&#x27;,
          borderCollapse: &#x27;separate&#x27;,
          borderSpacing: 0
        }}&gt;
          &lt;thead&gt;
            &lt;tr&gt;
              &lt;th style={{
                padding: &#x27;16px&#x27;,
                backgroundColor: COLORS.secondary,
                color: COLORS.textPrimary,
                fontWeight: &#x27;bold&#x27;,
                textAlign: &#x27;left&#x27;,
                position: &#x27;sticky&#x27;,
                top: 0,
                zIndex: 10,
              }}&gt;Date&lt;/th&gt;
              {HABITS.map(habit =&gt; (
                &lt;th key={habit.id} style={{
                  padding: &#x27;16px&#x27;,
                  backgroundColor: COLORS.secondary,
                  color: COLORS.textPrimary,
                  fontWeight: &#x27;bold&#x27;,
                  textAlign: &#x27;center&#x27;,
                  position: &#x27;sticky&#x27;,
                  top: 0,
                  zIndex: 10,
                }}&gt;
                  &lt;div style={{ fontSize: &#x27;1.4em&#x27; }}&gt;{habit.emoji}&lt;/div&gt;
                  &lt;div&gt;{habit.label}&lt;/div&gt;
                &lt;/th&gt;
              ))}
              &lt;th style={{
                padding: &#x27;16px&#x27;,
                backgroundColor: COLORS.secondary,
                color: COLORS.textPrimary,
                fontWeight: &#x27;bold&#x27;,
                textAlign: &#x27;center&#x27;,
                position: &#x27;sticky&#x27;,
                top: 0,
                zIndex: 10,
              }}&gt;Completion&lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;
            {displayNotes.map((entry, index) =&gt; (
              &lt;tr key={entry.$path} style={{
                backgroundColor: index % 2 === 0 ? &#x27;var(--background-primary)&#x27; : &#x27;var(--background-secondary)&#x27;
              }}&gt;
                &lt;td style={{
                  padding: &#x27;12px 16px&#x27;,
                  borderBottom: &#x27;1px solid rgba(0, 0, 0, 0.05)&#x27;,
                  minWidth: &#x27;150px&#x27;
                }}&gt;{entry.$name}&lt;/td&gt;
                {HABITS.map(habit =&gt; {
                  const isCompleted = getHabitStatus(entry, habit.id);
                  return (
                    &lt;td key={habit.id} style={{
                      padding: &#x27;12px 16px&#x27;,
                      borderBottom: &#x27;1px solid rgba(0, 0, 0, 0.05)&#x27;,
                      textAlign: &#x27;center&#x27;,
                      minWidth: &#x27;120px&#x27;
                    }}&gt;
                      &lt;div style={{
                        display: &#x27;flex&#x27;,
                        flexDirection: &#x27;column&#x27;,
                        alignItems: &#x27;center&#x27;,
                        gap: &#x27;4px&#x27;
                      }}&gt;
                        &lt;div
                          onClick={() =&gt; updateHabit(entry, habit.id)}
                          style={{
                            padding: &#x27;4px 8px&#x27;,
                            borderRadius: &#x27;4px&#x27;,
                            backgroundColor: isCompleted ? COLORS.primary : COLORS.secondary,
                            color: isCompleted ? COLORS.textLight : &#x27;var(--text-muted)&#x27;,
                            cursor: &#x27;pointer&#x27;
                          }}
                        &gt;
                          {isCompleted ? &#x27;✓&#x27; : &#x27;×&#x27;}
                        &lt;/div&gt;
                        {isCompleted &amp;&amp; (
                          &lt;TimeInput
                            entry={entry}
                            habitId={habit.id}
                            editingTime={editingTime}
                            setEditingTime={setEditingTime}
                            updateHabitDuration={updateHabitDuration}
                            getHabitStatus={getHabitStatus}
                            getHabitDuration={getHabitDuration}
                          /&gt;
                        )}
                      &lt;/div&gt;
                    &lt;/td&gt;
                  );
                })}
                &lt;td style={{
                  padding: &#x27;12px 16px&#x27;,
                  borderBottom: &#x27;1px solid rgba(0, 0, 0, 0.05)&#x27;,
                  textAlign: &#x27;center&#x27;,
                  color: getCompletionColor(Math.round((calculateCompletedHabits(entry) / HABITS.length) * 100)),
                  fontWeight: &#x27;600&#x27;
                }}&gt;
                  {Math.round((calculateCompletedHabits(entry) / HABITS.length) * 100)}%
                &lt;/td&gt;
              &lt;/tr&gt;
            ))}
          &lt;/tbody&gt;
        &lt;/table&gt;
      &lt;/div&gt;</pre>
  <pre id="YvCI">      &lt;div style={{
        display: &#x27;flex&#x27;,
        justifyContent: &#x27;center&#x27;,
        gap: &#x27;8px&#x27;,
        marginTop: &#x27;16px&#x27;
      }}&gt;
        &lt;ActionButton
          icon=&quot;←&quot;
          onClick={() =&gt; setCurrentPage(prev =&gt; Math.max(0, prev - 1))}
          extraStyles={{
            opacity: currentPage === 0 ? 0.5 : 1,
            cursor: currentPage === 0 ? &#x27;default&#x27; : &#x27;pointer&#x27;
          }}
        /&gt;
        &lt;span style={{
          padding: &#x27;8px 16px&#x27;,
          backgroundColor: &#x27;var(--background-primary)&#x27;,
          borderRadius: &#x27;8px&#x27;
        }}&gt;
          Page {currentPage + 1} of {totalPages}
        &lt;/span&gt;
        &lt;ActionButton
          icon=&quot;→&quot;
          onClick={() =&gt; setCurrentPage(prev =&gt; Math.min(totalPages - 1, prev + 1))}
          extraStyles={{
            opacity: currentPage === totalPages - 1 ? 0.5 : 1,
            cursor: currentPage === totalPages - 1 ? &#x27;default&#x27; : &#x27;pointer&#x27;
          }}
        /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</pre>
  <pre id="vEOo">const GoalsView = ({ entries, daysInMonth }) =&gt; {
  const habitsWithGoals = HABITS.filter(h =&gt; h.monthlyGoal);</pre>
  <pre id="1fpo">  const calculateProgress = (habitId) =&gt; {
    const total = entries.reduce((sum, entry) =&gt; sum + (entry?.value(habitId) ?? 0), 0);
    const habit = HABITS.find(h =&gt; h.id === habitId);</pre>
  <pre id="tZ1L">    // Count days that actually have data
    const daysWithData = entries.filter(entry =&gt; {
      const value = entry?.value(habitId);
      return value !== null &amp;&amp; value !== undefined &amp;&amp; value &gt; 0;
    }).length;</pre>
  <pre id="X2fg">    // Calculate progress against monthly goal
    const progress = (total / habit.monthlyGoal) * 100;</pre>
  <pre id="FU8s">    // Calculate daily average based on days with actual data, or 1 if no days have data
    const daysForAverage = Math.max(daysWithData, 1);
    const dailyAverage = Number((total / daysForAverage).toFixed(2));</pre>
  <pre id="VDTh">    // Project monthly total based on daily average
    const projection = Number((dailyAverage * daysInMonth).toFixed(2));
    const isOnTrack = projection &gt;= habit.monthlyGoal;</pre>
  <pre id="Ya1z">    return {
      total,
      progress: Number(Math.min(progress, 100).toFixed(2)),
      dailyAverage,
      projection,
      isOnTrack,
      daysWithData
    };
  };</pre>
  <pre id="kZSO">  const getProgressGradient = (isOnTrack) =&gt; {
    return {
      start: isOnTrack ? COLORS.progressBar.gradient.start : COLORS.progressBar.gradient.start,
      end: isOnTrack ? COLORS.progressBar.gradient.end : COLORS.progressBar.gradient.end
    };
  };</pre>
  <pre id="rxYH">  return (
    &lt;div style={{
      padding: &#x27;16px&#x27;,
      width: &#x27;100%&#x27;,
      maxWidth: &#x27;100%&#x27;
    }}&gt;
      &lt;div style={{
        display: &#x27;grid&#x27;,
        gridTemplateColumns: &#x27;repeat(auto-fit, minmax(450px, 1fr))&#x27;,
        gap: &#x27;24px&#x27;,
        width: &#x27;100%&#x27;
      }}&gt;
        {habitsWithGoals.map(habit =&gt; {
          const stats = calculateProgress(habit.id);
          const progressColor = stats.isOnTrack ? COLORS.progressBar.high : COLORS.progressBar.low;
          const gradient = getProgressGradient(stats.isOnTrack);</pre>
  <pre id="SkyI">          return (
            &lt;div key={habit.id} style={{
              background: &#x27;var(--background-secondary)&#x27;,
              borderRadius: &#x27;12px&#x27;,
              padding: &#x27;24px&#x27;,
              boxShadow: &#x27;var(--shadow-s)&#x27;,
              minWidth: &#x27;450px&#x27;,
              flex: &#x27;1 1 auto&#x27;
            }}&gt;
              &lt;div style={{
                display: &#x27;flex&#x27;,
                alignItems: &#x27;center&#x27;,
                gap: &#x27;16px&#x27;,
                marginBottom: &#x27;16px&#x27;
              }}&gt;
                &lt;div style={{
                  width: &#x27;100px&#x27;,
                  height: &#x27;100px&#x27;,
                  position: &#x27;relative&#x27;
                }}&gt;
                  &lt;CircularProgress
                    progress={stats.progress}
                    size={100}
                    strokeWidth={10}
                    circleColor={progressColor}
                    gradientStart={gradient.start}
                    gradientEnd={gradient.end}
                  /&gt;
                  &lt;div style={{
                    position: &#x27;absolute&#x27;,
                    top: &#x27;50%&#x27;,
                    left: &#x27;50%&#x27;,
                    transform: &#x27;translate(-50%, -50%)&#x27;,
                    fontSize: &#x27;42px&#x27;,
                    display: &#x27;flex&#x27;,
                    alignItems: &#x27;center&#x27;,
                    justifyContent: &#x27;center&#x27;,
                    width: &#x27;80%&#x27;,
                    height: &#x27;80%&#x27;
                  }}&gt;
                    {habit.emoji}
                  &lt;/div&gt;
                &lt;/div&gt;</pre>
  <pre id="0GnZ">                &lt;div style={{ flex: 1 }}&gt;
                  &lt;h3 style={{
                    margin: &#x27;0 0 8px 0&#x27;,
                    textAlign: &#x27;center&#x27;,
                    fontSize: &#x27;1.4em&#x27;,
                    color: &#x27;var(--text-normal)&#x27;
                  }}&gt;{habit.label}&lt;/h3&gt;
                  &lt;div style={{
                    display: &#x27;grid&#x27;,
                    gridTemplateColumns: &#x27;1fr 1fr&#x27;,
                    gap: &#x27;12px&#x27;
                  }}&gt;
                    &lt;Stat
                      label=&quot;Current&quot;
                      value={formatMetricValue(stats.total, habit)}
                    /&gt;
                    &lt;Stat
                      label=&quot;Goal&quot;
                      value={formatMetricValue(habit.monthlyGoal, habit)}
                    /&gt;
                    &lt;Stat
                      label=&quot;Daily Avg&quot;
                      value={formatMetricValue(stats.dailyAverage, habit)}
                    /&gt;
                    &lt;Stat
                      label=&quot;Projected&quot;
                      value={formatMetricValue(stats.projection, habit)}
                      color={stats.isOnTrack ? &#x27;var(--color-green)&#x27; : &#x27;var(--color-red)&#x27;}
                    /&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;</pre>
  <pre id="rND4">              &lt;div style={{
                height: &#x27;40px&#x27;,
                background: &#x27;var(--background-primary)&#x27;,
                borderRadius: &#x27;20px&#x27;,
                overflow: &#x27;hidden&#x27;,
                position: &#x27;relative&#x27;
              }}&gt;
                &lt;div style={{
                  position: &#x27;absolute&#x27;,
                  top: &#x27;0&#x27;,
                  left: &#x27;0&#x27;,
                  height: &#x27;100%&#x27;,
                  width: &#x60;${stats.progress}%&#x60;,
                  background: &#x60;linear-gradient(90deg, ${gradient.start} 0%, ${gradient.end} 100%)&#x60;,
                  transition: &#x27;width 0.3s ease&#x27;
                }} /&gt;
                &lt;div style={{
                  position: &#x27;absolute&#x27;,
                  top: &#x27;50%&#x27;,
                  left: &#x27;50%&#x27;,
                  transform: &#x27;translate(-50%, -50%)&#x27;,
                  color: &#x27;var(--text-normal)&#x27;,
                  fontWeight: &#x27;bold&#x27;
                }}&gt;
                  {stats.progress}%
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          );
        })}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</pre>
  <pre id="KffV">const WeeklyGoalsView = ({ entries }) =&gt; {
  const habitsWithGoals = HABITS.filter(h =&gt; h.monthlyGoal);
  const daysInWeek = 7;</pre>
  <pre id="pBdZ">  const calculateWeeklyProgress = (habitId) =&gt; {
    const total = entries.reduce((sum, entry) =&gt; sum + (entry?.value(habitId) ?? 0), 0);
    const habit = HABITS.find(h =&gt; h.id === habitId);</pre>
  <pre id="qRq5">    // Count days that actually have data
    const daysWithData = entries.filter(entry =&gt; {
      const value = entry?.value(habitId);
      return value !== null &amp;&amp; value !== undefined &amp;&amp; value &gt; 0;
    }).length;</pre>
  <pre id="ntCt">    // Calculate weekly goal as a proportion of monthly goal
    const weeklyGoal = Math.round(habit.monthlyGoal * (daysInWeek / 30));
    const progress = (total / weeklyGoal) * 100;</pre>
  <pre id="q65H">    // Calculate daily average based on days with actual data, or 1 if no days have data
    const daysForAverage = Math.max(daysWithData, 1);
    const dailyAverage = Number((total / daysForAverage).toFixed(2));</pre>
  <pre id="qWDe">    const projection = Number((dailyAverage * daysInWeek).toFixed(2));
    const isOnTrack = projection &gt;= weeklyGoal;</pre>
  <pre id="4HjU">    return {
      total,
      weeklyGoal,
      progress: Number(Math.min(progress, 100).toFixed(2)),
      dailyAverage,
      projection,
      isOnTrack,
      daysWithData
    };
  };</pre>
  <pre id="qwbQ">  const getProgressGradient = (isOnTrack) =&gt; {
    return {
      start: isOnTrack ? COLORS.progressBar.gradient.start : COLORS.progressBar.gradient.start,
      end: isOnTrack ? COLORS.progressBar.gradient.end : COLORS.progressBar.gradient.end
    };
  };</pre>
  <pre id="CBeC">  return (
    &lt;div style={{
      padding: &#x27;16px&#x27;,
      width: &#x27;100%&#x27;,
      maxWidth: &#x27;100%&#x27;
    }}&gt;
      &lt;div style={{
        display: &#x27;grid&#x27;,
        gridTemplateColumns: &#x27;repeat(auto-fit, minmax(450px, 1fr))&#x27;,
        gap: &#x27;24px&#x27;,
        width: &#x27;100%&#x27;
      }}&gt;
        {habitsWithGoals.map(habit =&gt; {
          const stats = calculateWeeklyProgress(habit.id);
          const progressColor = stats.isOnTrack ? COLORS.progressBar.high : COLORS.progressBar.low;
          const gradient = getProgressGradient(stats.isOnTrack);</pre>
  <pre id="PH84">          return (
            &lt;div key={habit.id} style={{
              background: &#x27;var(--background-secondary)&#x27;,
              borderRadius: &#x27;12px&#x27;,
              padding: &#x27;24px&#x27;,
              boxShadow: &#x27;var(--shadow-s)&#x27;,
              minWidth: &#x27;450px&#x27;,
              flex: &#x27;1 1 auto&#x27;
            }}&gt;
              &lt;div style={{
                display: &#x27;flex&#x27;,
                alignItems: &#x27;center&#x27;,
                gap: &#x27;16px&#x27;,
                marginBottom: &#x27;16px&#x27;
              }}&gt;
                &lt;div style={{
                  width: &#x27;100px&#x27;,
                  height: &#x27;100px&#x27;,
                  position: &#x27;relative&#x27;
                }}&gt;
                  &lt;CircularProgress
                    progress={stats.progress}
                    size={100}
                    strokeWidth={10}
                    circleColor={progressColor}
                    gradientStart={gradient.start}
                    gradientEnd={gradient.end}
                  /&gt;
                  &lt;div style={{
                    position: &#x27;absolute&#x27;,
                    top: &#x27;50%&#x27;,
                    left: &#x27;50%&#x27;,
                    transform: &#x27;translate(-50%, -50%)&#x27;,
                    fontSize: &#x27;42px&#x27;,
                    display: &#x27;flex&#x27;,
                    alignItems: &#x27;center&#x27;,
                    justifyContent: &#x27;center&#x27;,
                    width: &#x27;80%&#x27;,
                    height: &#x27;80%&#x27;
                  }}&gt;
                    {habit.emoji}
                  &lt;/div&gt;
                &lt;/div&gt;</pre>
  <pre id="OFMN">                &lt;div style={{ flex: 1 }}&gt;
                  &lt;h3 style={{
                    margin: &#x27;0 0 8px 0&#x27;,
                    textAlign: &#x27;center&#x27;,
                    fontSize: &#x27;1.4em&#x27;,
                    color: &#x27;var(--text-normal)&#x27;
                  }}&gt;{habit.label}&lt;/h3&gt;
                  &lt;div style={{
                    display: &#x27;grid&#x27;,
                    gridTemplateColumns: &#x27;1fr 1fr&#x27;,
                    gap: &#x27;12px&#x27;
                  }}&gt;
                    &lt;Stat
                      label=&quot;Current&quot;
                      value={formatMetricValue(stats.total, habit)}
                    /&gt;
                    &lt;Stat
                      label=&quot;Weekly Goal&quot;
                      value={formatMetricValue(stats.weeklyGoal, habit)}
                    /&gt;
                    &lt;Stat
                      label=&quot;Daily Avg&quot;
                      value={formatMetricValue(stats.dailyAverage, habit)}
                    /&gt;
                    &lt;Stat
                      label=&quot;Projected&quot;
                      value={formatMetricValue(stats.projection, habit)}
                      color={stats.isOnTrack ? &#x27;var(--color-green)&#x27; : &#x27;var(--color-red)&#x27;}
                    /&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;</pre>
  <pre id="Hijd">              &lt;div style={{
                height: &#x27;40px&#x27;,
                background: &#x27;var(--background-primary)&#x27;,
                borderRadius: &#x27;20px&#x27;,
                overflow: &#x27;hidden&#x27;,
                position: &#x27;relative&#x27;
              }}&gt;
                &lt;div style={{
                  position: &#x27;absolute&#x27;,
                  top: &#x27;0&#x27;,
                  left: &#x27;0&#x27;,
                  height: &#x27;100%&#x27;,
                  width: &#x60;${stats.progress}%&#x60;,
                  background: &#x60;linear-gradient(90deg, ${gradient.start} 0%, ${gradient.end} 100%)&#x60;,
                  transition: &#x27;width 0.3s ease&#x27;
                }} /&gt;
                &lt;div style={{
                  position: &#x27;absolute&#x27;,
                  top: &#x27;50%&#x27;,
                  left: &#x27;50%&#x27;,
                  transform: &#x27;translate(-50%, -50%)&#x27;,
                  color: &#x27;var(--text-normal)&#x27;,
                  fontWeight: &#x27;bold&#x27;
                }}&gt;
                  {stats.progress}%
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          );
        })}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</pre>
  <pre id="1zyu">const Stat = ({ label, value, color }) =&gt; (
  &lt;div style={{ textAlign: &#x27;center&#x27; }}&gt;
    &lt;div style={{
      fontSize: &#x27;0.9em&#x27;,
      color: &#x27;var(--text-muted)&#x27;,
      marginBottom: &#x27;4px&#x27;
    }}&gt;
      {label}
    &lt;/div&gt;
    &lt;div style={{
      fontSize: &#x27;1.1em&#x27;,
      fontWeight: &#x27;bold&#x27;,
      color: color || &#x27;var(--text-normal)&#x27;
    }}&gt;
      {value}
    &lt;/div&gt;
  &lt;/div&gt;
);</pre>
  <pre id="NLoN">function HabitTracker() {
  // State Management
  const [activeView, setActiveView] = dc.useState(&#x27;weekly&#x27;);
  const [selectedDate, setSelectedDate] = dc.useState(dc.luxon.DateTime.now());
  const [editingTime, setEditingTime] = dc.useState(null);
  const [currentPage, setCurrentPage] = dc.useState(0);</pre>
  <pre id="3b3G">  // Data Queries and Utility Functions
  const dailyNotes = dc.useQuery(&#x60;
    @page 
    AND path(&quot;002 Journal&quot;)
  &#x60;);</pre>
  <pre id="NBGs">  const sortedNotes = dc.useMemo(() =&gt; {
    return [...dailyNotes].sort((a, b) =&gt; b.$name.localeCompare(a.$name));
  }, [dailyNotes]);</pre>
  <pre id="H95B">  const getNotesForPeriod = (startDate) =&gt; {
    return sortedNotes.filter(note =&gt; {
      const noteDate = dc.luxon.DateTime.fromISO(note.$name);
      return noteDate &gt;= startDate;
    });
  };</pre>
  <pre id="tzI3">  // Add new function to get notes for specific date range
  const getNotesForDateRange = (startDate, endDate) =&gt; {
    return sortedNotes.filter(note =&gt; {
      const noteDate = dc.luxon.DateTime.fromISO(note.$name);
      // Use startOf(&#x27;day&#x27;) and endOf(&#x27;day&#x27;) to ensure full day coverage
      return noteDate &gt;= startDate.startOf(&#x27;day&#x27;) &amp;&amp; noteDate &lt;= endDate.endOf(&#x27;day&#x27;);
    });
  };</pre>
  <pre id="VthU">  const last30DaysNotes = dc.useMemo(() =&gt;
    getNotesForPeriod(selectedDate.minus({ days: 30 })),
    [sortedNotes, selectedDate]
  );</pre>
  <pre id="yhTC">  const yearToDateNotes = dc.useMemo(() =&gt;
    getNotesForPeriod(selectedDate.startOf(&#x27;year&#x27;)),
    [sortedNotes, selectedDate]
  );</pre>
  <pre id="A0WH">  const currentMonthNotes = dc.useMemo(() =&gt;
    getNotesForPeriod(selectedDate.startOf(&#x27;month&#x27;)),
    [sortedNotes, selectedDate]
  );</pre>
  <pre id="PybG">  const previousMonthNotes = dc.useMemo(() =&gt;
    sortedNotes.filter(note =&gt; {
      const noteDate = dc.luxon.DateTime.fromISO(note.$name);
      const monthAgo = selectedDate.minus({ months: 1 });
      return noteDate &gt;= monthAgo &amp;&amp; noteDate &lt; selectedDate.startOf(&#x27;month&#x27;);
    }),
    [sortedNotes, selectedDate]
  );</pre>
  <pre id="aKrl">  const getHabitStatus = (entry, habitId) =&gt; {
    const habit = HABITS.find(h =&gt; h.id === habitId);
    const value = entry?.value(habitId) ?? 0;
    return value &gt;= habit.defaultDuration;
  };</pre>
  <pre id="OIyB">  const getHabitDuration = (entry, habitId) =&gt; {
    return entry?.value(habitId) ?? null;
  };</pre>
  <pre id="xzsC">  const calculateCompletedHabits = (entry) =&gt; {
    if (!entry) return 0;
    return HABITS.reduce((count, habit) =&gt;
      count + (getHabitStatus(entry, habit.id) ? 1 : 0), 0);
  };</pre>
  <pre id="1KYg">  const calculatePerfectDays = (notes) =&gt; {
    return notes.reduce((count, note) =&gt;
      count + (calculateCompletedHabits(note) === HABITS.length ? 1 : 0), 0);
  };</pre>
  <pre id="taVQ">  const calculateTrends = () =&gt; {
    const trends = {
      last30Days: {
        perfectDays: calculatePerfectDays(last30DaysNotes),
        habitMetrics: {}
      },
      yearToDate: {
        perfectDays: calculatePerfectDays(yearToDateNotes),
        habitMetrics: {}
      },
      currentMonth: {
        perfectDays: calculatePerfectDays(currentMonthNotes),
        progress: 0
      }
    };</pre>
  <pre id="TSy6">    trends.currentMonth.progress = (trends.currentMonth.perfectDays / GOALS.perfectDays.monthly) * 100;</pre>
  <pre id="A9Tb">    HABITS.forEach(habit =&gt; {
      const last30Total = last30DaysNotes.reduce((sum, note) =&gt; {
        const value = note?.value(habit.id);
        const numValue = value ? Number(value) : 0;
        return sum + (isNaN(numValue) ? 0 : numValue);
      }, 0);</pre>
  <pre id="bWIE">      const ytdTotal = yearToDateNotes.reduce((sum, note) =&gt; {
        const value = note?.value(habit.id);
        const numValue = value ? Number(value) : 0;
        return sum + (isNaN(numValue) ? 0 : numValue);
      }, 0);</pre>
  <pre id="gUN9">      const previousMonthTotal = previousMonthNotes.reduce((sum, note) =&gt; {
        const value = note?.value(habit.id);
        const numValue = value ? Number(value) : 0;
        return sum + (isNaN(numValue) ? 0 : numValue);
      }, 0);</pre>
  <pre id="Ox75">      trends.last30Days.habitMetrics[habit.id] = {
        total: last30Total,
        previousPeriodTotal: previousMonthTotal
      };</pre>
  <pre id="tnXn">      trends.yearToDate.habitMetrics[habit.id] = {
        total: ytdTotal
      };
    });</pre>
  <pre id="xLuI">    return trends;
  };</pre>
  <pre id="SvIW">  // Get current week&#x27;s notes based on selected date
  const currentWeekNotes = dc.useMemo(() =&gt;
    sortedNotes.filter(note =&gt; {
      const noteDate = dc.luxon.DateTime.fromISO(note.$name);
      const startOfWeek = selectedDate.startOf(&#x27;week&#x27;);
      const endOfWeek = selectedDate.endOf(&#x27;week&#x27;);
      return noteDate &gt;= startOfWeek &amp;&amp; noteDate &lt;= endOfWeek;
    }),
    [sortedNotes, selectedDate]
  );</pre>
  <pre id="PonN">  // Action Handlers
  async function updateHabit(entry, habitId) {
    const file = app.vault.getAbstractFileByPath(entry.$path);
    await app.fileManager.processFrontMatter(file, (frontmatter) =&gt; {
      const habit = HABITS.find(h =&gt; h.id === habitId);
      const currentValue = frontmatter[habitId];
      frontmatter[habitId] = currentValue ? 0 : habit.defaultDuration;
    });
  }</pre>
  <pre id="el9P">  async function updateHabitDuration(entry, habitId, duration) {
    const file = app.vault.getAbstractFileByPath(entry.$path);
    await app.fileManager.processFrontMatter(file, (frontmatter) =&gt; {
      frontmatter[habitId] = parseInt(duration) || 0;
    });
    setEditingTime(null);
  }</pre>
  <pre id="rZTY">  const navigateDate = (direction) =&gt; {
    setSelectedDate(prev =&gt; prev.plus({ days: direction }));
  };</pre>
  <pre id="hr3D">  // Main Layout
  return (
  &lt;div style={{
    width: &#x27;100%&#x27;,
    margin: &#x27;0 auto&#x27;,
    padding: &#x27;24px&#x27;,
    display: &#x27;flex&#x27;,
    flexDirection: &#x27;column&#x27;,
    gap: &#x27;24px&#x27;
  }}&gt;
    &lt;NavigationControls
      selectedDate={selectedDate}
      navigateDate={navigateDate}
      activeView={activeView}
      setActiveView={setActiveView}
    /&gt;</pre>
  <pre id="DABF">    &lt;StyledCard&gt;
      &lt;CalendarView
        selectedDate={selectedDate}
        sortedNotes={getNotesForDateRange(selectedDate.minus({ days: 6 }), selectedDate)}
        getHabitStatus={getHabitStatus}
        calculateCompletedHabits={calculateCompletedHabits}
        updateHabit={updateHabit}
        getHabitDuration={getHabitDuration}
        editingTime={editingTime}
        setEditingTime={setEditingTime}
        updateHabitDuration={updateHabitDuration}
      /&gt;</pre>
  <pre id="2fNM">      &lt;div style={{
        display: &#x27;flex&#x27;,
        justifyContent: &#x27;center&#x27;,
        gap: &#x27;16px&#x27;,
        marginTop: &#x27;16px&#x27;,
        paddingTop: &#x27;16px&#x27;,
        borderTop: &#x27;1px solid var(--background-modifier-border)&#x27;
      }}&gt;
        &lt;ActionButton
          icon=&quot;📅&quot;
          onClick={() =&gt; setActiveView(activeView === &#x27;weekly&#x27; ? null : &#x27;weekly&#x27;)}
          isActive={activeView === &#x27;weekly&#x27;}
          extraStyles={{ padding: &#x27;12px&#x27; }}
        /&gt;
        &lt;ActionButton
          icon=&quot;🚀&quot;
          onClick={() =&gt; setActiveView(activeView === &#x27;goals&#x27; ? null : &#x27;goals&#x27;)}
          isActive={activeView === &#x27;goals&#x27;}
          extraStyles={{ padding: &#x27;12px&#x27; }}
        /&gt;
        &lt;ActionButton
          icon=&quot;🚧&quot;
          onClick={() =&gt; setActiveView(activeView === &#x27;stats&#x27; ? null : &#x27;stats&#x27;)}
          isActive={activeView === &#x27;stats&#x27;}
          extraStyles={{ padding: &#x27;12px&#x27; }}
        /&gt;
        &lt;ActionButton
          icon=&quot;🎯&quot;
          onClick={() =&gt; setActiveView(activeView === &#x27;history&#x27; ? null : &#x27;history&#x27;)}
          isActive={activeView === &#x27;history&#x27;}
          extraStyles={{ padding: &#x27;12px&#x27; }}
        /&gt;
      &lt;/div&gt;
    &lt;/StyledCard&gt;</pre>
  <pre id="qt9I">    {activeView === &#x27;weekly&#x27; &amp;&amp; (
      &lt;WeeklyGoalsView entries={currentWeekNotes} /&gt;
    )}
    {activeView === &#x27;goals&#x27; &amp;&amp; (
      &lt;GoalsView
        entries={currentMonthNotes}
        daysInMonth={new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0).getDate()}
      /&gt;
    )}
    {activeView === &#x27;stats&#x27; &amp;&amp; &lt;TrendsView trends={calculateTrends()} /&gt;}
    {activeView === &#x27;history&#x27; &amp;&amp; (
      &lt;HistoricalView
        sortedNotes={sortedNotes}
        currentPage={currentPage}
        setCurrentPage={setCurrentPage}
        updateHabit={updateHabit}
        getHabitStatus={getHabitStatus}
        getHabitDuration={getHabitDuration}
        editingTime={editingTime}
        setEditingTime={setEditingTime}
        updateHabitDuration={updateHabitDuration}
        calculateCompletedHabits={calculateCompletedHabits}
      /&gt;
    )}
  &lt;/div&gt;
);
}</pre>
  <pre id="Iarx">return HabitTracker;
&#x60;&#x60;&#x60;&#x60;</pre>
  <p id="3vAL"></p>
  <h3 id="Hwig" data-align="center">Основная настройка трекера</h3>
  <p id="5jvN">1. Чтобы начать работу с трекером, у вас должны быть настроены <strong>Ежедневные заметки</strong> (указана папка, куда отправлять <strong>Daily notes</strong>). Также желательно установить плагин <strong>Calendar </strong>– так будет проще работать с трекером</p>
  <p id="OBij">2. Дальше в коде трекера ищем <em>query</em> (переходим в исходный код <strong>ctrl+e </strong>–&gt; поиск <strong>ctrl+f</strong> –&gt; вводим <strong><em>query</em></strong>). Тут нужно указать название своей папки с <strong>Daily notes</strong></p>
  <figure id="HqDi" class="m_column">
    <img src="https://img4.teletype.in/files/7a/91/7a917b19-e244-45b3-8fe8-f159840a6c82.png" width="1920" />
    <figcaption>Habit tracker settings</figcaption>
  </figure>
  <p id="Tps4">3. Проверяем, что все работает. Протыкиваем на календаре текущую неделю = создаем <strong>Ежедневные заметки на неделю</strong>. В трекере появляются вот такие штучки, которые позволяет отмечать выполнение привычки ⬇</p>
  <figure id="uq85" class="m_column">
    <img src="https://img3.teletype.in/files/ee/94/ee94132e-5560-44e4-a869-542cf6b806f2.png" width="1920" />
    <figcaption>Habit tracker settings</figcaption>
  </figure>
  <p id="Q5sS">4. Теперь настраиваем то, что будет отображаться в вашем трекере. Это самая первая колонка в коде ⬇</p>
  <figure id="balo" class="m_column">
    <img src="https://img4.teletype.in/files/b0/af/b0af95a0-b986-4e5e-88ee-5f32be6e9f7b.png" width="857" />
    <figcaption>Habit tracker settings</figcaption>
  </figure>
  <section style="background-color:hsl(hsl(199, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="5QVj"><strong>id:</strong> так привычка будет отображаться в свойствах Ежедневной заметки</p>
    <p id="wr6m"><strong>emoji:</strong> эмодзи привычки</p>
    <p id="y5cJ"><strong>label:</strong> название привычки (так она будет отображаться в трекере)</p>
    <p id="uHzx"><strong>defaultDuration:</strong> количество в цифрах (времени, денег, раз)</p>
    <p id="zc9I"><strong>unit:</strong> в чем измеряете? (в долларах, рублях, часах, минутах, секундах и тд)</p>
  </section>
  <figure id="DIzB" class="m_column">
    <img src="https://img2.teletype.in/files/d7/fa/d7fa389e-7736-4a2e-8542-d97fd41a98f6.png" width="1920" />
    <figcaption>Habit tracker settings</figcaption>
  </figure>
  <hr />
  <p id="MQB9">✔ Telegram-канал <a href="https://t.me/ed_knowledgebase" target="_blank">Обучение и базы знаний</a></p>
  <p id="Vc81"><em>✔ Telegram-канал <a href="https://t.me/second_brain_ru" target="_blank">Second Brain</a> про управление личными знаниями</em></p>
  <p id="yPMq"><em>✔ Telegram-канал <a href="https://t.me/obsidianrus" target="_blank">Pro Obsidian</a> про Obsidian и заметковедение</em></p>
  <p id="2PJ9"><em>✔ Официальный <a href="https://second-brain.ru/" target="_blank">сайт</a> сообщества Second Brain</em></p>
  <p id="N8ZQ">✔ Youtube-канал <a href="https://www.youtube.com/@second-brain" target="_blank">Second brain</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/QXnTUJH3fOA</guid><link>https://teletype.in/@zakirov_edtech/QXnTUJH3fOA?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/QXnTUJH3fOA?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>Perfectionist Homepage in Obsidian</title><pubDate>Mon, 20 Jan 2025 09:56:55 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/c4/a6/c4a66502-3589-4daa-9033-7480e0bd569a.png"></media:content><category>Obsidian</category><description><![CDATA[<img src="https://img3.teletype.in/files/63/6d/636dea67-eee2-4a91-80e0-906d7b7acb42.jpeg"></img>Автор: публикация на Reddit]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(263, 48%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="C0HW">Автор: <a href="https://www.reddit.com/r/ObsidianMD/comments/1gswbv9/my_homepage/#lightbox" target="_blank">публикация на Reddit</a></p>
    <p id="9mdz">Репозиторий на <a href="https://github.com/Nighty3098/MY_NOTES/tree/main" target="_blank">GitHub</a></p>
  </section>
  <figure id="anh5" class="m_column">
    <img src="https://img3.teletype.in/files/63/6d/636dea67-eee2-4a91-80e0-906d7b7acb42.jpeg" width="1080" />
    <figcaption>Homepage 1/2</figcaption>
  </figure>
  <h2 id="nURu" data-align="center">Инструкция по установке</h2>
  <ol id="qT1P">
    <li id="vF8n">Скачиваем <a href="https://github.com/Nighty3098/MY_NOTES/tree/main" target="_blank">репозиторий</a> с GitHub</li>
    <li id="oK7M">Переносим в свое хранилище файл <em>Home.md</em></li>
    <li id="XehG">Находим .obsidian. Копируем папки snippets, themes и plugins в свою корневую папку .obsidian</li>
    <li id="baiC">Запускаем <em>Obsidian</em>. Включаем все <em>Сторонние плагины </em>и <em>Фрагменты CSS</em>. Готово ✅</li>
  </ol>
  <pre id="6nte">Ваше хранилище/.obsidian/snippets</pre>
  <pre id="vibx">Ваше хранилище/.obsidian/themes</pre>
  <pre id="8ovE">Ваше хранилище/.obsidian/plugins</pre>
  <figure id="eYUV" class="m_column">
    <img src="https://img4.teletype.in/files/7c/f0/7cf06b09-fdf9-4fd0-8167-55bc0bef2220.jpeg" width="2100" />
    <figcaption>Homepage 2/2</figcaption>
  </figure>
  <hr />
  <p id="MQB9">✔ Telegram-канал <a href="https://t.me/ed_knowledgebase" target="_blank">Обучение и базы знаний</a></p>
  <p id="Vc81"><em>✔ Telegram-канал <a href="https://t.me/second_brain_ru" target="_blank">Second Brain</a> про управление личными знаниями</em></p>
  <p id="yPMq"><em>✔ Telegram-канал <a href="https://t.me/obsidianrus" target="_blank">Pro Obsidian</a> про Obsidian и заметковедение</em></p>
  <p id="2PJ9"><em>✔ Официальный <a href="https://second-brain.ru/" target="_blank">сайт</a> сообщества Second Brain</em></p>
  <p id="N8ZQ">✔ Youtube-канал <a href="https://www.youtube.com/@second-brain" target="_blank">Second brain</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/WAG_7yK8F0P</guid><link>https://teletype.in/@zakirov_edtech/WAG_7yK8F0P?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/WAG_7yK8F0P?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>SQ3R. Продуктивное чтение</title><pubDate>Fri, 17 Jan 2025 18:51:14 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/f6/6f/f66f4172-8781-4fdb-b6c2-7908431aec01.png"></media:content><category>learning</category><description><![CDATA[<img src="https://img4.teletype.in/files/3b/84/3b84a34f-9344-41dc-aacb-0bc2bc183b60.png"></img>Подробности можно узнать в telegram-канале Second Brain]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h2 id="pFMg">Насколько эффективен метод? </h2>
  </section>
  <p id="97pL">Работает ли метод? Подробности можно узнать в telegram-канале <a href="https://t.me/second_brain_ru/291" target="_blank">Second Brain</a></p>
  <figure id="AknU" class="m_column">
    <img src="https://img2.teletype.in/files/95/53/955373fa-da25-4eeb-8dbb-0e0dd0e897bc.png" width="1000" />
    <figcaption>SQ3R</figcaption>
  </figure>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h2 id="QGKb">Для кого этот метод?</h2>
  </section>
  <ul id="rbjf">
    <li id="F0Zl"><strong>Работники науки/исследователи. </strong>Это, собственно, главная целевая аудитория SQ3R. Все дело в постановке конкретных вопросов, которые помогают продвигать исследование в своей сфере. Порой ученым нужна конкретная информация из прочитанной книги</li>
    <li id="9iyx"><strong>Студенты/школьники/самообразованцы</strong>. Часто студентам в университетах, техникумах требуется найти конкретный информацию из научной литературы. Если обучающийся серьезно настроен к написанию своего исследованию, то он неизбежно будет так или иначе касаться метода SQ3R</li>
  </ul>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h2 id="mb5z">Специфика и описание SQ3R</h2>
  </section>
  <p id="gTKI" data-align="center"><strong>Поверхностное чтение (Survey)</strong></p>
  <p id="ridQ">Просмотрите текст, обращая внимание на заголовки, подзаголовки и иллюстрации. Это поможет вам понять, о чём идёт речь. Некая предподготовка и восприятию информацию. На этом же этапе можно оценить, зачем вам это читать и нужно ли вообще</p>
  <p id="4QRX" data-align="center"><strong>Задаем себе вопросы (Question)</strong></p>
  <p id="Chuu">Прежде чем начать читать, сформулируйте вопросы, на которые вы хотите получить ответы. Особенно полезными в этом могут быть заголовки, выделенные жирным слова, цитаты и прочие моменты. В начале и в конце текста, главы, книги обычно находится концентрат авторской мысли</p>
  <p id="qPJx" data-align="center"><strong>Чтение (Read)</strong></p>
  <p id="jX80">Теперь, когда вы примерно представляете себе содержание статьи, можно приступать к чтению. Ваша цель: найти информацию, которая поможет ответить на поставленные себе вопросы</p>
  <p id="1Y0q"><strong>Это главный минус метода</strong>. Да, когда есть конкретная задача, проще ориентироваться в потоке информации, однако вы можете упустить другие интересные мысли и рассуждения. Тут все зависит от запроса</p>
  <p id="X26B" data-align="center"><strong>Повторение = вспоминание (Recite)</strong></p>
  <p id="UY1T">Прочитав раздел, перескажите его содержание так, будто вы рассказываете его кому-то другому. Постарайтесь выразить свои мысли как можно более сжато и лаконично. После этого подумайте, отвечает ли этот раздел на какой-либо из ваших вопросов</p>
  <p id="Hutz">Можно в прямом смысле постараться пересказать другому человеку прочитанное, но своими словами. Этот метод имеет научное обоснование эффективности, он действительно работает. Это часть <a href="https://t.me/second_brain_ru/245" target="_blank">метода обучения Фейнмана</a>. Главное, не скатиться в перечитывание и зубрежка – это безрезультативно.</p>
  <p id="vVlt">Если вы ведете заметки – это тоже действенный способ повторения и закрепления информации. Просто записывайте своими словами то, что поняли из прочитанного. Цитирование допускается, но лучше не злоупотреблять</p>
  <p id="NgiC" data-align="center"><strong>Возвращаемся к материалу (Review)</strong></p>
  <p id="1x5q">Главное, не скатиться в перечитывание и зубрежку – это безрезультативно. Нужно уделить особое внимание поставленным вопросам и полученным ответам. Можно повторять по <a href="https://t.me/second_brain_ru/243" target="_blank">схеме Кривой Эббингауза</a></p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <h2 id="hNte">С чего начать?</h2>
  </section>
  <ol id="VLXP">
    <li id="nvC8">Повышение осознанности. Стоит начать с понимания того, что вы вообще читаете. Нужно ли вам это? Для какого проекта? Кто автор?</li>
    <li id="H63r">Стараться войти в состояние потока, про которое писал <a href="https://www.litres.ru/book/mihay-chiksentmihayi/potok-psihologiya-optimalnogo-perezhivaniya-4244565/" target="_blank">Михай Чиксентмихайи</a></li>
    <li id="zN2u">Применять шаги из метода</li>
  </ol>
  <hr />
  <p id="MQB9">✔ Telegram-канал <a href="https://t.me/ed_knowledgebase" target="_blank">Обучение и базы знаний</a></p>
  <p id="Vc81"><em>✔ Telegram-канал <a href="https://t.me/second_brain_ru" target="_blank">Second Brain</a> про управление личными знаниями</em></p>
  <p id="yPMq"><em>✔ Telegram-канал <a href="https://t.me/obsidianrus" target="_blank">Pro Obsidian</a> про Obsidian и заметковедение</em></p>
  <p id="2PJ9"><em>✔ Официальный <a href="https://second-brain.ru/" target="_blank">сайт</a> сообщества Second Brain</em></p>
  <p id="N8ZQ">✔ Youtube-канал <a href="https://www.youtube.com/@second-brain" target="_blank">Second brain</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/2ZHhng6dtpr</guid><link>https://teletype.in/@zakirov_edtech/2ZHhng6dtpr?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/2ZHhng6dtpr?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>Миграция текстовых заметок из Word в Obsidian</title><pubDate>Tue, 07 Jan 2025 15:24:58 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/f4/bb/f4bb9444-a864-4cc3-8fb6-5ff3b35a4f09.png"></media:content><category>Obsidian</category><description><![CDATA[<img src="https://img4.teletype.in/files/b2/63/b2634fc2-8651-4d4e-8355-2c1fbbc72da7.jpeg"></img>Форматы: почти все текстовые]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="BZxL"><strong>Форматы:</strong> почти все текстовые</p>
    <p id="ugi7"><strong>Источник: </strong>Илья Шабанов в <a href="https://x.com/Artifexx/status/1606455384147128320" target="_blank">twitter/x</a></p>
  </section>
  <p id="ljxL">1. Поместите все ваши документы Word (*.docx, *.txt, *.rtf ...) в ОДНУ плоскую папку (т. е. без подпапок) на вашем компьютере</p>
  <p id="sXCf">2. Теперь все наши файлы в одном месте! Пришло время скачать малоизвестный скрипт <a href="https://pandoc.org/installing.html" target="_blank">Pandoc</a>. Это инструмент, который преобразует любой документ в формат, который понимает Obsidian: Markdown</p>
  <h3 id="d4JM" data-align="center"><strong>Mac/OS </strong></h3>
  <p id="OD87">Щёлкните правой кнопкой мыши по нашей папке и выберите «Службы» &gt; «Новый терминал в папке». Скопируйте и вставьте это в терминал: </p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="hSEd"><code>for f in *.docx; do pandoc &quot;$f&quot; -s -t markdown -o &quot;${f%.docx}.md&quot;; done</code></p>
  </section>
  <figure id="LPjk" class="m_column">
    <img src="https://img2.teletype.in/files/dd/78/dd788a45-fb53-4c81-9eb3-fea7c9d2839d.jpeg" width="1148" />
    <figcaption>MacOS 2/3</figcaption>
  </figure>
  <figure id="WL74" class="m_column">
    <img src="https://img1.teletype.in/files/c8/2c/c82cbbc8-7eca-4bf0-a1c0-a630490099ad.jpeg" width="1610" />
    <figcaption>MacOS 3/3</figcaption>
  </figure>
  <p id="CyFX">Это команда для pandoc, которая преобразует все файлы *.docx в &quot;markdown&quot;. (Повторите, заменив &quot;docx&quot; на &quot;txt&quot; или &quot;rtf&quot;, для любых других форматов файлов, которые у вас есть)</p>
  <h3 id="vxtc" data-align="center">Windows</h3>
  <p id="DKFS">Скачиваем папку для Windows с <a href="https://github.com/jgm/pandoc/releases/tag/3.6.1" target="_blank">github</a>. Переносим файл <em>pandoc.exe</em> в нашу папку с <em>.docx файлами </em></p>
  <figure id="XxSU" class="m_column">
    <img src="https://img1.teletype.in/files/4e/35/4e35b2a4-b341-4784-adfe-a16ce2c2bc9b.jpeg" width="1920" />
    <figcaption>Windows 1/3</figcaption>
  </figure>
  <p id="gWHP">Переходим в свою папку, чтобы скопировать её путь. Нажимаем на адресную строку и нажмите CTRL + C. Открываем приложение «командная строка». Вводим «cd» и вставляем путь, который вы скопировали на предыдущем шаге (нажмите CTRL + V для вставки). Теперь вы внутри терминала находитесь в своей папке с текстовыми файлами</p>
  <figure id="gghp" class="m_column">
    <img src="https://img2.teletype.in/files/d5/9f/d59f219b-a9bc-4215-8e51-303c4ad3ff6a.jpeg" width="1668" />
    <figcaption>Windows 2/3</figcaption>
  </figure>
  <figure id="JqxL" class="m_column">
    <img src="https://img3.teletype.in/files/23/a6/23a6bb76-937f-4e55-8c88-334238aa89be.jpeg" width="1920" />
    <figcaption>Windows 3/3</figcaption>
  </figure>
  <p id="2jIC">Когда вы уже внутри своей папки (вы видите это в командной строке). Вводим команду:</p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="cn97"><code>pandoc input.docx -t markdown -o output.md</code></p>
  </section>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="K1T5"><strong>input.docx</strong> — название вашего файла</p>
    <p id="8m78"><strong>output.md </strong>— конечное название файла в markdown-формате</p>
  </section>
  <p id="5QAo">Конвертация в обратную сторону:</p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <pre id="ryeV">pandoc input.md -o output.docx</pre>
  </section>
  <p id="K1T5"><strong>input.md</strong> — название вашего файла</p>
  <p id="8m78"><strong>output.docx </strong>— конечное название файла в markdown-формате</p>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="C67B">Ура, мы преобразовали все наши файлы в Markdown, который может читать Obsidian. Последний шаг: Если вы раньше не работали с Obsidian. Запустите его сейчас, нажмите кнопку «Открыть папку как хранилище» и выберите нашу папку. ИЛИ: если у вас есть хранилище, скопируйте наши файлы в него</p>
  </section>
  <hr />
  <p id="MQB9">✔ Telegram-канал <a href="https://t.me/ed_knowledgebase" target="_blank">Обучение и базы знаний</a></p>
  <p id="Vc81"><em>✔ Telegram-канал <a href="https://t.me/second_brain_ru" target="_blank">Second Brain</a> про управление личными знаниями</em></p>
  <p id="yPMq"><em>✔ Telegram-канал <a href="https://t.me/obsidianrus" target="_blank">Pro Obsidian</a> про Obsidian и заметковедение</em></p>
  <p id="2PJ9"><em>✔ Официальный <a href="https://second-brain.ru/" target="_blank">сайт</a> сообщества Second Brain</em></p>
  <p id="N8ZQ">✔ Youtube-канал <a href="https://www.youtube.com/@second-brain" target="_blank">Second brain</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/RoJcD3gq3Ck</guid><link>https://teletype.in/@zakirov_edtech/RoJcD3gq3Ck?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/RoJcD3gq3Ck?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>Система SCTO в Obsidian</title><pubDate>Sat, 04 Jan 2025 19:58:35 GMT</pubDate><category>PKM</category><description><![CDATA[Автор: Илья Шабанов в twitter/x]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Zeuf"><strong>Автор:</strong> Илья Шабанов в <a href="https://x.com/Artifexx?t=xj0NmH3exzVH9dpY5JnRQQ&s=09" target="_blank">twitter/x</a></p>
    <p id="aDeS"><strong>Ссылка на хранилище:</strong> <a href="https://github.com/lnilya/scto_obsidian" target="_blank">https://github.com/lnilya/scto_obsidian</a></p>
  </section>
  <blockquote id="XIDj">Моя практика написания заметок со временем развилась из структуры Zettelkasten. В науке большинство наших знаний изначально поступает из чтения статей, которые мы должны тщательно отслеживать, поскольку мы сжимаем и объединяем эти знания. Система SCTO разработана для того, чтобы отражать этот процесс и облегчать сжимание идей из него</blockquote>
  <p id="jN4r"></p>
  <p id="yMac" data-align="center"><strong>Sources/Источники</strong></p>
  <p id="jPNf">В большинстве случаев мы создаем одну заметку на каждую прочитанную мной статью. Эта заметка содержит резюме, мои мысли и заметки, а также включает файл PDF с хайлайтами. Сохранение некоторых метаданных, таких как DOI, теги и т. д., позволит легко цитировать заметку в дальнейшем</p>
  <p id="2fb6" data-align="center"><strong>Compendium/Компендиум</strong></p>
  <p id="xuB6">Это сборник результатов, которые либо напрямую извлечены из первоисточников, либо являются моими собственными идеями. Вывод — это короткий абзац или предложение, написанное моими собственными словами. Каждый вывод всегда имеет ссылку на свой первоисточник. Когда в компендиуме слишком много фактов, я разбиваю его на несколько подкомпендиумов</p>
  <p id="hyFn" data-align="center"><strong>Thinking/Размышления</strong></p>
  <p id="r6Zo">Очень часто при чтении научной статьи у нас возникает идея или вопрос, например: «Что, если я применю эту технику к этой проблеме?». Чаще всего кто-то на самом деле это делал, но для собственного мышления крайне важно продолжать записывать эти вопросы. Это развивает вашу способность быть научно креативным. Никакие идеи не бывают слишком глупыми, просто запишите их</p>
  <p id="tWwI" data-align="center"><strong>Ontologies/Онтологии</strong></p>
  <p id="SsGf">Это мои собственные мысли, которые развиваются при просмотре компендиумов и сравнении их с заметками для размышлений. Готовая онтология должна стремиться стать главой обзорной статьи или предложением для проекта</p>
  <section style="background-color:hsl(hsl(323, 50%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="tUx2" data-align="center">Источники → Компендиумы → Размышления → Онтология</p>
  </section>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="4sGA">Вы собираете свои первичные источники и создаете заметку для каждого источника. Постарайтесь сделать ее краткой и всегда следите за своими метаданными, это будет иметь большое значение, когда ваша коллекция вырастет.<br />Когда вы найдете небольшой «атомарный» фрагмент информации, поместите его в заметку-конспект и продолжайте объединять их, пока они не станут большими. На этом этапе разделите их на несколько заметок.<br />Запишите вопросы и идеи в заметках-размышлениях, которые у вас есть по всей теме. Сделайте ссылки и сравнения с вашими первичными источниками. Не пытайтесь ответить на них сразу, просто запишите.<br />Как только чтение ваших первичных источников замедлится, чтобы дать вам новое понимание, переходите к просмотру своих заметок-размышлений, сокращая те вопросы, на которые уже даны ответы, или идеи, которые были признаны недействительными.<br />Начните писать онтологии, резюме и ответы на свои собственные вопросы по мере продвижения.<br />Стремитесь сделать онтологии публикуемыми и читаемыми — то, что вы можете отправить коллеге, который еще не знаком с вашей темой. Эти онтологии станут основой вашей следующей публикации</p>
  </section>
  <hr />
  <p id="RglU">✔ Telegram-канал <a href="https://t.me/ed_knowledgebase" target="_blank">Обучение и базы знаний</a></p>
  <p id="Vc81">✔ Telegram-канал <a href="https://t.me/second_brain_ru" target="_blank">Second Brain</a> про управление личными знаниями</p>
  <p id="yPMq">✔ Telegram-канал <a href="https://t.me/obsidianrus" target="_blank">Pro Obsidian</a> про Obsidian и заметковедение</p>
  <p id="2PJ9">✔ Официальный <a href="https://second-brain.ru/" target="_blank">сайт</a> сообщества Second Brain</p>
  <p id="N8ZQ">✔ Youtube-канал <a href="https://www.youtube.com/@second-brain" target="_blank">Second brain</a></p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/0tIanB1IIDx</guid><link>https://teletype.in/@zakirov_edtech/0tIanB1IIDx?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/0tIanB1IIDx?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>habit tracker in Obsidian</title><pubDate>Sat, 30 Nov 2024 19:33:57 GMT</pubDate><category>Obsidian</category><description><![CDATA[code dataviewjs]]></description><content:encoded><![CDATA[
  <p id="s2a7"><strong>code dataviewjs</strong></p>
  <section style="background-color:hsl(hsl(55,  86%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="fQrD">const startOfWeek = moment().startOf(&quot;isoWeek&quot;).format(&quot;YYYY-MM-DD&quot;);</p>
    <p id="O8vY">const endOfWeek = moment().endOf(&quot;isoWeek&quot;).format(&quot;YYYY-MM-DD&quot;);</p>
    <p id="izFU">// Enhanced color palette with harmonious colors</p>
    <p id="Qqzv">const colorPalette = [</p>
    <p id="sJT2">&quot;#9C27B0&quot;, // Deep Purple for early wake-up and sleep</p>
    <p id="iUrK">&quot;#4CAF50&quot;, // Green for meals and smoothie</p>
    <p id="7urA">&quot;#2196F3&quot;, // Blue for university and gym</p>
    <p id="a7m3">&quot;#FF5722&quot;, // Deep Orange for studying/coding</p>
    <p id="GVG4">];</p>
    <p id="U2a7">// Habit definitions remain the same, but with updated color indices</p>
    <p id="BNgA">const habits = [</p>
    <p id="4VcH">{</p>
    <p id="kd9D">name: &quot;Levantarme temprano&quot;,</p>
    <p id="aBI5">colorIndex: 0, // Deep Purple</p>
    <p id="tTyb">filter: (task) =&gt; task.text.includes(&quot;Levantarme temprano&quot;),</p>
    <p id="7Lpf">},</p>
    <p id="4wbl">{</p>
    <p id="xMXV">name: &quot;Bañarme&quot;,</p>
    <p id="fdEa">colorIndex: 2, // Green</p>
    <p id="N1aX">filter: (task) =&gt; task.text.includes(&quot;Bañarme&quot;),</p>
    <p id="qa5o">},</p>
    <p id="AqPw">{</p>
    <p id="dcYf">name: &quot;Desayunar&quot;,</p>
    <p id="ydVI">colorIndex: 1, // Green</p>
    <p id="flRd">filter: (task) =&gt; task.text.includes(&quot;Desayunar&quot;),</p>
    <p id="RYlF">},</p>
    <p id="vklL">{</p>
    <p id="b7HY">name: &quot;Ir a la u&quot;,</p>
    <p id="AJ29">colorIndex: 2, // Blue</p>
    <p id="VWw6">filter: (task) =&gt; task.text.includes(&quot;Ir a la u&quot;),</p>
    <p id="8pEG">},</p>
    <p id="htVK">{</p>
    <p id="mLQh">name: &quot;Almorzar&quot;,</p>
    <p id="vayL">colorIndex: 1, // Green</p>
    <p id="m9t5">filter: (task) =&gt; task.text.includes(&quot;Almorzar&quot;),</p>
    <p id="9nar">},</p>
    <p id="JaQk">{</p>
    <p id="LVfu">name: &quot;Estudiar/codear/hacer tareas&quot;,</p>
    <p id="O5R0">colorIndex: 3, // Deep Orange</p>
    <p id="dSOH">filter: (task) =&gt;</p>
    <p id="FraX">task.text.includes(&quot;Estudiar&quot;) ||</p>
    <p id="xCT1">task.text.includes(&quot;codear&quot;) ||</p>
    <p id="W6iy">task.text.includes(&quot;hacer tareas&quot;),</p>
    <p id="43OY">},</p>
    <p id="1B4L">{</p>
    <p id="WM6Y">name: &quot;Ir al gym&quot;,</p>
    <p id="9dwB">colorIndex: 2, // Blue</p>
    <p id="1iMz">filter: (task) =&gt; task.text.includes(&quot;Ir al gym&quot;),</p>
    <p id="cwA3">},</p>
    <p id="AZvi">{</p>
    <p id="DNpY">name: &quot;Batido&quot;,</p>
    <p id="AoyE">colorIndex: 1, // Green</p>
    <p id="kaJ5">filter: (task) =&gt; task.text.includes(&quot;Batido&quot;),</p>
    <p id="sSNd">},</p>
    <p id="1J7h">{</p>
    <p id="ziob">name: &quot;Dormir&quot;,</p>
    <p id="chQ2">colorIndex: 0, // Deep Purple</p>
    <p id="2pMP">filter: (task) =&gt; task.text.includes(&quot;Dormir&quot;),</p>
    <p id="7Yar">},</p>
    <p id="Kxyj">];</p>
    <p id="eM8b">// Initialize weekData if not already defined</p>
    <p id="2gbt">if (!weekData) {</p>
    <p id="TxMl">var weekData = {</p>
    <p id="ZyaH">habits: []</p>
    <p id="ESW4">};</p>
    <p id="zddk">}</p>
    <p id="iHiX">// Filter completed tasks</p>
    <p id="8w0m">for (const habit of habits) {</p>
    <p id="rTEI">const entries = [];</p>
    <p id="LeJw">for (let page of dv.pages(&#x27;&quot;ZZZ Journal&quot;&#x27;)</p>
    <p id="I3Id">.where((p) =&gt; p.file.name &gt;= startOfWeek &amp;&amp; p.file.name &lt;= endOfWeek)) {</p>
    <p id="oQpa">const tasks = page.file.tasks.filter((t) =&gt; habit.filter(t) &amp;&amp; t.checked);</p>
    <p id="lrjr">entries.push({</p>
    <p id="j9mU">date: page.file.name,</p>
    <p id="2HDu">value: tasks.length &gt; 0 // Simplified entry creation</p>
    <p id="FbbG">});</p>
    <p id="eFKr">}</p>
    <p id="ru5Y">weekData.habits.push({</p>
    <p id="q91X">name: habit.name,</p>
    <p id="K9Hj">color: colorPalette[habit.colorIndex],</p>
    <p id="eaN3">entries: entries,</p>
    <p id="mgS9">});</p>
    <p id="P8PH">}</p>
    <p id="A1jN">// Enhanced Habit Tracker Rendering Function</p>
    <p id="iwFK">function renderHabitTracker(container, weekData) {</p>
    <p id="QE43">// Create main container with modern styling</p>
    <p id="zWry">const trackerContainer = dv.el(&quot;div&quot;);</p>
    <p id="RPMM">trackerContainer.style.cssText = &#x60;</p>
    <p id="f6G2">font-family: &#x27;Arial&#x27;, sans-serif;</p>
    <p id="tKvF">background-color: #f4f4f4;</p>
    <p id="t7nT">border-radius: 12px;</p>
    <p id="cEBP">box-shadow: 0 4px 6px rgba(0,0,0,0.1);</p>
    <p id="7rnB">padding: 20px;</p>
    <p id="EOPk">max-width: 900px;</p>
    <p id="IO24">margin: 0 auto;</p>
    <p id="iXeS">&#x60;;</p>
    <p id="nXQ7">const table = dv.el(&quot;table&quot;);</p>
    <p id="uM0Y">table.style.cssText = &#x60;</p>
    <p id="w9tP">width: 100%;</p>
    <p id="yUQm">border-collapse: separate;</p>
    <p id="X12G">border-spacing: 0;</p>
    <p id="LWRg">overflow: hidden;</p>
    <p id="6B3V">&#x60;;</p>
    <p id="Frmq">// Create header</p>
    <p id="ScIK">const header = table.createTHead();</p>
    <p id="kHVS">const headerRow = header.insertRow();</p>
    <p id="jIxg">headerRow.style.backgroundColor = &quot;#3f51b5&quot;;</p>
    <p id="rt9s">headerRow.style.color = &quot;white&quot;;</p>
    <p id="O8vL">// Habit header cell</p>
    <p id="Ygnp">const habitHeaderCell = headerRow.insertCell();</p>
    <p id="iZmt">habitHeaderCell.textContent = &quot;Hábitos&quot;;</p>
    <p id="GXp6">habitHeaderCell.style.cssText = &#x60;</p>
    <p id="if4h">padding: 12px;</p>
    <p id="1NTQ">text-align: left;</p>
    <p id="JfJW">font-weight: bold;</p>
    <p id="s0rb">border-right: 1px solid rgba(255,255,255,0.2);</p>
    <p id="hVBo">&#x60;;</p>
    <p id="0NBb">// Days of week</p>
    <p id="1bn8">const daysOfWeek = [</p>
    <p id="Wc9y">&quot;Lunes&quot;, &quot;Martes&quot;, &quot;Miércoles&quot;, &quot;Jueves&quot;,</p>
    <p id="3WVg">&quot;Viernes&quot;, &quot;Sábado&quot;, &quot;Domingo&quot;</p>
    <p id="PsDT">];</p>
    <p id="tfRR">// Create day header cells</p>
    <p id="Yykq">daysOfWeek.forEach(day =&gt; {</p>
    <p id="5Yss">const headerCell = headerRow.insertCell();</p>
    <p id="fAMn">headerCell.textContent = day;</p>
    <p id="CJla">headerCell.style.cssText = &#x60;</p>
    <p id="NjL4">padding: 12px;</p>
    <p id="6u3n">text-align: center;</p>
    <p id="YetT">font-weight: bold;</p>
    <p id="opmY">border-left: 1px solid rgba(255,255,255,0.2);</p>
    <p id="eTch">&#x60;;</p>
    <p id="loak">});</p>
    <p id="nf7L">// Create table body</p>
    <p id="yPly">const body = table.createTBody();</p>
    <p id="dmSf">// Render habit rows</p>
    <p id="W5jo">weekData.habits.forEach(habit =&gt; {</p>
    <p id="S9Dz">const row = body.insertRow();</p>
    <p id="5s6f">row.style.backgroundColor = &quot;#ffffff&quot;;</p>
    <p id="urPH">// Habit name cell</p>
    <p id="CaRw">const habitCell = row.insertCell();</p>
    <p id="2h0C">habitCell.textContent = habit.name;</p>
    <p id="nrUu">habitCell.style.cssText = &#x60;</p>
    <p id="cx4E">padding: 12px;</p>
    <p id="VTX7">font-weight: bold;</p>
    <p id="AlCi">background-color: #f0f0f0;</p>
    <p id="K3ek">border-right: 1px solid #e0e0e0;</p>
    <p id="wKW8">&#x60;;</p>
    <p id="Hpw2">// Create cells for each day</p>
    <p id="Jksp">for (let i = 0; i &lt; 7; i++) {</p>
    <p id="lTCG">const dayDate = moment(startOfWeek).add(i, &quot;days&quot;).format(&quot;YYYY-MM-DD&quot;);</p>
    <p id="zDP2">const entry = habit.entries.find((e) =&gt; e.date === dayDate);</p>
    <p id="bSfW">const cell = row.insertCell();</p>
    <p id="C2tr">cell.style.cssText = &#x60;</p>
    <p id="gcWY">text-align: center;</p>
    <p id="2RUX">padding: 12px;</p>
    <p id="OtHf">border: 1px solid #e0e0e0;</p>
    <p id="UAEU">transition: background-color 0.3s ease;</p>
    <p id="CrDs">&#x60;;</p>
    <p id="al3T">if (entry &amp;&amp; entry.value) {</p>
    <p id="myol">// Completed task</p>
    <p id="NMI7">cell.style.backgroundColor = habit.color;</p>
    <p id="VvT0">cell.style.opacity = &quot;0.7&quot;;</p>
    <p id="vfqy">cell.innerHTML = &quot;✓&quot;;</p>
    <p id="rpEs">cell.style.color = &quot;white&quot;;</p>
    <p id="r90s">cell.style.fontWeight = &quot;bold&quot;;</p>
    <p id="ivEp">} else {</p>
    <p id="gpLl">// Incomplete or no task</p>
    <p id="Fuxn">cell.style.backgroundColor = &quot;white&quot;;</p>
    <p id="fK7e">}</p>
    <p id="ezxr">}</p>
    <p id="WceX">});</p>
    <p id="ol4G">// Append table to container</p>
    <p id="KEeO">trackerContainer.appendChild(table);</p>
    <p id="tgd4">container.appendChild(trackerContainer);</p>
    <p id="DE4Y">}</p>
    <p id="cADa">// Render the Habit Tracker</p>
    <p id="pgq5">renderHabitTracker(this.container, weekData);</p>
  </section>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@zakirov_edtech/ZplUupVCYJT</guid><link>https://teletype.in/@zakirov_edtech/ZplUupVCYJT?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech</link><comments>https://teletype.in/@zakirov_edtech/ZplUupVCYJT?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=zakirov_edtech#comments</comments><dc:creator>zakirov_edtech</dc:creator><title>Критика школьного образования | Radical education reform</title><pubDate>Tue, 12 Nov 2024 14:31:02 GMT</pubDate><category>education</category><description><![CDATA[Аргументы от известных научных деятелей:]]></description><content:encoded><![CDATA[
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="lXXg"><strong>Аргументы от известных научных деятелей: </strong></p>
  </section>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="E3IF"><a href="https://en.wikipedia.org/wiki/Neil_Postman" target="_blank">Нил Постман</a> и Чарльз Вейнгартнер в своей книге <em>«Преподавание как подрывная деятельность»</em> выступали за метод обучения, не связанный с учебной программой. В <a href="https://en.wikipedia.org/wiki/Inquiry_education" target="_blank">исследовательском обучении</a> учащимся предлагается задавать вопросы, которые имеют для них значение и на которые не всегда есть простые ответы; учителям рекомендуется избегать давать ответы</p>
  </section>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Iwom"><a href="https://en.wikipedia.org/wiki/Murray_N._Rothbard" target="_blank">Мюррей Н. Ротбард</a> утверждает, что история стремления к <a href="https://en.wikipedia.org/wiki/Compulsory_schooling" target="_blank">обязательному школьному образованию</a> обусловлена не <a href="https://en.wikipedia.org/wiki/Altruism" target="_blank">альтруизмом</a>, а желанием подчинить население господствующим в обществе силам</p>
  </section>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="hEzA"><a href="https://en.wikipedia.org/wiki/John_Caldwell_Holt" target="_blank">Джон Колдуэлл Холт</a> утверждает, что молодёжь должна иметь право контролировать и направлять своё собственное обучение и что нынешняя система обязательного школьного образования нарушает основное фундаментальное право человека: право решать, что проникает в наш разум. Он считает, что свобода обучения является частью <a href="https://en.wikipedia.org/wiki/Freedom_of_thought" target="_blank">свободы мысли</a>, которая является даже более фундаментальным правом человека, чем <a href="https://en.wikipedia.org/wiki/Freedom_of_speech" target="_blank">свобода слова</a>. Он особенно подчёркивает, что принудительное обучение, независимо от того, учится ли ученик чему-либо вообще или может ли он более эффективно учиться в другом месте и другими способами, является грубым нарушением гражданских свобод</p>
  </section>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="oYNY"><a href="https://en.wikipedia.org/wiki/Nathaniel_Branden" target="_blank">Натаниэль Бранден</a> утверждает, что правительство не должно иметь права насильно изымать детей из их домов с согласия родителей или без него и подвергать детей обучению и процедурам, которые родители могут одобрять или не одобрять. Он также утверждает, что у граждан не должно отнимать их имущество для поддержки образовательной системы, которую они могут одобрять или не одобрять, и для оплаты обучения неродных им детей. Он слцели это должно быть верно для тех, кто понимает и последовательно привержен принципу <a href="https://en.wikipedia.org/wiki/Individual_rights" target="_blank">личные права</a>. Он, какутверждает, что позорно низкий уровень образования в сегодняшней Америке является предсказуемым результатом школьной системы, контролируемой государством, и что решение состоит в том, чтобы вывести сферу образования на рынок</p>
  </section>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="YnFY"><a href="https://en.wikipedia.org/wiki/Jean-Jacques_Rousseau" target="_blank">Жан-Жак Руссо</a> написал в своей книге <em><a href="https://en.wikipedia.org/wiki/Emile:_or,_On_Education" target="_blank">«Эмиль, или О воспитании»</a></em> (впервые опубликованной в 1762 году), что все дети — это идеально устроенные организмы, готовые учиться у своего окружения, чтобы вырасти в добродетельных взрослых, но из-за пагубного влияния порочного общества они часто не достигают этого. Руссо выступал за метод воспитания, который заключался в том, чтобы изолировать ребёнка от общества — например, в загородном доме — и поочерёдно приучать его к изменениям в окружающей среде, а также ставить перед ним задачи и головоломки, которые он должен был решать или преодолевать</p>
    <p id="AHIi">Руссо был необычен тем, что признавал и рассматривал потенциальную проблему легитимизации обучения. Он выступал за то, чтобы взрослые всегда были честны с детьми, и, в частности, за то, чтобы взрослые заявляли, что их авторитет в обучении основан на физическом принуждении: «Я сильнее тебя». Как только дети достигали возраста рассудка, примерно в 12 лет, они становились свободными личностями и участвовали в собственном процессе обучения</p>
  </section>
  <section style="background-color:hsl(hsl(34,  84%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="BdjF">В <em><a href="https://en.wikipedia.org/wiki/Deschooling_Society" target="_blank">Обществе дешулинга</a></em><a href="https://en.wikipedia.org/wiki/Ivan_Illich" target="_blank"> Иван Ильич</a> призывает к упразднению школ. Он утверждает, что школьное образование путает преподавание с обучением, оценки с образованием, дипломы с компетентностью, посещаемость с достижениями и, особенно, процесс с содержанием. Он пишет, что школы не поощряют реальные достижения, только процессы. Школы подавляют волю и способность человека к самообучению, что в конечном итоге приводит к психологической импотенции. Он clстремится к тому, чтобы принудительное школьное обучение извращало естественную склонность жертв к росту и обучению и заменяло ее требованием обучения. Далее, тнынешняя модель школьного образования, изобилующая верительными грамотами, предает ценность человека-самоучки. Более того,, институционализированное школьное образование стремится количественно оценить не поддающееся количественному измерению развитие человека</p>
  </section>

]]></content:encoded></item></channel></rss>