# 行尾策略：按文件类型钉死，避免各平台/各编辑器来回转换
#
# .bat 必须永远是 CRLF —— cmd.exe 逐字节解析批处理文件，用裸 LF 会
# 解析错位、把每行开头吞掉（`%PY% start.py` 会被读成 `art.py`），
# 双击启动必然失败。2026-10 本项目就因为 .bat 被存成 LF 而全线打不开，
# 且这份坏文件已经进了仓库。下面的规则让它不可能再发生。
*.bat text eol=crlf

# 源码与文本统一 LF（跨平台开发最通用）
*.py   text eol=lf
*.js   text eol=lf
*.css  text eol=lf
*.html text eol=lf
*.md   text eol=lf
*.yaml text eol=lf
*.yml  text eol=lf
*.toml text eol=lf
*.txt  text eol=lf

# 下面三类 + 无扩展名的 LICENSE 也必须钉死（2026-10-23 第十一轮外部复核后补）
# ---------------------------------------------------------------------------
# 钉了 eol 的文件，**每一台机器**检出的字节都一样；没钉的就跟着本机的
# `core.autocrlf` 走 —— 而本项目的产品是「从源码构建出可复现的产物」，
# 那条承诺要求**产物字节只由内容决定**。
#
# 实测踩到的后果（2026-10-23）：已发布的 2.12.6 sdist 里，MANIFEST.in /
# docs/*.json / docs/*.csv / server.json 是 **CRLF**，而 git 里存的是 **LF**
# —— 同一份源码在不同机器上构建出**不同字节**的 sdist，
# 「本地构建 == PyPI == GitHub 三方 sha256 对账」因此只在那台机器上成立。
# 同样的洞也让 wheel 差 21 字节：LICENSE 没钉 eol，
# Windows 检出后是 CRLF（1108 字节），而已发布的那份是 LF（1087 字节）。
#
# 判据：**每个进产物的文本文件都必须有 eol 规则**。
# 少了任何一条，构建出来的字节就随构建机变 —— 而这件事在 CI 上看不出来
# （CI 的 runner 固定是 Linux）。
*.json text eol=lf
*.csv  text eol=lf
*.in   text eol=lf
LICENSE text eol=lf

# 2026-10-24 第十二轮外部复核后补：上一版补的是「按扩展名」，于是**无扩展名**
# 的那三个文件漏在外面 —— 而它们恰恰是会进产物的（.gitignore 与 .gitattributes
# 由 MANIFEST.in 收进 sdist，py.typed 是包数据）。
#
# 实测踩到的后果：已发布的 2.12.7 sdist 里，`.gitignore` 与 `.gitattributes`
# 是 **CRLF**，而在 `core.autocrlf=false` 的机器上从同一个 tag 重建出来是 **LF**
# —— 同一份源码在两种机器上导出成**不同字节**的 sdist
# （29a9f8bf… vs c3001fed…，差 96 个 CR）。
# 根因：`git archive` 对**没有 eol 规则**的文本文件按本机 `core.autocrlf` 转换，
# 而那三个文件正好一条规则都没有（`git check-attr` 实测：text/eol 都是
# unspecified）。
#
# 判据仍然是那一条：**每个进产物的文本文件都必须有 eol 规则**。
# 这次补齐的是「无扩展名」这一类 —— 上一版按扩展名补，漏的正是这一类。
.gitignore     text eol=lf
.gitattributes text eol=lf
py.typed      text eol=lf

# 二进制：禁止任何行尾转换
*.log   binary
*.png   binary
*.jpg   binary
*.svg   binary
*.whl   binary
