mirror of
https://ghfast.top/https://github.com/aeroxw/easy_tdx_max.git
synced 2026-09-12 16:54:20 +08:00
feat: add extended market, offline data reader, rewrite README
- Add ExTdxClient/AsyncExTdxClient for futures, HK stocks, etc (port 7727) - Add offline module: read daily bars, minute bars, blocks, gbbq, financials from local TDX installation directory (inspired by pytdx) - Add examples 09 (file download) and 10 (offline data reading) - Rewrite README with comprehensive API docs and code examples - Add TdxFileNotFoundError and TdxOfflineError exceptions Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
321043f9a5
commit
9c5672b4d2
@@ -1,28 +1,27 @@
|
||||
# xmtdx
|
||||
|
||||
通达信 TCP 协议 A 股行情数据客户端,零运行时依赖。
|
||||
通达信 TCP 协议行情数据客户端,零运行时依赖。支持在线行情获取和离线本地数据读取。
|
||||
|
||||
pytdx 年久失修:多处已知解析 bug、Python 2 包袱、无类型注解、大量未知字段被静默丢弃。xmtdx 重新实现协议,修复已知 bug,保留全部原始字节与未知字段供后续逆向分析。
|
||||
|
||||
离线数据读取模块借鉴了 [pytdx](https://github.com/rainx/pytdx) 的数据格式解析方法,感谢 pytdx 项目的贡献。
|
||||
|
||||
## 特性
|
||||
|
||||
- **零依赖**:纯标准库,Python ≥ 3.10
|
||||
- **零依赖**:纯标准库,Python >= 3.10
|
||||
- **同步 + asyncio 双接口**:`TdxClient` / `AsyncTdxClient`,commands 层不含任何 IO
|
||||
- **完整类型注解**:strict `mypy` + `ruff` 通过
|
||||
- **高可用传输**:同步/异步均支持 `ping_all()`、`from_best_host()`、断线自动重连
|
||||
- **修复 pytdx 已知 bug**(见下文)
|
||||
- **保留原始字节**:每条数据记录含 `_raw: bytes`,未知字段以 `unknown_N` 命名而非丢弃
|
||||
- **保活心跳机制**:`AsyncTdxClient` 自动发送心跳包,确保长连接生产环境稳定性
|
||||
- **沪深 A 股完整列表**:`get_security_list_all()` 自动过滤非 A 股品种并挂载行业信息
|
||||
- **北交所列表限制**:`get_security_list(Market.BJ, start)` 当前不能稳定获取,BJ 暂未纳入 `get_security_list_all()`
|
||||
- **全市场涨跌统计**:一键获取全 A 股涨/跌/平家数及总成交额
|
||||
- **离线 + 本地传输回归测试**:覆盖解析、异步并发串行化、超时、自动重连与坏包处理
|
||||
- **扩展行情**:`ExTdxClient` / `AsyncExTdxClient` 支持期货、港股、外盘等扩展市场(端口 7727)
|
||||
- **离线数据读取**:从本地通达信安装目录直接读取日线、分钟线、财务、板块、股本变迁等数据,无需网络
|
||||
- **专业财务数据**:通过计算服务器下载历史财报 ZIP 文件并解析
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -e . # 开发模式
|
||||
pip install -e ".[dev]" # 含测试/类型检查工具
|
||||
pip install -e ".[pandas]" # 含 pandas(可选)
|
||||
@@ -30,22 +29,23 @@ pip install -e ".[pandas]" # 含 pandas(可选)
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 同步
|
||||
### 连接与基本查询
|
||||
|
||||
```python
|
||||
from xmtdx import TdxClient, Market, KlineCategory
|
||||
|
||||
# 指定服务器
|
||||
# 手动指定服务器
|
||||
with TdxClient("180.153.18.170") as c:
|
||||
count = c.get_security_count(Market.SH)
|
||||
print(f"沪市证券总数: {count}")
|
||||
|
||||
# 自动优选最低延迟服务器
|
||||
with TdxClient.from_best_host() as c:
|
||||
bars = c.get_security_bars(Market.SH, "600000", KlineCategory.DAY, 0, 5)
|
||||
for b in bars:
|
||||
print(b.year, b.month, b.day, b.open, b.close, b.high, b.low, b.vol)
|
||||
|
||||
# 自动测速选最低延迟服务器
|
||||
with TdxClient.from_best_host() as c:
|
||||
quotes = c.get_security_quotes([(Market.SH, "600000"), (Market.SZ, "000001")])
|
||||
print(quotes[0].price, quotes[0].bid1, quotes[0].ask1)
|
||||
print(f"{b.year}-{b.month:02d}-{b.day:02d} "
|
||||
f"开:{b.open:.2f} 高:{b.high:.2f} "
|
||||
f"低:{b.low:.2f} 收:{b.close:.2f}")
|
||||
```
|
||||
|
||||
### asyncio
|
||||
@@ -55,80 +55,414 @@ import asyncio
|
||||
from xmtdx import AsyncTdxClient, Market, KlineCategory
|
||||
|
||||
async def main():
|
||||
async with AsyncTdxClient("180.153.18.170") as c:
|
||||
bars = await c.get_security_bars(Market.SH, "600000", KlineCategory.DAY, 0, 5)
|
||||
print(bars[0])
|
||||
async with AsyncTdxClient.from_best_host() as c:
|
||||
bars = await c.get_security_bars(
|
||||
Market.SH, "600000", KlineCategory.DAY, 0, 5
|
||||
)
|
||||
for bar in bars:
|
||||
print(f"{bar.year}-{bar.month:02d}-{bar.day:02d} "
|
||||
f"开:{bar.open:.2f} 高:{bar.high:.2f} "
|
||||
f"低:{bar.low:.2f} 收:{bar.close:.2f}")
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
### 高可用工具
|
||||
### 服务器测速
|
||||
|
||||
```python
|
||||
from xmtdx import ping_all, KNOWN_HOSTS
|
||||
from xmtdx import TdxClient
|
||||
|
||||
# 并发测速,返回按延迟排序的 [(host, seconds), ...]
|
||||
results = ping_all(KNOWN_HOSTS, timeout=5.0)
|
||||
for host, ms in results:
|
||||
print(f"{host} {ms*1000:.0f} ms")
|
||||
|
||||
# 自动选最优服务器
|
||||
with TdxClient.from_best_host(ping_timeout=5.0) as c:
|
||||
...
|
||||
|
||||
# asyncio 版本同样支持
|
||||
client = AsyncTdxClient.from_best_host(ping_timeout=5.0)
|
||||
# 测速并排序
|
||||
results = TdxClient.ping_all()
|
||||
for host, latency in results:
|
||||
print(f"{host} {latency * 1000:.0f} ms")
|
||||
```
|
||||
|
||||
内置服务器列表(`KNOWN_HOSTS`):
|
||||
## API 参考
|
||||
|
||||
```
|
||||
180.153.18.170 180.153.18.171 180.153.18.172
|
||||
115.238.56.198 115.238.90.165 218.75.126.9
|
||||
47.107.75.159 59.175.238.38
|
||||
### 连接管理
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `TdxClient(host, port=7709, timeout=15.0)` | 指定服务器创建客户端 |
|
||||
| `TdxClient.from_best_host(ping_timeout=5.0)` | 自动选延迟最低的服务器 |
|
||||
| `TdxClient.ping_all(timeout=5.0)` | 并发测速,返回 `[(host, seconds), ...]` |
|
||||
| `AsyncTdxClient` / `AsyncTdxClient.from_best_host()` | 异步版,接口一一对应 |
|
||||
|
||||
内置服务器列表 `KNOWN_HOSTS`(8 台)和计算服务器 `CALC_HOSTS`(1 台)。
|
||||
|
||||
### 市场信息
|
||||
|
||||
```python
|
||||
with TdxClient.from_best_host() as c:
|
||||
# 市场证券总数
|
||||
count = c.get_security_count(Market.SH)
|
||||
|
||||
# 证券列表(分页,每页约 1000 条)
|
||||
stocks = c.get_security_list(Market.SH, start=0)
|
||||
# stocks[0].code / .name / .pre_close / .industry_tdx / .industry_sw
|
||||
|
||||
# 沪深 A 股完整列表(自动挂载行业信息,本地缓存 1 天)
|
||||
all_stocks = c.get_security_list_all()
|
||||
|
||||
# 批量实时五档行情(最多 80 只/次)
|
||||
quotes = c.get_security_quotes([
|
||||
(Market.SH, "600000"), # 浦发银行
|
||||
(Market.SH, "600519"), # 贵州茅台
|
||||
(Market.SZ, "000001"), # 平安银行
|
||||
(Market.SZ, "000858"), # 五粮液
|
||||
])
|
||||
# quotes[0].price / .pre_close / .open / .high / .low / .bid1..bid5 / .ask1..ask5
|
||||
|
||||
# 全市场涨跌统计
|
||||
stat = c.get_market_stat()
|
||||
# stat.up_count / .down_count / .neutral_count / .total_amount / .total_market_cap
|
||||
```
|
||||
|
||||
### K 线数据
|
||||
|
||||
## API
|
||||
```python
|
||||
from xmtdx import Market, KlineCategory
|
||||
|
||||
### TdxClient
|
||||
with TdxClient.from_best_host() as c:
|
||||
# 个股 K 线
|
||||
bars = c.get_security_bars(Market.SZ, "002176", KlineCategory.DAY, 0, 100)
|
||||
|
||||
# 指数 K 线(常用指数代码:上证 "999999",深成 "399001",创业板 "399006")
|
||||
bars = c.get_index_bars(Market.SH, "999999", KlineCategory.DAY, 0, 10)
|
||||
```
|
||||
|
||||
K 线类别:
|
||||
|
||||
```
|
||||
KlineCategory.MIN_1 MIN_5 MIN_15 MIN_30 MIN_60
|
||||
KlineCategory.DAY WEEK MONTH YEAR
|
||||
```
|
||||
|
||||
K 线字段:`open` `close` `high` `low` `vol` `amount` `year` `month` `day` `hour` `minute` `_raw`
|
||||
|
||||
### 分时数据
|
||||
|
||||
```python
|
||||
with TdxClient.from_best_host() as c:
|
||||
# 今日分时(240 条)
|
||||
bars = c.get_minute_time_data(Market.SH, "600000")
|
||||
|
||||
# 历史某日分时,date 为 YYYYMMDD 格式整数
|
||||
bars = c.get_history_minute_time_data(Market.SH, "600000", 20250110)
|
||||
```
|
||||
|
||||
分时字段:`price` `vol` `unknown_1`(原 pytdx 丢弃字段,保留供分析)`_raw`
|
||||
|
||||
### 逐笔成交
|
||||
|
||||
```python
|
||||
with TdxClient.from_best_host() as c:
|
||||
# 当日逐笔成交(分页)
|
||||
records = c.get_transaction_data(Market.SH, "600000", 0, 20)
|
||||
|
||||
# 历史逐笔成交
|
||||
records = c.get_history_transaction_data(Market.SH, "600000", 20250110, 0, 20)
|
||||
```
|
||||
|
||||
成交字段:`hour` `minute` `price` `vol` `buyorsell`(0=买, 1=卖, 2=中性, 8=集合竞价)`unknown_last` `_raw`
|
||||
|
||||
### 财务与公司信息
|
||||
|
||||
```python
|
||||
from xmtdx import XDXR_CATEGORY_NAMES
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
# 除权除息历史
|
||||
records = c.get_xdxr_info(Market.SH, "600519")
|
||||
# records[0].fenhong / .songzhuangu / .peigujia / .peigu
|
||||
|
||||
# 最新财务数据
|
||||
info = c.get_finance_info(Market.SH, "600519")
|
||||
# info.zong_guben / .liutong_guben / .jing_lirun / .zhuying_shouru / ...
|
||||
|
||||
# 涨跌停价计算
|
||||
quotes = c.get_security_quotes([(Market.SH, "600519")])
|
||||
limit_up, limit_down = c.get_price_limits(
|
||||
Market.SH, "600519", "贵州茅台", quotes[0].pre_close
|
||||
)
|
||||
|
||||
# 公司信息目录
|
||||
categories = c.get_company_info_category(Market.SH, "600519")
|
||||
for cat in categories:
|
||||
print(cat.name, cat.filename, cat.start, cat.length)
|
||||
|
||||
# 公司信息内容
|
||||
content = c.get_company_info_content(
|
||||
Market.SH, "600519", cat.filename, cat.start, cat.length
|
||||
)
|
||||
```
|
||||
|
||||
### 板块信息
|
||||
|
||||
```python
|
||||
with TdxClient.from_best_host() as c:
|
||||
# 行业/指数板块
|
||||
blocks = c.get_block_info("block_zs.dat")
|
||||
# 概念板块
|
||||
blocks = c.get_block_info("block_gn.dat")
|
||||
# 风格板块
|
||||
blocks = c.get_block_info("block_fg.dat")
|
||||
# blocks[0].name / .category / .count / .codes
|
||||
```
|
||||
|
||||
### 资金流向
|
||||
|
||||
```python
|
||||
with TdxClient.from_best_host() as c:
|
||||
# 当日资金流向(超大/大/中/小单)
|
||||
flow = c.get_fund_flow(Market.SH, "600519")
|
||||
# flow.super_in / .super_out / .large_in / .large_out / .main_net_inflow
|
||||
|
||||
# 历史日线资金流向序列
|
||||
flows = c.get_history_fund_flow(Market.SH, "600519", 0, 10)
|
||||
# flows[0].year / .month / .day / .super_in / .main_net_inflow
|
||||
```
|
||||
|
||||
### 文件下载
|
||||
|
||||
```python
|
||||
from xmtdx import CALC_HOSTS
|
||||
|
||||
with TdxClient.from_best_host() as c:
|
||||
# 行情服务器可用的文件
|
||||
data = c.get_report_file("tdxhy.cfg") # 行业映射配置
|
||||
data = c.get_report_file("block_gn.dat") # 概念板块
|
||||
|
||||
# 计算服务器:专业财务数据
|
||||
with TdxClient(CALC_HOSTS[0]) as calc:
|
||||
file_list = calc.get_financial_file_list()
|
||||
# file_list[0].filename / .filesize / .hash
|
||||
|
||||
zip_data = calc.get_financial_file("tdxfin/gpcw20260331.zip")
|
||||
records = calc.get_financial_records("tdxfin/gpcw20260331.zip")
|
||||
# records[0].market / .code / .report_date / .fields
|
||||
```
|
||||
|
||||
### 扩展行情(期货、港股、外盘)
|
||||
|
||||
```python
|
||||
from xmtdx import ExTdxClient
|
||||
|
||||
# 扩展行情服务器端口 7727
|
||||
with ExTdxClient() as c:
|
||||
markets = c.get_markets() # 可用市场列表
|
||||
count = c.get_instrument_count() # 品种总数
|
||||
instruments = c.get_instrument_info(0, 50) # 品种信息(分页)
|
||||
quote = c.get_instrument_quote(market, code) # 单品种行情
|
||||
|
||||
# K 线(支持日期范围查询)
|
||||
bars = c.get_instrument_bars(market, code, category, start, count)
|
||||
bars = c.get_history_instrument_bars_range(market, code, date_start, date_end)
|
||||
|
||||
# 分时 / 逐笔
|
||||
minute = c.get_minute_time_data(market, code)
|
||||
trades = c.get_transaction_data(market, code, start, count)
|
||||
```
|
||||
|
||||
`AsyncExTdxClient` 提供与同步版对应的 `async def` 方法。
|
||||
|
||||
## 离线数据读取
|
||||
|
||||
从本地通达信安装目录直接读取数据文件,无需网络连接。离线模块的路径检测优先级:
|
||||
|
||||
1. `TDX_HOME` 环境变量
|
||||
2. 平台常见路径猜测(Windows: `C:\new_jyplug`、`C:\new_tdx` 等)
|
||||
|
||||
```python
|
||||
# Windows
|
||||
set TDX_HOME=C:\new_jyplug
|
||||
|
||||
# Linux/macOS
|
||||
export TDX_HOME=/opt/new_tdx
|
||||
```
|
||||
|
||||
### 日线 K 线
|
||||
|
||||
```python
|
||||
from xmtdx.offline import detect_tdx_home, read_daily_bars, find_daily_bar_file
|
||||
from xmtdx import Market
|
||||
|
||||
home = detect_tdx_home()
|
||||
|
||||
# 通过 市场+代码 自动定位文件
|
||||
filepath = find_daily_bar_file(Market.SH, "600000")
|
||||
bars = read_daily_bars(filepath)
|
||||
|
||||
for bar in bars[-10:]:
|
||||
print(f"{bar.year}-{bar.month:02d}-{bar.day:02d} "
|
||||
f"开:{bar.open:.2f} 收:{bar.close:.2f} 量:{bar.vol:.0f}")
|
||||
```
|
||||
|
||||
文件位于 `vipdoc/{sh,sz}/lday/`,如 `sh600000.day`。自动识别证券类型(A 股/B 股/指数/基金/债券)并应用对应的价格和成交量系数。
|
||||
|
||||
### 分钟 K 线
|
||||
|
||||
```python
|
||||
from xmtdx.offline import (
|
||||
read_5min_bars, read_lc_min_bars,
|
||||
find_5min_bar_file, find_lc1_bar_file, find_lc5_bar_file,
|
||||
)
|
||||
from xmtdx import Market
|
||||
|
||||
# .5 文件(OHLC 为整数 / 100)
|
||||
filepath = find_5min_bar_file(Market.SH, "600000")
|
||||
bars = read_5min_bars(filepath)
|
||||
|
||||
# .lc1 文件(1 分钟线,OHLC 为浮点数)
|
||||
filepath = find_lc1_bar_file(Market.SH, "600000")
|
||||
bars = read_lc_min_bars(filepath)
|
||||
|
||||
# .lc5 文件(5 分钟线,OHLC 为浮点数)
|
||||
filepath = find_lc5_bar_file(Market.SZ, "002176")
|
||||
bars = read_lc_min_bars(filepath)
|
||||
```
|
||||
|
||||
文件位于 `vipdoc/{sh,sz}/fzline/`,如 `sh600000.5`、`sh600000.lc1`、`sh600000.lc5`。
|
||||
|
||||
### 扩展市场日线
|
||||
|
||||
```python
|
||||
from xmtdx.offline import read_ex_daily_bars
|
||||
|
||||
# 期货、港股、外盘等扩展市场数据
|
||||
# 文件位于 vipdoc/ds/lday/,如 29#A1801.day
|
||||
bars = read_ex_daily_bars(r"C:\new_jyplug\vipdoc\ds\lday\38#2_CPI.day")
|
||||
# bar.open / .high / .low / .close / .settlement / .vol
|
||||
```
|
||||
|
||||
### 板块数据
|
||||
|
||||
```python
|
||||
from xmtdx.offline import read_block_dat, read_customer_blocks
|
||||
|
||||
# 系统板块(本地 .dat 文件)
|
||||
blocks = read_block_dat(r"C:\new_jyplug\vipdoc\block_zs.dat")
|
||||
# blocks[0].name / .category / .count / .codes
|
||||
|
||||
# 自定义板块(blocknew 目录)
|
||||
blocks = read_customer_blocks(r"C:\new_jyplug\T0002\blocknew")
|
||||
# blocks[0].blockname / .codes
|
||||
```
|
||||
|
||||
支持本地 .dat 文件离线读取,本地不存在时可通过 `TdxClient.get_block_info()` 在线获取。
|
||||
|
||||
### 股本变迁
|
||||
|
||||
```python
|
||||
from xmtdx.offline import read_gbbq
|
||||
|
||||
records = read_gbbq(r"C:\new_jyplug\T0002\hq_cache\gbbq")
|
||||
# records[0].market / .code / .datetime / .category / .hongli_panqianliutong / ...
|
||||
```
|
||||
|
||||
gbbq 文件使用 XOR 加密存储,读取时自动解密。
|
||||
|
||||
### 历史财务数据
|
||||
|
||||
```python
|
||||
from xmtdx.offline import read_history_financial
|
||||
|
||||
# 支持 .dat 和 .zip 文件(.zip 自动解压)
|
||||
records = read_history_financial(r"C:\new_jyplug\vipdoc\fin\gpcw20260331.zip")
|
||||
# records[0].code / .market / .report_date / .fields
|
||||
```
|
||||
|
||||
文件可通过 `TdxClient.get_financial_file_list()` 查询可用文件,再用 `get_financial_file()` 下载到本地。
|
||||
|
||||
### 路径检测
|
||||
|
||||
```python
|
||||
from xmtdx.offline import detect_tdx_home, resolve_vipdoc
|
||||
|
||||
# 自动检测通达信安装目录
|
||||
home = detect_tdx_home()
|
||||
|
||||
# 解析 vipdoc 数据目录
|
||||
vipdoc = resolve_vipdoc()
|
||||
```
|
||||
|
||||
vipdoc 目录结构:
|
||||
|
||||
```
|
||||
vipdoc/
|
||||
├── sh/lday/ 上海日线 sh600000.day
|
||||
├── sh/fzline/ 上海分钟线 sh600000.5 / .lc1 / .lc5
|
||||
├── sz/lday/ 深圳日线 sz000001.day
|
||||
├── sz/fzline/ 深圳分钟线 sz000001.5 / .lc1 / .lc5
|
||||
├── ds/lday/ 扩展市场 29#A1801.day
|
||||
└── fin/ 历史财务 gpcw*.dat / gpcw*.zip
|
||||
```
|
||||
|
||||
## 完整 API 列表
|
||||
|
||||
### TdxClient / AsyncTdxClient
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `get_security_count(market)` | 市场证券总数 |
|
||||
| `get_security_list(market, start)` | 证券列表(每页 ~1000 条;BJ 当前不能稳定获取) |
|
||||
| `get_security_list_all()` | 沪深 A 股列表(自动挂载行业信息;BJ 暂未纳入) |
|
||||
| `get_market_stat()` | 全市场 A 股涨跌统计(家数、成交额) |
|
||||
| `get_security_list(market, start)` | 证券列表(每页约 1000 条) |
|
||||
| `get_security_list_all()` | 沪深 A 股完整列表(含行业映射,本地缓存 1 天) |
|
||||
| `get_security_quotes([(market, code), ...])` | 批量实时五档行情(最多 80 只/次) |
|
||||
| `get_price_limits(market, code, name, pre_close)` | 计算当前涨跌停价(自动处理上市初期无涨跌幅限制) |
|
||||
| `get_security_bars(market, code, category, start, count=800)` | K 线(股票) |
|
||||
| `get_index_bars(market, code, category, start, count=800)` | K 线(指数) |
|
||||
| `get_price_limits(market, code, name, pre_close)` | 计算涨跌停价 |
|
||||
| `get_security_bars(market, code, category, start, count)` | 个股 K 线 |
|
||||
| `get_index_bars(market, code, category, start, count)` | 指数 K 线 |
|
||||
| `get_minute_time_data(market, code)` | 今日分时(240 条) |
|
||||
| `get_history_minute_time_data(market, code, date)` | 历史某日分时,`date=YYYYMMDD` |
|
||||
| `get_transaction_data(market, code, start, count=800)` | 当日逐笔成交(分页) |
|
||||
| `get_history_transaction_data(market, code, date, start, count=800)` | 历史逐笔成交 |
|
||||
| `get_fund_flow(market, code)` | 当日资金流向统计(超大/大/中/小单) |
|
||||
| `get_history_fund_flow(market, code, start, count)` | 历史日线资金流向序列(优先 Category 22,空回包时自动回退到历史逐笔重算) |
|
||||
| `get_history_minute_time_data(market, code, date)` | 历史分时 |
|
||||
| `get_transaction_data(market, code, start, count)` | 当日逐笔成交 |
|
||||
| `get_history_transaction_data(market, code, date, start, count)` | 历史逐笔成交 |
|
||||
| `get_fund_flow(market, code)` | 当日资金流向 |
|
||||
| `get_history_fund_flow(market, code, start, count)` | 历史日线资金流向 |
|
||||
| `get_xdxr_info(market, code)` | 除权除息历史 |
|
||||
| `get_finance_info(market, code)` | 最新财务数据 |
|
||||
| `get_company_info_category(market, code)` | 公司信息文件目录 |
|
||||
| `get_company_info_category(market, code)` | 公司信息目录 |
|
||||
| `get_company_info_content(market, code, filename, offset, length)` | 公司信息文本 |
|
||||
| `get_block_info(filename)` | 板块信息(行业、概念、风格等) |
|
||||
| `get_report_file(filename)` | 批量拉取大文件(如 'base_info.zip', 'gpcw.txt') |
|
||||
| `get_block_info(filename)` | 板块信息 |
|
||||
| `get_report_file(filename)` | 下载服务器文件 |
|
||||
| `get_market_stat()` | 全市场涨跌统计 |
|
||||
| `get_financial_file_list()` | 计算服务器财务文件列表 |
|
||||
| `get_financial_file(filename)` | 下载财务文件 |
|
||||
| `get_financial_records(filename)` | 下载并解析财务记录 |
|
||||
|
||||
`AsyncTdxClient` 提供与同步版对应的查询方法与高可用入口,均为 `async def`。
|
||||
单个 `AsyncTdxClient` 仅维护一条 TCP 连接;并发调用会在连接内串行执行。
|
||||
### ExTdxClient / AsyncExTdxClient
|
||||
|
||||
## 已知限制
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| `get_markets()` | 可用市场列表 |
|
||||
| `get_instrument_count()` | 品种总数 |
|
||||
| `get_instrument_info(start, count)` | 品种信息(分页) |
|
||||
| `get_instrument_quote(market, code)` | 单品种行情 |
|
||||
| `get_instrument_quote_list(market, start, count)` | 批量行情 |
|
||||
| `get_instrument_bars(market, code, category, start, count)` | 品种 K 线 |
|
||||
| `get_history_instrument_bars_range(market, code, start, end)` | 日期范围 K 线 |
|
||||
| `get_minute_time_data(market, code)` | 分时数据 |
|
||||
| `get_history_minute_time_data(market, code, date)` | 历史分时 |
|
||||
| `get_transaction_data(market, code, start, count)` | 逐笔成交 |
|
||||
| `get_history_transaction_data(market, code, date, start, count)` | 历史逐笔 |
|
||||
|
||||
- `xmtdx` 当前不能稳定获取 BJ 证券列表;`get_security_count(Market.BJ)` 可用,但 `get_security_list(Market.BJ, start)` 经常超时,因此 `get_security_list_all()` 暂不纳入 BJ。
|
||||
### xmtdx.offline
|
||||
|
||||
### KlineCategory
|
||||
|
||||
```
|
||||
MIN_1 MIN_3 MIN_5 MIN_15 MIN_30 MIN_60
|
||||
DAY WEEK MONTH SEASON YEAR YEAR_ALT
|
||||
```
|
||||
| 函数 | 说明 |
|
||||
|------|------|
|
||||
| `detect_tdx_home()` | 检测通达信安装目录 |
|
||||
| `resolve_vipdoc(path)` | 解析 vipdoc 数据目录 |
|
||||
| `read_daily_bars(filepath)` | 读取日线 .day 文件 |
|
||||
| `find_daily_bar_file(market, code)` | 定位日线文件路径 |
|
||||
| `read_5min_bars(filepath)` | 读取 .5 分钟线文件 |
|
||||
| `read_lc_min_bars(filepath)` | 读取 .lc1/.lc5 分钟线文件 |
|
||||
| `find_5min_bar_file(market, code)` | 定位 .5 文件路径 |
|
||||
| `find_lc1_bar_file(market, code)` | 定位 .lc1 文件路径 |
|
||||
| `find_lc5_bar_file(market, code)` | 定位 .lc5 文件路径 |
|
||||
| `read_ex_daily_bars(filepath)` | 读取扩展市场日线 |
|
||||
| `read_block_dat(filepath)` | 读取系统板块 .dat 文件 |
|
||||
| `read_customer_blocks(block_dir)` | 读取自定义板块目录 |
|
||||
| `read_gbbq(filepath)` | 读取股本变迁文件 |
|
||||
| `read_history_financial(filepath)` | 读取历史财务数据 |
|
||||
|
||||
## 数据模型
|
||||
|
||||
@@ -149,31 +483,11 @@ market code price pre_close open high low
|
||||
vol cur_vol amount s_vol b_vol
|
||||
bid1..bid5 bid_vol1..bid_vol5
|
||||
ask1..ask5 ask_vol1..ask_vol5
|
||||
rise_speed limit_up limit_down server_time
|
||||
unknown_2..unknown_3 unknown_5..unknown_8
|
||||
server_time
|
||||
_raw
|
||||
```
|
||||
|
||||
`limit_up` / `limit_down` 当前不再直接由协议字段映射,默认保留为 `None`;
|
||||
建议通过 `client.get_price_limits(...)` 计算当前涨跌停价,或用
|
||||
`xmtdx.codec.price_rules.compute_price_limits(..., listed_days=...)` 做纯规则计算。
|
||||
|
||||
### MinuteBar(分时)
|
||||
|
||||
```
|
||||
price vol
|
||||
unknown_1 # 原 pytdx 丢弃字段,保留供分析(≠ 均价)
|
||||
_raw
|
||||
```
|
||||
|
||||
### TransactionRecord(逐笔成交)
|
||||
|
||||
```
|
||||
hour minute price vol
|
||||
buyorsell # 0=买, 1=卖, 2=中性, 8=集合竞价
|
||||
unknown_last
|
||||
_raw
|
||||
```
|
||||
`limit_up` / `limit_down` 默认为 `None`,涨跌停价应通过 `get_price_limits()` 计算。
|
||||
|
||||
### SecurityInfo(证券列表)
|
||||
|
||||
@@ -182,42 +496,50 @@ market code name volunit decimal_point pre_close
|
||||
industry_tdx industry_sw
|
||||
```
|
||||
|
||||
### MinuteBar(分时)
|
||||
|
||||
```
|
||||
price vol unknown_1 _raw
|
||||
```
|
||||
|
||||
### TransactionRecord(逐笔成交)
|
||||
|
||||
```
|
||||
hour minute price vol buyorsell unknown_last _raw
|
||||
```
|
||||
|
||||
### XdxrRecord(除权除息)
|
||||
|
||||
```
|
||||
market code year month day category name
|
||||
fenhong peigujia songzhuangu peigu suogu
|
||||
xingquanjia fenshu
|
||||
panqian_liutong panhou_liutong # 单位:万股
|
||||
qian_zongguben hou_zongguben # 单位:万股
|
||||
panqian_liutong panhou_liutong # 万股
|
||||
qian_zongguben hou_zongguben # 万股
|
||||
_raw
|
||||
```
|
||||
|
||||
`category == 1` 时,`fenhong / songzhuangu / peigu` 已归一化为“每股”口径。
|
||||
`category == 1` 时为现金分红/送转/配股,`fenhong / songzhuangu / peigu` 已归一化为每股口径。
|
||||
|
||||
### 复权公式
|
||||
|
||||
若在仓库外自行计算前复权 / 后复权,建议仅使用 `category == 1` 的 `xdxr`
|
||||
记录(现金分红 / 送转 / 配股)参与因子计算:
|
||||
|
||||
- `cash = fenhong`
|
||||
- `bonus = songzhuangu`
|
||||
- `rights = peigu`
|
||||
- `rights_price = peigujia`
|
||||
|
||||
单次除权除息事件的价格因子可写为:
|
||||
仅使用 `category == 1` 的 xdxr 记录:
|
||||
|
||||
```text
|
||||
factor = (pre_close - cash + rights * rights_price) / (1 + bonus + rights)
|
||||
```
|
||||
|
||||
其中 `pre_close` 为事件前一交易日的未复权收盘价。
|
||||
其中 `cash = fenhong`,`bonus = songzhuangu`,`rights = peigu`,`rights_price = peigujia`,`pre_close` 为事件前一日未复权收盘价。
|
||||
|
||||
- 前复权:将事件日前的历史价格连续乘以各次 `factor`
|
||||
- 后复权:将事件日后的价格连续除以各次 `factor`
|
||||
- 前复权:事件日前的历史价格连续乘以各次 `factor`
|
||||
- 后复权:事件日后的价格连续除以各次 `factor`
|
||||
|
||||
当前建议只把 `category == 1` 用作复权;`2..14` 类事件仍更适合作为原始事件暴露,
|
||||
不建议直接纳入通用复权引擎。
|
||||
### FundFlow(资金流向)
|
||||
|
||||
```
|
||||
super_in/out large_in/out medium_in/out small_in/out
|
||||
main_net_inflow total_net_inflow
|
||||
```
|
||||
|
||||
### FinanceInfo(财务)
|
||||
|
||||
@@ -235,24 +557,13 @@ name filename start length
|
||||
name category count codes
|
||||
```
|
||||
|
||||
### FundFlow(资金流)
|
||||
## 已知限制
|
||||
|
||||
```
|
||||
super_in/out large_in/out medium_in/out small_in/out
|
||||
main_net_inflow total_net_inflow
|
||||
```
|
||||
|
||||
### HistoricalFundFlow(历史资金流序列)
|
||||
|
||||
```
|
||||
year month day
|
||||
super_in/out large_in/out medium_in/out small_in/out
|
||||
main_net_inflow
|
||||
```
|
||||
- `get_security_list(Market.BJ, start)` 当前不能稳定获取(服务器端问题),`get_security_list_all()` 暂不纳入 BJ
|
||||
- `limit_up` / `limit_down` 在 `SecurityQuote` 中默认为 `None`,涨跌停价应通过 `get_price_limits()` 计算
|
||||
|
||||
## 修复的 pytdx Bug
|
||||
|
||||
|
||||
| # | 位置 | 问题 | 修复 |
|
||||
|---|------|------|------|
|
||||
| 1 | `xdxr_info` | 循环内始终读 `body[:7]`,所有记录字段相同 | 改为从当前 `pos` 读取,pos 正确推进 |
|
||||
@@ -260,7 +571,7 @@ main_net_inflow
|
||||
| 3 | `security_list` | `pre_close` 误当作整数价格 `/100` | 恢复为通达信自定义浮点解码 |
|
||||
| 4 | `transaction` | 最后一个字段被 `_` 丢弃 | 保留为 `unknown_last` |
|
||||
| 5 | `minute_time` | `reversed1` 字段被丢弃 | 保留为 `unknown_1` |
|
||||
| 6 | `xdxr_info` | 股本字段用 `float(uint32)` 直解,差约 374 倍 | 改用 `_decode_volume`(通达信自定义浮点),单位万股,与 `FinanceInfo` 完全吻合 |
|
||||
| 6 | `xdxr_info` | 股本字段用 `float(uint32)` 直解,差约 374 倍 | 改用 `_decode_volume`,单位万股,与 `FinanceInfo` 完全吻合 |
|
||||
| 7 | `security_quotes` | 涨停/跌停价映射错误或缺失 | 停止使用不可信协议位,改由业务规则计算 |
|
||||
|
||||
## 架构
|
||||
@@ -268,6 +579,18 @@ main_net_inflow
|
||||
```
|
||||
src/xmtdx/
|
||||
├── client.py # TdxClient / AsyncTdxClient(高层 API)
|
||||
├── ex/
|
||||
│ ├── client.py # ExTdxClient / AsyncExTdxClient(扩展行情)
|
||||
│ └── models.py # 扩展行情数据模型
|
||||
├── offline/ # 离线数据读取模块
|
||||
│ ├── paths.py # 路径检测与解析
|
||||
│ ├── daily_bar.py # 日线读取
|
||||
│ ├── min_bar.py # 分钟线读取
|
||||
│ ├── ex_daily_bar.py # 扩展市场日线
|
||||
│ ├── block.py # 板块数据读取
|
||||
│ ├── gbbq.py # 股本变迁(XOR 解密)
|
||||
│ ├── history_financial.py # 历史财务数据
|
||||
│ └── finders.py # 文件路径定位
|
||||
├── transport/
|
||||
│ ├── sync.py # TdxConnection(socket)+ ping_host / ping_all
|
||||
│ └── async_.py # AsyncTdxConnection(asyncio)
|
||||
@@ -276,7 +599,17 @@ src/xmtdx/
|
||||
└── models/ # 纯 dataclass,无业务逻辑
|
||||
```
|
||||
|
||||
commands 层不依赖 transport,可独立单测。transport 层负责 TCP、握手、帧解压、分发。
|
||||
commands 层不依赖 transport,可独立单测。transport 层负责 TCP、握手、帧解压、分发。offline 层直接读取本地二进制文件,不依赖 transport。
|
||||
|
||||
## 协议说明
|
||||
|
||||
通达信使用私有二进制 TCP 协议:
|
||||
|
||||
- **帧格式**:16 字节响应头(含 zipsize / unzipsize),body 按需 zlib 解压
|
||||
- **价格编码**:变长有符号整数(类 LEB128,bit8=继续,bit7=符号,首字节低 6 位 + 后续低 7 位)
|
||||
- **成交量编码**:4 字节自定义浮点(字节 3 = 指数,字节 0-2 = 精度),不可用于价格字段
|
||||
- **握手**:连接后必须顺序发送 3 条 setup 命令,响应丢弃
|
||||
- **价格存储**:整数 x 100,差分编码(相邻 tick 存 delta)
|
||||
|
||||
## 开发
|
||||
|
||||
@@ -287,22 +620,15 @@ python -m pytest tests/unit/
|
||||
# 集成测试(需要网络,默认跳过)
|
||||
XMTDX_LIVE=1 python -m pytest tests/integration/
|
||||
|
||||
# 未知字段探测脚本
|
||||
python scripts/probe_unknowns.py
|
||||
|
||||
# 类型检查
|
||||
mypy src/
|
||||
|
||||
# lint
|
||||
# lint + format
|
||||
ruff check src/ tests/
|
||||
ruff format --check src/ tests/
|
||||
```
|
||||
|
||||
## 协议说明
|
||||
## 致谢
|
||||
|
||||
通达信使用私有二进制 TCP 协议:
|
||||
|
||||
- **帧格式**:16 字节响应头(含 zipsize / unzipsize),body 按需 zlib 解压
|
||||
- **价格编码**:变长有符号整数(类 LEB128,bit8=继续,bit7=符号,首字节低 6 位 + 后续低 7 位)
|
||||
- **成交量编码**:4 字节自定义浮点(字节 3 = 指数,字节 0-2 = 精度),**不可用于价格字段**
|
||||
- **握手**:连接后必须顺序发送 3 条 setup 命令,响应丢弃
|
||||
- **价格存储**:整数 × 100,差分编码(相邻 tick 存 delta)
|
||||
- [pytdx](https://github.com/rainx/pytdx) — 离线数据读取模块(日线、分钟线、板块、股本变迁、历史财务的文件格式解析方法)借鉴自 pytdx 项目,感谢 rainx 及所有贡献者的工作
|
||||
- 通达信协议分析离不开开源社区的逆向工程成果
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
||||
"""演示:板块数据读取(本地 + 网络自动回退)。
|
||||
|
||||
系统板块获取优先级:
|
||||
1. 本地 .dat 文件(离线读取)
|
||||
2. TDX 服务器在线获取(自动回退)
|
||||
|
||||
自定义板块仅支持本地读取。
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from xmtdx import TdxClient
|
||||
from xmtdx.models.finance import TdxBlock
|
||||
from xmtdx.offline import detect_tdx_home, read_block_dat, read_customer_blocks
|
||||
|
||||
|
||||
def _print_blocks(blocks: list[TdxBlock], title: str) -> None:
|
||||
print(f"\n{title} ({len(blocks)} 个板块):")
|
||||
for block in blocks[:5]:
|
||||
codes_preview = ", ".join(block.codes[:5])
|
||||
suffix = "..." if len(block.codes) > 5 else ""
|
||||
print(f" {block.name} ({block.count}只): {codes_preview}{suffix}")
|
||||
if len(blocks) > 5:
|
||||
print(f" ... 还有 {len(blocks) - 5} 个板块")
|
||||
|
||||
|
||||
home = detect_tdx_home()
|
||||
|
||||
# --- 系统板块 ---
|
||||
print("=" * 60)
|
||||
print("系统板块")
|
||||
print("=" * 60)
|
||||
|
||||
vipdoc = Path(home) / "vipdoc" if home else None
|
||||
block_names = ["block_zs.dat", "block_gn.dat", "block_fg.dat"]
|
||||
block_labels = {
|
||||
"block_zs.dat": "行业板块",
|
||||
"block_gn.dat": "概念板块",
|
||||
"block_fg.dat": "风格板块",
|
||||
}
|
||||
|
||||
need_fetch = []
|
||||
for name in block_names:
|
||||
local_path = vipdoc / name if vipdoc else None
|
||||
if local_path and local_path.is_file():
|
||||
blocks = read_block_dat(local_path)
|
||||
_print_blocks(blocks, f"{block_labels[name]} ({name}, 本地)")
|
||||
else:
|
||||
print(f"\n{block_labels[name]}: 本地文件不存在,将从服务器获取")
|
||||
need_fetch.append(name)
|
||||
|
||||
# 本地没有的板块,通过网络获取
|
||||
if need_fetch:
|
||||
print(f"\n正在连接服务器获取 {len(need_fetch)} 个板块文件...")
|
||||
with TdxClient.from_best_host() as c:
|
||||
for name in need_fetch:
|
||||
blocks = c.get_block_info(name)
|
||||
_print_blocks(blocks, f"{block_labels[name]} ({name}, 网络)")
|
||||
|
||||
# --- 自定义板块 ---
|
||||
print(f"\n{'=' * 60}")
|
||||
print("自定义板块")
|
||||
print("=" * 60)
|
||||
|
||||
if home:
|
||||
blocknew_dir = Path(home) / "T0002" / "blocknew"
|
||||
if blocknew_dir.is_dir():
|
||||
blocks = read_customer_blocks(blocknew_dir)
|
||||
if blocks:
|
||||
print(f"\n共 {len(blocks)} 个自定义板块:")
|
||||
for block in blocks[:10]:
|
||||
codes_preview = ", ".join(block.codes[:5])
|
||||
suffix = "..." if len(block.codes) > 5 else ""
|
||||
print(f" {block.blockname} ({len(block.codes)}只): {codes_preview}{suffix}")
|
||||
else:
|
||||
print("未找到自定义板块数据")
|
||||
else:
|
||||
print(f"自定义板块目录不存在: {blocknew_dir}")
|
||||
else:
|
||||
print("需要本地通达信安装目录才能读取自定义板块")
|
||||
@@ -0,0 +1,43 @@
|
||||
"""演示:从本地通达信目录读取日线 K 线数据。
|
||||
|
||||
两种用法:
|
||||
1. 直接指定 .day 文件路径
|
||||
2. 通过 市场+代码 自动定位文件(需要设置 TDX_HOME 环境变量)
|
||||
|
||||
需要本地已安装通达信并下载过日线数据。
|
||||
"""
|
||||
|
||||
from xmtdx.offline import detect_tdx_home, read_daily_bars, find_daily_bar_file
|
||||
from xmtdx import Market
|
||||
|
||||
home = detect_tdx_home()
|
||||
if home is None:
|
||||
print("未检测到通达信安装目录,请设置 TDX_HOME 环境变量")
|
||||
print("例如: set TDX_HOME=C:\\new_jyplug")
|
||||
raise SystemExit(1)
|
||||
|
||||
print(f"通达信目录: {home}")
|
||||
|
||||
# --- 方式1: 通过 市场+代码 自动定位文件 ---
|
||||
filepath = find_daily_bar_file(Market.SH, "600000")
|
||||
print(f"\n文件路径: {filepath}")
|
||||
|
||||
bars = read_daily_bars(filepath)
|
||||
if not bars:
|
||||
print("未读取到数据,请确认通达信已下载该股票的日线数据")
|
||||
raise SystemExit(0)
|
||||
|
||||
# 最近 10 个交易日
|
||||
print(f"\n浦发银行 日线 (最近 {min(10, len(bars))} 个交易日):")
|
||||
print(f"{'日期':>12s} {'开盘':>8s} {'最高':>8s} {'最低':>8s} {'收盘':>8s} {'成交量':>10s}")
|
||||
for bar in bars[-10:]:
|
||||
print(
|
||||
f"{bar.year}-{bar.month:02d}-{bar.day:02d} "
|
||||
f"{bar.open:>8.2f} {bar.high:>8.2f} "
|
||||
f"{bar.low:>8.2f} {bar.close:>8.2f} "
|
||||
f"{bar.vol:>10.0f}"
|
||||
)
|
||||
|
||||
# --- 方式2: 直接指定文件路径 ---
|
||||
# from pathlib import Path
|
||||
# bars2 = read_daily_bars(Path(r"C:\new_jyplug\vipdoc\sz\lday\sz000001.day"))
|
||||
@@ -0,0 +1,80 @@
|
||||
"""演示:检测通达信安装目录与路径解析。
|
||||
|
||||
offline 模块的路径检测优先级:
|
||||
1. TDX_HOME 环境变量
|
||||
2. 平台常见路径猜测 (Windows: C:\\new_jyplug, C:\\new_tdx, D:\\... 等)
|
||||
|
||||
vipdoc 目录结构:
|
||||
vipdoc/
|
||||
├── sh/lday/ 上海日线 sh600000.day
|
||||
├── sh/fzline/ 上海5分钟线 sh600000.5
|
||||
├── sh/fzline/ 上海分钟线 sh600000.lc1 / .lc5
|
||||
├── sz/lday/ 深圳日线 sz000001.day
|
||||
├── sz/fzline/ 深圳5分钟线 sz000001.5
|
||||
├── sz/fzline/ 深圳分钟线 sz000001.lc1 / .lc5
|
||||
└── ds/ 扩展市场 29#A1801.day
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from xmtdx.offline import detect_tdx_home, resolve_vipdoc
|
||||
from xmtdx.offline import find_daily_bar_file, find_5min_bar_file, find_lc1_bar_file
|
||||
from xmtdx import Market
|
||||
|
||||
# --- 检测安装目录 ---
|
||||
print("=" * 60)
|
||||
print("通达信安装目录检测")
|
||||
print("=" * 60)
|
||||
|
||||
home = detect_tdx_home()
|
||||
if home:
|
||||
print(f"检测到: {home}")
|
||||
else:
|
||||
print("未检测到,可通过以下方式指定:")
|
||||
print(f" set TDX_HOME=C:\\new_jyplug")
|
||||
|
||||
# --- 手动指定路径 ---
|
||||
print(f"\n{'=' * 60}")
|
||||
print("手动指定 vipdoc 路径")
|
||||
print("=" * 60)
|
||||
|
||||
if home:
|
||||
vipdoc = resolve_vipdoc()
|
||||
print(f"vipdoc 目录: {vipdoc}")
|
||||
|
||||
# 列出 vipdoc 子目录
|
||||
if vipdoc.is_dir():
|
||||
for d in sorted(vipdoc.iterdir()):
|
||||
if d.is_dir():
|
||||
files = list(d.rglob("*"))
|
||||
print(f" {d.name}/ ({len(files)} 个文件)")
|
||||
else:
|
||||
print("(需要 TDX_HOME 才能自动解析)")
|
||||
|
||||
# --- 文件定位示例 ---
|
||||
print(f"\n{'=' * 60}")
|
||||
print("通过 市场+代码 定位文件")
|
||||
print("=" * 60)
|
||||
|
||||
if home:
|
||||
examples = [
|
||||
("浦发银行 日线", lambda: find_daily_bar_file(Market.SH, "600000")),
|
||||
("平安银行 日线", lambda: find_daily_bar_file(Market.SZ, "000001")),
|
||||
("浦发银行 5分钟", lambda: find_5min_bar_file(Market.SH, "600000")),
|
||||
("平安银行 1分钟", lambda: find_lc1_bar_file(Market.SZ, "000001")),
|
||||
]
|
||||
for label, finder in examples:
|
||||
p = finder()
|
||||
exists = "存在" if p.is_file() else "不存在"
|
||||
print(f" {label}: {p} ({exists})")
|
||||
else:
|
||||
print("(需要 TDX_HOME)")
|
||||
|
||||
# --- 设置环境变量的方式 ---
|
||||
print(f"\n{'=' * 60}")
|
||||
print("如何设置 TDX_HOME")
|
||||
print("=" * 60)
|
||||
print(" Windows CMD: set TDX_HOME=C:\\new_jyplug")
|
||||
print(" Windows PS: $env:TDX_HOME = 'C:\\new_jyplug'")
|
||||
print(" Linux/macOS: export TDX_HOME=/opt/new_tdx")
|
||||
@@ -0,0 +1,69 @@
|
||||
"""演示:从本地通达信目录读取扩展市场日线数据。
|
||||
|
||||
扩展市场包括:期货、港股、外盘等。
|
||||
文件位于 vipdoc/ds/ 目录下,如 29#A1801.day
|
||||
|
||||
需要本地已安装通达信并下载过扩展市场数据。
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from xmtdx.offline import detect_tdx_home, read_ex_daily_bars
|
||||
|
||||
home = detect_tdx_home()
|
||||
if home is None:
|
||||
print("未检测到通达信安装目录,请设置 TDX_HOME 环境变量")
|
||||
raise SystemExit(1)
|
||||
|
||||
vipdoc = Path(home) / "vipdoc" / "ds" / "lday"
|
||||
|
||||
# 列出 ds 目录下可用的 .day 文件
|
||||
day_files = sorted(vipdoc.glob("*.day")) if vipdoc.is_dir() else []
|
||||
if not day_files:
|
||||
print(f"扩展市场目录为空或不存在: {vipdoc}")
|
||||
print("请在通达信中下载扩展市场数据后再试")
|
||||
raise SystemExit(0)
|
||||
|
||||
print(f"可用文件 ({len(day_files)} 个):")
|
||||
for f in day_files[:10]:
|
||||
print(f" {f.name}")
|
||||
if len(day_files) > 10:
|
||||
print(f" ... 还有 {len(day_files) - 10} 个")
|
||||
|
||||
# 读取第一个文件作为示例
|
||||
sample = day_files[5]
|
||||
"""
|
||||
可用文件 (211 个):
|
||||
12#A_IXIC.day
|
||||
38#1_GDP.day
|
||||
38#1_GDPI.day
|
||||
38#1_MSR.day
|
||||
38#2_CGPI.day
|
||||
38#2_CPI.day
|
||||
38#2_PPCI.day
|
||||
38#2_PPI.day
|
||||
38#2_PPPI.day
|
||||
38#3_BCI.day
|
||||
... 还有 201 个
|
||||
|
||||
读取: 38#2_CPI.day
|
||||
共 250 条记录,最后 5 条:
|
||||
日期 开盘 最高 最低 收盘 结算
|
||||
2025-12-31 100.80 100.80 100.80 100.80 0.00
|
||||
2026-01-31 100.20 100.20 100.20 100.20 0.00
|
||||
2026-02-28 101.30 101.30 101.30 101.30 0.00
|
||||
2026-03-31 101.00 101.00 101.00 101.00 0.00
|
||||
2026-04-30 101.20 101.20 101.20 101.20 0.00
|
||||
"""
|
||||
print(f"\n读取: {sample.name}")
|
||||
bars = read_ex_daily_bars(sample)
|
||||
|
||||
if bars:
|
||||
print(f"共 {len(bars)} 条记录,最后 5 条:")
|
||||
print(f" {'日期':>12s} {'开盘':>8s} {'最高':>8s} {'最低':>8s} {'收盘':>8s} {'结算':>8s}")
|
||||
for bar in bars[-5:]:
|
||||
print(
|
||||
f" {bar.year}-{bar.month:02d}-{bar.day:02d} "
|
||||
f"{bar.open:>8.2f} {bar.high:>8.2f} "
|
||||
f"{bar.low:>8.2f} {bar.close:>8.2f} {bar.settlement:>8.2f}"
|
||||
)
|
||||
@@ -0,0 +1,53 @@
|
||||
"""演示:从本地通达信目录读取股本变迁数据。
|
||||
|
||||
股本变迁文件包含分红、送股、配股、扩缩股等历史记录。
|
||||
数据使用 XOR 加密存储,读取时会自动解密。
|
||||
|
||||
需要本地已安装通达信。
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from xmtdx.offline import detect_tdx_home, read_gbbq
|
||||
|
||||
home = detect_tdx_home()
|
||||
if home is None:
|
||||
print("未检测到通达信安装目录,请设置 TDX_HOME 环境变量")
|
||||
raise SystemExit(1)
|
||||
|
||||
gbbq_path = Path(home) / "T0002" / "hq_cache" / "gbbq"
|
||||
if not gbbq_path.is_file():
|
||||
# 尝试其他可能的路径
|
||||
gbbq_path = Path(home) / "T0002" / "gbbq"
|
||||
|
||||
if not gbbq_path.is_file():
|
||||
print(f"股本变迁文件不存在")
|
||||
print(f" 尝试过: {Path(home) / 'T0002' / 'hq_cache' / 'gbbq'}")
|
||||
print(f" 尝试过: {Path(home) / 'T0002' / 'gbbq'}")
|
||||
print("请在通达信中确认 gbbq 文件的位置")
|
||||
raise SystemExit(0)
|
||||
|
||||
print(f"读取: {gbbq_path}")
|
||||
records = read_gbbq(gbbq_path)
|
||||
|
||||
if not records:
|
||||
print("未读取到数据")
|
||||
raise SystemExit(0)
|
||||
|
||||
print(f"共 {len(records)} 条股本变迁记录\n")
|
||||
|
||||
# 按代码分组统计
|
||||
from collections import Counter
|
||||
|
||||
code_counts = Counter(r.code for r in records)
|
||||
print(f"涉及 {len(code_counts)} 只股票")
|
||||
|
||||
# 显示前 20 条记录
|
||||
print(f"\n前 20 条记录:")
|
||||
print(f" {'市场':>4s} {'代码':>8s} {'日期':>10s} {'类别':>4s} {'红利/盘前流通':>12s} {'配股价/前总股本':>14s}")
|
||||
for rec in records[:20]:
|
||||
print(
|
||||
f" {rec.market:>4d} {rec.code:>8s} {rec.datetime:>10d} "
|
||||
f"{rec.category:>4d} {rec.hongli_panqianliutong:>12.4f} "
|
||||
f"{rec.peigujia_qianzongguben:>14.4f}"
|
||||
)
|
||||
@@ -0,0 +1,68 @@
|
||||
"""演示:从本地通达信目录读取历史财务数据。
|
||||
|
||||
支持两种文件格式:
|
||||
- .dat 文件: 直接读取
|
||||
- .zip 文件: 自动解压后读取(如 gpcw20260331.zip)
|
||||
|
||||
文件可通过 TdxClient.get_financial_file_list() + download_file() 获取,
|
||||
也可从 calc 服务器下载。
|
||||
|
||||
需要本地有 gpcw*.dat 或 gpcw*.zip 文件。
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from xmtdx.offline import detect_tdx_home, read_history_financial
|
||||
|
||||
home = detect_tdx_home()
|
||||
if home is None:
|
||||
print("未检测到通达信安装目录,请设置 TDX_HOME 环境变量")
|
||||
raise SystemExit(1)
|
||||
|
||||
# 常见的历史财务数据存放位置
|
||||
candidates = [
|
||||
Path(home) / "vipdoc" / "fin",
|
||||
Path(home) / "T0002" / "fin",
|
||||
Path.home() / "Downloads",
|
||||
Path("."),
|
||||
]
|
||||
|
||||
# 查找可用的财务数据文件
|
||||
fin_files: list[Path] = []
|
||||
for d in candidates:
|
||||
if d.is_dir():
|
||||
fin_files.extend(d.glob("gpcw*.dat"))
|
||||
fin_files.extend(d.glob("gpcw*.zip"))
|
||||
|
||||
if not fin_files:
|
||||
print("未找到历史财务数据文件 (gpcw*.dat 或 gpcw*.zip)")
|
||||
print("\n获取方式:")
|
||||
print(" 1. 使用 TdxClient.get_financial_file_list() 查询可用文件")
|
||||
print(" 2. 使用 TdxClient.download_file() 下载到本地")
|
||||
raise SystemExit(0)
|
||||
|
||||
print(f"找到 {len(fin_files)} 个财务数据文件:")
|
||||
for f in fin_files:
|
||||
print(f" {f}")
|
||||
|
||||
# 读取第一个文件
|
||||
sample = fin_files[0]
|
||||
print(f"\n读取: {sample.name}")
|
||||
records = read_history_financial(sample)
|
||||
|
||||
if not records:
|
||||
print("未读取到数据")
|
||||
raise SystemExit(0)
|
||||
|
||||
print(f"共 {len(records)} 条记录")
|
||||
print(f"\n前 10 条:")
|
||||
print(f" {'代码':>8s} {'市场':>4s} {'报告期':>10s} {'字段数':>6s}")
|
||||
for rec in records[:10]:
|
||||
print(f" {rec.code:>8s} {rec.market.name:>4s} {rec.report_date:>10d} {len(rec.fields):>6d}")
|
||||
|
||||
# 展示一只股票的详细数据
|
||||
if records:
|
||||
rec = records[0]
|
||||
print(f"\n{rec.code} ({rec.market.name}) 报告期 {rec.report_date} 的前 20 个字段:")
|
||||
for i, val in enumerate(rec.fields[:20]):
|
||||
print(f" 字段{i + 1:3d}: {val:>15.4f}")
|
||||
@@ -0,0 +1,83 @@
|
||||
"""演示:从本地通达信目录读取分钟 K 线数据。
|
||||
|
||||
支持三种文件格式:
|
||||
- .5 文件: vipdoc/{sh,sz}/fzline/ (OHLC 为整数÷100)
|
||||
- .lc1 文件: vipdoc/{sh,sz}/fzline/ (OHLC 为浮点数)
|
||||
- .lc5 文件: vipdoc/{sh,sz}/fzline/ (OHLC 为浮点数)
|
||||
|
||||
需要本地已安装通达信并下载过分钟数据。
|
||||
"""
|
||||
|
||||
from xmtdx.offline import (
|
||||
detect_tdx_home,
|
||||
read_5min_bars,
|
||||
read_lc_min_bars,
|
||||
find_5min_bar_file,
|
||||
find_lc1_bar_file,
|
||||
find_lc5_bar_file,
|
||||
)
|
||||
from xmtdx import Market
|
||||
|
||||
home = detect_tdx_home()
|
||||
if home is None:
|
||||
print("未检测到通达信安装目录,请设置 TDX_HOME 环境变量")
|
||||
raise SystemExit(1)
|
||||
|
||||
"""
|
||||
# --- .5 文件 (5 分钟线) ---
|
||||
print("=" * 60)
|
||||
print("5 分钟线 (.5 文件)")
|
||||
print("=" * 60)
|
||||
|
||||
filepath = find_5min_bar_file(Market.SH, "600000")
|
||||
bars = read_5min_bars(filepath)
|
||||
if bars:
|
||||
print(f"共 {len(bars)} 条记录,最后 5 条:")
|
||||
for bar in bars[-5:]:
|
||||
print(
|
||||
f" {bar.year}-{bar.month:02d}-{bar.day:02d} "
|
||||
f"{bar.hour:02d}:{bar.minute:02d} "
|
||||
f"开{bar.open:>7.2f} 高{bar.high:>7.2f} "
|
||||
f"低{bar.low:>7.2f} 收{bar.close:>7.2f} 量{bar.vol:>8.0f}"
|
||||
)
|
||||
else:
|
||||
print("未读取到数据")
|
||||
|
||||
# --- .lc1 文件 (1 分钟线) ---
|
||||
print(f"\n{'=' * 60}")
|
||||
print("1 分钟线 (.lc1 文件)")
|
||||
print("=" * 60)
|
||||
|
||||
filepath = find_lc1_bar_file(Market.SH, "600000")
|
||||
bars = read_lc_min_bars(filepath)
|
||||
if bars:
|
||||
print(f"共 {len(bars)} 条记录,最后 5 条:")
|
||||
for bar in bars[-5:]:
|
||||
print(
|
||||
f" {bar.year}-{bar.month:02d}-{bar.day:02d} "
|
||||
f"{bar.hour:02d}:{bar.minute:02d} "
|
||||
f"开{bar.open:>7.2f} 高{bar.high:>7.2f} "
|
||||
f"低{bar.low:>7.2f} 收{bar.close:>7.2f} 量{bar.vol:>8.0f}"
|
||||
)
|
||||
else:
|
||||
print("未读取到数据")
|
||||
"""
|
||||
|
||||
# --- .lc5 文件 (5 分钟线) ---
|
||||
print(f"\n{'=' * 60}")
|
||||
print("5 分钟线 (.lc5 文件)")
|
||||
print("=" * 60)
|
||||
|
||||
filepath = find_lc5_bar_file(Market.SZ, "002176")
|
||||
bars = read_lc_min_bars(filepath)
|
||||
if bars:
|
||||
print(f"共 {len(bars)} 条记录,最后 5 条:")
|
||||
for bar in bars[-5:]:
|
||||
print(
|
||||
f" {bar.year}-{bar.month:02d}-{bar.day:02d} "
|
||||
f"{bar.hour:02d}:{bar.minute:02d} "
|
||||
f"开{bar.open:>7.2f} 高{bar.high:>7.2f} "
|
||||
f"低{bar.low:>7.2f} 收{bar.close:>7.2f} 量{bar.vol:>8.0f}"
|
||||
)
|
||||
else:
|
||||
print("未读取到数据")
|
||||
@@ -0,0 +1,11 @@
|
||||
"""xmtdx.ex — 通达信扩展行情(期货、港股、外股等,端口 7727)。"""
|
||||
|
||||
from .client import AsyncExTdxClient, ExTdxClient
|
||||
from .models import KNOWN_EX_HOSTS, KNOWN_EX_MARKETS
|
||||
|
||||
__all__ = [
|
||||
"ExTdxClient",
|
||||
"AsyncExTdxClient",
|
||||
"KNOWN_EX_HOSTS",
|
||||
"KNOWN_EX_MARKETS",
|
||||
]
|
||||
@@ -0,0 +1,439 @@
|
||||
"""扩展行情高层 API:ExTdxClient(同步)和 AsyncExTdxClient(asyncio)。"""
|
||||
|
||||
import asyncio
|
||||
from collections import OrderedDict
|
||||
from types import TracebackType
|
||||
from typing import TypeVar
|
||||
|
||||
from ..commands.base import BaseCommand
|
||||
from ..exceptions import TdxConnectionError
|
||||
from .commands.get_history_bars_range import GetExHistoryInstrumentBarsRangeCmd
|
||||
from .commands.get_instrument_bars import GetExInstrumentBarsCmd
|
||||
from .commands.get_instrument_count import GetExInstrumentCountCmd
|
||||
from .commands.get_instrument_info import GetExInstrumentInfoCmd
|
||||
from .commands.get_instrument_quote import GetExInstrumentQuoteCmd
|
||||
from .commands.get_instrument_quote_list import GetExInstrumentQuoteListCmd
|
||||
from .commands.get_markets import GetExMarketsCmd
|
||||
from .commands.get_minute_time import (
|
||||
GetExHistoryMinuteTimeDataCmd,
|
||||
GetExMinuteTimeDataCmd,
|
||||
)
|
||||
from .commands.get_transaction import (
|
||||
GetExHistoryTransactionDataCmd,
|
||||
GetExTransactionDataCmd,
|
||||
)
|
||||
from .models import (
|
||||
KNOWN_EX_HOSTS,
|
||||
ExInstrumentBar,
|
||||
ExInstrumentInfo,
|
||||
ExInstrumentQuote,
|
||||
ExMarketInfo,
|
||||
ExMinuteBar,
|
||||
ExTransactionRecord,
|
||||
)
|
||||
from .transport.async_ import AsyncExTdxConnection
|
||||
from .transport.sync import ExTdxConnection, ping_ex_all
|
||||
|
||||
_DEFAULT_EX_PORT = 7727
|
||||
_T = TypeVar("_T")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 同步客户端
|
||||
# ============================================================
|
||||
|
||||
|
||||
class ExTdxClient:
|
||||
"""同步扩展行情客户端(期货、港股、外股等,端口 7727)。
|
||||
|
||||
使用示例::
|
||||
|
||||
with ExTdxClient("61.152.107.141") as c:
|
||||
markets = c.get_markets()
|
||||
quote = c.get_instrument_quote(47, "IFL0")
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
host: str = KNOWN_EX_HOSTS[0],
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = 15.0,
|
||||
auto_reconnect: bool = True,
|
||||
) -> None:
|
||||
self._host = host
|
||||
self._port = port
|
||||
self._timeout = timeout
|
||||
self._auto_reconnect = auto_reconnect
|
||||
self._conn = ExTdxConnection(host, port, timeout)
|
||||
|
||||
@classmethod
|
||||
def from_best_host(
|
||||
cls,
|
||||
hosts: list[str] | None = None,
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = 15.0,
|
||||
ping_timeout: float = 5.0,
|
||||
auto_reconnect: bool = True,
|
||||
) -> "ExTdxClient":
|
||||
"""测量所有扩展行情服务器延迟,选最低延迟建立连接。"""
|
||||
ranked = ping_ex_all(hosts, port, ping_timeout)
|
||||
best = ranked[0][0] if ranked else (hosts or KNOWN_EX_HOSTS)[0]
|
||||
return cls(best, port, timeout, auto_reconnect)
|
||||
|
||||
@staticmethod
|
||||
def ping_all(
|
||||
hosts: list[str] | None = None,
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = 5.0,
|
||||
) -> list[tuple[str, float]]:
|
||||
return ping_ex_all(hosts, port, timeout)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 连接管理
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def connect(self) -> None:
|
||||
self._conn.connect()
|
||||
|
||||
def close(self) -> None:
|
||||
self._conn.close()
|
||||
|
||||
def __enter__(self) -> "ExTdxClient":
|
||||
self.connect()
|
||||
return self
|
||||
|
||||
def __exit__(
|
||||
self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_val: BaseException | None,
|
||||
exc_tb: TracebackType | None,
|
||||
) -> None:
|
||||
self.close()
|
||||
|
||||
def _execute(self, cmd: "BaseCommand[_T]") -> _T:
|
||||
try:
|
||||
return self._conn.execute(cmd)
|
||||
except TdxConnectionError:
|
||||
if not self._auto_reconnect:
|
||||
raise
|
||||
self._conn.close()
|
||||
self._conn = ExTdxConnection(self._host, self._port, self._timeout)
|
||||
self._conn.connect()
|
||||
return self._conn.execute(cmd)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 市场信息
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def get_markets(self) -> list[ExMarketInfo]:
|
||||
"""获取扩展行情支持的市场列表。"""
|
||||
return self._execute(GetExMarketsCmd())
|
||||
|
||||
def get_instrument_count(self) -> int:
|
||||
"""获取扩展行情商品总数。"""
|
||||
return self._execute(GetExInstrumentCountCmd())
|
||||
|
||||
def get_instrument_info(self, start: int, count: int = 100) -> list[ExInstrumentInfo]:
|
||||
"""获取商品信息列表(分页)。"""
|
||||
return self._execute(GetExInstrumentInfoCmd(start, count))
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 行情
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def get_instrument_quote(self, market: int, code: str) -> ExInstrumentQuote | None:
|
||||
"""获取单个商品五档实时行情。"""
|
||||
return self._execute(GetExInstrumentQuoteCmd(market, code))
|
||||
|
||||
def get_instrument_quote_list(
|
||||
self,
|
||||
market: int,
|
||||
category: int,
|
||||
start: int = 0,
|
||||
count: int = 80,
|
||||
) -> list[OrderedDict[str, object]]:
|
||||
"""按类别获取商品行情列表。"""
|
||||
return self._execute(GetExInstrumentQuoteListCmd(market, category, start, count))
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# K线
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def get_instrument_bars(
|
||||
self,
|
||||
category: int,
|
||||
market: int,
|
||||
code: str,
|
||||
start: int = 0,
|
||||
count: int = 700,
|
||||
) -> list[ExInstrumentBar]:
|
||||
"""获取K线数据。"""
|
||||
return self._execute(GetExInstrumentBarsCmd(category, market, code, start, count))
|
||||
|
||||
def get_history_instrument_bars_range(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
start_date: int,
|
||||
end_date: int,
|
||||
) -> list[ExInstrumentBar]:
|
||||
"""按日期范围获取历史K线。"""
|
||||
return self._execute(GetExHistoryInstrumentBarsRangeCmd(market, code, start_date, end_date))
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 分时
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def get_minute_time_data(self, market: int, code: str) -> list[ExMinuteBar]:
|
||||
"""获取当日分时行情数据。"""
|
||||
return self._execute(GetExMinuteTimeDataCmd(market, code))
|
||||
|
||||
def get_history_minute_time_data(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
date: int,
|
||||
) -> list[ExMinuteBar]:
|
||||
"""获取历史某日分时行情数据(date: YYYYMMDD)。"""
|
||||
return self._execute(GetExHistoryMinuteTimeDataCmd(market, code, date))
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 成交
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
def get_transaction_data(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
start: int = 0,
|
||||
count: int = 1800,
|
||||
) -> list[ExTransactionRecord]:
|
||||
"""获取当日分笔成交数据。"""
|
||||
return self._execute(GetExTransactionDataCmd(market, code, start, count))
|
||||
|
||||
def get_history_transaction_data(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
date: int,
|
||||
start: int = 0,
|
||||
count: int = 1800,
|
||||
) -> list[ExTransactionRecord]:
|
||||
"""获取历史某日分笔成交数据(date: YYYYMMDD)。"""
|
||||
return self._execute(GetExHistoryTransactionDataCmd(market, code, date, start, count))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 异步客户端
|
||||
# ============================================================
|
||||
|
||||
|
||||
class AsyncExTdxClient:
|
||||
"""异步扩展行情客户端(asyncio,端口 7727)。
|
||||
|
||||
使用示例::
|
||||
|
||||
async with AsyncExTdxClient("61.152.107.141") as c:
|
||||
markets = await c.get_markets()
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
host: str = KNOWN_EX_HOSTS[0],
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = 15.0,
|
||||
auto_reconnect: bool = True,
|
||||
heartbeat_interval: float = 60.0,
|
||||
) -> None:
|
||||
self._host = host
|
||||
self._port = port
|
||||
self._timeout = timeout
|
||||
self._auto_reconnect = auto_reconnect
|
||||
self._heartbeat_interval = heartbeat_interval
|
||||
self._conn = AsyncExTdxConnection(host, port, timeout)
|
||||
self._execute_lock = asyncio.Lock()
|
||||
self._heartbeat_task: asyncio.Task[None] | None = None
|
||||
|
||||
@classmethod
|
||||
def from_best_host(
|
||||
cls,
|
||||
hosts: list[str] | None = None,
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = 15.0,
|
||||
ping_timeout: float = 5.0,
|
||||
auto_reconnect: bool = True,
|
||||
heartbeat_interval: float = 60.0,
|
||||
) -> "AsyncExTdxClient":
|
||||
ranked = ping_ex_all(hosts, port, ping_timeout)
|
||||
best = ranked[0][0] if ranked else (hosts or KNOWN_EX_HOSTS)[0]
|
||||
return cls(best, port, timeout, auto_reconnect, heartbeat_interval)
|
||||
|
||||
@staticmethod
|
||||
def ping_all(
|
||||
hosts: list[str] | None = None,
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = 5.0,
|
||||
) -> list[tuple[str, float]]:
|
||||
return ping_ex_all(hosts, port, timeout)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 连接管理
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
async def connect(self) -> None:
|
||||
await self._conn.connect()
|
||||
self._start_heartbeat()
|
||||
|
||||
async def close(self) -> None:
|
||||
await self._stop_heartbeat()
|
||||
await self._conn.close()
|
||||
|
||||
async def __aenter__(self) -> "AsyncExTdxClient":
|
||||
await self.connect()
|
||||
return self
|
||||
|
||||
async def __aexit__(
|
||||
self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_val: BaseException | None,
|
||||
exc_tb: TracebackType | None,
|
||||
) -> None:
|
||||
await self.close()
|
||||
|
||||
def _start_heartbeat(self) -> None:
|
||||
if self._heartbeat_interval <= 0:
|
||||
return
|
||||
if self._heartbeat_task is not None:
|
||||
self._heartbeat_task.cancel()
|
||||
self._heartbeat_task = asyncio.create_task(self._heartbeat_loop())
|
||||
|
||||
async def _stop_heartbeat(self) -> None:
|
||||
if self._heartbeat_task:
|
||||
self._heartbeat_task.cancel()
|
||||
try:
|
||||
await self._heartbeat_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
self._heartbeat_task = None
|
||||
|
||||
async def _heartbeat_loop(self) -> None:
|
||||
while True:
|
||||
try:
|
||||
await asyncio.sleep(self._heartbeat_interval)
|
||||
await self.get_instrument_count()
|
||||
except asyncio.CancelledError:
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
async def _execute(self, cmd: "BaseCommand[_T]") -> _T:
|
||||
async with self._execute_lock:
|
||||
try:
|
||||
return await self._conn.execute(cmd)
|
||||
except TdxConnectionError:
|
||||
if not self._auto_reconnect:
|
||||
raise
|
||||
await self._conn.close()
|
||||
self._conn = AsyncExTdxConnection(self._host, self._port, self._timeout)
|
||||
await self._conn.connect()
|
||||
return await self._conn.execute(cmd)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 市场信息
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
async def get_markets(self) -> list[ExMarketInfo]:
|
||||
return await self._execute(GetExMarketsCmd())
|
||||
|
||||
async def get_instrument_count(self) -> int:
|
||||
return await self._execute(GetExInstrumentCountCmd())
|
||||
|
||||
async def get_instrument_info(
|
||||
self,
|
||||
start: int,
|
||||
count: int = 100,
|
||||
) -> list[ExInstrumentInfo]:
|
||||
return await self._execute(GetExInstrumentInfoCmd(start, count))
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 行情
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
async def get_instrument_quote(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
) -> ExInstrumentQuote | None:
|
||||
return await self._execute(GetExInstrumentQuoteCmd(market, code))
|
||||
|
||||
async def get_instrument_quote_list(
|
||||
self,
|
||||
market: int,
|
||||
category: int,
|
||||
start: int = 0,
|
||||
count: int = 80,
|
||||
) -> list[OrderedDict[str, object]]:
|
||||
return await self._execute(GetExInstrumentQuoteListCmd(market, category, start, count))
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# K线
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
async def get_instrument_bars(
|
||||
self,
|
||||
category: int,
|
||||
market: int,
|
||||
code: str,
|
||||
start: int = 0,
|
||||
count: int = 700,
|
||||
) -> list[ExInstrumentBar]:
|
||||
return await self._execute(GetExInstrumentBarsCmd(category, market, code, start, count))
|
||||
|
||||
async def get_history_instrument_bars_range(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
start_date: int,
|
||||
end_date: int,
|
||||
) -> list[ExInstrumentBar]:
|
||||
return await self._execute(
|
||||
GetExHistoryInstrumentBarsRangeCmd(market, code, start_date, end_date)
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 分时
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
async def get_minute_time_data(self, market: int, code: str) -> list[ExMinuteBar]:
|
||||
return await self._execute(GetExMinuteTimeDataCmd(market, code))
|
||||
|
||||
async def get_history_minute_time_data(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
date: int,
|
||||
) -> list[ExMinuteBar]:
|
||||
return await self._execute(GetExHistoryMinuteTimeDataCmd(market, code, date))
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# 成交
|
||||
# ------------------------------------------------------------------ #
|
||||
|
||||
async def get_transaction_data(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
start: int = 0,
|
||||
count: int = 1800,
|
||||
) -> list[ExTransactionRecord]:
|
||||
return await self._execute(GetExTransactionDataCmd(market, code, start, count))
|
||||
|
||||
async def get_history_transaction_data(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
date: int,
|
||||
start: int = 0,
|
||||
count: int = 1800,
|
||||
) -> list[ExTransactionRecord]:
|
||||
return await self._execute(GetExHistoryTransactionDataCmd(market, code, date, start, count))
|
||||
@@ -0,0 +1 @@
|
||||
"""扩展行情命令模块。"""
|
||||
@@ -0,0 +1,76 @@
|
||||
"""获取扩展行情历史K线(按日期范围)。"""
|
||||
|
||||
import struct
|
||||
|
||||
from ...commands.base import BaseCommand
|
||||
from ..models import ExInstrumentBar
|
||||
|
||||
|
||||
class GetExHistoryInstrumentBarsRangeCmd(BaseCommand[list[ExInstrumentBar]]):
|
||||
"""按日期范围获取历史K线数据。"""
|
||||
|
||||
_seqid: int = 1
|
||||
|
||||
def __init__(self, market: int, code: str, start_date: int, end_date: int) -> None:
|
||||
self.market = market
|
||||
self.code = code.encode("utf-8")
|
||||
self.start_date = start_date
|
||||
self.end_date = end_date
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
pkg = bytearray.fromhex("01")
|
||||
pkg.extend(struct.pack("<B", self._seqid))
|
||||
self.__class__._seqid += 1
|
||||
pkg.extend(bytearray.fromhex("38 92 00 01 16 00 16 00 0D 24"))
|
||||
pkg.extend(struct.pack("<B9s", self.market, self.code))
|
||||
pkg.extend(bytearray.fromhex("07 00"))
|
||||
pkg.extend(struct.pack("<II", self.start_date, self.end_date))
|
||||
return bytes(pkg)
|
||||
|
||||
@staticmethod
|
||||
def _parse_date(num: int) -> tuple[int, int, int]:
|
||||
year = num // 2048 + 2004
|
||||
month = (num % 2048) // 100
|
||||
day = (num % 2048) % 100
|
||||
return year, month, day
|
||||
|
||||
@staticmethod
|
||||
def _parse_time(num: int) -> tuple[int, int]:
|
||||
return num // 60, num % 60
|
||||
|
||||
def parse_response(self, body: bytes) -> list[ExInstrumentBar]:
|
||||
pos = 12 # skip 12-byte header
|
||||
if pos + 2 > len(body):
|
||||
return []
|
||||
(ret_count,) = struct.unpack("<H", body[pos : pos + 2])
|
||||
pos += 2
|
||||
results: list[ExInstrumentBar] = []
|
||||
for _ in range(ret_count):
|
||||
if pos + 32 > len(body):
|
||||
break
|
||||
record_start = pos
|
||||
(d1, d2, open_p, high, low, close_p, position, trade, settlement) = struct.unpack(
|
||||
"<HHffffIIf",
|
||||
body[pos : pos + 32],
|
||||
)
|
||||
pos += 32
|
||||
year, month, day = self._parse_date(d1)
|
||||
hour, minute = self._parse_time(d2)
|
||||
results.append(
|
||||
ExInstrumentBar(
|
||||
open=open_p,
|
||||
high=high,
|
||||
low=low,
|
||||
close=close_p,
|
||||
position=position,
|
||||
trade=trade,
|
||||
amount=settlement,
|
||||
year=year,
|
||||
month=month,
|
||||
day=day,
|
||||
hour=hour,
|
||||
minute=minute,
|
||||
_raw=body[record_start:pos],
|
||||
)
|
||||
)
|
||||
return results
|
||||
@@ -0,0 +1,74 @@
|
||||
"""获取扩展行情K线数据。"""
|
||||
|
||||
import struct
|
||||
|
||||
from ...codec.datetime_ import get_datetime
|
||||
from ...commands.base import BaseCommand
|
||||
from ..models import ExInstrumentBar
|
||||
|
||||
|
||||
class GetExInstrumentBarsCmd(BaseCommand[list[ExInstrumentBar]]):
|
||||
"""获取K线数据(扩展行情版本,支持期货/港股等)。"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
category: int,
|
||||
market: int,
|
||||
code: str,
|
||||
start: int = 0,
|
||||
count: int = 700,
|
||||
) -> None:
|
||||
self.category = category
|
||||
self.market = market
|
||||
self.code = code.encode("utf-8")
|
||||
self.start = start
|
||||
self.count = count
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
header = bytes.fromhex("01 01 08 6a 01 01 16 00 16 00 ff 23")
|
||||
return header + struct.pack(
|
||||
"<B9sHHIH",
|
||||
self.market,
|
||||
self.code,
|
||||
self.category,
|
||||
1,
|
||||
self.start,
|
||||
self.count,
|
||||
)
|
||||
|
||||
def parse_response(self, body: bytes) -> list[ExInstrumentBar]:
|
||||
pos = 18 # skip 18-byte header
|
||||
if pos + 2 > len(body):
|
||||
return []
|
||||
(ret_count,) = struct.unpack("<H", body[pos : pos + 2])
|
||||
pos += 2
|
||||
results: list[ExInstrumentBar] = []
|
||||
for _ in range(ret_count):
|
||||
record_start = pos
|
||||
year, month, day, hour, minute, pos = get_datetime(self.category, body, pos)
|
||||
if pos + 28 > len(body):
|
||||
break
|
||||
(open_p, high, low, close_p, position, trade, _price) = struct.unpack(
|
||||
"<ffffIIf",
|
||||
body[pos : pos + 28],
|
||||
)
|
||||
(amount,) = struct.unpack("<f", body[pos + 16 : pos + 20])
|
||||
pos += 28
|
||||
results.append(
|
||||
ExInstrumentBar(
|
||||
open=open_p,
|
||||
high=high,
|
||||
low=low,
|
||||
close=close_p,
|
||||
position=position,
|
||||
trade=trade,
|
||||
amount=amount,
|
||||
year=year,
|
||||
month=month,
|
||||
day=day,
|
||||
hour=hour,
|
||||
minute=minute,
|
||||
_raw=body[record_start:pos],
|
||||
)
|
||||
)
|
||||
return results
|
||||
@@ -0,0 +1,17 @@
|
||||
"""获取扩展行情商品数量。"""
|
||||
|
||||
from ..._binary import unpack_from
|
||||
from ...commands.base import BaseCommand
|
||||
|
||||
|
||||
class GetExInstrumentCountCmd(BaseCommand[int]):
|
||||
"""获取扩展行情市场中商品总数。"""
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
return bytes.fromhex("01 03 48 66 00 01 02 00 02 00 f0 23")
|
||||
|
||||
def parse_response(self, body: bytes) -> int:
|
||||
if len(body) < 23:
|
||||
return 0
|
||||
(count,) = unpack_from("<I", body, 19, "ex instrument count")
|
||||
return count
|
||||
@@ -0,0 +1,50 @@
|
||||
"""获取扩展行情商品信息。"""
|
||||
|
||||
import struct
|
||||
|
||||
from ...commands.base import BaseCommand
|
||||
from ..models import ExInstrumentInfo
|
||||
|
||||
|
||||
class GetExInstrumentInfoCmd(BaseCommand[list[ExInstrumentInfo]]):
|
||||
"""获取扩展行情市场中的商品信息列表。"""
|
||||
|
||||
def __init__(self, start: int, count: int = 100) -> None:
|
||||
self.start = start
|
||||
self.count = count
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
header = bytes.fromhex("01 04 48 67 00 01 08 00 08 00 f5 23")
|
||||
return header + struct.pack("<IH", self.start, self.count)
|
||||
|
||||
def parse_response(self, body: bytes) -> list[ExInstrumentInfo]:
|
||||
if len(body) < 6:
|
||||
return []
|
||||
pos = 0
|
||||
(_start, _count) = struct.unpack("<IH", body[pos : pos + 6])
|
||||
count = _count
|
||||
pos += 6
|
||||
results: list[ExInstrumentInfo] = []
|
||||
for _ in range(count):
|
||||
if pos + 64 > len(body):
|
||||
break
|
||||
raw = body[pos : pos + 64]
|
||||
(category, market, _unused, raw_code, raw_name, raw_desc) = struct.unpack(
|
||||
"<BB3s9s17s9s",
|
||||
raw[:40],
|
||||
)
|
||||
pos += 64
|
||||
code = raw_code.decode("gbk", errors="replace").rstrip("\x00")
|
||||
name = raw_name.decode("gbk", errors="replace").rstrip("\x00")
|
||||
desc = raw_desc.decode("gbk", errors="replace").rstrip("\x00")
|
||||
results.append(
|
||||
ExInstrumentInfo(
|
||||
category=category,
|
||||
market=market,
|
||||
code=code,
|
||||
name=name,
|
||||
desc=desc,
|
||||
_raw=raw,
|
||||
)
|
||||
)
|
||||
return results
|
||||
@@ -0,0 +1,103 @@
|
||||
"""获取扩展行情实时五档报价。"""
|
||||
|
||||
import struct
|
||||
|
||||
from ...commands.base import BaseCommand
|
||||
from ..models import ExInstrumentQuote
|
||||
|
||||
|
||||
class GetExInstrumentQuoteCmd(BaseCommand[ExInstrumentQuote | None]):
|
||||
"""获取单个商品的五档实时行情。"""
|
||||
|
||||
def __init__(self, market: int, code: str) -> None:
|
||||
self.market = market
|
||||
self.code = code.encode("utf-8")
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
header = bytes.fromhex("01 01 08 02 02 01 0c 00 0c 00 fa 23")
|
||||
return header + struct.pack("<B9s", self.market, self.code)
|
||||
|
||||
def parse_response(self, body: bytes) -> ExInstrumentQuote | None:
|
||||
if len(body) < 150:
|
||||
return None
|
||||
pos = 0
|
||||
(market, raw_code) = struct.unpack("<B9s", body[pos : pos + 10])
|
||||
pos += 10
|
||||
pos += 4 # skip 4 unknown bytes
|
||||
record_start = pos - 14
|
||||
(
|
||||
pre_close,
|
||||
open_price,
|
||||
high,
|
||||
low,
|
||||
price,
|
||||
kaicang,
|
||||
_unk1,
|
||||
zongliang,
|
||||
xianliang,
|
||||
_unk2,
|
||||
neipan,
|
||||
waipan,
|
||||
_unk3,
|
||||
chicang,
|
||||
b1,
|
||||
b2,
|
||||
b3,
|
||||
b4,
|
||||
b5,
|
||||
bv1,
|
||||
bv2,
|
||||
bv3,
|
||||
bv4,
|
||||
bv5,
|
||||
a1,
|
||||
a2,
|
||||
a3,
|
||||
a4,
|
||||
a5,
|
||||
av1,
|
||||
av2,
|
||||
av3,
|
||||
av4,
|
||||
av5,
|
||||
) = struct.unpack(
|
||||
"<fffffIIIIIIIIIfffffIIIIIfffffIIIII",
|
||||
body[pos : pos + 136],
|
||||
)
|
||||
code = raw_code.decode("utf-8", errors="replace").rstrip("\x00")
|
||||
return ExInstrumentQuote(
|
||||
market=market,
|
||||
code=code,
|
||||
pre_close=pre_close,
|
||||
open=open_price,
|
||||
high=high,
|
||||
low=low,
|
||||
price=price,
|
||||
kaicang=kaicang,
|
||||
zongliang=zongliang,
|
||||
xianliang=xianliang,
|
||||
neipan=neipan,
|
||||
waipan=waipan,
|
||||
chicang=chicang,
|
||||
bid1=b1,
|
||||
bid2=b2,
|
||||
bid3=b3,
|
||||
bid4=b4,
|
||||
bid5=b5,
|
||||
bid_vol1=bv1,
|
||||
bid_vol2=bv2,
|
||||
bid_vol3=bv3,
|
||||
bid_vol4=bv4,
|
||||
bid_vol5=bv5,
|
||||
ask1=a1,
|
||||
ask2=a2,
|
||||
ask3=a3,
|
||||
ask4=a4,
|
||||
ask5=a5,
|
||||
ask_vol1=av1,
|
||||
ask_vol2=av2,
|
||||
ask_vol3=av3,
|
||||
ask_vol4=av4,
|
||||
ask_vol5=av5,
|
||||
_raw=body[record_start : pos + 136],
|
||||
)
|
||||
@@ -0,0 +1,218 @@
|
||||
"""获取扩展行情商品列表行情。"""
|
||||
|
||||
import struct
|
||||
from collections import OrderedDict
|
||||
|
||||
from ...commands.base import BaseCommand
|
||||
from ...exceptions import TdxCommandError
|
||||
|
||||
|
||||
class GetExInstrumentQuoteListCmd(BaseCommand[list[OrderedDict[str, object]]]):
|
||||
"""按类别获取商品行情列表(期货/港股等)。"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
market: int,
|
||||
category: int,
|
||||
start: int = 0,
|
||||
count: int = 80,
|
||||
) -> None:
|
||||
self.market = market
|
||||
self.category = category
|
||||
self.start = start
|
||||
self.count = count
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
header = bytes.fromhex("01 c1 06 0b 00 02 0b 00 0b 00 00 24")
|
||||
return header + struct.pack(
|
||||
"<BHHHH",
|
||||
self.market,
|
||||
0,
|
||||
self.start,
|
||||
self.count,
|
||||
1,
|
||||
)
|
||||
|
||||
def parse_response(self, body: bytes) -> list[OrderedDict[str, object]]:
|
||||
if len(body) < 2:
|
||||
return []
|
||||
(num,) = struct.unpack("<H", body[0:2])
|
||||
pos = 2
|
||||
results: list[OrderedDict[str, object]] = []
|
||||
for _ in range(num):
|
||||
if pos + 10 > len(body):
|
||||
break
|
||||
(market, raw_code) = struct.unpack("<B9s", body[pos : pos + 10])
|
||||
code = raw_code.strip(b"\x00").decode("gbk", errors="replace")
|
||||
pos += 10
|
||||
if self.category == 3:
|
||||
pos = self._parse_futures(market, code, body, pos, results)
|
||||
elif self.category == 2:
|
||||
pos = self._parse_hk_stocks(market, code, body, pos, results)
|
||||
else:
|
||||
raise TdxCommandError(f"不支持的扩展行情类别: {self.category}")
|
||||
return results
|
||||
|
||||
@staticmethod
|
||||
def _parse_futures(
|
||||
market: int,
|
||||
code: str,
|
||||
body: bytes,
|
||||
pos: int,
|
||||
results: list[OrderedDict[str, object]],
|
||||
) -> int:
|
||||
if pos + 140 > len(body):
|
||||
return pos + 290
|
||||
(
|
||||
bi_shu,
|
||||
zuo_jie,
|
||||
jin_kai,
|
||||
zui_gao,
|
||||
zui_di,
|
||||
mai_chu,
|
||||
kai_cang,
|
||||
_unk1,
|
||||
zong_liang,
|
||||
xian_liang,
|
||||
zong_jin_e,
|
||||
nei_pan,
|
||||
wai_pan,
|
||||
_unk2,
|
||||
chi_cang_liang,
|
||||
mai_ru_jia,
|
||||
_u1,
|
||||
_u2,
|
||||
_u3,
|
||||
_u4,
|
||||
mai_ru_liang,
|
||||
_u5,
|
||||
_u6,
|
||||
_u7,
|
||||
_u8,
|
||||
mai_chu_jia,
|
||||
_u9,
|
||||
_u10,
|
||||
_u11,
|
||||
_u12,
|
||||
mai_chu_liang,
|
||||
_u13,
|
||||
_u14,
|
||||
_u15,
|
||||
) = struct.unpack("<IfffffIIIIfIIfIfIIIIIIIIIfIIIIIIIII", body[pos : pos + 140])
|
||||
pos += 290
|
||||
results.append(
|
||||
OrderedDict(
|
||||
[
|
||||
("market", market),
|
||||
("code", code),
|
||||
("BiShu", bi_shu),
|
||||
("ZuoJie", zuo_jie),
|
||||
("JinKai", jin_kai),
|
||||
("ZuiGao", zui_gao),
|
||||
("ZuiDi", zui_di),
|
||||
("MaiChu", mai_chu),
|
||||
("KaiCang", kai_cang),
|
||||
("ZongLiang", zong_liang),
|
||||
("XianLiang", xian_liang),
|
||||
("ZongJinE", zong_jin_e),
|
||||
("NeiPan", nei_pan),
|
||||
("WaiPan", wai_pan),
|
||||
("ChiCangLiang", chi_cang_liang),
|
||||
("MaiRuJia", mai_ru_jia),
|
||||
("MaiRuLiang", mai_ru_liang),
|
||||
("MaiChuJia", mai_chu_jia),
|
||||
("MaiChuLiang", mai_chu_liang),
|
||||
]
|
||||
)
|
||||
)
|
||||
return pos
|
||||
|
||||
@staticmethod
|
||||
def _parse_hk_stocks(
|
||||
market: int,
|
||||
code: str,
|
||||
body: bytes,
|
||||
pos: int,
|
||||
results: list[OrderedDict[str, object]],
|
||||
) -> int:
|
||||
if pos + 140 > len(body):
|
||||
return pos + 290
|
||||
(
|
||||
huo_yue_du,
|
||||
zuo_shou,
|
||||
jin_kai,
|
||||
zui_gao,
|
||||
zui_di,
|
||||
xian_jia,
|
||||
_unk1,
|
||||
mai_ru_jia,
|
||||
zong_liang,
|
||||
xian_liang,
|
||||
zong_jin_e,
|
||||
_unk2,
|
||||
_unk3,
|
||||
nei,
|
||||
wai,
|
||||
mrj1,
|
||||
mrj2,
|
||||
mrj3,
|
||||
mrj4,
|
||||
mrj5,
|
||||
mrl1,
|
||||
mrl2,
|
||||
mrl3,
|
||||
mrl4,
|
||||
mrl5,
|
||||
mcj1,
|
||||
mcj2,
|
||||
mcj3,
|
||||
mcj4,
|
||||
mcj5,
|
||||
mcl1,
|
||||
mcl2,
|
||||
mcl3,
|
||||
mcl4,
|
||||
mcl5,
|
||||
) = struct.unpack("<IfffffIfIIfIIIIfffffIIIIIfffffIIIII", body[pos : pos + 140])
|
||||
pos += 290
|
||||
results.append(
|
||||
OrderedDict(
|
||||
[
|
||||
("market", market),
|
||||
("code", code),
|
||||
("HuoYueDu", huo_yue_du),
|
||||
("ZuoShou", zuo_shou),
|
||||
("JinKai", jin_kai),
|
||||
("ZuiGao", zui_gao),
|
||||
("ZuiDi", zui_di),
|
||||
("XianJia", xian_jia),
|
||||
("MaiRuJia", mai_ru_jia),
|
||||
("ZongLiang", zong_liang),
|
||||
("XianLiang", xian_liang),
|
||||
("ZongJinE", zong_jin_e),
|
||||
("Nei", nei),
|
||||
("Wai", wai),
|
||||
("MaiRuJia1", mrj1),
|
||||
("MaiRuJia2", mrj2),
|
||||
("MaiRuJia3", mrj3),
|
||||
("MaiRuJia4", mrj4),
|
||||
("MaiRuJia5", mrj5),
|
||||
("MaiRuLiang1", mrl1),
|
||||
("MaiRuLiang2", mrl2),
|
||||
("MaiRuLiang3", mrl3),
|
||||
("MaiRuLiang4", mrl4),
|
||||
("MaiRuLiang5", mrl5),
|
||||
("MaiChuJia1", mcj1),
|
||||
("MaiChuJia2", mcj2),
|
||||
("MaiChuJia3", mcj3),
|
||||
("MaiChuJia4", mcj4),
|
||||
("MaiChuJia5", mcj5),
|
||||
("MaiChuLiang1", mcl1),
|
||||
("MaiChuLiang2", mcl2),
|
||||
("MaiChuLiang3", mcl3),
|
||||
("MaiChuLiang4", mcl4),
|
||||
("MaiChuLiang5", mcl5),
|
||||
]
|
||||
)
|
||||
)
|
||||
return pos
|
||||
@@ -0,0 +1,41 @@
|
||||
"""获取扩展行情市场列表。"""
|
||||
|
||||
import struct
|
||||
|
||||
from ..._binary import unpack_from
|
||||
from ...commands.base import BaseCommand
|
||||
from ..models import ExMarketInfo
|
||||
|
||||
|
||||
class GetExMarketsCmd(BaseCommand[list[ExMarketInfo]]):
|
||||
"""获取扩展行情支持的市场列表。"""
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
return bytes.fromhex("01 02 48 69 00 01 02 00 02 00 f4 23")
|
||||
|
||||
def parse_response(self, body: bytes) -> list[ExMarketInfo]:
|
||||
if len(body) < 2:
|
||||
return []
|
||||
(count,) = unpack_from("<H", body, 0, "ex markets count")
|
||||
pos = 2
|
||||
results: list[ExMarketInfo] = []
|
||||
for _ in range(count):
|
||||
if pos + 64 > len(body):
|
||||
break
|
||||
raw = body[pos : pos + 64]
|
||||
(category, raw_name, market, raw_short_name) = struct.unpack("<B32sB2s", raw[:36])
|
||||
pos += 64
|
||||
if category == 0 and market == 0:
|
||||
continue
|
||||
name = raw_name.decode("gbk", errors="replace").rstrip("\x00")
|
||||
short_name = raw_short_name.decode("gbk", errors="replace").rstrip("\x00")
|
||||
results.append(
|
||||
ExMarketInfo(
|
||||
market=market,
|
||||
category=category,
|
||||
name=name,
|
||||
short_name=short_name,
|
||||
_raw=raw,
|
||||
)
|
||||
)
|
||||
return results
|
||||
@@ -0,0 +1,74 @@
|
||||
"""获取扩展行情分时数据(当日 + 历史)。"""
|
||||
|
||||
import struct
|
||||
|
||||
from ...commands.base import BaseCommand
|
||||
from ..models import ExMinuteBar
|
||||
|
||||
|
||||
class GetExMinuteTimeDataCmd(BaseCommand[list[ExMinuteBar]]):
|
||||
"""获取当日分时行情数据。"""
|
||||
|
||||
def __init__(self, market: int, code: str) -> None:
|
||||
self.market = market
|
||||
self.code = code.encode("utf-8")
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
header = bytes.fromhex("01 07 08 00 01 01 0c 00 0c 00 0b 24")
|
||||
return header + struct.pack("<B9s", self.market, self.code)
|
||||
|
||||
def parse_response(self, body: bytes) -> list[ExMinuteBar]:
|
||||
if len(body) < 12:
|
||||
return []
|
||||
pos = 0
|
||||
(market, raw_code, num) = struct.unpack("<B9sH", body[pos : pos + 12])
|
||||
pos += 12
|
||||
return self._parse_records(body, pos, num)
|
||||
|
||||
@staticmethod
|
||||
def _parse_records(body: bytes, pos: int, num: int) -> list[ExMinuteBar]:
|
||||
results: list[ExMinuteBar] = []
|
||||
for _ in range(num):
|
||||
if pos + 18 > len(body):
|
||||
break
|
||||
record_start = pos
|
||||
(raw_time, price, avg_price, volume, amount) = struct.unpack(
|
||||
"<HffII",
|
||||
body[pos : pos + 18],
|
||||
)
|
||||
pos += 18
|
||||
hour = raw_time // 60
|
||||
minute = raw_time % 60
|
||||
results.append(
|
||||
ExMinuteBar(
|
||||
hour=hour,
|
||||
minute=minute,
|
||||
price=price,
|
||||
avg_price=avg_price,
|
||||
volume=volume,
|
||||
open_interest=amount,
|
||||
_raw=body[record_start:pos],
|
||||
)
|
||||
)
|
||||
return results
|
||||
|
||||
|
||||
class GetExHistoryMinuteTimeDataCmd(BaseCommand[list[ExMinuteBar]]):
|
||||
"""获取历史某日分时行情数据。"""
|
||||
|
||||
def __init__(self, market: int, code: str, date: int) -> None:
|
||||
self.market = market
|
||||
self.code = code.encode("utf-8")
|
||||
self.date = date
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
header = bytes.fromhex("01 01 30 00 01 01 10 00 10 00 0c 24")
|
||||
return header + struct.pack("<IB9s", self.date, self.market, self.code)
|
||||
|
||||
def parse_response(self, body: bytes) -> list[ExMinuteBar]:
|
||||
if len(body) < 20:
|
||||
return []
|
||||
pos = 0
|
||||
(_market, _code, _unk, num) = struct.unpack("<B9s8sH", body[pos : pos + 20])
|
||||
pos += 20
|
||||
return GetExMinuteTimeDataCmd._parse_records(body, pos, num)
|
||||
@@ -0,0 +1,97 @@
|
||||
"""获取扩展行情成交数据(当日 + 历史)。"""
|
||||
|
||||
import struct
|
||||
|
||||
from ...commands.base import BaseCommand
|
||||
from ..models import ExTransactionRecord
|
||||
|
||||
|
||||
class GetExTransactionDataCmd(BaseCommand[list[ExTransactionRecord]]):
|
||||
"""获取当日分笔成交数据。"""
|
||||
|
||||
def __init__(self, market: int, code: str, start: int = 0, count: int = 1800) -> None:
|
||||
self.market = market
|
||||
self.code = code.encode("utf-8")
|
||||
self.start = start
|
||||
self.count = count
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
header = bytes.fromhex("01 01 08 00 03 01 12 00 12 00 fc 23")
|
||||
return header + struct.pack("<B9siH", self.market, self.code, self.start, self.count)
|
||||
|
||||
def parse_response(self, body: bytes) -> list[ExTransactionRecord]:
|
||||
if len(body) < 16:
|
||||
return []
|
||||
pos = 0
|
||||
(_market, _code, _unk, num) = struct.unpack("<B9s4sH", body[pos : pos + 16])
|
||||
pos += 16
|
||||
return self._parse_records(body, pos, num)
|
||||
|
||||
@staticmethod
|
||||
def _parse_records(body: bytes, pos: int, num: int) -> list[ExTransactionRecord]:
|
||||
results: list[ExTransactionRecord] = []
|
||||
for _ in range(num):
|
||||
if pos + 16 > len(body):
|
||||
break
|
||||
record_start = pos
|
||||
(raw_time, price, volume, zengcang, direction) = struct.unpack(
|
||||
"<HIIiH",
|
||||
body[pos : pos + 16],
|
||||
)
|
||||
pos += 16
|
||||
hour = raw_time // 60
|
||||
minute = raw_time % 60
|
||||
second = direction % 10000
|
||||
if second > 59:
|
||||
second = 0
|
||||
nature = direction // 10000
|
||||
results.append(
|
||||
ExTransactionRecord(
|
||||
hour=hour,
|
||||
minute=minute,
|
||||
second=second,
|
||||
price=price,
|
||||
volume=volume,
|
||||
zengcang=zengcang,
|
||||
nature=nature,
|
||||
_raw=body[record_start:pos],
|
||||
)
|
||||
)
|
||||
return results
|
||||
|
||||
|
||||
class GetExHistoryTransactionDataCmd(BaseCommand[list[ExTransactionRecord]]):
|
||||
"""获取历史某日分笔成交数据。"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
market: int,
|
||||
code: str,
|
||||
date: int,
|
||||
start: int = 0,
|
||||
count: int = 1800,
|
||||
) -> None:
|
||||
self.market = market
|
||||
self.code = code.encode("utf-8")
|
||||
self.date = date
|
||||
self.start = start
|
||||
self.count = count
|
||||
|
||||
def build_request(self) -> bytes:
|
||||
header = bytes.fromhex("01 01 30 00 02 01 16 00 16 00 06 24")
|
||||
return header + struct.pack(
|
||||
"<IB9siH",
|
||||
self.date,
|
||||
self.market,
|
||||
self.code,
|
||||
self.start,
|
||||
self.count,
|
||||
)
|
||||
|
||||
def parse_response(self, body: bytes) -> list[ExTransactionRecord]:
|
||||
if len(body) < 16:
|
||||
return []
|
||||
pos = 0
|
||||
(_market, _code, _unk, num) = struct.unpack("<B9s4sH", body[pos : pos + 16])
|
||||
pos += 16
|
||||
return GetExTransactionDataCmd._parse_records(body, pos, num)
|
||||
@@ -0,0 +1,16 @@
|
||||
"""扩展行情握手命令。"""
|
||||
|
||||
from typing import Final
|
||||
|
||||
EX_SETUP_CMD: Final[bytes] = bytes.fromhex(
|
||||
"01 01 48 65 00 01 52 00 52 00 54 24"
|
||||
"1f 32 c6 e5 d5 3d fb 41"
|
||||
"1f 32 c6 e5 d5 3d fb 41"
|
||||
"1f 32 c6 e5 d5 3d fb 41"
|
||||
"1f 32 c6 e5 d5 3d fb 41"
|
||||
"1f 32 c6 e5 d5 3d fb 41"
|
||||
"1f 32 c6 e5 d5 3d fb 41"
|
||||
"1f 32 c6 e5 d5 3d fb 41"
|
||||
"cc e1 6d ff d5 ba 3f b8"
|
||||
"cb c5 7a 05 4f 77 48 ea"
|
||||
)
|
||||
@@ -0,0 +1,158 @@
|
||||
"""扩展行情数据模型与常量。"""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
# 扩展行情服务器(端口 7727),来源: pytdx_backup/util/best_ip.py
|
||||
KNOWN_EX_HOSTS: list[str] = [
|
||||
"106.14.95.149",
|
||||
"112.74.214.43",
|
||||
"119.147.86.171",
|
||||
"119.97.185.5",
|
||||
"120.24.0.77",
|
||||
"47.92.127.181",
|
||||
"59.175.238.38",
|
||||
"61.152.107.141",
|
||||
"61.152.107.171",
|
||||
"47.107.75.159",
|
||||
"120.25.218.6",
|
||||
"43.139.173.246",
|
||||
"159.75.90.107",
|
||||
"106.52.170.195",
|
||||
"139.9.191.175",
|
||||
"175.24.47.69",
|
||||
"150.158.9.199",
|
||||
"150.158.20.127",
|
||||
"49.235.119.116",
|
||||
"49.234.13.160",
|
||||
"116.205.143.214",
|
||||
"124.71.223.19",
|
||||
"113.45.175.47",
|
||||
"123.60.173.210",
|
||||
"118.89.69.202",
|
||||
]
|
||||
|
||||
# 已知扩展行情市场代码
|
||||
KNOWN_EX_MARKETS: dict[int, str] = {
|
||||
0: "深圳",
|
||||
1: "上海",
|
||||
28: "郑州商品",
|
||||
29: "大连商品",
|
||||
30: "上海期货",
|
||||
31: "香港主板",
|
||||
47: "中金所",
|
||||
48: "香港创业板",
|
||||
49: "香港基金",
|
||||
71: "沪港通",
|
||||
74: "外盘",
|
||||
}
|
||||
|
||||
_DEFAULT_EX_PORT = 7727
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExMarketInfo:
|
||||
"""市场定义(GetMarkets 返回)。"""
|
||||
|
||||
market: int
|
||||
category: int
|
||||
name: str
|
||||
short_name: str
|
||||
_raw: bytes = field(default=b"", repr=False, compare=False)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExInstrumentInfo:
|
||||
"""合约/证券信息(GetInstrumentInfo 返回)。"""
|
||||
|
||||
category: int
|
||||
market: int
|
||||
code: str
|
||||
name: str
|
||||
desc: str
|
||||
_raw: bytes = field(default=b"", repr=False, compare=False)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExInstrumentQuote:
|
||||
"""五档行情(GetInstrumentQuote 返回)。"""
|
||||
|
||||
market: int
|
||||
code: str
|
||||
pre_close: float
|
||||
open: float
|
||||
high: float
|
||||
low: float
|
||||
price: float
|
||||
kaicang: int
|
||||
zongliang: int
|
||||
xianliang: int
|
||||
neipan: int
|
||||
waipan: int
|
||||
chicang: int
|
||||
bid1: float
|
||||
bid2: float
|
||||
bid3: float
|
||||
bid4: float
|
||||
bid5: float
|
||||
bid_vol1: int
|
||||
bid_vol2: int
|
||||
bid_vol3: int
|
||||
bid_vol4: int
|
||||
bid_vol5: int
|
||||
ask1: float
|
||||
ask2: float
|
||||
ask3: float
|
||||
ask4: float
|
||||
ask5: float
|
||||
ask_vol1: int
|
||||
ask_vol2: int
|
||||
ask_vol3: int
|
||||
ask_vol4: int
|
||||
ask_vol5: int
|
||||
_raw: bytes = field(default=b"", repr=False, compare=False)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExInstrumentBar:
|
||||
"""K线数据(GetInstrumentBars / GetHistoryInstrumentBarsRange 返回)。"""
|
||||
|
||||
open: float
|
||||
high: float
|
||||
low: float
|
||||
close: float
|
||||
position: int
|
||||
trade: int
|
||||
amount: float
|
||||
year: int
|
||||
month: int
|
||||
day: int
|
||||
hour: int
|
||||
minute: int
|
||||
_raw: bytes = field(default=b"", repr=False, compare=False)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExMinuteBar:
|
||||
"""分时数据(GetMinuteTimeData / GetHistoryMinuteTimeData 返回)。"""
|
||||
|
||||
hour: int
|
||||
minute: int
|
||||
price: float
|
||||
avg_price: float
|
||||
volume: int
|
||||
open_interest: int
|
||||
_raw: bytes = field(default=b"", repr=False, compare=False)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExTransactionRecord:
|
||||
"""逐笔成交记录(GetTransactionData / GetHistoryTransactionData 返回)。"""
|
||||
|
||||
hour: int
|
||||
minute: int
|
||||
second: int
|
||||
price: int
|
||||
volume: int
|
||||
zengcang: int
|
||||
nature: int
|
||||
_raw: bytes = field(default=b"", repr=False, compare=False)
|
||||
@@ -0,0 +1 @@
|
||||
"""扩展行情传输层。"""
|
||||
@@ -0,0 +1,125 @@
|
||||
"""扩展行情异步 TCP 连接(asyncio,端口 7727)。"""
|
||||
|
||||
import asyncio
|
||||
from types import TracebackType
|
||||
from typing import TYPE_CHECKING, TypeVar
|
||||
|
||||
from ...codec.frame import HEADER_SIZE, decompress_body, parse_header
|
||||
from ...exceptions import TdxConnectionError
|
||||
from ..commands.setup import EX_SETUP_CMD
|
||||
from ..models import KNOWN_EX_HOSTS
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...commands.base import BaseCommand
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
_DEFAULT_EX_PORT = 7727
|
||||
_DEFAULT_TIMEOUT = 15.0
|
||||
|
||||
|
||||
class AsyncExTdxConnection:
|
||||
"""扩展行情异步 TCP 连接(asyncio,端口 7727,单包握手)。"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
host: str = KNOWN_EX_HOSTS[0],
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = _DEFAULT_TIMEOUT,
|
||||
) -> None:
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.timeout = timeout
|
||||
self._reader: asyncio.StreamReader | None = None
|
||||
self._writer: asyncio.StreamWriter | None = None
|
||||
self._io_lock = asyncio.Lock()
|
||||
|
||||
async def connect(self) -> None:
|
||||
async with self._io_lock:
|
||||
if self._writer is not None and not self._writer.is_closing():
|
||||
return
|
||||
await self._connect_unlocked()
|
||||
|
||||
async def close(self) -> None:
|
||||
async with self._io_lock:
|
||||
await self._close_unlocked()
|
||||
|
||||
async def execute(self, cmd: "BaseCommand[T]") -> T:
|
||||
async with self._io_lock:
|
||||
if self._writer is None or self._reader is None:
|
||||
raise TdxConnectionError("未连接,请先调用 connect()")
|
||||
request = cmd.build_request()
|
||||
try:
|
||||
self._writer.write(request)
|
||||
await asyncio.wait_for(self._writer.drain(), timeout=self.timeout)
|
||||
header_buf = await self._recv_exact(HEADER_SIZE)
|
||||
header = parse_header(header_buf)
|
||||
raw_body = await self._recv_exact(header.zipsize)
|
||||
except asyncio.TimeoutError as e:
|
||||
await self._close_unlocked()
|
||||
raise TdxConnectionError(f"通信超时: {self.timeout}s") from e
|
||||
except (OSError, asyncio.IncompleteReadError) as e:
|
||||
await self._close_unlocked()
|
||||
raise TdxConnectionError(f"通信错误: {e}") from e
|
||||
|
||||
body = decompress_body(header, raw_body)
|
||||
return cmd.parse_response(body)
|
||||
|
||||
async def _connect_unlocked(self) -> None:
|
||||
try:
|
||||
reader, writer = await asyncio.wait_for(
|
||||
asyncio.open_connection(self.host, self.port),
|
||||
timeout=self.timeout,
|
||||
)
|
||||
except (OSError, asyncio.TimeoutError) as e:
|
||||
raise TdxConnectionError(f"无法连接 {self.host}:{self.port}: {e}") from e
|
||||
self._reader = reader
|
||||
self._writer = writer
|
||||
try:
|
||||
await self._send_setup()
|
||||
except Exception:
|
||||
await self._close_unlocked()
|
||||
raise
|
||||
|
||||
async def _close_unlocked(self) -> None:
|
||||
if self._writer is not None:
|
||||
try:
|
||||
self._writer.close()
|
||||
await self._writer.wait_closed()
|
||||
except OSError:
|
||||
pass
|
||||
self._reader = None
|
||||
self._writer = None
|
||||
|
||||
async def __aenter__(self) -> "AsyncExTdxConnection":
|
||||
await self.connect()
|
||||
return self
|
||||
|
||||
async def __aexit__(
|
||||
self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_val: BaseException | None,
|
||||
exc_tb: TracebackType | None,
|
||||
) -> None:
|
||||
await self.close()
|
||||
|
||||
async def _send_setup(self) -> None:
|
||||
"""发送单条扩展行情握手命令并丢弃响应。"""
|
||||
assert self._writer is not None
|
||||
assert self._reader is not None
|
||||
self._writer.write(EX_SETUP_CMD)
|
||||
await asyncio.wait_for(self._writer.drain(), timeout=self.timeout)
|
||||
try:
|
||||
hdr_buf = await self._recv_exact(HEADER_SIZE)
|
||||
hdr = parse_header(hdr_buf)
|
||||
if hdr.zipsize > 0:
|
||||
await self._recv_exact(hdr.zipsize)
|
||||
except (OSError, asyncio.TimeoutError, asyncio.IncompleteReadError):
|
||||
pass
|
||||
|
||||
async def _recv_exact(self, n: int) -> bytes:
|
||||
assert self._reader is not None
|
||||
return await asyncio.wait_for(
|
||||
self._reader.readexactly(n),
|
||||
timeout=self.timeout,
|
||||
)
|
||||
@@ -0,0 +1,163 @@
|
||||
"""扩展行情同步 TCP 连接(端口 7727)。"""
|
||||
|
||||
import socket
|
||||
import time
|
||||
from types import TracebackType
|
||||
from typing import TYPE_CHECKING, TypeVar
|
||||
|
||||
from ...codec.frame import HEADER_SIZE, decompress_body, parse_header
|
||||
from ...exceptions import TdxConnectionError
|
||||
from ..commands.setup import EX_SETUP_CMD
|
||||
from ..models import KNOWN_EX_HOSTS
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...commands.base import BaseCommand
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
_DEFAULT_EX_PORT = 7727
|
||||
_DEFAULT_TIMEOUT = 15.0
|
||||
|
||||
|
||||
def ping_ex_host(
|
||||
host: str,
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = 5.0,
|
||||
) -> float | None:
|
||||
"""测量扩展行情服务器延迟(秒)。失败返回 None。"""
|
||||
t0 = time.monotonic()
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(timeout)
|
||||
try:
|
||||
sock.connect((host, port))
|
||||
sock.sendall(EX_SETUP_CMD)
|
||||
hdr_buf = _recv_exact_sock(sock, HEADER_SIZE)
|
||||
hdr = parse_header(hdr_buf)
|
||||
if hdr.zipsize > 0:
|
||||
_recv_exact_sock(sock, hdr.zipsize)
|
||||
return time.monotonic() - t0
|
||||
except OSError:
|
||||
return None
|
||||
finally:
|
||||
try:
|
||||
sock.close()
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def ping_ex_all(
|
||||
hosts: list[str] | None = None,
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = 5.0,
|
||||
) -> list[tuple[str, float]]:
|
||||
"""并发测量多台扩展行情服务器延迟,按延迟排序返回。"""
|
||||
import concurrent.futures
|
||||
|
||||
if hosts is None:
|
||||
hosts = KNOWN_EX_HOSTS
|
||||
results: list[tuple[str, float]] = []
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=len(hosts)) as pool:
|
||||
futures = {pool.submit(ping_ex_host, h, port, timeout): h for h in hosts}
|
||||
for fut in concurrent.futures.as_completed(futures):
|
||||
host = futures[fut]
|
||||
latency = fut.result()
|
||||
if latency is not None:
|
||||
results.append((host, latency))
|
||||
results.sort(key=lambda t: t[1])
|
||||
return results
|
||||
|
||||
|
||||
def _recv_exact_sock(sock: socket.socket, n: int) -> bytes:
|
||||
buf = bytearray()
|
||||
while len(buf) < n:
|
||||
chunk = sock.recv(n - len(buf))
|
||||
if not chunk:
|
||||
raise TdxConnectionError("连接被服务器关闭")
|
||||
buf.extend(chunk)
|
||||
return bytes(buf)
|
||||
|
||||
|
||||
class ExTdxConnection:
|
||||
"""扩展行情同步 TCP 连接(端口 7727,单包握手)。"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
host: str = KNOWN_EX_HOSTS[0],
|
||||
port: int = _DEFAULT_EX_PORT,
|
||||
timeout: float = _DEFAULT_TIMEOUT,
|
||||
) -> None:
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.timeout = timeout
|
||||
self._sock: socket.socket | None = None
|
||||
|
||||
def connect(self) -> None:
|
||||
"""建立 TCP 连接并完成扩展行情握手。"""
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(self.timeout)
|
||||
try:
|
||||
sock.connect((self.host, self.port))
|
||||
except OSError as e:
|
||||
sock.close()
|
||||
raise TdxConnectionError(f"无法连接 {self.host}:{self.port}: {e}") from e
|
||||
self._sock = sock
|
||||
try:
|
||||
self._send_setup()
|
||||
except Exception:
|
||||
try:
|
||||
sock.close()
|
||||
except OSError:
|
||||
pass
|
||||
self._sock = None
|
||||
raise
|
||||
|
||||
def close(self) -> None:
|
||||
if self._sock is not None:
|
||||
try:
|
||||
self._sock.close()
|
||||
except OSError:
|
||||
pass
|
||||
self._sock = None
|
||||
|
||||
def execute(self, cmd: "BaseCommand[T]") -> T:
|
||||
"""执行一条命令:发送请求,接收并解压响应,返回解析结果。"""
|
||||
if self._sock is None:
|
||||
raise TdxConnectionError("未连接,请先调用 connect()")
|
||||
request = cmd.build_request()
|
||||
try:
|
||||
self._sock.sendall(request)
|
||||
header_buf = self._recv_exact(HEADER_SIZE)
|
||||
header = parse_header(header_buf)
|
||||
raw_body = self._recv_exact(header.zipsize)
|
||||
except OSError as e:
|
||||
raise TdxConnectionError(f"通信错误: {e}") from e
|
||||
body = decompress_body(header, raw_body)
|
||||
return cmd.parse_response(body)
|
||||
|
||||
def __enter__(self) -> "ExTdxConnection":
|
||||
self.connect()
|
||||
return self
|
||||
|
||||
def __exit__(
|
||||
self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_val: BaseException | None,
|
||||
exc_tb: TracebackType | None,
|
||||
) -> None:
|
||||
self.close()
|
||||
|
||||
def _send_setup(self) -> None:
|
||||
"""发送单条扩展行情握手命令并丢弃响应。"""
|
||||
assert self._sock is not None
|
||||
self._sock.sendall(EX_SETUP_CMD)
|
||||
try:
|
||||
hdr_buf = self._recv_exact(HEADER_SIZE)
|
||||
hdr = parse_header(hdr_buf)
|
||||
if hdr.zipsize > 0:
|
||||
self._recv_exact(hdr.zipsize)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def _recv_exact(self, n: int) -> bytes:
|
||||
assert self._sock is not None
|
||||
return _recv_exact_sock(self._sock, n)
|
||||
@@ -15,3 +15,11 @@ class TdxDecodeError(TdxError):
|
||||
|
||||
class TdxCommandError(TdxError):
|
||||
"""命令执行失败(服务器返回错误)"""
|
||||
|
||||
|
||||
class TdxFileNotFoundError(TdxError):
|
||||
"""本地数据文件不存在"""
|
||||
|
||||
|
||||
class TdxOfflineError(TdxError):
|
||||
"""离线数据读取失败(路径未配置、文件格式错误等)"""
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
"""离线数据读取模块 —— 从本地通达信安装目录读取数据文件。"""
|
||||
|
||||
from .block import CustomerBlock, read_block_dat, read_customer_blocks
|
||||
from .daily_bar import find_daily_bar_file, read_daily_bars
|
||||
from .ex_daily_bar import ExDailyBar, read_ex_daily_bars
|
||||
from .finders import find_5min_bar_file, find_lc1_bar_file, find_lc5_bar_file
|
||||
from .gbbq import GbbqRecord, read_gbbq
|
||||
from .history_financial import read_history_financial
|
||||
from .min_bar import read_5min_bars, read_lc_min_bars
|
||||
from .paths import detect_tdx_home, resolve_vipdoc
|
||||
|
||||
__all__ = [
|
||||
# 路径
|
||||
"detect_tdx_home",
|
||||
"resolve_vipdoc",
|
||||
# 日线
|
||||
"read_daily_bars",
|
||||
"find_daily_bar_file",
|
||||
# 分钟线
|
||||
"read_5min_bars",
|
||||
"read_lc_min_bars",
|
||||
"find_5min_bar_file",
|
||||
"find_lc1_bar_file",
|
||||
"find_lc5_bar_file",
|
||||
# 扩展市场
|
||||
"ExDailyBar",
|
||||
"read_ex_daily_bars",
|
||||
# 板块
|
||||
"CustomerBlock",
|
||||
"read_block_dat",
|
||||
"read_customer_blocks",
|
||||
# 股本变迁
|
||||
"GbbqRecord",
|
||||
"read_gbbq",
|
||||
# 历史财务
|
||||
"read_history_financial",
|
||||
]
|
||||
@@ -0,0 +1,92 @@
|
||||
"""板块数据读取(.dat 文件和自定义板块目录)。"""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
from ..codec.block import parse_block_dat
|
||||
from ..exceptions import TdxFileNotFoundError, TdxOfflineError
|
||||
from ..models.finance import TdxBlock
|
||||
|
||||
|
||||
@dataclass
|
||||
class CustomerBlock:
|
||||
"""自定义板块。"""
|
||||
|
||||
blockname: str
|
||||
block_type: str
|
||||
codes: list[str] = field(default_factory=list)
|
||||
|
||||
|
||||
def read_block_dat(filepath: str | Path) -> list[TdxBlock]:
|
||||
"""从本地 .dat 板块文件读取板块数据。
|
||||
|
||||
直接复用 codec/block.py 的 parse_block_dat()。
|
||||
|
||||
Args:
|
||||
filepath: .dat 文件路径(如 block_zs.dat)。
|
||||
|
||||
Returns:
|
||||
TdxBlock 列表。
|
||||
"""
|
||||
filepath = Path(filepath)
|
||||
if not filepath.is_file():
|
||||
raise TdxFileNotFoundError(f"板块数据文件不存在: {filepath}")
|
||||
data = filepath.read_bytes()
|
||||
return parse_block_dat(data, filename=filepath.name)
|
||||
|
||||
|
||||
def read_customer_blocks(block_dir: str | Path) -> list[CustomerBlock]:
|
||||
"""从通达信自定义板块目录读取板块数据。
|
||||
|
||||
目录结构:
|
||||
blocknew.cfg — 板块索引(120 字节/条:50B 名称 + 70B 文件名)
|
||||
*.blk — 板块内容(每行一个代码,首位为市场标识)
|
||||
|
||||
Args:
|
||||
block_dir: 自定义板块目录路径。
|
||||
|
||||
Returns:
|
||||
CustomerBlock 列表。
|
||||
"""
|
||||
block_dir = Path(block_dir)
|
||||
if not block_dir.is_dir():
|
||||
raise TdxOfflineError(f"自定义板块目录不存在: {block_dir}")
|
||||
|
||||
cfg_path = block_dir / "blocknew.cfg"
|
||||
if not cfg_path.is_file():
|
||||
raise TdxOfflineError(f"板块配置文件不存在: {cfg_path}")
|
||||
|
||||
cfg_data = cfg_path.read_bytes()
|
||||
results: list[CustomerBlock] = []
|
||||
pos = 0
|
||||
|
||||
while pos + 120 <= len(cfg_data):
|
||||
name = cfg_data[pos : pos + 50].decode("gbk", errors="replace").rstrip("\x00")
|
||||
name = name.split("\x00")[0]
|
||||
blk_filename = cfg_data[pos + 50 : pos + 120].decode("gbk", errors="replace").rstrip("\x00")
|
||||
blk_filename = blk_filename.split("\x00")[0]
|
||||
pos += 120
|
||||
|
||||
if not blk_filename:
|
||||
continue
|
||||
|
||||
blk_path = block_dir / f"{blk_filename}.blk"
|
||||
if not blk_path.is_file():
|
||||
continue
|
||||
|
||||
codes: list[str] = []
|
||||
for line in blk_path.read_text(encoding="utf-8", errors="replace").splitlines():
|
||||
line = line.strip()
|
||||
if line and len(line) > 1:
|
||||
codes.append(line[1:]) # 去掉首位的市场标识
|
||||
|
||||
if name:
|
||||
results.append(
|
||||
CustomerBlock(
|
||||
blockname=name,
|
||||
block_type=blk_filename,
|
||||
codes=codes,
|
||||
)
|
||||
)
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,131 @@
|
||||
"""日线 K 线数据读取(.day 文件)。"""
|
||||
|
||||
import struct
|
||||
from pathlib import Path
|
||||
|
||||
from ..exceptions import TdxFileNotFoundError
|
||||
from ..models.bar import SecurityBar
|
||||
from .paths import _market_to_exchange, resolve_vipdoc
|
||||
|
||||
# struct 格式:日期(YYYYMMDD) 开盘 最高 最低 收盘 成交额 成交量 保留
|
||||
# 全部为小端序,32 字节/条
|
||||
_DAILY_FMT = struct.Struct("<IIIIIfII")
|
||||
|
||||
# 证券类型 → (价格系数, 量系数)
|
||||
_SECURITY_COEFFICIENTS: dict[str, tuple[float, float]] = {
|
||||
"SH_A_STOCK": (0.01, 0.01),
|
||||
"SH_B_STOCK": (0.001, 0.01),
|
||||
"SH_INDEX": (0.01, 1.0),
|
||||
"SH_FUND": (0.001, 1.0),
|
||||
"SH_BOND": (0.001, 1.0),
|
||||
"SZ_A_STOCK": (0.01, 0.01),
|
||||
"SZ_B_STOCK": (0.01, 0.01),
|
||||
"SZ_INDEX": (0.01, 1.0),
|
||||
"SZ_FUND": (0.001, 0.01),
|
||||
"SZ_BOND": (0.001, 1.0),
|
||||
}
|
||||
|
||||
|
||||
def _detect_security_type(filename: str) -> str:
|
||||
"""从文件名推断证券类型。
|
||||
|
||||
文件名格式: {exchange}{code}.day,如 sh600000.day、sz000001.day
|
||||
"""
|
||||
base = Path(filename).name.lower()
|
||||
exchange = base[:2] # "sh" or "sz"
|
||||
code_head = base[2:4]
|
||||
|
||||
if exchange == "sz":
|
||||
if code_head in ("00", "30"):
|
||||
return "SZ_A_STOCK"
|
||||
if code_head == "20":
|
||||
return "SZ_B_STOCK"
|
||||
if code_head == "39":
|
||||
return "SZ_INDEX"
|
||||
if code_head in ("15", "16"):
|
||||
return "SZ_FUND"
|
||||
if code_head in ("10", "11", "12", "13", "14"):
|
||||
return "SZ_BOND"
|
||||
elif exchange == "sh":
|
||||
if code_head == "60":
|
||||
return "SH_A_STOCK"
|
||||
if code_head == "90":
|
||||
return "SH_B_STOCK"
|
||||
if code_head in ("00", "88", "99"):
|
||||
return "SH_INDEX"
|
||||
if code_head in ("50", "51"):
|
||||
return "SH_FUND"
|
||||
if code_head in ("01", "10", "11", "12", "13", "14"):
|
||||
return "SH_BOND"
|
||||
|
||||
return "SZ_A_STOCK" # 默认按 A 股处理
|
||||
|
||||
|
||||
def read_daily_bars(filepath: str | Path) -> list[SecurityBar]:
|
||||
"""从本地 .day 文件读取日线 K 线数据。
|
||||
|
||||
Args:
|
||||
filepath: .day 文件路径。
|
||||
|
||||
Returns:
|
||||
SecurityBar 列表(按时间升序)。
|
||||
"""
|
||||
filepath = Path(filepath)
|
||||
if not filepath.is_file():
|
||||
raise TdxFileNotFoundError(f"日线数据文件不存在: {filepath}")
|
||||
|
||||
sec_type = _detect_security_type(filepath.name)
|
||||
price_coeff, vol_coeff = _SECURITY_COEFFICIENTS.get(sec_type, (0.01, 0.01))
|
||||
|
||||
data = filepath.read_bytes()
|
||||
if len(data) < _DAILY_FMT.size:
|
||||
return []
|
||||
|
||||
results: list[SecurityBar] = []
|
||||
record_size = _DAILY_FMT.size
|
||||
for offset in range(0, len(data) - record_size + 1, record_size):
|
||||
raw = data[offset : offset + record_size]
|
||||
date_int, op, hi, lo, cl, amount, vol, _res = _DAILY_FMT.unpack(raw)
|
||||
|
||||
year = date_int // 10000
|
||||
month = (date_int % 10000) // 100
|
||||
day = date_int % 100
|
||||
|
||||
results.append(
|
||||
SecurityBar(
|
||||
open=op * price_coeff,
|
||||
close=cl * price_coeff,
|
||||
high=hi * price_coeff,
|
||||
low=lo * price_coeff,
|
||||
vol=vol * vol_coeff,
|
||||
amount=amount,
|
||||
year=year,
|
||||
month=month,
|
||||
day=day,
|
||||
hour=0,
|
||||
minute=0,
|
||||
_raw=raw,
|
||||
)
|
||||
)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def find_daily_bar_file(
|
||||
market: int,
|
||||
code: str,
|
||||
vipdoc: str | Path | None = None,
|
||||
) -> Path:
|
||||
"""根据市场和代码定位日线文件路径。
|
||||
|
||||
Args:
|
||||
market: 市场代码(Market.SZ=0, Market.SH=1)。
|
||||
code: 6 位股票代码。
|
||||
vipdoc: vipdoc 目录路径,None 则自动检测。
|
||||
|
||||
Returns:
|
||||
.day 文件的 Path。
|
||||
"""
|
||||
vipdoc_path = resolve_vipdoc(vipdoc)
|
||||
exchange = _market_to_exchange(market)
|
||||
return vipdoc_path / exchange / "lday" / f"{exchange}{code}.day"
|
||||
@@ -0,0 +1,82 @@
|
||||
"""扩展市场日线数据读取(期货、港股等 .day 文件)。"""
|
||||
|
||||
import struct
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
from ..exceptions import TdxFileNotFoundError
|
||||
|
||||
# 日期(4B) 开盘(4Bf) 最高(4Bf) 最低(4Bf) 收盘(4Bf) 成交额(4B) 成交量(4B) 结算价(4Bf)
|
||||
_EX_DAILY_FMT = struct.Struct("<IffffIIf")
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExDailyBar:
|
||||
"""扩展市场日线(期货/港股等,含结算价)。"""
|
||||
|
||||
open: float
|
||||
high: float
|
||||
low: float
|
||||
close: float
|
||||
amount: int
|
||||
vol: int
|
||||
settlement: float
|
||||
hk_stock_amount: float
|
||||
year: int
|
||||
month: int
|
||||
day: int
|
||||
_raw: bytes = field(default=b"", repr=False, compare=False)
|
||||
|
||||
|
||||
def read_ex_daily_bars(filepath: str | Path) -> list[ExDailyBar]:
|
||||
"""从本地扩展市场 .day 文件读取日线数据。
|
||||
|
||||
文件位于 vipdoc/ds/ 目录下,如 29#A1801.day。
|
||||
|
||||
Args:
|
||||
filepath: .day 文件路径。
|
||||
|
||||
Returns:
|
||||
ExDailyBar 列表(按时间升序)。
|
||||
"""
|
||||
filepath = Path(filepath)
|
||||
if not filepath.is_file():
|
||||
raise TdxFileNotFoundError(f"扩展市场日线文件不存在: {filepath}")
|
||||
|
||||
data = filepath.read_bytes()
|
||||
if len(data) < _EX_DAILY_FMT.size:
|
||||
return []
|
||||
|
||||
results: list[ExDailyBar] = []
|
||||
record_size = _EX_DAILY_FMT.size
|
||||
|
||||
for offset in range(0, len(data) - record_size + 1, record_size):
|
||||
raw = data[offset : offset + record_size]
|
||||
date_int, op, hi, lo, cl, amt, vol, settlement = _EX_DAILY_FMT.unpack(raw)
|
||||
|
||||
# 第 5 个字段(成交额位置)重新解释为 float 作为港股量
|
||||
hk_bytes = struct.pack("<I", amt)
|
||||
(hk_stock_amount,) = struct.unpack("<f", hk_bytes)
|
||||
|
||||
year = date_int // 10000
|
||||
month = (date_int % 10000) // 100
|
||||
day = date_int % 100
|
||||
|
||||
results.append(
|
||||
ExDailyBar(
|
||||
open=op,
|
||||
high=hi,
|
||||
low=lo,
|
||||
close=cl,
|
||||
amount=vol,
|
||||
vol=vol,
|
||||
settlement=settlement,
|
||||
hk_stock_amount=hk_stock_amount,
|
||||
year=year,
|
||||
month=month,
|
||||
day=day,
|
||||
_raw=raw,
|
||||
)
|
||||
)
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,38 @@
|
||||
"""路径定位辅助函数。"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from .paths import _market_to_exchange, resolve_vipdoc
|
||||
|
||||
|
||||
def find_5min_bar_file(
|
||||
market: int,
|
||||
code: str,
|
||||
vipdoc: str | Path | None = None,
|
||||
) -> Path:
|
||||
"""根据市场和代码定位 .5 分钟线文件路径。"""
|
||||
vipdoc_path = resolve_vipdoc(vipdoc)
|
||||
exchange = _market_to_exchange(market)
|
||||
return vipdoc_path / exchange / "fzline" / f"{exchange}{code}.5"
|
||||
|
||||
|
||||
def find_lc1_bar_file(
|
||||
market: int,
|
||||
code: str,
|
||||
vipdoc: str | Path | None = None,
|
||||
) -> Path:
|
||||
"""根据市场和代码定位 .lc1 分钟线文件路径。"""
|
||||
vipdoc_path = resolve_vipdoc(vipdoc)
|
||||
exchange = _market_to_exchange(market)
|
||||
return vipdoc_path / exchange / "fzline" / f"{exchange}{code}.lc1"
|
||||
|
||||
|
||||
def find_lc5_bar_file(
|
||||
market: int,
|
||||
code: str,
|
||||
vipdoc: str | Path | None = None,
|
||||
) -> Path:
|
||||
"""根据市场和代码定位 .lc5 分钟线文件路径。"""
|
||||
vipdoc_path = resolve_vipdoc(vipdoc)
|
||||
exchange = _market_to_exchange(market)
|
||||
return vipdoc_path / exchange / "fzline" / f"{exchange}{code}.lc5"
|
||||
@@ -0,0 +1,366 @@
|
||||
"""股本变迁数据读取(XOR 加密的 gbbq 文件)。"""
|
||||
|
||||
import struct
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
from ..exceptions import TdxFileNotFoundError
|
||||
|
||||
_MASK32 = 0xFFFFFFFF
|
||||
|
||||
# XOR 解密密钥(从 pytdx 移植,1072 字节 hex dump)
|
||||
_HEX_KEY = (
|
||||
"38 A7 C2 1D E0 6A 17 E2 D1 39 A2 40 9C BA 46 AF "
|
||||
"42 C6 FF 05 74 EA DA BB 89 B4 F8 44 AC 89 D7 F2 "
|
||||
"98 7F B6 BC E4 F7 6B 75 05 04 58 67 79 C8 6D C6 "
|
||||
"2B 06 96 8C FB 86 06 8B BF D6 E8 E1 87 49 6B 36 "
|
||||
"C7 18 02 79 53 25 72 72 13 CC 04 0B 90 24 0C DC "
|
||||
"DB 03 1A D5 2E 04 85 5C 7E 8E BD 02 26 2D BD 06 "
|
||||
"1B 50 34 99 1B A2 24 04 F2 88 35 C8 89 EA D5 FB "
|
||||
"12 24 BB B5 3B 29 CA 14 A6 04 CE A9 A8 58 02 B9 "
|
||||
"AA E3 97 A3 A6 22 57 BB AD A0 22 5F EB 05 86 11 "
|
||||
"C3 ED B1 3F 39 C2 36 D1 4A 43 C8 64 4D B0 6E 3A "
|
||||
"7C 51 6D F7 8E C6 DF F3 8E A4 1E 74 9D B2 22 05 "
|
||||
"4D 07 3F 96 7F 97 F9 63 B9 C4 2B 98 75 F6 D6 84 "
|
||||
"56 DC 15 D3 52 8B 60 F3 D6 0E A9 AD 07 07 E9 02 "
|
||||
"86 58 C2 32 9C 90 BC C9 19 BF B0 54 7A F8 CC A8 "
|
||||
"27 63 82 29 EE FB 98 11 BF 35 29 62 91 93 95 FC "
|
||||
"F4 F0 08 E4 B2 3A B4 5E B3 B0 2E 3E 20 C1 D7 43 "
|
||||
"59 7D C6 29 5F 69 74 7F B2 77 E1 0E FA 85 A1 C9 "
|
||||
"77 73 83 B3 CB 1C 60 DB E9 53 69 FC B3 18 59 15 "
|
||||
"0F 97 8A 7A C8 83 F5 49 DC 1B 3E 86 C1 95 45 46 "
|
||||
"E2 16 67 7F 12 35 A0 BB 27 FB CC F8 30 7E 4F C8 "
|
||||
"6D AB 18 B2 0D 01 CC 79 20 80 7B FA 37 AA 14 9E "
|
||||
"85 E8 25 E9 D4 2D 35 4E 8F D3 DE B0 06 8D 15 15 "
|
||||
"52 65 E8 39 03 28 09 02 67 99 3D 13 BA F3 68 5C "
|
||||
"4C 89 B0 E3 6B AE 16 5C 88 25 F8 33 03 19 02 5B "
|
||||
"29 7B 2A 41 2D 75 49 48 9B B3 B6 B3 BF AA DF 8C "
|
||||
"95 FE 0F 13 B8 7B 02 BB 52 E1 1C 34 C3 9B 87 59 "
|
||||
"E2 46 CC 22 77 4B D7 C4 2C 31 AA 84 7C 44 51 88 "
|
||||
"15 1A CC AE 40 9D 1F 44 97 29 98 45 60 74 47 A1 "
|
||||
"0D A5 73 F0 53 FF 01 F9 F4 9A F1 36 07 D0 2D A0 "
|
||||
"79 2D 81 23 25 AD 4B 9C C8 BC 12 55 4D D4 BB 95 "
|
||||
"B1 B9 BE 7D A6 E6 A0 53 BA 83 8C DD 7E E9 4B ED "
|
||||
"BA 28 42 D8 FF 98 69 35 CA 4E 9C 9D 57 D6 CF A0 "
|
||||
"89 5C A2 E7 54 D2 AF 4C FB 54 C4 B4 4F C3 BA F8 "
|
||||
"A2 58 69 19 79 0E A8 0E 3D C8 04 FD 26 32 C8 E1 "
|
||||
"02 8B A7 1C C3 91 25 E5 D8 49 DB DF 19 5F 16 F5 "
|
||||
"A7 8B 18 23 04 D4 BF FB 44 C4 61 7C 79 6E C8 90 "
|
||||
"15 B5 EB 50 87 CA 7A 69 47 2F AF A8 B5 A2 8A 84 "
|
||||
"C4 41 79 E8 DE 0C AC D0 D5 6F 34 C6 CB A7 76 F9 "
|
||||
"00 24 42 05 26 7E 7B 14 86 59 7B DB 1C 62 D5 B7 "
|
||||
"3E F7 17 44 27 4B D2 C6 6F FF C8 49 55 AD 65 52 "
|
||||
"2D 43 C2 33 9B 63 AB 3D 54 54 28 E2 02 65 03 9A "
|
||||
"03 4B 8F 64 1A 92 52 DE 32 D6 2B F0 BE BE 1D 54 "
|
||||
"B1 7C 70 41 9B 90 55 DA 71 55 21 B9 B6 68 90 19 "
|
||||
"5F BC AA B4 55 0E E6 81 4C A3 BE BC 64 D7 59 00 "
|
||||
"59 BD 0F 6A 57 1A A6 A0 D5 1A 0A 80 D3 09 06 73 "
|
||||
"5A 51 E2 DD 29 66 AC A0 86 29 21 2B 7A 6D 9E 3A "
|
||||
"68 D0 A3 DC A7 2B 85 A0 4C D4 F0 C5 C4 43 E4 CF "
|
||||
"0C 19 81 30 B6 F6 BE 71 F5 AC 25 AA CF 42 90 06 "
|
||||
"64 1B 45 29 FD 3A A3 B6 0B 9D 29 9F FA 31 B8 6D "
|
||||
"D8 EC 43 F5 92 7E 35 22 E0 C3 D3 09 06 61 71 DA "
|
||||
"E8 36 0A 19 F6 23 81 CB 89 E0 67 6E FE B1 E6 47 "
|
||||
"72 63 5C 25 18 E0 B4 65 85 EF B5 1B 26 23 90 89 "
|
||||
"CC EE E3 01 77 95 63 DF C4 AC BF E6 37 14 99 15 "
|
||||
"49 8A 96 02 91 AA 1D 98 21 57 5E 87 96 C7 B5 87 "
|
||||
"08 3F 58 06 52 58 17 8F AB A8 4E A1 7A 60 B1 69 "
|
||||
"5E 9C BE E2 D0 C5 12 59 DF 31 EB D2 19 54 96 E2 "
|
||||
"10 11 8E 68 B4 1A 2D D3 2F AB 12 F7 FE F3 A7 F7 "
|
||||
"61 FC F7 7C CB FC 87 8C 6A 10 40 29 7B 30 D6 0D "
|
||||
"13 4C 71 CD 5E AB 36 A2 F1 4C 05 ED 53 88 E5 FF "
|
||||
"8E 71 79 5D B5 AF D3 67 6D C4 44 6B AB C1 A7 AA "
|
||||
"38 D8 70 1E 08 E6 D2 36 7B 88 11 96 DB D2 68 D9 "
|
||||
"FF D8 50 2B 3A A9 CC 45 1A CA CD D2 05 C6 FC A0 "
|
||||
"35 0C EE 98 2B 5C B2 39 6A 27 12 8F 97 EC CB 7B "
|
||||
"B6 C0 27 F6 A7 48 75 09 82 98 CA 3A 5D E3 96 0C "
|
||||
"A5 D2 B3 6C A4 D1 1F AE 99 67 B0 3D D6 9A 7A 3E "
|
||||
"00 8B FD 45 32 F7 9F 28 7C 94 03 DB 64 AA 44 80 "
|
||||
"D2 27 AF B3 73 87 57 31 EB 08 D9 BA 73 4D 2C 77 "
|
||||
"03 BF F5 0F 47 3C 22 DA 3F B9 F1 9A 1B 22 83 16 "
|
||||
"EE F4 18 FC 08 E8 3B 30 1C 04 50 AA 4C E3 28 53 "
|
||||
"AB DE F8 5F 32 D9 E1 78 7B F1 C5 A8 CA 85 B6 9F "
|
||||
"89 1F 40 B8 2C 88 D7 C1 66 34 45 D6 46 FD 7B F3 "
|
||||
"72 A3 32 55 23 CF B5 B0 79 AB A0 F1 00 5C DB EE "
|
||||
"3F 51 AA AE C0 89 8E 47 A5 30 4E 4B DD D6 AE D8 "
|
||||
"6D 40 1C 4E 8E FB 0C 60 8D 54 1E 2F 17 B7 3A ED "
|
||||
"DE DC 81 F5 72 85 B7 A6 39 31 6F 47 50 84 43 C5 "
|
||||
"11 F3 6A 26 8E BA 7F 81 98 31 FD 13 6B 83 C9 11 "
|
||||
"61 48 64 FA E3 F5 39 2C 12 11 C1 6D 4D 03 13 A6 "
|
||||
"C2 E0 DF F5 32 8E 5B 35 A7 7F 08 F7 85 27 0D 71 "
|
||||
"9D B8 CE 9C 1E BA 77 3A F6 A1 A7 26 94 29 C0 20 "
|
||||
"10 65 75 6E EF AA 32 0C 66 91 3A 4E 0E 74 E2 8A "
|
||||
"FE B6 F8 17 C7 A7 E4 D8 35 67 2E F0 83 A8 9F A6 "
|
||||
"28 13 40 A3 96 DC 49 83 55 E1 85 AB BD 4D ED 88 "
|
||||
"FA 36 69 A9 77 59 5A 9C D0 A0 B1 3D EB 31 16 DC "
|
||||
"3E 29 7B 39 01 5B D4 FF 5C E5 9E DA F7 55 D5 3F "
|
||||
"E3 3B 51 76 83 8E 40 AE E1 2E E8 3E F8 08 B7 B0 "
|
||||
"24 26 91 AD 82 4C 2E 2F 37 7A 34 A1 05 BD 8C 9A "
|
||||
"75 52 5C CD 59 80 CB 92 F8 B1 F8 A5 F2 2C 9F 4A "
|
||||
"59 BF EF 76 A3 74 4F E1 C9 7C 7F 91 D9 0D 12 05 "
|
||||
"B2 8E D0 E0 BB 46 D4 5C 44 2F 65 6D 7A 1C 02 86 "
|
||||
"FB 7E 7D B6 2A 57 B9 DB 80 CD 02 BF E7 9E 35 21 "
|
||||
"FB BE 28 13 82 9F F0 74 F7 92 55 DE F2 7B F2 F2 "
|
||||
"7D F5 A0 14 0F 99 4D 25 F4 DC 11 17 7A 77 65 77 "
|
||||
"CC BE EF 90 88 E8 FD B2 4E 8E F5 26 FE 53 5D 65 "
|
||||
"A9 74 47 0B CB E9 E8 71 95 95 87 6C FD 86 94 A7 "
|
||||
"E5 FC 20 00 1E 0A 0A E3 85 17 24 D4 D0 73 8A 11 "
|
||||
"1E 1E EF 83 E3 D7 E1 BF CC 98 07 6D 70 37 3A 8F "
|
||||
"31 17 55 4E 60 A8 C8 AB 4F 08 2D 37 76 E6 2B 58 "
|
||||
"DD 81 0F D1 6E 9A A6 55 3D 80 82 99 9E 2D 16 9A "
|
||||
"DF 4E CB 3B 5D DA A8 53 08 C7 FF 54 DD C6 11 31 "
|
||||
"1A B6 EB A3 03 08 4A FB B4 45 EC C0 7C 0D C6 CF "
|
||||
"CB 1B 78 46 88 8F F4 6A 15 62 2F 17 12 E6 41 64 "
|
||||
"76 58 96 78 DB 29 B5 6A AE DE 63 41 6F BE 9B 37 "
|
||||
"6C C9 D0 EC 1B F6 79 17 9E FE 79 0E B1 82 28 F2 "
|
||||
"06 15 C2 BE 96 9C E0 81 80 D7 00 DB 95 87 4B C0 "
|
||||
"0D 91 55 5B 1F 86 22 64 74 EA 1B 89 85 D2 DD F7 "
|
||||
"9F F1 D9 09 06 64 FA 6D 59 72 EF CE 66 A7 03 D1 "
|
||||
"99 E8 DF AE D7 63 5F 60 5F AB 6E C5 22 C8 3A 94 "
|
||||
"6A 3B 00 72 F8 DB 90 E7 05 DC A2 89 0F 83 AA 03 "
|
||||
"FE 42 14 1C 8A E6 1C 9E DB D8 D0 CA 97 21 6C AD "
|
||||
"ED 0A E0 A2 9E EC C1 FF D1 B4 8A 9A AD AB 34 0B "
|
||||
"13 3F B5 18 8D 85 9E 0D F9 FB AC 21 2E DD 7A DE "
|
||||
"BF 9F 7E BD BF 84 DF F5 FD 1E BE E1 1F 0F F8 18 "
|
||||
"9D 73 09 02 29 B7 5B 26 7E 44 75 04 4D B1 AA 2F "
|
||||
"3A DB 46 38 12 D1 41 35 91 29 06 DF C9 98 69 92 "
|
||||
"02 F2 48 12 A9 71 D2 AE 3B 23 6D 1C E2 6B 8B 75 "
|
||||
"87 4A 13 A7 1F 81 4D 29 65 53 0A 3A 34 CE 6D E6 "
|
||||
"31 8D 7E 4E DD 25 6E 76 44 82 3C 47 36 4C B9 C4 "
|
||||
"9B F4 4F 84 43 11 56 C2 94 53 7E B0 2E 36 DA EB "
|
||||
"77 5F C1 64 E2 CA 9F BE 29 D8 06 36 53 D0 6F 82 "
|
||||
"19 DA BC 8C 5F 4D 45 E7 21 37 9E 90 A6 D4 33 A8 "
|
||||
"64 4D EC BC 90 5E FE 8E 8B CA 17 7C FF AC 96 BB "
|
||||
"21 CF 3D 24 71 3B C2 A1 74 68 85 CF 32 8E 7F 63 "
|
||||
"39 C5 E7 8E A5 E0 CD 3A F5 9A B8 FD 43 D4 43 39 "
|
||||
"08 8E 45 76 5F DF E9 17 54 59 12 ED D0 E9 3D 6F "
|
||||
"3F 02 14 8A 0A 47 9A D1 E7 FA 4E A1 41 00 50 EF "
|
||||
"60 9D 4D C1 CA 87 98 40 E7 B2 0F 76 C0 9D 71 EF "
|
||||
"D7 46 93 C1 2B 9F 11 B8 F9 05 AC ED A7 72 6B F5 "
|
||||
"11 9B 3E 0A 04 21 7D 06 D7 46 76 7B AD AE 9D 95 "
|
||||
"A6 47 68 05 AD F5 38 7C C7 A5 5A CA B2 CB 48 18 "
|
||||
"C1 F2 62 55 98 36 39 08 80 C5 28 B1 06 E4 FB 46 "
|
||||
"11 3C 38 A1 4F 1C FE A1 81 B7 FC DB 94 B0 7A FE "
|
||||
"B5 74 F1 BB 92 AA FF B0 FE 1E 31 8B C6 BC F0 4F "
|
||||
"1A FE 91 C5 7A 9C 73 09 4A 32 90 51 01 8B 12 C0 "
|
||||
"20 CA 3C CB 14 83 D3 C7 7C 5A 12 79 EE 56 1A 36 "
|
||||
"C4 09 E2 3E DC E8 CE F1 C1 A1 9E 99 DA 64 4F CF "
|
||||
"1E D6 2B 70 27 86 3E CF BE 75 1C 39 9B F9 53 63 "
|
||||
"C1 6B 58 CC 71 D2 07 41 88 BB 14 70 96 F1 68 CE "
|
||||
"13 75 FE F4 A0 C8 85 A2 67 18 49 56 0D 07 94 1D "
|
||||
"74 61 89 0C 32 49 9D 0D 94 73 4A AB 1A E9 0F E0 "
|
||||
"BA B6 4A 34 F9 33 1D B3 71 C2 B8 64 D7 0B CB 19 "
|
||||
"F7 BD E0 69 3E 24 96 B1 C4 28 09 5F 58 AE 8A C0 "
|
||||
"83 99 19 64 4D 44 37 55 A6 9B A1 42 50 84 B8 18 "
|
||||
"29 B5 21 91 58 23 88 EB 8F 13 4A 24 09 EC 0F 6D "
|
||||
"7D AF 3E FC F7 F3 9F 34 39 15 C4 84 03 BB 7E 67 "
|
||||
"39 5F 2A 2C 67 94 F4 A6 B5 02 3F 45 56 79 0C 2A "
|
||||
"9B 25 77 67 C2 3B CC F2 71 3B 4F 83 2A 8D 8C 53 "
|
||||
"0D 18 49 54 CA 58 0E BE 8B 3A 53 74 FC 6F 47 28 "
|
||||
"07 8E C1 F5 53 D3 34 4B 08 05 FF E9 14 29 40 1B "
|
||||
"57 AD 77 EC E8 DA DA 35 55 A7 78 03 56 4C 7C B2 "
|
||||
"ED 3B B5 61 65 91 DF 41 B4 5D C9 B7 9B 13 82 41 "
|
||||
"15 D7 B3 6E 1C C8 15 B4 F0 F3 3F 91 4B A1 C8 90 "
|
||||
"78 91 39 5A 21 55 DA 6A E1 2C BA C9 38 69 F6 AE "
|
||||
"A8 2B 8C B7 14 C1 35 82 35 A0 78 47 56 C0 9A A7 "
|
||||
"7F 74 14 64 85 F1 B7 48 BC 55 8C 6A A4 95 1C CB "
|
||||
"F3 52 F9 54 61 15 27 56 43 D0 27 95 E3 35 AA 39 "
|
||||
"DC 23 38 DA EF 1F 27 65 3A AB F7 CC BB 25 DB 00 "
|
||||
"36 34 96 D1 F7 C4 EC 44 37 42 7E 17 18 67 C8 9C "
|
||||
"9A 5B 39 08 5C 3C F4 92 F1 16 31 88 FA 12 44 9E "
|
||||
"79 27 1C C2 0B 46 AC CD 1F 39 B8 9F 9A 56 34 0A "
|
||||
"85 86 C2 B1 B1 9B 31 CE 47 57 05 3E A7 AE 3F 3E "
|
||||
"01 2D C5 B9 C1 CB BA AB 0A 2A D2 71 E4 EC F8 0A "
|
||||
"71 85 CC A1 CA 6E EF 9D 87 22 38 5D 80 81 F7 1A "
|
||||
"6C 31 7B 82 86 BD 7F 10 9D 89 B6 F7 AF E4 41 0D "
|
||||
"4F 97 28 80 34 06 3E 19 3A 21 60 ED 54 18 02 0F "
|
||||
"2F D5 D5 3B A5 87 01 21 38 1B A6 99 32 28 E9 8D "
|
||||
"6F 02 35 60 85 BD 64 C4 B0 26 7E 68 D1 E6 97 B5 "
|
||||
"32 6E B2 4F EB 06 4C 4D C2 97 8E 6B 30 22 C0 B4 "
|
||||
"3D 47 93 78 67 AC 27 42 DD 5C 3C 27 ED 0A 6C E4 "
|
||||
"4A 0D 0F DF 52 63 A6 70 76 09 F0 2E 58 F6 05 B2 "
|
||||
"DF EE C9 1F CB 1D 11 0C A1 8B 19 26 B8 10 2C 81 "
|
||||
"48 FF 98 EF 30 36 0C 01 C5 4A D9 AC 05 72 89 C7 "
|
||||
"3F D6 4D E0 17 BA BA B3 D3 E8 1B 0C 8C C8 DF 6B "
|
||||
"FE 7E BA 91 FD F6 A0 CB 59 19 B0 01 2F D7 0B A0 "
|
||||
"62 0F 5F CE 74 B8 EB 42 89 B5 BE CA C9 EF DA 9A "
|
||||
"BB C6 66 1B E0 65 EE D4 3A CE D9 CC 0E BB 85 50 "
|
||||
"41 45 01 BA 1B 29 11 6F 34 11 55 03 DD 0C B5 99 "
|
||||
"56 3A 93 4D 4D 95 6D CE C3 51 E0 15 54 3E FF 2F "
|
||||
"A3 DA 59 EC 3D 59 2D 62 FC 64 39 D6 7B C8 80 78 "
|
||||
"1D D7 FD E8 0B 5D 8A ED 1A 9D 98 CB C2 EE 78 47 "
|
||||
"30 AD 8F 64 A5 82 12 23 DA B3 3E CA 4C 85 7A 80 "
|
||||
"D5 9F 46 20 D6 EE D1 F9 33 FA 1F C5 9C 8E F9 1E "
|
||||
"66 51 A5 46 68 DC B7 7F A8 5A DE E6 18 D7 8C 2B "
|
||||
"5D EA A8 EC 6B 8B 48 C1 92 5A C1 B1 6A 5E 37 82 "
|
||||
"22 4B 6A B6 F0 40 16 89 16 A5 81 F8 D4 1B 20 26 "
|
||||
"86 35 E5 AD C1 01 6E C9 B5 D0 69 C5 0B 31 08 51 "
|
||||
"5D 35 FC 74 F5 13 04 7A F4 57 10 53 5B A4 CC 8B "
|
||||
"21 82 82 15 4B 8C 3D 6B DA 91 85 CB D6 CF 05 80 "
|
||||
"D0 F0 CF 0D DF 7A B4 99 C7 F8 D5 4C 76 56 30 E9 "
|
||||
"65 B6 58 60 C1 C0 39 8A 42 54 BC 4A 48 8B A1 D9 "
|
||||
"5C 32 05 7A 1C BB 50 51 5B 7F C7 75 2D 68 55 E6 "
|
||||
"83 7B C3 98 FD E6 D5 B8 DA A8 31 01 78 F5 60 8B "
|
||||
"1A D2 FD 51 34 47 FA AF 23 AE E2 DE 15 A7 07 66 "
|
||||
"69 35 9A 40 61 55 25 98 23 54 2A 50 C9 7D A6 CE "
|
||||
"74 F8 19 0C 8E 63 E5 49 2F F9 17 05 FD 39 15 55 "
|
||||
"F4 B0 91 BF 60 B7 B2 40 2E 7A D3 68 86 C0 FC 38 "
|
||||
"88 AB B9 03 8A 04 05 1A 9F 61 AE F2 D3 B8 A4 29 "
|
||||
"F8 51 43 CF 84 26 4A 90 6E 13 27 AF 7B 52 DB F9 "
|
||||
"00 E8 AE C0 B5 6F 64 03 57 20 59 7C F5 E1 65 A8 "
|
||||
"47 C3 BD EE 72 2A 85 E2 70 8D EA 9D 98 D4 2A D5 "
|
||||
"70 A2 E9 76 A2 DA E6 7C B0 F7 14 D9 23 B6 88 C0 "
|
||||
"B3 6F 42 12 F4 69 0C 15 81 D6 F7 0B B7 1B DF 15 "
|
||||
"E6 75 63 13 53 B3 20 43 79 90 34 E3 34 48 80 D6 "
|
||||
"86 BB 45 A2 85 DD F8 23 64 3B D5 68 AB 99 53 34 "
|
||||
"C6 25 0A 87 73 17 37 56 39 BA 8C 0E 39 24 4B CC "
|
||||
"AA 98 84 0C 2F 27 E6 E2 AC 86 34 5D 1E 25 AE FD "
|
||||
"1E FF 3C 27 AD 26 18 4A 1A E5 09 61 5D 83 5F 2C "
|
||||
"DC 41 A7 C6 07 55 5B B5 0B 71 FE 86 E7 30 A1 BC "
|
||||
"27 AF 5F 24 51 1A DD 20 F6 32 9E 3D 64 6F DC 43 "
|
||||
"65 2A 80 CB 95 C4 B6 F0 E1 F3 CF 6C F2 C2 9C EA "
|
||||
"81 88 0C 2D D2 DA 74 82 C6 A5 1E 98 D3 BC 71 ED "
|
||||
"E2 0B 05 DA BB 0E FA 35 0A 2C D5 C8 62 E7 B1 AF "
|
||||
"95 14 6C 83 7D F1 CE 9F 13 6B D8 68 C9 A5 F5 87 "
|
||||
"2E A5 8F D7 5C B2 C6 99 37 31 5A A4 D0 E2 43 DF "
|
||||
"C8 BE BD 10 C0 D8 22 63 95 46 1E E7 8C A8 61 E4 "
|
||||
"74 02 6C B4 30 F3 06 15 11 E6 2A 3A 0D 3B 2F B9 "
|
||||
"3B B3 83 40 18 79 FB 39 38 B7 CE 4D BA F6 9E AA "
|
||||
"E1 8F 32 1C B1 68 DD 5C 2C 37 65 61 73 3D C6 34 "
|
||||
"56 CD EA BC 77 6A A1 7D 6A F1 F9 78 AF 0F D9 C2 "
|
||||
"AA D3 D7 A8 2D A8 6E BC 19 83 96 B5 A3 3E B3 B2 "
|
||||
"5C 54 AD 77 CE 1D E5 D5 AA B3 0D 36 7A 32 7D 5C "
|
||||
"A3 60 66 8D 84 A0 BD 4F 0F A9 09 89 B8 EC 14 8A "
|
||||
"2B 2B 74 8E 75 77 5A 8E B2 51 D0 26 D6 06 8C 9A "
|
||||
"CA 31 D6 94 17 F0 14 D7 43 1C 82 0C 00 83 E6 75 "
|
||||
"05 5C 52 AB 0C 38 8F A3 35 77 52 E8 3E 3B CB 48 "
|
||||
"81 E3 25 B1 A9 40 12 76 4F 16 F1 CE 3D D7 23 89 "
|
||||
"44 D7 3F 24 7E B7 46 66 C1 16 7A 17 B2 2A 99 F1 "
|
||||
"AC 3C C9 9D C5 FE 89 BE BF 2C 68 BC 2C A7 F1 C5 "
|
||||
"2F 26 1E CC D1 AF 7D AA 7D C5 94 4A 4D C4 87 97 "
|
||||
"2D 2B 6A 5E 5E BF 39 82 18 AB 8C B9 DC 80 83 A1 "
|
||||
"D1 80 D2 65 FE 2E CC 6A F1 02 84 B2 36 60 37 24 "
|
||||
"4E 5E 57 AD A5 C5 50 1A 5E A4 5C 31 B6 93 60 57 "
|
||||
"AC EB ED 65 3F BF EA C7 08 CA 13 00 93 E5 E6 79 "
|
||||
"F6 37 20 CA B4 6E 39 9E 83 4F 15 8B 15 CD E7 8C "
|
||||
"90 93 B0 85 91 9B AE 21 EF 03 D0 A4 B6 2A B4 C6 "
|
||||
"D3 07 04 92 54 72 8E EC 2E B3 47 6C CE 42 06 7F "
|
||||
"E0 5B 96 F2 48 8B FA 8F 83 E2 47 10 A5 B7 30 F8 "
|
||||
"68 B0 FD 02 74 6F 48 71 D7 F1 2E DF A1 52 61 76 "
|
||||
"99 47 BE 0A 2F F8 F2 69 9D AD 03 FA E6 84 A7 CF "
|
||||
"35 7D 8F 5F C5 A6 9B 21 66 35 BC 58 D5 89 B5 E0 "
|
||||
"9F 11 F0 A8 8A 1F C8 3C 24 B2 B7 F1 6C 8A DB 3B "
|
||||
"39 7A CA D0 EF 15 61 22 72 FD FC 02 3D BD 76 35 "
|
||||
"9E E1 C6 D7 2C B2 59 E1 03 E0 FF 7A 87 03 79 9F "
|
||||
"61 AB CC 49 98 C2 41 CF 6E 9B AA 52 9B D0 08 B5 "
|
||||
"9E 23 F6 C1 39 82 77 16 5D D4 E1 B3 AD A0 0C 58 "
|
||||
"F8 E2 67 00 6A 0B 4B D2 6C E1 C5 6B 9D BA 3F 40 "
|
||||
"82 C5 28 B8 C1 60 75 85 EE C4 FA 04 ED 62 64 B6 "
|
||||
"29 10 67 4B 9B D6 6C 0E 06 62 64 83 CA F0 2F 2D "
|
||||
"B8 F6 0A D7 D7 6A 1C 58 14 BE 18 60 80 29 02 CD "
|
||||
"F6 B1 95 A5 6D 2E 27 9C 08 E3 1F C5 C2 07 7F 63 "
|
||||
"7F DB 82 C6 C6 85 AC A6 D2 4C F1 7F DB 1D CF 86 "
|
||||
"20 56 60 C0 24 E0 C0 42 0B 4E 00 5F 8B 78 60 FE "
|
||||
"EA EC 6D 31 93 49 70 EB 2A 45 4F 92 9B 6C 17 28 "
|
||||
"BB 89 FC C0 07 84 CC AD 1B 85 F2 85 18 5C 3D 5A "
|
||||
"60 54 AF 03 9D 9E E4 26 D3 86 AA 0B 7C A3 32 9C "
|
||||
"C2 0F 3A D4 3E 1F 52 43 A8 31 E9 70 FC 0C B4 7C "
|
||||
"F5 E3 C7 6F 11 ED 22 4C 0C 1B 82 CB 72 A4 95 28 "
|
||||
"1A D4 1B E5 C4 6E D7 F1 EC BF 25 2C B8 92 87 A8 "
|
||||
"D2 15 79 34 39 C0 BE 0D C8 68 2D F2 D3 8E 01 09 "
|
||||
"3C 48 94 32 69 89 D5 C0 5D E8 2C E6 A6 97 59 4B "
|
||||
"9A C6 61 B0 9E DB 81 DC D3 F9 47 34 84 00 CA 87 "
|
||||
"BE 5D 6D 56 F3 01 02 3B FF FF FF FF 00 00 00 00"
|
||||
)
|
||||
|
||||
_BIN_KEYS: bytes = bytes.fromhex(_HEX_KEY.replace(" ", ""))
|
||||
|
||||
|
||||
@dataclass
|
||||
class GbbqRecord:
|
||||
"""股本变迁记录。"""
|
||||
|
||||
market: int
|
||||
code: str
|
||||
datetime: int
|
||||
category: int
|
||||
hongli_panqianliutong: float
|
||||
peigujia_qianzongguben: float
|
||||
songgu_qianzongguben: float
|
||||
peigu_houzongguben: float
|
||||
_raw: bytes = field(default=b"", repr=False, compare=False)
|
||||
|
||||
|
||||
def read_gbbq(filepath: str | Path) -> list[GbbqRecord]:
|
||||
"""从本地 gbbq 文件读取股本变迁数据(XOR 加密)。
|
||||
|
||||
Args:
|
||||
filepath: gbbq 文件路径。
|
||||
|
||||
Returns:
|
||||
GbbqRecord 列表。
|
||||
"""
|
||||
filepath = Path(filepath)
|
||||
if not filepath.is_file():
|
||||
raise TdxFileNotFoundError(f"股本变迁文件不存在: {filepath}")
|
||||
|
||||
content = filepath.read_bytes()
|
||||
if len(content) < 4:
|
||||
return []
|
||||
|
||||
(count,) = struct.unpack("<I", content[:4])
|
||||
results: list[GbbqRecord] = []
|
||||
data_offset = 4
|
||||
|
||||
for _ in range(count):
|
||||
clear_data = bytearray()
|
||||
# 每条记录解密 3 轮,每轮 8 字节
|
||||
for _round in range(3):
|
||||
(eax,) = struct.unpack("<I", _BIN_KEYS[0x44 : 0x44 + 4])
|
||||
(ebx,) = struct.unpack("<I", content[data_offset : data_offset + 4])
|
||||
num = (eax ^ ebx) & _MASK32
|
||||
(numold,) = struct.unpack("<I", content[data_offset + 4 : data_offset + 8])
|
||||
|
||||
for j in range(0x40, 0x04 - 1, -4):
|
||||
ebx = (num & 0xFF0000) >> 16
|
||||
(eax,) = struct.unpack("<I", _BIN_KEYS[ebx * 4 + 0x448 : ebx * 4 + 0x448 + 4])
|
||||
ebx = num >> 24
|
||||
(eax_add,) = struct.unpack("<I", _BIN_KEYS[ebx * 4 + 0x48 : ebx * 4 + 0x48 + 4])
|
||||
eax = (eax + eax_add) & _MASK32
|
||||
ebx = (num & 0xFF00) >> 8
|
||||
(eax_xor,) = struct.unpack("<I", _BIN_KEYS[ebx * 4 + 0x848 : ebx * 4 + 0x848 + 4])
|
||||
eax = (eax ^ eax_xor) & _MASK32
|
||||
ebx = num & 0xFF
|
||||
(eax_add,) = struct.unpack("<I", _BIN_KEYS[ebx * 4 + 0xC48 : ebx * 4 + 0xC48 + 4])
|
||||
eax = (eax + eax_add) & _MASK32
|
||||
(eax_xor,) = struct.unpack("<I", _BIN_KEYS[j : j + 4])
|
||||
eax = (eax ^ eax_xor) & _MASK32
|
||||
ebx = num
|
||||
num = (numold ^ eax) & _MASK32
|
||||
numold = ebx
|
||||
|
||||
(numold_op,) = struct.unpack("<I", _BIN_KEYS[:4])
|
||||
numold = (numold ^ numold_op) & _MASK32
|
||||
clear_data.extend(struct.pack("<II", numold, num))
|
||||
data_offset += 8
|
||||
|
||||
# 追加剩余 5 字节
|
||||
clear_data.extend(content[data_offset : data_offset + 5])
|
||||
|
||||
v1, v2, v3, v4, v5, v6, v7, v8 = struct.unpack("<B7sIBffff", clear_data)
|
||||
results.append(
|
||||
GbbqRecord(
|
||||
market=v1,
|
||||
code=v2.rstrip(b"\x00").decode("utf-8"),
|
||||
datetime=v3,
|
||||
category=v4,
|
||||
hongli_panqianliutong=v5,
|
||||
peigujia_qianzongguben=v6,
|
||||
songgu_qianzongguben=v7,
|
||||
peigu_houzongguben=v8,
|
||||
_raw=bytes(clear_data),
|
||||
)
|
||||
)
|
||||
data_offset += 5
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,59 @@
|
||||
"""历史财务数据读取(gpcw*.dat / gpcw*.zip 文件)。"""
|
||||
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
from ..codec.financial import parse_financial_dat
|
||||
from ..exceptions import TdxFileNotFoundError, TdxOfflineError
|
||||
from ..models.enums import Market
|
||||
from ..models.finance import FinancialRecord
|
||||
|
||||
|
||||
def read_history_financial(filepath: str | Path) -> list[FinancialRecord]:
|
||||
"""从本地 gpcw*.dat 或 gpcw*.zip 文件读取历史财务数据。
|
||||
|
||||
复用 codec/financial.py 的 parse_financial_dat() 解析二进制格式。
|
||||
|
||||
Args:
|
||||
filepath: .dat 或 .zip 文件路径。
|
||||
|
||||
Returns:
|
||||
FinancialRecord 列表。
|
||||
"""
|
||||
filepath = Path(filepath)
|
||||
if not filepath.is_file():
|
||||
raise TdxFileNotFoundError(f"历史财务数据文件不存在: {filepath}")
|
||||
|
||||
if filepath.suffix.lower() == ".zip":
|
||||
data = _read_from_zip(filepath)
|
||||
else:
|
||||
data = filepath.read_bytes()
|
||||
|
||||
raw_records = parse_financial_dat(data)
|
||||
results: list[FinancialRecord] = []
|
||||
for code, market_byte, report_date, fields in raw_records:
|
||||
try:
|
||||
market = Market(market_byte)
|
||||
except ValueError:
|
||||
market = Market.SZ # 默认深圳
|
||||
results.append(
|
||||
FinancialRecord(
|
||||
code=code,
|
||||
market=market,
|
||||
report_date=report_date,
|
||||
fields=fields,
|
||||
)
|
||||
)
|
||||
return results
|
||||
|
||||
|
||||
def _read_from_zip(zip_path: Path) -> bytes:
|
||||
"""从 zip 中提取 .dat 文件内容。"""
|
||||
try:
|
||||
with zipfile.ZipFile(zip_path, "r") as zf:
|
||||
for name in zf.namelist():
|
||||
if name.endswith(".dat"):
|
||||
return zf.read(name)
|
||||
raise TdxOfflineError(f"zip 中未找到 .dat 文件: {zip_path}")
|
||||
except zipfile.BadZipFile as e:
|
||||
raise TdxOfflineError(f"无效的 zip 文件: {zip_path}") from e
|
||||
@@ -0,0 +1,122 @@
|
||||
"""分钟 K 线数据读取(.5 文件和 .lc1/.lc5 文件)。"""
|
||||
|
||||
import struct
|
||||
from pathlib import Path
|
||||
|
||||
from ..exceptions import TdxFileNotFoundError
|
||||
from ..models.bar import SecurityBar
|
||||
|
||||
# .5 文件: 日期(2B) 时间(2B) 开盘(4B) 最高(4B) 最低(4B) 收盘(4B) 额(4B) 量(4B) 保留(4B)
|
||||
_MIN_FMT = struct.Struct("<HHIIIIfII")
|
||||
|
||||
# .lc1/.lc5 文件: 日期(2B) 时间(2B) 开(4Bf) 高(4Bf) 低(4Bf) 收(4Bf) 额(4Bf) 量(4B) 保留(4B)
|
||||
_LC_MIN_FMT = struct.Struct("<HHfffffII")
|
||||
|
||||
|
||||
def _decode_tdx_date(num: int) -> tuple[int, int, int]:
|
||||
"""解码通达信压缩日期(2 字节)。"""
|
||||
year = num // 2048 + 2004
|
||||
month = (num % 2048) // 100
|
||||
day = (num % 2048) % 100
|
||||
return year, month, day
|
||||
|
||||
|
||||
def _decode_tdx_time(num: int) -> tuple[int, int]:
|
||||
"""解码通达信分钟时间(从 0:00 开始的分钟数)。"""
|
||||
return num // 60, num % 60
|
||||
|
||||
|
||||
def read_5min_bars(filepath: str | Path) -> list[SecurityBar]:
|
||||
"""从本地 .5 文件读取 5 分钟 K 线数据。
|
||||
|
||||
OHLC 为整数,需除以 100 得到实际价格。
|
||||
|
||||
Args:
|
||||
filepath: .5 文件路径。
|
||||
|
||||
Returns:
|
||||
SecurityBar 列表(按时间升序)。
|
||||
"""
|
||||
filepath = Path(filepath)
|
||||
if not filepath.is_file():
|
||||
raise TdxFileNotFoundError(f"分钟线数据文件不存在: {filepath}")
|
||||
|
||||
data = filepath.read_bytes()
|
||||
if len(data) < _MIN_FMT.size:
|
||||
return []
|
||||
|
||||
results: list[SecurityBar] = []
|
||||
record_size = _MIN_FMT.size
|
||||
for offset in range(0, len(data) - record_size + 1, record_size):
|
||||
raw = data[offset : offset + record_size]
|
||||
date_num, time_num, op, hi, lo, cl, amount, vol, _res = _MIN_FMT.unpack(raw)
|
||||
|
||||
year, month, day = _decode_tdx_date(date_num)
|
||||
hour, minute = _decode_tdx_time(time_num)
|
||||
|
||||
results.append(
|
||||
SecurityBar(
|
||||
open=op / 100.0,
|
||||
close=cl / 100.0,
|
||||
high=hi / 100.0,
|
||||
low=lo / 100.0,
|
||||
vol=vol,
|
||||
amount=amount,
|
||||
year=year,
|
||||
month=month,
|
||||
day=day,
|
||||
hour=hour,
|
||||
minute=minute,
|
||||
_raw=raw,
|
||||
)
|
||||
)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def read_lc_min_bars(filepath: str | Path) -> list[SecurityBar]:
|
||||
"""从本地 .lc1/.lc5 文件读取分钟 K 线数据。
|
||||
|
||||
OHLC 为 float 类型,无需额外转换。
|
||||
|
||||
Args:
|
||||
filepath: .lc1 或 .lc5 文件路径。
|
||||
|
||||
Returns:
|
||||
SecurityBar 列表(按时间升序)。
|
||||
"""
|
||||
filepath = Path(filepath)
|
||||
if not filepath.is_file():
|
||||
raise TdxFileNotFoundError(f"分钟线数据文件不存在: {filepath}")
|
||||
|
||||
data = filepath.read_bytes()
|
||||
if len(data) < _LC_MIN_FMT.size:
|
||||
return []
|
||||
|
||||
results: list[SecurityBar] = []
|
||||
record_size = _LC_MIN_FMT.size
|
||||
for offset in range(0, len(data) - record_size + 1, record_size):
|
||||
raw = data[offset : offset + record_size]
|
||||
date_num, time_num, op, hi, lo, cl, amount, vol, _res = _LC_MIN_FMT.unpack(raw)
|
||||
|
||||
year, month, day = _decode_tdx_date(date_num)
|
||||
hour, minute = _decode_tdx_time(time_num)
|
||||
|
||||
results.append(
|
||||
SecurityBar(
|
||||
open=op,
|
||||
close=cl,
|
||||
high=hi,
|
||||
low=lo,
|
||||
vol=vol,
|
||||
amount=amount,
|
||||
year=year,
|
||||
month=month,
|
||||
day=day,
|
||||
hour=hour,
|
||||
minute=minute,
|
||||
_raw=raw,
|
||||
)
|
||||
)
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,74 @@
|
||||
"""通达信安装目录检测与路径解析。"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from ..exceptions import TdxOfflineError
|
||||
|
||||
_WIN_CANDIDATES = [
|
||||
Path(r"C:\new_jyplug"),
|
||||
Path(r"C:\new_tdx"),
|
||||
Path(r"D:\new_jyplug"),
|
||||
Path(r"D:\new_tdx"),
|
||||
]
|
||||
|
||||
_UNIX_CANDIDATES = [
|
||||
Path.home() / "new_jyplug",
|
||||
Path.home() / "new_tdx",
|
||||
]
|
||||
|
||||
|
||||
def detect_tdx_home() -> Path | None:
|
||||
"""按优先级检测通达信安装目录。
|
||||
|
||||
1. TDX_HOME 环境变量
|
||||
2. 平台常见路径猜测
|
||||
"""
|
||||
env = os.getenv("TDX_HOME")
|
||||
if env:
|
||||
p = Path(env)
|
||||
if p.is_dir():
|
||||
return p
|
||||
candidates = _WIN_CANDIDATES if sys.platform == "win32" else _UNIX_CANDIDATES
|
||||
for p in candidates:
|
||||
if p.is_dir():
|
||||
return p
|
||||
return None
|
||||
|
||||
|
||||
def resolve_vipdoc(path: str | Path | None = None) -> Path:
|
||||
"""解析 vipdoc 数据目录。
|
||||
|
||||
Args:
|
||||
path: 显式指定的 vipdoc 路径。为 None 时自动检测。
|
||||
|
||||
Returns:
|
||||
vipdoc 目录的 Path 对象。
|
||||
|
||||
Raises:
|
||||
TdxOfflineError: 无法定位 vipdoc 目录。
|
||||
"""
|
||||
if path is not None:
|
||||
p = Path(path)
|
||||
if p.is_dir():
|
||||
return p
|
||||
raise TdxOfflineError(f"指定的 vipdoc 路径不存在: {p}")
|
||||
home = detect_tdx_home()
|
||||
if home is None:
|
||||
raise TdxOfflineError(
|
||||
"无法定位通达信安装目录,请设置 TDX_HOME 环境变量或显式传入 vipdoc 路径"
|
||||
)
|
||||
vipdoc = home / "vipdoc"
|
||||
if not vipdoc.is_dir():
|
||||
raise TdxOfflineError(f"vipdoc 目录不存在: {vipdoc}")
|
||||
return vipdoc
|
||||
|
||||
|
||||
def _market_to_exchange(market: int) -> str:
|
||||
"""Market 枚举值 → vipdoc 子目录名(sh/sz)。"""
|
||||
if market == 0: # Market.SZ
|
||||
return "sz"
|
||||
if market == 1: # Market.SH
|
||||
return "sh"
|
||||
raise TdxOfflineError(f"不支持的市场代码: {market}")
|
||||
@@ -0,0 +1,872 @@
|
||||
version = 1
|
||||
revision = 1
|
||||
requires-python = ">=3.10"
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.15' and sys_platform == 'win32'",
|
||||
"python_full_version >= '3.15' and sys_platform == 'emscripten'",
|
||||
"python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
"python_full_version == '3.14.*' and sys_platform == 'win32'",
|
||||
"python_full_version == '3.14.*' and sys_platform == 'emscripten'",
|
||||
"python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'win32'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'emscripten'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
"python_full_version < '3.11'",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ast-serialize"
|
||||
version = "0.5.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/81/9d/09e27731bd5864a9ce04e3244074e674bb8936bf62b45e0357248717adac/ast_serialize-0.5.0.tar.gz", hash = "sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6", size = 61157 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/9a/13dde51ba9e15f8b97957ab7cb0120d0e381524d651c6bd630b9c359227f/ast_serialize-0.5.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a", size = 1183520 },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/de/5a7f0a9fe68944f536632a5af84676739c7d2582be42deb082634bf3a754/ast_serialize-0.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b", size = 1175779 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/81/0bb853e76e4f6e9a1855d569003c59e19ffac45f7079d91505d1bb212f92/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1", size = 1233750 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/d3/4cf705beeccc08754d0bbda99aefff26110e209b9a07ac8a6b60eec48531/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6", size = 1235942 },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/c8/ee097e437ea27dd2b8b227865c875492b585650a5802a22d82b304c8201b/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2", size = 1442517 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/bd/68063442838f1ba68ec72b5436430bc75b3bb17a1a3c3063f09b0c05ae2b/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903", size = 1254081 },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/e2/1e520793bc6a4e4524a6ab022391e827825eaa0c3811828bfdc6852eca26/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261", size = 1259910 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/e1/49b60f467979979cfe6913b43948ff25bca971ad0591d181812f163a988e/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027", size = 1250678 },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/ba/66ab9555de6275677566f6574e5ef6c29cb185ea866f643bc06f8280a8ee/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937", size = 1301603 },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/42/6aca9b9abc710014b2be9059689e5dd1679339e78f567ffb4d255a9e2050/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c", size = 1410332 },
|
||||
{ url = "https://files.pythonhosted.org/packages/47/68/2f76594432a22581ecf878b5e75a9b8601c24b2241cf0bbeb1e21fcf370c/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b", size = 1509979 },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/ac/a93c9b58292653f6c595752f677a08e608f903b710594909e9231a389b3b/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab", size = 1505002 },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/2e/b278f68c497ee2f1d1576cbbef8db5281cd4a5f2db040537592ac9c8862e/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3", size = 1456231 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/43/419be1c566a4c504cd8fd60ce2f84e790f295495c0f327cfaeadf3d51012/ast_serialize-0.5.0-cp314-cp314t-win32.whl", hash = "sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38", size = 1058668 },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/6f/c9d4d549295ed05111aeb8853232d1afd9d0a179fddb01eeffbb3a4a6842/ast_serialize-0.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c", size = 1101075 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/8e/d00c5ab30c58222e07d62956fca86c59d91b9ad32997e633c38b526623a3/ast_serialize-0.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb", size = 1075347 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/9e/dc2530acb3a60dc6e46d65abf27d1d9f86721694757906a148d90a6860de/ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101", size = 1191380 },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/0a/bd3d18a582f273d6c843d16bb9e22e9e16365ff7991e92f18f798e9f1224/ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a", size = 1183879 },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/ae/1f919100f8620887af58fcc381c61a1f218cdf89c6e155f87b213e61010a/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211", size = 1244529 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/ca/6376559dcce707cdbc1d0d9a13c8d3baaaa501e949ce0ebdc4230cd881aa/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf", size = 1240560 },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/b2/a620e206b5aeb7efbf2710336df57d457cffbb3991076bbcc1147ef9abd4/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9", size = 1451172 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/e0/4ad5c04c24a40481b2935ce9a0ccdb6023dc8b667167d06ae530cc3512f2/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee", size = 1265072 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/71/4d1d479aa56d0101c40e17720c3d6ac2af7269ea0487a80b18e7bfd1a5b7/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809", size = 1270488 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/4f/0de1bbe06f6edef9fde4ed12ca8e7b3ec7e6e2bd4e672c5af487f7957665/ast_serialize-0.5.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43", size = 1260702 },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/61/e00872439cfdddcc3c1b6cdaa6e5d904ba8e26a18807c67c4e14409d0ca8/ast_serialize-0.5.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934", size = 1311182 },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/8e/699a5b955f7926956c95e9e1d74132acad73c2fe7a426f94da89123c20aa/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759", size = 1421410 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/ae/d5b7626874478997adc7a29ab28accf21e596fb590c944290401dfd0b29e/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887", size = 1516587 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/ce/b59e02a82d9c4244d64cde502e0b00e83e38816abe19155ceb5437402c7f/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27", size = 1515171 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/38/d8d90042747d05aa08d4efcf1c99035a5f670a6bf4c214d31644392afbca/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d", size = 1464668 },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/51/5b840c4df7334104cecffa28f23904fe81ca89ca223d2450e288de39fd3c/ast_serialize-0.5.0-cp39-abi3-win32.whl", hash = "sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a", size = 1068311 },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/11/ca5672c7d491825bc4cd6702dea106a6b60d928707712ec257c7833ae476/ast_serialize-0.5.0-cp39-abi3-win_amd64.whl", hash = "sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590", size = 1108931 },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/19/cc8bd127d28a43da249aa955cfd164cf8fd534e79e42cea96c4854d72fd0/ast_serialize-0.5.0-cp39-abi3-win_arm64.whl", hash = "sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642", size = 1081181 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "7.14.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/23/7f/d0720730a397a999ffc0fd3f5bebef347338e3a47b727da66fbb228e2ff2/coverage-7.14.0.tar.gz", hash = "sha256:057a6af2f160a85384cde4ab36f0d2777bae1057bae255f95413cdd382aa5c74", size = 919489 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/59/9d/7c83ef51c3eb495f10010094e661833588b7709946da634c8b66520b97c7/coverage-7.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:84c32d90bf4537f0e7b4dec9aaa9a938fb8205136b9d2ecf4d7629d5262dc075", size = 219668 },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/34/898546aefbd28f0af131201d0dc852c9e976f817bd7d5bfb8dc4e02863bb/coverage-7.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7c843572c605ab51cfdb5c6b5f2586e2a8467c0d28eca4bdef4ec70c5fecbd82", size = 220192 },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/4a/b457c88aca72b0df13a98167ebd5d947135ccd9881ea88ce6a570e13aa9b/coverage-7.14.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0c451757d3fa2603354fdc789b5e58a0e327a117c370a40e3476ba4eabab228c", size = 246932 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/d9/92600e89486fd074c50f0117422b2c9592c3e144e2f25bd5ac0bc62bc7a0/coverage-7.14.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3fd43f0616e765ab78d069cf8358def7363957a45cee446d65c502dcfeea7893", size = 248762 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/e1/9ea1eb9c311da7f15853559dc1d9d82bef88ecd3e59fbeb51f16bc2ffa91/coverage-7.14.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:731e535b1498b27d13594a0527a79b0510867b0ad891532be41cb883f2128e20", size = 250625 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/03/57afca1b8106f8549a5329139315041fe166d6099bd9381346b9430dfbd1/coverage-7.14.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c7492f2d493b976941c7ca050f273cbda2f43c381124f7586a3e3c16d1804fec", size = 252539 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/5e/2e9fc63c9928119c1dbae02222be51407d3e7ebac5811ebbda4af3557795/coverage-7.14.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dc38367eaa2abb1b766ac333142bce7655335a73537f5c8b75aaa89c2b987757", size = 247636 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/e2/0b7898cda21041cc67546e19b80ba66cbbb47cbece52a76a5904de6a3aaf/coverage-7.14.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0a951308cde22cf77f953955a754d04dccb57fe3bb8e345d685778ed9fc1632a", size = 248666 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/e3/d33662a2fdaef23229c15921f39c84ec38441f3069ba26e134ed402c833b/coverage-7.14.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fab3877e4ebb06bd9d4d4d00ee53309ee5478e66873c66a382272e3ee33eb7ea", size = 246670 },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/b2/533942c3bfbf6770b5c32d7f2ff029fe013dba31f3fe8b45cabbb250365e/coverage-7.14.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b812eb847b19876ebf33fb6c4f11819af05ab6050b0bfa1bc53412ae81779adb", size = 250484 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/00/15acbad83a96de13c73831486c7627bfed73dfaec53b04e4a6315edf3fd8/coverage-7.14.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d9c8ef6ed820c433de075657d72dda1f89a2984955e58b8a75feb3f184250218", size = 246942 },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/db/cef0228de493f2c740c760a9057a61d00c6849480073b70a75b87c7d4bab/coverage-7.14.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d128b1bba9361fbaaf6a19e179e6cfd6a9103ce0c0555876f72780acc93efd85", size = 247544 },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/a0/d9ef8e148f3025c2ae8401d77cda1502b6d2a4d8102603a8af31460aedb6/coverage-7.14.0-cp310-cp310-win32.whl", hash = "sha256:65f267ca1370726ec2c1aa38bbe4df9a71a740f22878d2d4bf59d71a4cd8d323", size = 222285 },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/c0/30c454c7d3cf47b2805d4e06f12443f5eece8a5d030d3b0350e7b74ecb49/coverage-7.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:b34ece8065914f938ed7f2c5872bb865336977a52919149846eac3744327267a", size = 223215 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/e4/649c8d4f7f1709b6dbfc474358aa1bba02f67bcd52e2fec291a5014006cd/coverage-7.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a78e2a9d9c5e3b8d4ab9b9d28c985ea66fced0a7d7c2aec1f216e03a2011480", size = 219795 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/8d/46692d24b3f395d4cbf17bfcc57136b4f2f9c0c0df864b0bddfc1d71a014/coverage-7.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1816c505187592dcd1c5a5f226601a549f70365fbd00930ac88b0c225b76bb4", size = 220299 },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/c2/a40f5cb295bbcbb697a76947a56081c494c61950366294ee426ffe261099/coverage-7.14.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d8e1762f0e9cbc26ec315471e7b47855218e833cd5a032d706fbf43845d878c7", size = 250721 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/35/202235eb5c3c14c212462cd91d61b7386bf8fc44bc7a77f4742d2a69174b/coverage-7.14.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9336e23e8bb3a3925398261385e2a1533957d3e760e91070dcb0e98bfa514eed", size = 252633 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/80/5f596e8995785124ee191c42535664c5e62c65995b66f4ca21e28ae04c81/coverage-7.14.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd1169b2230f9cbe9c638ba38022ed7a2b1e641cc07f7cea0365e4be2a74980", size = 254743 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/6d/0d178825be2350f0adb27984d0aa7cf84bbdab201f6fb926b535d23a8f5f/coverage-7.14.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d1bb3543b58fea74d2cd1abc4054cc927e4724687cb4560cd2ed88d2c7d820c0", size = 256700 },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/5b/9e549c2f6e9dfea472adadba06c294e64735dabc2dd19015fac082095013/coverage-7.14.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a93bac2cb577ef60074999ed56d8a1535894398e2ed920d4185c3ec0c8864742", size = 250854 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/1c/b94f9f5f36396021ee2f62c5834b12e6a3d31f0bed5d6fc6d1c3caec087c/coverage-7.14.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5904abf7e18cddc463219b17552229650c6b79e061d31a1059283051169cf7d5", size = 252433 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/cb/d192cd8e1345eccabc32016f2d39072ecd10cb4f4b983ed8d0ebdeaf00dc/coverage-7.14.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:741f57cddc9004a8c81b084660215f33a6b597dbe62c31386b983ee26310e327", size = 250494 },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/c5/aac9f460a41d835dbddef1d377f105f6ac2311d0f3c1588e9f51046d8813/coverage-7.14.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:664123feb0929d7affc135717dbd70d61d98688a08ab1e5ba464739620c6252d", size = 254261 },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/aa/7af7c0081980a9cb3d289c5a435a4b7657dcecbd128e25c580e6a50389b5/coverage-7.14.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:c83d2399a51bbec8429266905d33616f04bc5726b1138c35844d5fcd896b2e20", size = 250216 },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/60/a4257538ce2f6b978aeb51870d6c4208c510928a03db7e0339bb625dccb7/coverage-7.14.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb2e855b87321259a037429288ae85216d191c74de3e79bf57cd2bc0761992c", size = 251125 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/ab/f91af47642ec1aa53490e835a95847168d9c77fc39aa58527604c051e145/coverage-7.14.0-cp311-cp311-win32.whl", hash = "sha256:731dc15b385ac52289743d476245b61e1a2927e803bef655b52bc3b2a75a21f3", size = 222300 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/f0/a71ddbd874431e7a7cd96071f0c331cfbbad07704833c765d24ffbab8a67/coverage-7.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:bfb0ed8ec5d25e93face268115d7964db9df8b9aae8edcde9ec6b16c726a7cc1", size = 223241 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/6e/d9d312a5151a96cd110efee32efc3fc97b01ebd86203fe618ccb29cf4c92/coverage-7.14.0-cp311-cp311-win_arm64.whl", hash = "sha256:7ebb1c6df9f78046a1b1e0a89674cd4bf73b7c648914eebcf976a57fd99a5627", size = 221908 },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/1e/2f996b2c8415cbb6f54b0f5ec1ee850c96d7911961afb4fc05f4a89d8c58/coverage-7.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7ffd19fc8aed057fd686a17a4935eef5f9859d69208f96310e893e64b9b6ccf5", size = 219967 },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/23/35c7aea1274aef7525bdd2dc92f710bdde6d11652239d71d1ec450067939/coverage-7.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:829994cfe1aeb773ca27bf246d4badc1e764893e3bfb98fff820fcecd1ca4662", size = 220329 },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/cf/a8f4b43a16e194b0261257ad28ded5853ec052570afef4a84e1d81189f3b/coverage-7.14.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b4f07cf7edcb7ec39431a5074d7ea83b29a9f71fcfc494f0f40af4e65180420f", size = 251839 },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/ff/6699e7b71e60d3049eb2bdcbc95ee3f35707b2b0e48f32e9e63d3ce30c08/coverage-7.14.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ca3d9cf2c32b521bd9518385608787fa86f38daf993695307531822c3430ed67", size = 254576 },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/ec/c936d495fcd67f48f03a9c4ad3297ff80d1f222a5df3980f15b34c186c21/coverage-7.14.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92af52828e7f29d827346b0294e5a0853fa206db77db0395b282918d41e28db9", size = 255690 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/42/5af63f636cc62a4a2b1b3ba9146f6ee6f53a35a50d5cefc54d5670f60999/coverage-7.14.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7b2bb6c9d7e769360d0f20a0f219603fd64f0c8f97de17ab25853261602be0fb", size = 257949 },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/d3/a225317bd2012132a27e1176d51660b826f99bb975876463c44ea0d7ee5a/coverage-7.14.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1c9ed6ef99f88fb8c14aa8e2bf8eb0fe55fa2edfea68f8675d78741df1a5ac0e", size = 252242 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/7f/9e65495298c3ea414742998539c37d048b5e81cc818fb1828cc6b51d10bf/coverage-7.14.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8231ade007f37959fbf58acc677f26b922c02eda6f0428ea307da0fd39681bf3", size = 253608 },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/46/1522b524a35bdad22b2b8c4f9d32d0a104b524726ec380b2db68db1746f5/coverage-7.14.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d8b013632cc1ce1d09dbe4f32667b4d320ec2f54fc326ebeffcd0b0bcc2bb6c4", size = 251753 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/e9/cdf00d38817742c541ade405e115a3f7bf36e6f2a8b99d4f209861b85a2d/coverage-7.14.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1733198802d71ec4c524f322e2867ee05c62e9e75df86bdca545407a221827d1", size = 255823 },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/fc/5e7877cf5f902d08a17ff1c532511476d87e1bea355bd5028cb97f902e79/coverage-7.14.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:72a305291fa8ee01332f1aaf38b348ca34097f6aa0b0ef627eef2837e57bbba5", size = 251323 },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/9d/50f05a72dff8487464fdd4178dda5daed642a060e60afb644e3d45123559/coverage-7.14.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fcaba850dd317c65423a9d63d88f9573c53b00354d6dd95724576cc98a131595", size = 253197 },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/3f/6f61ffe6439df266c3cf60f5c99cfaa21103d0210d706a42fc6c30683ff8/coverage-7.14.0-cp312-cp312-win32.whl", hash = "sha256:5ac83957a80d0701310e96d8bec68cdcf4f90a7674b7d13f15a344315b41ab27", size = 222515 },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/19/93853133df2cb371083285ef6a93982a0173e7a233b0f61373ba9fd30eb2/coverage-7.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:70390b0da32cb90b501953716302906e8bcce087cb283e70d8c97729f22e92b2", size = 223324 },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/18/9f7fe62f659f24b7a82a0be56bf94c1bd0a89e0ae7ab4c668f6e82404294/coverage-7.14.0-cp312-cp312-win_arm64.whl", hash = "sha256:91b993743d959b8be85b4abf9d5478216a69329c321efe5be0433c1a841d691d", size = 221944 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/76/b7c66ee3c66e1b0f9d894c8125983aa0c03fb2336f2fd16559f9c966157f/coverage-7.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f2bbb8254370eb4c628ff3d6fa8a7f74ddc40565394d4f7ab791d1fe568e37ef", size = 219990 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/af/e567cbad5ba69c013a50146dfa886dc7193361fda77521f51274ff620e1b/coverage-7.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:23b81107f46d3f21d0cbce30664fcec0f5d9f585638a67081750f99738f6bf66", size = 220365 },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/6f/9ad575d505b4d805b254febc8a5b338a2efe278f8786e56ff1cb8413f9c3/coverage-7.14.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:22a7e06a5f11a757cdfe79018e9095f9f69ae283c5cd8123774c788deec8717b", size = 251363 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/5f/b5370068b2f57787454592ed7dcd1002f0f1703b7db1fa30f6a325a4ca6e/coverage-7.14.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9d1aa57a1dc8e05bdc42e81c5d671d849577aeedf279f4c449d6d286f9ed88ca", size = 253961 },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/1e/51adf17738976e8f2b85ddef7b7aa12a0838b056c92f175941d8862767c1/coverage-7.14.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90c1a51bcfddf645b3bb7ec333d9e94393a8e94f55642380fa8a9a5a9e636cb7", size = 255193 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/7b/5bfd7ac1df3b881c2ac7a5cbc99c7609e6296c402f5ef587cd81c6f355b3/coverage-7.14.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a841fae2fadcae4f438d43b6ccc4aac2ad609f47cdb6cfdce60cbb3fe5ca7bc2", size = 257326 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/38/1d37d316b174fad3843a1d76dbdfe4398771c9ecd0515935dd9ece9cd627/coverage-7.14.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c79d2319cabef1fe8e86df73371126931550804738f78ad7d31e3aad85a67367", size = 251582 },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/46/746704f95980ba220214e1a41e18cec5aea80a898eaa53c51bf2d645ff36/coverage-7.14.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1b23b0c6f0b1db6ad769b7050c8b641c0bf215ded26c1816955b17b7f26edfa9", size = 253325 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/b9/bbe87206d9687b192352f893797825b5f5b15ecd3aa9c68fbff0c074d77b/coverage-7.14.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:55d3089079ce181a4566b1065ab28d2575eb76d8ac8f81f4fcda2bf037fee087", size = 251291 },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/57/b8cdb12ac0d73ef0243218bd5e22c9df8f92edab8018213a86aec67c5324/coverage-7.14.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:49c005cba1e2f9677fb2845dcdf9a2e72a52a17d63e8231aaaae35d9f50215ef", size = 255448 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/d4/5002019538b2036ce3c84340f54d2fd5100d55b0a6b0894eee56128d03c7/coverage-7.14.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:9117377b823daa28aa8635fbb08cda1cd6be3d7143257345459559aeef852d52", size = 251110 },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/53/20c5009477660f084e6ed60bc02a91894b8e234e617e86ecfd9aaf78e27b/coverage-7.14.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7b79d646cf46d5cf9a9f40281d4441df5849e445726e369006d2b117710b33fe", size = 252885 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/ab/3cf6427ac9c1f1db747dbb1ce71dde47984876d4c2cfd018a3fef0a78d4d/coverage-7.14.0-cp313-cp313-win32.whl", hash = "sha256:fb609b3658479e33f9516d46f1a89dbb9b6c261366e3a11844a96ec487533dae", size = 222539 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/b8/9228523e80321c2cb4880d1f589bc0171f2f71432c35118ad04dc01decce/coverage-7.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:0773d8329cf32b6fd222e4b52622c61fe8d503eb966cfc8d3c3c10c96266d50e", size = 223344 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/99/118daa192f95e3a6cb2740100fbf8797cda1734b4134ef0b5d501a7fa8f3/coverage-7.14.0-cp313-cp313-win_arm64.whl", hash = "sha256:b4e26a0f1b696faf283bffe5b8569e44e336c582439df5d53281ab89ee0cba96", size = 221966 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/f1/a46cc0c013be170216253184a32366d7cbdb9252feaec866b05c2d12a894/coverage-7.14.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:953f521ca9445300397e65fda3dca58b2dbd68fee983777420b57ac3c77e9f90", size = 220679 },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/8c/9c30a3d311a34177fa432995be7fbfc64477d8bac5630bd38055b1c9b424/coverage-7.14.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:98af83fd65ae24b1fdd03aaead967a9f523bcd2f1aab2d4f3ffda65bb568a6f1", size = 221033 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/cd/3fb5e06c3badefd0c1b47e2044fdca67f8220a4ec2e7fcfb476aa0a67c6c/coverage-7.14.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:668b92e6958c4db7cf92e81caac328dfbbdbb215db2850ad28f0cbe1eea0bfbd", size = 262333 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/e6/fbc322325c7294d3e22c1ad6b79e45d0806b25228c8e5842aed6d8169aa7/coverage-7.14.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9fbd898551762dea00d3fef2b1c4f99afd2c6a3ff952ea07d60a9bd5ed4f34bc", size = 264410 },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/92/c497b264bec1673c47cc77e26f760fcda4654cabf1f39546d1a23a3b8c35/coverage-7.14.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68af363c07ecd8d4b7d4043d85cb376d7d227eceb54e5323ee45da73dbd3e426", size = 266836 },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/fc/045da320987f401af5d2815d351e8aa799aec859f60e29f445e3089eeedb/coverage-7.14.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6e57054a583da8ac55edf24117ea4c9133032cfc4cf72aa2d48c1e5d4b52f899", size = 267974 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/ae/227b1e379497fb7a4fc3286e620f80c8a1e7cec66d45695a01639eb1af65/coverage-7.14.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cc3499459bbcdd51a65b64c35ab7ed2764eaf3cba826e0df3f1d7fe2e102b70b", size = 261578 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/f5/3570342900f2acea31d33ff1590c5d8bac1a8e1a2e1c6d34a5d5e61de681/coverage-7.14.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:45899ec2138a4346ed34d601dedf5076fb74edf2d1dd9dc76a78e82397edee90", size = 264394 },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/29/de1bbc01c935b28f89b1dc3db85b011c055e843a8e5e3b83141c3f80af7f/coverage-7.14.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8767486808c436f05b23ab98eb963fb29185e32a9357a166971685cb3459900f", size = 262022 },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/95/f53890b0bf2fc10ab168e05d38869215e73ca24c4cb521c3bb0eb62fe16b/coverage-7.14.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:a3b5ddfd6aa7ddad53ee3edb231e88a2151507a43229b7d71b953916deca127d", size = 265732 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/ea/c919e259081dd2bdf0e43b87209709ba7ec2e4117c2a7f5185379c43463c/coverage-7.14.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:63df0fe568e698e1045792399f8ab6da3a6c2dce3182813fb92afa2641087b47", size = 260921 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/2c/c2831889705a81dc5d1c6ca12e4d8e9b95dfc146d153488a6c0ea685d28e/coverage-7.14.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:827d6397dbd95144939b18f89edf31f63e1f99633e8d5f32f22ba8bdda567477", size = 263109 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/a9/2fcae5003cac3d63fe344d2166243c2756935f48420863c5272b240d550b/coverage-7.14.0-cp313-cp313t-win32.whl", hash = "sha256:7bf43e000d24012599b879791cff41589af90674722421ef11b11a5431920bab", size = 223212 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/bb/18e94d7b14b9b398164197114a587a04ab7c9fdbe1d237eef57311c5e883/coverage-7.14.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3f5549365af25d770e06b1f8f5682d9a5637d06eb494db91c6fa75d3950cc917", size = 224272 },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/56/4f14fad782b035c81c4ffd09159e7103d42bb1d93ac8496d04b90a11b7da/coverage-7.14.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6d160217ec6fe890f16ad3a9531761589443749e448f91986c972714fad361c8", size = 222530 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/18/b9a6586d73992807c26f9a5f274131be3d76b56b18a82b9392e2a25d2e45/coverage-7.14.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9aed9fa983514ca032790f3fe0d1c0e42ca7e16b42432af1706b50a9a46bef5d", size = 220036 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/9b/4165a1d56ddc302a0e2d518fd9d412a4fd0b57562618c78c5f21c57194f5/coverage-7.14.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ba3b8390db29296dbbf49e91b6fe08f990743a90c8f447ba4c2ffc29670dfa63", size = 220368 },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/aa/c12e52a5ba148d9995229d557e3be6e554fe469addc0e9241b2f0956d8ea/coverage-7.14.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3a5d8e876dfa2f102e970b183863d6dedd023d3c0eeca1fe7a9787bc5f28b212", size = 251417 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/51/ec641c26e6dca1b25a7d2035ba6ecb7c884ef1a100a9e42fbe4ce4405139/coverage-7.14.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5ebb8f4614a3787d567e610bbfdf96a4798dd69a1afb1bd8ad228d4111fe6ff3", size = 253924 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/c4/59c3de0bd1b538824173fd518fed51c1ce740ca5ed68e74545983f4053a9/coverage-7.14.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b9bf47223dd8db3d4c4b2e443b02bace480d428f0822c3f991600448a176c97", size = 255269 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/a9/36dfa153a62040296f6e7febfdb20a5720622f6ef5a81a41e8237b9a5344/coverage-7.14.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3485a836550b303d006d57cc06e3d5afaabc642c77050b7c985a97b13e3776b8", size = 257583 },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/7b/cc2c048d4114d9ab1c2409e9ee365e5ae10736df6dffcfc9444effa6c708/coverage-7.14.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3e7e88110bae996d199d1693ca8ec3fd52441d426401ae963437598667b4c5eb", size = 251434 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/df/6770eaa576e604575e9a78055313250faef5faa84bd6f71a39fece519c43/coverage-7.14.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15228a6800ce7bdf1b74800595e56db7138cecb338fdbf044806e10dcf182dfe", size = 253280 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/9e/1c0264514a3f98259a6d64765a397b2c8373e3ba59ee722a4802d3ec0c61/coverage-7.14.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9d26ac7f5398bafc5b57421ad994e8a4749e8a7a0e62d05ec7d53014d5963bfa", size = 251241 },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/16/4efdf3e3c4079cdbf0ece56a2fea872df9e8a3e15a13a0af4400e1075944/coverage-7.14.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2fb73254ff43c911c967a899e1359bc5049b4b115d6e8fbdde4937d0a2246cd5", size = 255516 },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/69/b1de96346603881b3d1bc8d6447c83200e1c9700ffbaff926ba01ff5724c/coverage-7.14.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:454a380af72c6adada298ed270d38c7a391288198dbfb8467f786f588751a90c", size = 251059 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/66/2881853e0363a5e0a724d1103e53650795367471b6afb234f8b49e713bc6/coverage-7.14.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:65c86fb646d2bd2972e96bd1a8b45817ed907cee68655d6295fe7ec031d04cca", size = 252716 },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/5c/0d3305d002c41dcde873dbe456491e663dc55152ca526b630b5c47efd62f/coverage-7.14.0-cp314-cp314-win32.whl", hash = "sha256:6a6516b02a6101398e19a3f44820f69bab2590697f7def4331f668b14adaf828", size = 222788 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/58/6e1b8f52fdc3184b47dc5037f5070d83a3d11042db1594b02d2a44d786c8/coverage-7.14.0-cp314-cp314-win_amd64.whl", hash = "sha256:45e0f79d8351fa76e256716df91eab12890d32678b9590df7ae1042e4bd4cf5d", size = 223600 },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/70/a18c408e674bc26281cadaedc7351f929bd2094e191e4b15271c30b084cc/coverage-7.14.0-cp314-cp314-win_arm64.whl", hash = "sha256:4b899594a8b2d81e5cc064a0d7f9cac2081fed91049456cae7676787e41549c9", size = 222168 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/89/2681f071d238b62aff8dfc2ab44fc24cfdb38d1c01f391a80522ff5d3a16/coverage-7.14.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f580f8c80acd94ac72e863efe2cab791d8c38d153e0b463b92dfa000d5c84cd1", size = 220766 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/c7/c987babafd9207ffa1995e1ef1f9b26762cf4963aa768a66b6f0501e4616/coverage-7.14.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a2bd259c442cd43c49b30fbafc51776eb19ea396faf159d26a83e6a0a5f13b0c", size = 221035 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/e9/d6a5ac3b333088143d6fc877d398a9a674dc03124a2f776e131f03864823/coverage-7.14.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a706b908dfa85538863504c624b237a3cc34232bf403c057414ebfdb3b4d9f84", size = 262405 },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/b1/e70838d29a7c08e22d44398a46db90815bbcbf28de06992bd9210d1a8d8e/coverage-7.14.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7333cd944ee4393b9b3d3c1b598c936d4fc8d70573a4c7dacfec5590dd50e436", size = 264530 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/73/5c31ef97763288d03d9995152b96d5475b527c63d91c84b01caea894b83a/coverage-7.14.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f162bc9a15b82d947b02651b0c7e1609d6f7a8735ca330cfadec8481dd97d5a", size = 266932 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/76/dd56d80f29c5f05b4d76f7e7c6d47cafacae017189c75c5759d24f9ff0cc/coverage-7.14.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:362cb78e01a5dc82009d88004cf60f2e6b6d6fcbfdec05b05af73b0abf40118f", size = 268062 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/c7/27ba85cd5b95614f159ff93ebff1901584a8d192e2e5e24c4943a7453f59/coverage-7.14.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:acebd068fca5512c3a6fde9c045f901613478781a73f0e82b307b214daef23fb", size = 261504 },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/2e/e8149f60ab5d5684c6eee881bdf34b127115cddbb958b196768dd9d63473/coverage-7.14.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:29fe3da551dface75deb2ccbf87b6b66e2e7ef38f6d89050b428be94afff3490", size = 264398 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/7f/1261b025285323225f4b4abffa5a643649dfd67e25ddca7ebcbdea3b7cb3/coverage-7.14.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b4cc4fce8672fffcb09b0eafc167b396b3ba53c4a7230f54b7aaffbf6c835fa9", size = 262000 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/dc/829c54f60b9d08389439c00f813c752781c496fc5788c78d8006db4b4f2b/coverage-7.14.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5d4a51aad8ba8bdcd2b8bd8f03d4aca19693fa2327a3470e4718a25b03481020", size = 265732 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/b0/70bd1419941652fa062689cba9c3eeafb8f5e6fbb890bce41c3bdda5dbd6/coverage-7.14.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:9f323af3e1e4f68b60b7b247e37b8515563a61375518fa59de1af48ba28a3db6", size = 260847 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/73/be40b2390656c654d35ea0015ea7ba3d945769cf80790ad5e0bb2d56d2ba/coverage-7.14.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1a0abc7342ea9711c469dd8b821c6c311e6bc6aac1442e5fbd6b27fae0a8f3db", size = 263166 },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/55/4a643f712fcf7cf2881f8ec1e0ccb7b164aff3108f69b51801246c8799f2/coverage-7.14.0-cp314-cp314t-win32.whl", hash = "sha256:a9f864ef57b7172e2db87a096642dd51e179e085ab6b2c371c29e885f65c8fb2", size = 223573 },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/96/3acae5da0953be042c0b4dea6d6789d2f080701c77b88e44d5bd41b9219b/coverage-7.14.0-cp314-cp314t-win_amd64.whl", hash = "sha256:29943e552fdc08e082eb51400fb2f58e118a83b5542bd06531214e084399b644", size = 224680 },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/3d/6ab5d2dd8325d838737c6f8d83d62eb6230e0d70b87b51b57bbfd08fa767/coverage-7.14.0-cp314-cp314t-win_arm64.whl", hash = "sha256:742a73ea621953b012f2c4c2219b512180dd84489acf5b1596b0aafc55b9100b", size = 222703 },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/e8/cb8e80d6f9f55b99588625062822bf946cf03ed06315df4bd8397f5632a1/coverage-7.14.0-py3-none-any.whl", hash = "sha256:8de5b61163aee3d05c8a2beab6f47913df7981dad1baf82c414d99158c286ab1", size = 211764 },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
toml = [
|
||||
{ name = "tomli", marker = "python_full_version <= '3.11'" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exceptiongroup"
|
||||
version = "1.3.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "librt"
|
||||
version = "0.11.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/40/08/9e7f6b5d2b5bed6ad055cdd5925f192bb403a51280f86b56554d9d0699a2/librt-0.11.0.tar.gz", hash = "sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1", size = 200139 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/83/10/37fd9e9ba96cb0bd742dfb20fc3d082e54bdbec759d7300df927f360ef07/librt-0.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f", size = 141706 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/72/1b1466f358e4a0b728051f69bc27e67b432c6eaa2e05b88db49d3785ae0d/librt-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45", size = 142605 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/85/ed26dd2f6bc9a0baf48306433e579e8d354d70b2bcb78134ed950a5d0e1e/librt-0.11.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c", size = 476555 },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/fe/11891191c0e0a3fd617724e891f6e67a71a7658974a892b9a9a97fdb2977/librt-0.11.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33", size = 468434 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/50/5ec949d7f9ce1a07af903aa3e13abb98b717923bdead6e719b2f824ccc07/librt-0.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884", size = 496918 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/c4/177336c7524e34875a38bf668e88b193a6723a4eb4045d07f74df6e1506c/librt-0.11.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280", size = 490334 },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/1f/da3112f7569eda3b49f9a2629bae1fe059812b6085df16c885f6454dff49/librt-0.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c", size = 511287 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/94/03fec301522e172d105581431223be56b27594ff46440ebfbb658a3735d5/librt-0.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb", size = 517202 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/6e/339f6e5a7b413ce014f1917a756dae630fe59cc99f34153205b1cb540901/librt-0.11.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783", size = 497517 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/43/acdd5ce317cb46e8253ca9bfbdb8b12e68a24d745949336a7f3d5fb79ba0/librt-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0", size = 538878 },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/b5/7a25bb12e3172839f647f196b3e988318b7bb1ca7501732a225c4dce2ec0/librt-0.11.0-cp310-cp310-win32.whl", hash = "sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89", size = 100070 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/0d/ebbcf4d77999c02c937b05d2b90ff4cd4dcc7e9a365ba132329ac1fe7a0f/librt-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4", size = 117918 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/87/2bf31fe17587b29e3f93ec31421e2b1e1c3e349b8bf6c7c313dbad1d5340/librt-0.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29", size = 141092 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/08/5c5bf772920b7ebac6e32bc91a643e0ab3870199c0b542356d3baa83970a/librt-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9", size = 142035 },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/20/662a03d254e5b000d838e8b345d83303ddb768c080fd488e40634c0fa66b/librt-0.11.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5", size = 475022 },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/f3/aa81523e45184c6ec23dc7f63263362ec55f80a09d424c012359ecbe7e35/librt-0.11.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b", size = 467273 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/6f/59c74b560ca8853834d5501d589c8a2519f4184f273a085ffd0f37a1cc47/librt-0.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89", size = 497083 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/7b/5aa4d2c9600a719401160bf7055417df0b2a47439b9d88286ce45e56b65f/librt-0.11.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc", size = 489139 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/31/9143803d7da6856a69153785768c4936864430eec0fd9461c3ea527d9922/librt-0.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5", size = 508442 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/5a/bce08184488426bda4ccc2c4964ac048c8f68ae89bd7120082eef4233cfd/librt-0.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7", size = 514230 },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/8c/bb5e213d254b7505a0e658da199d8ab719086632ce09eef311ab27976523/librt-0.11.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d", size = 494231 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/fb/541cdad5b1ab1300398c74c4c9a497b88e5074c21b1244c8f49731d3a284/librt-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412", size = 537585 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/f2/464bb69295c320cb06bddb4f14a4ec67934ee14b2bffb12b19fb7ab287ba/librt-0.11.0-cp311-cp311-win32.whl", hash = "sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d", size = 100509 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/e7/a17ee1788f9e4fbf548c19f4afa07c92089b9e24fef6cb2410863781ef4c/librt-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73", size = 118628 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/c7/6c766214f9f9903bcfcfbef97d807af8d8f5aa3502d247858ab17582d212/librt-0.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c", size = 103122 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/d0/07c77e067f0838949b43bd89232c29d72efebb9d2801a9750184eb706b71/librt-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46", size = 144147 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/24/8493538fa4f62f982686398a5b8f68008138a75086abdea19ade64bf4255/librt-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3", size = 143614 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/1e/f8bad050810d9171f34a1648ed910e56814c2ba61639f2bd53c6377ae24b/librt-0.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67", size = 485538 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/fe/3594ebfbaf03084ba4b120c9ba5c3183fd938a48725e9bbe6ff0a5159ad8/librt-0.11.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a", size = 479623 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/da/5d1876984b3746c85dbd219dbfcb73c85f54ee263fd32e5b2a632ec14571/librt-0.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a", size = 513082 },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/6e/55bdf5d5ca00c3e18430690bf2c953d8d3ffd3c337418173d33dec985dc9/librt-0.11.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f", size = 508105 },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/10/f1f23a7c595ee90ece4d35c851e5d104b1311a887ed1b4ac4c35bbd13da8/librt-0.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b", size = 522268 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/02/5720f5697a7f54b78b3aefbe20df3a48cedcff1276618c4aa481177942ed/librt-0.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766", size = 527348 },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/db/b4a47c6f91db4ff76348a0b3dd0cc65e090a078b765a810a62ff9434c3d3/librt-0.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d", size = 516294 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/58/9384b2f4eb1ed1d273d40948a7c5c4b2360213b402ef3be4641c06299f9c/librt-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8", size = 553608 },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/7b/5aa8848a7c6a9278c79375146da1812e695754ceec5f005e6043461a7315/librt-0.11.0-cp312-cp312-win32.whl", hash = "sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a", size = 101879 },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/33/8a745436944947575b584231750a41417de1a38cf6a2e9251d1065651c09/librt-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9", size = 119831 },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/67/a6739ac96e28b7855808bdb0370e250606104a859750d209e5a0716fe7ab/librt-0.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c", size = 103470 },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/61/e59168d4d0bf2bf90f4f0caf7a001bfc60254c3af4586013b04dc3ef517b/librt-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894", size = 144119 },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/fd/caa1d60b12f7dd79ccea23054e06eeaebe266a5f52c40a6b651069200ce5/librt-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c", size = 143565 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/a9/dc744f5c2b4978d48db970be29f22716d3413d28b14ad99740817315cf2c/librt-0.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea", size = 485395 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/21/7f8e97a1e4dae952a5a95948f6f8507a173bc1e669f54340bba6ca1ca31b/librt-0.11.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230", size = 479383 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/6d/d8ee9c114bebf2c50e29ec2aa940826fccb62a645c3e4c18760987d0e16d/librt-0.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2", size = 513010 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/43/0b5708af2bd30a46400e72ba6bdaa8f066f15fb9a688527e34220e8d6c06/librt-0.11.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3", size = 508433 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/50/356187247d09013490481033183b3532b58acf8028bcb34b2b56a375c9b2/librt-0.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21", size = 522595 },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/e7/c6ac4240899c7f3248079d5a9900debe0dadb3fdeaf856684c987105ba47/librt-0.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930", size = 527255 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/b5/a81322dbeedeeaf9c1ee6f001734d28a09d8383ac9e6779bc24bbd0743c6/librt-0.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be", size = 516847 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/66/6e6323787d592b55204a42595ff1102da5115601b53a7e9ddebc889a6da5/librt-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e", size = 553920 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/21/623f8ca230857102066d9ca8c6c1734995908c4d0d1bee7bb2ef0021cb33/librt-0.11.0-cp313-cp313-win32.whl", hash = "sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e", size = 101898 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/1d/b4ebd44dd723f768469007515cb92251e0ae286c94c140f374801140fa74/librt-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47", size = 119812 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/e4/b2f4ca7965ca373b491cdb4bc25cdb30c1649ca81a8782056a83850292a9/librt-0.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44", size = 103448 },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/eb/dbce197da4e227779e56b5735f2decc3eb36e55a1cdbf1bd65d6639d76c1/librt-0.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd", size = 143345 },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/a3/254bebd0c11c8ba684018efb8006ff22e466abce445215cca6c778e7d9de/librt-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4", size = 143131 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/3f/f77d6122d21ac7bf6ae8a7dfced1bd2a7ac545d3273ebdcaf8042f6d619f/librt-0.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8", size = 477024 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/0a/2c996dadebaa7d9bbbd43ef2d4f3e66b6da545f838a41694ef6172cebec8/librt-0.11.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b", size = 474221 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/7e/f5d92af8486b8272c23b3e686b46ff72d89c8169585eb61eef01a2ac7147/librt-0.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175", size = 505174 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/1a/cb0734fe86398eb33193ab753b7326255c74cac5eb09e76b9b16536e7adb/librt-0.11.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03", size = 497216 },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/06/094820f91558b66e29943c0ec41c9914f460f48dd51fc503c3101e10842d/librt-0.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c", size = 513921 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/c2/00de9018871a282f530cacb457d5ec0428f6ac7e6fedde9aff7468d9fb04/librt-0.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3", size = 520850 },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/9d/64631832348fd1834fb3a61b996434edddaaf25a31d03b0a76273159d2cf/librt-0.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96", size = 504237 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/ec/ae5525eb16edc827a044e7bb8777a455ff95d4bca9379e7e6bddd7383647/librt-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe", size = 546261 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/09/adce371f27ca039411da9659f7430fcc2ba6cd0c7b3e4467a0f091be7fa9/librt-0.11.0-cp314-cp314-win32.whl", hash = "sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f", size = 96965 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/ee/8ac720d98548f173c7ce2e632a7ca94673f74cacd5c8162a84af5b35958a/librt-0.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7", size = 115151 },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/20/c900cf14efeb09b6bef2b2dff20779f73464b97fd58d1c6bccc379588ae3/librt-0.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1", size = 98850 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/71/944bfe4b64e12abffcd3c15e1cce07f72f3d55655083786285f4dedeb532/librt-0.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72", size = 151138 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/10/99e64a5c86989357fda078c8143c533389585f6473b7439172dd8f3b3b2d/librt-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa", size = 151976 },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/31/5072ad880946d83e5ea4147d6d018c78eefce85b77819b19bdd0ee229435/librt-0.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548", size = 557927 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/8d/70b5fb7cfbab60edbe7381614ab985da58e144fbf465c86d44c95f43cdca/librt-0.11.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2", size = 539698 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/a3/ba3495a0b3edbd24a4cae0d1d3c64f39a9fc45d06e812101289b50c1a619/librt-0.11.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f", size = 577162 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/db/36e25fb81f99937ff1b96612a1dc9fd66f039cb9cc3aee12c01fac31aab9/librt-0.11.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51", size = 566494 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/0d/3f622b47f0b013eeb9cf4cc07ae9bfe378d832a4eec998b2b209fe84244d/librt-0.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2", size = 596858 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/02/71b90bc93039c46a2000651f6ad60122b114c8f54c4ad306e0e96f5b75ad/librt-0.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085", size = 590318 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/04/418cb3f75621e2b761fb1ab0f017f4d70a1a72a6e7c74ee4f7e8d198c2f3/librt-0.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3", size = 575115 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/2c/5a2183ac58dd911f26b5d7e7d7d8f1d87fcecdddd99d6c12169a258ff62c/librt-0.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd", size = 617918 },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/1f/dc6771a52592a4451be6effa200cbfc9cec61e4393d3033d81a9d307961d/librt-0.11.0-cp314-cp314t-win32.whl", hash = "sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8", size = 103562 },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/4a/7d1415567027286a75ba1093ec4aca11f073e0f559c530cf3e0a757ad55c/librt-0.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c", size = 124327 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/62/b40b382fa0c66fee1478073eb8db352a4a6beda4a1adccf1df911d8c289c/librt-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253", size = 102572 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "2.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "ast-serialize" },
|
||||
{ name = "librt", marker = "platform_python_implementation != 'PyPy'" },
|
||||
{ name = "mypy-extensions" },
|
||||
{ name = "pathspec" },
|
||||
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/82/15/cca9d88503549ed6fedeaa1d448cdddd542ee8a490232d732e278036fbf2/mypy-2.1.0.tar.gz", hash = "sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633", size = 3898359 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/71/d351dca3e9b30da2328ee9d445c88b8388072808ebfbc49eb69d30b67749/mypy-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc", size = 14778792 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/45/7d51594b644c17c0bcf74ed8cd5fc33b324276d708e8506f220b70dab9d9/mypy-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849", size = 13645739 },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/01/455c31b170e9468265074840bf18863a8482a24103fdaabe4e199392aa5f/mypy-2.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd", size = 14074199 },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/5a/93093f0b29a9e982deafde698f740a2eb2e05886e79ccf0594c7fd5413a3/mypy-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166", size = 14953128 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/2f/a196f5331d96170ad3d28f144d2aba690d4b2911381f68d51e489c7ab82a/mypy-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8", size = 15249378 },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/de/94d321cc12da9f71341ac0c270efbed5c725750c7b4c334d957de9a087d9/mypy-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8", size = 11060994 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/62/0c27ca55219a7c764a7fb88c7bb2b7b2f9780ade8bbf16bc8ed8400eef6b/mypy-2.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e", size = 9976743 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/a1/639f3024794a2a15899cb90707fe02e044c4412794c39c5769fd3df2e2ef/mypy-2.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41", size = 14691685 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/08/9a585dea4325f20d8b80dc78623fa50d1fd2173b710f6237afd6ba6ab39b/mypy-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca", size = 13555165 },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/dc/7c42cc9c6cb01e8eb09961f1f738741d3e9c7e9d5c5b30ec69222625cd5f/mypy-2.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538", size = 13994376 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/fa/285946c33bce716e082c11dfeee9ee196eaf1f5042efb3581a31f9f205e4/mypy-2.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398", size = 14864618 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/83/82397f48af6c27e295d57979ded8490c9829040152cf7571b2f026aeb9a0/mypy-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563", size = 15102063 },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/68/b02dec39057b88eb03dc0aa854732e26e8361f34f9d0e20c7614967d1eba/mypy-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389", size = 11060564 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/a8/ea3dcbef31f99b634f2ee23bb0321cbc8c1b388b76a861eb849f13c347dc/mypy-2.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666", size = 9966983 },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/b1/55861beb5c339b44f9a2ba92df9e2cb1eeb4ae1eee674cdf7772c797778b/mypy-2.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af", size = 14874381 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/b3/b7f770114b7d0ac92d0f76e8d93c2780844a70488a90e91821927850da86/mypy-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6", size = 13665501 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/f3/8ae2037967e2126689a0c11d99e2b707134a565191e92c60ca2572aec60a/mypy-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211", size = 14045750 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/32/615eb5911859e43d054941b0d0a7d06cfa2870eba86529cf385b052b111c/mypy-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b", size = 15061630 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/03/4eafbfff8bfab1b87082741eae6e6a624028c984e6708b73bce2a8570c9d/mypy-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22", size = 15288831 },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/ee/919661478e5891a3c96e549c036e467e64563ab85995b10c53c8358e16a3/mypy-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b", size = 11135228 },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/0a/6a12b9782ca0831a553192f351679f4548abc9d19a7cc93bb7feb02084c7/mypy-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8", size = 10040684 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/dd/c7191469c777f07689c032a8f7326e393ea34c92d6d76eb7ce5ba57ea66d/mypy-2.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5", size = 14852174 },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/8c/aed55408879043d72bb9135f4d0d19a02b886dd569631e113e3d2706cb8d/mypy-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e", size = 13651542 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/8e/f371a824b1f1fa8ea6e3dbb8703d232977d572be2329554a3bc4d960302f/mypy-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e", size = 14033929 },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/21/f54be870d6dd53a82c674407e0f8eed7174b05ec78d42e5abd7b42e84fd5/mypy-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285", size = 15039200 },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/99/bf21748626a40ce59fd29a39386ab46afec88b7bd2f0fa6c3a97c995523f/mypy-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5", size = 15272690 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/d7/9e90d2cf47100bea550ed2bc7b0d4de3a62181d84d5e37da0003e8462637/mypy-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65", size = 11147435 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/46/e5c449e858798e35ffc90946282a27c62a77be743fe17480e4977374eb91/mypy-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d", size = 10035052 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/ca/b279a672e874aedd5498ae25f722dacc8aa86bbffb939b3f97cbb1cf6686/mypy-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2", size = 14848422 },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/e6/3efe56c631d959b9b4454e208b0ac4b7f4f58b404c89f8bec7b49efdfc21/mypy-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f", size = 13677374 },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/7f/8107ea87a44fd1f1b59882442f033c9c3488c127201b1d1d15f1cbd6022e/mypy-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4", size = 14055743 },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/4d/b6d34db183133b83761b9199a82d31557cdbb70a380d8c3b3438e11882a3/mypy-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef", size = 15020937 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/d7/f08360c691d758acb02f45022c34d98b92892f4ea756644e1000d4b9f3d8/mypy-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135", size = 15253371 },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/1b/09460a13719530a19bce27bd3bc8449e83569dd2ba7faf51c9c3c30c0b61/mypy-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21", size = 11326429 },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/62/75dbf0f82f7b6680340efc614af29dd0b3c17b8a4f1cd09b8bd2fd6bc814/mypy-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57", size = 10218799 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/66/caca04ed7d972fb6eb6dd1ccd6df1de5c38fae8c5b3dc1c4e8e0d85ee6b9/mypy-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e", size = 15923458 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/52/2d90cbe49d014b13ed7ff337930c30bad35893fe38a1e4641e756bb62191/mypy-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780", size = 14757697 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/37/d98f4a14e081b238992d0ed96b6d39c7cc0148c9699eb71eaa68629665ea/mypy-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd", size = 15405638 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/c2/15c46613b24a84fad2aea1248bf9619b99c2767ae9071fe224c179a0b7d4/mypy-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08", size = 16215852 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/90/9c16a57f482c76d25f6379762b56bbf65c711d8158cf271fb2802cfb0640/mypy-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081", size = 16452695 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/4c/215a4eeb63cacc5f17f516691ea7285d11e249802b942476bff15922a314/mypy-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7", size = 12866622 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/50/1043e1db5f455ffe4c9ab22747cd8ca2bc492b1e4f4e21b130a44ee2b217/mypy-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6", size = 10610798 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/2a/13ca1f292f6db1b98ff495ef3467736b331621c5917cad984b7043e7348d/mypy-2.1.0-py3-none-any.whl", hash = "sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289", size = 2693302 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "1.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "2.2.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version < '3.11'",
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245 },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050 },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034 },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620 },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616 },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579 },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570 },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866 },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455 },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348 },
|
||||
{ url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618 },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506 },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828 },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765 },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736 },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719 },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213 },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467 },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217 },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935 },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122 },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143 },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260 },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225 },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391 },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476 },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "2.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.15' and sys_platform == 'win32'",
|
||||
"python_full_version >= '3.15' and sys_platform == 'emscripten'",
|
||||
"python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
"python_full_version == '3.14.*' and sys_platform == 'win32'",
|
||||
"python_full_version == '3.14.*' and sys_platform == 'emscripten'",
|
||||
"python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'win32'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'emscripten'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/49/ec46835a70be8fa6446c495126ac84fdb28cb2558e1620ffb87a10c8b64c/numpy-2.4.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4", size = 16969194 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/0d/f5957185c0ee2f3e12f78715aa9e3b353fd83633316c8532b38faa37e3f6/numpy-2.4.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d", size = 14964111 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/40/40a40ee0ddf7ceb782c49af278894b686e586d65d8c1889c8b5da01a3d7d/numpy-2.4.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8", size = 5469159 },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/13/f9a8046535cb21deae82f8d03de9617e08882d274fad2539630761888228/numpy-2.4.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538", size = 6798936 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/a8/6fa8c1a345a8c85dbb21932c447bee07c30a2c2a3f31e369c0a84b300147/numpy-2.4.6-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47", size = 15966692 },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/03/74fe2a4cb3817d94d86402f2506554130a2f01414e299b5a843e5a8a957f/numpy-2.4.6-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93", size = 16918164 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/80/3615be3313f7e7696609bc194b9f0101da809df79e859bdb84e0cd043f46/numpy-2.4.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8", size = 17322877 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/ac/a691e0fe2675e370d0e08ff905adc49a1c8830e8cae03efe4477e92cd55d/numpy-2.4.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6", size = 18651487 },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/a7/9bc1cd626d7bf6869bfedf27b91b6ab5dd607758bf8e959d6fa80c6a59cb/numpy-2.4.6-cp311-cp311-win32.whl", hash = "sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8", size = 6233945 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/31/7fc6239c12bce7e931463251cca4426c465e1876ba3cc785402ef4dd8f4e/numpy-2.4.6-cp311-cp311-win_amd64.whl", hash = "sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147", size = 12608406 },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/83/140f85a466595a16382996a1bf06b2b54bcd597488921b0c9daaeeda72af/numpy-2.4.6-cp311-cp311-win_arm64.whl", hash = "sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577", size = 10479528 },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/2a/3d7b5ac8aac24feaf9ad7ed58f45b0bbc06d37e4338ae84c9f2298b570f9/numpy-2.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", size = 16689119 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/12/92c4c131527599e8288d6918e888d88726f84d805d784b771f32408aeaef/numpy-2.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb", size = 14699246 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/fe/c0a6b7b2ca128a8fb228575147073b660656734b8ebe4d76c8fd748dcc79/numpy-2.4.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", size = 5204410 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/d4/9770d14ba719432bb90a421bfd443872ed0f70f7264b64bec12ea363d5fd/numpy-2.4.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", size = 6551240 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012 },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/81/e1b27545deedce7f4a0b348618c6b62d74e36a4dc9ccd42f3eb2f85eee32/numpy-2.4.6-cp312-cp312-win32.whl", hash = "sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45", size = 5962825 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751", size = 12321687 },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/82/bdab26d7438c6791ca31b7c024ca37c1eab8b726ba236129005cd4a06e45/numpy-2.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", size = 16684648 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/30/a80189bcc7f5e4258b3fbc3968d909d1756f54d023299ecc39ad6fdb9ef8/numpy-2.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", size = 14693902 },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/12/70b5d0d7c15e1ebb8a6a84a8caa1d19e181d84fb58bb6d70aca29099dec1/numpy-2.4.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", size = 5198992 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/8c/ebd2a8f8a83541f8d38cc5667e8c2b69cecfd30da6e45693e8158857d44b/numpy-2.4.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", size = 6546944 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220 },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/da/2ccc6c2fe8898dee01d90c75c5f5f914a23daf99e3e0f59516a08760c8b5/numpy-2.4.6-cp313-cp313-win32.whl", hash = "sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", size = 5961134 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/cd/9cc4dc876fb065d5c220aae4d5e14826b2715331bb7618ce1fb07a679d99/numpy-2.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", size = 12318598 },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/1e/c0bcba1f8694116485fe28fd1be698c278fcda4141c5b0e53a2aed8b12a8/numpy-2.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", size = 10222272 },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/6d/cc5619247c8f4204e507f5883528372e4ac4bb189e579fb859a12e480b1f/numpy-2.4.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", size = 14821197 },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/58/f1c39161c87d9e9bed660f1ed4bafc0e403d5ec9650b6dd77aead07d489b/numpy-2.4.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe", size = 5326287 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/57/3917ab0fd97f271a8694513581b8a36c655f111c446852c302f04ccdb6fc/numpy-2.4.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", size = 6646763 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070 },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752 },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/90/0ac3bc947217e66dec77e7cbc6a1979d1af70b6461b82f620d3bccd5e4c8/numpy-2.4.6-cp313-cp313t-win32.whl", hash = "sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", size = 6084971 },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/71/5673e351671a1d2bd6063b91b44f70c0affea7d1516fa7a6572941ba4aa1/numpy-2.4.6-cp313-cp313t-win_amd64.whl", hash = "sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", size = 12458532 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/88/19d3503c5046e688f049274b27a3ef3d771152fa80d3ba3d01a3dff61abe/numpy-2.4.6-cp313-cp313t-win_arm64.whl", hash = "sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", size = 10291881 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559 },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716 },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226 },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196 },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334 },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678 },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672 },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805 },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496 },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616 },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908 },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867 },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/12/b422cc84439adc0d00de605bf4a308890ae5c26f2c71fbd73e5d08fbb0dd/numpy-2.4.6-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662", size = 16847511 },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/53/f481bef68011740f8849418d82db07230e825013f31f4eef5ba5b805316a/numpy-2.4.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7", size = 14889064 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/57/42ed575c10ced8af951d426bc4e1f8aff16fd851db33f067036215a7f860/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f", size = 5394157 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/ef/f66cc724fcc36c1e364c67f51ae9146090b8b584f27d58b97fdae3edd737/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c", size = 6708728 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/9c/c531f2293b91265d8b48e9b329f54fdd7ffae73cb4134ea10cca4237e9cc/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0", size = 15798374 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/b0/413077f6b1153ed3cba361401c6783bbad6114804a000cc22eb71c13e190/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02", size = 16747286 },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/ce/e5ec180bc41812edcd8daeb8639d205622c0e8c02259d8ab25a0201b3c2a/numpy-2.4.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73", size = 12504263 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "26.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pandas"
|
||||
version = "2.3.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version < '3.11'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
||||
{ name = "python-dateutil", marker = "python_full_version < '3.11'" },
|
||||
{ name = "pytz", marker = "python_full_version < '3.11'" },
|
||||
{ name = "tzdata", marker = "python_full_version < '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/f7/f425a00df4fcc22b292c6895c6831c0c8ae1d9fac1e024d16f98a9ce8749/pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c", size = 11555763 },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/4f/66d99628ff8ce7857aca52fed8f0066ce209f96be2fede6cef9f84e8d04f/pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a", size = 10801217 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/03/3fc4a529a7710f890a239cc496fc6d50ad4a0995657dccc1d64695adb9f4/pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1", size = 12148791 },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/a8/4dac1f8f8235e5d25b9955d02ff6f29396191d4e665d71122c3722ca83c5/pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838", size = 12769373 },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/91/82cc5169b6b25440a7fc0ef3a694582418d875c8e3ebf796a6d6470aa578/pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250", size = 13200444 },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/ae/89b3283800ab58f7af2952704078555fa60c807fff764395bb57ea0b0dbd/pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4", size = 13858459 },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/72/530900610650f54a35a19476eca5104f38555afccda1aa11a92ee14cb21d/pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826", size = 11346086 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453 },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002 },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971 },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671 },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807 },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872 },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056 },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189 },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912 },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635 },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049 },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071 },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582 },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963 },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pandas"
|
||||
version = "3.0.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.15' and sys_platform == 'win32'",
|
||||
"python_full_version >= '3.15' and sys_platform == 'emscripten'",
|
||||
"python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
"python_full_version == '3.14.*' and sys_platform == 'win32'",
|
||||
"python_full_version == '3.14.*' and sys_platform == 'emscripten'",
|
||||
"python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'win32'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'emscripten'",
|
||||
"python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
{ name = "python-dateutil", marker = "python_full_version >= '3.11'" },
|
||||
{ name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f8/87/4341c6252d1c47b08768c3d25ac487362bf403f0313ddae4a2a26c9b1b4c/pandas-3.0.3.tar.gz", hash = "sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc", size = 4651414 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/42/16/b5c76b838fd9bf6ce84d3a53346b8874ec05c5f0040d75ef2c320100cd2a/pandas-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:455f6f8139d4282188f526868dbc3c828470e88a3d9d59a891bd46a455f21b98", size = 10338495 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/b0/a4ffc4ae74d2d822200dcc46898987d8eb6032d1e2b219cae39da6f5cbcc/pandas-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4e15135e2ee5df1063313e2425ceef8ac0f4ae775893815b0923651b806a5639", size = 9938250 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/b2/3323601a52caee42c019e370090ca4544b241437240ca04f786cce82b0cf/pandas-3.0.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:05f1f1752b8533ea03f7f39a9c15b1a058d067bb48f4748948e7a8691e0510f2", size = 10770558 },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/f1/bbecd2f867b97abebe0f9b53d750f862251b40337e061b36676ded3d920f/pandas-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a1e45c80cceb3b4a21bc5939d52e8cbd8d9b7305309219d59e9754d9ce09e27", size = 11274611 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/4f/eafabf2d5fae5adf143b4d18d3706c5efdc368a7c4eb1ee8a3eddabbd0f6/pandas-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:14da8316da4d0c5a77618425996bfb1248ca87fc2c1486e6fde4652bd18b5824", size = 11784670 },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/44/1eb20389301b57b19cc099a1c2f662501f72f08a65f912d05822613c1532/pandas-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a55066a0505dae0ba2b50a46637db34b46f9094c65c5d4800794ef6335010938", size = 12353708 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/62/c321f13b5ba1819fc8dca456c7fce578da2dcfecff1abbf0eaddf8406c0f/pandas-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6674ab18ad8c57802867264b00e15e7bb904700cdd9046e3b2fa1fce237439ea", size = 9907609 },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/85/1b7f563ebc6357c27233a02a96b589bcce1fa9c6eb89fb4f0e56421d277e/pandas-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:5cc09a68b3120e0f54870dede8287a7bb1fa463907e4fcec1ea77cab6179bf7a", size = 9165596 },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/f1/392f8c5bfc16f66a0d2d41561c01627c228fe7ed2a0d056ef11315042570/pandas-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fed2ff7fd9779120e388e285fc029bd5cf9490cdd2e4166a9ee22c0e49a9ab09", size = 10357846 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/3d/b16412745651e855f357e5e66930248688378853a6e2698a214e331fba1f/pandas-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b168fc218fd80a6cbdbdbc1a97ddc7889ed057d7eb45f50d866ceab5f39904c4", size = 9899550 },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/a8/fa2535168fffcedf67f4f6de28d2dd903a747ca7c8ea6989451aaeb3a92f/pandas-3.0.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0383c72c75cdcca61a9e116e611143902dbfd08bff356829c2f6d1cf40a9ca8c", size = 10412965 },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/b6/09b01cdbc15224e2850365192d17b7bdebb8bdbd8780ed221fcdf0d9a515/pandas-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6dc0b3fd2169c9157deed50b4d519553a3655c8c6a96027136d654592be973a9", size = 10894600 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/a4/2eb28f2fccb4ced4a2c79ab2a5dee9ade1ebf44922ebad6fea158c9f95d4/pandas-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e65d5407dc0b394f509699650e4a2ec01c0514f21850f453fa60f3be79a5dbf", size = 11422824 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/45/830bb57f533a4604b355e07edcb8ea18cf88b5f94e5fca92f27052d7c597/pandas-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8894dc474d648fe7b6ff0ca9b0bd73950d19952bc1a6534540762c5d79d305c", size = 11950889 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/c5/fc1b368f303087d20e8c9bf3d6ceb186263cfac0ade735cd938538bea839/pandas-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:c7be265b62cef88e253a941e4698604973736dcfe242fdb5198f0f7bc473cdcc", size = 9755463 },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/bd/fda8f9705b1b09c6ebe14bfc0fa0e4ec8584d54ea673628f157ff55131af/pandas-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:557409bc4178e70ee8d9ddb494798e51ebf6ea59330f6be22c51bab2a7db6c49", size = 9066158 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/90/62d8302883c44308c477e222c3daf7c813a34c8e96985882fbd53d964352/pandas-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:67b3b64c11910cfa29f4e94a14d3bff9ee693b6fc76055e7cad549cee0aec5fa", size = 10331071 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/ae/6a6493c783a101f165e4356953ba3c74d6f77f0042fa7d753da9dfbb640c/pandas-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39436b377d56d2a2e52d0395bdbee171f01068e99af5250509aceeb929f765c7", size = 9875690 },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/7c/5df8e9f56c69a2769fbe9382a5ef8f2658c007e376434e1e2cbb57ad895f/pandas-3.0.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4be06d68f9ddcfc645b87534911da79a8fbffc7573c80e0edcf42a5020624d8", size = 10381634 },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/68/1237369725aa617bb358263d535803e3053fdbc593513ec5ed9c9896b5b6/pandas-3.0.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4eeb6830daf35a71cc09649bd823e2b542dac246cdee9614c6e4bd65028cd6a", size = 10891243 },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/93/77d108e8af7222b4a503ebde0e30215b1c2e4f8e53a526431890f22d5586/pandas-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1928e07221f82db493cd4af1e23c1bfca524a19a4699887975bff68f49a72bfb", size = 11388659 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/bd/eff5b4399f332ac386c853f6cd2bd3fa2ca0061b9f36ecd9c4d7c4265649/pandas-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51b1fe551acb77dac643c6fda86084d8d446c10fe64b06a9cc29c4cc8540e7f2", size = 11942880 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/20/559ace4200982c3887d0b86bfd0d856a2143ef8ddab63cc07934951a964c/pandas-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:a82d532a3351d435432cd913edbccaf8b8e01d4dd0e5ced5a8d2e8ecd94c7e44", size = 9757091 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/66/69055a09fe200f29f922a3eeec4804611900b95f52d932ece3393c3c0c19/pandas-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:275c14e0fce14a2ec20eee474aecd305478ea3c1e6f6a9d8fe219a165542717e", size = 9057282 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/0e/efe801b0e6811e8e650cd21b7f2608e30f08a7067e2bf6e8752b0d56ee3c/pandas-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:46997386d528eb40376ecd6b033cf4a8a1e5282580f68f43de875b78cba2199d", size = 10767016 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/dc/eb55135a1d5f0f0519f28da1f609a206d2cad1f9c35c32d51e38dd7261ae/pandas-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:261e308dfb22448384b7580cf719d2f998fe2966c92893c3e77d14008af1f066", size = 10420210 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/3e/b1d5d955ce33ffecb407465a60bc32769d74fcf68224b7ae67ae11d4dea4/pandas-3.0.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd1a5d1def6a46002e964510bdc67c368aa0951df5d1d9f8365336f5a1f490cd", size = 10336126 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/76/a01261711ab60a22d71b862f0de20e4c504bf80457270ad8cb42110f6abc/pandas-3.0.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d72828c20c6d6e83e1e22a6a3b47b326b71664112fa9705dcbccfd7a39b62085", size = 10728051 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/21/ea191195e587b18cf682e97f433f81b2d0fbe341380e80a3e0d6e4403c8e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d26cbe1fcfc12e8fd900e2454163e466b2d3af84f7c75481df7683ffc073d870", size = 11350796 },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/69/f0eaaf54939f0e8c6768fd06be9af2cef9b36048b96dfb9e1b2c685a807e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e91cec1879ada0624fc3dc9953c5cbd60208e59c0db28f540c5d6d47502422f", size = 11799741 },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/a4/865e0e510cae5fc2194de4db28be638952de942571ba9125934fd9c01d47/pandas-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:08d789b41f87e0905880e293cedf6197ce71fe67cc081358b1e148a491b9bd13", size = 10499958 },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/54/effdcc3c0ff7a08037889200e148ebe94c16c4f653be078c7b3675955df1/pandas-3.0.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3650109c0f22879df8bd6179ab9ee3d7f1d1d4e7e0094a3f0032d9f51e2e64ac", size = 10336065 },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/10/bf2d6738d72748b961a3751ab89522d58c54efc36a8e1a12161216cd45cf/pandas-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bab900348131a7db1f69a7309ef141fd5680f1487094193bcbbb61791573bf8f", size = 9926101 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/e9/e35cf11c8a136e757b956f5f0efdcaa50aecde85ea055f1898dfc68262f3/pandas-3.0.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba7e08b9ac1d54569cd1e256e3668975ed624d6826f7b68df0342b012007bddb", size = 10457553 },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/3b/1cdec6772bdbaf7b25dab360c59f03cadf05492dd724c6540af905389b07/pandas-3.0.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d71c63ae4ebdbf70209742096f1fc46a83a0613c99d4b23766cced9ff8cd62a", size = 10914065 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/c2/1ef644445fcd72e3627bceec77e3560636f87ddce4ed841afe76b83b5bf9/pandas-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3a2ec42c98ffa2565a67e08e218d06d72576d758d90facb7c00805194d8f360", size = 11459188 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/49/4d8d4f42cbc9c4adc7a1870f269c02cbd6cd40d059622c06fb298addcbad/pandas-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:335f62418ed562cfc3c49e9e196375c28b729dcef8543abf4f9438e381bf3c76", size = 11982966 },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/55/792619469bab9882d8bbd5865d45a72f6478762d04a9af4bf0d08c503e95/pandas-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:3c20a521bbb85902f79f7270c80a59e1b5452d96d170c034f207181870f97ac5", size = 9876755 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/af/33c469653b0ba03b50c3a98192d4c07f0c75c66b263ceb097fce0ee97d31/pandas-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:a2d2dff8a04f3917b55ab3910c32990f8ddf7eceba114947838cefa976a68977", size = 9198658 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/fa/b8c257bd76b8bd060c3a9151c1fca05e9b9c5e3af5d0f549c0356f6d143d/pandas-3.0.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:0d589105b3c14645af1738ff279b2995102d8f7a03b0a66dc8d95550eb513e04", size = 10787242 },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/eb/f19206ffb0bf1919002969aa448b4702c6594845156a6f8050674855aac3/pandas-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:13fc1e853d9e04743d11ba75a985ccbc2a317fe07d8af61e445a6fd24dacd6a6", size = 10436369 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/24/c7c39fb4fe22b71a0c2d78bf0c585c600092d85f94f086d2b3b2f6ca27e2/pandas-3.0.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:819959dab7bbd0049c15623fbac4e29a191b9528160a61fb1032242d8ced2d9c", size = 10358306 },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/ec/dd2a9eb7fa1204df88c0864164e35b228ac581062ac612ba0a67fd812e4c/pandas-3.0.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:60ae316d3fd75d1858d450d0db0103ea2be3e7d4a95ec2f064f7e2ae63f7b028", size = 10758394 },
|
||||
{ url = "https://files.pythonhosted.org/packages/95/6e/00c61ea8e85b4f6d8d35e11852a1a4998fc7fafc91c6a602d1cc9c972d64/pandas-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd3a518890b400d32f9023722dc9a9a5c969f00b415419a3c06c043f09bb5d7d", size = 11375717 },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/89/8fc1c268969fac43688d65fd92e67df24bd128d53cb4d2eee534cd307399/pandas-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c39be2d709d01fa972a0cabc522389fceca4f3969332ba25a7d6c5802cf976a", size = 11828897 },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/3b/e7d20dea247a3e6dc0bd8a6953854afbedc03951def4e7371e05e7263e25/pandas-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4db8c527972a821cf5286b40ccc57642a39bc62e62022b42f99f8a67fca8c3a1", size = 10900855 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "1.1.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", size = 135180 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.6.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.20.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "9.0.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
|
||||
{ name = "iniconfig" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pluggy" },
|
||||
{ name = "pygments" },
|
||||
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-cov"
|
||||
version = "7.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "coverage", extra = ["toml"] },
|
||||
{ name = "pluggy" },
|
||||
{ name = "pytest" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.9.0.post0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "six" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2026.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a", size = 320861 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.15.13"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/24/21/a7d5c126d5b557715ef81098f3db2fe20f622a039ff2e626af28d674ab80/ruff-0.15.13.tar.gz", hash = "sha256:f9d89f17f7ba7fb2ed42921f0df75da797a9a5d71bc39049e2c687cf2baf44b7", size = 4678180 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/61/11d458dc6ac22504fd8e237b29dfd40504c7fbbcc8930402cfe51a8e63ed/ruff-0.15.13-py3-none-linux_armv6l.whl", hash = "sha256:444b580fc72fd6887e650acd3e575e18cdc79dbcf42fb4030b491057921f61f8", size = 10738279 },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/ca/caa871ee7be718c45256fada4e16a218ee3e33f0c4a46b729a60a24912e6/ruff-0.15.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6590d009e7cb7ebf36f83dbdd44a3fa48a0994ff6f1cdc1b08006abe58f98dc7", size = 11124798 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/19/43f5f2e568dddde567fc41f8471f9432c09563e19d3e617a48cfa52f8f0a/ruff-0.15.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1c26d2f66163deeb6e08d8b39fbbe983ce3c71cea06a6d7591cfd1421793c629", size = 10460761 },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/df/cf938cd6de3003178f03ad7c1ea2a6c099468c03a35037985070b37e76be/ruff-0.15.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dbd6f94b434f896308e4d57fb7bfde0d02b99f7a64b3bdab0fdfa6a864203a5", size = 10804451 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/7d/5d0973129b154ded2225729169d7068f26b467760b146493fde138415f23/ruff-0.15.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf3259f3be4d181bda591da5db2571aed6853c6a048157756448020bc6c5cd22", size = 10534285 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/e3/6b999bbc66cd51e5f073842bc2a3995e99c5e0e72e16b15e7261f7abf57a/ruff-0.15.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae9c17e5eb4430c154e76abc25d79a318190f5a997f38fb6b114416c5319ffc9", size = 11312063 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/5a/642639e9f5db04f1e97fbd6e091c6fd20725bdf072fb114d00eefb9e6eb8/ruff-0.15.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e2e39bff6c341f4b577a21b801326fab0b11847f48fcaa83f00a113c9b3cb55", size = 12183079 },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/4c/7585735f6b53b0f12de13618b2f7d250a844f018822efc899df2e7b8295f/ruff-0.15.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e8d9a8e08013542e94d3220bc5b62cc3e5ef87c5f74bff367d3fac14fab013e6", size = 11440833 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/31/bf1a0803d077e679cfeee5f2f67290a0fa79c7385b5d9a8c17b9db2c48f0/ruff-0.15.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc411dfebe5eebe55ce041c6ae080eb7668955e866daa2fbb16692a784f1c4ca", size = 11434486 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/4e/62c9b999875d4f14db80f277c030578f5e249c9852d65b7ac7ad0b43c041/ruff-0.15.13-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:768494eb08b9cee54e2fd27969966f74db5a57f6eaa7a90fcb3306af34dfc4bd", size = 11385189 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/89/7e959047a104df3eb12863447c110140191fc5b6c4f379ea2e803fcdb0e4/ruff-0.15.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fb75f9a3a7e42ffe117d734494e6c5e5cb3565d66e12612cb63d0e572a41a5b6", size = 10781380 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/52/5fd18f3b88cab63e88aa11516b3b4e1e5f720e5c330f8dbe5c26210f41f8/ruff-0.15.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8cb74dd33bb2f6613faf7fc03b660053b5ac4f80e706d5788c6335e2a8048d51", size = 10540605 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/e0/9e35f338990d3e41a82875ff7053ffe97541dae81c9d02143177f381d572/ruff-0.15.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:7ef823f817fcd191dc934e984be9cf4094f808effa16f2542ad8e821ba02bbf2", size = 11036554 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/13/070fb048c24080fba188f66371e2a92785be257ad02242066dc7255ac6e9/ruff-0.15.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f345a13937bd7f09f6f5d19fa0721b0c103e00e7f62bc67089a8e5e037719e0b", size = 11528133 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/8c/b1e1666aef7fc6555094d73ae6cd981701781ae85b97ceefc0eebd0b4668/ruff-0.15.13-py3-none-win32.whl", hash = "sha256:4044f94208b3b05ba0fc4a4abd0558cf4d6459bd18325eead7fd8cc66f909b41", size = 10721455 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/a6/870a3e8a50590bb92be184ad928c2922f088b00d9dc5c5ec7b924ee08c22/ruff-0.15.13-py3-none-win_amd64.whl", hash = "sha256:7064884d442b7d477b4e7473d12da7f08851d2b1982763c5d3f388a19468a1a4", size = 11900409 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/36/9c015cd052fca743dae8cb2aeb16b551444787467db42ceab0fc968865af/ruff-0.15.13-py3-none-win_arm64.whl", hash = "sha256:2471da9bd1068c8c064b5fd9c0c4b6dddffd6369cb1cd68b29993b1709ff1b21", size = 11179336 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.17.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.4.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454 },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561 },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824 },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859 },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204 },
|
||||
{ url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924 },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948 },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159 },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141 },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847 },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088 },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866 },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704 },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674 },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755 },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726 },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713 },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084 },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973 },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973 },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490 },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263 },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736 },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461 },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855 },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683 },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.15.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tzdata"
|
||||
version = "2026.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xmtdx"
|
||||
version = "0.1.1"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "tzdata" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
dev = [
|
||||
{ name = "mypy" },
|
||||
{ name = "pytest" },
|
||||
{ name = "pytest-cov" },
|
||||
{ name = "ruff" },
|
||||
]
|
||||
pandas = [
|
||||
{ name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
||||
{ name = "pandas", version = "3.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "mypy", marker = "extra == 'dev'", specifier = ">=1.9" },
|
||||
{ name = "pandas", marker = "extra == 'pandas'", specifier = ">=2.0" },
|
||||
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" },
|
||||
{ name = "pytest-cov", marker = "extra == 'dev'" },
|
||||
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.4" },
|
||||
{ name = "tzdata", specifier = ">=2024.1" },
|
||||
]
|
||||
provides-extras = ["dev", "pandas"]
|
||||
Reference in New Issue
Block a user