PageSourceSearch

https://tw93.fun/

html tw93.fun collected 2026-10-01 12:17:20 UTC 30,721 bytes, 740 lines download raw bytes

1<!DOCTYPE html>
2<html lang="zh-CN">
3<head>
4  <meta charset="utf-8">
5  
6  
7  
8  
9  
10  
11  <title>Tw93 · 产品工程、AI Coding 与开源工具</title>
12  <meta name="description" content="Tw93 的个人博客,记录产品工程、AI Coding、开源工具、设计与原生 macOS 软件开发。">
13  
14
15  <!-- Canonical URL -->
16  
17
18  <!-- Viewport and Theme Color -->
19  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
20  <meta name="theme-color" content="#e8e8e8">
21  <meta name="mobile-web-app-capable" content="yes">
22  <meta name="apple-mobile-web-app-status-bar-style" content="default">
23
24  <!-- Open Graph Metadata -->
25  
26  
27  
28
29  <meta property="og:locale" content="zh_CN">
30  
31  <meta property="og:type" content="website">
32  
33  <meta property="og:title" content="Tw93 · 产品工程、AI Coding 与开源工具">
34  <meta property="og:description" content="Tw93 的个人博客,记录产品工程、AI Coding、开源工具、设计与原生 macOS 软件开发。">
35  <meta property="og:url" content="https://tw93.fun/">
36  <meta property="og:site_name" content="Tw93">
37  <meta property="og:image" content="https://gw.alicdn.com/imgextra/i1/O1CN01BjlaXE1auDGoniJGl_!!6000000003389-2-tps-480-444.png">
38
39  <!-- Twitter Metadata -->
40  
41
42  <link rel="canonical" href="https://tw93.fun/">
43
44  <!-- Hreflang for multilingual content -->
45  
46    
47  <link rel="alternate" hreflang="zh" href="https://tw93.fun/" />
48  <link rel="alternate" hreflang="en" href="https://tw93.fun/en/" />
49  <link rel="alternate" hreflang="x-default" href="https://tw93.fun/" />
50    
51  
52
53  <!-- DNS Prefetch & Preconnect for Performance -->
54  <link rel="dns-prefetch" href="https://gw.alipayobjects.com">
55  <link rel="dns-prefetch" href="https://gw.alicdn.com">
56  <link rel="preconnect" href="https://gw.alipayobjects.com" crossorigin>
57
58  <!-- Styles and Scripts -->
59  <link rel="stylesheet" href="/css/index.css?v=e703a60516">
60  <!-- jinkai.css only holds @font-face declarations (font-display: swap), so it must not block rendering -->
61  <link rel="preload" href="/css/jinkai.css?v=e703a60516" as="style" onload="this.onload=null;this.rel='stylesheet'">
62  <noscript>
63    <link rel="stylesheet" href="/css/jinkai.css?v=e703a60516">
64  </noscript>
65
66  <!-- Favicon -->
67  <link rel="shortcut icon" type="image/png"
68    href="https://gw.alicdn.com/imgextra/i4/O1CN01XYYPwL1uheeXASHIQ_!!6000000006069-2-tps-420-420.png">
69
70  <!-- Additional Meta Tags -->
71  <meta name="HandheldFriendly" content="True">
72  <meta name="MobileOptimized" content="320">
73  <meta http-equiv="cleartype" content="on">
74  <meta name="format-detection" content="telephone=no">
75  <meta name="author" content="Tw93">
76  <meta name="robots" content="index, follow">
77
78  <!-- Feed -->
79  <link href="https://tw93.fun/feed.xml" type="application/atom+xml" rel="alternate" title="Tw93 Feed">
80
81  <!-- Performance: Reduce render blocking -->
82  <link rel="preconnect" href="https://giscus.app">
83  <link rel="dns-prefetch" href="https://giscus.app">
84
85  <!-- Structured Data for SEO and AI Crawlers -->
86  
86<script type="application/ld+json">
87  {
88    "@context": "https://schema.org",
89    "@graph": [
90      {
91        "@type": "WebSite",
92        "@id": "https://tw93.fun/#website",
93        "name": "Tw93",
94        "url": "https://tw93.fun",
95        "description": "Tw93 的个人博客,记录产品工程、AI Coding、开源工具、设计与原生 macOS 软件开发。",
96        "inLanguage": ["zh-CN", "en-US"],
97        "publisher": { "@id": "https://tw93.fun/#organization" },
98        "author": { "@id": "https://tw93.fun/#person" }
99      },
100      {
101        "@type": "WebPage",
102        "@id": "https://tw93.fun/#webpage",
103        "url": "https://tw93.fun/",
104        "name": "Tw93 · 产品工程、AI Coding 与开源工具",
105        "description": "Tw93 的个人博客,记录产品工程、AI Coding、开源工具、设计与原生 macOS 软件开发。",
106        "isPartOf": { "@id": "https://tw93.fun/#website" },
107        "about": { "@id": "https://tw93.fun/#person" },
108        "inLanguage": "zh-CN",
109        "encoding": {
110          "@type": "MediaObject",
111          "encodingFormat": "text/markdown",
112          "contentUrl": "https://tw93.fun/index.md"
113        }
114      },
115      {
116        "@type": "Person",
117        "@id": "https://tw93.fun/#person",
118        "name": "Tw93",
119        "alternateName": "Tw93",
120        "url": "https://tw93.fun",
121        "email": "mailto:[email protected]",
122        "jobTitle": "Product Engineer",
123        "description": "Product engineer from Hangzhou building small, fast, open source developer tools and macOS applications.",
124        "image": "https://gw.alicdn.com/imgextra/i4/O1CN01XYYPwL1uheeXASHIQ_!!6000000006069-2-tps-420-420.png",
125        "knowsAbout": ["Rust", "Swift", "TypeScript", "Go", "Shell", "Python", "macOS development", "AI coding workflows", "Product engineering", "Open source", "Design"],
126        "address": {
127          "@type": "PostalAddress",
128          "addressLocality": "Hangzhou",
129          "addressRegion": "Zhejiang",
130          "addressCountry": "CN"
131        },
132        "sameAs": [
133          "https://github.com/tw93",
134          "https://twitter.com/HiTw93",
135          "https://www.youtube.com/@HiTw93",
136          "https://www.zhihu.com/people/tw93",
137          "https://www.v2ex.com/member/tw93",
138          "https://yobi.tw93.fun"
139        ]
140      },
141      {
142        "@type": "Organization",
143        "@id": "https://tw93.fun/#organization",
144        "name": "Tw93",
145        "url": "https://tw93.fun",
146        "description": "Independent one-person studio publishing open source developer tools and macOS applications.",
147        "founder": { "@id": "https://tw93.fun/#person" },
148        "logo": {
149          "@type": "ImageObject",
150          "url": "https://gw.alicdn.com/imgextra/i4/O1CN01XYYPwL1uheeXASHIQ_!!6000000006069-2-tps-420-420.png",
151          "width": 420,
152          "height": 420
153        },
154        "email": "mailto:[email protected]",
155        "contactPoint": [
156          {
157            "@type": "ContactPoint",
158            "contactType": "customer support",
159            "email": "[email protected]",
160            "url": "https://tw93.fun/about.html",
161            "availableLanguage": ["Chinese", "English"]
162          },
163          {
164            "@type": "ContactPoint",
165            "contactType": "technical support",
166            "url": "https://github.com/tw93",
167            "availableLanguage": ["Chinese", "English"]
168          }
169        ],
170        "address": {
171          "@type": "PostalAddress",
172          "addressLocality": "Hangzhou",
173          "addressRegion": "Zhejiang",
174          "addressCountry": "CN"
175        },
176        "sameAs": [
177          "https://github.com/tw93",
178          "https://twitter.com/HiTw93",
179          "https://www.youtube.com/@HiTw93",
180          "https://yobi.tw93.fun"
181        ]
182      },
183      {
184        "@type": "SoftwareApplication",
185        "name": "Pake",
186        "url": "https://github.com/tw93/Pake",
187        "applicationCategory": "DeveloperApplication",
188        "operatingSystem": "macOS, Windows, Linux",
189        "description": "Turn any web page into a lightweight desktop app with Rust and Tauri v2. Builds are typically under 5MB against 80MB+ for Electron.",
190        "license": "https://spdx.org/licenses/GPL-3.0-only.html",
191        "isAccessibleForFree": true,
192        "author": { "@id": "https://tw93.fun/#person" },
193        "offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD", "availability": "https://schema.org/InStock" }
194      },
195      {
196        "@type": "SoftwareApplication",
197        "name": "Kaku",
198        "url": "https://github.com/tw93/Kaku",
199        "applicationCategory": "DeveloperApplication",
200        "operatingSystem": "macOS",
201        "description": "GPU-accelerated macOS terminal emulator with a Rust core and Lua configuration, built for AI coding sessions.",
202        "license": "https://spdx.org/licenses/MIT.html",
203        "isAccessibleForFree": true,
204        "author": { "@id": "https://tw93.fun/#person" },
205        "offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD", "availability": "https://schema.org/InStock" }
206      },
207      {
208        "@type": "SoftwareApplication",
209        "name": "MiaoYan",
210        "url": "https://github.com/tw93/MiaoYan",
211        "applicationCategory": "BusinessApplication",
212        "operatingSystem": "macOS",
213        "description": "Native Swift macOS markdown editor. Local-first plain files with no sync service or vault format, LaTeX and Mermaid built in.",
214        "license": "https://spdx.org/licenses/MIT.html",
215        "isAccessibleForFree": true,
216        "author": { "@id": "https://tw93.fun/#person" },
217        "offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD", "availability": "https://schema.org/InStock" }
218      },
219      {
220        "@type": "SoftwareApplication",
221        "name": "Mole",
222        "url": "https://github.com/tw93/Mole",
223        "subjectOf": { "@type": "WebPage", "url": "https://mole.fit/blog/mole-cli-vs-mac-app" },
224        "downloadUrl": "https://github.com/tw93/Mole/releases",
225        "applicationCategory": "UtilitiesApplication",
226        "operatingSystem": "macOS",
227        "description": "Free open source macOS CLI to clean, uninstall, optimize, analyze, and monitor a Mac. Every destructive command supports a dry run.",
228        "license": "https://spdx.org/licenses/GPL-3.0-only.html",
229        "isAccessibleForFree": true,
230        "author": { "@id": "https://tw93.fun/#person" },
231        "offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD", "availability": "https://schema.org/InStock" }
232      },
233      {
234        "@type": "SoftwareApplication",
235        "name": "Mole for Mac",
236        "url": "https://mole.fit",
237        "applicationCategory": "UtilitiesApplication",
238        "operatingSystem": "macOS 14",
239        "description": "Native macOS app to clean, uninstall, optimize, analyze, and monitor a Mac. One-time purchase with lifetime updates, no subscription.",
240        "isAccessibleForFree": false,
241        "author": { "@id": "https://tw93.fun/#person" },
242        "offers": {
243          "@type": "Offer",
244          "price": "19",
245          "priceCurrency": "USD",
246          "url": "https://mole.fit",
247          "availability": "https://schema.org/InStock",
248          "category": "one-time purchase",
249          "description": "$19 one-time licence covering up to 2 Macs, lifetime updates, 14-day money-back guarantee. Scanning is free and each tool runs twice for free before a licence is required."
250        }
251      },
252      {
253        "@type": "SoftwareSourceCode",
254        "name": "Waza",
255        "url": "https://github.com/tw93/Waza",
256        "codeRepository": "https://github.com/tw93/Waza",
257        "programmingLanguage": "Markdown",
258        "description": "Reusable engineering skill pack for AI coding agents: review, debugging, design, writing, and research.",
259        "license": "https://spdx.org/licenses/MIT.html",
260        "isAccessibleForFree": true,
261        "author": { "@id": "https://tw93.fun/#person" }
262      },
263      {
264        "@type": "SoftwareSourceCode",
265        "name": "Kami",
266        "url": "https://github.com/tw93/kami",
267        "codeRepository": "https://github.com/tw93/kami",
268        "programmingLanguage": "Markdown",
269        "description": "Document design system that typesets AI-generated content into PDFs, with bilingual Chinese and English typography.",
270        "license": "https://spdx.org/licenses/MIT.html",
271        "isAccessibleForFree": true,
272        "author": { "@id": "https://tw93.fun/#person" }
273      }
274    ]
275  }
276  </script>
276
277  
278</head>
279
280
281
282<body id="post-index">
283  
284
285<div class="header-menu" id="J_header">
286  <ul class="header-item-container">
287    <li class="header-item-title active">
288      
289      <a href="/" class="title">Tw93</a>
290      
291    </li>
292
293    
294    
295    
296
297    
298    <li class="header-item-left header-item-weekly "><a href="https://weekly.tw93.fun/" target="_blank" rel="noopener noreferrer">Weekly</a></li>
299    
300    
301    
302    
303
304    
305    <li class="header-item-left header-item-github "><a href="https://github.com/tw93" target="_blank" rel="noopener noreferrer">GitHub</a></li>
306    
307    
308    
309    
310
311    
312    <li class="header-item-left header-item-twitter "><a href="https://twitter.com/HiTw93" target="_blank" rel="noopener noreferrer">Twitter</a></li>
313    
314    
315    
316    
317
318    
319    
320    <li class="header-item-left header-item-about "><a href="/about.html">About</a></li>
321    
322    
323    
324
325    <li class="header-item search-btn-container">
326      <button id="search-btn" class="search-btn" aria-label="Search" title="Search (Press /)">
327        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
328          <circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="2" />
329          <path d="M20 20L16 16" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
330        </svg>
331      </button>
332    </li>
333
334    <!-- Smart Language Switch -->
335
336
337
338<li class="header-item language-item">
339  <a href="/en/" class="language-switch" aria-label="Switch to English">En</a>
340</li>
341
342
343
344
345  </ul>
346</div>
347
348
349
350<div class="entry-header">
351  <svg width="100%" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
352    version="1.1" role="img" aria-label="Be yourself and don't go with the flow.">
353    <path id="svg-title-path">
354      <animate attributeName="d" from="m0,110 h80" to="m0,110 h1600" dur="3000ms" repeatCount="1" fill="freeze" begin="0s" />
355    </path>
356    <text font-size="36" font-weight="600" fill="#f3ebdb" x="50%" y="50%" text-anchor="middle"
357      word-spacing="2.0" letter-spacing="1.2">
358      <textPath xlink:href="#svg-title-path">Be yourself and don't go with the flow.</textPath>
359    </text>
360  </svg>
361  <canvas id="J_firework_canvas" aria-hidden="true" role="presentation"></canvas>
362</div>
363
364  
365  <main id="main">
366    
367<h1 class="visually-hidden">Tw93 · 产品工程师、开源作者与写作者</h1>
368
369
370
371  
372  
373    <a href="/2026-08-16/mole-mac.html" rel="bookmark" title="Mole 出 Mac 版后,用户教会了我做产品" itemprop="url" class="header-href">
374      <article class="hentry">
375        <h2 class="entry-title">Mole 出 Mac 版后,用户教会了我做产品</h2>
376        <div class="entry-content">
377          <span>【2026-08-16】</span>Mole CLI 是去年在泳池边写的几百行代码,Mac 桌面版做出来才三个月。这篇记下真正学到的几件事:AI 多出来的三类垃圾该怎么分、删之前为什么要先看一眼、怎么让它平时不来打扰你、怎么把它做到 70 岁的老爷爷也能用,以及一个人做产品时的取舍。
378        </div>
379      </article>
380    </a>
381  
382
383  
384  
385    <a href="/2026-06-07/robot.html" rel="bookmark" title="你不知道的具身智能:从小机器狗到 Optimus" itemprop="url" class="header-href">
386      <article class="hentry">
387        <h2 class="entry-title">你不知道的具身智能:从小机器狗到 Optimus</h2>
388        <div class="entry-content">
389          <span>【2026-06-07】</span>4 月份的时候,我用 STM32、ASRPRO、ESP32-C3、舵机和 3D 打印件手搓了一台能听懂话、能走路、能接云端 AI 的小机器狗。跑通之后再看具身智能,很多判断都落到了很具体的地方:串口、PWM、空间、动作、控制频率、执行器、失败样本和量产约束。
390        </div>
391      </article>
392    </a>
393  
394
395  
396  
397    <a href="/2026-05-01/ai-visibility.html" rel="bookmark" title="你不知道的 GEO:AI 可见性的原理、实践与取舍" itemprop="url" class="header-href">
398      <article class="hentry">
399        <h2 class="entry-title">你不知道的 GEO:AI 可见性的原理、实践与取舍</h2>
400        <div class="entry-content">
401          <span>【2026-05-01】</span>有小伙伴说我的作品被 AI 主动推荐了,想了想居然啥也没做就被收录了,于是花了一个小时把内容结构化做了一遍。做了什么、哪些有效、哪些别碰。
402        </div>
403      </article>
404    </a>
405  
406
407  
408  
409    <a href="/2026-04-26/ai-coding.html" rel="bookmark" title="你不知道的 AI Coding:非技术人的上手、场景与实战" itemprop="url" class="header-href">
410      <article class="hentry">
411        <h2 class="entry-title">你不知道的 AI Coding:非技术人的上手、场景与实战</h2>
412        <div class="entry-content">
413          <span>【2026-04-26】</span>写给产品、业务、运营的 Claude Code 实战指南。不讲 prompt 工程,讲怎么真正用起来:CLAUDE.md 怎么写、Skills 怎么沉淀、Plan 模式什么时候用、哪些场景适合让 Claude Code 干。
414        </div>
415      </article>
416    </a>
417  
418
419  
420  
421    <a href="/2026-04-06/learn.html" rel="bookmark" title="在 AI 时代,我是如何深入学习一个技术领域的" itemprop="url" class="header-href">
422      <article class="hentry">
423        <h2 class="entry-title">在 AI 时代,我是如何深入学习一个技术领域的</h2>
424        <div class="entry-content">
425          <span>【2026-04-06】</span>想聊聊在 AI 时代我是怎么深入学一个新领域的,从收集资料、筛选阅读、写大纲,到 AI 辅助精简、自读发布,我把整个过程当代码一样组织起来。
426        </div>
427      </article>
428    </a>
429  
430
431  
432  
433    <a href="/2026-04-03/llm.html" rel="bookmark" title="你不知道的大模型训练:原理、路径与新实践" itemprop="url" class="header-href">
434      <article class="hentry">
435        <h2 class="entry-title">你不知道的大模型训练:原理、路径与新实践</h2>
436        <div class="entry-content">
437          <span>【2026-04-03】</span>很多人会把模型升级理解为参数变大,但线上体感差异常常出在后半段训练和发布链路。这篇从预训练一路讲到蒸馏上线,重点看数据工程、系统配方、后训练、评测奖励和 Agent 训练怎么一起影响最终表现。最后会看到,模型变强通常是权重、训练链路和部署决策共同作用的结果,不只是参数规模。
438        </div>
439      </article>
440    </a>
441  
442
443  
444  
445    <a href="/2026-03-30/kill.html" rel="bookmark" title="杀死那个手工程序员" itemprop="url" class="header-href">
446      <article class="hentry">
447        <h2 class="entry-title">杀死那个手工程序员</h2>
448        <div class="entry-content">
449          <span>【2026-03-30】</span>标题来自 12 年前我很喜欢的一首万青的歌《杀死那个石家庄人》的改写,虽然歌里写的不是一回事,但那种看着熟悉世界一点点被替换掉的感觉,还真有点像。
450        </div>
451      </article>
452    </a>
453  
454
455  
456  
457    <a href="/2026-03-21/agent.html" rel="bookmark" title="你不知道的 Agent:原理、架构与工程实践" itemprop="url" class="header-href">
458      <article class="hentry">
459        <h2 class="entry-title">你不知道的 Agent:原理、架构与工程实践</h2>
460        <div class="entry-content">
461          <span>【2026-03-21】</span>研究完 Claude Code 的架构之后,发现自己对 Agent 底层的理解还不够深入,加上团队在 Agent 方向已经有不少业务落地,但一直缺少一份系统梳理,所以又补了一轮资料、开源实现和轻量实验,把控制流、上下文工程、工具设计、记忆、评测和安全这些问题重新串了一遍。
462        </div>
463      </article>
464    </a>
465  
466
467  
468  
469    <a href="/2026-03-12/claude.html" rel="bookmark" title="你不知道的 Claude Code:架构、治理与工程实践" itemprop="url" class="header-href">
470      <article class="hentry">
471        <h2 class="entry-title">你不知道的 Claude Code:架构、治理与工程实践</h2>
472        <div class="entry-content">
473          <span>【2026-03-12】</span>我把最近半年用 Claude Code 积累的一些实际经验分享给大伙,两个账号每月氪金 40 刀。这篇文章主要围绕上下文管理、Skills、Hooks、Subagents、Prompt Caching 以及 CLAUDE.md 的设计展开,重点讨论怎样让协作过程更稳定、更可控,偏工程师技术视角的最佳实践,欢迎大伙一起交流。
474        </div>
475      </article>
476    </a>
477  
478
479  
480  
481    <a href="/2026-03-07/openclaw.html" rel="bookmark" title="连龙虾都不会装的人,怎么会用龙虾呢?" itemprop="url" class="header-href">
482      <article class="hentry">
483        <h2 class="entry-title">连龙虾都不会装的人,怎么会用龙虾呢?</h2>
484        <div class="entry-content">
485          <span>【2026-03-07】</span>今天看腾讯大厦装龙虾这件事,挺有感触。最近很多大厂都在疯狂让一线非技术员工去安装龙虾,网上甚至真有 500 上门安装服务。大家都在拼命找使用场景,拼命要求落地,拼命证明这个东西已经重要到不能错过,整个过程让我有一种很强的赛博科技折叠感。
486        </div>
487      </article>
488    </a>
489  
490
491
492
493<div class="pagination">
494  <ul class="inline-list">
495    
496    
497
498    
499    
500    <li><strong class="current-page">1</strong></li>
501    
502
503    
504    
505
506    
507    
508    
509
510    
511    
512    <li><a href="/page2/">2</a></li>
513    
514    
515    
516    <li><a href="/page3/">3</a></li>
517    
518    
519
520    
521    
522    <li>…</li>
523    
524
525    
526    <li><a href="/page9/">9</a></li>
527    
528
529    
530    
531    <li><a href="/page2/" class="btn-arrow">&gt;</a></li>
532    
533  </ul>
534</div>
535
536
537
538
539
540  </main>
541
542  <!-- Search Modal -->
543<div id="search-modal" class="search-modal" aria-hidden="true" role="dialog" aria-labelledby="search-title">
544  <div class="search-container">
545    <div class="search-header">
546      <input
547        type="search"
548        id="search-input"
549        class="search-input"
550        placeholder="Search articles..."
551        aria-label="Search articles"
552        autocomplete="off"
553      >
554      <button class="search-close" id="search-close" aria-label="Close search">
555        <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
556          <path d="M15 5L5 15M5 5L15 15" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
557        </svg>
558      </button>
559    </div>
560    <div id="search-results" class="search-results" role="listbox"></div>
561    <div class="search-footer">
562      <div class="search-tips">
563        <kbd>/</kbd> to search
564        <kbd>ESC</kbd> to close
565        <kbd>↑↓</kbd> to navigate
566        <kbd>Enter</kbd> to select
567      </div>
568    </div>
569  </div>
570</div>
571
572  <div class="footer-wrapper">
573  <footer role="contentinfo">
574
575    <a href="https://github.com/tw93" rel="nofollow" target="_blank" class="social-icon github-icon"
576      aria-label="Follow on GitHub">
577      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
578        <path
579          d="M12.001 2C6.47598 2 2.00098 6.475 2.00098 12C2.00098 16.425 4.86348 20.1625 8.83848 21.4875C9.33848 21.575 9.52598 21.275 9.52598 21.0125C9.52598 20.775 9.51348 19.9875 9.51348 19.15C7.00098 19.6125 6.35098 18.5375 6.15098 17.975C6.03848 17.6875 5.55098 16.8 5.12598 16.5625C4.77598 16.375 4.27598 15.9125 5.11348 15.9C5.90098 15.8875 6.46348 16.625 6.65098 16.925C7.55098 18.4375 8.98848 18.0125 9.56348 17.75C9.65098 17.1 9.91348 16.6625 10.201 16.4125C7.97598 16.1625 5.65098 15.3 5.65098 11.475C5.65098 10.3875 6.03848 9.4875 6.67598 8.7875C6.57598 8.5375 6.22598 7.5125 6.77598 6.1375C6.77598 6.1375 7.61348 5.875 9.52598 7.1625C10.326 6.9375 11.176 6.825 12.026 6.825C12.876 6.825 13.726 6.9375 14.526 7.1625C16.4385 5.8625 17.276 6.1375 17.276 6.1375C17.826 7.5125 17.476 8.5375 17.376 8.7875C18.0135 9.4875 18.401 10.375 18.401 11.475C18.401 15.3125 16.0635 16.1625 13.8385 16.4125C14.201 16.725 14.5135 17.325 14.5135 18.2625C14.5135 19.6 14.501 20.675 14.501 21.0125C14.501 21.275 14.6885 21.5875 15.1885 21.4875C19.259 20.1133 21.9999 16.2963 22.001 12C22.001 6.475 17.526 2 12.001 2Z">
580        </path>
581      </svg>
582    </a>
583
584    <a href="https://twitter.com/HiTw93" rel="nofollow" target="_blank" class="social-icon"
585      aria-label="Follow on Twitter">
586      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
587        <path
588          d="M22.2125 5.65605C21.4491 5.99375 20.6395 6.21555 19.8106 6.31411C20.6839 5.79132 21.3374 4.9689 21.6493 4.00005C20.8287 4.48761 19.9305 4.83077 18.9938 5.01461C18.2031 4.17106 17.098 3.69303 15.9418 3.69434C13.6326 3.69434 11.7597 5.56661 11.7597 7.87683C11.7597 8.20458 11.7973 8.52242 11.8676 8.82909C8.39
588047 8.65404 5.31007 6.99005 3.24678 4.45941C2.87529 5.09767 2.68005 5.82318 2.68104 6.56167C2.68104 8.01259 3.4196 9.29324 4.54149 10.043C3.87737 10.022 3.22788 9.84264 2.64718 9.51973C2.64654 9.5373 2.64654 9.55487 2.64654 9.57148C2.64654 11.5984 4.08819 13.2892 6.00199 13.6731C5.6428 13.7703 5.27232 13.8194 4.90022 13.8191C4.62997 13.8191 4.36771 13.7942 4.11279 13.7453C4.64531 15.4065 6.18886 16.6159 8.0196 16.6491C6.53813 17.8118 4.70869 18.4426 2.82543 18.4399C2.49212 18.4402 2.15909 18.4205 1.82812 18.3811C3.74004 19.6102 5.96552 20.2625 8.23842 20.2601C15.9316 20.2601 20.138 13.8875 20.138 8.36111C20.138 8.1803 20.1336 7.99886 20.1256 7.81997C20.9443 7.22845 21.651 6.49567 22.2125 5.65605Z">
589        </path>
590      </svg>
591    </a>
592
593    <a href="/feed.xml" rel="nofollow" target="_blank" class="social-icon"
594      aria-label="Subscribe to RSS feed">
595      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
596        <path
597          d="M3 3C12.9411 3 21 11.0589 21 21H18C18 12.7157 11.2843 6 3 6V3ZM3 10C9.07513 10 14 14.9249 14 21H11C11 16.5817 7.41828 13 3 13V10ZM3 17C5.20914 17 7 18.7909 7 21H3V17Z">
598        </path>
599      </svg>
600    </a>
601
602    <a href="https://github.com/tw93" rel="nofollow" target="_blank" class="social-icon time-icon"
603      aria-label="Tw93 on GitHub (2015 to 2026)">
604      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
605        <path
606          d="M16.5 3C19.5376 3 22 5.5 22 9C22 16 14.5 20 12 21.5C9.5 20 2 16 2 9C2 5.5 4.5 3 7.5 3C9.35997 3 11 4 12 5C13 4 14.64 3 16.5 3Z">
607        </path>
608      </svg>
609      <span class="repo-time">2015~2026</span>
610    </a>
611  </footer>
612</div>
613
614<script>window.ASSET_VERSION = 'e703a60516';</script>
vendor: 1 bytes, line 614
614
615<script type="text/javascript" src="/js/index.js?v=e703a60516" defer></script>
vendor: 1 bytes, line 615
615
616<script type="text/javascript" src="/js/search.js?v=e703a60516" defer></script>
616
617
618
619<script>
620  window.dataLayer = window.dataLayer || [];
621  function gtag () {
622    dataLayer.push(arguments);
623  }
624  const loadGA = () => {
625    const script = document.createElement('script');
626    script.src = 'https://www.googletagmanager.com/gtag/js?id=G-KS7EDB6BRM';
627    script.async = true;
628    document.head.appendChild(script);
629    gtag("js", new Date());
630    gtag("config", "G-KS7EDB6BRM");
631  };
632  const triggerGA = () => {
633    window.removeEventListener('scroll', triggerGA);
634    window.removeEventListener('mousemove', triggerGA);
635    window.removeEventListener('touchstart', triggerGA);
636    loadGA();
637  };
638  window.addEventListener('scroll', triggerGA, { once: true });
639  window.addEventListener('mousemove', triggerGA, { once: true });
640  window.addEventListener('touchstart', triggerGA, { once: true });
641  setTimeout(() => { if (!window.dataLayer.length) loadGA(); }, 5000);
642</script>
642
643 
644<script>
645  function hereDoc (f) {
646    return f
647      .toString()
648      .replace(/^[^\/]+\/\*!?\s?/, "")
649      .replace(/\*\/[^\/]+$/, "");
650  }
651  var string = hereDoc(function () {
652    /*
653    _                               ___                  _____           _       _
654   | |                             |_  |                /  ___|         (_)     | |
655   | |     ___  __ _ _ __ _ __       | | __ ___   ____ _\ `--.  ___ _ __ _ _ __ | |_
656   | |    / _ \/ _` | '__| '_ \      | |/ _` \ \ / / _` |`--. \/ __| '__| | '_ \| __|
657   | |___|  __/ (_| | |  | | | | /\__/ / (_| |\ V / (_| /\__/ / (__| |  | | |_) | |_
658   \_____/\___|\__,_|_|  |_| |_| \____/ \__,_| \_/ \__,_\____/ \___|_|  |_| .__/ \__|
659
660   Hey, I'm Tw93, a Product Engineer from China with experience in Swift, Rust, Go, TypeScript, and design. I've created Kaku, Pake, MiaoYan, Mole, Waza, Kami, and Trendy Weekly. I believe in long-termism, love open source, and enjoy tinkering with new ideas.
661   */
662  });
663  console.log(string);
664</script>
664
665
666
667<script>
668  if ('serviceWorker' in navigator) {
669    window.addEventListener('load', () => {
670      navigator.serviceWorker.register('/sw.js');
671    });
672  }
673
674  document.addEventListener("DOMContentLoaded", function () {
675    // Jump out
676    const links = document.links;
677    for (let i = 0; i < links.length; i++) {
678      if (
679        links[i].hostname != window.location.hostname ||
680        (links[i].href && links[i].href.indexOf("feed.xml") != -1)
681      ) {
682        links[i].target = "_blank";
683      }
684    }
685
686    // The second image is the cover image, both of which could do with some optimization
687    const images = document.querySelectorAll('.entry-content img');
688    images.forEach((img, index) => {
689      if (index > 1) {
690        img.setAttribute('loading', 'lazy');
691        img.setAttribute('decoding', 'async');
692      }
693    });
694
695    // Full screen button
696    const fullscreenBtn = document.getElementById("fullscreenBtn");
697    fullscreenBtn && fullscreenBtn.addEventListener("click", function () {
698      var elem = document.getElementById("postIframe");
699
700      if (!document.fullscreenElement) {
701        if (elem.requestFullscreen) {
702          elem.requestFullscreen();
703        }
704      } else {
705        if (document.exitFullscreen) {
706          document.exitFullscreen();
707        }
708      }
709    });
710
711    // Select all the links that need to be preloaded
712    const linksToPrefetch = document.querySelectorAll('.read-more, .header-href, .pagination a, .header-item a');
713    const prefetchedLinks = new Set();
714
715    // Debounce to avoid excessive prefetching
716    let prefetchTimer;
717
718    linksToPrefetch.forEach(function (link) {
719      // Use mouseenter for hover devices only
720      if (window.matchMedia('(hover: hover)').matches) {
721        link.addEventListener('mouseenter', function () {
722          clearTimeout(prefetchTimer);
723          prefetchTimer = setTimeout(function () {
724            if (!prefetchedLinks.has(link.href)) {
725              var prefetchLink = document.createElement('link');
726              prefetchLink.rel = 'prefetch';
727              prefetchLink.href = link.href;
728              prefetchLink.as = 'document';
729              document.head.appendChild(prefetchLink);
730              prefetchedLinks.add(link.href);
731            }
732          }, 100); // 100ms delay to avoid prefetching on quick mouse movements
733        });
734      }
735    });
736  });
737</script>
737
738
739</body>
740</html>

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