diff --git a/.gitignore b/.gitignore index 015fddc..1788bb0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ __pycache__/ *.pyc .pytest_cache/ .venv/ +.license.json diff --git a/LICENSE.md b/LICENSE.md index d8b3874..56c69a5 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -25,6 +25,12 @@ 本技能的全部知识产权归授权方所有。本授权书未明示授予的权利,均由授权方保留。对违反本授权书的行为,授权方保留依法追究责任的权利。 +## 六、命主档案与共建数据 + +1. **命主档案权属**:本机命主档案(`memory/archives/`)归命主与使用者本机所有,授权方不主张任何权利;档案只存于使用者本机,不随授权副本分发,使用者不得将档案原文外发。 +2. **脱敏共建数据**:经使用者授权推送的脱敏档案(`share/`,结构化 JSON,不含姓名、出生分钟与钟表时间、省以下地域与自由文本),授权方仅可用于本技能的优化与规则蒸馏,不另作他用,不对外出售或转授。命主或使用者可随时联系授权方,按盘 hash 撤回已推送的脱敏档案。 +3. 未经使用者明示授权而导出、推送命主数据,或将脱敏档案用于上述用途之外的用途,均构成对本授权的违反。 + --- 四川灵爻妙解文化传播有限公司 · https://lingyaomiaojie.com diff --git a/README.md b/README.md index 68b9f7d..08f6a78 100644 --- a/README.md +++ b/README.md @@ -61,14 +61,23 @@ tests/ 排盘脚本测试(时区、夏令时、日界、流年小 ## 授权说明(重要) -本仓库为**公众授权版**副本: +本仓库为**公众版**: -- **副本编号**:`LY-20261007-AC63`(水印指纹,嵌入 SKILL.md、rules/ 各文件、cast_chart.py 与授权状态文件,泄露可溯源) -- **授权对象**:normal(公众) -- **授权额度**:排盘 **1000 次** -- **有效期至**:**2026-12-31** +- **首启签发**:首次排盘时自动在本机签发个人副本(副本编号 `LY-日期-随机`),**初始 20 次、不限期**;授权状态只存本机 `data/.license.json`(不入库)。 +- **档案共建激励**:每成功推送一份脱敏档案(见下),授权次数 **+10**;同一盘(四柱+出生地)只计一次。 +- **水印指纹**:副本编号(池编号 `LY-20261007-AC63` + 个人编号)嵌入 SKILL.md、rules/ 各文件、cast_chart.py 与授权状态文件,泄露可溯源。 +- 软锁(`scripts/_license_gate.py`):次数用尽后排盘脚本拒绝运行(退出码 4)。完整授权条款见 [LICENSE.md](LICENSE.md)——**禁止商业用途,禁止二次传播**。本技能全部知识产权归 **四川灵爻妙解文化传播有限公司** 所有。 -副本内置软锁(`scripts/_license_gate.py`):次数用尽或到期后排盘脚本拒绝运行(退出码 4)。完整授权条款见 [LICENSE.md](LICENSE.md)——**禁止商业用途,禁止二次传播**。本技能全部知识产权归 **四川灵爻妙解文化传播有限公司** 所有。 +## 自更新 + +技能会持续迭代。排盘后有新版本时 stderr 会提示一行;更新由你决定: + +```bash +python scripts/self_update.py --check # 检查更新(24h 缓存) +python scripts/self_update.py --apply # 应用更新(先校验 SHA256 清单再换文件,授权与档案保留) +``` + +更新线路 GitHub 优先、Gitea 镜像兜底。 ## 开发 diff --git a/SKILL.md b/SKILL.md index 40261e4..b842fe3 100644 --- a/SKILL.md +++ b/SKILL.md @@ -66,9 +66,10 @@ python scripts/query_shensha.py --gender 女 \ 本技能归**四川灵爻妙解文化传播有限公司**所有,以**测试授权**方式分发,条款见 `LICENSE.md`:禁止商业用途、禁止个人传播、保留法律追责途径。 -- **水印指纹**:定制副本在 `SKILL.md`、`rules/` 各文件、`scripts/cast_chart.py` 与授权状态文件中嵌入唯一副本编号(形如 `LY-20261007-A3F9`),副本泄露可按编号溯源。 -- **软锁**:定制副本含 `data/.license.json`,排盘脚本按授权次数与有效期放行;用尽、到期或授权文件被改动时退出码 4。总开关为 `scripts/_license_gate.py` 顶部 `_ENABLED` 一行变量——软锁防君子不防小人,是授权边界的可见表达,真正约束以 `LICENSE.md` 为准。 -- **母版与副本**:技能开发目录为母版(无授权状态文件,不锁)。分发副本由授权方一侧的 `tools/make_license_copy.py` 生成:`python tools/make_license_copy.py --licensee 张三 --uses 20 --expires 2027-12-31 --out <目标目录>`;该工具不随副本分发。 +- **公众版(首启签发个人副本)**:公众版不带授权状态文件,只带标记 `data/.public_edition.json`;首次排盘时由 `scripts/_license_gate.py` 就地签发个人副本——**初始 20 次、不限期**,授权对象 `public-personal`,个人副本编号此时生成。之后与定制副本同样校验。**推送脱敏档案每盘 +10 次,同一盘只计一次**(见「档案共建(share/)」节)。 +- **水印指纹**:副本在 `SKILL.md`、`rules/` 各文件、`scripts/cast_chart.py` 与授权状态文件中嵌入唯一副本编号(定制副本形如 `LY-20261007-A3F9`,公众版为池编号形如 `LY-20261009-PUB0`),副本泄露可按编号溯源。 +- **软锁**:授权副本含 `data/.license.json`,排盘脚本按授权次数与有效期放行;用尽、到期或授权文件被改动时退出码 4。总开关为 `scripts/_license_gate.py` 顶部 `_ENABLED` 一行变量——软锁防君子不防小人,是授权边界的可见表达,真正约束以 `LICENSE.md` 为准。 +- **母版与副本**:技能开发目录为母版(无授权状态文件、无公众版标记,不锁)。分发副本由授权方一侧的 `tools/make_license_copy.py` 生成:定制副本 `python tools/make_license_copy.py --licensee 张三 --uses 20 --expires 2027-12-31 --out <目标目录>`;公众版 `python tools/make_license_copy.py --public-edition --out <目标目录>`。该工具不随副本分发。 ## 输出契约(v1.2,章节标题冻结) @@ -181,7 +182,21 @@ stdout 的 Markdown 依次包含以下章节。标题是解释规则的定位锚 `python scripts/memory_lookup.py --birth "1990-05-14 08:30" --place "四川省成都市" --gender 男` (亦可按 `--name` / `--pillars "丁亥 乙巳 庚子 辛巳"` 任意组合检索)。有档则读档延续——此前的归纳、已核实/已证伪反馈在分析推理时直接参用,已证伪的断法不得再断;无档则正常排盘解释,解释完成后用 `python scripts/memory_save.py --name ... --gender ... --birth ... --place ...` 建档(建档即一次排盘,授权副本照常扣次)。 - **回写纪律**:用户核对或澄清了任何断语后,当轮把结果写回该档案的 `## 反馈与澄清` 小节,每条以状态标签开头——推测性归纳标【未核实】,命主确认改【已核实】,被否改【已证伪】并补一句实际情况;结构性结论同步更新 `## 归纳` 各行。 -- **隐私**:档案属命主个人信息,只存本机、不随授权副本分发、不进 share;不得把档案原文外发(不粘贴到外部对话、不上传网络、不写入其他文件)。 +- **隐私**:档案属命主个人信息,只存本机、不随授权副本分发、档案原文不进 share;不得把档案原文外发(不粘贴到外部对话、不上传网络、不写入其他文件)。回传授权方的只有按下节规格生成的结构化脱敏包,且必须经用户授权。 + +## 档案共建(share/) + +用户可自愿把**脱敏后**的命盘数据回传授权方,用于技能优化与规则蒸馏(脱敏规格、隐私协议与撤回方式见 `share/README.md`)。每成功推送一盘,本副本授权次数 **+10**;同一盘(按盘 hash)只计一次,不重复加次。 + +- **导出**:`python scripts/share_export.py --archive <档案路径>`(或按 `--birth/--place/--gender` 检索定位),生成结构化 JSON 脱敏包到 `share/pending/<盘hash>.json`。完整度门槛:性别/四柱/大运齐全 + 至少一条反馈事件(任意核实状态),不满足则拒绝导出(退出码 2)。**未核实推测不得入包**:归纳小节的推测性结论一律不导出;反馈事件(带核实状态标签)可入包,自由文本(反馈原文、盘面细节、归纳文字)一律不入。 +- **授权询问(强制)**:推送前必须先把脱敏包**全文展示**给用户,并询问是否授权推送——用户同意才执行推送;不同意则取消,脱敏包保留在 `share/pending/`(用户可随时删除),不影响技能正常使用。 +- **推送**:`python scripts/share_push.py`,把 `share/pending/` 的包推送到 `share/config.json` 配置的共建远端(GitHub / Gitea 逐个尝试,至少一个成功即算成功;远端地址由授权方填写)。推送成功后包移入 `share/pushed/`,并告知用户新增授权次数(+10;该盘已计励过则不重复加)。推送失败(无 git / 无网络 / 远端不可达)保留 pending,不丢数据。 + +## 版本与自更新 + +- **版本基准**:仓库根 `VERSION` 文件(如 `3.5.0`)+ `manifest.json`(全部文件 SHA256 清单,发布时由 `tools/build_manifest.py` 生成)。 +- **更新提示(缓存制、不打扰排盘)**:每次排盘成功后,若本地缓存的检查结果已过期(24 小时)则后台线程拉一次远端 VERSION 刷新缓存(超时 3 秒、失败静默,主流程不等);缓存显示有新版本时,stderr 提示一行「技能有新版本 X.Y.Z,运行 `python scripts/self_update.py --apply` 可更新」。 +- **应用更新(须用户同意)**:用户说「更新技能」时再运行 `python scripts/self_update.py --apply`——从 GitHub 拉取(失败转 Gitea),**先按 manifest.json 逐文件校验 SHA256、任一不符即中止不动本地**,通过后覆盖更新;`data/.license.json`、`memory/archives/`、`share/pending/`、`share/pushed/`、`.git` 保留不动。不得替用户自动执行 --apply。 ## 文风与反 AI 腔(强制) diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..1545d96 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +3.5.0 diff --git a/data/.license.json b/data/.license.json deleted file mode 100644 index a29be2b..0000000 --- a/data/.license.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "copy_id": "LY-20261007-AC63", - "licensee": "normal", - "issued_at": "2026-10-07", - "expires_at": "2026-12-31", - "max_uses": 1000, - "remaining_uses": 1000, - "sig": "be2d5467c8bc1d78" -} \ No newline at end of file diff --git a/data/.public_edition.json b/data/.public_edition.json new file mode 100644 index 0000000..3fdd699 --- /dev/null +++ b/data/.public_edition.json @@ -0,0 +1,7 @@ +{ + "edition": "public", + "pack_version": "3.5.0", + "pool_copy_id": "LY-20261007-AC63", + "issued_at": "2026-10-09", + "note": "公众版:首次排盘时自动签发个人副本(初始 20 次、不限期);推送脱敏档案每盘 +10 次(同一盘只计一次)。" +} diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..adb7ffa --- /dev/null +++ b/manifest.json @@ -0,0 +1,1269 @@ +{ + "files": { + ".gitignore": "56100520d4c482622c8e8f5abb3822815e73e0926028e0859105d5acef556961", + "LICENSE.md": "6b839540e0fd4ab75530ec31fc5c3cbc3c2d5de5fe85068ef1c0901e54be9315", + "README.md": "1e11e5d19856fbd9bb15068c74e184617a10b2e0b18c7e42d9b617cd0d8f534a", + "SKILL.md": "8b493ae2236b5941c88e282d4793126487e4d81a6f3c24976020fb26e50cf67a", + "VERSION": "76120c1f2c4311c2154c22a6b58e00e411e0ebe76afae0daf608d9196c61f114", + "data/.public_edition.json": "e8692c45d512c78903fc89a924d0e6d4dc9b95a78ca6b359bb7a5ef5c946ffee", + "data/cities.json": "00f17905c8843218162e25238a78aeb4c4a3bb5424b611cc30ed9e436db31854", + "memory/README.md": "b3cf2c58a8418a8c1a54243c2e09fbdb42f31dcd48ba8c841b74f1234c7fe063", + "pyproject.toml": "58e415e53d2418721fa07bd81b829e4bc5bbfb2155a446bce6222d3f7afeda12", + "requirements.txt": "46a4c971b192cbf2c4972dd0f420e7928b7e44cd3cb9f7dc5a36efb321ab6fd6", + "rules/00_总纲_取格.md": "829a35454f5c91966ecafe4dd2113b913588933efe08d0e1c127ae82ccec0da8", + "rules/11_正官格.md": "385193d93dfba89a935ca8907098f70548ad1fc12ab6a07a5280fd04224c83b6", + "rules/12_财格.md": "8d2bafdf859d51e4d3932e0dbcddb0eb6b300cbef412b3b17a8b8232a0cef8c8", + "rules/13_印绶格.md": "57e6e02a47b464ed0983145f01e7dd457ea34be8d7beaccc851f34680b6b10e0", + "rules/14_食神格.md": "90379637f528c8502de8397ae60c5447fc9cf07157ed480042fabcf7ea5f2830", + "rules/15_偏官格.md": "12b7f6fa55075e45519e559f4648abe32f16f0b0c85f9761d4b2b058954b4a7e", + "rules/16_伤官格.md": "c70f90d7d6823bb330e8f53141408e304b6761b3e0ec6adfc9fadf109a22fbf5", + "rules/17_阳刃格.md": "51055e7c0edd607f6fe98425b7c82c69fb9ec88f2c058fcd3e5aa04d6ede8c0a", + "rules/18_建禄月劫格.md": "f0b400292d22cb3b38ab5011bda8080d511a065c661305f7a9c0485f1c57705c", + "rules/19_杂格.md": "78939bc9d61621a427fd41a31156086b3ae6675eccc77c899a3aa7443408ef26", + "rules/89_旺衰扶抑.md": "758180d5ee0aa46f4b22e8817baa831974c9c3b239078ba51e0a7b9016f7f47b", + "rules/90_行运.md": "510c243e84f3cffacf0a85887b8cc8650bb009083112390c50d5f8ab8c969587", + "rules/91_何知事类.md": "3775448e1830929dbcbc90cacf1065a4ab0592c9c4ee984c09ec187911bcf2c1", + "rules/92_调候.md": "8d37d2cb722ae4b581532b7b73218fd648f1e75d8e16c6bedbabe0f93a2e1946", + "rules/93_性情.md": "c9d3003cf4e0869e5075623e34bad41faa294623df1b2481e0f30b80fc61cec6", + "rules/94_神煞细节.md": "96daaac4ff70ece5d1fb7b4eea3da458ef30578933d770b9ce7e1fed067f78a2", + "rules/95_禁则.md": "c151aba005c1789ed5e75eb26fcccab4b636035d8f035fa4e0fc18bcdcbf6251", + "rules/96_六亲.md": "96cf362bd180558352d0181401ac8e297ac89c09d91d1098972a9d1c40468198", + "rules/97_女命.md": "52962aa666faa3fa2a5175d352380df14f54fefb8f57cfe0761779ad51e18696", + "rules/99_附录_干支通例.md": "da906502391833eb1744ff0145a03c7d1e10781ac7156034632dc5994da0d2f4", + "rules/README.md": "80a77a744fcac31673dd7eb9f84cb80b83c9d61c4d0aaabcb39e86f98f661c2f", + "rules/sources/README.md": "183ba554b1d89c16b19fb65ac8a4d0614069c865676fb4c1bd20d95b5581c209", + "rules/sources/三命通会/00_卷一·原造化之始.md": "6329058dd08aed5f41d1111da99027cac38761aeea7120a84eff02683426294d", + "rules/sources/三命通会/01_卷一·论五行生成.md": "c9db87683a6d3f9b7eea665e3814e383e11a69b608114d9317beb2a2c56825f8", + "rules/sources/三命通会/02_卷一·论五行生克.md": "f548bc646cdd24d7c23464dd5ab54dbabf7ef097fa4ca92444ffafba3e9a9569", + "rules/sources/三命通会/03_卷一·论支干源流.md": "25d989a7ff21664260fc3468ba19a834e527a9abcdd1e76b8202dee708ba179e", + "rules/sources/三命通会/04_卷一·总论纳音.md": "75b80bef411e74d4e5ff35dc7ac4c977c664bc381dcd7ee4899f3f7f84893915", + "rules/sources/三命通会/05_卷一·论纳音取象.md": "a12cc515c843c3938a3bfb79366dcb619dfa4e1af199d85c2cf6d3b4dac9789e", + "rules/sources/三命通会/06_卷一·释六十甲子性质吉凶一.md": "ba07e0b9b9c15005e647c643dbf17e12d2b47af38d8b2db4fbfe366f09bcae9b", + "rules/sources/三命通会/07_卷一·释六十甲子性质吉凶二.md": "07299823398e22d0160f3f501a2fa5bfdca5cf5886fb2ec45b6959710dca68b0", + "rules/sources/三命通会/08_卷一·释六十甲子性质吉凶三.md": "da53ae2d7facc2fc30a7bff4d18ef289ee74d8f99001e80daea157e7e0547876", + "rules/sources/三命通会/09_卷一·释六十甲子性质吉凶四.md": "101d661b93f0371818c3c6eeaf2165bf4bf638a6b8d520615ccba9efad30f34d", + "rules/sources/三命通会/100_卷六·日禄归时.md": "4534cf99d0f5ca08ecf4c72055a4483eabb4e2a2a9b9e1970b47f9e24d20ca74", + "rules/sources/三命通会/101_卷六·拱禄拱贵.md": "f0beb5f4304bddd9b7718e6c552ac76eafc12b76e2f26c069b18053cd01ebf92", + "rules/sources/三命通会/102_卷六·冲禄.md": "78635c4c17cc43b4de841af5caa906c6f7f0a826c79447dce3fdf9f52b6ff482", + "rules/sources/三命通会/103_卷六·六壬趋艮.md": "88c68cb3b542688fb0d7a441e332bb172a6125312739d19f07e578ed4a8f1342", + "rules/sources/三命通会/104_卷六·六甲趋乾.md": "8b8c44b51950d653467e8df747ac9f29d6fa41ac8715383c734183dc5daeaed5", + "rules/sources/三命通会/105_卷六·财官双美.md": "e552f5a0a220bc0f35e0ba0b40bacfac0afab64530b5ffd0b1471681d3f4c926", + "rules/sources/三命通会/106_卷六·日贵.md": "2d40b224ec02a388201c26fbf2bb773ef8c7b2c7bca7bfc1325eafcc41ffe6fb", + "rules/sources/三命通会/107_卷六·日德.md": "ce4356a41d31daae4ee6fb7e746baa352ab2695db0d5a03c813a787d094917d4", + "rules/sources/三命通会/108_卷六·魁罡.md": "d8441124094f5308b19dbfd1e9c8fc733847fa725f4e4b48c38bb7a2451b1039", + "rules/sources/三命通会/109_卷六·福德秀气.md": "3ef9f4352f5b1ffe39bf24b52c2a66dec3dff4bfdfaf4f3e6e5469c4450433a8", + "rules/sources/三命通会/10_卷一·释六十甲子性质吉凶五.md": "7a4f3ef7a82952a69a00847220b07637daa92c7424d53e1fab4b69f362096fa7", + "rules/sources/三命通会/110_卷六·禄元互换.md": "d91d57ca9c30f4eb1f959543ba2068489c6aef7fc061a2ee4376707e276e42c5", + "rules/sources/三命通会/111_卷六·子午双包.md": "26ea138d9622700bba25a7cda2dc81baaaeb0ee7ff0f65cbb3c68e3a8d9a1361", + "rules/sources/三命通会/112_卷六·青龙伏形.md": "c52ac86a1a9ff74812558d3ea24df98786db5feb6c2dcd44b37f5020e064f812", + "rules/sources/三命通会/113_卷六·白虎持势.md": "1531a1a911c3a9331e5ca140fda6e1aeab28d0b8cdf5ca226b277e47a910e10e", + "rules/sources/三命通会/114_卷六·朱雀乘风.md": "6d493ffc17c91d80049ebc35922c919df9e2b11a3f6c0da6fba6beef90dbf39b", + "rules/sources/三命通会/115_卷六·玄武当权.md": "15d87958027ce55ee6905874a2a12228dded8ddef34cd8e006c35f42c76b2545", + "rules/sources/三命通会/116_卷六·勾陈得位.md": "6e2d732438bf76eb8edc5f6975b82c2096189584cf8e83963c77c3db3c35885e", + "rules/sources/三命通会/117_卷六·还魂借气.md": "76c9b7e02c6ec08925404a2b298a95c53ee48e1a801146a83d4942df3f5cba0a", + "rules/sources/三命通会/118_卷六·八专禄旺.md": "92ee18c8b19d62375cbf3c1319c1393d15d4b98a0386cdb0c9da06ce13c2b9d6", + "rules/sources/三命通会/119_卷六·曲直.md": "8708af3c1b27df54500d92dee6f049510cdd9c7b581dd9abcea0570e9d7a327a", + "rules/sources/三命通会/11_卷一·释六十甲子性质吉凶六.md": "ca23dab477f1f7049da5a1c15263569aa571ee0af426acdfcdf67f19d24cca01", + "rules/sources/三命通会/120_卷六·炎上.md": "f3baca071f3ce61eeebfb9973720eb65ccc1c83f389a523c49e0acd94ee0d3cc", + "rules/sources/三命通会/121_卷六·从革.md": "fe979fbc0eb71e2a317b8ff633902597e7fc067aa7c7cb3c9fcd96c1cc230038", + "rules/sources/三命通会/122_卷六·润下.md": "87a33174b6988bdbab316f267ec7f7b3defffa0f52729d8db9cebe13a6a1c0ba", + "rules/sources/三命通会/123_卷六·稼穑.md": "04a33c6bb6815dafb3ef1853e750c794451cd05572d06181e14c4cb33062f35e", + "rules/sources/三命通会/124_卷六·土局润下.md": "33ae3248ec653ac53ee5583674dfb95099079d3e9256f09fee122017445d6355", + "rules/sources/三命通会/125_卷六·金白水清.md": "57e36f09c9d4153b73608bb003a61aafbfed1744ed941a243afd1fb86a8e0f18", + "rules/sources/三命通会/126_卷六·木火交辉.md": "ffeb193cef08898c694dcd04cf561cd09d0c75eabf112b36e514482bd6b0b234", + "rules/sources/三命通会/127_卷六·火金铸印.md": "3e21128b4e0973c8572845de20c3ba76d5a1fda96319b0c76dbc050975ea083a", + "rules/sources/三命通会/128_卷六·火土夹杂.md": "7d1dfdf45886e10881a50d06d0b6835b43128047866c6400e4ebc299f0df9c62", + "rules/sources/三命通会/129_卷六·墓煞.md": "e7283de57150cb599983e12094b8c596c63a025f6d73eabdbef528ec034cd63a", + "rules/sources/三命通会/12_卷一·释六十甲子性质吉凶七.md": "23354e945b34a8d5d1e406aa93b082756768cd5fbb7416682a59602a0d009d4c", + "rules/sources/三命通会/130_卷六·四位纯全.md": "2bc41fb48261a1ab524adb79a05b6399715d7bcb5d22090ef405b0107d2459ec", + "rules/sources/三命通会/131_卷六·一气生成.md": "29a8af066343433b542bb46fa2b49c07775cac05b6db93d20cf3c04db608be9d", + "rules/sources/三命通会/132_卷六·背禄逐马.md": "4a23afc4e08a5aff3a235b1530a01bc3f29fdc320a922b395ae7aa922c5af10e", + "rules/sources/三命通会/133_卷六·十干十二年生大贵人例.md": "adab9ddbf6c6cc921f285cac3d402cee14678145a95a5708ba4a0d947e37c759", + "rules/sources/三命通会/134_卷六·论正财.md": "e7c183ccabd9a4350b5ae2131325ac32792340b99bb1638bbbca0984d753a815", + "rules/sources/三命通会/135_卷六·带正马.md": "62302faac1b3fc2c8f4c11844af7480e71291ebfb87314a593a3a1b43da24faa", + "rules/sources/三命通会/136_卷六·时带正马.md": "e28ea00417161c51b90dddf7b45e5dc0f9ad8dcc5a673c6e2c33309743abdab2", + "rules/sources/三命通会/137_卷六·财旺生官.md": "00e91fa77deee11ccf3d8e5e4665e020ed08984ae61d3222de4d908b28820337", + "rules/sources/三命通会/138_卷六·天元坐财.md": "d1e4f37ad83355a64f8354d03c995e4bbdd4adbe7531ffca41794985105e8d87", + "rules/sources/三命通会/139_卷六·论偏财.md": "f5d2896cfa6631463613308bc89cb1a411b27701a0894eedf37292d2b0f8c601", + "rules/sources/三命通会/13_卷二·论天干阴阳生死.md": "2920157e9362e65b3a0f6b59e76b8587019b757da5c140078d6eaf7b2a6c5acd", + "rules/sources/三命通会/140_卷六·时上偏财.md": "6a04318eb03cf7d02ffb123715445fe377b44d2b90b07e52d84f5f8a7827f385", + "rules/sources/三命通会/141_卷六·弃命从财.md": "eae2d728f9a7f13756760dcab4f56b5a8126945cf14e5fb8eea23b84aa902784", + "rules/sources/三命通会/142_卷六·日坐天财.md": "eae2a343b0b721b9bef222694cbdd36d3ceedaba326883c24d2eeb98fd3e1869", + "rules/sources/三命通会/143_卷六·偏正财合论.md": "e8d7b627292104bd10490d8448a5c217ef384c6e37855a2bfbd7d7dcb9c607cb", + "rules/sources/三命通会/144_卷六·论印绶.md": "e3f1830f34feaadad2d385d976a9cdc835b5f0708ee683a2b24295c310ffea16", + "rules/sources/三命通会/145_卷六·时逢生印.md": "e43af6f3c765a5cd01d5de04c8b4fe79721d62196dd94d93d8ff2443fd39c98f", + "rules/sources/三命通会/146_卷六·胞胎逢印绶.md": "687e63aec61004ea01b390fd16e5eea35d55091105e4287fc67f051387b5625d", + "rules/sources/三命通会/147_卷六·弃印就财.md": "5861dfee5c0bd4ed3b4e653dd62d68fdd057ceccf2176f0b0c6a218831daaf3b", + "rules/sources/三命通会/148_卷六·论倒食.md": "2bedbb89f8866244feca2314be34b52bf5399ace0ed1b2346039c8c5278463d0", + "rules/sources/三命通会/149_卷六·论杂气.md": "f77c81f161085f8cdaedc876105cc46aaf02fea1517d854f66c78f24f353c519", + "rules/sources/三命通会/14_卷二·论地支.md": "d74791999dc1209f7981175a05f30d58df83a5df796596feacf0ac9bbf332134", + "rules/sources/三命通会/150_卷六·附论墓运.md": "e080ca2e3e2ac093a1bd65ded9284c5489a502e23905e8b2e064e65cd3be9b37", + "rules/sources/三命通会/151_卷六·论伤官.md": "8cf2b76cbc85528dd284fa3fc6a81d4db8e91e0b18a73883ee002bbe441fb252", + "rules/sources/三命通会/152_卷六·论食神.md": "14c8f3197f192b240b1b0b7e303fd7bda80f4d5ba6627ae9def8ea892e1c9d36", + "rules/sources/三命通会/153_卷六·飞天禄马.md": "96d88b4faec1be9971c001d413f6d8daf4167ef77c0acac7349cfb3d6ce6ee8e", + "rules/sources/三命通会/154_卷六·倒冲禄.md": "8c07f571d9ffa62fc9b9a7b3e7e718f72d816c6eb0e84e1603a37c53b73e9a6f", + "rules/sources/三命通会/155_卷六·福星贵人.md": "c57684010e9cd76faf719290b6ca1ea3a419da83b53366afc1190f2eb12aa913", + "rules/sources/三命通会/156_卷六·食神同窠.md": "b41aab71ff9df5b25d426d9a758fb5c09489e7e647c243cbbc40223f003be687", + "rules/sources/三命通会/157_卷六·食神带合.md": "7b3e60076786b7fe5ab82803649b16c75035deccfdb237ea43f1027fbe797314", + "rules/sources/三命通会/158_卷六·红鸾天印.md": "d0cb143306a8562213bd36d4df83dc4a0e5ac5706b37768b216a5c07bb7054a6", + "rules/sources/三命通会/159_卷六·墨池涌泉.md": "e5aadb587b966a386e20a4ebbc6aa0054057256270e0bf4eb2272d82939591c1", + "rules/sources/三命通会/15_卷二·十干分配天文.md": "14ae474aba10da9765820d2d1968042d59c48c294bbd02ab9331163af68d0766", + "rules/sources/三命通会/160_卷六·论阳刃.md": "75573d62cb278973ea5d669b6b2e7ead2844250e2e4fd780073a7feffaf41b96", + "rules/sources/三命通会/161_卷六·论建禄.md": "3238da4c0aa51b8c7a61f19b7700e9bd2e8e1d33ac144a9b23817dfba58034fb", + "rules/sources/三命通会/162_卷七·论性情相貌.md": "a849b527430a41256b32c62d3abb746af0c988e2803c90dfcd8e683104bd0502", + "rules/sources/三命通会/163_卷七·论疾病先知五脏六腑所属干支.md": "b5c479a480671d7afc72bb9edb225a73c59eed7bc45fec4607ecd1dc0cadd24b", + "rules/sources/三命通会/164_卷七·论女命.md": "517a1de529da651401b65f2ee5816af061846043559800e584ed86a819288998", + "rules/sources/三命通会/165_卷七·纯.md": "7ebbafbbc45a692e3ac4b83587e301da4b63da265994b8cf73bd2dda6c2c19c2", + "rules/sources/三命通会/166_卷七·和.md": "0cdff5f963ac3bc0ee2af63486795cb347706539d7443dddcb5328aa8e19c507", + "rules/sources/三命通会/167_卷七·清.md": "f429f489afc1b0370ad48f678a7ebfacccc7aa3254d408ce78a62c387a198479", + "rules/sources/三命通会/168_卷七·贵.md": "4f39871f629eab8cb672837a14cbf5cb539f1c9de4b5ca6d542e35a0dfca3d3a", + "rules/sources/三命通会/169_卷七·浊.md": "07874a1327d7a6c15185748d911a047745414cfc7f44c353098a3931e64807d7", + "rules/sources/三命通会/16_卷二·十二支分配地理.md": "4c9cbec03f1dd887288f1cd93e0408be8a09d72babfbc38b78c00905ab65dec4", + "rules/sources/三命通会/170_卷七·滥.md": "60172afb74732f4dd4206f35e5a3add11ab64b3563ed357023535ef95fc6e31c", + "rules/sources/三命通会/171_卷七·娼.md": "7d6af20dc5df1253c7bec566fc3229a91c201d46cbae5ade24882a1ba2af6dba", + "rules/sources/三命通会/172_卷七·淫.md": "b1d8908d4d4be818750bb8cf9951a655d84444a35b1c6880100f45d0abdfde01", + "rules/sources/三命通会/173_卷七·旺夫克子.md": "33622d4743c025d74b6b72595696dc09f2915858fd27bc52a10578e63e7d1d62", + "rules/sources/三命通会/174_卷七·旺子伤夫.md": "15a2fec673ac438431b66eec794dcaf3c317e978559df3b9145904008bd91ee1", + "rules/sources/三命通会/175_卷七·伤夫克子.md": "1ad876b7769d3761eaa232043b4cfbf810c4530844dd254f0d283a19c5de44b4", + "rules/sources/三命通会/176_卷七·安静守分.md": "a8c358eeb87ef8ff21213d071f2d9662db2136e3d1c19c0183fdb4a4a7309380", + "rules/sources/三命通会/177_卷七·横夭少年.md": "d7caed5014e9164f14fdc0eb18c2257b1649198c937fee417b68b562b9964caf", + "rules/sources/三命通会/178_卷七·福寿两备.md": "9c7bb57c47db6dbf07c5d3599d9506aba898454490c08a34adfcb5e879924fe4", + "rules/sources/三命通会/179_卷七·正偏自处.md": "b78f5d63ec7edb37b6433d5d2d4c59ca9dcdbc836ac6512d99d45a873115c1a4", + "rules/sources/三命通会/17_卷二·论地支属相.md": "b7cbf6e3d849042b7656f89c81f4c3034747398ed93629bd57610cc157921eaa", + "rules/sources/三命通会/180_卷七·招嫁不定.md": "5fb06a761f44de8a79f81632c91b4fff3c597144bc7c2e05f14640c88ec029d5", + "rules/sources/三命通会/181_卷七·论小儿.md": "89a2254d5eb1288d126595bccf7a016e6b89bce678d51c8236fb1ba9fcc9dcb8", + "rules/sources/三命通会/182_卷七·论六亲.md": "4b5a32bc886e2bb95dd17a2d7ef054294561cc92d9bff03bd54ee4059f4ffed0", + "rules/sources/三命通会/183_卷七·定妇人孕生男女.md": "b79a5a240ef012fb950132728193e899e3c3416a46072c88f75e678c9f2e4398", + "rules/sources/三命通会/184_卷八·六甲日甲子时断.md": "bb0244481df89ed927512601031059a4104c886103e36388386f890459338c9c", + "rules/sources/三命通会/185_卷八·六甲日乙丑时断.md": "4118d3cb2b99a4f2765f79eaf2f51136043092741d6cb5e71a5f0eec4c571518", + "rules/sources/三命通会/186_卷八·六甲日丙寅时断.md": "ae6d5678a8a12b462e5a176c774869dca6e70e857f6ee6ff8a373f7595f539a7", + "rules/sources/三命通会/187_卷八·六甲日丁卯时断.md": "1bd3278b8390234f366a38b8a5bc1cbb0ce1f931c30354cc64b112a3da73ecd4", + "rules/sources/三命通会/188_卷八·六甲日戊辰时断.md": "994e7619c8b2920f74084454698399052090321fff65bacec976b39bec15a37c", + "rules/sources/三命通会/189_卷八·六甲日己巳时断.md": "004ab2513bec8bfdfaa289964da4bf0cb8ba695f851f05701b409de45989482c", + "rules/sources/三命通会/18_卷二·论人元司事.md": "fb80bcbafbdeaae24a63c20441a79734e0e9f7a7cbc41f52a8d8d5cfe239cec0", + "rules/sources/三命通会/190_卷八·六甲日庚午时断.md": "62083baa764e8d415bb442b2eacbd0146fae83e5b03fb8e3e5698157a102a28e", + "rules/sources/三命通会/191_卷八·六甲日辛未时断.md": "68e4caf435b399d7c60384a08717253d56628552b92616802cf3653fd44878c0", + "rules/sources/三命通会/192_卷八·六甲日壬申时断.md": "505766821ce63a947300fd472a26c3f27151e4946272aa8bea2f852a7f539aac", + "rules/sources/三命通会/193_卷八·六甲日癸酉时断.md": "05df0885d8db333b5e8325dd1b5cbe0d5667e4c15ab206e63ce2911670e47011", + "rules/sources/三命通会/194_卷八·六甲日甲戌时断.md": "2dba1efd0f6bc0d4773012c3eee7c960ef7fe2fcd2e9a871952d2bd06498020e", + "rules/sources/三命通会/195_卷八·六甲日乙亥时断.md": "93f54d240fc42173ced15526297759c82805623956fc105afa52618cadcdf830", + "rules/sources/三命通会/196_卷八·六乙日丙子时断.md": "b8416f1bbd0cc2d6bed67db5b1c3074a967224ea3ab2ed4c70d2ad14de17cd6f", + "rules/sources/三命通会/197_卷八·六乙日丁丑时断.md": "b37de5584733b16d47ef40e7645a91b8ac571da455fd4fd1b0227a018a77c7e5", + "rules/sources/三命通会/198_卷八·六乙日戊寅时断.md": "d0bc9d91a9b37fcb66f2d898da3df410586ffbd21f6281257317809169e493bb", + "rules/sources/三命通会/199_卷八·六乙日己卯时断.md": "e91dd31d6428342554b8f2f63d6ef3744330e55d15527f60fae42194dffe550d", + "rules/sources/三命通会/19_卷二·论四时节气.md": "3df9d1dcf35276c38c29528437bd2bb66ca0fcce8e41f685dd65df103cd7f70b", + "rules/sources/三命通会/200_卷八·六乙日庚辰时断.md": "4d18e211ae89bf60eebea25c59ef0240ff43aabdd0f87e87b86a5096c25f21e5", + "rules/sources/三命通会/201_卷八·六乙日辛巳时断.md": "a8366a9b9113459e8b7be94bd574f991fb1101a88c80747d0593463d7405d5d2", + "rules/sources/三命通会/202_卷八·六乙日壬午时断.md": "74372b0521a73a57f5f4b2170013ad2623bb2c1b7a1720ff825f6c1e27eb3add", + "rules/sources/三命通会/203_卷八·六乙日癸未时断.md": "bc6aa7b7093dfcc56d1230017daee975430e6f1b96fc0e202a28f5b1b80dc34d", + "rules/sources/三命通会/204_卷八·六乙日甲申时断.md": "4f8488bbb46292f7c71fac8aefa82545dee7cace3185855eacf7c1d833cea8c4", + "rules/sources/三命通会/205_卷八·六乙日乙酉时断.md": "c541018b92b6ddb9213d41816b6be79f28269eae373d370e7d1deeb5dab6c220", + "rules/sources/三命通会/206_卷八·六乙日丙戌时断.md": "477d26d3a5adfe3e0f282da3924b3304e955a034e86b5159152ac1cec7b15b24", + "rules/sources/三命通会/207_卷八·六乙日丁亥时断.md": "64da3da7f0bf953b0aebd9188c3541ae780f5d2b2d6196e905243700bc36c2b9", + "rules/sources/三命通会/208_卷八·六丙日戊子时断.md": "530127c5d79812ac8457abd0432724154dd30c6448adba74bb7d1208aa04cfcf", + "rules/sources/三命通会/209_卷八·六丙日己丑时断.md": "73055b43aaf182f3789a5408362257558ad2509eaad026b982c96a6e6cd60073", + "rules/sources/三命通会/20_卷二·论五行旺相休囚死并寄生十二宫.md": "fac6e27d99d16a7504ee40aaf752b06d18049d7e8fe9cc3592cf76e48befef79", + "rules/sources/三命通会/210_卷八·六丙日庚寅时断.md": "33b4bda2ce3f3d81e370e96c49cd97c66f85b8b88070b2f96377eda94dd1c569", + "rules/sources/三命通会/211_卷八·六丙日辛卯时断.md": "473649507866c4451cd86f188b2a6aef5a48435dd2f57e2a8714530f207d52d8", + "rules/sources/三命通会/212_卷八·六丙日壬辰时断.md": "8f732f74d033bc5eff97f66bc6f415569ad226bd8362182a84f69f8f8773893e", + "rules/sources/三命通会/213_卷八·六丙日癸巳时断.md": "f9d4333df1a9fd67abb1504abeacceb9dfb9c261287c0319e52939f74562783d", + "rules/sources/三命通会/214_卷八·六丙日甲午时断.md": "573377ea302fdadae30487ab72191ebf5e6377e4ee49f90d191909e3f25c1bf5", + "rules/sources/三命通会/215_卷八·六丙日乙未时断.md": "9a7b774e778f6ab0827ea225e878bf86269fdd58647ce62efd1074d4931429c9", + "rules/sources/三命通会/216_卷八·六丙日丙申时断.md": "6a72bd514d8b8706970bd9347911ac3e11e2d9c663c8ff1517acc1ed8d1c731c", + "rules/sources/三命通会/217_卷八·六丙日丁酉时断.md": "9b0a3c164ecbdfca8b40b04dff7f494f0896d3827f074d86b741483f39909cc2", + "rules/sources/三命通会/218_卷八·六丙日戊戌时断.md": "7736d5446e08e8b4482efc716034bc971c3601b4a15a801b3a9d3a7cc8be2a9a", + "rules/sources/三命通会/219_卷八·六丙日己亥时断.md": "33997a7c0bccdc1d77550d40a43b89bab38729ae3f2e9fd69c9aba239113c877", + "rules/sources/三命通会/21_卷二·论遁月时.md": "82b90ef2db68cf95fbf05e736c1e8d7445fb3bbe7ae7e127a93e1689f667f860", + "rules/sources/三命通会/220_卷八·六丁日庚子时断.md": "254e76d49e8f34f6e50465f1d598d28cfd89109c9fa754e55af33555ad442dec", + "rules/sources/三命通会/221_卷八·六丁日辛丑时断.md": "0c6451e05b0276a41489c28edb34ddfe46b8003a1ae220d776b3203dadf6bd0a", + "rules/sources/三命通会/222_卷八·六丁日壬寅时断.md": "f328a04446ca57a4e6a20dc70856144572a2175bd48702e2293f125cca069d73", + "rules/sources/三命通会/223_卷八·六丁日癸卯时断.md": "b142a10ea14b0c723f1abf31c23b1f5ed59d88364115d3fb56490ade25df6f36", + "rules/sources/三命通会/224_卷八·六丁日甲辰时断.md": "9f3e5907a841250366dd74edb373e76dc6a8f13730e0ef361682491ce79aace7", + "rules/sources/三命通会/225_卷八·六丁日乙巳时断.md": "f713c5f25759d6c1ed3aac761b7ed95676051941dce622f7d16a05f979367c8d", + "rules/sources/三命通会/226_卷八·六丁日丙午时断.md": "7a59d4e08794c03b148986e6edec7abc5ea4fdbbe29d5330ab241e67ead0adc2", + "rules/sources/三命通会/227_卷八·六丁日丁未时断.md": "5748e009e8a5dd5c5273de48bc04a9f8d21fdc0b22404c250f75ebf29b0d72c3", + "rules/sources/三命通会/228_卷八·六丁日戊申时断.md": "a997891d702b6782600a8b16cffa3af73968bc23df3e84463b1f53f46299448e", + "rules/sources/三命通会/229_卷八·六丁日己酉时断.md": "ec63ea763d5b3110f892e70d0c7d559b1f72c98da3c512ee34f60b23a9b6bd37", + "rules/sources/三命通会/22_卷二·论年月日时.md": "fc55c3431499f5d1d0c7985abc0602c385f1ff45f2d58a11c15b463a8a4bc198", + "rules/sources/三命通会/230_卷八·六丁日庚戌时断.md": "3215de62bc288a94d318d287c54bc18ef48322c028816f3f94631c3338c6c6ef", + "rules/sources/三命通会/231_卷八·六丁日辛亥时断.md": "a4155a7035f03e9000d4f1603c11ed7bb07b36131bf44d04f5b67ab6908a3894", + "rules/sources/三命通会/232_卷八·六戊日壬子时断.md": "c116760db58f2f3702da9bd8aad5649a55550270a051f581a78e2033b7ba3136", + "rules/sources/三命通会/233_卷八·六戊日癸丑时断.md": "1e087e46ed773e497fa9101beb58fe6829c02be7d11700ea24a226b5313cf996", + "rules/sources/三命通会/234_卷八·六戊日甲寅时断.md": "ecaa5dbba6986d9a808456f2afb44e1933808d70878ca07caa6e0e9bd0e39715", + "rules/sources/三命通会/235_卷八·六戊日乙卯时断.md": "7cd337eadb5cb598a39d8817cdd1285b5491b19c3005899c1406262145b731ee", + "rules/sources/三命通会/236_卷八·六戊日丙辰时断.md": "922c8025f30a40f54e0a5c32fbba7de5ca660f0326f68b020ec0c80e3d9b58d9", + "rules/sources/三命通会/237_卷八·六戊日丁巳时断.md": "365f86f2cd9cdf6630282b854941e400686ce2c7ab1566fa20eda5a2de93b683", + "rules/sources/三命通会/238_卷八·六戊日戊午时断.md": "bcd0b8474e6df6426cd21a20cb7b572cf0cc711b6ca0e55ee523610e5cacb554", + "rules/sources/三命通会/239_卷八·六戊日己未时断.md": "5bc51fba309ee80242922d3d5b26320a5beab146f5776c7393934241f2f649a7", + "rules/sources/三命通会/23_卷二·论胎元.md": "3bdff1e138fc7c12d2ec5cc9e381fa3d77e0ab457de05cbdd92615fdbe81daf3", + "rules/sources/三命通会/240_卷八·六戊日庚申时断.md": "7b3051319118c8f734fa815c0c4ef2793dbbda7bba1061f7be9618977e4f4813", + "rules/sources/三命通会/241_卷八·六戊日辛酉时断.md": "eef8ce6f90e7e3061ff144858c48c4dec701c0e118e323ca30e638a13f6717ce", + "rules/sources/三命通会/242_卷八·六戊日壬戌时断.md": "ed32b507e74c374e96ca05d00537adebcdc8f2878c693115ad2af15a4e348f58", + "rules/sources/三命通会/243_卷八·六戊日癸亥时断.md": "79b46903af0ba453195e8a7a98148d4a6fcb8f940570d923fe8f1d47f623e02c", + "rules/sources/三命通会/244_卷九·六己日甲子时断.md": "f4bd4a696861d84236d8abff9f8ddbcce37ba3d14ec0eb3dded7d63d8bb9609f", + "rules/sources/三命通会/245_卷九·六己日乙丑时断.md": "895782a9df84f66adf231d4106fb498441522958dd39c5849d8b0c3e69a25045", + "rules/sources/三命通会/246_卷九·六己日丙寅时断.md": "a0d20dcf4ae9122745594892fc5f2f5c41ff7486bb9b5bf6a271b4e559bf8ee6", + "rules/sources/三命通会/247_卷九·六己日丁卯时断.md": "ed562c43421264f7ae6c58561e209982705afb5435ac40e0749cd5811d35a614", + "rules/sources/三命通会/248_卷九·六己日戊辰时断.md": "ce22c1d897086c4c75bc977e933368244540d7517dd7d272b093719af6080633", + "rules/sources/三命通会/249_卷九·六己日己巳时断.md": "b3147c59dd31d34ed37443dccc79c7c02645e6432b307955c88db8ca97714b60", + "rules/sources/三命通会/24_卷二·论坐命官.md": "792b53e58e5cb131eabdc3abd47b2fd81f287851d43c2b6685b9d3cc1163b42e", + "rules/sources/三命通会/250_卷九·六己日庚午时断.md": "c31db43c9e188d13bab7b713d7d136557c2799bcca82bc2a9973012d72047066", + "rules/sources/三命通会/251_卷九·六己日辛未时断.md": "a1d9c6ca96028d806f952b6b53476e81a6ac90e706746286a8e58dbbcf50d42f", + "rules/sources/三命通会/252_卷九·六己日壬申时断.md": "3d8fd249ae817dbb3b2183efcbcd0849d5d54c25e360b8eb1584bf2dcfe537e9", + "rules/sources/三命通会/253_卷九·六己日癸酉时断.md": "5b2c1a010022f43d54c80858026a7835ab7df9bf20fd5511559a7e221942aee8", + "rules/sources/三命通会/254_卷九·六己日甲戌时断.md": "64a6f1e40fb6d863b5d32ee918d4b3a971f31ed157bb1c4b16e4c4a8680df8a7", + "rules/sources/三命通会/255_卷九·六己日乙亥时断.md": "301399eef5e536a25e7b03e4ba72461c11a924fa6c7aef7aef1f2febb8e034b0", + "rules/sources/三命通会/256_卷九·六庚日丙子时断.md": "ae2de1c5e35828ba7c148a16a0d9026e65dc06b742205e183f777a12750d7859", + "rules/sources/三命通会/257_卷九·六庚日丁丑时断.md": "0bef3c6331535be672ef2255cff94a5accf32b7ad48dfa05012e40995091c900", + "rules/sources/三命通会/258_卷九·六庚日戊寅时断.md": "2237f862258bbebcdc32d0043bdd7861a968700d7442ecbe64419258c0b8971b", + "rules/sources/三命通会/259_卷九·六庚日己卯时断.md": "d0ad3d2aee763a31ebc386c461f4a0557aec3d40045f44f07b1c1240822933ae", + "rules/sources/三命通会/25_卷二·论大运.md": "2f0a3fd7c9e1aac684c1c1d7835b4c61a31738331a071bbb1de599232520a498", + "rules/sources/三命通会/260_卷九·六庚日庚辰时断.md": "34f7e87780cec47ed1dc820dbc54297288e131bb55a80bf7246e025fb868aca0", + "rules/sources/三命通会/261_卷九·六庚日辛巳时断.md": "0920673aaa2b600e2c7d79037257d6456c2b60412d5b0b36b7e0caed63dc0b6f", + "rules/sources/三命通会/262_卷九·六庚日壬午时断.md": "98bd6eb3e5a998467c293756caa0d6e1b591d146e6e96e1aaa62a20e81de2094", + "rules/sources/三命通会/263_卷九·六庚日癸未时断.md": "eb6c1d2abcc5960b7745beb895ef137c8babdc4ecdfcf578a190798475da6091", + "rules/sources/三命通会/264_卷九·六庚日甲申时断.md": "df28f7b68d2d70846508f0d6e057bc434998977703cef12d00362606005bae42", + "rules/sources/三命通会/265_卷九·六庚日乙酉时断.md": "fefa9055bc657c625765771f68c385b0f10fbcad3ba0e88235e0452090d39018", + "rules/sources/三命通会/266_卷九·六庚日丙戌时断.md": "a980920118c74aec782eace5e2625a01ef114235a23e9d44f1003ae467d182a5", + "rules/sources/三命通会/267_卷九·六庚日丁亥时断.md": "6b3df0a4800ada73ff0fe00bdd1f4a8945b2c5c14ea24f16247312f351762e11", + "rules/sources/三命通会/268_卷九·六辛日戊子时断.md": "8cc629866f7836d628ed7decee9a8c3057783aea95eb5871812fd063a19242cf", + "rules/sources/三命通会/269_卷九·六辛日己丑时断.md": "3b3506ddd1780967ad1ff7cbee17504c40d5f988c398a179018a7e07b2352163", + "rules/sources/三命通会/26_卷二·论小运.md": "2d5ff4968de1f367efb1595424389eb4293885981c6fe827da49ee8e92ee10ad", + "rules/sources/三命通会/270_卷九·六辛日庚寅时断.md": "bd0c3cef5aeb17cc7a8d01ee34cfb530f5c5d27c6b5bcddd0035d48c226327a7", + "rules/sources/三命通会/271_卷九·六辛日辛卯时断.md": "1ecf986fbccb23326b5d09842763de5506a05dee9ebdfbb0820b3488176adbba", + "rules/sources/三命通会/272_卷九·六辛日壬辰时断.md": "acc21f0ee46680254d160bd87fc0903cbd2cd426c3ab64ba1a0ea2fa00d84946", + "rules/sources/三命通会/273_卷九·六辛日癸巳时断.md": "6e0dcd7b66d02492bda7c8a3513adfa3e39fdaa5083768b73b96c58989ff174e", + "rules/sources/三命通会/274_卷九·六辛日甲午时断.md": "0b87153f1a793f8b29d92842ece1c39ba755b8541b1e384c36efcfb8ef78e47f", + "rules/sources/三命通会/275_卷九·六辛日乙未时断.md": "1f1ea1eb25decd5418cfcd0cee4e731b7e035900e4df09ba28839e598c23a3f2", + "rules/sources/三命通会/276_卷九·六辛日丙申时断.md": "b1d6c7b40f3497e79e2d7a0300d18edde325484ae3ab2c8d6d54c362a05d68e7", + "rules/sources/三命通会/277_卷九·六辛日丁酉时断.md": "49a603f34f27e99c983bcb11aee6b2f3793d4b8eb1994d91ef16fe534a124a0b", + "rules/sources/三命通会/278_卷九·六辛日戊戌时断.md": "8ca70671133c5620b7c4e11bf37e3badd01a39c08faed4079daa1a2dbd769913", + "rules/sources/三命通会/279_卷九·六辛日己亥时断.md": "8e68d7c883098bf1fe554a16f7ac09e7d78bd38aa5b24df45c6309b9f231823b", + "rules/sources/三命通会/27_卷二·论太岁.md": "41eb5e5e50a6c6488d50fd3bcc4a4d7b525406209f436dced72110273e3b2302", + "rules/sources/三命通会/280_卷九·六壬日庚子时断.md": "52851d9a4def410b7a88b4167b2a0636ebb7b3c2fd63821a7d5eae14cdc48611", + "rules/sources/三命通会/281_卷九·六壬日辛丑时断.md": "7e95d3991b9d8e2ab745ff1bcfb01097891be3e7386acade1416ff69434e78cd", + "rules/sources/三命通会/282_卷九·六壬日壬寅时断.md": "5a7d65c97f622a992b21753046daa60d723b861ec51f77383e1272166b4ca807", + "rules/sources/三命通会/283_卷九·六壬日癸卯时断.md": "9a83476f9542d8662dc079cd145b04ffbbf7c2c82a7d8fd4866fbd9a2a55301b", + "rules/sources/三命通会/284_卷九·六壬日甲辰时断.md": "a0a2b4a244b978e3659123dca75565e6c5dd5112f1c4f7ae22b1c858f789847f", + "rules/sources/三命通会/285_卷九·六壬日乙巳时断.md": "9121f196470c6958aece53ffa1de99e0965c096b78bb4e1dde8a9d61b0f38e75", + "rules/sources/三命通会/286_卷九·六壬日丙午时断.md": "34b60d17d770fec936cfd2ced877af44b9a538b556f08bafc9b5261593956ef7", + "rules/sources/三命通会/287_卷九·六壬日丁未时断.md": "8b508e4e2eeadd25f2c2f4a6eb66482c6d6a0bf3f4e298077f3a24b4270cc018", + "rules/sources/三命通会/288_卷九·六壬日戊申时断.md": "ff917b6cee158c8d544fc3c074756783f99bf79168e9a99957f74cec0be61005", + "rules/sources/三命通会/289_卷九·六壬日己酉时断.md": "2fcf9773042331709d01656e708ebc638844b3c51ba20947fd89f4ddedb3878e", + "rules/sources/三命通会/28_卷二·总论岁运.md": "e8c8b03d9fdadfc0b9f1637098c89094b5b4d82fbfceaded8b7391feb35a9cdd", + "rules/sources/三命通会/290_卷九·六壬日庚戌时断.md": "a17760ed524032035af76b2b226ef4482157295aa712c407b7131f623a3fa4e8", + "rules/sources/三命通会/291_卷九·六壬日辛亥时断.md": "221b4d7f21b6f7391d670f509221ccdf9cb36d62817e95bd5adda4b91d7936be", + "rules/sources/三命通会/292_卷九·六癸日壬子时断.md": "0db0525f9b410313cfb4be21dc5ecf0a159d39482b22da536d81bd1d1b313fad", + "rules/sources/三命通会/293_卷九·六癸日癸丑时断.md": "a3cc5a5616a9526313951ab5c8f431de424cfef3db2964b1200b7a44951b1a0a", + "rules/sources/三命通会/294_卷九·六癸日甲寅时断.md": "e39ff5b1ab36babac700f9779e38904848661467684d75827c8d6edb3e984721", + "rules/sources/三命通会/295_卷九·六癸日乙卯时断.md": "3d4ebe9e63690cf87c8e14b1c56babe32f58dbff23631d56444a77d5f8f65593", + "rules/sources/三命通会/296_卷九·六癸日丙辰时断.md": "028e2b6d20355a830021077ccb2d60069e0aa36537a4d280b8f334ca40ef96ad", + "rules/sources/三命通会/297_卷九·六癸日丁巳时断.md": "4a479848bc308a2066acacfff290c61afa76043a35a1604196d2490f324cf110", + "rules/sources/三命通会/298_卷九·六癸日戊午时断.md": "1611fd3b5db36a9afd3061d7a7463ea20af8063ac2c16284b425c2be07ecbf0f", + "rules/sources/三命通会/299_卷九·六癸日己未时断.md": "b6e602b8795b4f28b2f6025a9bfaa8470b8f9bedf2a3f9c44252cad4672f8cff", + "rules/sources/三命通会/29_卷二·论十干合.md": "871ede02e98a86409e82c0457b765c4dd36f9f95994222e3fcdaed8b8157a673", + "rules/sources/三命通会/300_卷九·六癸日庚申时断.md": "ce44fa8ef8267eea6e0962298a663df8d58131fe3887a911455dc3d608110170", + "rules/sources/三命通会/301_卷九·六癸日辛酉时断.md": "e77959aa35fb009404772fb312d5c60960475ade10239a8591b51c2f88115036", + "rules/sources/三命通会/302_卷九·六癸日壬戌时断.md": "f3289e524b87ab021c75cdae9e7bbe67de1ef4509f40ee7f9dbbebc2fd2be649", + "rules/sources/三命通会/303_卷九·六癸日癸亥时断.md": "05bc18a438ace03b89897af5d5f4060357da33a6509125f09bcf88349e662a76", + "rules/sources/三命通会/304_卷十·看命口诀一.md": "a5854069069567b963c5614a51acf36ce5a4a3ef3a40d927948dd27ad26cb862", + "rules/sources/三命通会/305_卷十·看命口诀二.md": "d41897affbc7ee99f1667741a3a81225c2e67eb7a9afd59b72fbbaf8e775a3da", + "rules/sources/三命通会/306_卷十·看命口诀三.md": "7969c16fcb73e785159ddc97223925fd7d5e18fc018c1443295a8cd082b5ec61", + "rules/sources/三命通会/307_卷十·看命口诀四.md": "8867fe8c3b19c9095b92ef1c79d815e6c1df4f4ef0c86287424637adadca25df", + "rules/sources/三命通会/308_卷十·看命口诀五.md": "de42f0748b2af5276c311e4b2a2956ccdf19d12083795ca64f7b7129b5bc0203", + "rules/sources/三命通会/309_卷十·看命口诀六.md": "f5d1896fb4932154cb6ed91fbafef783602f592846b37ca9135b9bc2cb9bfe25", + "rules/sources/三命通会/30_卷二·论进交退伏.md": "2cccaf59115beca0024af14d6b12b3cb6fdb055b095da7c2574c9c1afe6d136e", + "rules/sources/三命通会/310_卷十·看命口诀七.md": "04b8733c9f7bf53a2d6798562199b2b0fb94090b142f3c00f974debb6634bebe", + "rules/sources/三命通会/311_卷十·看命口诀八.md": "ad9b7437fb622d5fc3a91984e9f7fa16f7193e00d328c908006315fc55747223", + "rules/sources/三命通会/312_卷十·看命口诀九.md": "044532a80ed433ae100b182259c70645b09627ba9bed678d94888254c656bc89", + "rules/sources/三命通会/313_卷十·看命口诀十.md": "4cbbffbd0a159d281bb00aa867aee9b99fa1142cfe7fbf3d5de7ed2d3cf0e42b", + "rules/sources/三命通会/314_卷十·看命口诀十一.md": "5a5d278c574c279774632bdb3ca33c0a01eab46bacf3cad74e8f825df7f1b53c", + "rules/sources/三命通会/315_卷十·看命口诀十二.md": "734c7aa0fa8c8f1952ab65eca4791e18bec284720b978c308c9bceaec427bdfc", + "rules/sources/三命通会/316_卷十·看命口诀十三.md": "c01691d357255d1379b2fa13e96354b09dc03473fafb2757b5c186b87d018411", + "rules/sources/三命通会/317_卷十·看命口诀十四.md": "44f6844a7e9d3ddcd6ea22adfe211d41fb934831395804c9e27701780e810d59", + "rules/sources/三命通会/318_卷十·巫咸撮要一.md": "41526c88fe4cdfb300896f1304fa4ba806ef502ed274a7948b090b9b600a02b5", + "rules/sources/三命通会/319_卷十·巫咸撮要二.md": "bccd52adac1b0ad57c97886e745ba6703a2ca433b1e86fc0cd23f5ac3599413c", + "rules/sources/三命通会/31_卷二·论十干化气.md": "8bfc28893fd026570a5cf03415c51ad1a5b855922819839482ee238e3eebe462", + "rules/sources/三命通会/320_卷十·巫咸撮要三.md": "d8620ace665a959cb9ebb907fc0515de635f691c4fbfa585c60cd2ee81f5fc99", + "rules/sources/三命通会/321_卷十·巫咸撮要四.md": "3333b7f61d0887bddf4eed824fcce62b5a6cf2b853dedb0dca97bd9481ad50ac", + "rules/sources/三命通会/322_卷十·巫咸撮要五.md": "25afd281b5cc48123fd02d2649c45df48853df32e5a48be161563af7250db560", + "rules/sources/三命通会/323_卷十·巫咸撮要六.md": "d3d2957958bb83fd42be47bb7e1c0c352c96f7e064abaf18ef9fba70ab9a05bb", + "rules/sources/三命通会/324_卷十·玉井奥诀一.md": "084fd14d1784b66e8562c03eedbd296f3d05e527736ab44b5763ddb2f6cccd3b", + "rules/sources/三命通会/325_卷十·玉井奥诀二.md": "761748eaa89687c264df464fce3170c2d37a450c48caea584897b890f40332da", + "rules/sources/三命通会/326_卷十·玉井奥诀三.md": "d6404987b8cc19c50f4dffe7218f7ae868a124a6ce58e5417b019021a4a4f5cb", + "rules/sources/三命通会/327_卷十·玉井奥诀四.md": "81128e4b39bba29ee5958561ab943c744a0833f708d6c41e34f12ec4f763e525", + "rules/sources/三命通会/328_卷十·玉井奥诀五.md": "690d8fc1cb68037cc952d5b3336ed2536a6fb7f8a48bebe988cf7b87dcc85e57", + "rules/sources/三命通会/329_卷十·玉井奥诀六.md": "c88cebf260ce3a6f02f7f6e7807e52d8c2ee97ac6b5ecdc61806cffb4cd5efc8", + "rules/sources/三命通会/32_卷二·论支元六合.md": "c1e7ff7ac5cd2e4eb0aea6426058fee1d68d0c530d0cce292eef99f23dfc2bdb", + "rules/sources/三命通会/330_卷十·玉井奥诀七.md": "c23516d93b73dcf159d70557bc1824d669ae0228be721315469eedbd6f428fd8", + "rules/sources/三命通会/331_卷十·玉井奥诀八.md": "f1a61540cf81cfdc63d5aac0dc1bf9c06338755c1ef6cc80e2278d1fa798f500", + "rules/sources/三命通会/332_卷十·玉井奥诀九.md": "031695414795892fe282a5ecbebee18abea4b4634f4af4ea62a866fc3a080b75", + "rules/sources/三命通会/333_卷十·玉井奥诀十.md": "5ed3890464377fc20dbeb6cd01603bedb09ff98c1b8c9a0c52b9eab2f38749e8", + "rules/sources/三命通会/334_卷十·玉井奥诀十一.md": "27582ed692e94c6c6bcf7cb074afcc9409a48d108a3f7873a1e8f39eb4e040df", + "rules/sources/三命通会/335_卷十·玉井奥诀十二.md": "d48f6dd3beb2c09fdb96637f16ea6498d6789cba8a6c476c78a42bc2814c0c12", + "rules/sources/三命通会/336_卷十·玉井奥诀十三.md": "5f3cd08e886cea81d0f0d898ceff5da809fa048bb91ec39c5a579cf58a3481ad", + "rules/sources/三命通会/337_卷十·玉井奥诀十四.md": "a030a84495812b93c2de97cf3d0fe915a40ada67524ac394c1f1af85497c3c08", + "rules/sources/三命通会/338_卷十·玉井奥诀十五.md": "eedd7720311b4a716ad19dfa9bcb69e263ffcf10e1a75a1153b04c5a36fcb841", + "rules/sources/三命通会/339_卷十·玉井奥诀十六.md": "f5bf229e5545c845afb4dd0d66bbd28633ca5614330107ef6b0c1424aff80235", + "rules/sources/三命通会/33_卷二·论支元三合.md": "9641b5be2302644341aa40267eee8794594032376c9ccff72c1cde0184a5778c", + "rules/sources/三命通会/340_卷十·玉井奥诀十七.md": "8f6543bc76511484676ebc4c82389061d1733980576393201da5cfa8401c58c8", + "rules/sources/三命通会/341_卷十·玉井奥诀十八.md": "a2a8eb74f53e0d5ace4cd2eae024ba112decaa8d501c1aa9b6263f5577277994", + "rules/sources/三命通会/342_卷十·玉井奥诀十九.md": "293dfdc00b8bc7d25579ad46896484c84e4387723b3602d49b13fdbf7aa523b2", + "rules/sources/三命通会/343_卷十·玉井奥诀二十.md": "f4bd9ce34eaf044c80d27858c62c79f8b0ce66b0c90cf65aff5888dbc8107ba6", + "rules/sources/三命通会/344_卷十·玉井奥诀二十一.md": "f2f80185b203fb64c64e4fb6eaca7f6cf21141b4bf372c3b0a65b593eed214da", + "rules/sources/三命通会/345_卷十·玉井奥诀二十二.md": "0f01d6450faab4c5caec4038cd512773100b7957fd90834334b89c1cc3364f51", + "rules/sources/三命通会/346_卷十一·气象篇一.md": "7f773bb053edd33956f9118749ce8e61a1a8cc34bdb1c9654dfc0fc8885b5bd2", + "rules/sources/三命通会/347_卷十一·气象篇二.md": "ac82946d88bedbddc01b6f1c07da238e523b9705f42b0d8dcbb91a25fa1e43a2", + "rules/sources/三命通会/348_卷十一·气象篇三.md": "39839eda757b5a5bc74381ab6b2511d40badfbd3886c39abf3efa55ee7e18a69", + "rules/sources/三命通会/349_卷十一·气象篇四.md": "21cde0d59c7d1d19007cd7dbeb4d9b8b671bcbb002b170c51078fb945a4009b2", + "rules/sources/三命通会/34_卷二·论将星华盖.md": "2acbe52dca82b10a6f7a693f13bd869a0d372fdda538c886fe101cee6ef57699", + "rules/sources/三命通会/350_卷十一·六神篇.md": "f6a01fbdd5584d62c2a153cb4af80bb59ac015a7bbef6d90a8efa29931610982", + "rules/sources/三命通会/351_卷十一·憎爱赋.md": "426ed66c18bde2308675cef9e065b7cadc41c94499a5923c38e6edd80841e121", + "rules/sources/三命通会/352_卷十一·消息赋一.md": "320ec5be584129e8490744e0e79e028e8099983a172efc9954bc5e8f5e1a5e81", + "rules/sources/三命通会/353_卷十一·消息赋二.md": "11c79da7c9ed07f895bfeda24f98714dae08e178cd90fb5ce70d1392cdf801f5", + "rules/sources/三命通会/354_卷十一·消息赋三.md": "c90f6ed1b2c8936e97f8279fef579d46fd61714336ea9e5e77a5128fd996b994", + "rules/sources/三命通会/355_卷十一·消息赋四.md": "4344447a553e4585630629aca1cdaf7939e69828eb41bc08dbff8b4b749aa32e", + "rules/sources/三命通会/356_卷十一·消息赋五.md": "18beb3d0d39b1aedad78f2e7cbae54b95751d8ac161e3e694528326f88a7776b", + "rules/sources/三命通会/357_卷十一·消息赋六.md": "6998ad069f7c825bdde82d72570b4ca983a465e4ec604efb77ef53947937602d", + "rules/sources/三命通会/358_卷十一·消息赋八.md": "4ab7e3a048923b32d79dd29be9583fa8f336e30c59d141b5980890c361b3336e", + "rules/sources/三命通会/359_卷十一·通玄子撰集.md": "4c52c4b724e0272a822063934b62830b1fddf3c004b81e86b81010c1c685e377", + "rules/sources/三命通会/35_卷二·论咸池.md": "5dabed3f319409579d47bdde7711e4602a965e42cf93bea4eded011d694867bd", + "rules/sources/三命通会/360_卷十一·明通赋一.md": "df43c829084d651d7f979656d7d3aa869b8e8bc318225c4a296c17d986b12138", + "rules/sources/三命通会/361_卷十一·明通赋二.md": "a5b33c087c98e4824f18c7b7d3d2894236dd31638bda05ecaf31f3e29452b278", + "rules/sources/三命通会/362_卷十一·明通赋三.md": "e661e3da233ce2922ff219574adcb0fecbfa5e8c767000b0e97616c4bf466b53", + "rules/sources/三命通会/363_卷十一·明通赋四.md": "ab9b8d9b0fba9260ed793d2c66888d077b9a4b721c8b12cba22a60b964f80678", + "rules/sources/三命通会/364_卷十一·明通赋五.md": "fb2d2e1a1630a5ad3078be1d8dfe1f6fa7977d6abab53fb8e3eaddb85ae550db", + "rules/sources/三命通会/365_卷十一·喜忌篇.md": "8b58ef0a40e571d2463b3d3f3a0bb1ac418429a1efc2b398324be9c8345bdc9f", + "rules/sources/三命通会/366_卷十一·继善篇.md": "cac0d02c6d56de5ba7340954776662918b1ed8d79f8eb99c5b25ba0e059d05d6", + "rules/sources/三命通会/367_卷十二·元理赋.md": "1a254d671d9cc857602cb2d73ab7bd73a844a67971805e4aaf9dcd2e6916f27f", + "rules/sources/三命通会/368_卷十二·真宝赋.md": "0ce44a28d1e470b8d9c4a87cc69cc87c872dacbf453b904d8102fdcafd02735a", + "rules/sources/三命通会/369_卷十二·金声玉振赋.md": "63bb41c346f713b0b12f0032f0e063bd0a5c5894d36e6e4726242a2fe4beed30", + "rules/sources/三命通会/36_卷二·论六害.md": "65e6afc7b244ed9b86549e93d75a4f06e1d63e3e980b3783c420ab12c8ce1477", + "rules/sources/三命通会/370_卷十二·金鼎神秘赋.md": "0dd4993d2ad9d687ac832310df687be03c9750a2f21ce2e39d3f319ebab966d0", + "rules/sources/三命通会/371_卷十二·络绎赋.md": "e5c21cab2fdee6fa1179d159a9ac7788fdba8be5f452384f2aa62fe9794df797", + "rules/sources/三命通会/372_卷十二·金玉赋.md": "181160b7b806c95c3241c8e9a33790dfa359985a2c95e16d9d8b5bb2fddbd707", + "rules/sources/三命通会/373_卷十二·心镜五七赋.md": "1d8c6eff1a62400743cea1d543f60bad3643476a9ee6f13297417198cfc6ea22", + "rules/sources/三命通会/374_卷十二·造微论.md": "0af8a886e2d61595d627d4b734f625fe144dec99319651509c564577606de7b8", + "rules/sources/三命通会/375_卷十二·人鉴论.md": "842f6d88fdba256d22bed5ac9440a3f5e31f1c9966e30137d536923dc49b8a27", + "rules/sources/三命通会/376_卷十二·元妙论.md": "3cb6894fa34c18f4877187fb22bac1ac9a79b59ff6558c836c26cdb64bc7b90a", + "rules/sources/三命通会/377_卷十二·精微论.md": "5f1c361c65229ecdf1503117324982c9c386d47a3f93d62b91cf282e6e12f4e9", + "rules/sources/三命通会/378_卷十二·惊神论.md": "2f1b019395f9f960f5101dd9f9af473f78a4de1c079af47b81c33669f412eb4a", + "rules/sources/三命通会/379_卷十二·明津先生骨髓歌.md": "7e87bee72a1ceebe5b436bc82475bf6b1cd29db52963d1c16e1542ad4311d8d7", + "rules/sources/三命通会/37_卷二·论三刑.md": "1002ef7453f18b113eeca5cdf91d3d21a2a3daf6784ca143b2f7f22ea4db0e77", + "rules/sources/三命通会/380_卷十二·搜髓歌.md": "61fc4cb173f3bdd6878cfb82d1c5024c31914a35b246d3852ddb7a8bd311d241", + "rules/sources/三命通会/381_卷十二·四言独步.md": "3a832d8efeadfe338570c9a107d397ea3e77d2dbb04f7f1bd97541e857b37833", + "rules/sources/三命通会/382_卷十二·五言独步.md": "b0d92f93372bfcb1b9586b41391681cc8dd4e56dfaf8375bbd9b34d5a01972f5", + "rules/sources/三命通会/38_卷二·论冲击.md": "b88477b2bb1066900293eca338ac58044f5191d2facdee6445b7d5db53d0b89a", + "rules/sources/三命通会/39_卷三·论十干禄.md": "b6085f57f7398603d24941b50f57ae555b7ce716266afa3171bf51e6775d7b5d", + "rules/sources/三命通会/40_卷三·论金舆.md": "4a5040cc65edb73e56105998b0af8fcfea01b47c5832e6f37abe3dc2d08c8b72", + "rules/sources/三命通会/41_卷三·论驿马.md": "c4fbda90c3a43134ebde1d1acedc57747b90916924686d3d065ab1d150fe0d80", + "rules/sources/三命通会/42_卷三·总论禄马.md": "8d8bb59fd1700b0afcf0de4322379786f89e905c6ffd750159c2b8c861701642", + "rules/sources/三命通会/43_卷三·论天乙贵人.md": "dc662dff6c3bc0de774c4dbad3f657d16198f592a33d6c0f9250355279928606", + "rules/sources/三命通会/44_卷三·论三奇.md": "de52cf99b456a7ee10d26fed3dcac6be0a3df57262696344a99d9e365763c1aa", + "rules/sources/三命通会/45_卷三·论天月德.md": "29445becfab472258775c23add67961a6136932677d359665d8a1b8217e25da0", + "rules/sources/三命通会/46_卷三·论太极贵.md": "f1323840dd9989f029df9ea5115d82393da85fa0d2fc93330adf9aa48b63dce5", + "rules/sources/三命通会/47_卷三·论学堂词馆.md": "e5951d38b3be568a829b6506121acd297ea6ae5de3299df7cc77a77ffbeca991", + "rules/sources/三命通会/48_卷三·论正印.md": "fbb95302000a48543835500ccfd50382aabc755683b57aca18365f7dbfb261e4", + "rules/sources/三命通会/49_卷三·论德秀.md": "8c9b3360fbf62f5d71d6d2eec112fb9515fe9a2fa25b657423626ff903674be7", + "rules/sources/三命通会/50_卷三·论劫煞亡神.md": "ebda3320480488b79817f09ef01b9b88ec9910f91605c2089a276b73436dd2a7", + "rules/sources/三命通会/51_卷三·论羊刃.md": "f6fc9eca6631e722abee02b8940eca21d51c5a70c35bb73d6a9b40533190e378", + "rules/sources/三命通会/52_卷三·论空亡.md": "a9ba1c7a86f9420323f067039adc0549d90215880d744d00d3150dc4fbb791a6", + "rules/sources/三命通会/53_卷三·论元辰.md": "444584a113a1455e548d4067905a27938ce4945492925c3430e3c69f710ad9bc", + "rules/sources/三命通会/54_卷三·论暗金的煞.md": "ff8c11fbca751d636601ea877df13b609f3a3f6cadeacbf4e50a94791c991280", + "rules/sources/三命通会/55_卷三·论灾煞.md": "a1cb7c64e85b12d2495b2b094166f1a4d1a3e2c0318817f861fa1f9f2a5a043b", + "rules/sources/三命通会/56_卷三·论六厄.md": "9b6a9469e66c4332692729f895109270be88849827ea9716eca663e0900f47b4", + "rules/sources/三命通会/57_卷三·论勾绞.md": "bf7033f8818e6fcf97a36b30e362cbdf02c583ec214d38960be28424660b80f6", + "rules/sources/三命通会/58_卷三·论孤辰寡宿.md": "02f9239af9500041e1bb5b2baf599175a21369ad7cf431435471121eaf02a636", + "rules/sources/三命通会/59_卷三·论天罗地网.md": "aa6be9c69423b315200a4d4660e8b912b73c6a7872843eabe111f0f8b6620d72", + "rules/sources/三命通会/60_卷三·论十恶大败.md": "034e72bc1bdc57c4259fd8db461a7f042d2435ca6565e1524e60b50ea52bae1c", + "rules/sources/三命通会/61_卷三·总论诸神煞.md": "dab1df4fc95675c9c4e6351a7e47e1e3a998d868010034a81dce93cda8acbb6b", + "rules/sources/三命通会/62_卷四·论十干坐支兼得月时及行运吉凶.md": "fa8ae1234dd2f2230ac5081e8fa9de43077939d9db267c8c88a2de033159149e", + "rules/sources/三命通会/63_卷四·论十二月支得日干吉凶.md": "8e27c2b1bf91c6cbb55b8a5f63e674919b9821bd77d52e762c3642c9d1bf5480", + "rules/sources/三命通会/64_卷四·论五行时地分野吉凶.md": "ee989faf41ef1eb9a9741e333c83f5511404559159fba12b6f855f8127fa916a", + "rules/sources/三命通会/65_卷四·论木.md": "75465c0bf8161f85b7f40f91497922a56a29a838363818b022beca1c0ef4de14", + "rules/sources/三命通会/66_卷四·论火.md": "f609f308f242b8a585ffe76cd9c7a6ce81ea0baafb12a03c2f4e1f53d2136efd", + "rules/sources/三命通会/67_卷四·论土.md": "fc55b7834f92bd7cdcc18afcae48ecba39c92e3955e7e28847317e509f61c309", + "rules/sources/三命通会/68_卷四·论金.md": "48957aa897185defa1c6c212801a6c99b474a763c2e568874168a0403c8dc6d6", + "rules/sources/三命通会/69_卷四·论水.md": "0b0f6e2049ce5c65270b53d5f11c81e5dfa95bacb5c063cddf2ff4a5fd2c29ce", + "rules/sources/三命通会/70_卷五·论古人立印食官财名义.md": "50e99280ca9330a62effbdc5e58ca600d5ce2e0e7efa2d71302d12f1d67d87ad", + "rules/sources/三命通会/71_卷五·论正官.md": "c87dd904d7bbbd0ed0a8d1728d7bd04bd83dfb512e69808863a33641de6c0dd0", + "rules/sources/三命通会/72_卷五·天福贵人.md": "ff8ad4ec0c30f4317f2d9d40d76fdf99e2cfb75e6a1220ad628a90a36ed4f0a0", + "rules/sources/三命通会/73_卷五·天元作禄.md": "8d9866e9ead042e206034b50a6f617b3c1ab79a63fe11d917219e79ecce73683", + "rules/sources/三命通会/74_卷五·岁德正官.md": "7cda91ab2f547e7370e698bb3620e2917f29d639cb0fdcf0dea04cf377a5ead6", + "rules/sources/三命通会/75_卷五·时上正官.md": "bb2ea0fb953f26673f9d5eff34ff7a19a174a8289e73ecd26c3a4e89b58d524c", + "rules/sources/三命通会/76_卷五·官印禄库.md": "ee91af23ce50a1f239997d840cedfac5f949cab92a387e24cf0e4f8bd3977c2b", + "rules/sources/三命通会/77_卷五·相刑遇贵.md": "67edd84f3ed0e7f4205f64ecf3333262f4703369d17e82e18c02b29dd03ca6bf", + "rules/sources/三命通会/78_卷五·三合遇贵.md": "f293985c60e9f4c34d4b4a43cb295291eac030ac83f3ac43ae4f380f9095c79c", + "rules/sources/三命通会/79_卷五·金木间隔.md": "25dac5b26cbbd5d7cbb5ce11fd572a7fc69d6b1aefe1d16b4ad2f001a474b040", + "rules/sources/三命通会/80_卷五·水火既济.md": "78383d202fb722b70946c87a17c341a784f149febbff629e046775ef85c3f400", + "rules/sources/三命通会/81_卷五·金火相成.md": "856162eb4627ff1003d57ff05f40cdb9339be63b8c56577f0e3aa3c5170d8944", + "rules/sources/三命通会/82_卷五·天元坐煞.md": "6661160094f3118f2f69570cf178902e6867223ae89f44244e7ab2429c5a2e79", + "rules/sources/三命通会/83_卷五·时上一位贵.md": "f1c3b078edadbd490e86989dd561f1f96fa6d8c5babc108d2eb4663140ea9060", + "rules/sources/三命通会/84_卷五·年上七煞.md": "16cf7a48d951b1fe5c7175645ee57d02abd23b3cf4db6a382e46b888325a72a4", + "rules/sources/三命通会/85_卷五·官煞混杂.md": "fba35368d2b04ec1352179c132385f0347d224e0c2dde1700f7c555257caa315", + "rules/sources/三命通会/86_卷五·专禄要制.md": "37eea539d5bf60b2a67d6b0a652062196c5828ff13c8f4aa87dae8e4a41c3b64", + "rules/sources/三命通会/87_卷五·弃命从煞.md": "2d16d729d855a0602798bf57bc718fea0d604325e9653c7e5f3763db7e89d04a", + "rules/sources/三命通会/88_卷五·官煞去留杂论.md": "fd4b9dfa470071daf94e8d5b2e1cb75eeabd5b143c37bb53439ac5bbb3022918", + "rules/sources/三命通会/89_卷六·壬骑龙背.md": "d36ba24c617a9fc7c8f69bd0256ede18c8f2341a740021e837e9fcdb8b270bdb", + "rules/sources/三命通会/90_卷六·子遥巳禄.md": "5320ab8806f5a9f68fa6ab01f7a69317537e6be17396fbac6e92ae469887af03", + "rules/sources/三命通会/91_卷六·丑遥巳禄.md": "e70f9f435b9ea72185871f17261a4e977ee80fa6b51656fdd2ed0fb4dfedf689", + "rules/sources/三命通会/92_卷六·冲合禄马.md": "459191d48995fd04272ee6912c7b4144d5ac680f248c786418269eb384fc0020", + "rules/sources/三命通会/93_卷六·破官.md": "f3159a3e75356ed9f3c344d251e3dcec158231ccdc5b9dec3b12dec6ecdd978c", + "rules/sources/三命通会/94_卷六·飞财.md": "c5b8c0ed7625c503b592e5bcc02fb4f2e0a7b68ac94fd3b67559a4421970c0d5", + "rules/sources/三命通会/95_卷六·破财.md": "7929cff276d6a50e51380caab46fd7a7ab15264b1d927008b5fa087638c4796a", + "rules/sources/三命通会/96_卷六·虎午奔巳.md": "ee93046e9708acbd80d2c6965cd699066adbac9a8aa47dc12204b9b10c60c0b8", + "rules/sources/三命通会/97_卷六·羊击猪蛇.md": "ffdc2aa67092c403017abb65306faba18d5f9ec040d96afa6b00dbec2198101f", + "rules/sources/三命通会/98_卷六·六阴朝阳.md": "b82b6d409b62acfae7fc729512717ab0426ccc014e50142ded6abfecfa71d410", + "rules/sources/三命通会/99_卷六·六乙鼠贵.md": "26cbf7dab8b5028f300b42ac202f7fc2558d0b14315d395bb2fd8bd259bfcc00", + "rules/sources/三命通会/_index.md": "1754cea108ff7f3944e4e1166bee00c5dd64b72a2041a3de703069b5415c1858", + "rules/sources/命理探源/00_卷一本原.md": "8884863533e1a4e841c428bdc8cd8a07f0375cd40b65efff13fc2ebc7f24748d", + "rules/sources/命理探源/01_卷二起例.md": "0e219e9bf38c60c1b233e50dd29baf15a68f860d53b1878499949d51a34c5b85", + "rules/sources/命理探源/02_卷三强弱.md": "c43ff370db71c5dd4005d58cd5163b1303e6d4dcdee23e1e444dc2e2d392233e", + "rules/sources/命理探源/03_卷四宜忌.md": "e799f8eb4ac18aef4ab094132eb669bcdba3a3f910ce642b6471d8dc4d8646ab", + "rules/sources/命理探源/04_卷五化合刑冲.md": "358c71127860d08fbbbf5e1e1e8ba060d9b863523562fa09c256f46eb478d31d", + "rules/sources/命理探源/05_卷六先贤名论.md": "722f9e4a9df791c22f8fc0a719f28cf70b4d7d45fda41c6738982e29c9babd5e", + "rules/sources/命理探源/06_卷七润德堂藏稿--为推命范例.md": "25059100312f8991c1ce924d32754aa63b6017088dc9dd503540ce699a85e46f", + "rules/sources/命理探源/07_卷八星家十要.md": "4c09b9b282e2eac7377930934f33d6a8ce000071f552aad5bec73f2e9d55b316", + "rules/sources/命理探源/08_跋.md": "be6f2668c97b26046bb0de691b49beca4df0be95087ff6b581e291c6221b4663", + "rules/sources/命理探源/_index.md": "0c76d0cf71ac71c63682e457a14b3177891be7a862fb1b84d5f2ae9218b6508f", + "rules/sources/子平真诠/00_序.md": "8edb00890e79aa7dc4410d2bf7ee402854c84bfcc789fc0cd7d3623a433f7dd8", + "rules/sources/子平真诠/01_凡例.md": "be4c915855c9bb903dc054ad80dceea078baada8b8d0de1d5080ba04e1aee78a", + "rules/sources/子平真诠/02_论十干十二支.md": "891c8df8099364d849d1f553344c02991b7f3d366d814a1376f18c8fc344d723", + "rules/sources/子平真诠/03_论阴阳生克.md": "58fe62c25eea8c8c3bf3901ccba490d5cc2d448ae466a9367c03ec04a7cba2b4", + "rules/sources/子平真诠/04_论阴阳生死.md": "58d0de43d855c052af98626cd877eef55ec252adc0048616cc4402c79cddee5c", + "rules/sources/子平真诠/05_论十干配合性情.md": "f0c6ff0a2cf3118a6ac7fc1d5574f4f3fb9dfec29da3f3d570098fbb4a45f584", + "rules/sources/子平真诠/06_论十干合而不合.md": "0ad5cf89081ef718b2358e8488900889e6671bffc536d7985ad85b44ad237173", + "rules/sources/子平真诠/07_论十干得时不旺失时不弱.md": "1530181f10f961d60fff624f2a54823f57074ad6c477c3872c70512a8bddae58", + "rules/sources/子平真诠/08_论刑冲会合解法.md": "9814329665bde05cf16889585af9b586de90a214d64fa525c6fb88138b9da68f", + "rules/sources/子平真诠/09_论用神.md": "decb56df148ed83435cea8e8bdea01eac723b54d1c34f17c888e90deb020f89d", + "rules/sources/子平真诠/10_论用神成败救应.md": "403c8a9ca75caf8896636d23182ee6fd8c7907e934f915d06ac307acb485c79e", + "rules/sources/子平真诠/11_论用神变化.md": "78a0780cba141fbff595a6b9a7a351143ba2d3e0038ca12a34e208af2a43b627", + "rules/sources/子平真诠/12_论用神纯杂.md": "1e62594fb6b37c7574b0ce64ee5485ae9731a43eb7f6a5cf782d4e4a089b0e82", + "rules/sources/子平真诠/13_论用神格局高低.md": "f52bec2bcf30d2554b33794240e0f16516367161af4140d792675dbdeb8cf505", + "rules/sources/子平真诠/14_论用神因成得败因败得成.md": "cae59ff21022f9d6832c4b4bd08139c038d5159b939065dbedbc9019db57ed92", + "rules/sources/子平真诠/15_论用神配气候得失.md": "0fb5a651042e79fabfe106ec27757902e8b5c759541fc922639f9d4ebc061d23", + "rules/sources/子平真诠/16_论相神紧要.md": "7b179a1e9c6c7632d09b8388de4280810d8bb1de0046d732b4b44bb0a9d65771", + "rules/sources/子平真诠/17_论杂气如何取用.md": "bbc894577411952d3820b92a633d400b6c83dd26bee3aba973ba74b65822306f", + "rules/sources/子平真诠/18_论墓库刑冲之说.md": "d2bcbee12363e1213d29ff38627f290b4ebd1c6ae36622684088ffbe4220dcf8", + "rules/sources/子平真诠/19_论四吉神能破格.md": "98ce6d11be6edc9d9de8d2096568344e1936c2e4803203a59437d4cb9e95cf94", + "rules/sources/子平真诠/20_论四凶神能成格.md": "979c834193da066df82f782b66062831d3c463a1136ff47537c36d762c753724", + "rules/sources/子平真诠/21_论生克先后分吉凶.md": "55443d8ba78dd5ec41c50a1703888fc58a48de6605cbdfacd2b0dc6d4c9c306a", + "rules/sources/子平真诠/22_论星辰无关格局.md": "9a1137b274bbc7623cace20aefaad83ecfd7a15e35e10c1c67d04e4c9f032386", + "rules/sources/子平真诠/23_论外格用舍.md": "af7f41485d6ad36a360b61439c71d8f81f8dd6f213565c2ad33b92fb6f4ee0c9", + "rules/sources/子平真诠/24_论宫分用神配六亲.md": "e15f49bce84573d2dc1b33a5cc2e3367f231cb84d532a33ab6fc03c4518dff13", + "rules/sources/子平真诠/25_论妻子.md": "13cf04f3c88a3f8c990f6442599d0fa2bf85c94301ad6372c6a8fc01437ddd73", + "rules/sources/子平真诠/26_论行运.md": "339f3ddb5ae07140bcb837f0c24c4ddf20d5e4a07039929c095c416bde80f24a", + "rules/sources/子平真诠/27_论行运成格变格.md": "cdf99e19b66a6bd96d47106bfa9d9cf9754ef19562ad132c571d7dd076203976", + "rules/sources/子平真诠/28_论喜忌干支有别.md": "59746ebdfa3b94940ddba591a67623ddd5021e8e8e40d2827da3057ebf90abd0", + "rules/sources/子平真诠/29_论支中喜忌逢运透清.md": "ab0dc39999ddd6483da0cccdca86e658e4efbe2f0504d11843540c20b3a76c82", + "rules/sources/子平真诠/30_论时说拘泥格局.md": "caa1c2508868b58d343fb5165d198f67c79c1d9682a677074c9943502bdaa21f", + "rules/sources/子平真诠/31_论时说以讹传讹.md": "e8e88edbff2d27e4cfd4b0f79ce3acc9b7ee2fdb5060009c571aa674be53e582", + "rules/sources/子平真诠/32_论正官.md": "98eb70ce6acc4bdc749f5f2703e082321cfd8cc98b7a5aa7ce94f3444a5b6f18", + "rules/sources/子平真诠/33_论正官取运.md": "a51dac7bd9aecd2c7b5282e7375764fd21acf2a5201337bad933ee913fac7acd", + "rules/sources/子平真诠/34_论财.md": "754b8ddfc38e98709fede7f00e997dd89ed879bf70b1d58426f4b818859c20d0", + "rules/sources/子平真诠/35_论财取运.md": "60b5523b3aca43d711d3633e20a2f77a3678e35ad54b7eab5345c9257cc9a5c7", + "rules/sources/子平真诠/36_论印绶.md": "1daf781511128186fbefc86e55c4adb976b2ac9de366ddcdf7ddf1b51e7d650d", + "rules/sources/子平真诠/37_论印绶取运.md": "2bd9513e11ea55e56b8c1b5a5d6af2cd2dd0499ec3f4f9246ceabe26050faf38", + "rules/sources/子平真诠/38_论食神.md": "a77bbe5f3c08c3c5ca2c2c600048d1c7d958126432c6e06838bbc8007636b4ba", + "rules/sources/子平真诠/39_论食神取运.md": "5ae4d92ea87aa60e417b23be83c20cdae7ca83a371a139ca1e71bc35a56d5bd0", + "rules/sources/子平真诠/40_论偏官.md": "ccd2e61f4c5274c06447298ec07f72abd29eaac0419ed5f9aaa34253e06519ed", + "rules/sources/子平真诠/41_论偏官取运.md": "04bf981fa35e3d6452e83815e1a681f265755657261ace108116c9bebe4779b1", + "rules/sources/子平真诠/42_论伤官.md": "1ca987b205e415659223458615e5ce0d7408fb04e2ea6cb7bf8c998ac7797964", + "rules/sources/子平真诠/43_论伤官取运.md": "c1f2ff5574391b21fbf9e4279d7069afd0edefe72027188e2b4c83df73e8059d", + "rules/sources/子平真诠/44_论阳刃.md": "b588e4f3e0ef588aa954455e77bf75b05d0ab96783da2c31bd3b2ddbefbb3e43", + "rules/sources/子平真诠/45_论阳刃取运.md": "ed3391b5d326ba4729a215c1f92591d5e6845ee5337f89cf02186cd7727472ba", + "rules/sources/子平真诠/46_论建禄月劫.md": "5f46bc0558058db50ebf26f64fe446a84cf44eb46c7bb8c8f71370f1bdd8b0fa", + "rules/sources/子平真诠/47_论建禄月劫取运.md": "c7e465ed460b8aaa390c33a07f9947fcdafcca9d32f277ee88eb739196cf64c9", + "rules/sources/子平真诠/48_论杂格.md": "2701f481b02242361628f0c552882b582bd302e87dadd021525578dd7bbef579", + "rules/sources/子平真诠/49_论杂格取运.md": "ef860e668b32ca210e8379c49bc632cc52713d3cdbcc0ef6232fd9d9f4d6150e", + "rules/sources/子平真诠/_index.md": "50085bf830898f0d834ee69b678d7cd73f7fde9cb5979be1bd92dfe2b2491f3d", + "rules/sources/滴天髓阐微/00_序·序.md": "5cd1063aea18a28907db290a30c17d14d18753df59a3633c46ec7780e9335f71", + "rules/sources/滴天髓阐微/01_上篇·天道.md": "84315d5214a22c47e29f53dbd797cf65f098cf2033e676437c0f927fe278c631", + "rules/sources/滴天髓阐微/02_上篇·坤道.md": "65442b13647cc92b80b835d21b8b76e0929c74806829765ba8fb2ca5a90d9e5d", + "rules/sources/滴天髓阐微/03_上篇·人道.md": "9f27e3c7a196fb20b3b8e864d1f5116c6114ba1106a7e9f8cbf301df610d4b6e", + "rules/sources/滴天髓阐微/04_上篇·知命.md": "1ef7e2f2e64c3a3a51af91cb1a92098b29a79a72ed708345b5debe2bb798cc31", + "rules/sources/滴天髓阐微/05_上篇·理气.md": "df1d584526f7480ebd7147a218796293b28a86f879b5c6c7b0e6971d6e4d8727", + "rules/sources/滴天髓阐微/06_上篇·配合.md": "7d21d4558da0e4978d9f0c139863a8ce79dba1c39b7a856a753013134c98a132", + "rules/sources/滴天髓阐微/07_上篇·天干.md": "2b7e1d0dd5851a5a38056c8ef232430965fcc6baadeb7c8930ab12af17978979", + "rules/sources/滴天髓阐微/08_上篇·地支.md": "b86c6369eebee302273273433e858799cc0a504c43d771e2243b0049ae3eddd8", + "rules/sources/滴天髓阐微/09_上篇·干支总论.md": "088bee7d214095de039e23cb422e9042ae8727e055dcff9385c6e7fd5da1289a", + "rules/sources/滴天髓阐微/10_上篇·形象.md": "041840095018c847955e366656115350332b2195ff179d049b89f40522e6ba98", + "rules/sources/滴天髓阐微/11_上篇·方局.md": "caf08587ea6d86397f82492f7ddc64ac3c058a513622c08146b7be0521444df2", + "rules/sources/滴天髓阐微/12_上篇·八格.md": "5f56a4832d4e717330593dc3efd652b3d1268144938be7a7641743219b94527b", + "rules/sources/滴天髓阐微/13_上篇·体用.md": "551fd2a2fc0a6ef3033fb5e50a25899692d052769e9b4dec7269269588d3bdc8", + "rules/sources/滴天髓阐微/14_上篇·精神.md": "e605d373ae812524598e48efd55e129027974ae2e27a1fd44a17a106339d154f", + "rules/sources/滴天髓阐微/15_上篇·月令.md": "32b1d01f06e3e91726416dea6416646a8d04c8361d4f1456b0f2d3359575df5e", + "rules/sources/滴天髓阐微/16_上篇·生时.md": "310a6c58a2909a847b920c1321d568b9cdd20eb5dad60f6917f420d4ae1f75e1", + "rules/sources/滴天髓阐微/17_上篇·衰旺.md": "a09fe2460fc6c3d397ad4d1695026d1d2a736021a8486b8a07c87b327478df24", + "rules/sources/滴天髓阐微/18_上篇·中和.md": "8124a4bf1f166f100af41a214c388ac97733d5ca4743babd9c2fe02be94d54a2", + "rules/sources/滴天髓阐微/19_上篇·源流.md": "5f7a52aef09607a7ce564887a52099b20239432d4f80b965dc841b474826d5ca", + "rules/sources/滴天髓阐微/20_上篇·通关.md": "33a11ffc52168379e72050d3ef8edc5e9108f2fad37195d29b4982e93b426001", + "rules/sources/滴天髓阐微/21_上篇·官杀.md": "2d489bb7c3ff72e7a658ea1a0e7ea2a61f4821fcc5512c9ce8faa4ff74c0b05b", + "rules/sources/滴天髓阐微/22_上篇·伤官.md": "9d039859a841df59658823eedd23b37e1525510a0ee15a36d6f0f7a60cf6395c", + "rules/sources/滴天髓阐微/23_上篇·清气.md": "f1c458e2552f50fa646131227eb25679ec830efbf1e4f6d170b41b8a72a7d356", + "rules/sources/滴天髓阐微/24_上篇·浊气.md": "85972f7112b6939ca1ee0e00bec8653914a9ae8b6e011ae990ee93c2d4d3cf5e", + "rules/sources/滴天髓阐微/25_上篇·真神.md": "1053f60ab46c006399c25d80a4fb729f2f555749cd8dac0a8f88c56b92123da8", + "rules/sources/滴天髓阐微/26_上篇·假神.md": "76dc0f9405f28d68ad1defb5b8a368b6d7ef93da88425baf6987aff22f113096", + "rules/sources/滴天髓阐微/27_上篇·刚柔.md": "523a0c352db97d16feaee3848a3c83829f844df8c63ccc4c6d8707b13cb490fc", + "rules/sources/滴天髓阐微/28_上篇·顺逆.md": "5c4f62f2daea5288f61d6c4a9f08708d1b57f823db4817af306df25d96962d4c", + "rules/sources/滴天髓阐微/29_上篇·寒暖.md": "5c86e072a35a044aba66623171dc37848a629b204f3025ea9ce3716e242d0f6f", + "rules/sources/滴天髓阐微/30_上篇·燥湿.md": "df0efd0303c8e60831c95d93f25e5aa4fde52f86d859db6b92825c00390f6e4d", + "rules/sources/滴天髓阐微/31_上篇·隐显.md": "d274ae3bea040379511fc5d33ca2b8ec11ed3a4a8479195052659eb30605b64b", + "rules/sources/滴天髓阐微/32_上篇·众寡.md": "92e9a2d48c1396c521f04bfd94d5c2aa8fd1e97797adfe254bbd979393e01279", + "rules/sources/滴天髓阐微/33_上篇·震兑.md": "e269e0ebf4a529ba88eed4c473367902e96b074cce64f6f8c389f0774d110b31", + "rules/sources/滴天髓阐微/34_上篇·坎离.md": "60366735c11315afa2a271669d7c03839d8557f463a862d64de8532a1dfec305", + "rules/sources/滴天髓阐微/35_下篇·夫妻.md": "1e86f1c4dc83d511f1aa7961b629aad28a8bdec8684d843faaea4b77106165d1", + "rules/sources/滴天髓阐微/36_下篇·子女.md": "5efccf7ec37f60bae1cfde539f53fdf06bb3048bf14a80099f430bb6e4cb215d", + "rules/sources/滴天髓阐微/37_下篇·父母.md": "32aa8779470f66759c9b22f8c28874d25532c10a151294d76ce77cadac0e8895", + "rules/sources/滴天髓阐微/38_下篇·兄弟.md": "86513a70021cc85c9df2f642fc8c69c969e5e4fbb0dd04b2d8dcbc51a761a6b1", + "rules/sources/滴天髓阐微/39_下篇·何知.md": "26cabfa705c6e4ce2f6763b1b3a79f5edc2477a6f7ff5f38867aa222adceb7bd", + "rules/sources/滴天髓阐微/40_下篇·女命.md": "fba0fbbc869d6ba5cacbd2d47398f4cb8429601d66bbc5d9102b7f60cdff7eb7", + "rules/sources/滴天髓阐微/41_下篇·小儿.md": "37a5d7aa4c5e169158098f2d0eb184de3d0bf850a0df5e0ca5be27a5f1c85843", + "rules/sources/滴天髓阐微/42_下篇·才德.md": "3d0e617eb3e11735e698955af4072afaf60fbbcd24b1f4b6b46aca6705a38d9a", + "rules/sources/滴天髓阐微/43_下篇·奋郁.md": "ad4972be90c39a231101b3a7a965738f37d312e4f8d7ce0e2e6910e34db1fab2", + "rules/sources/滴天髓阐微/44_下篇·恩怨.md": "5013bffacde922b3cc8e54c4e3dc811fd052bbadab97751c291af50c438b1d7d", + "rules/sources/滴天髓阐微/45_下篇·闲神.md": "a6381c204d4b566255f186c80189337e2fc92e45397579460c25a360fac5269a", + "rules/sources/滴天髓阐微/46_下篇·从象.md": "935082f22bce9af23768afb6a63958cefbe73c411b8d8bff2ac63ec0a956a1aa", + "rules/sources/滴天髓阐微/47_下篇·化象.md": "5b1f8d9370a0f1fadbbe1319b88482d97a2897bf9ec0b4f45e7a520b6c3c4d2a", + "rules/sources/滴天髓阐微/48_下篇·假从.md": "17e99e0cf0b5f68e6a3d0ddb4a95f869933ffce8a53f0acbd78738f1318d5785", + "rules/sources/滴天髓阐微/49_下篇·假化.md": "3ce45d44380735a6beb903f8c4073c75179d6f9ed84b7db0e89fb30e57cbbb0a", + "rules/sources/滴天髓阐微/50_下篇·顺局.md": "ec281687a7a2b29c0c9caa5ff3be56cb826c5296c9c043c9e96ab752203f88d7", + "rules/sources/滴天髓阐微/51_下篇·反局.md": "c30d96b559a82c582046235abaf9c8ab257360aba0b0aa5fabb6c4bf6fe23f35", + "rules/sources/滴天髓阐微/52_下篇·战局.md": "fbc5191c5b7291472af0de6ea71b242804aaecffb0216f362ca4dc1cf137707f", + "rules/sources/滴天髓阐微/53_下篇·合局.md": "94ea503c35fd0cca4e4cc491d6173b00699420bd8b40dd1f1f1ed4d198254929", + "rules/sources/滴天髓阐微/54_下篇·君象.md": "c4b22b1310595cb242a854d37a2fd0e3015de78e2fcfccb94e716dae970e4b68", + "rules/sources/滴天髓阐微/55_下篇·臣象.md": "b5819b4ffb374aeac14d8e8b941385463f97876d6f893f52f331036a5027b354", + "rules/sources/滴天髓阐微/56_下篇·母象.md": "ae864ea6190b2bd3017997a20828d66d77766ceadec8b3322349e93d2df0de33", + "rules/sources/滴天髓阐微/57_下篇·子象.md": "26680a40e888263cd805232b497c1af8ee4c37ac8369d01fa2228afc930ea197", + "rules/sources/滴天髓阐微/58_下篇·性情.md": "19e20f700cecedde9b7a0ef635dabe4b5e7b8eb84edc6357d9853fc8858fe9c4", + "rules/sources/滴天髓阐微/59_下篇·疾病.md": "bfd653dfceaf9c1cc73380d3d99abe475c5f7c3cbbd233bebdb6bf383f37299c", + "rules/sources/滴天髓阐微/60_下篇·出身.md": "452615ede85cd3e63367ecb12a6679c0c8cde7c1b102ba6d2cb57f985af782db", + "rules/sources/滴天髓阐微/61_下篇·地位.md": "2dffaae75672085f380ac698799141cdfe823e9da3ae517bb2727c581e8e1c5a", + "rules/sources/滴天髓阐微/62_下篇·岁运.md": "6946b075d59a308328e3e7589dc9a19837cf4f0d2755ccbddb452c791b1e1f44", + "rules/sources/滴天髓阐微/63_下篇·贞元.md": "7de6b8bdbcef2d3e4dd0e2b6ffa992fa3cfad30229de3a7f334f37957d4b614e", + "rules/sources/滴天髓阐微/_index.md": "39b94ae588ff5a38b3f25c138b2fe930f182b6629bea0ca60ee5eea65b2c259d", + "rules/sources/穷通宝鉴/00_行总论.md": "6350e4900b02cff7d481426e7c18b96656f04e21cb6d353438b0067756f7555b", + "rules/sources/穷通宝鉴/01_论木.md": "987775ae397912d324b4a53a40a4548a1166e8c486784a1e187b973a0f451b8f", + "rules/sources/穷通宝鉴/02_论火.md": "271c7f9c69d0e5f79f89c8903c7f2a303cdebf1f9a3d65c47870540630a67297", + "rules/sources/穷通宝鉴/03_论土.md": "a6dae239b4101bef0fe41b5208e223636be92460a73478035e399f66afdecd5c", + "rules/sources/穷通宝鉴/04_论金.md": "46e35aaeb88b5e082cfa26344df3830c2b1ffbf9050740fe2ae96f1a2529bc6d", + "rules/sources/穷通宝鉴/05_论水.md": "35285f8c801a06ff7585829cab89cdb0fafff007ad15b8382a05b1e937906e66", + "rules/sources/穷通宝鉴/_index.md": "54c254abb2d796f604a19a127c700b218a792524dfa0f2ff18414580acb99901", + "rules/tests/README.md": "784f3e67c9332ddf41c1cff9fb1eebb210cf29c1467bf2d0b40f2d5ba1c297e9", + "rules/tests/golden/11_正官格.yaml": "1ac25e23d499319c64bebde32e65b5e0025984b254244e6fcb41e8b1c9535cbc", + "rules/tests/golden/12_财格.yaml": "55dbb814f0c22f77ace7814407573e82b511deefdef88893a775979f53e70db8", + "rules/tests/golden/13_印绶格.yaml": "61db3b076b884e7bd754910bb79f16ca467ccd027db25372f96dd2787a470ba4", + "rules/tests/golden/14_食神格.yaml": "f049d9b55b8b5c872e46c192982b9930fffc29e0b878ee02c0a1067b12725463", + "rules/tests/golden/15_偏官格.yaml": "b25cb871b794cf5f377898be111587fad071f8e44f08927cfbbc5277772c1964", + "rules/tests/golden/16_伤官格.yaml": "59402cf354b48b07fb55f58c40597dc8474d07afae0b8c17432a67b459e130f6", + "rules/tests/golden/17_阳刃格.yaml": "965d8eab944f360113a65c095fcfb383ac439558e98c9c2c8dcba8adcd709128", + "rules/tests/golden/18_建禄月劫格.yaml": "17b062c7cfcdeadf899a1ef7cabe7a40c9d1aa65494b13858ebc4dcca6b517c9", + "rules/tests/golden/19_杂格.yaml": "d8073d71d6b3241e1f7db4e382dca6619676496215018a4b5b96546f628fd994", + "rules/tests/golden/91_何知事类.yaml": "6dae10900536b78e3639daa380e6470771fc4a92aaa13f71f63c7cbd3244e57a", + "rules/tests/golden/93_性情.yaml": "acfefd4165008a145152fd11cddfbac92d4a5cd7b1abfd68e31ac73b1923dd48", + "rules/tests/golden/96_六亲.yaml": "dd45a0dd94ebb2a32e2e2d2613dc99fc6335183cc0832abdd69988a1d074ccdd", + "rules/tests/golden/97_女命.yaml": "dc229eae558be6592f392be4f71e72ec6650d64590c9bac3361febed9ead9b89", + "scripts/_license_gate.py": "4f3a24685c86abc6c66a158b441b89e2738bd14f5d63e8bdd41489654a29e837", + "scripts/_memory_store.py": "690e088a208ee5aeb9f66e6d4b5d4342f44bfc852bad51870cdfe397fbdf7660", + "scripts/astro/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "scripts/astro/day_boundary.py": "5dbd942f08a009400c2fbc60faa77c9d9a0c315d01e0cc6edf3d7b2efc09d2c3", + "scripts/astro/equation_of_time.py": "ee9331022b4ed35d407664e97b5ce9ce99167a06ce7cb8c9ffba5497a437da8e", + "scripts/astro/solar_time.py": "35b45edc365083a6ce90afe076176c6f3e798509e76d3f03819fd1845491b153", + "scripts/astro/timezone_resolve.py": "3a287a64bd50736ce91ac15876e88edeb98745eb6d0459cf18e7e6ee3c026aba", + "scripts/cast_chart.py": "bc08b53ab50f7d9e51b4d7e84deb3c2660040c025dd03c578f7fd51aeba6f315", + "scripts/chart/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "scripts/chart/luck.py": "d930f3f402cf814eaaa10fdcaa0a8be4a47411e6961dd0324ac38a8f898b4299", + "scripts/chart/model.py": "8279145da10901cfb1a7b4823762074169dfd554bbe8ce39ae15862334b001f6", + "scripts/chart/shensha.py": "1a9a59fa35ad5f2e2700d6b1a0155979dd7bf6f9fea4637356bfd41c5eae7e05", + "scripts/chart/tyme_adapter.py": "06a46f16efc3d745edb5f35bbdcfee1c78552a44235fc85de0af3eb6c163eaca", + "scripts/geo/__init__.py": "1211b885ec767b399472df572f970b07d6d028a5889af49fe50f6fc1a2a0cf7d", + "scripts/geo/cities.py": "9d393608c03a2ad5c7352939e70ea717dae5dd4bc833dfdd0e2f663940c61fb5", + "scripts/memory_lookup.py": "853c815a97b457ca20d5b4c03aff234dfb218a58a5511f6c1a55dc635de31c90", + "scripts/memory_save.py": "42638841cceb586783b8764eacff91a8518d8df7dfe99b3919b3caa5a432e0ec", + "scripts/query_shensha.py": "1d77205c8781676f3536bbeb2f36d397b825ff3065a4b968344fb95e5b8859dd", + "scripts/render/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "scripts/render/markdown.py": "4b2bcc3fc6581728d74bbaa357bf1db2e8aec1d3ec54c2c27ca645b6c5179977", + "scripts/self_update.py": "b80789b81be67e063100ddbf64763836263cc2068b4642b23170e56c47ad8bce", + "scripts/share_export.py": "21396143ad5cc2d244c7cc060a3ece25702594465689a9f12438dfe92de3296f", + "scripts/share_push.py": "8a367a3a4aa1bad27fbf3e9b241ebf69bf687a134045a06842e06047b58458ae", + "share/README.md": "42ebed92285752af93c7c7af5eb4b6e84ed836408d0cedb57e1b32c796746b26", + "share/config.json": "c91e88dd0f166c975e173d9d1d609113da6d986adb16711e242da12e87b07a29", + "tests/golden/history_tz.yaml": "3fb74e90c4f53abebaac0a5de8825ac3794fc0b5b41dc84121201e70cecade47", + "tests/golden/longitudes.yaml": "6fda1e6b632d29c135362c9273b931c4416c9f24c31b07e2a7baadc6e2077bc2", + "tests/golden/time_boundary.yaml": "637090a1c081b9b824fc0073d29dad073d29138c3b48082bdf41ce77f5af3b37", + "tests/test_day_boundary.py": "0e6c9ee32177a178f21a7812f83032abe4d1f585de48d07d21e2b432bdbcbd04", + "tests/test_e2e.py": "e324930fad582dc38618fa3599425bb48ec718beaf426efcb76531911c9464fa", + "tests/test_equation_of_time.py": "8a3a1baf7e61c42015405cc80fc0bdf4fd9bc732d440bc156f9c92c94e30f790", + "tests/test_license_gate.py": "ee44226b75620b3965ba52cc2a0cc5404fbff37822fd96a6faf2aed89d07d47e", + "tests/test_luck.py": "821f98bc19ab1e920353de58c6ffacac5d757c887c690a2d596f51c1485b21ea", + "tests/test_memory.py": "d3decfdc8d7c5bbfc4af5e3aed93bb3c53ab09071b682a0f4808614ac2cd3c6f", + "tests/test_self_update.py": "455461ba121814c8cdbe98bb2d31cd2dac630ef111eafb23118583c42f65a71c", + "tests/test_share.py": "399f20da22689d00e71eb78c76d60507060c29a7d68865e6b0e9f591d19be871", + "tests/test_shensha.py": "b8a20d264e18c79f1fe546281381b0d929543af44ec68dc890ef8b64efc625b0", + "tests/test_solar_time.py": "f072e5ea82fd0cb331c8a4fdc6dce08148cd9ac81ef9fe4506196fa68a42d1e4", + "tests/test_timezone.py": "3698878999d232bd431d6908c42fe8f4845c696da6085731abaf2f74017d722d", + "tests/test_version_sentinel.py": "9b2bc603a2e86aa33d904f1381ecd8ab41eb0e759803ec47122d662c10a7df83", + "vendor/VENDOR.md": "dbf017616ac2fda4fef56ce95e3610e77457108b7fa426136fd25764d78fa3c8", + "vendor/tyme4py.LICENSE": "e017c12d3476152144886c06e12b67277bb64e922b88c902b76ac02a84ea1c9d", + "vendor/tyme4py/__init__.py": "70fa797fbdc32818b25365bae430e943c12d5b68dfad2e21c616300a279fdbae", + "vendor/tyme4py/culture/__init__.py": "a3c580db378582e6ab0ca3746ddea29b524a127b50dbd5fa510dc614bba6cc54", + "vendor/tyme4py/culture/dog/__init__.py": "628a01283cac9f403c5a02c9648c28e6c1ba33c8c89338b05ae07f765f48e7e6", + "vendor/tyme4py/culture/fetus/__init__.py": "8ae8cefa98701125cda67245858a14469186a9784318cd7e3faed717332f3b6f", + "vendor/tyme4py/culture/nine/__init__.py": "e6c8e0d6474ac863b6d7d85ff577b1c6a7ea143530279e862be09ac1f393acba", + "vendor/tyme4py/culture/pengzu/__init__.py": "e8dc1a8aa3a1bbbf12e60d2dcedc7bb9cf5531bdcdd1e15ada2de27ac33c6377", + "vendor/tyme4py/culture/phenology/__init__.py": "74d7845b874627a063be479861994ad65855d9883476e70ef15cb9f582b5a096", + "vendor/tyme4py/culture/plumrain/__init__.py": "8f3df9e534a41a8141d0f2d6d63b6006122be91d6f0f82a9cf431d8f040684aa", + "vendor/tyme4py/culture/ren/__init__.py": "87e0b18985df285af27eb4e0d273064b6e572fff56e0d4ffe301ba7fab7354ac", + "vendor/tyme4py/culture/star/__init__.py": "fb26010e480c0d21d87ff17fb97db7c19b034a3aee761a6926f9b7e2cbbcfc8e", + "vendor/tyme4py/culture/star/nine.py": "cde1503bfbf04f72c530a6428190ac463dcd2e068607f6e80d3c6109fd48f7c2", + "vendor/tyme4py/culture/star/seven.py": "ea158958cfc94cf2d3599e2f655d26b21ac01919f173a231e1f3d29fee2c3004", + "vendor/tyme4py/culture/star/six.py": "3f20bce518e967096fd56835d4ffeb2f8754d32d7c8324f1dedd85f8d2287edf", + "vendor/tyme4py/culture/star/ten.py": "85315b07d79f1087713085beb15683f655bf159529e950f89c71a51f52039f15", + "vendor/tyme4py/culture/star/twelve.py": "03b8c00fb603b7bdbe626ae166c2daa96d9bd52e57aee903728f8dcbbb0518d7", + "vendor/tyme4py/culture/star/twentyeight.py": "1dd5ccb9d9f2c3d50ea59d7ddde2a1ef1013f4193a8bf0135350b17f28e9e807", + "vendor/tyme4py/eightchar/__init__.py": "18fb65e71e2144349b8688dccca2778bb95fbe589017cfe04ef3d7a1db46e95e", + "vendor/tyme4py/eightchar/provider/__init__.py": "2700f6b9e0fb1fe1acdb194d1804b55219e523e412f135d2e0236e40778ba04e", + "vendor/tyme4py/eightchar/provider/impl/__init__.py": "99c7ec64fe14f803de40326b628bed2aae4ab2a930b911377f95e6f9a12fa494", + "vendor/tyme4py/enums/__init__.py": "54f0aeaebeceb7df0bc97d22f920b28e7bafae2eb6877454d6bc426fc7da0cb2", + "vendor/tyme4py/event/__init__.py": "c07b89d5fbe411e232305d2fa2288905e028d18ac20ad5c17b4de5f4657e1420", + "vendor/tyme4py/festival/__init__.py": "5fcfc2e54f86f511f57fd15e1fe5d6d07a8ee2b818f0e382b2f3bf88118db778", + "vendor/tyme4py/hijri/__init__.py": "babb28e63239edb0370c42a1f1165a95a0f793ad5065ad1f726eae3ed84143c9", + "vendor/tyme4py/holiday/__init__.py": "78774af0c81276c48e9d63266ec6688b794209543134dce47932b9df9a257467", + "vendor/tyme4py/jd/__init__.py": "ef83854cee3b86260dc3b9741b49c3725697cdf99f21208c1b92ab808b98b2c7", + "vendor/tyme4py/lunar/__init__.py": "9dcaa6fd15e2740a0626e68dc18f96421223ed52039df5c384f4ec81703b96a6", + "vendor/tyme4py/rabbyung/__init__.py": "6133b6550306d3a22b170f15f790fdf7a15390d63ef4c9bf7292420af271171a", + "vendor/tyme4py/sixtycycle/__init__.py": "bb098f0e5b370aca2294f7dc29ea77ec01e2a4680861ecda83c1af1f19ae6221", + "vendor/tyme4py/solar/__init__.py": "1339df54b8c9aec4a18aab340102a7f90640b36b3675a8c7951c1472237b3371", + "vendor/tyme4py/unit/__init__.py": "019ce6396fe3424f782c4a7d14dbaf0510733c5be8dcd8862abf210da14cd517", + "vendor/tyme4py/util/__init__.py": "e8c943edaf11bcc5aa7510dfd3989b2482869aa76ded3d5393939f10b7260983", + "vendor/tzdata.LICENSE": "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4", + "vendor/tzdata/__init__.py": "71df42918330781675fb39c7a66c669968dc114c082c0d49b46e180a148c07b8", + "vendor/tzdata/zoneinfo/Africa/Abidjan": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Accra": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Addis_Ababa": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Africa/Algiers": "2f69d2e202cd16fba8f3da7762d07e9520d8636dbce12aa4187f6941023cbb07", + "vendor/tzdata/zoneinfo/Africa/Asmara": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Africa/Asmera": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Africa/Bamako": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Bangui": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/Banjul": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Bissau": "c1adeebdad76f5d2474428bbb58b74e2414e9f5fa8b0c4b669f32395e3bd983c", + "vendor/tzdata/zoneinfo/Africa/Blantyre": "910c97c091cd34ae7427c83226234ce7b4f2f425c5822d6669c24be62010a792", + "vendor/tzdata/zoneinfo/Africa/Brazzaville": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/Bujumbura": "910c97c091cd34ae7427c83226234ce7b4f2f425c5822d6669c24be62010a792", + "vendor/tzdata/zoneinfo/Africa/Cairo": "89cb9a36212fb82e933dcd9faa10efdfa969a29ec80c32063bbb4518c033d1be", + "vendor/tzdata/zoneinfo/Africa/Casablanca": "6b026cdcb00868a3dc1f24f7072a1ce3ac0c3ff83b3d847fee5f3cc01fa85f50", + "vendor/tzdata/zoneinfo/Africa/Ceuta": "a042202b9dda7f3d52631601fc3d2347df12b37839f35c9bf139cba693da61c6", + "vendor/tzdata/zoneinfo/Africa/Conakry": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Dakar": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Dar_es_Salaam": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Africa/Djibouti": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Africa/Douala": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/El_Aaiun": "aa0da6c9bbfb8b9526ac35f0ab9a3dd0035d69949a3eeee2b65a82a7319c51b5", + "vendor/tzdata/zoneinfo/Africa/Freetown": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Gaborone": "910c97c091cd34ae7427c83226234ce7b4f2f425c5822d6669c24be62010a792", + "vendor/tzdata/zoneinfo/Africa/Harare": "910c97c091cd34ae7427c83226234ce7b4f2f425c5822d6669c24be62010a792", + "vendor/tzdata/zoneinfo/Africa/Johannesburg": "d19aebe2435c4e84bf7ae65533d23a9d440f98162e5b4d69c73f783e02299ec8", + "vendor/tzdata/zoneinfo/Africa/Juba": "553a683003fe8c9e9c2ac0de355afb9772ca1a8283531194d9bd60aaf0cfcf7e", + "vendor/tzdata/zoneinfo/Africa/Kampala": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Africa/Khartoum": "351c0ec08838491e97b83d75937871073efbba8069cde8d7abbbf1b6ad97cacf", + "vendor/tzdata/zoneinfo/Africa/Kigali": "910c97c091cd34ae7427c83226234ce7b4f2f425c5822d6669c24be62010a792", + "vendor/tzdata/zoneinfo/Africa/Kinshasa": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/Lagos": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/Libreville": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/Lome": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Luanda": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/Lubumbashi": "910c97c091cd34ae7427c83226234ce7b4f2f425c5822d6669c24be62010a792", + "vendor/tzdata/zoneinfo/Africa/Lusaka": "910c97c091cd34ae7427c83226234ce7b4f2f425c5822d6669c24be62010a792", + "vendor/tzdata/zoneinfo/Africa/Malabo": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/Maputo": "910c97c091cd34ae7427c83226234ce7b4f2f425c5822d6669c24be62010a792", + "vendor/tzdata/zoneinfo/Africa/Maseru": "d19aebe2435c4e84bf7ae65533d23a9d440f98162e5b4d69c73f783e02299ec8", + "vendor/tzdata/zoneinfo/Africa/Mbabane": "d19aebe2435c4e84bf7ae65533d23a9d440f98162e5b4d69c73f783e02299ec8", + "vendor/tzdata/zoneinfo/Africa/Mogadishu": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Africa/Monrovia": "58cf8955faf9d36560cb5f057ba880276c8c80e59bc30ba621087fca9e7778a3", + "vendor/tzdata/zoneinfo/Africa/Nairobi": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Africa/Ndjamena": "4e58f865450d271121bc0a28ed324aa96bf527bb4461a7f514431ecfe2bdc448", + "vendor/tzdata/zoneinfo/Africa/Niamey": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/Nouakchott": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Ouagadougou": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Porto-Novo": "e5ef1288571cc56c5276ca966e1c8a675c6747726d758ecafe7effce6eca7be4", + "vendor/tzdata/zoneinfo/Africa/Sao_Tome": "3df8aeb5a930e41e71af5392835b85bd3d06c02ea354eaaac67c7af46109bb9d", + "vendor/tzdata/zoneinfo/Africa/Timbuktu": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Africa/Tripoli": "cf33012d9661e15438fc045ee64e0bfebb2ea8a3fb79d2af56df05ea4be3e453", + "vendor/tzdata/zoneinfo/Africa/Tunis": "ba8004111e3c449a8d786a1806e93921e62a8dcf2c1ef58bbcab2cb9509dd7c8", + "vendor/tzdata/zoneinfo/Africa/Windhoek": "8358cb464a3fda9786b144e0d3fc19c9c382e20c53007c1f57648ef48dca7423", + "vendor/tzdata/zoneinfo/Africa/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/America/Adak": "abfb1980e20d5f84ec5fd881c7580d77a5c6c019f30a383aaa97404212b489e0", + "vendor/tzdata/zoneinfo/America/Anchorage": "77ca0c22962f06998bce5e48d81cb865a14466c83ff5dc607eaa483344058bf6", + "vendor/tzdata/zoneinfo/America/Anguilla": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Antigua": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Araguaina": "4dac185f8955031ab40715068530f1e02f2fb414672ee5a2f2a2d5fe85c3894a", + "vendor/tzdata/zoneinfo/America/Argentina/Buenos_Aires": "20454ea527c8ea888926614d21bf556f46ce38c220c4ee5b821170eef9071469", + "vendor/tzdata/zoneinfo/America/Argentina/Catamarca": "502d1fc71ed93e68cfc370f404afb9bdaa7e735701cdb811dbddcc76611f3b1d", + "vendor/tzdata/zoneinfo/America/Argentina/ComodRivadavia": "502d1fc71ed93e68cfc370f404afb9bdaa7e735701cdb811dbddcc76611f3b1d", + "vendor/tzdata/zoneinfo/America/Argentina/Cordoba": "f488f75a34fd99630a438dcb792508a90b836fdcd2dc54a51d83d535025315fd", + "vendor/tzdata/zoneinfo/America/Argentina/Jujuy": "ed8a6339c99568a2a98aadf5ad07bc4d30cd131747f638d922175c66ff928548", + "vendor/tzdata/zoneinfo/America/Argentina/La_Rioja": "9949110f98da589532d9ff2f345a8e94c80a3e9b542ce067faf7ff8cc805eb1f", + "vendor/tzdata/zoneinfo/America/Argentina/Mendoza": "74be2ad33818d8528f6c6f1c0be5a49e7a69f2d17663b496816482fc6fd6ce72", + "vendor/tzdata/zoneinfo/America/Argentina/Rio_Gallegos": "6c2a56325108f0a59ee1cde7e9f9fcbba5823e7c6362d572e7b111b4b4d9684b", + "vendor/tzdata/zoneinfo/America/Argentina/Salta": "1ffc9bc55c9c7ce7bb2e5500dc69e0a12d2310d1e44144484618df25017691f5", + "vendor/tzdata/zoneinfo/America/Argentina/San_Juan": "323e6f214cd09790edb0f7b788ccd2eeb47ef3c53d1ca5b672c42a51d6b824d3", + "vendor/tzdata/zoneinfo/America/Argentina/San_Luis": "ae46bc068928832bcc4451fa8ebf03eacd6d148a6c51ea8727f7de2cae4ee9db", + "vendor/tzdata/zoneinfo/America/Argentina/Tucuman": "cafdda0be8402cb8a8db2aa778b208ca56615ca0e56cf24601dfda6e0b23f608", + "vendor/tzdata/zoneinfo/America/Argentina/Ushuaia": "99c999801d691075fa8bb9e5c91ce32e71bc6ea02d00ad53c0c7510f6a59a811", + "vendor/tzdata/zoneinfo/America/Argentina/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/America/Aruba": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Asuncion": "dc938d02e787eca6bfc6ae4a3ab72d2a42806ae3dedc14e0d01393040f143542", + "vendor/tzdata/zoneinfo/America/Atikokan": "a78d73067ba3cbd94f8a23dfdd6aa8b68cb33b18484bc17b4e20ea1aec2f0a81", + "vendor/tzdata/zoneinfo/America/Atka": "abfb1980e20d5f84ec5fd881c7580d77a5c6c019f30a383aaa97404212b489e0", + "vendor/tzdata/zoneinfo/America/Bahia": "ffe645c3e1f35dcedbc9a7075bf3491ed274dc00c576ab7591a620c966286d8c", + "vendor/tzdata/zoneinfo/America/Bahia_Banderas": "949f0af8fad4a8b4de7eeaa970aa7f616bdfbf31f458d36b67f2c87a5ff4a194", + "vendor/tzdata/zoneinfo/America/Barbados": "81d8897fd64a38cb3d401e1ec74f9caef76684d7c7a4dcd74d5db14da3430808", + "vendor/tzdata/zoneinfo/America/Belem": "c348effa07416c4059401176cf69622a944cf4210e580dfa3b5a94d6724a782b", + "vendor/tzdata/zoneinfo/America/Belize": "b9804f26a9c21a738e78a9e8cf5206f4f3964ef5c3e64522ae916e0743c78d5a", + "vendor/tzdata/zoneinfo/America/Blanc-Sablon": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Boa_Vista": "8584c514d35925d97f9d260875f23c49086d99f89a92308323fd794e507ec44c", + "vendor/tzdata/zoneinfo/America/Bogota": "268c2f06cb3237ba930d64a0bcf30c4266eee89ddc9dfabf250cc3900e411c34", + "vendor/tzdata/zoneinfo/America/Boise": "26dde89b23d23d1a0a13e29755dfb0c5538df820c4e6819a240ec0afdd10d8e3", + "vendor/tzdata/zoneinfo/America/Buenos_Aires": "20454ea527c8ea888926614d21bf556f46ce38c220c4ee5b821170eef9071469", + "vendor/tzdata/zoneinfo/America/Cambridge_Bay": "345c0d55f8316f660c2f373ee36440f922ad35c383a6e9047d87ff4165984ec2", + "vendor/tzdata/zoneinfo/America/Campo_Grande": "9a780a623687fc4355989fa6b544558e3168e641e02df60d3c765a0954b14051", + "vendor/tzdata/zoneinfo/America/Cancun": "612a14c5b8da2f633270a0930776402bd8cf55a78c856ecc90e100f1e59a90a6", + "vendor/tzdata/zoneinfo/America/Caracas": "507994c1cd2614fa22751e140c259be13e30fe6a4206c49be01916dd238a2156", + "vendor/tzdata/zoneinfo/America/Catamarca": "502d1fc71ed93e68cfc370f404afb9bdaa7e735701cdb811dbddcc76611f3b1d", + "vendor/tzdata/zoneinfo/America/Cayenne": "f54454e28d6fe7be7d516ba1f3123dbe768034e71e39e456ebb5e8190bae51af", + "vendor/tzdata/zoneinfo/America/Cayman": "a78d73067ba3cbd94f8a23dfdd6aa8b68cb33b18484bc17b4e20ea1aec2f0a81", + "vendor/tzdata/zoneinfo/America/Chicago": "c27b739ff46a7df0594e120d725b439217e11e44ea9a50cdc49130383b5482e7", + "vendor/tzdata/zoneinfo/America/Chihuahua": "b733a603bb6b845ca4c9467b41bb8c03a03cf01485da8e26ba6a3ae5aa23ceaa", + "vendor/tzdata/zoneinfo/America/Ciudad_Juarez": "98413e54dfaca950da1c52721465016323ac607091b2951971226ab76e96b9f8", + "vendor/tzdata/zoneinfo/America/Coral_Harbour": "a78d73067ba3cbd94f8a23dfdd6aa8b68cb33b18484bc17b4e20ea1aec2f0a81", + "vendor/tzdata/zoneinfo/America/Cordoba": "f488f75a34fd99630a438dcb792508a90b836fdcd2dc54a51d83d535025315fd", + "vendor/tzdata/zoneinfo/America/Costa_Rica": "8a1a2a03fb479989b46234d12d9bb7abc3eab2aa8e79bd4210b8d684f7ff1d71", + "vendor/tzdata/zoneinfo/America/Coyhaique": "73f2b76ddba22343ff9449e825435466adaa176f92bdfa3bd31bde2a0f72f5f7", + "vendor/tzdata/zoneinfo/America/Creston": "ae11453c21d08984de75f2efec04dc93178a7b4e23c5e52f2098b8bd45ccb547", + "vendor/tzdata/zoneinfo/America/Cuiaba": "39a2257b40abf8129ed213a2939af075ca026d0e4b487907a814b670ba02a805", + "vendor/tzdata/zoneinfo/America/Curacao": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Danmarkshavn": "710391b80f29474bf0dd9c187de1a459a4f5b4f53aea7310db144a4f54f561be", + "vendor/tzdata/zoneinfo/America/Dawson": "065295d14dfa8ea9e5c4ce7e3f19fc388898e6424470b96ddd0668f86b0cce56", + "vendor/tzdata/zoneinfo/America/Dawson_Creek": "b7851232e22fab55552fd81809a6eb68062cdf592602a027c1fec6cc488924d7", + "vendor/tzdata/zoneinfo/America/Denver": "9bb703920eca4b6119e81a105583a4f6ca220651f13b418479ab7cd56c413f3e", + "vendor/tzdata/zoneinfo/America/Detroit": "23817c32df67c77f0017a0feb2d798b2405afc71ceea3294d7e5b4c9116be740", + "vendor/tzdata/zoneinfo/America/Dominica": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Edmonton": "d52173b56a28205d8d6f792bcfa8bc07614ee0d269f7bf6e43ec91f68d410600", + "vendor/tzdata/zoneinfo/America/Eirunepe": "ead298691a676c14a65e2c17cbbfe6e165bfadb55f9f92d479cd24782dc9ec8c", + "vendor/tzdata/zoneinfo/America/El_Salvador": "e308ec0a9447f40164e5a6cb01b9eebfece8ba144a7306f469e9e4fa75ad9b3d", + "vendor/tzdata/zoneinfo/America/Ensenada": "af9aea4aee505143fa5e847643c0ffe164190c38411010ac7f0b170f4098a6c8", + "vendor/tzdata/zoneinfo/America/Fort_Nelson": "fe3ec827e8571ed57fedd48c83aa711902dbeb3fc8694323dda25d7bf178f504", + "vendor/tzdata/zoneinfo/America/Fort_Wayne": "e678f42a13efbd7be0f26a9ce53e04b1c28a582eab05611cb01c16836432f07b", + "vendor/tzdata/zoneinfo/America/Fortaleza": "ba01780d63b78ff92138d79b7fb08bb13f6574bf893967b2ffaf52d239762c80", + "vendor/tzdata/zoneinfo/America/Glace_Bay": "235a68b0f1c011f83f2dcfc541d5f507c17cfc0d0d7899caef6a77e8f13ba4a3", + "vendor/tzdata/zoneinfo/America/Godthab": "2e5199e58fee77d270591be77079d41d102b41b6e735c9a6af3dddb8c851dc77", + "vendor/tzdata/zoneinfo/America/Goose_Bay": "802240d52936722520d962279fc0e63c1c11030d058d06d83da5092bcd26b4c2", + "vendor/tzdata/zoneinfo/America/Grand_Turk": "1a9f21a4cb7d3f74281079ac217d9ba8634c9144af97066aa8dcdc711f9c6def", + "vendor/tzdata/zoneinfo/America/Grenada": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Guadeloupe": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Guatemala": "0463c623897237a20517f4f4931d6ada587753948485bc83a8b16e5bc10509a5", + "vendor/tzdata/zoneinfo/America/Guayaquil": "f0e21a0b2f928ab28acf823bee5e8c4050e048b1ed8cdd13be494b54467fd34f", + "vendor/tzdata/zoneinfo/America/Guyana": "3e69c4b56b4e4da9ac3c95c4a3b3dc3500b2d91a7e7af1b2261e1c7f4a63011e", + "vendor/tzdata/zoneinfo/America/Halifax": "90ee5a841336a132df592e0a5f5e456ca5dfa39c20f9ff6fc35fe130e2121a28", + "vendor/tzdata/zoneinfo/America/Havana": "9ace6b0aeab6c81338f55993ca632d15037773968137596477c8e3cca767366f", + "vendor/tzdata/zoneinfo/America/Hermosillo": "52bd4c612017dd06d3d945f9ecb983f37a3ab3667ee986d878eb9f2af4fecd33", + "vendor/tzdata/zoneinfo/America/Indiana/Indianapolis": "e678f42a13efbd7be0f26a9ce53e04b1c28a582eab05611cb01c16836432f07b", + "vendor/tzdata/zoneinfo/America/Indiana/Knox": "2890b35dcb7c093308b552d82d8781a8ce9a4fa6f9de058283a6836ec1f9f282", + "vendor/tzdata/zoneinfo/America/Indiana/Marengo": "ca05a6abcb1879ef0d17095267243fb6c2a8a4540ca7d35ee79ef31866f21766", + "vendor/tzdata/zoneinfo/America/Indiana/Petersburg": "048aee6f31c4a79428c8c68f8186c2d7349afc5dcbc295f328cf311f7ac7b292", + "vendor/tzdata/zoneinfo/America/Indiana/Tell_City": "7a6d983070d61055dd647d012a2e5b2d1010f1b6037e8a764f443c4aa0e1d01f", + "vendor/tzdata/zoneinfo/America/Indiana/Vevay": "74f937df87bb310c25ef5f9abcdc911016155ae15341c54a7e5b65461ae5469c", + "vendor/tzdata/zoneinfo/America/Indiana/Vincennes": "8e23830d77a998b3f782f0a406e7dd137ae9e5c1177ed0479ca9def3f5ce3828", + "vendor/tzdata/zoneinfo/America/Indiana/Winamac": "86c12e9da2eb6f1beca72577426e140fbc7ba8e01e06dcdc6dbcc034d32b762c", + "vendor/tzdata/zoneinfo/America/Indiana/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/America/Indianapolis": "e678f42a13efbd7be0f26a9ce53e04b1c28a582eab05611cb01c16836432f07b", + "vendor/tzdata/zoneinfo/America/Inuvik": "bd932739fc83073f8b9ad0f54f1252983b1be98d718f7d6843d1a9396310b18b", + "vendor/tzdata/zoneinfo/America/Iqaluit": "9ce352ef392c1874eb6c4263ef72d84595bdeb83a7710ba3fd5e9f363a43a10d", + "vendor/tzdata/zoneinfo/America/Jamaica": "a437b1700333aeff53a8b5868d5387c080dc14c2d3e95aa5ce36f901b3669284", + "vendor/tzdata/zoneinfo/America/Jujuy": "ed8a6339c99568a2a98aadf5ad07bc4d30cd131747f638d922175c66ff928548", + "vendor/tzdata/zoneinfo/America/Juneau": "57c22a45a247487ee89cad60bb7618b56fdae1590dc23c790c2bd05e915d600a", + "vendor/tzdata/zoneinfo/America/Kentucky/Louisville": "cd2d924b9ef70fd4e6419156b52c9121537765754dff61695416eda9014ccca5", + "vendor/tzdata/zoneinfo/America/Kentucky/Monticello": "e78a2bda843d6d26ccf627d1a0e8d5ed48d117cde34923eec5f19e5c7d2722a9", + "vendor/tzdata/zoneinfo/America/Kentucky/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/America/Knox_IN": "2890b35dcb7c093308b552d82d8781a8ce9a4fa6f9de058283a6836ec1f9f282", + "vendor/tzdata/zoneinfo/America/Kralendijk": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/La_Paz": "da2601c677341c8c00ce5c7e437008f4b6f4188f3b558dbbf6819cae8059495b", + "vendor/tzdata/zoneinfo/America/Lima": "eef363461c732fe5f89326daf8d9335d8340384f9caaa717bf35d3a9c4d70616", + "vendor/tzdata/zoneinfo/America/Los_Angeles": "200d05754f6d83a371cf408d7085125797657b3b0bebeba1e508cffe86a3e5c8", + "vendor/tzdata/zoneinfo/America/Louisville": "cd2d924b9ef70fd4e6419156b52c9121537765754dff61695416eda9014ccca5", + "vendor/tzdata/zoneinfo/America/Lower_Princes": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Maceio": "752560d1d1de753f70d503b617502f5a87a5e3f87cc26b984b882e11a2fee4a9", + "vendor/tzdata/zoneinfo/America/Managua": "658b28c8dfc6225c00229223d6ca634033d6190f641594a2a6351b3bc71a19fc", + "vendor/tzdata/zoneinfo/America/Manaus": "f6482b869af207de18395a2c8499628a20d27fd9b08dbdce6705f41eeb0d46b9", + "vendor/tzdata/zoneinfo/America/Marigot": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Martinique": "9b7ac2e8ca2073a71cd5af5727c14f21885969214d758931699fa97c7846dd7e", + "vendor/tzdata/zoneinfo/America/Matamoros": "2b1800306904ed326eba0f5bc85b13dca37cdfa5f73b25eaefbbfeb45a4b56f7", + "vendor/tzdata/zoneinfo/America/Mazatlan": "20dede710f520eaf6c0cdbeefe773fc6e30dd8b1d28aaf17e9842099551ee9a6", + "vendor/tzdata/zoneinfo/America/Mendoza": "74be2ad33818d8528f6c6f1c0be5a49e7a69f2d17663b496816482fc6fd6ce72", + "vendor/tzdata/zoneinfo/America/Menominee": "a149899b3399b42858ac1f489fe1351aa1158b6a202a33c4497954c92506b3de", + "vendor/tzdata/zoneinfo/America/Merida": "2c1a4e12fe31c5470be41ef015235add4c84efadbe1224976f528f40d2b0c025", + "vendor/tzdata/zoneinfo/America/Metlakatla": "1158f52e430282bcba993f0b9ff1691f1a49494d284a771f6c7196210d1223fd", + "vendor/tzdata/zoneinfo/America/Mexico_City": "37dd2bf08f13fce0f707c3b1f4cec4018efbd9c47c8367b0fb4debbd461bd72f", + "vendor/tzdata/zoneinfo/America/Miquelon": "11ecbe21de5be0714e0c837079116d6c38dc823b3f9b2882d94c2c818b789159", + "vendor/tzdata/zoneinfo/America/Moncton": "927ac13431701c0185af49d6253050fb5d05fdf679c789f74a766d1fe288ea1f", + "vendor/tzdata/zoneinfo/America/Monterrey": "d5a62c229f8d6b494300a56b716e3054a1405f2e4102a0c6db058b4fdc139a64", + "vendor/tzdata/zoneinfo/America/Montevideo": "97b1635baaac706cddbdf8e56c8799e4243f005592dd97950d2e69a4c24234cd", + "vendor/tzdata/zoneinfo/America/Montreal": "815ab4db7a1b1292867d2f924b718e1bba32455ce9f92205db2feb65029c6761", + "vendor/tzdata/zoneinfo/America/Montserrat": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Nassau": "815ab4db7a1b1292867d2f924b718e1bba32455ce9f92205db2feb65029c6761", + "vendor/tzdata/zoneinfo/America/New_York": "d7f2206b3a45989fc9ad63d558922532fa7352280d5f87176bf1db79cb1d1fa9", + "vendor/tzdata/zoneinfo/America/Nipigon": "815ab4db7a1b1292867d2f924b718e1bba32455ce9f92205db2feb65029c6761", + "vendor/tzdata/zoneinfo/America/Nome": "ffe8a77109e1d03c0af6126a15a6333b8a2c50a01407693695a7b9eb9b1b9690", + "vendor/tzdata/zoneinfo/America/Noronha": "434af71ad039cb644690e8f9e8e4d91b9b6e072d41ea47db872ac9a8281fdbb8", + "vendor/tzdata/zoneinfo/America/North_Dakota/Beulah": "46f681212eb46cd351991122e815d25846c94ab70fec9f0d9b183c3a405cae8c", + "vendor/tzdata/zoneinfo/America/North_Dakota/Center": "334f71e0cc7a85c040c24b6fc2fd7a62f3d19acb838d9103c074f452691c832a", + "vendor/tzdata/zoneinfo/America/North_Dakota/New_Salem": "99971af60c9f3b6512cdac7bbf498b24460128156622aca55aa9df2e04ac572b", + "vendor/tzdata/zoneinfo/America/North_Dakota/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/America/Nuuk": "2e5199e58fee77d270591be77079d41d102b41b6e735c9a6af3dddb8c851dc77", + "vendor/tzdata/zoneinfo/America/Ojinaga": "f7b989f5523c875951011108749753cff3022edc21e1bdfa89a43d4289444e90", + "vendor/tzdata/zoneinfo/America/Panama": "a78d73067ba3cbd94f8a23dfdd6aa8b68cb33b18484bc17b4e20ea1aec2f0a81", + "vendor/tzdata/zoneinfo/America/Pangnirtung": "9ce352ef392c1874eb6c4263ef72d84595bdeb83a7710ba3fd5e9f363a43a10d", + "vendor/tzdata/zoneinfo/America/Paramaribo": "0b6bfdb51ea7a39e024440960c5840353978d14b00e00847b1d9c6a0d09be3f4", + "vendor/tzdata/zoneinfo/America/Phoenix": "ae11453c21d08984de75f2efec04dc93178a7b4e23c5e52f2098b8bd45ccb547", + "vendor/tzdata/zoneinfo/America/Port-au-Prince": "c2c4ba55b43ffdb289d8850c3f2fcf6a8d022d12b9a57101aea91a62eaacdcdb", + "vendor/tzdata/zoneinfo/America/Port_of_Spain": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Porto_Acre": "563b9052bebaf2986ae5b707e34afde013e7641287cc97ff31005f33a0dbf7a5", + "vendor/tzdata/zoneinfo/America/Porto_Velho": "f723d4f045ed2834072c5ef8e444dcf6a659f4c7b608aea3be06fa4b9de948a8", + "vendor/tzdata/zoneinfo/America/Puerto_Rico": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Punta_Arenas": "d80aa1edbaa8fa64259cc8d444390239e11899e5e193328fecec4502f8538e30", + "vendor/tzdata/zoneinfo/America/Rainy_River": "6072e5fb802900b193407239b4fb4de9fb2ce80b43ea0f4286a954665b565cbd", + "vendor/tzdata/zoneinfo/America/Rankin_Inlet": "25009740177273cb894e32053b88d9bb34b43a31b48111eff0c3e677337ddc25", + "vendor/tzdata/zoneinfo/America/Recife": "df2653c05dcc265918d03e3c090513cc24700c27c636af045d74d96250605138", + "vendor/tzdata/zoneinfo/America/Regina": "fc91ee9ecdb6e6213e4c773d345a7e441ab83d650b02e1b0d8e2dba4e07f50cc", + "vendor/tzdata/zoneinfo/America/Resolute": "d94789051d994a49f56d4672d06d1212106d63dbf27304915389da2beb30d38e", + "vendor/tzdata/zoneinfo/America/Rio_Branco": "563b9052bebaf2986ae5b707e34afde013e7641287cc97ff31005f33a0dbf7a5", + "vendor/tzdata/zoneinfo/America/Rosario": "f488f75a34fd99630a438dcb792508a90b836fdcd2dc54a51d83d535025315fd", + "vendor/tzdata/zoneinfo/America/Santa_Isabel": "af9aea4aee505143fa5e847643c0ffe164190c38411010ac7f0b170f4098a6c8", + "vendor/tzdata/zoneinfo/America/Santarem": "743106b27ae6e30af3978b0ae8af0fcc4ae804a0fb03557b1c16bc7165b870c9", + "vendor/tzdata/zoneinfo/America/Santiago": "fd006953c2b442a2e1e66db2a967dd932a4824390f01cddd9c801ce63450c715", + "vendor/tzdata/zoneinfo/America/Santo_Domingo": "c66268e7d9995cded69dffb7263977ee6082fbc19f37ac6693697fbe78327de2", + "vendor/tzdata/zoneinfo/America/Sao_Paulo": "fa2ceb222f065c0289f3997ff0c54ba05a74a599b4522870fa86a96e24e18891", + "vendor/tzdata/zoneinfo/America/Scoresbysund": "c2b848115005236f6a293dd374e5a2889c08f34028857c307dbd6608f4805c7a", + "vendor/tzdata/zoneinfo/America/Shiprock": "9bb703920eca4b6119e81a105583a4f6ca220651f13b418479ab7cd56c413f3e", + "vendor/tzdata/zoneinfo/America/Sitka": "a45e72967fbe30ecc430369c35dfc87741d7f6902681ef0f39f731c93361d7ed", + "vendor/tzdata/zoneinfo/America/St_Barthelemy": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/St_Johns": "bfdf6afc014c3e597930cc4ca7df1aa98e347268acdb07224df4eab36fe46f49", + "vendor/tzdata/zoneinfo/America/St_Kitts": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/St_Lucia": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/St_Thomas": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/St_Vincent": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Swift_Current": "17e6fae5869ac76dc2b2e85299e4c397a4eff5dbb822cbd6bcc6db4aec0790b3", + "vendor/tzdata/zoneinfo/America/Tegucigalpa": "2a5bea0491acc1af43217944dda714fa981de0816a0de051ad4cf4d8f9a5342d", + "vendor/tzdata/zoneinfo/America/Thule": "2f32f98dd9999314641dd0375e4a2a24f1bf2269659d24616182d0a4c7ff4d8f", + "vendor/tzdata/zoneinfo/America/Thunder_Bay": "815ab4db7a1b1292867d2f924b718e1bba32455ce9f92205db2feb65029c6761", + "vendor/tzdata/zoneinfo/America/Tijuana": "af9aea4aee505143fa5e847643c0ffe164190c38411010ac7f0b170f4098a6c8", + "vendor/tzdata/zoneinfo/America/Toronto": "815ab4db7a1b1292867d2f924b718e1bba32455ce9f92205db2feb65029c6761", + "vendor/tzdata/zoneinfo/America/Tortola": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Vancouver": "7d23681b36849ac7f50537b9c02bd8d3aa000b98bd3d1825ce85e7ea3e5534c9", + "vendor/tzdata/zoneinfo/America/Virgin": "abbe8628dd5487c889db816ce3a5077bbb47f6bafafeb9411d92d6ef2f70ce8d", + "vendor/tzdata/zoneinfo/America/Whitehorse": "0b26388cd7747f335275fd4795819f6a4b40a661fbd6d44d465a4e10edf60c6b", + "vendor/tzdata/zoneinfo/America/Winnipeg": "6072e5fb802900b193407239b4fb4de9fb2ce80b43ea0f4286a954665b565cbd", + "vendor/tzdata/zoneinfo/America/Yakutat": "a6f1cb54d035988f87f5f0439e59e923a07d5f354541ecaf23d9f22246853584", + "vendor/tzdata/zoneinfo/America/Yellowknife": "d52173b56a28205d8d6f792bcfa8bc07614ee0d269f7bf6e43ec91f68d410600", + "vendor/tzdata/zoneinfo/America/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Antarctica/Casey": "d6373e1408ef90a9e60a3873f3ec908042ab37fb159b3022f03568cbdfcaf004", + "vendor/tzdata/zoneinfo/Antarctica/Davis": "3e89bfdbaeebb28665eb22ef62596efd25b5922c48ad23e6b1df872f3b67df76", + "vendor/tzdata/zoneinfo/Antarctica/DumontDUrville": "683001055b6ef9dc9d88734e0eddd1782f1c3643b7c13a75e9cf8e9052006e19", + "vendor/tzdata/zoneinfo/Antarctica/Macquarie": "68e66523321d4f07af6935e84240e57b1d8b4850eb83ae06bd17dc2e77c20c03", + "vendor/tzdata/zoneinfo/Antarctica/Mawson": "518ba2052134a99fb69240406ba5eae60f4d5e0f96fd1d0ffab976b653b48c77", + "vendor/tzdata/zoneinfo/Antarctica/McMurdo": "0e06e7e55aedbc92ef5b3d106e7c392ab1628cfd8a428b20e92e99028a0bfbb9", + "vendor/tzdata/zoneinfo/Antarctica/Palmer": "dcc5df85005a441e7bfe3a8764c97e33f2b8f0d3057b8cc02dceef68cc92e71c", + "vendor/tzdata/zoneinfo/Antarctica/Rothera": "5de75d44bd984c37c45b3408ee70ea7d6f937e0fb911e6f1b07b0c1f2cc6b9d2", + "vendor/tzdata/zoneinfo/Antarctica/South_Pole": "0e06e7e55aedbc92ef5b3d106e7c392ab1628cfd8a428b20e92e99028a0bfbb9", + "vendor/tzdata/zoneinfo/Antarctica/Syowa": "46853e94276af2eea8e86c2f152a871c092df195dc51273b8fc7091faa4b461c", + "vendor/tzdata/zoneinfo/Antarctica/Troll": "b38cf417fb8acf1ddb88a8c4cef1f06f9eb5df65d1b3a211db67c2420956e462", + "vendor/tzdata/zoneinfo/Antarctica/Vostok": "703a7e078c0a5c4f14e5bff3a89225c5d198f802003024c93991b76d164128d7", + "vendor/tzdata/zoneinfo/Antarctica/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Arctic/Longyearbyen": "a7fd9932d785d4d690900b834c3563c1810c1cf2e01711bcc0926af6c0767cb7", + "vendor/tzdata/zoneinfo/Arctic/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Asia/Aden": "46853e94276af2eea8e86c2f152a871c092df195dc51273b8fc7091faa4b461c", + "vendor/tzdata/zoneinfo/Asia/Almaty": "f3b58d30a085ed6d95eadab92ef5f90d75a88bd32ec230806377fd760c2e8b8b", + "vendor/tzdata/zoneinfo/Asia/Amman": "28e9ca3b8ff55d1950bcb1bad464db7ca2264ad8700473129f35751315bc8b94", + "vendor/tzdata/zoneinfo/Asia/Anadyr": "df46dd66eae0e10fff942a47e74f5313453ba4e70463aab18efb8f17d6a2e727", + "vendor/tzdata/zoneinfo/Asia/Aqtau": "6d18f6eef1b91ef19e80583978828d9aaddd7ed7989abeca993b382453beed23", + "vendor/tzdata/zoneinfo/Asia/Aqtobe": "3e6ef22397267f3c7c0865d1da64090e3b47d76282a71f1ecc529c862255549e", + "vendor/tzdata/zoneinfo/Asia/Ashgabat": "3932c7750f2314f0efc6efc8c0a5ff7375b78dd37a7bb146a0248411bd172aec", + "vendor/tzdata/zoneinfo/Asia/Ashkhabad": "3932c7750f2314f0efc6efc8c0a5ff7375b78dd37a7bb146a0248411bd172aec", + "vendor/tzdata/zoneinfo/Asia/Atyrau": "d581b84332f13d16507861e23ab6e6d1c46cf04453360d4d17d7561305b63e2d", + "vendor/tzdata/zoneinfo/Asia/Baghdad": "cc57ba2d749fba82631ac9984cc1a326d05c00c2e2285903ee3efe55aa8ac07f", + "vendor/tzdata/zoneinfo/Asia/Bahrain": "6160d6575a371c75b19e6c25cf03160b9dc2f386583e42bf8189fdf8fd17c785", + "vendor/tzdata/zoneinfo/Asia/Baku": "fd687a38d6916ad31cf65a7018eeb307da53137f0d678a16838ffeb19975ee60", + "vendor/tzdata/zoneinfo/Asia/Bangkok": "cdc8e2c282d8bc9a5e9c3caf2fc45ff4e9e5cd18f5dec8cb873340ad7c584d64", + "vendor/tzdata/zoneinfo/Asia/Barnaul": "506158258bed818552f13aacaaf8faa743900a6377cdd63dc084d683c3831be9", + "vendor/tzdata/zoneinfo/Asia/Beirut": "16033882a6d6169e8ab949d59fe1fc5085d9813c9d05e3b10dd6de6c9d06a547", + "vendor/tzdata/zoneinfo/Asia/Bishkek": "4577715716a2139cf15f96ad425fbb65eb04799563b025c1199e9c25b554f691", + "vendor/tzdata/zoneinfo/Asia/Brunei": "dda8e0208df167e59cf9da9745348cc3ca904434a35e5481231c84fec0d11939", + "vendor/tzdata/zoneinfo/Asia/Calcutta": "3a00bdbe1bc4959e727567c730ba51b03455ecd455f7c190c5ad14386eb79b0d", + "vendor/tzdata/zoneinfo/Asia/Chita": "d4b99eddc70ee3b4798264dee550aad4149bd26ff5a295a26eadb5cef6659ed8", + "vendor/tzdata/zoneinfo/Asia/Choibalsan": "fbe23c3fafdee01b5121edf009290fb701cebbf93dacfb30f8aa90287242f6f3", + "vendor/tzdata/zoneinfo/Asia/Chongqing": "bf8b7ed82fe6e63e6d98f8cea934eeac901cd16aba85eb5755ce3f8b4289ea8a", + "vendor/tzdata/zoneinfo/Asia/Chungking": "bf8b7ed82fe6e63e6d98f8cea934eeac901cd16aba85eb5755ce3f8b4289ea8a", + "vendor/tzdata/zoneinfo/Asia/Colombo": "400ca32bb82d5d459f2ee8eed4cd07dff7b0ea24ccf9bc1fccee686e0bda1f2f", + "vendor/tzdata/zoneinfo/Asia/Dacca": "ac21a61306d6e2a91453641f4e3e732ebc9d542abc1d35a5d5db2a10340ebefa", + "vendor/tzdata/zoneinfo/Asia/Damascus": "02d6530d1cc7101ed09cac455efb56b0d508d5c0827b6eec01fa437d07743306", + "vendor/tzdata/zoneinfo/Asia/Dhaka": "ac21a61306d6e2a91453641f4e3e732ebc9d542abc1d35a5d5db2a10340ebefa", + "vendor/tzdata/zoneinfo/Asia/Dili": "e5f7021e45486642d5f1372ca8143c1ecb482c4a73ddacb7306194eac80dc4b0", + "vendor/tzdata/zoneinfo/Asia/Dubai": "0d9ea5053e83188032a6fb4d301d5db688f43011e5b6b1f917a11b71a0da7b16", + "vendor/tzdata/zoneinfo/Asia/Dushanbe": "f2a6e7efaadff71bb8ecd61575f1af8e791fd8a67134de49f1e905897533dc04", + "vendor/tzdata/zoneinfo/Asia/Famagusta": "dfce5f6da467c7e99d11a5ea4b204a5410c328fcc218a6f29d662def9c300ae8", + "vendor/tzdata/zoneinfo/Asia/Gaza": "f8f0bffe018e0da0c682fe4b2f31fba6d34b6cd752b4f931198e0b99e6ef70d5", + "vendor/tzdata/zoneinfo/Asia/Harbin": "bf8b7ed82fe6e63e6d98f8cea934eeac901cd16aba85eb5755ce3f8b4289ea8a", + "vendor/tzdata/zoneinfo/Asia/Hebron": "e05ba37ee13e10221780a5b8a6fd25c6ad999008fb8c3c2dd2b7b3b80d1f1738", + "vendor/tzdata/zoneinfo/Asia/Ho_Chi_Minh": "0d6e76fb941d0540214ee81f161f449c6a7dc3d515e5654618a7ae42d0acd1e1", + "vendor/tzdata/zoneinfo/Asia/Hong_Kong": "f4068f73246db97417f73467453564c57d6646ce4909b9fa2536923efcd7eb4f", + "vendor/tzdata/zoneinfo/Asia/Hovd": "7aa02f0f645fb887d20e1b6a939f0c102223cf95f5e0e1d9eda3b8cf5e249dd9", + "vendor/tzdata/zoneinfo/Asia/Irkutsk": "b16c69f20fda49f15a9f867217db3afa9117e55830c62fe336feefc0dd3a5c8a", + "vendor/tzdata/zoneinfo/Asia/Istanbul": "2a7163b16b94806f69991348e7d0a60c46eb61b1f0305f5f4b83f613db10806f", + "vendor/tzdata/zoneinfo/Asia/Jakarta": "e2a099ea48b1f7166b88d219b326f7c44373d08909cd9723b44346946fd6a384", + "vendor/tzdata/zoneinfo/Asia/Jayapura": "0546b4917d6239d7f413ebfbe35e61ee5d2542fe03042617ff77406d8990d315", + "vendor/tzdata/zoneinfo/Asia/Jerusalem": "9fcde8d584dea0585f5c8727aaf35f48a149e0dbd3a83bf6cef8bca9c14021e3", + "vendor/tzdata/zoneinfo/Asia/Kabul": "a4d2304df8921bbd4118abeb84aaa8d71771724031f6f7dcc799c96a7acbf354", + "vendor/tzdata/zoneinfo/Asia/Kamchatka": "422c7cc77b3e9bc5137a2c3334f072fd942f0335ff69a8a1cff3f32df4e251a7", + "vendor/tzdata/zoneinfo/Asia/Karachi": "ba3a38c2ffb7a1af6d7eb153e63b0b70461c8de19e051806d90c1d5e0fe28d4e", + "vendor/tzdata/zoneinfo/Asia/Kashgar": "849cafd377611cc2fc2b41891ab63c6fb3343949045db961fd16267593315ad4", + "vendor/tzdata/zoneinfo/Asia/Kathmandu": "76b8f1bfe072231a1d9e7f8501310e27c0d08048c48f7422860b6477c142c438", + "vendor/tzdata/zoneinfo/Asia/Katmandu": "76b8f1bfe072231a1d9e7f8501310e27c0d08048c48f7422860b6477c142c438", + "vendor/tzdata/zoneinfo/Asia/Khandyga": "7dd1033ac0c990bb843726ea217b53888e24d9edb874a1c37c14f0c3d02d6d2c", + "vendor/tzdata/zoneinfo/Asia/Kolkata": "3a00bdbe1bc4959e727567c730ba51b03455ecd455f7c190c5ad14386eb79b0d", + "vendor/tzdata/zoneinfo/Asia/Krasnoyarsk": "6ee348e52d60ede79d2be3e99eb2e40451590d4c82b47c5cc570d0185d80468b", + "vendor/tzdata/zoneinfo/Asia/Kuala_Lumpur": "0954b2d9a301d94f4348024606a71bbcb2fa24d3cd3709f5bc8bca605039785d", + "vendor/tzdata/zoneinfo/Asia/Kuching": "dda8e0208df167e59cf9da9745348cc3ca904434a35e5481231c84fec0d11939", + "vendor/tzdata/zoneinfo/Asia/Kuwait": "46853e94276af2eea8e86c2f152a871c092df195dc51273b8fc7091faa4b461c", + "vendor/tzdata/zoneinfo/Asia/Macao": "9abf3d8bfc293285a102da99ac5d9219ca082dc530eab62b0e42143400deb3b1", + "vendor/tzdata/zoneinfo/Asia/Macau": "9abf3d8bfc293285a102da99ac5d9219ca082dc530eab62b0e42143400deb3b1", + "vendor/tzdata/zoneinfo/Asia/Magadan": "c00b9f30658bfecd40c369779b201f045b6b44e54f7acddd32836e0c4a0dc13f", + "vendor/tzdata/zoneinfo/Asia/Makassar": "355f63fd14ee894e3b9af26f7ca13c75a5c7e4015827c2a2e20bc70494b1c8b7", + "vendor/tzdata/zoneinfo/Asia/Manila": "1681a62321489c79277c4d74dcf6e20fae46530b269d85b3179a06cacd3706a6", + "vendor/tzdata/zoneinfo/Asia/Muscat": "0d9ea5053e83188032a6fb4d301d5db688f43011e5b6b1f917a11b71a0da7b16", + "vendor/tzdata/zoneinfo/Asia/Nicosia": "4d862a5a9f2c2b40300541c0a74c2eba2859b90d7d45776ddbc6ed877df33812", + "vendor/tzdata/zoneinfo/Asia/Novokuznetsk": "6985bdae9731a5fff3ace65cdaf9a972a822b8244a30707594cae2a08e37282c", + "vendor/tzdata/zoneinfo/Asia/Novosibirsk": "2369f830212569df6c31cc8900073861d553e9ec1b851efd3a8000ba11097c26", + "vendor/tzdata/zoneinfo/Asia/Omsk": "cbbbb8ec439b077c08f0cc4a1c145314cf8111966a846a730e0ef1e657302576", + "vendor/tzdata/zoneinfo/Asia/Oral": "43e19ff39348bdd02d539d999207fbf2b5473e583ce71c8c7bd666f726e1d29a", + "vendor/tzdata/zoneinfo/Asia/Phnom_Penh": "cdc8e2c282d8bc9a5e9c3caf2fc45ff4e9e5cd18f5dec8cb873340ad7c584d64", + "vendor/tzdata/zoneinfo/Asia/Pontianak": "a34c748cd4e5c23894a80cc65ff1e5cef08caeedb3514460438c73a52f79c5db", + "vendor/tzdata/zoneinfo/Asia/Pyongyang": "3710b975af284d9e12b621509e5863969f454d1b8c33e5f0b2add8838cb4c640", + "vendor/tzdata/zoneinfo/Asia/Qatar": "6160d6575a371c75b19e6c25cf03160b9dc2f386583e42bf8189fdf8fd17c785", + "vendor/tzdata/zoneinfo/Asia/Qostanay": "e6d6648f5a34a78bda444b0f3b4620222c3a7837f572a3b9db1fb410c83fd8be", + "vendor/tzdata/zoneinfo/Asia/Qyzylorda": "265b4a0c49ee1e62101987454c024c0c3a5d0c0fc7c6324e0071da57b905ae54", + "vendor/tzdata/zoneinfo/Asia/Rangoon": "e89d835c811d4da44aa8b386782ce8828df085aa0ee8f25661a9881d2f00e90c", + "vendor/tzdata/zoneinfo/Asia/Riyadh": "46853e94276af2eea8e86c2f152a871c092df195dc51273b8fc7091faa4b461c", + "vendor/tzdata/zoneinfo/Asia/Saigon": "0d6e76fb941d0540214ee81f161f449c6a7dc3d515e5654618a7ae42d0acd1e1", + "vendor/tzdata/zoneinfo/Asia/Sakhalin": "33f4c177ed378fedd873d2b0846128053c1227158ed653c11bb9ddb2dd7a3c6a", + "vendor/tzdata/zoneinfo/Asia/Samarkand": "299feafba18c0d58096fc445a9cadb55c3c2d162dcce8942942e27640d4754d5", + "vendor/tzdata/zoneinfo/Asia/Seoul": "64a70b6fbcc9b65e762dbd25eb89b6f40c137146edc8dbd4d081eafacdab78de", + "vendor/tzdata/zoneinfo/Asia/Shanghai": "bf8b7ed82fe6e63e6d98f8cea934eeac901cd16aba85eb5755ce3f8b4289ea8a", + "vendor/tzdata/zoneinfo/Asia/Singapore": "0954b2d9a301d94f4348024606a71bbcb2fa24d3cd3709f5bc8bca605039785d", + "vendor/tzdata/zoneinfo/Asia/Srednekolymsk": "d3a9a88deb456c37786a0d69f0d2b4160eab17638e9d93054510bdd0dd804d97", + "vendor/tzdata/zoneinfo/Asia/Taipei": "a04c2c72f4f76a83178d036dd97d157ee1f32e478e44dda7a5c10923687ee6cf", + "vendor/tzdata/zoneinfo/Asia/Tashkent": "d2fa4dda023d198e74cf59de6bacc23c57f607a542bba5d0407c7897aae19d32", + "vendor/tzdata/zoneinfo/Asia/Tbilisi": "07317f2e828107fb3dd3080ee831197c8c6d35f87b67cb7c5cb5bb642cec1389", + "vendor/tzdata/zoneinfo/Asia/Tehran": "452d5a097a6c260fccb4e7b229b4eddca5563f5cac30c515bc89cb73bc615b72", + "vendor/tzdata/zoneinfo/Asia/Tel_Aviv": "9fcde8d584dea0585f5c8727aaf35f48a149e0dbd3a83bf6cef8bca9c14021e3", + "vendor/tzdata/zoneinfo/Asia/Thimbu": "37a77fbdf16f60e45f327af57c7263612b780c139149b2e2ff64feaf67490672", + "vendor/tzdata/zoneinfo/Asia/Thimphu": "37a77fbdf16f60e45f327af57c7263612b780c139149b2e2ff64feaf67490672", + "vendor/tzdata/zoneinfo/Asia/Tokyo": "59a3871430f0d3b93e619fa30a43a41d1e88bdd49ff26f09d0f405a500706f96", + "vendor/tzdata/zoneinfo/Asia/Tomsk": "05fec6a054dc51e3f6858cae629aee2638b7ded704a0b3fef34a37f00ea2e335", + "vendor/tzdata/zoneinfo/Asia/Ujung_Pandang": "355f63fd14ee894e3b9af26f7ca13c75a5c7e4015827c2a2e20bc70494b1c8b7", + "vendor/tzdata/zoneinfo/Asia/Ulaanbaatar": "fbe23c3fafdee01b5121edf009290fb701cebbf93dacfb30f8aa90287242f6f3", + "vendor/tzdata/zoneinfo/Asia/Ulan_Bator": "fbe23c3fafdee01b5121edf009290fb701cebbf93dacfb30f8aa90287242f6f3", + "vendor/tzdata/zoneinfo/Asia/Urumqi": "849cafd377611cc2fc2b41891ab63c6fb3343949045db961fd16267593315ad4", + "vendor/tzdata/zoneinfo/Asia/Ust-Nera": "e8d92e575cce9acfb8a87421abe70673e72a11580a1e4eea77730b0ccf9ed810", + "vendor/tzdata/zoneinfo/Asia/Vientiane": "cdc8e2c282d8bc9a5e9c3caf2fc45ff4e9e5cd18f5dec8cb873340ad7c584d64", + "vendor/tzdata/zoneinfo/Asia/Vladivostok": "ce4397b840e0a715fc1d01a00e587d49b010cc739a3715f65d223a63880c0fe9", + "vendor/tzdata/zoneinfo/Asia/Yakutsk": "c43eb3038136dbc742d6621443b70c3bef4b39149f13e1689346b01831ba8ee9", + "vendor/tzdata/zoneinfo/Asia/Yangon": "e89d835c811d4da44aa8b386782ce8828df085aa0ee8f25661a9881d2f00e90c", + "vendor/tzdata/zoneinfo/Asia/Yekaterinburg": "ab5ede532a8e10ad8b25829760b089ab2963faf99a086daf48d32db6aad04d19", + "vendor/tzdata/zoneinfo/Asia/Yerevan": "a4b10175c840f07f65fbd85d03a1631e6c1a8f94f58eea4ad2ef9ba2bd4a29ad", + "vendor/tzdata/zoneinfo/Asia/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Atlantic/Azores": "e97069fab820f211114ded9cf9b4ca6a160f9640e7dac44e06eaa8f7001db4f1", + "vendor/tzdata/zoneinfo/Atlantic/Bermuda": "3eec6a0f6703f7d3f38dbf211fdf43c2cd39dddff35e76478de1f4919f0b48b2", + "vendor/tzdata/zoneinfo/Atlantic/Canary": "5cc9b1065b1c3c85978626ae2b2fdde5bc57e318cd30cfb9570f381706644f4d", + "vendor/tzdata/zoneinfo/Atlantic/Cape_Verde": "139b2ceb1a48a43d20fd5103b053058be96db1e6e9f7c3c14a950ba15c480325", + "vendor/tzdata/zoneinfo/Atlantic/Faeroe": "230d2a074981baf887e70dd0cbc8dac4239eb34ed91e1db0916f0c3d4589aa3d", + "vendor/tzdata/zoneinfo/Atlantic/Faroe": "230d2a074981baf887e70dd0cbc8dac4239eb34ed91e1db0916f0c3d4589aa3d", + "vendor/tzdata/zoneinfo/Atlantic/Jan_Mayen": "a7fd9932d785d4d690900b834c3563c1810c1cf2e01711bcc0926af6c0767cb7", + "vendor/tzdata/zoneinfo/Atlantic/Madeira": "d85def2e6a7b3939b864c48bc72215410ea25de19490a28f7947621a6a95bae2", + "vendor/tzdata/zoneinfo/Atlantic/Reykjavik": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Atlantic/South_Georgia": "90f19f08b403d82ebf5dce53c809aa9973fe19874b2cfb9ca419f74bbc9b5aef", + "vendor/tzdata/zoneinfo/Atlantic/St_Helena": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Atlantic/Stanley": "42a41df085a494d6a930a8cde6f17bbef567e0afb297754abcce7390229a6c23", + "vendor/tzdata/zoneinfo/Atlantic/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Australia/ACT": "820d45a868a88f81c731d5b2c758b4ed000039b6260a80433f8e0f094a604b59", + "vendor/tzdata/zoneinfo/Australia/Adelaide": "1a4d52746455981db7dc8f961135c0302673ecbec7573a0de1a52821c80daf78", + "vendor/tzdata/zoneinfo/Australia/Brisbane": "da4556cfd088feab5f75be7983488be7d814042ee59cedc651a948431b470036", + "vendor/tzdata/zoneinfo/Australia/Broken_Hill": "77393d2ef180ff1452b670088c016e4c9f14c33feceea1961909a25cf803b0b6", + "vendor/tzdata/zoneinfo/Australia/Canberra": "820d45a868a88f81c731d5b2c758b4ed000039b6260a80433f8e0f094a604b59", + "vendor/tzdata/zoneinfo/Australia/Currie": "d4801581fd00037b013d71616b119fbbd510fdca5de06369b10f718a8da5e32d", + "vendor/tzdata/zoneinfo/Australia/Darwin": "6687b16e181d52557895e57e76106ee80c43564272e37c6b3dbf5443711009d2", + "vendor/tzdata/zoneinfo/Australia/Eucla": "dcdaac15f33347afa54943d588d5c100ec893eaca8922b2c7bbb835eead44699", + "vendor/tzdata/zoneinfo/Australia/Hobart": "d4801581fd00037b013d71616b119fbbd510fdca5de06369b10f718a8da5e32d", + "vendor/tzdata/zoneinfo/Australia/LHI": "f368bd25659c0293d02bb79ec7dac7d5b73a92dffafce14b4dd2ffb8ba11aada", + "vendor/tzdata/zoneinfo/Australia/Lindeman": "887902734409ee26907df8934d7415276b30b02ed02712d430740e1821659139", + "vendor/tzdata/zoneinfo/Australia/Lord_Howe": "f368bd25659c0293d02bb79ec7dac7d5b73a92dffafce14b4dd2ffb8ba11aada", + "vendor/tzdata/zoneinfo/Australia/Melbourne": "5fb24f3048ff4985b27e0585324a7a14e993e867f28d1fa517d8451a04dabe71", + "vendor/tzdata/zoneinfo/Australia/NSW": "820d45a868a88f81c731d5b2c758b4ed000039b6260a80433f8e0f094a604b59", + "vendor/tzdata/zoneinfo/Australia/North": "6687b16e181d52557895e57e76106ee80c43564272e37c6b3dbf5443711009d2", + "vendor/tzdata/zoneinfo/Australia/Perth": "66cb9e95c042d587d6ba01f60ab94e5d07120c3e20194242a1b0755be6aea47a", + "vendor/tzdata/zoneinfo/Australia/Queensland": "da4556cfd088feab5f75be7983488be7d814042ee59cedc651a948431b470036", + "vendor/tzdata/zoneinfo/Australia/South": "1a4d52746455981db7dc8f961135c0302673ecbec7573a0de1a52821c80daf78", + "vendor/tzdata/zoneinfo/Australia/Sydney": "820d45a868a88f81c731d5b2c758b4ed000039b6260a80433f8e0f094a604b59", + "vendor/tzdata/zoneinfo/Australia/Tasmania": "d4801581fd00037b013d71616b119fbbd510fdca5de06369b10f718a8da5e32d", + "vendor/tzdata/zoneinfo/Australia/Victoria": "5fb24f3048ff4985b27e0585324a7a14e993e867f28d1fa517d8451a04dabe71", + "vendor/tzdata/zoneinfo/Australia/West": "66cb9e95c042d587d6ba01f60ab94e5d07120c3e20194242a1b0755be6aea47a", + "vendor/tzdata/zoneinfo/Australia/Yancowinna": "77393d2ef180ff1452b670088c016e4c9f14c33feceea1961909a25cf803b0b6", + "vendor/tzdata/zoneinfo/Australia/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Brazil/Acre": "563b9052bebaf2986ae5b707e34afde013e7641287cc97ff31005f33a0dbf7a5", + "vendor/tzdata/zoneinfo/Brazil/DeNoronha": "434af71ad039cb644690e8f9e8e4d91b9b6e072d41ea47db872ac9a8281fdbb8", + "vendor/tzdata/zoneinfo/Brazil/East": "fa2ceb222f065c0289f3997ff0c54ba05a74a599b4522870fa86a96e24e18891", + "vendor/tzdata/zoneinfo/Brazil/West": "f6482b869af207de18395a2c8499628a20d27fd9b08dbdce6705f41eeb0d46b9", + "vendor/tzdata/zoneinfo/Brazil/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/CET": "b10f9542a8509f0a63ebca78e3d80432dd86b8ea296400280febd9cfa76e8288", + "vendor/tzdata/zoneinfo/CST6CDT": "658805949dfdfb295bbdd9c4795da09a49c154ffa9770fd718172f838c6ffd2f", + "vendor/tzdata/zoneinfo/Canada/Atlantic": "90ee5a841336a132df592e0a5f5e456ca5dfa39c20f9ff6fc35fe130e2121a28", + "vendor/tzdata/zoneinfo/Canada/Central": "6072e5fb802900b193407239b4fb4de9fb2ce80b43ea0f4286a954665b565cbd", + "vendor/tzdata/zoneinfo/Canada/Eastern": "815ab4db7a1b1292867d2f924b718e1bba32455ce9f92205db2feb65029c6761", + "vendor/tzdata/zoneinfo/Canada/Mountain": "d52173b56a28205d8d6f792bcfa8bc07614ee0d269f7bf6e43ec91f68d410600", + "vendor/tzdata/zoneinfo/Canada/Newfoundland": "bfdf6afc014c3e597930cc4ca7df1aa98e347268acdb07224df4eab36fe46f49", + "vendor/tzdata/zoneinfo/Canada/Pacific": "7d23681b36849ac7f50537b9c02bd8d3aa000b98bd3d1825ce85e7ea3e5534c9", + "vendor/tzdata/zoneinfo/Canada/Saskatchewan": "fc91ee9ecdb6e6213e4c773d345a7e441ab83d650b02e1b0d8e2dba4e07f50cc", + "vendor/tzdata/zoneinfo/Canada/Yukon": "0b26388cd7747f335275fd4795819f6a4b40a661fbd6d44d465a4e10edf60c6b", + "vendor/tzdata/zoneinfo/Canada/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Chile/Continental": "fd006953c2b442a2e1e66db2a967dd932a4824390f01cddd9c801ce63450c715", + "vendor/tzdata/zoneinfo/Chile/EasterIsland": "13054cef85e3b1ba0f5712bd6d699d7789d3aedbdab0fd7394b771acc07f61a1", + "vendor/tzdata/zoneinfo/Chile/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Cuba": "9ace6b0aeab6c81338f55993ca632d15037773968137596477c8e3cca767366f", + "vendor/tzdata/zoneinfo/EET": "f1fd678b0548e329b38934f6281255e698dfa761ad1ff841f6ccb79606c61345", + "vendor/tzdata/zoneinfo/EST": "a78d73067ba3cbd94f8a23dfdd6aa8b68cb33b18484bc17b4e20ea1aec2f0a81", + "vendor/tzdata/zoneinfo/EST5EDT": "d05c655502932c33bf9c1637d3ad19ba04c2060b04351d4b707738f97f3e64cf", + "vendor/tzdata/zoneinfo/Egypt": "89cb9a36212fb82e933dcd9faa10efdfa969a29ec80c32063bbb4518c033d1be", + "vendor/tzdata/zoneinfo/Eire": "db9497b0a9fcafc6630b0f06b41edb1827793b3b22d9f799d11419e0439f96ec", + "vendor/tzdata/zoneinfo/Etc/GMT": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/Etc/GMT+0": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/Etc/GMT+1": "e4bf68f1311482d075d69a086a0f39bd176ad3c2cc0d9999e833e7ed4a8f2ff8", + "vendor/tzdata/zoneinfo/Etc/GMT+10": "22f0718aa414efaab335bbb1468f0087dacf4124464062a9fd246ce6ed4f3e43", + "vendor/tzdata/zoneinfo/Etc/GMT+11": "f4c7c5a45a7faedf4f92c323436dd53a58abde1cd39672f3ff9576b5fa2785b5", + "vendor/tzdata/zoneinfo/Etc/GMT+12": "976e97085a7d21b8171af330ecd1e01f32196c7af2d81e6a1987e13031c556bc", + "vendor/tzdata/zoneinfo/Etc/GMT+2": "61b6ea1fb07a8cda101088f2578fbc6b67170fd9460b7bd02a7124636b9c0c62", + "vendor/tzdata/zoneinfo/Etc/GMT+3": "ab70fd0cb7e64c1500a3860c9cd50d5142ab024292c0ce50faf7ac77d03a4994", + "vendor/tzdata/zoneinfo/Etc/GMT+4": "52084a304de569748367babbe180dbe0570b9f336a5d0c9d719a501efb2c3f69", + "vendor/tzdata/zoneinfo/Etc/GMT+5": "4d9e6a6a810b96ccd6fd9e4576a00430a93c63fc6ee5785904d654728e794ab3", + "vendor/tzdata/zoneinfo/Etc/GMT+6": "ff69372d9e71f21563330c260b1e86a94c16fafd48bce901ac98d81f96c3e90c", + "vendor/tzdata/zoneinfo/Etc/GMT+7": "0e2f09e37d161abf7c5b0f79b5d7c8a3c846c645507c9be5c79e5a9ec0eea1e4", + "vendor/tzdata/zoneinfo/Etc/GMT+8": "388225505859c0bd9cb71ddfc4835b6361c30c099243b8b66405205fb1318e0c", + "vendor/tzdata/zoneinfo/Etc/GMT+9": "d6fa642283ea062c035b31fe7cb171c0d6e674a458ee6a9d889858408995c5ac", + "vendor/tzdata/zoneinfo/Etc/GMT-0": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/Etc/GMT-1": "4bcd52f59d3e57ed01e54fb44b43e76f1f1fbf6887b701352eb95993e7242eda", + "vendor/tzdata/zoneinfo/Etc/GMT-10": "56f746e48a5707fc495f8a26cdfaeb1db964454ce46c26573e14eb2e781ceef9", + "vendor/tzdata/zoneinfo/Etc/GMT-11": "dac60b7d5b83152cbb29cd5638f898d44aaab87c395f1e076c303540e2f585ce", + "vendor/tzdata/zoneinfo/Etc/GMT-12": "89f1d5864e5f733646dc60f2fcdbfb62c2cd6b17fcb2d07832bce05940883655", + "vendor/tzdata/zoneinfo/Etc/GMT-13": "08c90e45d5ec692c8bfb83749f7ec2c9cd650abdb666c5b2ba0f7f41955ed04d", + "vendor/tzdata/zoneinfo/Etc/GMT-14": "34ad3b125c2e794d0e3fc80e46d717514ba0ff7bf8774e2ec5f5473149cb33d5", + "vendor/tzdata/zoneinfo/Etc/GMT-2": "40c4e830b7227f54b848d3ce33132d04ba9cd6c9146272216d40232847407fdc", + "vendor/tzdata/zoneinfo/Etc/GMT-3": "d7418cbdfba5689c034221e258426253f6144728c37cf725e6e827601ba03771", + "vendor/tzdata/zoneinfo/Etc/GMT-4": "73a2b1defe3519192bbe4cbc93bd5d6ff5096e9cb2a763990ac8c34af8e4afab", + "vendor/tzdata/zoneinfo/Etc/GMT-5": "f784ef3bc7bff2de766ecf2bcbbd2702abaf80af2a24a41323b9509d50875fe5", + "vendor/tzdata/zoneinfo/Etc/GMT-6": "ddf1fc797fbed220e28e66004074342145e179ecda8faf9a69d66c40d001e1f1", + "vendor/tzdata/zoneinfo/Etc/GMT-7": "0e7b1327735461818b53015bfcbd7953f19b68c17e69c2d5b0fc933724b21fe3", + "vendor/tzdata/zoneinfo/Etc/GMT-8": "92f19053038d0c11bb9e1129ff0112738c65e31357897122bf102fd3d9e4aff8", + "vendor/tzdata/zoneinfo/Etc/GMT-9": "535591146590016f752572bdf606352bd774ac56580d61f30d4477cfbd4b87a6", + "vendor/tzdata/zoneinfo/Etc/GMT0": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/Etc/Greenwich": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/Etc/UCT": "fddce1e648a1732ac29afd9a16151b2973cdf082e7ec0c690f7e42be6b598b93", + "vendor/tzdata/zoneinfo/Etc/UTC": "fddce1e648a1732ac29afd9a16151b2973cdf082e7ec0c690f7e42be6b598b93", + "vendor/tzdata/zoneinfo/Etc/Universal": "fddce1e648a1732ac29afd9a16151b2973cdf082e7ec0c690f7e42be6b598b93", + "vendor/tzdata/zoneinfo/Etc/Zulu": "fddce1e648a1732ac29afd9a16151b2973cdf082e7ec0c690f7e42be6b598b93", + "vendor/tzdata/zoneinfo/Etc/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Europe/Amsterdam": "b10f9542a8509f0a63ebca78e3d80432dd86b8ea296400280febd9cfa76e8288", + "vendor/tzdata/zoneinfo/Europe/Andorra": "95eb93c84e2e76e2015f46876ffecf2bf2a5b25a564b24ba7b4492f3884a16b1", + "vendor/tzdata/zoneinfo/Europe/Astrakhan": "3f7139503810e20aac322f8a74c016c0e492b6881d70d97dacb31551da452d72", + "vendor/tzdata/zoneinfo/Europe/Athens": "f1fd678b0548e329b38934f6281255e698dfa761ad1ff841f6ccb79606c61345", + "vendor/tzdata/zoneinfo/Europe/Belfast": "676541f0b8ad457c744c093f807589adcad909e3fd03f901787d08786eedbd33", + "vendor/tzdata/zoneinfo/Europe/Belgrade": "a8c964f3eaa7a209d9a650fb16c68c003e9a5fc62ffbbb10fa849d54fb3662d6", + "vendor/tzdata/zoneinfo/Europe/Berlin": "a7fd9932d785d4d690900b834c3563c1810c1cf2e01711bcc0926af6c0767cb7", + "vendor/tzdata/zoneinfo/Europe/Bratislava": "a6e930e3375cdcb51f7d8a74885aff89fd14b861ebb75cb339d0f91c16c1469a", + "vendor/tzdata/zoneinfo/Europe/Brussels": "b10f9542a8509f0a63ebca78e3d80432dd86b8ea296400280febd9cfa76e8288", + "vendor/tzdata/zoneinfo/Europe/Bucharest": "898ef81fde9a693309be6a80873528488f128d952d3efbf83c61780a5c059ba5", + "vendor/tzdata/zoneinfo/Europe/Budapest": "a8dafebda9680c8d667afb905ea38c90e848713d7de0473338a2228f1ac3315f", + "vendor/tzdata/zoneinfo/Europe/Busingen": "199062b1c30cfeb2375ec84c56df52be51891986a6293b7a124d3a62509f45e9", + "vendor/tzdata/zoneinfo/Europe/Chisinau": "439e1ca44e245387148c1141d7d7c5e84bcca73188ff85351a126c8deea0e12e", + "vendor/tzdata/zoneinfo/Europe/Copenhagen": "a7fd9932d785d4d690900b834c3563c1810c1cf2e01711bcc0926af6c0767cb7", + "vendor/tzdata/zoneinfo/Europe/Dublin": "db9497b0a9fcafc6630b0f06b41edb1827793b3b22d9f799d11419e0439f96ec", + "vendor/tzdata/zoneinfo/Europe/Gibraltar": "b758609434cb50816ab3dd6763996e94dee8c64a005c79e1d338f268a1b66c6f", + "vendor/tzdata/zoneinfo/Europe/Guernsey": "676541f0b8ad457c744c093f807589adcad909e3fd03f901787d08786eedbd33", + "vendor/tzdata/zoneinfo/Europe/Helsinki": "71ca4af5998f09990c5e875d350fc3c8e34f280bae6fe14f36d4692face7a563", + "vendor/tzdata/zoneinfo/Europe/Isle_of_Man": "676541f0b8ad457c744c093f807589adcad909e3fd03f901787d08786eedbd33", + "vendor/tzdata/zoneinfo/Europe/Istanbul": "2a7163b16b94806f69991348e7d0a60c46eb61b1f0305f5f4b83f613db10806f", + "vendor/tzdata/zoneinfo/Europe/Jersey": "676541f0b8ad457c744c093f807589adcad909e3fd03f901787d08786eedbd33", + "vendor/tzdata/zoneinfo/Europe/Kaliningrad": "e7ba2ff46f26db9c35a4f74917cce8156ceae48e94a01315b24d9e1cf7a56c0f", + "vendor/tzdata/zoneinfo/Europe/Kiev": "0589e80ddecebf9d3077898c12975d2be7393df2856ee9926c534763e1e26bf2", + "vendor/tzdata/zoneinfo/Europe/Kirov": "2aa5c67086cc193b8ea0a658046fb96e3ee457315b2b218c03df4f034e35e03d", + "vendor/tzdata/zoneinfo/Europe/Kyiv": "0589e80ddecebf9d3077898c12975d2be7393df2856ee9926c534763e1e26bf2", + "vendor/tzdata/zoneinfo/Europe/Lisbon": "44d2f6cf84737e6a1e0daf914109e94256beca40b40c9a11b7a04e8bddaee4ec", + "vendor/tzdata/zoneinfo/Europe/Ljubljana": "a8c964f3eaa7a209d9a650fb16c68c003e9a5fc62ffbbb10fa849d54fb3662d6", + "vendor/tzdata/zoneinfo/Europe/London": "676541f0b8ad457c744c093f807589adcad909e3fd03f901787d08786eedbd33", + "vendor/tzdata/zoneinfo/Europe/Luxembourg": "b10f9542a8509f0a63ebca78e3d80432dd86b8ea296400280febd9cfa76e8288", + "vendor/tzdata/zoneinfo/Europe/Madrid": "ca5b321ddbfc88e07e0d03ed2fa0c832ce5d0dd8e7d90a25200a8e24898c3b21", + "vendor/tzdata/zoneinfo/Europe/Malta": "8ab5ff9c30fe05760e6da76ebbfbe13ded45df5c6680bdfae1d48e693fce55ca", + "vendor/tzdata/zoneinfo/Europe/Mariehamn": "71ca4af5998f09990c5e875d350fc3c8e34f280bae6fe14f36d4692face7a563", + "vendor/tzdata/zoneinfo/Europe/Minsk": "f3a88fff10ed89d9140aa8e4a0a847e7f125dd5236d5f4a0a0889797f07351a5", + "vendor/tzdata/zoneinfo/Europe/Monaco": "cd588e779c5737d70e4e47158dafab7945b026b2bb34454cc47741815459b068", + "vendor/tzdata/zoneinfo/Europe/Moscow": "ed2e0a099fb446b2416683438d3f56f9fc5a62a16c7549a7f59cbc935b364c8a", + "vendor/tzdata/zoneinfo/Europe/Nicosia": "4d862a5a9f2c2b40300541c0a74c2eba2859b90d7d45776ddbc6ed877df33812", + "vendor/tzdata/zoneinfo/Europe/Oslo": "a7fd9932d785d4d690900b834c3563c1810c1cf2e01711bcc0926af6c0767cb7", + "vendor/tzdata/zoneinfo/Europe/Paris": "cd588e779c5737d70e4e47158dafab7945b026b2bb34454cc47741815459b068", + "vendor/tzdata/zoneinfo/Europe/Podgorica": "a8c964f3eaa7a209d9a650fb16c68c003e9a5fc62ffbbb10fa849d54fb3662d6", + "vendor/tzdata/zoneinfo/Europe/Prague": "a6e930e3375cdcb51f7d8a74885aff89fd14b861ebb75cb339d0f91c16c1469a", + "vendor/tzdata/zoneinfo/Europe/Riga": "3d4f1a99ebfef1756f97807f25438e38cd687d231ba2da7edcc3c63c7a4fa13c", + "vendor/tzdata/zoneinfo/Europe/Rome": "86bd26a06fe3057b36cf29dd7a338f2524aff8116ef08d005aa2114ea6122869", + "vendor/tzdata/zoneinfo/Europe/Samara": "55ceb40097bed3e6fca6b362170653512d5b09b5b1c6e1279cd720a7c6244116", + "vendor/tzdata/zoneinfo/Europe/San_Marino": "86bd26a06fe3057b36cf29dd7a338f2524aff8116ef08d005aa2114ea6122869", + "vendor/tzdata/zoneinfo/Europe/Sarajevo": "a8c964f3eaa7a209d9a650fb16c68c003e9a5fc62ffbbb10fa849d54fb3662d6", + "vendor/tzdata/zoneinfo/Europe/Saratov": "d1f3777951557b01be0d2564f71240043401d52fcdca7dfb6c73a38f95fc066d", + "vendor/tzdata/zoneinfo/Europe/Simferopol": "cb63726dff4b19536a35d5bf18f4be3480d12eb8b21ffa72c4aa53d339804cae", + "vendor/tzdata/zoneinfo/Europe/Skopje": "a8c964f3eaa7a209d9a650fb16c68c003e9a5fc62ffbbb10fa849d54fb3662d6", + "vendor/tzdata/zoneinfo/Europe/Sofia": "2d08c2f8e2642f84f365ca83f895287c3020d7ea89ba2ff6462e84a228b632e4", + "vendor/tzdata/zoneinfo/Europe/Stockholm": "a7fd9932d785d4d690900b834c3563c1810c1cf2e01711bcc0926af6c0767cb7", + "vendor/tzdata/zoneinfo/Europe/Tallinn": "47ac917cfa8448e61059fb659dc0d6a3f7d06a4eb579e88440ac20fc2f82ed6f", + "vendor/tzdata/zoneinfo/Europe/Tirane": "23e6a501359177c99f4a0be7af774dfc5f6f6d307ae9a96fcf6190a342d46cf7", + "vendor/tzdata/zoneinfo/Europe/Tiraspol": "439e1ca44e245387148c1141d7d7c5e84bcca73188ff85351a126c8deea0e12e", + "vendor/tzdata/zoneinfo/Europe/Ulyanovsk": "daf2b45da86d07f74a8c30d771c8cc8db4366c039f2837baeae303aad8f31e6e", + "vendor/tzdata/zoneinfo/Europe/Uzhgorod": "0589e80ddecebf9d3077898c12975d2be7393df2856ee9926c534763e1e26bf2", + "vendor/tzdata/zoneinfo/Europe/Vaduz": "199062b1c30cfeb2375ec84c56df52be51891986a6293b7a124d3a62509f45e9", + "vendor/tzdata/zoneinfo/Europe/Vatican": "86bd26a06fe3057b36cf29dd7a338f2524aff8116ef08d005aa2114ea6122869", + "vendor/tzdata/zoneinfo/Europe/Vienna": "abcfd4176dfe287a9cd9acb88eed2a4f54ee052a514e7941ee2eaf125938789c", + "vendor/tzdata/zoneinfo/Europe/Vilnius": "857befd4f6909dd6a94fb85dcb03cedfbdfc63766a6d6fe1271f3b921c9a38f3", + "vendor/tzdata/zoneinfo/Europe/Volgograd": "bf73fa88527ead3849a6b54d0f107b6580eb8a6b6c5bb22f422fe026966224e4", + "vendor/tzdata/zoneinfo/Europe/Warsaw": "e88f5a51f168157a41ac2dd8a4ee0e9a879419c84c6122b4771b1a2a33d93a4c", + "vendor/tzdata/zoneinfo/Europe/Zagreb": "a8c964f3eaa7a209d9a650fb16c68c003e9a5fc62ffbbb10fa849d54fb3662d6", + "vendor/tzdata/zoneinfo/Europe/Zaporozhye": "0589e80ddecebf9d3077898c12975d2be7393df2856ee9926c534763e1e26bf2", + "vendor/tzdata/zoneinfo/Europe/Zurich": "199062b1c30cfeb2375ec84c56df52be51891986a6293b7a124d3a62509f45e9", + "vendor/tzdata/zoneinfo/Europe/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Factory": "d32b579ed0a7427316bea260b9ee2675451046bd58c57c679c24f2671860af76", + "vendor/tzdata/zoneinfo/GB": "676541f0b8ad457c744c093f807589adcad909e3fd03f901787d08786eedbd33", + "vendor/tzdata/zoneinfo/GB-Eire": "676541f0b8ad457c744c093f807589adcad909e3fd03f901787d08786eedbd33", + "vendor/tzdata/zoneinfo/GMT": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/GMT+0": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/GMT-0": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/GMT0": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/Greenwich": "dc4a07571b10884e4f4f3450c9d1a1cbf4c03ef53d06ed2e4ea152d9eba5d5d7", + "vendor/tzdata/zoneinfo/HST": "1daa5729aa1e0f32cd44be112d01ad4cc567a9fe76d87dcbb9182be8d2c88ff0", + "vendor/tzdata/zoneinfo/Hongkong": "f4068f73246db97417f73467453564c57d6646ce4909b9fa2536923efcd7eb4f", + "vendor/tzdata/zoneinfo/Iceland": "f3e7fcaa0e9840ff4169d3567d8fb5926644848f4963d7acf92320843c5d486e", + "vendor/tzdata/zoneinfo/Indian/Antananarivo": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Indian/Chagos": "27f692eebb34646d5d3d319ea245f1349a45e0f76cf2ed5cb78f5c46d5fb8226", + "vendor/tzdata/zoneinfo/Indian/Christmas": "cdc8e2c282d8bc9a5e9c3caf2fc45ff4e9e5cd18f5dec8cb873340ad7c584d64", + "vendor/tzdata/zoneinfo/Indian/Cocos": "e89d835c811d4da44aa8b386782ce8828df085aa0ee8f25661a9881d2f00e90c", + "vendor/tzdata/zoneinfo/Indian/Comoro": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Indian/Kerguelen": "94485f0f58f842767ec2db93539d5fc3afb2bdce16673d9e63c0988cccd6438e", + "vendor/tzdata/zoneinfo/Indian/Mahe": "0d9ea5053e83188032a6fb4d301d5db688f43011e5b6b1f917a11b71a0da7b16", + "vendor/tzdata/zoneinfo/Indian/Maldives": "94485f0f58f842767ec2db93539d5fc3afb2bdce16673d9e63c0988cccd6438e", + "vendor/tzdata/zoneinfo/Indian/Mauritius": "47aa5d25a96b1d52b92e518e984b320faebff9ce5af69b4933ec44ef5168f214", + "vendor/tzdata/zoneinfo/Indian/Mayotte": "0783854f52c33ada6b6d2a5d867662f0ae8e15238d2fce7b9ada4f4d319eb466", + "vendor/tzdata/zoneinfo/Indian/Reunion": "0d9ea5053e83188032a6fb4d301d5db688f43011e5b6b1f917a11b71a0da7b16", + "vendor/tzdata/zoneinfo/Indian/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Iran": "452d5a097a6c260fccb4e7b229b4eddca5563f5cac30c515bc89cb73bc615b72", + "vendor/tzdata/zoneinfo/Israel": "9fcde8d584dea0585f5c8727aaf35f48a149e0dbd3a83bf6cef8bca9c14021e3", + "vendor/tzdata/zoneinfo/Jamaica": "a437b1700333aeff53a8b5868d5387c080dc14c2d3e95aa5ce36f901b3669284", + "vendor/tzdata/zoneinfo/Japan": "59a3871430f0d3b93e619fa30a43a41d1e88bdd49ff26f09d0f405a500706f96", + "vendor/tzdata/zoneinfo/Kwajalein": "4be6458ba89d2b30da7a52f2ec346318f783d2cee856e777c4b33164a365064f", + "vendor/tzdata/zoneinfo/Libya": "cf33012d9661e15438fc045ee64e0bfebb2ea8a3fb79d2af56df05ea4be3e453", + "vendor/tzdata/zoneinfo/MET": "b10f9542a8509f0a63ebca78e3d80432dd86b8ea296400280febd9cfa76e8288", + "vendor/tzdata/zoneinfo/MST": "ae11453c21d08984de75f2efec04dc93178a7b4e23c5e52f2098b8bd45ccb547", + "vendor/tzdata/zoneinfo/MST7MDT": "ebcfec58d0b7a92dde0651382b90114996073fa3f679d06aeba2802133849b0f", + "vendor/tzdata/zoneinfo/Mexico/BajaNorte": "af9aea4aee505143fa5e847643c0ffe164190c38411010ac7f0b170f4098a6c8", + "vendor/tzdata/zoneinfo/Mexico/BajaSur": "20dede710f520eaf6c0cdbeefe773fc6e30dd8b1d28aaf17e9842099551ee9a6", + "vendor/tzdata/zoneinfo/Mexico/General": "37dd2bf08f13fce0f707c3b1f4cec4018efbd9c47c8367b0fb4debbd461bd72f", + "vendor/tzdata/zoneinfo/Mexico/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/NZ": "0e06e7e55aedbc92ef5b3d106e7c392ab1628cfd8a428b20e92e99028a0bfbb9", + "vendor/tzdata/zoneinfo/NZ-CHAT": "a67858fcb6fc5787a8e9c2b7c8be8964bd3ce9223f7ad1baac2c9ca6925f4c78", + "vendor/tzdata/zoneinfo/Navajo": "9bb703920eca4b6119e81a105583a4f6ca220651f13b418479ab7cd56c413f3e", + "vendor/tzdata/zoneinfo/PRC": "bf8b7ed82fe6e63e6d98f8cea934eeac901cd16aba85eb5755ce3f8b4289ea8a", + "vendor/tzdata/zoneinfo/PST8PDT": "a7baaa077f0000d45402257cfcee5726a3b1875874b42da9fd674b0d760506f6", + "vendor/tzdata/zoneinfo/Pacific/Apia": "dc70c47c80ab2c87a1ab754bab8febfc38508059e249dfe55e73a3759808ea14", + "vendor/tzdata/zoneinfo/Pacific/Auckland": "0e06e7e55aedbc92ef5b3d106e7c392ab1628cfd8a428b20e92e99028a0bfbb9", + "vendor/tzdata/zoneinfo/Pacific/Bougainville": "aea767d58e0749aaf1faf8cf934d25b0735f863dc842028256202cba6b8dfc86", + "vendor/tzdata/zoneinfo/Pacific/Chatham": "a67858fcb6fc5787a8e9c2b7c8be8964bd3ce9223f7ad1baac2c9ca6925f4c78", + "vendor/tzdata/zoneinfo/Pacific/Chuuk": "683001055b6ef9dc9d88734e0eddd1782f1c3643b7c13a75e9cf8e9052006e19", + "vendor/tzdata/zoneinfo/Pacific/Easter": "13054cef85e3b1ba0f5712bd6d699d7789d3aedbdab0fd7394b771acc07f61a1", + "vendor/tzdata/zoneinfo/Pacific/Efate": "2e25ffad37e2a5087f567a9bfe6ece1b1c81b720140bd5003552875292e809c5", + "vendor/tzdata/zoneinfo/Pacific/Enderbury": "a23386fa8aa2db91ce9d8e811616afff76e65a0d4b0c82d3e2ffa4c4e155baa2", + "vendor/tzdata/zoneinfo/Pacific/Fakaofo": "51ff3378c2f65fc7683e0f025fea7498c18ff883a3eda1c031eed42c3e648710", + "vendor/tzdata/zoneinfo/Pacific/Fiji": "ba608d86d4ee0738935e77be580c73bd8bc62aa6714d8393c0afad261621e0c4", + "vendor/tzdata/zoneinfo/Pacific/Funafuti": "09035620bd831697a3e9072f82de34cfca5e912d50c8da547739aa2f28fb6d8e", + "vendor/tzdata/zoneinfo/Pacific/Galapagos": "6752893d94af3bc33f3dacbd58b70d031ce3a3c8a63eb43b1675cd3977d997c7", + "vendor/tzdata/zoneinfo/Pacific/Gambier": "c8887cea18e90e4d704564d525138e1aa9fdb6473b7bdfceeb3371aacfb00683", + "vendor/tzdata/zoneinfo/Pacific/Guadalcanal": "522f0f374b61e2c6f5fa7d19f1c7acccd09e4a213462ee3b42c90d32bf2bf18c", + "vendor/tzdata/zoneinfo/Pacific/Guam": "8b9ede33ab32ae2505bc06eb5402e7ce20b0fc8e2510dcb305c25d39a1fbd725", + "vendor/tzdata/zoneinfo/Pacific/Honolulu": "1daa5729aa1e0f32cd44be112d01ad4cc567a9fe76d87dcbb9182be8d2c88ff0", + "vendor/tzdata/zoneinfo/Pacific/Johnston": "1daa5729aa1e0f32cd44be112d01ad4cc567a9fe76d87dcbb9182be8d2c88ff0", + "vendor/tzdata/zoneinfo/Pacific/Kanton": "a23386fa8aa2db91ce9d8e811616afff76e65a0d4b0c82d3e2ffa4c4e155baa2", + "vendor/tzdata/zoneinfo/Pacific/Kiritimati": "71454698c44182595fb982775f4074ce0d017fe2cfa3d97b2dee63bbcf36771e", + "vendor/tzdata/zoneinfo/Pacific/Kosrae": "a5030b2578a5ca03e19649b48c2a3926e566a6660980b21d89357178fe7d6448", + "vendor/tzdata/zoneinfo/Pacific/Kwajalein": "4be6458ba89d2b30da7a52f2ec346318f783d2cee856e777c4b33164a365064f", + "vendor/tzdata/zoneinfo/Pacific/Majuro": "09035620bd831697a3e9072f82de34cfca5e912d50c8da547739aa2f28fb6d8e", + "vendor/tzdata/zoneinfo/Pacific/Marquesas": "8a5a6b911be7f8dd578e9b5223fd19c148deba890ffb997ae2e2a3441a74931c", + "vendor/tzdata/zoneinfo/Pacific/Midway": "650d918751366590553063cd681592fdca8a09957e0ce2c18d6697ec385ef796", + "vendor/tzdata/zoneinfo/Pacific/Nauru": "c1a85938d8eb78d026630850d8259d28c004dd2566e12d9a62f319a9c0254987", + "vendor/tzdata/zoneinfo/Pacific/Niue": "f1659e6ed8029eb3012a3b8b3446045a592d348da8a769242a093455ccfc19a3", + "vendor/tzdata/zoneinfo/Pacific/Norfolk": "bcbf06e96e4249c62aa7bea0d1bd7950f2181f0d8bb7ad2a3a4b47505edc683b", + "vendor/tzdata/zoneinfo/Pacific/Noumea": "7b35329fb0185816e5ad96d2b6522d258bbb5c83422e28a1ac205907e065f90c", + "vendor/tzdata/zoneinfo/Pacific/Pago_Pago": "650d918751366590553063cd681592fdca8a09957e0ce2c18d6697ec385ef796", + "vendor/tzdata/zoneinfo/Pacific/Palau": "5642d1b0a514557a37ceb8405e7f6233ea4ac926c62157f35a8a290e199c78c0", + "vendor/tzdata/zoneinfo/Pacific/Pitcairn": "00987aa252715d0cc231628e139c9ee231df820d5503ef7e80267931bad7ffc1", + "vendor/tzdata/zoneinfo/Pacific/Pohnpei": "522f0f374b61e2c6f5fa7d19f1c7acccd09e4a213462ee3b42c90d32bf2bf18c", + "vendor/tzdata/zoneinfo/Pacific/Ponape": "522f0f374b61e2c6f5fa7d19f1c7acccd09e4a213462ee3b42c90d32bf2bf18c", + "vendor/tzdata/zoneinfo/Pacific/Port_Moresby": "683001055b6ef9dc9d88734e0eddd1782f1c3643b7c13a75e9cf8e9052006e19", + "vendor/tzdata/zoneinfo/Pacific/Rarotonga": "27a6b698ead3a786ec64da2f8f71e324af40549f3d3e1744a5030c543fff8b5f", + "vendor/tzdata/zoneinfo/Pacific/Saipan": "8b9ede33ab32ae2505bc06eb5402e7ce20b0fc8e2510dcb305c25d39a1fbd725", + "vendor/tzdata/zoneinfo/Pacific/Samoa": "650d918751366590553063cd681592fdca8a09957e0ce2c18d6697ec385ef796", + "vendor/tzdata/zoneinfo/Pacific/Tahiti": "22f72cd3886d8711108f523fe9a00273bd01cb4966c65be180615887ce377b5e", + "vendor/tzdata/zoneinfo/Pacific/Tarawa": "09035620bd831697a3e9072f82de34cfca5e912d50c8da547739aa2f28fb6d8e", + "vendor/tzdata/zoneinfo/Pacific/Tongatapu": "9a31a33525004dfc34c8b181d33b0bc73dff2f5b96c4f00d30bf0ae0741020c6", + "vendor/tzdata/zoneinfo/Pacific/Truk": "683001055b6ef9dc9d88734e0eddd1782f1c3643b7c13a75e9cf8e9052006e19", + "vendor/tzdata/zoneinfo/Pacific/Wake": "09035620bd831697a3e9072f82de34cfca5e912d50c8da547739aa2f28fb6d8e", + "vendor/tzdata/zoneinfo/Pacific/Wallis": "09035620bd831697a3e9072f82de34cfca5e912d50c8da547739aa2f28fb6d8e", + "vendor/tzdata/zoneinfo/Pacific/Yap": "683001055b6ef9dc9d88734e0eddd1782f1c3643b7c13a75e9cf8e9052006e19", + "vendor/tzdata/zoneinfo/Pacific/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/Poland": "e88f5a51f168157a41ac2dd8a4ee0e9a879419c84c6122b4771b1a2a33d93a4c", + "vendor/tzdata/zoneinfo/Portugal": "44d2f6cf84737e6a1e0daf914109e94256beca40b40c9a11b7a04e8bddaee4ec", + "vendor/tzdata/zoneinfo/ROC": "a04c2c72f4f76a83178d036dd97d157ee1f32e478e44dda7a5c10923687ee6cf", + "vendor/tzdata/zoneinfo/ROK": "64a70b6fbcc9b65e762dbd25eb89b6f40c137146edc8dbd4d081eafacdab78de", + "vendor/tzdata/zoneinfo/Singapore": "0954b2d9a301d94f4348024606a71bbcb2fa24d3cd3709f5bc8bca605039785d", + "vendor/tzdata/zoneinfo/Turkey": "2a7163b16b94806f69991348e7d0a60c46eb61b1f0305f5f4b83f613db10806f", + "vendor/tzdata/zoneinfo/UCT": "fddce1e648a1732ac29afd9a16151b2973cdf082e7ec0c690f7e42be6b598b93", + "vendor/tzdata/zoneinfo/US/Alaska": "77ca0c22962f06998bce5e48d81cb865a14466c83ff5dc607eaa483344058bf6", + "vendor/tzdata/zoneinfo/US/Aleutian": "abfb1980e20d5f84ec5fd881c7580d77a5c6c019f30a383aaa97404212b489e0", + "vendor/tzdata/zoneinfo/US/Arizona": "ae11453c21d08984de75f2efec04dc93178a7b4e23c5e52f2098b8bd45ccb547", + "vendor/tzdata/zoneinfo/US/Central": "c27b739ff46a7df0594e120d725b439217e11e44ea9a50cdc49130383b5482e7", + "vendor/tzdata/zoneinfo/US/East-Indiana": "e678f42a13efbd7be0f26a9ce53e04b1c28a582eab05611cb01c16836432f07b", + "vendor/tzdata/zoneinfo/US/Eastern": "d7f2206b3a45989fc9ad63d558922532fa7352280d5f87176bf1db79cb1d1fa9", + "vendor/tzdata/zoneinfo/US/Hawaii": "1daa5729aa1e0f32cd44be112d01ad4cc567a9fe76d87dcbb9182be8d2c88ff0", + "vendor/tzdata/zoneinfo/US/Indiana-Starke": "2890b35dcb7c093308b552d82d8781a8ce9a4fa6f9de058283a6836ec1f9f282", + "vendor/tzdata/zoneinfo/US/Michigan": "23817c32df67c77f0017a0feb2d798b2405afc71ceea3294d7e5b4c9116be740", + "vendor/tzdata/zoneinfo/US/Mountain": "9bb703920eca4b6119e81a105583a4f6ca220651f13b418479ab7cd56c413f3e", + "vendor/tzdata/zoneinfo/US/Pacific": "200d05754f6d83a371cf408d7085125797657b3b0bebeba1e508cffe86a3e5c8", + "vendor/tzdata/zoneinfo/US/Samoa": "650d918751366590553063cd681592fdca8a09957e0ce2c18d6697ec385ef796", + "vendor/tzdata/zoneinfo/US/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/UTC": "fddce1e648a1732ac29afd9a16151b2973cdf082e7ec0c690f7e42be6b598b93", + "vendor/tzdata/zoneinfo/Universal": "fddce1e648a1732ac29afd9a16151b2973cdf082e7ec0c690f7e42be6b598b93", + "vendor/tzdata/zoneinfo/W-SU": "ed2e0a099fb446b2416683438d3f56f9fc5a62a16c7549a7f59cbc935b364c8a", + "vendor/tzdata/zoneinfo/WET": "44d2f6cf84737e6a1e0daf914109e94256beca40b40c9a11b7a04e8bddaee4ec", + "vendor/tzdata/zoneinfo/Zulu": "fddce1e648a1732ac29afd9a16151b2973cdf082e7ec0c690f7e42be6b598b93", + "vendor/tzdata/zoneinfo/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "vendor/tzdata/zoneinfo/iso3166.tab": "837c80785080c8433fd9d4ea87e78f161ac7a40389301c5153d4f90198baeb2a", + "vendor/tzdata/zoneinfo/leapseconds": "8f066f297a37a798d5103321957c5f5f4f1c9dda0f3d05db30b77bec3491659e", + "vendor/tzdata/zoneinfo/tzdata.zi": "a37ece24ccd153ebad2c458f430023eb6811f6c6648c77096442a22e3b5065cf", + "vendor/tzdata/zoneinfo/zone.tab": "e2e8e31c4e10f44576c79345e76060591dbb3eef6ce14e006afc8a373caa9593", + "vendor/tzdata/zoneinfo/zone1970.tab": "5f23781702bf51408ff1581daa109ab3b9257fb433b1554e579d92172892c0cf", + "vendor/tzdata/zoneinfo/zonenow.tab": "7f9d1c11445af7a17862c20a9081226d31a09a1730e270ff59a34c8d2b4c7f7f", + "vendor/tzdata/zones": "28d8f3eb25839095fa8a209997bb20e822ebfbebe21e60edc483a3d5e20dc881" + }, + "version": "3.5.0" +} diff --git a/scripts/_license_gate.py b/scripts/_license_gate.py index 346a57c..1776266 100644 --- a/scripts/_license_gate.py +++ b/scripts/_license_gate.py @@ -4,16 +4,21 @@ 本锁只是授权边界的可见表达,真正的约束在 LICENSE.md 的法律条款—— 绕过、篡改、移除软锁或水印,即构成对授权的违反。 -母版(技能开发目录)无 `data/.license.json`,本模块全部放行; +母版(技能开发目录)无 `data/.license.json` 且无公众版标记,本模块全部放行; 由 `tools/make_license_copy.py` 生成的定制副本带该状态文件, 按剩余次数与到期日限制使用,并以签名防止手工篡改状态文件。 +公众版副本(`tools/make_license_copy.py --public-edition`)不带授权状态文件, +只带标记 `data/.public_edition.json`;首次 check 时就地签发个人副本 +(初始 20 次、不限期、授权对象 public-personal),之后按定制副本同样校验。 + 退出码 4 = 授权不可用(次数用尽 / 已过期 / 状态文件被篡改)。 """ from __future__ import annotations import hashlib import json +import secrets from datetime import date from pathlib import Path @@ -22,6 +27,11 @@ _ENABLED = True # 软锁总开关:False = 完全放行 _SALT = "lingyao-miaojie-ziping-eightchar" _COMPANY = "四川灵爻妙解文化传播有限公司" STATE_REL = Path("data") / ".license.json" +PUBLIC_MARKER_REL = Path("data") / ".public_edition.json" + +# 公众版首启签发的个人副本参数 +PUBLIC_LICENSEE = "public-personal" +PUBLIC_INITIAL_USES = 20 def _state_path(root: Path) -> Path: @@ -55,13 +65,28 @@ def _deny(reason: str, st: dict) -> str: f"如需续期或正式授权,请联系{_COMPANY}。") +def _issue_public_personal(root: Path) -> None: + """公众版首启:就地签发个人副本(初始 20 次、不限期)。""" + write_state(root, + copy_id=f"LY-{date.today():%Y%m%d}-{secrets.token_hex(2).upper()}", + licensee=PUBLIC_LICENSEE, + max_uses=PUBLIC_INITIAL_USES, + expires_at=None) + + def check(root: Path) -> str | None: """返回 None 表示放行;返回字符串表示拒跑原因(由调用方打印到 stderr,退出码 4)。""" if not _ENABLED: return None st = _load(root) if st is None: - return None # 母版无状态文件,不锁 + if (root / PUBLIC_MARKER_REL).is_file(): + _issue_public_personal(root) # 公众版首启:就地签发个人副本 + st = _load(root) + else: + return None # 母版无状态文件,不锁 + if st is None: # 签发失败(如磁盘只读)按母版放行,不阻断使用 + return None if st.get("sig") != _sig(st): return _deny("授权状态校验失败(授权文件被改动过)", st) exp = st.get("expires_at") @@ -95,9 +120,35 @@ def write_state(root: Path, *, copy_id: str, licensee: str, "expires_at": expires_at, "max_uses": max_uses, "remaining_uses": max_uses, + "granted_archives": [], } st["sig"] = _sig(st) p = _state_path(root) p.parent.mkdir(parents=True, exist_ok=True) p.write_text(json.dumps(st, ensure_ascii=False, indent=2), encoding="utf-8") return st + + +def grant_uses(root: Path, n: int, archive_hash: str) -> bool: + """脱敏档案共建的计励:推送成功后给本副本加 n 次。 + + 同一盘(archive_hash)只计一次:已在已计励列表中则返回 False 且不加次。 + 母版(无授权状态文件)不计励,直接返回 True。 + 状态文件签名校验失败(被篡改)时拒绝计励,返回 False。 + """ + if not _ENABLED: + return True + st = _load(root) + if st is None: + return True # 母版无锁,不计 + if st.get("sig") != _sig(st): + return False + granted = st.setdefault("granted_archives", []) + if archive_hash in granted: + return False + st["remaining_uses"] = int(st.get("remaining_uses", 0)) + int(n) + granted.append(archive_hash) + st["sig"] = _sig(st) + _state_path(root).write_text( + json.dumps(st, ensure_ascii=False, indent=2), encoding="utf-8") + return True diff --git a/scripts/cast_chart.py b/scripts/cast_chart.py index c9aca92..72886ca 100644 --- a/scripts/cast_chart.py +++ b/scripts/cast_chart.py @@ -129,6 +129,18 @@ def main() -> int: # L2 渲染:stdout 只出 Markdown print(render(chart)) _gate.consume(Path(__file__).resolve().parents[1]) + + # 自更新提示:只读本地缓存往 stderr 打一行;缓存过期则后台线程刷新, + # 主流程不等它(用当次缓存)。任何异常静默,绝不影响 stdout 命盘契约。 + try: + import self_update as _su + _root = Path(__file__).resolve().parents[1] + _msg = _su.notify_message(_root) + if _msg: + print(_msg, file=sys.stderr) + _su.refresh_cache_async(_root) + except Exception: + pass return 0 except Exception: print("ERROR: 排盘内部错误。请把以下信息原样报告给用户," diff --git a/scripts/self_update.py b/scripts/self_update.py new file mode 100644 index 0000000..d9575e0 --- /dev/null +++ b/scripts/self_update.py @@ -0,0 +1,386 @@ +#!/usr/bin/env python3 +"""技能自更新:版本检查、异步提示、应用更新。 + +用法: + python scripts/self_update.py --check 检查更新(24 小时缓存,重复检查不拉网络) + python scripts/self_update.py --notify 只读缓存打印提示,绝不碰网络(供 cast_chart 调用) + python scripts/self_update.py --apply 下载 zipball → 按 manifest 逐文件校验 → 同步本地 + +退出码(--apply):0 成功;2 无需更新或配置缺失;3 失败(本地原样不动)。 + +远端双线路 failover:GitHub 优先,Gitea 兜底。HTTPS_PROXY/HTTP_PROXY 等 +代理环境变量由 urllib 默认读取、自动生效。测试或自建场景可用环境变量 +ZIPEC_VERSION_URLS / ZIPEC_ZIPBALL_URLS(逗号分隔)整体覆盖远端地址, +支持 file:// 形式。 +""" +import argparse +import hashlib +import json +import os +import shutil +import sys +import tempfile +import threading +import time +import urllib.request +import zipfile +from pathlib import Path + +# ---- 远端配置(GitHub 优先,Gitea 兜底)---- +GITHUB_VERSION_URL = "https://raw.githubusercontent.com/mxiaonian/ZiPingEightChar/main/VERSION" +GITHUB_ZIPBALL_URL = "https://codeload.github.com/mxiaonian/ZiPingEightChar/zip/refs/heads/main" +# Gitea 占位地址:由授权方填写实际自建 Gitea 地址后启用 +GITEA_VERSION_URL = "https://gitea.example.com/owner/ZiPingEightChar/raw/branch/main/VERSION" +GITEA_ZIPBALL_URL = "https://gitea.example.com/owner/ZiPingEightChar/archive/main.zip" + +CACHE_REL = "data/.update_check.json" +CACHE_TTL_SECONDS = 24 * 3600 +NETWORK_TIMEOUT = 3 + +# 更新管辖区之外:同步时绝不覆盖、绝不删除(与 tools/build_manifest.py 排除表一致) +PRESERVE_FILES = {"data/.license.json", "data/.update_check.json"} +PRESERVE_DIRS = {".git", "memory/archives", "share/pending", "share/pushed"} +PRESERVE_DIR_NAMES = {".git", "__pycache__", ".pytest_cache"} +PRESERVE_FILE_NAMES = {".DS_Store"} +PRESERVE_SUFFIXES = {".pyc"} + + +def repo_root() -> Path: + return Path(__file__).resolve().parents[1] + + +def _version_urls() -> list: + env = os.environ.get("ZIPEC_VERSION_URLS") + if env: + return [u.strip() for u in env.split(",") if u.strip()] + return [GITHUB_VERSION_URL, GITEA_VERSION_URL] + + +def _zipball_urls() -> list: + env = os.environ.get("ZIPEC_ZIPBALL_URLS") + if env: + return [u.strip() for u in env.split(",") if u.strip()] + return [GITHUB_ZIPBALL_URL, GITEA_ZIPBALL_URL] + + +def _fetch_text(url: str, timeout: int = NETWORK_TIMEOUT) -> str: + with urllib.request.urlopen(url, timeout=timeout) as r: + return r.read().decode("utf-8") + + +def _download(url: str, dest: Path, timeout: int = NETWORK_TIMEOUT) -> None: + with urllib.request.urlopen(url, timeout=timeout) as r: + with open(dest, "wb") as fh: + shutil.copyfileobj(r, fh) + + +def parse_version(text: str) -> tuple: + parts = text.strip().split(".") + if not parts or any(not p.isdigit() for p in parts): + raise ValueError(f"无法解析版本号: {text!r}") + return tuple(int(p) for p in parts) + + +def read_local_version(root: Path): + try: + return (root / "VERSION").read_text(encoding="utf-8").strip() + except OSError: + return None + + +def _sha256(path: Path) -> str: + h = hashlib.sha256() + with open(path, "rb") as fh: + for chunk in iter(lambda: fh.read(1 << 20), b""): + h.update(chunk) + return h.hexdigest() + + +# ---- 缓存(data/.update_check.json)---- + +def load_cache(root: Path): + try: + return json.loads((root / CACHE_REL).read_text(encoding="utf-8")) + except Exception: + return None + + +def _write_cache(root: Path, remote_version, local_version) -> dict: + update_available = False + if remote_version and local_version: + try: + update_available = parse_version(remote_version) > parse_version(local_version) + except ValueError: + update_available = False + cache = { + "checked_at": time.time(), + "checked_at_iso": time.strftime("%Y-%m-%dT%H:%M:%S%z"), + "local_version": local_version, + "remote_version": remote_version, + "update_available": update_available, + } + p = root / CACHE_REL + p.parent.mkdir(parents=True, exist_ok=True) + p.write_text(json.dumps(cache, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + return cache + + +def _cache_fresh(cache) -> bool: + try: + return time.time() - float(cache.get("checked_at", 0)) < CACHE_TTL_SECONDS + except Exception: + return False + + +def cache_stale(root: Path) -> bool: + cache = load_cache(root) + return not _cache_fresh(cache) + + +def _fetch_remote_version(): + """双线 failover:按序尝试各源,返回第一个成功的 VERSION 文本;全失败返回 None。""" + for url in _version_urls(): + try: + text = _fetch_text(url).strip() + if text: + return text + except Exception: + continue + return None + + +# ---- --check / --notify ---- + +def _print_check_result(cache, note: str = "") -> None: + if cache.get("update_available") and cache.get("remote_version"): + print(f"有新版本 {cache['remote_version']}(当前 {cache.get('local_version') or '?'}){note}") + else: + print(f"已是最新({cache.get('local_version') or cache.get('remote_version') or '?'}){note}") + + +def cmd_check(root: Path, force: bool = False) -> int: + cache = load_cache(root) + if not force and _cache_fresh(cache): + _print_check_result(cache, note="(24 小时内已检查过)") + return 0 + remote = _fetch_remote_version() + if remote is None: + if cache: + _print_check_result(cache, note="(网络不可达,沿用上次结果)") + return 0 + print("检查失败:远端 VERSION 不可达", file=sys.stderr) + return 3 + _print_check_result(_write_cache(root, remote, read_local_version(root))) + return 0 + + +def notify_message(root: Path): + """只读缓存、绝不碰网络:有可更新版本时返回一行提示,否则返回 None。""" + cache = load_cache(root) + if not cache or not cache.get("update_available"): + return None + ver = cache.get("remote_version") or "?" + return f"技能有新版本 {ver},运行 `python scripts/self_update.py --apply` 可更新" + + +def cmd_notify(root: Path) -> int: + msg = notify_message(root) + if msg: + print(msg, file=sys.stderr) + return 0 + + +def refresh_cache(root: Path) -> None: + """同步刷新缓存;任何失败都静默(供后台线程调用)。""" + try: + remote = _fetch_remote_version() + if remote is not None: + _write_cache(root, remote, read_local_version(root)) + except Exception: + pass + + +def refresh_cache_async(root: Path) -> None: + """缓存过期(>24h)才起后台线程拉一次远端 VERSION;主流程不等它。""" + try: + if not cache_stale(root): + return + threading.Thread(target=refresh_cache, args=(root,), daemon=True).start() + except Exception: + pass + + +# ---- --apply ---- + +def _rel(root: Path, p: Path) -> str: + return p.relative_to(root).as_posix() + + +def _preserved_dir(root: Path, d: Path) -> bool: + if d.name in PRESERVE_DIR_NAMES: + return True + rel = _rel(root, d) + return any(rel == ex or rel.startswith(ex + "/") for ex in PRESERVE_DIRS) + + +def _preserved_file(root: Path, f: Path) -> bool: + rel = _rel(root, f) + if rel in PRESERVE_FILES or f.name in PRESERVE_FILE_NAMES: + return True + if f.suffix in PRESERVE_SUFFIXES: + return True + # 位于保留目录(或其子目录)内的文件一律保留 + parts = rel.split("/")[:-1] + for i, name in enumerate(parts): + if name in PRESERVE_DIR_NAMES or "/".join(parts[: i + 1]) in PRESERVE_DIRS: + return True + return False + + +def _safe_extract(zf: zipfile.ZipFile, dest: Path) -> None: + dest_real = os.path.realpath(dest) + for info in zf.infolist(): + target = os.path.realpath(dest / info.filename) + if target != dest_real and not target.startswith(dest_real + os.sep): + raise ValueError(f"zip 内含越界路径: {info.filename!r}") + zf.extractall(dest) + + +def _find_source_root(extract_dir: Path): + """zipball 通常带一层顶层目录(GitHub: -main/;Gitea: /)。""" + if (extract_dir / "manifest.json").is_file(): + return extract_dir + hits = [d for d in sorted(extract_dir.iterdir()) + if d.is_dir() and (d / "manifest.json").is_file()] + return hits[0] if len(hits) == 1 else None + + +def _verify_manifest(src: Path, files: dict): + """逐文件校验 sha256;返回错误信息列表(空 = 全部通过)。只校验,不动本地。""" + errors = [] + for rel, want in files.items(): + f = src / rel + if not f.is_file(): + errors.append(f"缺失 {rel}") + elif _sha256(f) != want: + errors.append(f"校验不符 {rel}") + return errors + + +def _sync(root: Path, src: Path, files: dict) -> None: + managed = set(files) | {"manifest.json", "VERSION"} + copied = deleted = 0 + for rel in sorted(managed - {"VERSION"}): # VERSION 最后写 + s = src / rel + if not s.is_file(): + continue + d = root / rel + d.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(s, d) + copied += 1 + # 删除本地多余但清单不含的文件(仅清单管辖区;保留区一律不动) + for dirpath, dirnames, filenames in os.walk(root, topdown=False): + d = Path(dirpath) + for name in filenames: + f = d / name + if _preserved_file(root, f) or _rel(root, f) in managed: + continue + f.unlink() + deleted += 1 + if d != root and not _preserved_dir(root, d) and not any(d.iterdir()): + d.rmdir() + # 最后写 VERSION + if (src / "VERSION").is_file(): + shutil.copy2(src / "VERSION", root / "VERSION") + print(f"同步完成:写入 {copied} 个文件,清理 {deleted} 个多余文件") + + +def cmd_apply(root: Path) -> int: + local = read_local_version(root) + if local is None: + print("配置缺失:本地没有 VERSION 文件", file=sys.stderr) + return 2 + print(f"本地版本 {local},正在获取远端版本…") + remote = _fetch_remote_version() + if remote is None: + print("失败:远端 VERSION 不可达(本地未改动)", file=sys.stderr) + return 3 + print(f"远端版本 {remote}") + try: + if parse_version(remote) <= parse_version(local): + print("已是最新,无需更新") + return 2 + except ValueError as e: + print(f"失败:{e}(本地未改动)", file=sys.stderr) + return 3 + + with tempfile.TemporaryDirectory(prefix="zipec-update-") as td: + zip_path = Path(td) / "remote.zip" + ok = False + for url in _zipball_urls(): + try: + print(f"下载 {url} …") + _download(url, zip_path) + ok = True + break + except Exception as e: + print(f" 下载失败({e}),尝试下一源") + if not ok: + print("失败:所有更新源均不可达(本地未改动)", file=sys.stderr) + return 3 + + try: + extract_dir = Path(td) / "src" + extract_dir.mkdir() + with zipfile.ZipFile(zip_path) as zf: + _safe_extract(zf, extract_dir) + except Exception as e: + print(f"失败:zip 解压异常({e})(本地未改动)", file=sys.stderr) + return 3 + + src = _find_source_root(extract_dir) + if src is None: + print("失败:远端包内找不到 manifest.json(本地未改动)", file=sys.stderr) + return 3 + try: + manifest = json.loads((src / "manifest.json").read_text(encoding="utf-8")) + files = manifest["files"] + except Exception as e: + print(f"失败:manifest.json 无法解析({e})(本地未改动)", file=sys.stderr) + return 3 + + errors = _verify_manifest(src, files) + if errors: + print(f"失败:{len(errors)} 个文件与清单不符,已中止(本地未改动)", + file=sys.stderr) + for e in errors[:5]: + print(f" {e}", file=sys.stderr) + return 3 + print(f"清单校验通过({len(files)} 个文件),开始同步…") + _sync(root, src, files) + + try: + _write_cache(root, remote, remote) + except Exception: + pass + print(f"更新完成:{local} → {remote}") + return 0 + + +def main() -> int: + ap = argparse.ArgumentParser(prog="self_update.py", description="技能自更新") + g = ap.add_mutually_exclusive_group(required=True) + g.add_argument("--check", action="store_true", help="检查更新(24 小时缓存)") + g.add_argument("--notify", action="store_true", help="只读缓存打印提示,不碰网络") + g.add_argument("--apply", action="store_true", help="校验并应用更新") + a = ap.parse_args() + root = repo_root() + if a.check: + return cmd_check(root) + if a.notify: + return cmd_notify(root) + return cmd_apply(root) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/share_export.py b/scripts/share_export.py new file mode 100644 index 0000000..a82b40e --- /dev/null +++ b/scripts/share_export.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python3 +"""脱敏档案导出 —— 从 memory 档案生成结构化脱敏包(JSON)到 share/pending/。 + +用法: + python share_export.py --archive memory/archives/庚午辛巳己卯戊辰-男-a1b2c3.md + python share_export.py --birth "1990-05-14 08:30" --place "四川省成都市" --gender 男 + +脱敏规格(见 share/README.md):不含姓名;出生信息只保留年月日与时辰(不留分钟 +与钟表时间);地域只保留到省级;事件一律类目化;正文自由文本(归纳、盘面细节、 +反馈原文)不入包。盘 hash = sha1(四柱+出生地) 前 8 位,用于去重与撤回。 + +完整度门槛:性别/四柱/大运齐全 + 至少一条反馈事件(任意核实状态); +不满足拒绝导出,退出码 2 并说明缺什么。退出码:0 成功;2 不可用/不完整;3 内部错误。 +""" +from __future__ import annotations + +import argparse +import hashlib +import json +import re +import sys +import traceback +from datetime import datetime +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +import _memory_store as store + +SCHEMA = "share/v1" +PLACEHOLDERS = {"(无)", "(未记录)", "无", "未记录"} + +# 事件/关注方向类目化:首个命中的类目生效,都不命中归「其他」 +CATEGORIES: list[tuple[str, tuple[str, ...]]] = [ + ("婚姻", ("婚姻", "结婚", "离婚", "配偶", "夫妻", "婚变", "再婚")), + ("感情", ("感情", "恋爱", "桃花", "对象", "分手", "复合")), + ("事业", ("事业", "工作", "升职", "跳槽", "调动", "失业", "创业", "辞职", "职务", "官非")), + ("财运", ("财运", "破财", "投资", "收入", "赚钱", "欠债", "债务", "置业", "买房")), + ("健康", ("健康", "生病", "手术", "伤病", "身体", "住院", "疾病", "意外")), + ("学业", ("学业", "考试", "升学", "考研", "高考", "留学", "读书")), + ("六亲", ("父亲", "母亲", "父母", "子女", "孩子", "兄弟", "姐妹", "六亲", "亲人", "丧")), + ("流年运势", ("流年", "运势", "大运", "运程")), +] + +_PROVINCES = ( + "北京市", "天津市", "上海市", "重庆市", + "河北省", "山西省", "辽宁省", "吉林省", "黑龙江省", "江苏省", "浙江省", + "安徽省", "福建省", "江西省", "山东省", "河南省", "湖北省", "湖南省", + "广东省", "海南省", "四川省", "贵州省", "云南省", "陕西省", "甘肃省", + "青海省", "台湾省", + "内蒙古自治区", "广西壮族自治区", "西藏自治区", "宁夏回族自治区", + "新疆维吾尔自治区", "香港特别行政区", "澳门特别行政区", +) +_PROVINCE_SHORT = { + "北京": "北京市", "天津": "天津市", "上海": "上海市", "重庆": "重庆市", + "内蒙古": "内蒙古自治区", "广西": "广西壮族自治区", "西藏": "西藏自治区", + "宁夏": "宁夏回族自治区", "新疆": "新疆维吾尔自治区", + "香港": "香港特别行政区", "澳门": "澳门特别行政区", +} + +_STATUS_TAGS = {"【已核实】": "已核实", "【已证伪】": "已证伪", "【未核实】": "未核实"} + + +def _categorize_all(text: str) -> list[str]: + return [cat for cat, keywords in CATEGORIES if any(k in text for k in keywords)] + + +def _categorize(text: str) -> str: + cats = _categorize_all(text) + return cats[0] if cats else "其他" + + +def _province_of(birthplace: str) -> str | None: + """地域脱敏:只保留到省级;识别不出省级则舍弃(宁缺毋滥)。""" + for p in _PROVINCES: + if p in birthplace: + return p + for short, full in _PROVINCE_SHORT.items(): + if birthplace.startswith(short): + return full + m = re.match(r"^(.{2,6}?省)", birthplace) + return m.group(1) if m else None + + +def _section_lines(body: str, heading: str) -> list[str]: + """取档案正文某固定小节(SECTIONS 内)的行,到下一个固定小节或文末。""" + lines = body.splitlines() + bounds = {f"## {s}" for s in store.SECTIONS} - {f"## {heading}"} + start = next((i for i, ln in enumerate(lines) + if ln.strip() == f"## {heading}"), None) + if start is None: + return [] + end = next((i for i in range(start + 1, len(lines)) + if lines[i].strip() in bounds), len(lines)) + return lines[start + 1:end] + + +def _chart_section_lines(body: str, heading: str, nxt: str) -> list[str]: + """取「盘面」内嵌命盘 Markdown 的小节(如 ## 大运 到 ## 小运)。""" + lines = body.splitlines() + start = next((i for i, ln in enumerate(lines) + if ln.strip() == f"## {heading}"), None) + if start is None: + return [] + end = next((i for i in range(start + 1, len(lines)) + if lines[i].strip() == f"## {nxt}"), len(lines)) + return lines[start + 1:end] + + +def _parse_luck(body: str) -> list[dict]: + luck = [] + for ln in _chart_section_lines(body, "大运", "小运"): + m = re.match(r"^-\s*第\s*(\d+)\s*步:(\S{2})([^)]*,(\d{4})\s*年)", ln.strip()) + if m: + luck.append({"seq": int(m.group(1)), "pillar": m.group(2), + "start_year": int(m.group(3))}) + return luck + + +def _parse_focus(body: str) -> list[str]: + cats: list[str] = [] + for ln in _section_lines(body, "主要关注方向"): + t = ln.strip().lstrip("-•· ").strip() + if not t or t in PLACEHOLDERS: + continue + for cat in _categorize_all(t): + if cat not in cats: + cats.append(cat) + return cats + + +def _parse_feedback(body: str) -> list[dict]: + """反馈事件:只取年份、类目、核实状态——反馈原文不入包。""" + events = [] + for ln in _section_lines(body, "反馈与澄清"): + t = ln.strip().lstrip("-•· ").strip() + if not t or t in PLACEHOLDERS: + continue + status = "未核实" + for tag, name in _STATUS_TAGS.items(): + if tag in t: + status = name + break + m = re.search(r"(?:19|20)\d{2}", t) + events.append({"year": int(m.group(0)) if m else None, + "category": _categorize(t), + "status": status}) + return events + + +def chart_hash(pillars: list[str], birthplace: str) -> str: + raw = f"{''.join(pillars)}|{birthplace.strip()}" + return hashlib.sha1(raw.encode("utf-8")).hexdigest()[:8] + + +def build_package(meta: dict, body: str) -> tuple[dict, list[str]]: + """组装脱敏包;返回 (package, 缺失项列表)。package 保证不含姓名/分钟/省以下地域。""" + pillars = meta.get("pillars", []) + if isinstance(pillars, str): + pillars = pillars.split() + pillars = [str(p) for p in pillars] + birthplace = str(meta.get("birthplace", "")) + gender = str(meta.get("gender", "")) + + pkg: dict = {"schema": SCHEMA, + "exported_at": datetime.now().strftime("%Y-%m-%d %H:%M"), + "chart_hash": chart_hash(pillars, birthplace), + "gender": gender or None, + "pillars": pillars, + "luck_pillars": _parse_luck(body), + "focus_categories": _parse_focus(body), + "feedback": _parse_feedback(body)} + + # 出生信息脱敏:只保留年月日与时辰(时支),不留分钟与钟表时间 + m = re.match(r"^(\d{4})-(\d{2})-(\d{2})", str(meta.get("birth_clock", "")).strip()) + if m: + pkg["birth_date"] = f"{m.group(1)}-{m.group(2)}-{m.group(3)}" + if len(pillars) == 4 and len(pillars[3]) == 2: + pkg["birth_shichen"] = pillars[3][1] + province = _province_of(birthplace) + if province: + pkg["region_province"] = province + + missing = [] + if not gender: + missing.append("性别") + if len(pillars) != 4: + missing.append("四柱") + if not pkg["luck_pillars"]: + missing.append("大运序列") + if not pkg["feedback"]: + missing.append("反馈事件(至少一条,任意核实状态)") + return pkg, missing + + +def _find_archive(args) -> Path | None: + if args.archive: + p = Path(args.archive).expanduser().resolve() + return p if p.is_file() else None + root = store.resolve_root(args.memory_root, __file__) + for path in store.iter_archives(root): + meta, _ = store.parse_frontmatter(path.read_text(encoding="utf-8")) + if meta and store.matches(meta, name=args.name, birth=args.birth, + place=args.place, gender=args.gender, + pillars=args.pillars): + return path + return None + + +def main() -> int: + ap = argparse.ArgumentParser( + prog="share_export.py", + description="从 memory 档案导出结构化脱敏包(JSON)到 share/pending/;不含姓名、分钟、省以下地域") + ap.add_argument("--archive", default=None, help="档案文件路径(直接指定)") + ap.add_argument("--name", default=None, help="姓名(检索条件)") + ap.add_argument("--gender", default=None, choices=["男", "女"], help="性别(检索条件)") + ap.add_argument("--birth", default=None, + help='出生时刻,格式 "YYYY-MM-DD HH:MM"(检索条件)') + ap.add_argument("--place", default=None, help="出生地(检索条件)") + ap.add_argument("--pillars", default=None, + help='四柱干支,如 "丁亥 乙巳 庚子 辛巳"(检索条件)') + ap.add_argument("--memory-root", default=None, + help=f"档案根目录(默认技能根 memory/;亦可用环境变量 {store.ENV_VAR})") + ap.add_argument("--share-root", default=None, + help="share/ 目录(默认技能根 share/,测试覆盖用)") + a = ap.parse_args() + + if not a.archive and all(v is None for v in (a.name, a.gender, a.birth, + a.place, a.pillars)): + print("ERROR: 给 --archive <档案路径>,或至少一个检索条件" + "(--name/--birth/--place/--gender/--pillars)。", file=sys.stderr) + return 2 + + try: + arch = _find_archive(a) + if arch is None: + print("ERROR: 未找到匹配档案(先用 scripts/memory_save.py 建档," + "并确认检索条件与档案一致)。", file=sys.stderr) + return 2 + meta, body = store.parse_frontmatter(arch.read_text(encoding="utf-8")) + pkg, missing = build_package(meta, body) + if missing: + print(f"ERROR: 档案完整度不足,拒绝导出。缺:{'、'.join(missing)}。" + f"(性别/四柱/大运齐全 + 至少一条反馈事件才可导出)", file=sys.stderr) + return 2 + + share_root = (Path(a.share_root).expanduser().resolve() if a.share_root + else Path(__file__).resolve().parents[1] / "share") + pending = share_root / "pending" + pending.mkdir(parents=True, exist_ok=True) + out = pending / f"{pkg['chart_hash']}.json" + out.write_text(json.dumps(pkg, ensure_ascii=False, indent=2) + "\n", + encoding="utf-8") + print(out) + return 0 + except SystemExit: + raise + except Exception: + print("ERROR: 导出内部错误。", file=sys.stderr) + traceback.print_exc(file=sys.stderr) + return 3 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/share_push.py b/scripts/share_push.py new file mode 100644 index 0000000..69b1ca0 --- /dev/null +++ b/scripts/share_push.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +"""脱敏包推送 —— 把 share/pending/ 的包 git commit+push 到共建远端。 + +用法:python share_push.py [--root 技能根目录] + +远端取自 share/config.json 的 github_remote / gitea_remote(占位为空则跳过, +由授权方填写;亦可用环境变量 ZIPING_SHARE_GITHUB_REMOTE / +ZIPING_SHARE_GITEA_REMOTE 覆盖)。两个远端逐个尝试,至少一个成功即算成功。 + +推送成功后:调 _license_gate.grant_uses(root, 10, 盘hash) 计励(同一盘只计一次), +并把该包移入 share/pushed/。推送失败保留 pending,退出码 3。 +无 git 或无网络安静失败(不打栈)。 + +退出码:0 至少一包推送成功或无包可推;2 输入不可用;3 推送失败。 +""" +from __future__ import annotations + +import argparse +import json +import os +import shutil +import subprocess +import sys +import tempfile +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +import _license_gate as gate + +GRANT_USES = 10 # 每盘推送成功的计励次数 +ENV_GITHUB = "ZIPING_SHARE_GITHUB_REMOTE" +ENV_GITEA = "ZIPING_SHARE_GITEA_REMOTE" +_GIT_ENV = {**os.environ, "GIT_TERMINAL_PROMPT": "0", "GIT_ASKPASS": "true"} + + +def _git(*args: str, cwd: str | None = None) -> subprocess.CompletedProcess: + return subprocess.run(["git", *args], cwd=cwd, env=_GIT_ENV, + capture_output=True, text=True, timeout=60) + + +def _push_to_remote(remote: str, pkg: Path, workdir: str) -> bool: + """克隆远端 → 放入脱敏包 → commit+push。任一步失败返回 False(安静)。""" + try: + if _git("clone", "--depth", "50", remote, workdir).returncode != 0: + return False + dst = Path(workdir) / pkg.name + shutil.copy2(pkg, dst) + if _git("add", pkg.name, cwd=workdir).returncode != 0: + return False + commit = _git("-c", "user.name=ziping-share", + "-c", "user.email=ziping-share@localhost", + "commit", "--allow-empty", "-m", f"share: {pkg.stem}", + cwd=workdir) + if commit.returncode != 0: + return False + return _git("push", "origin", "HEAD:main", cwd=workdir).returncode == 0 + except (OSError, subprocess.SubprocessError): + return False + + +def _remotes(root: Path) -> list[tuple[str, str]]: + cfg = {} + cfg_path = root / "share" / "config.json" + if cfg_path.is_file(): + try: + cfg = json.loads(cfg_path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + cfg = {} + out = [] + for key, env in (("github_remote", ENV_GITHUB), ("gitea_remote", ENV_GITEA)): + val = os.environ.get(env) or str(cfg.get(key) or "").strip() + if val: + out.append((key, val)) + return out + + +def main() -> int: + ap = argparse.ArgumentParser(prog="share_push.py", + description="把 share/pending/ 的脱敏包推送到共建远端," + "成功后计励 +10 次并移入 share/pushed/") + ap.add_argument("--root", default=None, + help="技能根目录(默认取脚本所在技能根,测试覆盖用)") + a = ap.parse_args() + root = (Path(a.root).expanduser().resolve() if a.root + else Path(__file__).resolve().parents[1]) + + if shutil.which("git") is None: + print("ERROR: 未找到 git,无法推送;pending 保留。", file=sys.stderr) + return 3 + remotes = _remotes(root) + if not remotes: + print("ERROR: share/config.json 未配置远端(github_remote/gitea_remote " + "由授权方填写);pending 保留。", file=sys.stderr) + return 3 + + pending = root / "share" / "pending" + pushed = root / "share" / "pushed" + packages = sorted(pending.glob("*.json")) if pending.is_dir() else [] + if not packages: + print("share/pending/ 无待推送脱敏包。") + return 0 + + pushed.mkdir(parents=True, exist_ok=True) + n_ok = 0 + for pkg in packages: + chart_hash = pkg.stem + ok_remote = None + for name, remote in remotes: + with tempfile.TemporaryDirectory(prefix="ziping-share-") as td: + if _push_to_remote(remote, pkg, td): + ok_remote = name + break + if ok_remote is None: + print(f"FAIL {pkg.name}:所有远端推送失败(无网络或远端不可达)," + f"pending 保留。", file=sys.stderr) + continue + granted = gate.grant_uses(root, GRANT_USES, chart_hash) + shutil.move(str(pkg), str(pushed / pkg.name)) + note = (f"+{GRANT_USES} 次(新增计励)" if granted + else "该盘已计励过,本次不重复加次") + print(f"OK {pkg.name} → {ok_remote};{note}") + n_ok += 1 + + return 0 if n_ok else 3 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/share/README.md b/share/README.md new file mode 100644 index 0000000..2ccd199 --- /dev/null +++ b/share/README.md @@ -0,0 +1,34 @@ +# 脱敏档案共建(share/) + +本目录是「命主档案共建」的唯一出口:使用者自愿把**脱敏后的**命盘数据回传给授权方, +用于技能优化与规则蒸馏。每成功推送一盘,本副本授权次数 +10(同一盘只计一次)。 + +- `pending/` —— 已导出、待推送的脱敏包(`scripts/share_export.py` 生成); +- `pushed/` —— 已推送成功的脱敏包(`scripts/share_push.py` 移入); +- `config.json` —— 接收远端配置,**远端地址由授权方填写**(占位为空时不推送)。 + +`pending/` 与 `pushed/` 的数据不随授权副本分发(`tools/` 已排除),骨架照常分发。 + +## 隐私协议与脱敏规格 + +脱敏包为结构化 JSON(`schema: share/v1`),不是档案原文。导出时强制: + +| 项目 | 处理 | +|---|---| +| 姓名 | 一律删除,不入包 | +| 出生信息 | 只保留年月日与时辰(时辰以时支表示),不留分钟与钟表时间 | +| 地域 | 只保留到省级,省以下(市、县、区县)一律删除 | +| 事件 | 一律类目化(婚姻/感情/事业/财运/健康/学业/六亲/流年运势/其他),不写细节 | +| 正文自由文本 | 不入包(归纳、盘面细节、反馈原文均不导出) | +| 标识 | 仅以盘 hash(四柱+出生地 sha1 前 8 位)标识,用于去重与撤回 | + +## 用途与许可 + +脱敏档案数据**仅用于本技能的优化与规则蒸馏**(校验取格、断运规则的命中率), +不另作他用,不对外出售或转授。推送即视为同意上述用途;不同意则不推送, +`pending/` 中的包可随时删除,不影响技能正常使用。 + +## 撤回 + +如需撤回已推送的脱敏档案,联系授权方(见 `LICENSE.md`),提供盘 hash +(脱敏包文件名即盘 hash),授权方按 hash 定位并删除对应数据。 diff --git a/share/config.json b/share/config.json new file mode 100644 index 0000000..d8531a1 --- /dev/null +++ b/share/config.json @@ -0,0 +1,5 @@ +{ + "github_remote": "", + "gitea_remote": "", + "_note": "脱敏包接收远端,由授权方填写(GitHub / Gitea 仓库地址)。占位为空时 share_push.py 不推送。亦可用环境变量 ZIPING_SHARE_GITHUB_REMOTE / ZIPING_SHARE_GITEA_REMOTE 覆盖。" +} diff --git a/share/pending/.gitkeep b/share/pending/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/share/pushed/.gitkeep b/share/pushed/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_license_gate.py b/tests/test_license_gate.py index a59ff7e..62244ed 100644 --- a/tests/test_license_gate.py +++ b/tests/test_license_gate.py @@ -1,5 +1,6 @@ -"""软授权锁:母版放行、副本扣次、用尽/过期/篡改/总开关。""" +"""软授权锁:母版放行、副本扣次、用尽/过期/篡改/总开关、公众版首启签发、计励幂等。""" import json +import re import sys from pathlib import Path @@ -71,3 +72,92 @@ class TestMasterSwitch: gate.consume(root) # 不扣次 st = json.loads((root / "data" / ".license.json").read_text("utf-8")) assert st["remaining_uses"] == 0 + + +def make_public_marker(root): + (root / "data").mkdir(exist_ok=True) + (root / "data" / ".public_edition.json").write_text(json.dumps( + {"edition": "public", "pack_version": "0.1.0", + "pool_copy_id": "LY-20261009-PUB0"}, ensure_ascii=False), "utf-8") + + +class TestPublicEdition: + def test_first_check_issues_personal_license(self, root): + make_public_marker(root) + assert gate.check(root) is None + st = json.loads((root / "data" / ".license.json").read_text("utf-8")) + assert re.fullmatch(r"LY-\d{8}-[0-9A-F]{4}", st["copy_id"]) + assert st["licensee"] == "public-personal" + assert st["max_uses"] == 20 + assert st["remaining_uses"] == 20 + assert st["expires_at"] is None + assert st["granted_archives"] == [] + + def test_second_check_keeps_same_copy_id(self, root): + make_public_marker(root) + gate.check(root) + first = json.loads((root / "data" / ".license.json").read_text("utf-8")) + gate.check(root) + second = json.loads((root / "data" / ".license.json").read_text("utf-8")) + assert first["copy_id"] == second["copy_id"] + assert first["sig"] == second["sig"] + + def test_issued_copy_consumes_then_denies(self, root): + make_public_marker(root) + assert gate.check(root) is None + for _ in range(20): + gate.consume(root) + assert "次数已用尽" in gate.check(root) + + def test_master_without_marker_stays_unlocked(self, root): + assert gate.check(root) is None # 母版:无状态文件也无标记 + assert not (root / "data" / ".license.json").exists() + + +class TestGrantUses: + def test_grant_adds_uses_and_is_idempotent(self, root): + make_state(root, max_uses=5) + assert gate.grant_uses(root, 10, "hashA") is True + st = json.loads((root / "data" / ".license.json").read_text("utf-8")) + assert st["remaining_uses"] == 15 + # 同一盘只计一次:第二次返回 False 且不加次 + assert gate.grant_uses(root, 10, "hashA") is False + st = json.loads((root / "data" / ".license.json").read_text("utf-8")) + assert st["remaining_uses"] == 15 + assert st["granted_archives"] == ["hashA"] + # 另一盘可再计 + assert gate.grant_uses(root, 10, "hashB") is True + st = json.loads((root / "data" / ".license.json").read_text("utf-8")) + assert st["remaining_uses"] == 25 + assert st["granted_archives"] == ["hashA", "hashB"] + + def test_grant_on_master_returns_true_without_state(self, root): + assert gate.grant_uses(root, 10, "hashA") is True + assert not (root / "data" / ".license.json").exists() + + def test_grant_on_tampered_state_refused(self, root): + make_state(root, max_uses=5) + p = root / "data" / ".license.json" + st = json.loads(p.read_text("utf-8")) + st["remaining_uses"] = 999 # 手改次数但不重算签名 + p.write_text(json.dumps(st, ensure_ascii=False), "utf-8") + assert gate.grant_uses(root, 10, "hashA") is False + st = json.loads(p.read_text("utf-8")) + assert st["remaining_uses"] == 999 # 未被计励写回 + + def test_state_written_by_old_schema_still_verifiable(self, root): + # 旧格式状态文件(无 granted_archives 字段)签名校验不受影响 + st = { + "copy_id": "LY-20261007-A3F9", "licensee": "张三", + "issued_at": "2026-10-07", "expires_at": None, + "max_uses": 2, "remaining_uses": 2, + } + st["sig"] = gate._sig(st) + (root / "data").mkdir() + (root / "data" / ".license.json").write_text( + json.dumps(st, ensure_ascii=False), "utf-8") + assert gate.check(root) is None + assert gate.grant_uses(root, 10, "hashA") is True + st = json.loads((root / "data" / ".license.json").read_text("utf-8")) + assert st["remaining_uses"] == 12 + assert gate.check(root) is None diff --git a/tests/test_self_update.py b/tests/test_self_update.py new file mode 100644 index 0000000..1e175b6 --- /dev/null +++ b/tests/test_self_update.py @@ -0,0 +1,247 @@ +"""自更新:版本比较、24h 缓存、manifest 校验拦截、apply 同步与保留区、退出码。 + +远端用本地临时目录伪造:VERSION / zipball 均以 file:// 地址经 +ZIPEC_VERSION_URLS / ZIPEC_ZIPBALL_URLS 注入,不碰真实网络。 +""" +import hashlib +import json +import subprocess +import sys +import time +import zipfile +from pathlib import Path + +import pytest + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts")) +import self_update as su + + +# ---- 造本地副本与伪造远端 ---- + +def make_local(tmp_path, version="3.5.0"): + root = tmp_path / "local" + (root / "scripts").mkdir(parents=True) + (root / "data").mkdir() + (root / "VERSION").write_text(version + "\n", encoding="utf-8") + (root / "scripts" / "cast_chart.py").write_text("# old\n", encoding="utf-8") + (root / "data" / "cities.json").write_text("{}", encoding="utf-8") + (root / "stale_legacy.py").write_text("# to be removed\n", encoding="utf-8") + (root / "legacy").mkdir() + (root / "legacy" / "gone.py").write_text("# to be removed\n", encoding="utf-8") + # 保留区:更新后必须原样存活 + (root / "data" / ".license.json").write_text('{"copy_id": "x"}', encoding="utf-8") + (root / "memory" / "archives").mkdir(parents=True) + (root / "memory" / "archives" / "keep.md").write_text("keep", encoding="utf-8") + (root / "share" / "pending").mkdir(parents=True) + (root / "share" / "pending" / "keep.md").write_text("keep", encoding="utf-8") + return root + + +def make_remote(tmp_path, version="3.6.0", files=None, tamper=None): + """造远端 zipball(带一层顶层目录,模拟 GitHub codeload 结构)+ 远端 VERSION。 + + tamper=<相对路径>:先按原内容算清单哈希,再篡改该文件,用于触发校验拦截。 + """ + src = tmp_path / "zipcontent" / "ZiPingEightChar-main" + src.mkdir(parents=True) + all_files = {"VERSION": version + "\n", **(files or {})} + for rel, content in all_files.items(): + p = src / rel + p.parent.mkdir(parents=True, exist_ok=True) + p.write_text(content, encoding="utf-8") + hashes = { + rel: hashlib.sha256((src / rel).read_bytes()).hexdigest() + for rel in all_files + } + (src / "manifest.json").write_text( + json.dumps({"version": version, "files": hashes}, indent=2) + "\n", + encoding="utf-8", + ) + if tamper: + (src / tamper).write_text("# tampered\n", encoding="utf-8") + zip_path = tmp_path / "remote.zip" + with zipfile.ZipFile(zip_path, "w") as zf: + for f in sorted(src.parent.rglob("*")): + zf.write(f, f.relative_to(src.parent)) + version_file = tmp_path / "REMOTE_VERSION" + version_file.write_text(version + "\n", encoding="utf-8") + return version_file, zip_path + + +def point_at_remote(monkeypatch, version_file, zip_path=None): + monkeypatch.setenv("ZIPEC_VERSION_URLS", version_file.as_uri()) + if zip_path is not None: + monkeypatch.setenv("ZIPEC_ZIPBALL_URLS", zip_path.as_uri()) + + +REMOTE_FILES = { + "scripts/cast_chart.py": "# new\n", + "scripts/new_feature.py": "# new file\n", + "data/cities.json": '{"new": 1}', +} + + +class TestVersionCompare: + def test_parse(self): + assert su.parse_version("3.5.0") == (3, 5, 0) + assert su.parse_version(" 3.10.1\n") == (3, 10, 1) + with pytest.raises(ValueError): + su.parse_version("3.x.0") + + def test_newer_remote_marks_update(self, tmp_path, monkeypatch): + root = make_local(tmp_path) + vf, _ = make_remote(tmp_path) + point_at_remote(monkeypatch, vf) + assert su.cmd_check(root) == 0 + cache = json.loads((root / "data" / ".update_check.json").read_text()) + assert cache["remote_version"] == "3.6.0" + assert cache["update_available"] is True + + def test_same_version_no_update(self, tmp_path, monkeypatch): + root = make_local(tmp_path) + vf, _ = make_remote(tmp_path, version="3.5.0") + point_at_remote(monkeypatch, vf) + assert su.cmd_check(root) == 0 + cache = json.loads((root / "data" / ".update_check.json").read_text()) + assert cache["update_available"] is False + + +class TestCacheFreshness: + def test_fresh_cache_skips_network(self, tmp_path, monkeypatch, capsys): + root = make_local(tmp_path) + calls = [] + + def fake_fetch(url, timeout=3): + calls.append(url) + return "3.6.0" + + monkeypatch.setattr(su, "_fetch_text", fake_fetch) + assert su.cmd_check(root) == 0 + assert su.cmd_check(root) == 0 + assert len(calls) == 1 # 24h 内第二次 --check 直接读缓存 + assert "已检查过" in capsys.readouterr().out + + def test_stale_cache_refetches(self, tmp_path, monkeypatch): + root = make_local(tmp_path) + calls = [] + monkeypatch.setattr( + su, "_fetch_text", + lambda url, timeout=3: calls.append(url) or "3.6.0", + ) + su.cmd_check(root) + p = root / "data" / ".update_check.json" + cache = json.loads(p.read_text()) + cache["checked_at"] = time.time() - 25 * 3600 # 人为过期 + p.write_text(json.dumps(cache), encoding="utf-8") + assert su.cmd_check(root) == 0 + assert len(calls) == 2 + + def test_notify_reads_cache_only(self, tmp_path, capsys): + root = tmp_path / "local" + root.mkdir() + assert su.notify_message(root) is None # 无缓存 → 静默 + assert su.cmd_notify(root) == 0 + assert capsys.readouterr().err == "" + + def test_notify_prints_hint(self, tmp_path, capsys): + root = make_local(tmp_path) + (root / "data" / ".update_check.json").write_text(json.dumps({ + "checked_at": time.time(), "local_version": "3.5.0", + "remote_version": "3.6.0", "update_available": True, + }), encoding="utf-8") + msg = su.notify_message(root) + assert "3.6.0" in msg and "--apply" in msg + assert su.cmd_notify(root) == 0 + assert "3.6.0" in capsys.readouterr().err + + def test_refresh_cache_failure_silent(self, tmp_path, monkeypatch): + root = make_local(tmp_path) + def boom(url, timeout=3): + raise OSError("network down") + monkeypatch.setattr(su, "_fetch_text", boom) + su.refresh_cache(root) # 不抛 + assert not (root / "data" / ".update_check.json").exists() + + +class TestApply: + def test_success_syncs_and_preserves(self, tmp_path, monkeypatch, capsys): + root = make_local(tmp_path) + vf, zp = make_remote(tmp_path, files=REMOTE_FILES) + point_at_remote(monkeypatch, vf, zp) + assert su.cmd_apply(root) == 0 + assert "更新完成" in capsys.readouterr().out + # 清单内文件被覆盖/新增 + assert (root / "VERSION").read_text().strip() == "3.6.0" + assert (root / "scripts" / "cast_chart.py").read_text() == "# new\n" + assert (root / "scripts" / "new_feature.py").exists() + assert (root / "manifest.json").exists() + # 清单不含的本地多余文件被清理 + assert not (root / "stale_legacy.py").exists() + assert not (root / "legacy").exists() # 清空后的空目录一并移除 + # 保留区原样存活 + assert (root / "data" / ".license.json").read_text() == '{"copy_id": "x"}' + assert (root / "data" / ".update_check.json").exists() + assert (root / "memory" / "archives" / "keep.md").read_text() == "keep" + assert (root / "share" / "pending" / "keep.md").read_text() == "keep" + + def test_tampered_file_aborts_untouched(self, tmp_path, monkeypatch, capsys): + root = make_local(tmp_path) + vf, zp = make_remote(tmp_path, files=REMOTE_FILES, + tamper="scripts/cast_chart.py") + point_at_remote(monkeypatch, vf, zp) + assert su.cmd_apply(root) == 3 + assert "不符" in capsys.readouterr().err + # 本地原样不动 + assert (root / "VERSION").read_text().strip() == "3.5.0" + assert (root / "scripts" / "cast_chart.py").read_text() == "# old\n" + assert (root / "stale_legacy.py").exists() + assert not (root / "scripts" / "new_feature.py").exists() + + def test_already_latest_exit_2(self, tmp_path, monkeypatch, capsys): + root = make_local(tmp_path) + vf, zp = make_remote(tmp_path, version="3.5.0") + point_at_remote(monkeypatch, vf, zp) + assert su.cmd_apply(root) == 2 + assert "无需更新" in capsys.readouterr().out + + def test_missing_local_version_exit_2(self, tmp_path): + root = tmp_path / "local" + root.mkdir() + assert su.cmd_apply(root) == 2 + + def test_remote_unreachable_exit_3(self, tmp_path, monkeypatch): + root = make_local(tmp_path) + monkeypatch.setenv("ZIPEC_VERSION_URLS", "file:///nonexistent/VERSION") + assert su.cmd_apply(root) == 3 + assert su.cmd_check(root) == 3 # 无缓存且远端不可达 + assert (root / "VERSION").read_text().strip() == "3.5.0" + + +class TestCastChartIntegration: + def test_notice_on_stderr_stdout_clean(self): + """排盘成功后 stderr 出一行提示;stdout 命盘契约不受影响。""" + root = su.repo_root() + cache_path = root / "data" / ".update_check.json" + old_bytes = cache_path.read_bytes() if cache_path.exists() else None + cache_path.parent.mkdir(parents=True, exist_ok=True) + cache_path.write_text(json.dumps({ + "checked_at": time.time(), "local_version": "3.5.0", + "remote_version": "9.9.9", "update_available": True, + }), encoding="utf-8") + try: + r = subprocess.run( + [sys.executable, str(root / "scripts" / "cast_chart.py"), + "--name", "测试", "--gender", "男", + "--birth", "1990-05-14 08:30", "--place", "四川省成都市"], + capture_output=True, text=True, timeout=60, + ) + assert r.returncode == 0 + assert r.stdout.startswith("# 命盘:测试") + assert "技能有新版本 9.9.9" in r.stderr + assert "--apply" in r.stderr + finally: + if old_bytes is None: + cache_path.unlink(missing_ok=True) + else: + cache_path.write_bytes(old_bytes) diff --git a/tests/test_share.py b/tests/test_share.py new file mode 100644 index 0000000..3b824e0 --- /dev/null +++ b/tests/test_share.py @@ -0,0 +1,220 @@ +"""share/ 脱敏共建:导出脱敏、完整度门槛、推送计励幂等(本地 bare git 仓库当远端,无网络)。""" +import json +import os +import shutil +import subprocess +import sys +from pathlib import Path + +import pytest + +SKILL_ROOT = Path(__file__).resolve().parents[1] +SCRIPTS_DIR = SKILL_ROOT / "scripts" +EXPORT = SCRIPTS_DIR / "share_export.py" +PUSH = SCRIPTS_DIR / "share_push.py" + +sys.path.insert(0, str(SCRIPTS_DIR)) +import _license_gate as gate +import _memory_store as store + +PILLARS = ["庚午", "辛巳", "己卯", "戊辰"] +BIRTH = "1990-05-14 08:30" +PLACE = "四川省成都市" + +git = pytest.mark.skipif(shutil.which("git") is None, reason="无 git") + + +def run(script, *args): + env = dict(os.environ) + env["PYTHONPATH"] = str(SCRIPTS_DIR) + os.pathsep + env.get("PYTHONPATH", "") + return subprocess.run([sys.executable, str(script), *args], + capture_output=True, text=True, timeout=120, env=env) + + +def make_archive(mem_root: Path, feedback: str | None = None) -> Path: + """造一份手工档案:四柱/大运/关注方向齐全,反馈小节可定制。""" + meta = {"name": "张三", "gender": "男", "birth_clock": BIRTH, + "birthplace": PLACE, "true_solar_time": "1990-05-14 08:23", + "pillars": PILLARS, "day_master": "己", + "created_at": "2026-10-01 10:00", "updated_at": "2026-10-08 15:00"} + body = ( + "# 档案:张三(男)\n\n" + "## 盘面\n\n" + "# 命盘:张三\n\n" + "## 大运\n\n" + "- 排法:顺行;起运:7 岁 8 个月 1 天(7.67 岁)\n" + "- 第 1 步:壬午(7.67 岁起,1998 年)\n" + "- 第 2 步:癸未(17.67 岁起,2008 年)\n" + "- 第 3 步:甲申(27.67 岁起,2018 年)\n\n" + "## 小运\n\n(无)\n\n" + "## 主要关注方向\n\n- 婚姻与事业走向\n\n" + "## 归纳\n\n- 性格:未断\n- 身体:未断\n- 事业:未断\n- 感情:未断\n- 婚姻:未断\n\n" + "## 流年大事\n\n(未记录)\n\n" + "## 反馈与澄清\n\n" + + (feedback if feedback is not None else + "- 【已核实】2018 年升职,跳槽到外企\n- 【未核实】2020 年感情波动\n") + ) + arch_dir = mem_root / "archives" + arch_dir.mkdir(parents=True, exist_ok=True) + path = arch_dir / store.archive_name( + PILLARS, "男", store.key_hash(BIRTH, PLACE, "男")) + path.write_text(store.dump_frontmatter(meta) + body, encoding="utf-8") + return path + + +@pytest.fixture +def share_root(tmp_path): + return tmp_path / "share" + + +class TestExport: + def test_package_is_sanitized(self, tmp_path, share_root): + arch = make_archive(tmp_path / "memory") + r = run(EXPORT, "--archive", str(arch), "--share-root", str(share_root)) + assert r.returncode == 0, r.stderr + out = Path(r.stdout.strip()) + assert out.parent == share_root / "pending" + text = out.read_text("utf-8") + pkg = json.loads(text) + + # 脱敏:不含姓名、出生分钟/钟表时间、省以下地域 + assert "name" not in pkg + assert "张三" not in text + assert "08:30" not in text and "08:23" not in text + assert "成都市" not in text + assert "birth_clock" not in pkg and "birthplace" not in pkg + + # 结构字段 + assert pkg["schema"] == "share/v1" + assert pkg["gender"] == "男" + assert pkg["pillars"] == PILLARS + assert pkg["birth_date"] == "1990-05-14" + assert pkg["birth_shichen"] == "辰" + assert pkg["region_province"] == "四川省" + assert [l["pillar"] for l in pkg["luck_pillars"]] == ["壬午", "癸未", "甲申"] + assert pkg["luck_pillars"][0]["start_year"] == 1998 + assert pkg["focus_categories"] == ["婚姻", "事业"] + assert {f["year"] for f in pkg["feedback"]} == {2018, 2020} + assert {f["status"] for f in pkg["feedback"]} == {"已核实", "未核实"} + assert all(f["category"] for f in pkg["feedback"]) + # 盘 hash = sha1(四柱+出生地) 前 8,文件名即 hash + assert out.stem == pkg["chart_hash"] + assert len(pkg["chart_hash"]) == 8 + + def test_lookup_by_birth_place_gender(self, tmp_path, share_root): + make_archive(tmp_path / "memory") + r = run(EXPORT, "--birth", BIRTH, "--place", PLACE, "--gender", "男", + "--memory-root", str(tmp_path / "memory"), + "--share-root", str(share_root)) + assert r.returncode == 0, r.stderr + assert (share_root / "pending").glob("*.json") + + def test_completeness_gate_refuses_without_feedback(self, tmp_path, share_root): + arch = make_archive(tmp_path / "memory", feedback="(无)\n") + r = run(EXPORT, "--archive", str(arch), "--share-root", str(share_root)) + assert r.returncode == 2 + assert "反馈事件" in r.stderr + assert not list((share_root / "pending").glob("*.json")) + + def test_archive_not_found(self, tmp_path, share_root): + r = run(EXPORT, "--archive", str(tmp_path / "nope.md"), + "--share-root", str(share_root)) + assert r.returncode == 2 + + +@git +class TestPush: + @pytest.fixture + def skill(self, tmp_path): + """假技能根:share/ 骨架 + 两个 bare 远端 + 授权状态(5 次)。""" + root = tmp_path / "skill" + (root / "share" / "pending").mkdir(parents=True) + (root / "share" / "pushed").mkdir(parents=True) + remotes = {} + for name in ("github", "gitea"): + bare = tmp_path / f"{name}.git" + subprocess.run(["git", "init", "--bare", str(bare)], + capture_output=True, check=True) + remotes[f"{name}_remote"] = str(bare) + (root / "share" / "config.json").write_text( + json.dumps(remotes, ensure_ascii=False), "utf-8") + gate.write_state(root, copy_id="LY-20261009-TEST", + licensee="测试", max_uses=5) + return root + + def _export_into(self, skill_root, tmp_path): + arch = make_archive(tmp_path / "memory") + r = run(EXPORT, "--archive", str(arch), + "--share-root", str(skill_root / "share")) + assert r.returncode == 0, r.stderr + return Path(r.stdout.strip()) + + def test_push_grants_uses_and_moves_package(self, skill, tmp_path): + pkg = self._export_into(skill, tmp_path) + r = run(PUSH, "--root", str(skill)) + assert r.returncode == 0, r.stderr + assert not pkg.exists() + assert (skill / "share" / "pushed" / pkg.name).is_file() + st = json.loads((skill / "data" / ".license.json").read_text("utf-8")) + assert st["remaining_uses"] == 15 # 5 + 10 + assert st["granted_archives"] == [pkg.stem] + # 远端确实收到提交 + log = subprocess.run( + ["git", "--git-dir", str(tmp_path / "github.git"), "log", "--oneline"], + capture_output=True, text=True) + assert f"share: {pkg.stem}" in log.stdout + + def test_push_same_chart_twice_grants_once(self, skill, tmp_path): + pkg = self._export_into(skill, tmp_path) + assert run(PUSH, "--root", str(skill)).returncode == 0 + # 同一盘再次导出推送:仍成功移走,但不重复计励 + pkg2 = self._export_into(skill, tmp_path) + assert pkg2.name == pkg.name + r = run(PUSH, "--root", str(skill)) + assert r.returncode == 0, r.stderr + assert "不重复" in r.stdout + st = json.loads((skill / "data" / ".license.json").read_text("utf-8")) + assert st["remaining_uses"] == 15 + assert st["granted_archives"] == [pkg.stem] + + def test_push_failure_keeps_pending(self, skill): + bad = {"github_remote": str(skill / "no-such-repo.git"), + "gitea_remote": ""} + (skill / "share" / "config.json").write_text( + json.dumps(bad, ensure_ascii=False), "utf-8") + pkg = skill / "share" / "pending" / "deadbeef.json" + pkg.write_text(json.dumps({"schema": "share/v1", + "chart_hash": "deadbeef"}), "utf-8") + r = run(PUSH, "--root", str(skill)) + assert r.returncode == 3 + assert pkg.is_file() # 失败保留 pending + st = json.loads((skill / "data" / ".license.json").read_text("utf-8")) + assert st["remaining_uses"] == 5 # 未计励 + + def test_no_remote_configured(self, tmp_path): + root = tmp_path / "skill" + (root / "share" / "pending").mkdir(parents=True) + (root / "share" / "config.json").write_text( + json.dumps({"github_remote": "", "gitea_remote": ""}), "utf-8") + (root / "share" / "pending" / "abc12345.json").write_text("{}", "utf-8") + r = run(PUSH, "--root", str(root)) + assert r.returncode == 3 + assert (root / "share" / "pending" / "abc12345.json").is_file() + + def test_env_overrides_config(self, skill, tmp_path): + # config 远端写死为坏地址,环境变量指向好远端 + (skill / "share" / "config.json").write_text(json.dumps( + {"github_remote": str(skill / "bad.git"), "gitea_remote": ""}), "utf-8") + good = tmp_path / "env.git" + subprocess.run(["git", "init", "--bare", str(good)], + capture_output=True, check=True) + pkg = skill / "share" / "pending" / "c0ffee11.json" + pkg.write_text(json.dumps({"schema": "share/v1", + "chart_hash": "c0ffee11"}), "utf-8") + env = dict(os.environ) + env["PYTHONPATH"] = str(SCRIPTS_DIR) + os.pathsep + env.get("PYTHONPATH", "") + env["ZIPING_SHARE_GITHUB_REMOTE"] = str(good) + r = subprocess.run([sys.executable, str(PUSH), "--root", str(skill)], + capture_output=True, text=True, timeout=120, env=env) + assert r.returncode == 0, r.stderr + assert (skill / "share" / "pushed" / "c0ffee11.json").is_file()