<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>笔记</title>
    <link>https://notes.shuohan.work/zh/</link>
    <description>Recent content on 笔记</description>
    <image>
      <title>笔记</title>
      <url>https://notes.shuohan.work/images/papermod-cover.png</url>
      <link>https://notes.shuohan.work/images/papermod-cover.png</link>
    </image>
    <generator>Hugo -- 0.147.2</generator>
    <language>zh-CN</language>
    <lastBuildDate>Sun, 29 Mar 2026 09:15:00 +0800</lastBuildDate>
    <atom:link href="https://notes.shuohan.work/zh/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>语言是什么</title>
      <link>https://notes.shuohan.work/zh/posts/%E8%AF%AD%E8%A8%80%E6%98%AF%E4%BB%80%E4%B9%88/</link>
      <pubDate>Sun, 29 Mar 2026 09:15:00 +0800</pubDate>
      <guid>https://notes.shuohan.work/zh/posts/%E8%AF%AD%E8%A8%80%E6%98%AF%E4%BB%80%E4%B9%88/</guid>
      <description>&lt;p&gt;什么是语言&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;呢？它人们离不开的“工具”，是人与人面对面交流最便捷的方式。既然是“工具”，那它就会有自身的特点，可以被“看到”，也被用来表达个人的观点……&lt;/p&gt;
&lt;h2 id=&#34;语言和文字&#34;&gt;语言和文字&lt;/h2&gt;
&lt;p&gt;我们常认为语言是文字，事实并非如此。我们平常说出的话就是语言。而我们看到的广告语、书籍故事等并非语言，而是文字。语言是&lt;strong&gt;声音与意义的结合体&lt;/strong&gt;（以下简称音义结合体），文字是对语言的再编码，或者说一个个文字&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;代表一个个音义结合体。文字与语言的关系，正如交通红灯有禁止通行的含义一样。文字是这个“红灯”，语言则是“禁止通行”。一些不识字的人，仍然可以理解他人说的话，还可以表达自己的想法。&lt;/p&gt;</description>
    </item>
    <item>
      <title>阅读札记 | 影响力</title>
      <link>https://notes.shuohan.work/zh/posts/%E5%BD%B1%E5%93%8D%E5%8A%9B/</link>
      <pubDate>Sun, 23 Nov 2025 18:57:25 +0800</pubDate>
      <guid>https://notes.shuohan.work/zh/posts/%E5%BD%B1%E5%93%8D%E5%8A%9B/</guid>
      <description>&lt;h3 id=&#34;第1章-影响力的武器&#34;&gt;第1章 影响力的武器&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;我们必须频繁地利用我们的范式、我们的首选经验，根据少数关键特征把事情分类，一碰到这样那样的触发特征，就不假思索地作出反应。&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>自律</title>
      <link>https://notes.shuohan.work/zh/posts/%E4%B9%90%E8%A7%82/</link>
      <pubDate>Sun, 09 Nov 2025 10:59:53 +0800</pubDate>
      <guid>https://notes.shuohan.work/zh/posts/%E4%B9%90%E8%A7%82/</guid>
      <description>&lt;p&gt;付诸行动的重点在于自律。一个人制定阅读计划，若执行计划便是付诸了行动。自律不简单，但也不会太难。我认为要想自律需要&lt;strong&gt;戒掉短视频&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如何戒掉呢？多出去走走，增加远离社交媒体的时间。是一个人，还是找自己的朋友一起散步呢？我的回答是&lt;em&gt;一个人&lt;/em&gt;。想象下面的场景：一个人在公园听歌散步，看日落日出，观察来往的行人；看够了之后，不要拿出你的手机，只需要盯着一个地方想一想：这样的感觉如何，自己内心的是否有一种突然开阔之感——只需想象桃花源记主人公，从狭窄的山洞中迈进宽广的桃花源那关键的一步，所带来的感受。&lt;/p&gt;</description>
    </item>
    <item>
      <title>卡片盒笔记法</title>
      <link>https://notes.shuohan.work/zh/posts/%E5%8D%A1%E7%89%87%E7%9B%92%E7%AC%94%E8%AE%B0%E6%B3%95/</link>
      <pubDate>Sun, 02 Nov 2025 16:23:51 +0800</pubDate>
      <guid>https://notes.shuohan.work/zh/posts/%E5%8D%A1%E7%89%87%E7%9B%92%E7%AC%94%E8%AE%B0%E6%B3%95/</guid>
      <description>&lt;p&gt;卡片盒笔记法是一个可关联不同笔记的方法，这样说也许有些简单，不过下文我会提到如何实施它。使用这个方法有一个前提：笔记软件最好支持 &lt;strong&gt;双链&lt;/strong&gt;，还有标签（如 obsidian）。&lt;/p&gt;</description>
    </item>
    <item>
      <title>数字工具</title>
      <link>https://notes.shuohan.work/zh/posts/%E6%95%B0%E5%AD%97%E5%B7%A5%E5%85%B7/</link>
      <pubDate>Sat, 01 Nov 2025 10:51:14 +0800</pubDate>
      <guid>https://notes.shuohan.work/zh/posts/%E6%95%B0%E5%AD%97%E5%B7%A5%E5%85%B7/</guid>
      <description>&lt;p&gt;本篇文章记录本人经常使用的软件和工具等。&lt;/p&gt;
&lt;h3 id=&#34;笔记软件&#34;&gt;笔记软件&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://obsidian.md/&#34;&gt;obsidian&lt;/a&gt;是一个多平台的笔记软件。支持&lt;strong&gt;markdown语法&lt;/strong&gt;和&lt;strong&gt;双链&lt;/strong&gt;，同时也支持安装插件。&lt;/p&gt;
&lt;p&gt;软件本身同步需要付费，因此可以安装&lt;strong&gt;Remotely save插件&lt;/strong&gt;实现在各个平台同步。&lt;/p&gt;
&lt;h3 id=&#34;云同步服务&#34;&gt;云同步服务&lt;/h3&gt;
&lt;h4 id=&#34;坚果云&#34;&gt;坚果云&lt;/h4&gt;
&lt;p&gt;国内云同步软件，无限容量，但是每月只能上传1G流量，下载3G流量。用来同步笔记完全是足够的。&lt;/p&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://notes.shuohan.work/zh/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://notes.shuohan.work/zh/about/</guid>
      <description>&lt;p&gt;本站用以记录自以为是笔记的东西。&lt;/p&gt;
&lt;h3 id=&#34;我&#34;&gt;我&lt;/h3&gt;
&lt;p&gt;想要学习感兴趣的一切的东西，记录生活，成长和经历。热爱听歌、散步、看电影，平常也会读书，偶尔“折腾”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;音乐：偏爱节奏适当的英文音乐，不会过于热烈，也不会太过轻柔。&lt;/li&gt;
&lt;li&gt;电影：目前最喜欢的电影系列是 Harry potter 七部曲、指环王和霍比特人系列；英剧喜欢《万物生灵》，有电影选择困难症。&lt;/li&gt;
&lt;li&gt;散步：希望多接触些真实的东西，而不是网络上的虚拟世界，遇到些自认为好看的风景，也会拍下来。&lt;/li&gt;
&lt;li&gt;读书：通过阅读获得知识，喜欢大脑“充实”的感觉。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;常看博客&#34;&gt;常看博客&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://guozheng.rbind.io/&#34;&gt;黄国政&lt;/a&gt;一名人类学研究生，记录日常以及人类学知识；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.wenxuecity.com/myoverview/80634/&#34;&gt;硅谷居士&lt;/a&gt;分享投资相关内容；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.qncd.com/&#34;&gt;尺宅杂记&lt;/a&gt;热爱阅读的一位老师；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://stephenleng.com/cn/&#34;&gt;心的道理&lt;/a&gt;对社会现象有个人的见解；&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wangyurui.com/&#34;&gt;太隐&lt;/a&gt;不只介绍历史人物。&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://notes.shuohan.work/zh/statics/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://notes.shuohan.work/zh/statics/</guid>
      <description>&lt;p&gt;一个统计页面。&lt;/p&gt;
&lt;h3 id=&#34;热力图&#34;&gt;热力图&lt;/h3&gt;
&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;zh-CN&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;博客文章热力图&lt;/title&gt;
    &lt;style&gt;
        :root {
          --ht-main: #334155;
          --ht-day-bg: #ebedf0;
          --ht-tooltip: #000000;
          --ht-tooltip-bg: #ffffff;
          --ht-lv-0: #ebebeb;          
          --ht-lv-1: #c0c0c0;          
          --ht-lv-2: #999999;          
          --ht-lv-3: #666666;          
          --ht-lv-4: #333333;          
        }
        [data-theme=&#34;dark&#34;] {
          --ht-main: #94a3b8;
          --ht-day-bg: #161b22;
          --ht-tooltip: #000000;
          --ht-tooltip-bg: #ffffff;
          --ht-lv-0: #444444;
          --ht-lv-1: #666666;
          --ht-lv-2: #888888;
          --ht-lv-3: #aaaaaa;
          --ht-lv-4: #cccccc;
        }
        .heatmap_container {
          display: flex;
          flex-direction: column;
          align-items: center;
          font-size: 10px;
          line-height: 12px;
          color: var(--ht-main);
          position: relative;
          top: 10px;
        }
        .heatmap_content {
          display: flex;
          flex-direction: row;
          align-items: flex-end;
        }
        .heatmap_week {
          display: flex;
          flex-direction: column;
          justify-content: flex-end;
          align-items: flex-end;
          text-align: right;
          margin-top: 0.25rem;
          margin-right: 0.25rem;
        }
        .heatmap_main {
          display: flex;
          flex-direction: column;
        }
        .heatmap_month {
          display: flex;
          flex-direction: row;
          justify-content: space-around;
          align-items: flex-end;
          text-align: right;
          margin-top: 0.25rem;
          margin-right: 0.25rem;
        }
        .heatmap {
          display: flex;
          flex-direction: row;
          height: 84px;
        }
        .heatmap_footer {
          display: flex;
          align-items: center;
          margin-top: 0.5rem;
        }
        .heatmap_level {
          display: flex;
          flex-direction: row;
          align-items: center;
          gap: 2px;
          margin: 0 0.25rem;
          height: 10px;
        }
        .heatmap_level_item {
          display: block;
          width: 10px;
          height: 10px;
          border-radius: 0.125rem;
        }
        .heatmap_level_0 { background: var(--ht-lv-0); }
        .heatmap_level_1 { background: var(--ht-lv-1); }
        .heatmap_level_2 { background: var(--ht-lv-2); }
        .heatmap_level_3 { background: var(--ht-lv-3); }
        .heatmap_level_4 { background: var(--ht-lv-4); }
        .heatmap_day {
          width: 10px;
          height: 10px;
          background-color: var(--ht-day-bg);
          margin: 1px;
          border-radius: 2px;
          display: inline-block;
          position: relative;
          cursor: pointer;
        }
        .heatmap_day_level_0 { background-color: var(--ht-lv-0); }
        .heatmap_day_level_1 { background-color: var(--ht-lv-1); }
        .heatmap_day_level_2 { background-color: var(--ht-lv-2); }
        .heatmap_day_level_3 { background-color: var(--ht-lv-3); }
        .heatmap_day_level_4 { background-color: var(--ht-lv-4); }
        
         
        .heatmap_tooltip {
          position: fixed;
          background-color: var(--ht-tooltip-bg);
          color: var(--ht-tooltip);
          font-size: 12px;
          line-height: 16px;
          padding: 12px 16px;
          border-radius: 8px;
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
          border: 1px solid #e5e7eb;
          white-space: nowrap;
          z-index: 1000;
          pointer-events: none;
          opacity: 0;
          transform: scale(0.9);
          transition: opacity 0.2s ease, transform 0.2s ease;
          max-width: 300px;
        }
        
        .heatmap_tooltip.show {
          opacity: 1;
          transform: scale(1);
        }
        
        .heatmap_tooltip_count,
        .heatmap_tooltip_post {
          font-weight: 600;
          color: #1f2937;
        }
        
        .heatmap_tooltip_title {
          display: block;
          font-weight: 500;
          color: #374151;
          margin-top: 4px;
          white-space: normal;
          word-wrap: break-word;
        }
        
        .heatmap_tooltip_date {
          display: block;
          color: #6b7280;
          font-size: 11px;
          margin-top: 6px;
        }
        
         
        .heatmap_less, .heatmap_more {
          font-size: 10px;
          color: var(--ht-main);
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&#34;heatmap_container&#34;&gt;
      &lt;div class=&#34;heatmap_content&#34;&gt;
        &lt;div class=&#34;heatmap_week&#34;&gt;
          &lt;span&gt;M&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;span&gt;W&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;span&gt;F&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;
          &lt;span&gt;S&lt;/span&gt;
        &lt;/div&gt;
        &lt;div class=&#34;heatmap_main&#34;&gt;
          &lt;div class=&#34;month heatmap_month&#34;&gt;&lt;/div&gt;
          &lt;div id=&#34;heatmap&#34; class=&#34;heatmap&#34;&gt;&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div class=&#34;heatmap_footer&#34;&gt;
        &lt;div class=&#34;heatmap_less&#34;&gt;less&lt;/div&gt;
        &lt;div class=&#34;heatmap_level&#34;&gt;
          &lt;span class=&#34;heatmap_level_item heatmap_level_0&#34;&gt;&lt;/span&gt;
          &lt;span class=&#34;heatmap_level_item heatmap_level_1&#34;&gt;&lt;/span&gt;
          &lt;span class=&#34;heatmap_level_item heatmap_level_2&#34;&gt;&lt;/span&gt;
          &lt;span class=&#34;heatmap_level_item heatmap_level_3&#34;&gt;&lt;/span&gt;
          &lt;span class=&#34;heatmap_level_item heatmap_level_4&#34;&gt;&lt;/span&gt;
        &lt;/div&gt;
        &lt;div class=&#34;heatmap_more&#34;&gt;more&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    
    &lt;div id=&#34;globalTooltip&#34; class=&#34;heatmap_tooltip&#34;&gt;&lt;/div&gt;

    &lt;script&gt;
      
      var blogInfo = {
    &#34;pages&#34;: [
      
      
      
      {
        &#34;title&#34;: &#34;数字工具&#34;,
        &#34;date&#34;: &#34;2025-11-01&#34;,
        &#34;year&#34;: &#34;2025&#34;,
        &#34;month&#34;: &#34;11&#34;,
        &#34;day&#34;: &#34;01&#34;,
        &#34;word_count&#34;: &#34;1436&#34;
      },
      
      {
        &#34;title&#34;: &#34;卡片盒笔记法&#34;,
        &#34;date&#34;: &#34;2025-11-02&#34;,
        &#34;year&#34;: &#34;2025&#34;,
        &#34;month&#34;: &#34;11&#34;,
        &#34;day&#34;: &#34;02&#34;,
        &#34;word_count&#34;: &#34;646&#34;
      },
      
      {
        &#34;title&#34;: &#34;自律&#34;,
        &#34;date&#34;: &#34;2025-11-09&#34;,
        &#34;year&#34;: &#34;2025&#34;,
        &#34;month&#34;: &#34;11&#34;,
        &#34;day&#34;: &#34;09&#34;,
        &#34;word_count&#34;: &#34;711&#34;
      },
      
      {
        &#34;title&#34;: &#34;阅读札记 | 影响力&#34;,
        &#34;date&#34;: &#34;2025-11-23&#34;,
        &#34;year&#34;: &#34;2025&#34;,
        &#34;month&#34;: &#34;11&#34;,
        &#34;day&#34;: &#34;23&#34;,
        &#34;word_count&#34;: &#34;4908&#34;
      },
      
      {
        &#34;title&#34;: &#34;语言是什么&#34;,
        &#34;date&#34;: &#34;2026-03-29&#34;,
        &#34;year&#34;: &#34;2026&#34;,
        &#34;month&#34;: &#34;03&#34;,
        &#34;day&#34;: &#34;29&#34;,
        &#34;word_count&#34;: &#34;1396&#34;
      }
      
    ]
  };

      
      const globalTooltip = document.getElementById(&#39;globalTooltip&#39;);
      let tooltipTimeout;

      
      const monthNames = [&#39;Jan&#39;, &#39;Feb&#39;, &#39;Mar&#39;, &#39;Apr&#39;, &#39;May&#39;, &#39;Jun&#39;, &#39;Jul&#39;, &#39;Aug&#39;, &#39;Sep&#39;, &#39;Oct&#39;, &#39;Nov&#39;, &#39;Dec&#39;];
      const monthDiv = document.querySelector(&#39;.heatmap_month&#39;);
      const monthsToShow = window.innerWidth &lt; 768 ? 5 : 12;
      const now = new Date();
      const startMonth = (now.getMonth() - (monthsToShow - 1) + 12) % 12;
      for (let i = startMonth; i &lt; startMonth + monthsToShow; i++) {
        const span = document.createElement(&#39;span&#39;);
        span.textContent = monthNames[i % 12];
        monthDiv.appendChild(span);
      }

      function getStartDate() {
        const today = new Date();
        const start = new Date(today.getFullYear(), today.getMonth() - monthsToShow + 1, 1);
        while (start.getDay() !== 1) start.setDate(start.getDate() + 1);
        return start;
      }

      function formatDate(date) {
        const options = { month: &#39;short&#39;, day: &#39;numeric&#39;, year: &#39;numeric&#39; };
        return date.toLocaleDateString(&#39;en-US&#39;, options);
      }

      function showTooltip(event, title, count, post, date) {
        clearTimeout(tooltipTimeout);
        
        let content = &#39;&#39;;
        if (post !== &#34;0&#34;) {
          content += `&lt;span class=&#34;heatmap_tooltip_post&#34;&gt;共 ${post} 篇&lt;/span&gt;`;
        }
        if (count !== &#34;0&#34;) {
          content += `&lt;span class=&#34;heatmap_tooltip_count&#34;&gt; ${count} 字；&lt;/span&gt;`;
        }
        if (title) {
          content += `&lt;span class=&#34;heatmap_tooltip_title&#34;&gt;《${title}》&lt;/span&gt;`;
        }
        content += `&lt;span class=&#34;heatmap_tooltip_date&#34;&gt;${date}&lt;/span&gt;`;
        
        globalTooltip.innerHTML = content;
        
        
        const rect = event.target.getBoundingClientRect();
        const tooltipRect = globalTooltip.getBoundingClientRect();
        
        let left = rect.left + rect.width / 2 - tooltipRect.width / 2;
        let top = rect.top - tooltipRect.height - 10;
        
        
        if (left &lt; 10) left = 10;
        if (left + tooltipRect.width &gt; window.innerWidth - 10) {
          left = window.innerWidth - tooltipRect.width - 10;
        }
        if (top &lt; 10) {
          top = rect.bottom + 10;
        }
        
        globalTooltip.style.left = left + &#39;px&#39;;
        globalTooltip.style.top = top + &#39;px&#39;;
        
        
        globalTooltip.classList.add(&#39;show&#39;);
      }

      function hideTooltip() {
        tooltipTimeout = setTimeout(() =&gt; {
          globalTooltip.classList.remove(&#39;show&#39;);
        }, 100);
      }

      function createDay(date, title, count, post) {
        const day = document.createElement(&#34;div&#34;);
        day.className = &#34;heatmap_day&#34;;
        day.dataset.title = title;
        day.dataset.count = count;
        day.dataset.post = post;
        day.dataset.date = date;

        
        day.addEventListener(&#34;mouseenter&#34;, (event) =&gt; {
          showTooltip(event, title, count, post, date);
        });

        
        day.addEventListener(&#34;mouseleave&#34;, () =&gt; {
          hideTooltip();
        });

        
        const c = parseInt(count, 10);
        if (c === 0) day.classList.add(&#34;heatmap_day_level_0&#34;);
        else if (c &lt; 1000) day.classList.add(&#34;heatmap_day_level_1&#34;);
        else if (c &lt; 2000) day.classList.add(&#34;heatmap_day_level_2&#34;);
        else if (c &lt; 3000) day.classList.add(&#34;heatmap_day_level_3&#34;);
        else day.classList.add(&#34;heatmap_day_level_4&#34;);

        return day;
      }

      function createHeatmap() {
        const container = document.getElementById(&#39;heatmap&#39;);
        const start = getStartDate();
        const end = new Date();
        let current = new Date(start);
        let week = document.createElement(&#39;div&#39;);
        week.className = &#39;heatmap_week&#39;;
        container.appendChild(week);

        let i = 0;
        while (current &lt;= end) {
          if (i % 7 === 0 &amp;&amp; i !== 0) {
            week = document.createElement(&#39;div&#39;);
            week.className = &#39;heatmap_week&#39;;
            container.appendChild(week);
          }

          const dateStr = `${current.getFullYear()}-${(current.getMonth()+1).toString().padStart(2,&#39;0&#39;)}-${current.getDate().toString().padStart(2,&#39;0&#39;)}`;
          const matched = blogInfo.pages.filter(p =&gt; p.date === dateStr);
          const titles = matched.map(p =&gt; p.title).join(&#39;&lt;br /&gt;&#39;);
          const totalWords = matched.reduce((sum, p) =&gt; sum + parseInt(p.word_count, 10), 0);
          const posts = matched.length;
          const day = createDay(formatDate(current), titles, totalWords.toString(), posts.toString());
          week.appendChild(day);

          current.setDate(current.getDate() + 1);
          i++;
        }
      }

      
      globalTooltip.addEventListener(&#39;mouseenter&#39;, () =&gt; {
        clearTimeout(tooltipTimeout);
      });

      globalTooltip.addEventListener(&#39;mouseleave&#39;, () =&gt; {
        hideTooltip();
      });

      
      createHeatmap();
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;h3 id=&#34;日历&#34;&gt;日历&lt;/h3&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&#34;zh-CN&#34;&gt;
&lt;head&gt;
    &lt;meta charset=&#34;UTF-8&#34;&gt;
    &lt;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;&gt;
    &lt;title&gt;修复后的发布日历&lt;/title&gt;
    &lt;style&gt;
        :root{
          --ht-main: #334155;
          --ht-day-bg: #fffdfd;
          --ht-tooltip: #000000;
          --ht-tooltip-bg: #ffffff;
          --ht-lv-0: #ebebeb;
          --ht-lv-1: #c0c0c0;
          --ht-lv-2: #999999;
          --ht-lv-3: #666666;
          --ht-lv-4: #333333;
        }
        [data-theme=&#34;dark&#34;]{
          --ht-main: #94a3b8;
          --ht-day-bg: #161b22;
          --ht-tooltip: #000000;
          --ht-tooltip-bg: #ffffff;
          --ht-lv-0: #444444;
          --ht-lv-1: #666666;
          --ht-lv-2: #888888;
          --ht-lv-3: #aaaaaa;
          --ht-lv-4: #cccccc;
        }

         
        .pm-calendar{ 
          max-width: 460px; 
          background:var(--ht-day-bg); 
          border-radius:14px; 
          padding:18px; 
          box-shadow:0 1px 6px rgba(0,0,0,0.03); 
          font-family:-apple-system,BlinkMacSystemFont,&#34;Segoe UI&#34;,Roboto,&#34;Helvetica Neue&#34;,Arial; 
          color:var(--ht-main); 
          margin: 0 auto; 
          position: relative;
          width: 100%;
          box-sizing: border-box;
        }
        
         
        .pm-cal-header{ 
          display:flex; 
          align-items:center; 
          justify-content:space-between; 
          margin-bottom:10px; 
          gap:8px;
          flex-wrap: nowrap;
        }
        
        .pm-arrow{ 
          background:transparent; 
          border:0; 
          font-size:20px; 
          cursor:pointer; 
          padding:8px; 
          color:var(--ht-main);
          border-radius: 6px;
          transition: background-color 0.2s;
          flex-shrink: 0;
          min-width: 36px;
          height: 36px;
          display: flex;
          align-items: center;
          justify-content: center;
          touch-action: manipulation;
        }
        
        .pm-arrow:hover {
          background-color: rgba(0,0,0,0.05);
        }
        
        .pm-arrow:active {
          background-color: rgba(0,0,0,0.1);
        }
        
        .pm-title{ 
          display:flex; 
          align-items:center; 
          gap:8px;
          flex: 1;
          justify-content: center;
          min-width: 0;
        }
        
         
        .pm-select{ 
           
          appearance: none !important;
          -webkit-appearance: none !important;
          -moz-appearance: none !important;
          
          border: 1px solid rgba(0,0,0,0.1);
          background: var(--ht-day-bg);
          background-image: url(&#34;data:image/svg+xml;charset=UTF-8,%3csvg xmlns=&#39;http://www.w3.org/2000/svg&#39; viewBox=&#39;0 0 24 24&#39; fill=&#39;none&#39; stroke=&#39;currentColor&#39; stroke-width=&#39;2&#39; stroke-linecap=&#39;round&#39; stroke-linejoin=&#39;round&#39;%3e%3cpolyline points=&#39;6,9 12,15 18,9&#39;%3e%3c/polyline%3e%3c/svg%3e&#34;);
          background-repeat: no-repeat;
          background-position: right 8px center;
          background-size: 16px;
          font-size: 16px;
          font-weight: 600;
          padding: 8px 32px 8px 12px;
          color: var(--ht-main);
          cursor: pointer;
          border-radius: 6px;
          transition: border-color 0.2s;
          min-width: 0;
          
           
          -webkit-tap-highlight-color: transparent;
          outline: none;
          
           
          background-color: var(--ht-day-bg) !important;
        }
        
         
        .pm-select::-ms-expand {
          display: none;
        }
        
         
        @supports (-webkit-appearance: none) {
          .pm-select {
            -webkit-appearance: none !important;
          }
        }
        
        .pm-weekdays{ 
          display:grid; 
          grid-template-columns:repeat(7,1fr); 
          text-align:center; 
          font-size:13px; 
          color:var(--ht-main); 
          margin-bottom:8px;
          font-weight: 500;
        }
        
        .pm-weekdays div {
          padding: 8px 0;
        }
        
        .pm-days{ 
          display:grid; 
          grid-template-columns:repeat(7,1fr); 
          gap:8px; 
          min-height: 260px; 
          padding:6px 4px;
        }
        
        .pm-day{ 
          width:100%; 
          aspect-ratio:1/1; 
          display:flex; 
          align-items:center; 
          justify-content:center; 
          border-radius:8px; 
          font-size:14px; 
          color:var(--ht-main); 
          background:transparent; 
          transition: transform .12s, opacity .14s, background-color .2s; 
          user-select:none; 
          cursor:pointer; 
          padding:4px; 
          box-sizing:border-box;
          position: relative;
          touch-action: manipulation;
          min-height: 32px;
        }
        
        .pm-day:not(.pm-empty):hover {
          transform: scale(1.05);
        }
        
        .pm-day:not(.pm-empty):active {
          transform: scale(0.95);
        }
        
        .pm-empty{ 
          background:transparent; 
          pointer-events:none; 
          cursor: default;
        }
        
        .pm-day.today{ 
          box-shadow: inset 0 0 0 2px rgba(66,133,244,0.3);
          font-weight: 600;
        }

        .pm-day.level-0{ background: var(--ht-lv-0); color: var(--ht-main); }
        .pm-day.level-1{ background: var(--ht-lv-1); color: var(--ht-main); }
        .pm-day.level-2{ background: var(--ht-lv-2); color: var(--ht-main); }
        .pm-day.level-3{ background: var(--ht-lv-3); color: #fff; font-weight:600; }
        .pm-day.level-4{ background: var(--ht-lv-4); color: #fff; font-weight:700; }

        .pm-legend{ 
          display:flex; 
          align-items:center; 
          justify-content:flex-end; 
          gap:8px; 
          margin-top:12px; 
          font-size:12px; 
          color:var(--ht-main);
        }
        
        .legend-squares{ 
          display:flex; 
          gap:4px; 
          align-items:center; 
          margin:0 6px;
        }
        
        .legend-squares .sq{ 
          width:16px; 
          height:12px; 
          border-radius:3px; 
          display:inline-block;
        }
        
        .legend-squares .sq-0{ background:var(--ht-lv-0); } 
        .legend-squares .sq-1{ background:var(--ht-lv-1); }
        .legend-squares .sq-2{ background:var(--ht-lv-2); } 
        .legend-squares .sq-3{ background:var(--ht-lv-3); } 
        .legend-squares .sq-4{ background:var(--ht-lv-4); }

         
        .pm-tooltip{
          position:absolute;
          min-width:180px;
          max-width:320px;
          padding:12px;
          background:var(--ht-tooltip-bg);
          color:var(--ht-tooltip);
          border-radius:8px;
          box-shadow:0 8px 24px rgba(0,0,0,0.15);
          font-size:13px;
          line-height:1.4;
          z-index:1000;
          opacity:0;
          pointer-events:none;
          transform-origin:center top;
          transition:opacity .2s, transform .2s;
          display: none;
          left: 0; 
          top: 0;
          border: 1px solid rgba(0,0,0,0.1);
        }
        
        .pm-tooltip.visible{
          display: block;
          opacity:1;
          pointer-events:auto;
        }

         
        .pm-tooltip .tp-date{ 
          font-weight:700; 
          margin-bottom:8px;
          font-size: 14px;
        }
        
        .pm-tooltip .tp-posts{ 
          max-height:180px; 
          overflow:auto; 
          margin:0; 
          padding:0; 
          list-style:none;
        }
        
        .pm-tooltip .tp-posts::-webkit-scrollbar {
          width: 4px;
        }
        
        .pm-tooltip .tp-posts::-webkit-scrollbar-track {
          background: rgba(0,0,0,0.05);
          border-radius: 2px;
        }
        
        .pm-tooltip .tp-posts::-webkit-scrollbar-thumb {
          background: rgba(0,0,0,0.2);
          border-radius: 2px;
        }
        
        .pm-tooltip .tp-posts li{ 
          margin:6px 0; 
          padding:0;
        }
        
        .pm-tooltip .tp-post-title{ 
          color:var(--ht-tooltip); 
          font-weight:500; 
          display:block; 
          max-width:280px; 
          white-space:nowrap; 
          overflow:hidden; 
          text-overflow:ellipsis;
        }
        
        .pm-tooltip .tp-post-meta{ 
          color:#888; 
          font-size:11px; 
          margin-left:6px;
        }
        
        .pm-tooltip .tp-meta{ 
          color:#666; 
          font-size:12px; 
          margin-top:8px; 
          padding-top: 6px;
          border-top: 1px solid rgba(0,0,0,0.1);
        }

         
        @media (max-width: 480px) { 
          .pm-calendar{ 
            padding: 12px; 
            border-radius: 10px;
            margin: 8px;
            max-width: none;
          } 
          
          .pm-select{ 
            font-size: 16px !important;  
            padding: 8px 32px 8px 12px;
             
            background-image: url(&#34;data:image/svg+xml;charset=UTF-8,%3csvg xmlns=&#39;http://www.w3.org/2000/svg&#39; viewBox=&#39;0 0 24 24&#39; fill=&#39;none&#39; stroke=&#39;%23334155&#39; stroke-width=&#39;2&#39; stroke-linecap=&#39;round&#39; stroke-linejoin=&#39;round&#39;%3e%3cpolyline points=&#39;6,9 12,15 18,9&#39;%3e%3c/polyline%3e%3c/svg%3e&#34;) !important;
          } 
          
          .pm-weekdays{ 
            font-size: 12px;
          }
          
          .pm-weekdays div {
            padding: 6px 0;
          }
          
          .pm-day{ 
            font-size: 13px;
            min-height: 28px;
          } 
          
          .pm-days {
            gap: 6px;
          }
          
          .legend-squares .sq{ 
            width: 14px; 
            height: 10px;
          } 
          
          .pm-tooltip{ 
            font-size: 12px; 
            min-width: 160px;
            max-width: calc(100vw - 32px);
            padding: 10px;
          }
          
          .pm-tooltip .tp-post-title {
            max-width: calc(100vw - 80px);
          }
          
          .pm-arrow {
            font-size: 18px;
            padding: 6px;
            min-width: 32px;
            height: 32px;
          }
          
          .pm-legend {
            font-size: 11px;
            gap: 6px;
          }
        }
        
         
        @media (prefers-color-scheme: dark) {
          :root {
            --ht-main: #94a3b8;
            --ht-day-bg: #161b22;
            --ht-tooltip: #ffffff;
            --ht-tooltip-bg: #1f2937;
            --ht-lv-0: #444444;
            --ht-lv-1: #666666;
            --ht-lv-2: #888888;
            --ht-lv-3: #aaaaaa;
            --ht-lv-4: #cccccc;
          }
          
          .pm-select {
            border-color: rgba(255,255,255,0.2);
            background-image: url(&#34;data:image/svg+xml;charset=UTF-8,%3csvg xmlns=&#39;http://www.w3.org/2000/svg&#39; viewBox=&#39;0 0 24 24&#39; fill=&#39;none&#39; stroke=&#39;%2394a3b8&#39; stroke-width=&#39;2&#39; stroke-linecap=&#39;round&#39; stroke-linejoin=&#39;round&#39;%3e%3cpolyline points=&#39;6,9 12,15 18,9&#39;%3e%3c/polyline%3e%3c/svg%3e&#34;) !important;
          }
          
          .pm-tooltip {
            box-shadow: 0 8px 24px rgba(0,0,0,0.4);
            border-color: rgba(255,255,255,0.1);
          }
        }
        
         
        .pm-day:focus {
          outline: 2px solid #4285f4;
          outline-offset: 2px;
        }
        
        .pm-select:focus {
          outline: 2px solid #4285f4;
          outline-offset: 1px;
        }
        
         
        @media screen and (-webkit-min-device-pixel-ratio: 0) {
          .pm-select {
            font-size: 16px;
          }
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&#34;pm-calendar&#34; id=&#34;pmCalendar&#34;&gt;
      &lt;div class=&#34;pm-cal-header&#34;&gt;
        &lt;button class=&#34;pm-arrow&#34; id=&#34;calPrev&#34; aria-label=&#34;上一月&#34;&gt;◀&lt;/button&gt;
        &lt;div class=&#34;pm-title&#34;&gt;
          &lt;select id=&#34;yearSelect&#34; aria-label=&#34;选择年份&#34; class=&#34;pm-select year-select&#34;&gt;&lt;/select&gt;
          &lt;select id=&#34;monthSelect&#34; aria-label=&#34;选择月份&#34; class=&#34;pm-select month-select&#34;&gt;&lt;/select&gt;
        &lt;/div&gt;
        &lt;button class=&#34;pm-arrow&#34; id=&#34;calNext&#34; aria-label=&#34;下一月&#34;&gt;▶&lt;/button&gt;
      &lt;/div&gt;

      &lt;div class=&#34;pm-weekdays&#34; aria-hidden=&#34;true&#34;&gt;
        &lt;div&gt;日&lt;/div&gt;&lt;div&gt;一&lt;/div&gt;&lt;div&gt;二&lt;/div&gt;&lt;div&gt;三&lt;/div&gt;&lt;div&gt;四&lt;/div&gt;&lt;div&gt;五&lt;/div&gt;&lt;div&gt;六&lt;/div&gt;
      &lt;/div&gt;

      &lt;div class=&#34;pm-days&#34; id=&#34;daysGrid&#34; role=&#34;grid&#34; aria-live=&#34;polite&#34;&gt;&lt;/div&gt;

      &lt;div class=&#34;pm-legend&#34; aria-hidden=&#34;true&#34;&gt;
        &lt;span&gt;less&lt;/span&gt;
        &lt;div class=&#34;legend-squares&#34;&gt;
          &lt;span class=&#34;sq sq-0&#34;&gt;&lt;/span&gt;
          &lt;span class=&#34;sq sq-1&#34;&gt;&lt;/span&gt;
          &lt;span class=&#34;sq sq-2&#34;&gt;&lt;/span&gt;
          &lt;span class=&#34;sq sq-3&#34;&gt;&lt;/span&gt;
          &lt;span class=&#34;sq sq-4&#34;&gt;&lt;/span&gt;
        &lt;/div&gt;
        &lt;span&gt;more&lt;/span&gt;
      &lt;/div&gt;

      &lt;div id=&#34;pmTooltip&#34; class=&#34;pm-tooltip&#34; role=&#34;tooltip&#34; aria-hidden=&#34;true&#34;&gt;&lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        
        var blogInfo = {
    &#34;pages&#34;: [
      
      
      
      {
        &#34;title&#34;: &#34;数字工具&#34;,
        &#34;date&#34;: &#34;2025-11-01&#34;,
        &#34;year&#34;: &#34;2025&#34;,
        &#34;month&#34;: &#34;11&#34;,
        &#34;day&#34;: &#34;01&#34;,
        &#34;word_count&#34;: &#34;1436&#34;
      },
      
      {
        &#34;title&#34;: &#34;卡片盒笔记法&#34;,
        &#34;date&#34;: &#34;2025-11-02&#34;,
        &#34;year&#34;: &#34;2025&#34;,
        &#34;month&#34;: &#34;11&#34;,
        &#34;day&#34;: &#34;02&#34;,
        &#34;word_count&#34;: &#34;646&#34;
      },
      
      {
        &#34;title&#34;: &#34;自律&#34;,
        &#34;date&#34;: &#34;2025-11-09&#34;,
        &#34;year&#34;: &#34;2025&#34;,
        &#34;month&#34;: &#34;11&#34;,
        &#34;day&#34;: &#34;09&#34;,
        &#34;word_count&#34;: &#34;711&#34;
      },
      
      {
        &#34;title&#34;: &#34;阅读札记 | 影响力&#34;,
        &#34;date&#34;: &#34;2025-11-23&#34;,
        &#34;year&#34;: &#34;2025&#34;,
        &#34;month&#34;: &#34;11&#34;,
        &#34;day&#34;: &#34;23&#34;,
        &#34;word_count&#34;: &#34;4908&#34;
      },
      
      {
        &#34;title&#34;: &#34;语言是什么&#34;,
        &#34;date&#34;: &#34;2026-03-29&#34;,
        &#34;year&#34;: &#34;2026&#34;,
        &#34;month&#34;: &#34;03&#34;,
        &#34;day&#34;: &#34;29&#34;,
        &#34;word_count&#34;: &#34;1396&#34;
      }
      
    ]
  };

        (function(){
          const monthNames = [&#39;1月&#39;,&#39;2月&#39;,&#39;3月&#39;,&#39;4月&#39;,&#39;5月&#39;,&#39;6月&#39;,&#39;7月&#39;,&#39;8月&#39;,&#39;9月&#39;,&#39;10月&#39;,&#39;11月&#39;,&#39;12月&#39;];
          const today = new Date();
          let isTooltipVisible = false;
          let currentTooltipCell = null;

          
          const dailyStats = {};
          if (window.blogInfo &amp;&amp; Array.isArray(window.blogInfo.pages)) {
            window.blogInfo.pages.forEach(p =&gt; {
              if (!p.date) return;
              if (!dailyStats[p.date]) dailyStats[p.date] = { count:0, words:0, posts:[] };
              dailyStats[p.date].count += 1;
              dailyStats[p.date].words += (Number(p.word_count) || 0);
              dailyStats[p.date].posts.push({ title: p.title, words: Number(p.word_count) || 0 });
            });
          }

          let curYear = today.getFullYear();
          let curMonth = today.getMonth();

          const yearSelect = document.getElementById(&#39;yearSelect&#39;);
          const monthSelect = document.getElementById(&#39;monthSelect&#39;);
          const daysGrid = document.getElementById(&#39;daysGrid&#39;);
          const prevBtn = document.getElementById(&#39;calPrev&#39;);
          const nextBtn = document.getElementById(&#39;calNext&#39;);
          const tooltip = document.getElementById(&#39;pmTooltip&#39;);
          const calendarRoot = document.getElementById(&#39;pmCalendar&#39;);

          
          function buildSelectors(year, month){
            const start = today.getFullYear() - 5;
            const end = today.getFullYear() + 5;
            let yhtml = &#39;&#39;;
            for (let y = start; y &lt;= end; y++){
              yhtml += `&lt;option value=&#34;${y}&#34; ${y===year? &#39;selected&#39;:&#39;&#39;}&gt;${y}年&lt;/option&gt;`;
            }
            yearSelect.innerHTML = yhtml;
            monthSelect.innerHTML = monthNames.map((m,i)=&gt;`&lt;option value=&#34;${i}&#34; ${i===month? &#39;selected&#39;:&#39;&#39;}&gt;${m}&lt;/option&gt;`).join(&#39;&#39;);
          }

          
          function wordsToLevel(words){
            const w = Number(words) || 0;
            if (w === 0) return 0;
            if (w &lt;= 100) return 1;
            if (w &lt;= 500) return 2;
            if (w &lt;= 1000) return 3;
            return 4;
          }

          
          function escapeHtml(str){
            return String(str).replace(/[&amp;&lt;&gt;&#34;&#39;]/g, function(m){ 
              return {&#39;&amp;&#39;:&#39;&amp;amp;&#39;,&#39;&lt;&#39;:&#39;&amp;lt;&#39;,&#39;&gt;&#39;:&#39;&amp;gt;&#39;,&#39;&#34;&#39;:&#39;&amp;quot;&#39;,&#34;&#39;&#34;:&#39;&amp;#39;&#39;}[m]; 
            });
          }

          
          function makeTooltipHtml(dateKey, entry){
            if (!entry || entry.count === 0) {
              return `&lt;div class=&#34;tp-date&#34;&gt;${dateKey}&lt;/div&gt;&lt;div&gt;无发布&lt;/div&gt;`;
            }
            let html = `&lt;div class=&#34;tp-date&#34;&gt;${dateKey}&lt;/div&gt;&lt;ul class=&#34;tp-posts&#34;&gt;`;
            entry.posts.forEach(p =&gt; {
              const safeTitle = escapeHtml(p.title);
              html += `&lt;li&gt;&lt;span class=&#34;tp-post-title&#34;&gt;${safeTitle}&lt;/span&gt; &lt;span class=&#34;tp-post-meta&#34;&gt;(${p.words} 字)&lt;/span&gt;&lt;/li&gt;`;
            });
            html += `&lt;/ul&gt;&lt;div class=&#34;tp-meta&#34;&gt;共 ${entry.count} 篇 · ${entry.words} 字&lt;/div&gt;`;
            return html;
          }

          
          function showTooltipForCell(cell, dateKey, entry){
            
            if (isTooltipVisible &amp;&amp; currentTooltipCell === cell) return;
            
            
            const wasVisible = isTooltipVisible;
            hideTooltip();
            
            
            const showDelay = wasVisible ? 50 : 0;
            
            setTimeout(() =&gt; {
              currentTooltipCell = cell;
              isTooltipVisible = true;

              tooltip.innerHTML = makeTooltipHtml(dateKey, entry);
              tooltip.style.display = &#39;block&#39;;
              tooltip.classList.remove(&#39;visible&#39;);

              
              requestAnimationFrame(() =&gt; {
                const rootRect = calendarRoot.getBoundingClientRect();
                const cellRect = cell.getBoundingClientRect();
                
                
                requestAnimationFrame(() =&gt; {
                  const tooltipRect = tooltip.getBoundingClientRect();

                  
                  let centerX = (cellRect.left + cellRect.width/2) - rootRect.left;
                  const halfTooltipWidth = tooltipRect.width / 2;
                  
                  
                  centerX = Math.max(halfTooltipWidth + 8, centerX);
                  centerX = Math.min(rootRect.width - halfTooltipWidth - 8, centerX);
                  
                  tooltip.style.left = `${centerX}px`;

                  
                  const spaceAbove = cellRect.top - rootRect.top;
                  const spaceBelow = rootRect.bottom - cellRect.bottom;
                  
                  if (spaceAbove &gt; tooltipRect.height + 16 || spaceAbove &gt; spaceBelow) {
                    
                    const top = (cellRect.top - rootRect.top) - 12;
                    tooltip.style.top = `${top}px`;
                    tooltip.style.transform = &#39;translate(-50%, -100%)&#39;;
                  } else {
                    
                    const top = (cellRect.bottom - rootRect.top) + 12;
                    tooltip.style.top = `${top}px`;
                    tooltip.style.transform = &#39;translate(-50%, 0%)&#39;;
                  }

                  
                  tooltip.classList.add(&#39;visible&#39;);
                  tooltip.setAttribute(&#39;aria-hidden&#39;,&#39;false&#39;);
                });
              });
            }, showDelay);
          }

          
          function hideTooltip(){
            if (!isTooltipVisible) return;
            
            isTooltipVisible = false;
            currentTooltipCell = null;
            tooltip.classList.remove(&#39;visible&#39;);
            tooltip.setAttribute(&#39;aria-hidden&#39;,&#39;true&#39;);

            
            setTimeout(() =&gt; {
              if (!isTooltipVisible) {
                tooltip.style.display = &#39;none&#39;;
                tooltip.style.left = &#39;&#39;;
                tooltip.style.top = &#39;&#39;;
                tooltip.innerHTML = &#39;&#39;;
              }
            }, 150); 
          }

          
          function render(year, month){
            daysGrid.innerHTML = &#39;&#39;;
            hideTooltip(); 
            
            const firstWeekday = new Date(year, month, 1).getDay();
            const daysInMonth = new Date(year, month+1, 0).getDate();

            
            for (let i=0;i&lt;firstWeekday;i++){
              const e = document.createElement(&#39;div&#39;);
              e.className = &#39;pm-day pm-empty&#39;;
              daysGrid.appendChild(e);
            }

            
            for (let d=1; d&lt;=daysInMonth; d++){
              const e = document.createElement(&#39;div&#39;);
              e.className = &#39;pm-day&#39;;
              e.setAttribute(&#39;role&#39;,&#39;button&#39;);
              e.setAttribute(&#39;tabindex&#39;,&#39;0&#39;);
              
              const span = document.createElement(&#39;span&#39;);
              span.textContent = d;
              e.appendChild(span);

              
              if (year===today.getFullYear() &amp;&amp; month===today.getMonth() &amp;&amp; d===today.getDate()){
                e.classList.add(&#39;today&#39;);
              }

              const dateKey = `${year}-${String(month+1).padStart(2,&#39;0&#39;)}-${String(d).padStart(2,&#39;0&#39;)}`;
              const entry = dailyStats[dateKey] || {count:0, words:0, posts:[]};
              const lvl = wordsToLevel(entry.words);

              e.classList.add(`level-${lvl}`);

              
              

              
              e.addEventListener(&#39;mouseenter&#39;, (ev) =&gt; {
                if (window.matchMedia(&#39;(pointer: fine)&#39;).matches) {
                  showTooltipForCell(e, dateKey, entry);
                }
              });
              
              e.addEventListener(&#39;mouseleave&#39;, (ev) =&gt; {
                if (window.matchMedia(&#39;(pointer: fine)&#39;).matches) {
                  hideTooltip();
                }
              });

              
              let touchStartTime = 0;
              
              e.addEventListener(&#39;touchstart&#39;, (ev) =&gt; {
                touchStartTime = Date.now();
              }, { passive: true });
              
              e.addEventListener(&#39;touchend&#39;, (ev) =&gt; {
                
                const touchDuration = Date.now() - touchStartTime;
                if (touchDuration &lt; 500) {
                  ev.preventDefault();
                  ev.stopPropagation();
                  
                  if (isTooltipVisible &amp;&amp; currentTooltipCell === e) {
                    hideTooltip();
                  } else {
                    showTooltipForCell(e, dateKey, entry);
                  }
                }
              });

              
              e.addEventListener(&#39;click&#39;, (ev) =&gt; {
                
                if (ev.detail === 0) return; 
                
                ev.stopPropagation();
                if (isTooltipVisible &amp;&amp; currentTooltipCell === e) {
                  hideTooltip();
                } else {
                  showTooltipForCell(e, dateKey, entry);
                }
              });

              
              e.addEventListener(&#39;keydown&#39;, (ev) =&gt; {
                if (ev.key === &#39;Enter&#39; || ev.key === &#39; &#39;) {
                  ev.preventDefault();
                  if (isTooltipVisible &amp;&amp; currentTooltipCell === e) {
                    hideTooltip(); 
                  } else {
                    showTooltipForCell(e, dateKey, entry);
                  }
                } else if (ev.key === &#39;Escape&#39;) {
                  hideTooltip();
                }
              });
              
              e.addEventListener(&#39;blur&#39;, ()=&gt; {
                
                setTimeout(() =&gt; {
                  if (!tooltip.matches(&#39;:hover&#39;) &amp;&amp; !e.matches(&#39;:focus&#39;)) {
                    hideTooltip();
                  }
                }, 100);
              });

              daysGrid.appendChild(e);
            }

            
            const totalCells = firstWeekday + daysInMonth;
            const remainder = (7 - (totalCells % 7)) % 7;
            for (let i=0;i&lt;remainder;i++){
              const e = document.createElement(&#39;div&#39;);
              e.className = &#39;pm-day pm-empty&#39;;
              daysGrid.appendChild(e);
            }
          }

          
          document.addEventListener(&#39;click&#39;, (ev) =&gt; {
            if (!tooltip.contains(ev.target) &amp;&amp; 
                !ev.target.closest(&#39;.pm-day&#39;) &amp;&amp;
                !ev.target.closest(&#39;.pm-tooltip&#39;)) {
              hideTooltip();
            }
          });

          
          let resizeTimer;
          window.addEventListener(&#39;resize&#39;, () =&gt; {
            clearTimeout(resizeTimer);
            resizeTimer = setTimeout(() =&gt; {
              hideTooltip();
            }, 100);
          });

          
          window.addEventListener(&#39;scroll&#39;, () =&gt; {
            hideTooltip();
          }, { passive: true });

          
          prevBtn.addEventListener(&#39;click&#39;, ()=&gt; {
            curMonth--;
            if (curMonth &lt; 0){ curMonth = 11; curYear--; }
            buildSelectors(curYear, curMonth);
            render(curYear, curMonth);
          });
          
          nextBtn.addEventListener(&#39;click&#39;, ()=&gt; {
            curMonth++;
            if (curMonth &gt; 11){ curMonth = 0; curYear++; }
            buildSelectors(curYear, curMonth);
            render(curYear, curMonth);
          });

          
          yearSelect.addEventListener(&#39;change&#39;, (e)=&gt;{
            curYear = Number(e.target.value);
            buildSelectors(curYear, curMonth);
            render(curYear, curMonth);
          });
          
          monthSelect.addEventListener(&#39;change&#39;, (e)=&gt;{
            curMonth = Number(e.target.value);
            buildSelectors(curYear, curMonth);
            render(curYear, curMonth);
          });

          
          buildSelectors(curYear, curMonth);
          render(curYear, curMonth);
        })();
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
    </item>
    <item>
      <title>My Bookshelf</title>
      <link>https://notes.shuohan.work/zh/bookshelf/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://notes.shuohan.work/zh/bookshelf/</guid>
      <description></description>
    </item>
  </channel>
</rss>
