leek-box-cli 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +88 -88
  2. package/dist/cli.mjs +3 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,166 +1,166 @@
1
1
  <p align="right">
2
- <strong>English</strong> | <a href="README-zh.md">中文</a>
2
+ <strong>中文</strong> | <a href="README-en.md">English</a>
3
3
  </p>
4
4
 
5
5
  # leek-box-cli(韭菜盒子)
6
6
 
7
- > An interactive terminal stock watchlist dashboard built with [Ink](https://github.com/vadimdemedes/ink).
7
+ > 基于 [Ink](https://github.com/vadimdemedes/ink) 的交互式终端自选股票看板.
8
8
 
9
- ## Screenshots
9
+ ## 截图
10
10
 
11
- ### Stock Watchlist
11
+ ### 自选股票看板
12
12
 
13
13
  <p align="center">
14
- <img src="scrennshots/stock-list.png" alt="Stock watchlist dashboard" width="100%">
14
+ <img src="scrennshots/stock-list.png" alt="自选股票看板" width="100%">
15
15
  </p>
16
16
 
17
- ### Menu & Settings
17
+ ### 菜单与设置
18
18
 
19
19
  <table>
20
20
  <tr>
21
- <td align="center" width="50%"><strong>Menu</strong></td>
22
- <td align="center" width="50%"><strong>Settings</strong></td>
21
+ <td align="center" width="50%"><strong>菜单</strong></td>
22
+ <td align="center" width="50%"><strong>设置</strong></td>
23
23
  </tr>
24
24
  <tr>
25
- <td><img src="scrennshots/dialog-menu.png" alt="Menu dialog"></td>
26
- <td><img src="scrennshots/settings.png" alt="Settings screen"></td>
25
+ <td><img src="scrennshots/dialog-menu.png" alt="菜单对话框"></td>
26
+ <td><img src="scrennshots/settings.png" alt="设置界面"></td>
27
27
  </tr>
28
28
  </table>
29
29
 
30
- ### Manage Watchlist
30
+ ### 自选股管理
31
31
 
32
32
  <table>
33
33
  <tr>
34
- <td align="center" width="50%"><strong>Add Stock</strong></td>
35
- <td align="center" width="50%"><strong>Remove Stock</strong></td>
34
+ <td align="center" width="50%"><strong>添加自选股</strong></td>
35
+ <td align="center" width="50%"><strong>删除自选股</strong></td>
36
36
  </tr>
37
37
  <tr>
38
- <td><img src="scrennshots/stock-add.png" alt="Add a stock to the watchlist"></td>
39
- <td><img src="scrennshots/stock-remove.png" alt="Remove a stock from the watchlist"></td>
38
+ <td><img src="scrennshots/stock-add.png" alt="添加自选股界面"></td>
39
+ <td><img src="scrennshots/stock-remove.png" alt="删除自选股界面"></td>
40
40
  </tr>
41
41
  </table>
42
42
 
43
- ### Stock Details
43
+ ### 股票详情
44
44
 
45
45
  <table>
46
46
  <tr>
47
- <td align="center" width="50%"><strong>Intraday</strong></td>
48
- <td align="center" width="50%"><strong>Five-day</strong></td>
47
+ <td align="center" width="50%"><strong>分时</strong></td>
48
+ <td align="center" width="50%"><strong>五日</strong></td>
49
49
  </tr>
50
50
  <tr>
51
- <td><img src="scrennshots/dialog-stock-detail-intraday.png" alt="Intraday stock chart"></td>
52
- <td><img src="scrennshots/dialog-stock-detail-five-day.png" alt="Five-day stock chart"></td>
51
+ <td><img src="scrennshots/dialog-stock-detail-intraday.png" alt="分时走势图"></td>
52
+ <td><img src="scrennshots/dialog-stock-detail-five-day.png" alt="五日走势图"></td>
53
53
  </tr>
54
54
  <tr>
55
- <td align="center" width="50%"><strong>Daily</strong></td>
56
- <td align="center" width="50%"><strong>Weekly</strong></td>
55
+ <td align="center" width="50%"><strong>日 K</strong></td>
56
+ <td align="center" width="50%"><strong>周 K</strong></td>
57
57
  </tr>
58
58
  <tr>
59
- <td><img src="scrennshots/dialog-stock-detail-day.png" alt="Daily stock chart"></td>
60
- <td><img src="scrennshots/dialog-stock-detail-week.png" alt="Weekly stock chart"></td>
59
+ <td><img src="scrennshots/dialog-stock-detail-day.png" alt=" K 走势图"></td>
60
+ <td><img src="scrennshots/dialog-stock-detail-week.png" alt=" K 走势图"></td>
61
61
  </tr>
62
62
  <tr>
63
- <td align="center" width="50%"><strong>Monthly</strong></td>
64
- <td align="center" width="50%"><strong>Yearly</strong></td>
63
+ <td align="center" width="50%"><strong>月 K</strong></td>
64
+ <td align="center" width="50%"><strong>年 K</strong></td>
65
65
  </tr>
66
66
  <tr>
67
- <td><img src="scrennshots/dialog-stock-detail-month.png" alt="Monthly stock chart"></td>
68
- <td><img src="scrennshots/dialog-stock-detail-year.png" alt="Yearly stock chart"></td>
67
+ <td><img src="scrennshots/dialog-stock-detail-month.png" alt=" K 走势图"></td>
68
+ <td><img src="scrennshots/dialog-stock-detail-year.png" alt=" K 走势图"></td>
69
69
  </tr>
70
70
  </table>
71
71
 
72
- ## Features
72
+ ## 功能
73
73
 
74
- - **Real-time dashboard**: Displays the latest price, percentage change, price change, open, high, low, volume, turnover, turnover rate, and total market capitalization for every stock in your watchlist. Refreshes every 5 seconds by default.
75
- - **Row selection and details**: Use `↑`/`↓` to select a stock and `enter` to open its quote details and trend chart. Press `1`-`6` to switch between intraday, five-day, daily, weekly, monthly, and yearly views.
76
- - **Multiple time frames**: Intraday and five-day minute charts refresh every 30 seconds. Daily, weekly, monthly, and yearly charts refresh every 5 minutes.
77
- - **Refresh controls**: Press `r` to refresh immediately. Configure the automatic refresh interval in Settings in 500 ms increments, from 1 to 60 seconds.
78
- - **Watchlist management**: Add or remove Shanghai, Shenzhen, and Beijing A-shares and ETFs. Stock codes can be entered as `600000`, `sh600000`, `600000.SH`, and other common formats.
79
- - **Resilient display**: Suspended stocks, incomplete quotes, and refresh failures each have a dedicated state. The display recovers automatically after a later poll succeeds.
74
+ - **实时看板**: 启动即展示自选股的现价, 涨跌幅, 涨跌额, 今开, 最高, 最低, 成交量, 成交额, 换手率和总市值; 默认每 5 秒刷新.
75
+ - **行选择与详情**: `↑`/`↓` 选择股票, `enter` 打开基础行情和趋势图; 数字键 `1`-`6` 切换分时, 五日, K, K, K 和年 K.
76
+ - **多周期行情**: 分时与五日分钟走势每 30 秒刷新; K, 周 K, K 和年 K 5 分钟刷新.
77
+ - **刷新控制**: `r` 立即刷新; 在设置页以 500 ms 步进调整自动刷新间隔, 范围为 1-60 秒.
78
+ - **自选股管理**: 支持添加, 删除沪深北 A 股与 ETF; 股票代码可写为 `600000`, `sh600000`, `600000.SH` 等形式.
79
+ - **容错展示**: 停牌, 部分行情缺失和刷新失败均有独立状态; 后续轮询成功后自动恢复.
80
80
 
81
- ## Controls
81
+ ## 交互方式
82
82
 
83
- - `esc`: Open the menu. If stock details are open, close them first; if the menu is open, close it.
84
- - In the menu, use `↑`/`↓`, `enter`, or a number key to select a page.
85
- - In the dashboard, use `↑`/`↓`, `enter`, and `r`.
86
- - In Settings, use `↑`/`↓` to select an item and `←`/`→` or `enter` to adjust it.
87
- - In stock details, press `1`-`6` to switch between `Intraday`, `Five-day`, `Daily`, `Weekly`, `Monthly`, and `Yearly`.
88
- - `q`: Exit when no menu or stock details overlay is open. It does nothing while an overlay is open to prevent accidental exits.
89
- - The right side of the status bar displays `YYYY-MM-DD HH:MM:SS` in the Asia/Shanghai time zone.
83
+ - `esc`: 打开菜单; 详情已打开时优先关闭详情, 菜单已打开时关闭菜单.
84
+ - 菜单内使用 `↑`/`↓`, `enter` 或数字键选择页面.
85
+ - 看板内使用 `↑`/`↓`, `enter`, `r`.
86
+ - 设置页使用 `↑`/`↓` 选择配置, 使用 `←`/`→` `enter` 调整.
87
+ - 股票详情内使用 `1`-`6` 切换 `分时`, `五日`, `日 K`, `周 K`, `月 K`, `年 K`.
88
+ - `q`: 没有菜单或详情浮层时退出; 浮层打开时不退出, 避免误触.
89
+ - 状态栏右侧显示 Asia/Shanghai 时区的 `YYYY-MM-DD HH:MM:SS`.
90
90
 
91
- ## Requirements
91
+ ## 环境要求
92
92
 
93
- - [Node.js](https://nodejs.org/) >= 22.19.0 (or >= 24)
93
+ - [Node.js](https://nodejs.org/) >= 22.19.0 ( >= 24)
94
94
  - [pnpm](https://pnpm.io/) >= 11.0.0
95
95
 
96
- Market data is retrieved with the native Node.js `fetch` API, with no external runtime dependency such as curl.
96
+ 行情通过 Node.js 原生 `fetch` 获取, curl 等外部运行工具依赖.
97
97
 
98
- ## Market Data Sources
98
+ ## 行情数据源
99
99
 
100
- - Real-time quotes: Tencent quote API at `https://qt.gtimg.cn/q=...`; GBK-encoded and requires no authentication.
101
- - Intraday data: Tencent minute API at `https://web.ifzq.gtimg.cn/appstock/app/minute/query?code=...`.
102
- - Five-day data: Tencent multi-day minute API at `https://web.ifzq.gtimg.cn/appstock/app/day/query?code=...`.
103
- - Daily, weekly, and monthly data: Tencent forward-adjusted K-line API at `https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param=...`.
104
- - Yearly data: Aggregated locally by year from backward-adjusted monthly data returned by the same API.
105
- - Data timeliness and availability depend on the upstream APIs. This project is intended for personal display purposes only.
100
+ - 实时行情: 腾讯行情接口 `https://qt.gtimg.cn/q=...`, GBK 编码, 无需鉴权.
101
+ - 当日分时: 腾讯分时接口 `https://web.ifzq.gtimg.cn/appstock/app/minute/query?code=...`.
102
+ - 五日分时: 腾讯多日分时接口 `https://web.ifzq.gtimg.cn/appstock/app/day/query?code=...`.
103
+ - 日 K, 周 K, K: 腾讯前复权 K 线接口 `https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param=...`.
104
+ - K: 使用同一接口的后复权月 K, 在本地按年份聚合.
105
+ - 数据实时性和可用性以接口实际返回为准, 仅用于个人展示用途.
106
106
 
107
- ## Installation and Usage
107
+ ## 安装与运行
108
108
 
109
- ### Install globally (recommended)
109
+ ### 全局安装 (推荐)
110
110
 
111
111
  ```bash
112
112
  npm install -g leek-box-cli
113
- # or
113
+ #
114
114
  pnpm add -g leek-box-cli
115
- # or
115
+ #
116
116
  yarn global add leek-box-cli
117
117
  ```
118
118
 
119
- Then run it from anywhere:
119
+ 之后即可在任意目录运行:
120
120
 
121
121
  ```bash
122
122
  leek-box-cli
123
123
  ```
124
124
 
125
- > Requires Node.js 22.19+ (or 24+) on the machine that runs the command.
125
+ > 运行命令的机器需要 Node.js 22.19+ ( 24+).
126
126
 
127
- Alternatively, run it once without installing:
127
+ 也可以免安装直接运行一次:
128
128
 
129
129
  ```bash
130
130
  npx leek-box-cli
131
- # or
131
+ #
132
132
  pnpm dlx leek-box-cli
133
133
  ```
134
134
 
135
- ### Run from source
135
+ ### 从源码运行
136
136
 
137
137
  ```bash
138
138
  pnpm install
139
139
 
140
- # Development mode
140
+ # 开发模式
141
141
  pnpm dev
142
142
 
143
- # Build and run
143
+ # 构建并运行
144
144
  pnpm build
145
145
  pnpm preview
146
146
  ```
147
147
 
148
- You can also select the initial page with a subcommand:
148
+ 也可以通过子命令指定初始页面:
149
149
 
150
150
  ```bash
151
- leek-box-cli # Stock watchlist dashboard
152
- leek-box-cli stock-list # Same as above
153
- leek-box-cli stock-add # Add a stock to the watchlist
154
- leek-box-cli stock-remove # Remove a stock from the watchlist
155
- leek-box-cli -v # Show version information
156
- leek-box-cli -h # Show help
151
+ leek-box-cli # 自选股票看板
152
+ leek-box-cli stock-list # 同上
153
+ leek-box-cli stock-add # 添加自选股
154
+ leek-box-cli stock-remove # 删除自选股
155
+ leek-box-cli -v # 查看版本
156
+ leek-box-cli -h # 查看帮助
157
157
  ```
158
158
 
159
- ## Settings and Watchlist Storage
159
+ ## 设置与自选股存储
160
160
 
161
- Settings and the watchlist are stored together at `$XDG_CONFIG_HOME/leek-box-cli/settings.json`. If `XDG_CONFIG_HOME` is not set, `~/.config/leek-box-cli/settings.json` is used.
161
+ 设置与自选股一起保存在 `$XDG_CONFIG_HOME/leek-box-cli/settings.json`; 未设置 `XDG_CONFIG_HOME` 时使用 `~/.config/leek-box-cli/settings.json`.
162
162
 
163
- File structure:
163
+ 文件结构为:
164
164
 
165
165
  ```json
166
166
  {
@@ -186,23 +186,23 @@ File structure:
186
186
  }
187
187
  ```
188
188
 
189
- The application reloads the file every time it refreshes the dashboard, so valid external edits take effect on the next refresh. It validates the `theme` and `request` fields, as well as each stock's `code`, `name`, `addedAt`, and duplicate codes when reading. Writes use an inter-process lock and atomic temporary-file replacement to prevent lost concurrent updates and partial JSON files.
189
+ 程序每次刷新看板都会重新读取文件, 因此合法的外部编辑会在下一轮刷新生效. 读取时会校验 `theme`, `request` 以及每只股票的 `code`, `name`, `addedAt` 和重复代码; 写入使用进程间锁与临时文件原子替换, 避免并发读改写丢失和半截 JSON.
190
190
 
191
- ## Development Scripts
191
+ ## 开发脚本
192
192
 
193
- | Command | Description |
194
- | ----------------- | ---------------------------------------- |
195
- | `pnpm dev` | Run the source code with tsx |
196
- | `pnpm build` | Build `dist/cli.mjs` with Vite |
197
- | `pnpm preview` | Run the build output |
198
- | `pnpm test` | Run tests with Vitest |
199
- | `pnpm typecheck` | Run TypeScript type checking |
200
- | `pnpm lint` | Run the linter and apply automatic fixes |
201
- | `pnpm lint:check` | Run the linter without modifying files |
202
- | `pnpm fmt` | Format the code |
203
- | `pnpm fmt:check` | Check code formatting |
193
+ | 命令 | 说明 |
194
+ | ----------------- | ----------------------------- |
195
+ | `pnpm dev` | 使用 tsx 运行源码 |
196
+ | `pnpm build` | 使用 Vite 构建 `dist/cli.mjs` |
197
+ | `pnpm preview` | 运行构建产物 |
198
+ | `pnpm test` | 使用 Vitest 运行测试 |
199
+ | `pnpm typecheck` | TypeScript 类型检查 |
200
+ | `pnpm lint` | Lint 并自动修复 |
201
+ | `pnpm lint:check` | 仅检查 Lint |
202
+ | `pnpm fmt` | 格式化代码 |
203
+ | `pnpm fmt:check` | 检查格式 |
204
204
 
205
- ## Tech Stack
205
+ ## 技术栈
206
206
 
207
207
  - TypeScript / ESM
208
208
  - Ink 7 + React 19
package/dist/cli.mjs CHANGED
@@ -147,15 +147,13 @@ Read about how to prevent this error on https://github.com/vadimdemedes/ink/#isr
147
147
  `))},$p=(e,t)=>{Xp(e,t),Qp(t.flags,e)},em=e=>{console.error([`Unknown flag${e.length>1?`s`:``}`,...e].join(`
148
148
  `))},tm=e=>/^-(?:\d+|\d*\.\d+)(?:e[+-]?\d+)?$/i.test(e),nm=e=>{let t=e.filter(e=>typeof e==`string`&&e.length>1&&e.startsWith(`-`)&&!tm(e));t.length>0&&(em(t),n.exit(2))},rm=(e,t,n,r)=>{let i=t[e],a=!0;if(typeof i.isRequired==`function`&&(a=i.isRequired(n,r),typeof a!=`boolean`))throw TypeError(`Return value for isRequired callback should be of type boolean, but ${typeof a} was returned.`);return(n[e]===void 0||i.isMultiple&&n[e].length===0)&&a},im=e=>{console.error(`Missing required flag${e.length>1?`s`:``}`);for(let t of e)console.error(`\t${Hp(t.key)}${t.shortFlag?`, -${t.shortFlag}`:``}`)},am=(e,t)=>{let{isRequired:r}=e.inputOptions;if(r){if(typeof r==`function`){let e=r(t);if(typeof e!=`boolean`)throw TypeError(`Return value for isRequired callback should be of type boolean, but ${typeof e} was returned.`);if(!e)return}t.length===0&&(console.error(`Missing required input`),n.exit(2))}},om=(e,t,r)=>{let i=[];for(let n of Object.keys(e))e[n].isRequired&&rm(n,e,t,r)&&i.push({key:n,...e[n]});i.length>0&&(im(i),n.exit(2))},sm=e=>{if(!e.startsWith(`@`))return e;let t=e.indexOf(`/`);return t===-1?e:e.slice(t+1)},cm=e=>{if(!e||typeof e!=`object`)return``;let t=typeof e.name==`string`?e.name:``,n=sm(t),{bin:r}=e;return typeof r==`string`?n:r&&typeof r==`object`?Object.keys(r).at(0)??t:t},lm=(e,t)=>{console.error(e),console.error(`Available commands: ${t.join(`, `)}`)},um=(e,t,n,r)=>{if(!t.commands)return{command:void 0,input:e};if(e.length===0)return{command:void 0,input:[]};let i=String(e[0]);if(!t.commands.includes(i)){if(!t.allowUnknownFlags&&i.startsWith(`-`)){let r=t.argv.indexOf(`--`),a=!1;if(r!==-1&&(a=!Iu(t.argv.slice(0,r),n)._.map(String).includes(i)),!a){let t=e.findIndex(e=>typeof e!=`string`||!e.startsWith(`-`));nm(t===-1?e:e.slice(0,t))}}return lm(`Unknown command: ${i}`,t.commands),r(),{command:void 0,input:[]}}return{command:i,input:e.slice(1)}},dm=({pkg:e,getPackage:t,...r},i)=>{let a=Iu(r.argv,i),o=``;if(r.help&&(o=ud((r.help||``).replace(/\t+\n*$/,``)),o.includes(`
149
149
  `)&&(o=pd(o,r.helpIndent)),o=`\n${o}`),r.description!==!1){let{description:e}=r;e&&(e=o?pd(`\n${e}\n`,r.helpIndent):`\n${e}`,o=`${e}${o}`)}o+=`
150
- `;let s=e=>{console.log(o),n.exit(typeof e==`number`?e:2)},c=()=>{console.log(r.version),n.exit(0)};a._.length===0&&r.argv.length===1&&(a.version===!0&&r.autoVersion?c():a.help===!0&&r.autoHelp&&s(0));let{command:l,input:u}=um(a._,r,i,s);if(delete a._,!r.allowUnknownFlags&&!r.commands){let e=u,t=r.argv.indexOf(`--`);t!==-1&&!Object.hasOwn(r.flags,`--`)&&(e=Iu(r.argv.slice(0,t),i)._),nm(e)}let d=ld(a,{exclude:[`--`,/^\w$/]}),f={...d};$p(d,r);for(let e of Object.values(r.flags)){if(Array.isArray(e.aliases))for(let t of e.aliases)delete d[t];delete d[e.shortFlag]}return om(r.flags,d,u),am(r,u),{input:u,command:l,flags:d,unnormalizedFlags:f,get pkg(){return t?t():e},help:o,showHelp:s,showVersion:c}},fm=(e,t={})=>{let r=Kp(e,t),i=dm(r,Yp(r));return n.title=cm(r.pkg),i},pm=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e))},o=t=e(r,i,a);return a},mm=(e=>e?pm(e):pm),hm=e=>e;function gm(e,t=hm){let n=U.useSyncExternalStore(e.subscribe,U.useCallback(()=>t(e.getState()),[e,t]),U.useCallback(()=>t(e.getInitialState()),[e,t]));return U.useDebugValue(n),n}var _m=e=>{let t=mm(e),n=e=>gm(t,e);return Object.assign(n,t),n},vm=(e=>e?_m(e):_m),ym=[`single`,`double`,`round`,`bold`,`singleDouble`,`doubleSingle`,`classic`,`arrow`],bm=[`red-up`,`green-up`],xm={"red-up":`涨红跌绿`,"green-up":`涨绿跌红`},Sm=`red-up`,Cm={classic:{label:`经典紫蓝`,primary:`magenta`,accent:`blue`,highlight:`cyan`,foreground:`white`},ocean:{label:`海洋青蓝`,primary:`cyan`,accent:`blue`,highlight:`cyan`,foreground:`white`},forest:{label:`森林绿`,primary:`green`,accent:`green`,highlight:`green`,foreground:`white`},sunset:{label:`日落黄红`,primary:`yellow`,accent:`red`,highlight:`yellow`,foreground:`white`},gray:{label:`低调灰`,primary:`gray`,accent:`gray`,highlight:`gray`,foreground:`white`}},wm=Object.keys(Cm),Tm={requestTimeoutMs:{min:1e3,max:6e4,step:1e3},minimumRequestDurationMs:{min:0,max:5e3,step:250},quotePollIntervalMs:{min:1e3,max:6e4,step:500},minuteChartPollIntervalMs:{min:5e3,max:3e5,step:5e3},klinePollIntervalMs:{min:3e4,max:18e5,step:3e4}},Em={themePreset:`classic`,trendColorMode:Sm,borderStyle:`round`,requestTimeoutMs:8e3,minimumRequestDurationMs:0,quotePollIntervalMs:5e3,minuteChartPollIntervalMs:3e4,klinePollIntervalMs:3e5},Dm=(e,t,n)=>Math.min(n,Math.max(t,Math.round(e))),Om=e=>{let t=Dm(e.requestTimeoutMs,Tm.requestTimeoutMs.min,Tm.requestTimeoutMs.max);return{...e,requestTimeoutMs:t,minimumRequestDurationMs:Math.min(t,Dm(e.minimumRequestDurationMs,Tm.minimumRequestDurationMs.min,Tm.minimumRequestDurationMs.max)),quotePollIntervalMs:Dm(e.quotePollIntervalMs,Tm.quotePollIntervalMs.min,Tm.quotePollIntervalMs.max),minuteChartPollIntervalMs:Dm(e.minuteChartPollIntervalMs,Tm.minuteChartPollIntervalMs.min,Tm.minuteChartPollIntervalMs.max),klinePollIntervalMs:Dm(e.klinePollIntervalMs,Tm.klinePollIntervalMs.min,Tm.klinePollIntervalMs.max)}},km=e=>({themePreset:e.themePreset,trendColorMode:e.trendColorMode,borderStyle:e.borderStyle,requestTimeoutMs:e.requestTimeoutMs,minimumRequestDurationMs:e.minimumRequestDurationMs,quotePollIntervalMs:e.quotePollIntervalMs,minuteChartPollIntervalMs:e.minuteChartPollIntervalMs,klinePollIntervalMs:e.klinePollIntervalMs}),Am=(e,t)=>e.themePreset===t.themePreset&&e.trendColorMode===t.trendColorMode&&e.borderStyle===t.borderStyle&&e.requestTimeoutMs===t.requestTimeoutMs&&e.minimumRequestDurationMs===t.minimumRequestDurationMs&&e.quotePollIntervalMs===t.quotePollIntervalMs&&e.minuteChartPollIntervalMs===t.minuteChartPollIntervalMs&&e.klinePollIntervalMs===t.klinePollIntervalMs,jm=(e,t)=>{let n={};return e.themePreset!==t.themePreset&&(n.themePreset=e.themePreset),e.trendColorMode!==t.trendColorMode&&(n.trendColorMode=e.trendColorMode),e.borderStyle!==t.borderStyle&&(n.borderStyle=e.borderStyle),e.requestTimeoutMs!==t.requestTimeoutMs&&(n.requestTimeoutMs=e.requestTimeoutMs),e.minimumRequestDurationMs!==t.minimumRequestDurationMs&&(n.minimumRequestDurationMs=e.minimumRequestDurationMs),e.quotePollIntervalMs!==t.quotePollIntervalMs&&(n.quotePollIntervalMs=e.quotePollIntervalMs),e.minuteChartPollIntervalMs!==t.minuteChartPollIntervalMs&&(n.minuteChartPollIntervalMs=e.minuteChartPollIntervalMs),e.klinePollIntervalMs!==t.klinePollIntervalMs&&(n.klinePollIntervalMs=e.klinePollIntervalMs),n},Mm=vm()(e=>({...Em,updateSettings:t=>e(e=>Om({...km(e),...t})),adjustNumericSetting:(t,n)=>e(e=>{let r=Tm[t],i=Dm(e[t]+r.step*n,r.min,r.max);return Om({...km(e),[t]:i})}),resetSettings:()=>e(Em),hydrateSettings:t=>e(Om(t))}));function Nm(){return Mm(e=>Cm[e.themePreset])}var Pm=vm()(e=>({open:!1,toggle:()=>e(e=>({open:!e.open})),close:()=>e({open:!1})})),Fm=e=>typeof e==`object`&&e?e:void 0,Im=(e,t)=>{let n=Number.parseFloat(e[t]??``);return Number.isFinite(n)?n:0},Lm=e=>{let t=Number.parseFloat(typeof e==`string`||typeof e==`number`?String(e):``);return Number.isFinite(t)?t:0},Rm=e=>{if(!Array.isArray(e))return[];let t=[];for(let n of e){if(typeof n!=`string`)continue;let[e=``,r=``,i=``]=n.split(` `);if(!/^(?:[01]\d|2[0-3])[0-5]\d$/.test(e)||e>`1500`)continue;let a=Number.parseFloat(r);if(!Number.isFinite(a)||a<=0)continue;let o=Number.parseFloat(i);t.push({time:e,price:a,volume:Number.isFinite(o)?o:0})}return t};function zm(e){let t=[];for(let n of e.split(`;`)){let e=/^v_([a-z]{2}\d{6})="([^"]*)"/.exec(n.trim());if(!e)continue;let r=e[2].split(`~`);if(r.length<50)continue;let i=r[1].trim();i&&t.push({code:e[1],name:i,current:Im(r,3),prevClose:Im(r,4),open:Im(r,5),high:Im(r,33),low:Im(r,34),change:Im(r,31),changePercent:Im(r,32),timestamp:r[30],volume:Im(r,36),turnover:Im(r,37),turnoverRate:Im(r,38),amplitude:Im(r,43),marketCap:Im(r,45),volumeRatio:Im(r,49)})}if(t.length===0)throw Error(`未查询到任何行情数据, 请检查股票代码`);return t}function Bm(e,t){return Rm(Fm(Fm(Fm(Fm(e)?.data)?.[t])?.data)?.data)}function Vm(e,t){let n=Fm(Fm(Fm(e)?.data)?.[t])?.data;return Array.isArray(n)?n.flatMap(e=>{let t=Fm(e),n=t?.date;if(typeof n!=`string`||!/^\d{8}$/.test(n))return[];let r=`${n.slice(0,4)}-${n.slice(4,6)}-${n.slice(6,8)}`,i=Lm(t?.prec);return[{sessionDate:r,points:Rm(t?.data).map(e=>({...e,sessionDate:r,prevClose:i}))}]}).sort((e,t)=>e.sessionDate.localeCompare(t.sessionDate)).slice(-5).flatMap(e=>e.points):[]}function Hm(e,t,n=`day`,r=`qfq`){let i=Fm(Fm(Fm(e)?.data)?.[t]),a=i?.[`${r}${n}`],o=Array.isArray(a)&&a.length>0?a:i?.[n];if(!Array.isArray(o))return[];let s=[];for(let e of o){if(!Array.isArray(e))continue;let[t,n,r,i,a,o]=e;if(typeof t!=`string`||!/^\d{4}-\d{2}-\d{2}$/.test(t))continue;let c=Lm(n),l=Lm(r),u=Lm(i),d=Lm(a),f=Lm(o);[c,l,u,d].some(e=>e<=0)||s.push({date:t,open:c,close:l,high:u,low:d,volume:Math.max(0,f)})}return s}var Um=(e,t)=>e<=0?Promise.resolve():t?.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let i=setTimeout(()=>{t?.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(t?.reason)};t?.addEventListener(`abort`,a,{once:!0})}),Wm=async(e,t)=>{let{requestTimeoutMs:n,minimumRequestDurationMs:r}=Mm.getState(),i=AbortSignal.timeout(n),a=e?AbortSignal.any([e,i]):i,o=Date.now(),s=await t(a);return await Um(r-(Date.now()-o),e),s};function Gm(e){let t=e.trim().toUpperCase();if(t=t.replace(/\.(SH|SZ|BJ)$/,``),t=t.replace(/^(SH|SZ|BJ)/,``),!/^\d{6}$/.test(t))return;let n;if(t.startsWith(`6`)||t.startsWith(`5`))n=`sh`;else if(t.startsWith(`0`)||t.startsWith(`1`)||t.startsWith(`3`))n=`sz`;else if(t.startsWith(`4`)||t.startsWith(`8`)||t.startsWith(`92`))n=`bj`;else return;return`${n}${t}`}async function Km(e,t){return e.length===0?[]:Wm(t,async t=>{let n=await fetch(`https://qt.gtimg.cn/q=${e.join(`,`)}`,{signal:t});if(!n.ok)throw Error(`行情接口请求失败: HTTP ${n.status}`);let r=await n.arrayBuffer();return zm(new TextDecoder(`gbk`).decode(r))})}async function qm(e,t){return Wm(t,async t=>{let n=await fetch(`https://web.ifzq.gtimg.cn/appstock/app/minute/query?code=${e}`,{signal:t});if(!n.ok)throw Error(`分时接口请求失败: HTTP ${n.status}`);return Bm(await n.json(),e)})}async function Jm(e,t){return Wm(t,async t=>{let n=await fetch(`https://web.ifzq.gtimg.cn/appstock/app/day/query?code=${e}`,{signal:t});if(!n.ok)throw Error(`五日行情接口请求失败: HTTP ${n.status}`);return Vm(await n.json(),e)})}var Ym=e=>{let t=new Map;for(let n of[...e].sort((e,t)=>e.date.localeCompare(t.date))){let e=n.date.slice(0,4),r=t.get(e);if(!r){t.set(e,{...n});continue}r.date=n.date,r.close=n.close,r.high=Math.max(r.high,n.high),r.low=Math.min(r.low,n.low),r.volume+=n.volume}return[...t.values()]};async function Xm(e,t){return Wm(t.signal,async n=>{let r=t.period===`year`?`month`:t.period,i=t.period===`year`?`hfq`:`qfq`,a=t.period===`year`?t.barCount*12:t.barCount,o=encodeURIComponent(`${e},${r},,,${a},${i}`),s=await fetch(`https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param=${o}`,{signal:n});if(!s.ok)throw Error(`K 线行情接口请求失败: HTTP ${s.status}`);let c=Hm(await s.json(),e,r,i);return(t.period===`year`?Ym(c):c).slice(-t.barCount)})}function Zm(e){return e instanceof Error?e.message:String(e)}var Qm={day:{barCount:60},week:{barCount:60},month:{barCount:60},year:{barCount:30}},$m=`intraday`,eh=e=>e!==`intraday`&&e!==`five-day`,th={fetchIntraday:qm,fetchFiveDay:Jm,fetchHistorical:Xm};function nh(e=th){return vm()((t,n)=>({stock:void 0,period:$m,status:`loading`,points:[],open:(e,n)=>t({stock:{code:e,name:n},period:$m,status:`loading`,points:[],errorMessage:void 0}),close:()=>t({stock:void 0}),setPeriod:e=>{n().period!==e&&t({period:e,status:`loading`,points:[],errorMessage:void 0})},refreshChart:async(r,i,a)=>{try{let o;if(i===`intraday`)o=await e.fetchIntraday(r,a);else if(i===`five-day`)o=await e.fetchFiveDay?.(r,a);else if(eh(i)){let t=Qm[i];o=await e.fetchHistorical?.(r,{period:i,...t,signal:a})}if(!o)throw Error(`${i===`five-day`?`五日`:`K 线`}行情数据源不可用`);if(n().stock?.code!==r||n().period!==i||a?.aborted)return;t({status:`ready`,points:o,errorMessage:void 0})}catch(e){if(n().stock?.code!==r||n().period!==i||a?.aborted)return;t({status:`error`,errorMessage:Zm(e)})}}}))}var rh=nh();function ih(){let e=Pm(e=>e.open),t=rh(e=>e.stock!==void 0);return e||t}var ah=z((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),Q=z(((e,t)=>{t.exports=ah()}))();function $({bright:e=!1,color:t,...n}){let r=ih(),i=Nm(),a=!e&&r;return(0,Q.jsx)(ml,{...n,color:t??i.foreground,dimColor:a})}function oh({title:e,bright:t=!1,top:n,left:r,right:i}){return(0,Q.jsxs)(pl,{position:`absolute`,top:n,left:r,right:i,children:[(0,Q.jsx)($,{bright:t,children:`|`}),e,(0,Q.jsx)($,{bright:t,children:`|`})]})}function sh(e){let{bright:t=!1,fullScreen:n,title:r,extra:i,footer:a,children:o}=e,{width:s,height:c,backgroundColor:l}=e,{columns:u,rows:d}=_u(),f=Mm(e=>e.borderStyle),p=Nm();return(0,Q.jsxs)(pl,{flexDirection:`column`,width:n?u:s,height:n?d:c,borderStyle:f,borderColor:p.primary,borderDimColor:t===!1,children:[r?(0,Q.jsx)(oh,{title:r,bright:t,top:-1,left:1}):void 0,i?(0,Q.jsx)(oh,{title:i,bright:t,top:-1,right:1}):void 0,(0,Q.jsx)(pl,{flexGrow:1,flexDirection:`column`,padding:1,backgroundColor:l,children:o}),a]})}var ch=new Intl.DateTimeFormat(`en-CA`,{timeZone:`Asia/Shanghai`,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1});function lh(e,t){let n=ch.formatToParts(e),r=e=>n.find(t=>t.type===e)?.value??``,i=`${r(`year`)}-${r(`month`)}-${r(`day`)}`,a=`${r(`hour`)}:${r(`minute`)}`;switch(t){case`date-time`:return`${i} ${a}:${r(`second`)}`;case`date`:return i;case`time`:return`${a}:${r(`second`)}`;case`hour-minute`:return a}}var uh={"date-time":1e3,date:6e4,time:1e3,"hour-minute":6e4};function dh(e){let[t,n]=(0,U.useState)(()=>new Date);return(0,U.useEffect)(()=>{let t=setInterval(()=>n(new Date),uh[e]);return()=>clearInterval(t)},[e]),lh(t,e)}function fh(e){let{hint:t,bright:n=!1}=e,r=dh(`date-time`),i=Nm();return(0,Q.jsxs)(pl,{justifyContent:`space-between`,paddingX:1,backgroundColor:n?i.accent:`gray`,children:[(0,Q.jsx)(pl,{flexShrink:0,children:t&&(0,Q.jsx)($,{bright:n,color:`white`,children:t})}),(0,Q.jsx)(pl,{flexShrink:0,children:(0,Q.jsx)($,{bright:n,color:`white`,children:r})})]})}function ph(e){let{title:t,extra:n,width:r,children:i}=e,{rows:a,columns:o}=_u();return(0,Q.jsx)(pl,{position:`absolute`,top:0,left:0,width:o,height:a,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,children:(0,Q.jsx)(sh,{bright:!0,title:t,extra:n,width:r,backgroundColor:`black`,footer:(0,Q.jsx)(fh,{bright:!0}),children:i})})}var mh=[{type:`theme`,label:`主题色系`,description:`界面配色`},{type:`trendColor`,label:`涨跌颜色`,description:`选择涨绿或跌绿`},{type:`border`,label:`卡片边框`,description:`边框样式`},{type:`numeric`,label:`请求超时`,description:`单次请求最长等待`,setting:`requestTimeoutMs`},{type:`numeric`,label:`请求最短耗时`,description:`避免加载闪烁`,setting:`minimumRequestDurationMs`},{type:`numeric`,label:`看板刷新间隔`,description:`自选股票看板自动刷新频率`,setting:`quotePollIntervalMs`},{type:`numeric`,label:`分时图刷新间隔`,description:`分时与五日图自动刷新频率`,setting:`minuteChartPollIntervalMs`},{type:`numeric`,label:`K 线刷新间隔`,description:`日/周/月/年 K 线自动刷新频率`,setting:`klinePollIntervalMs`}],hh=(e,t,n)=>e[(e.indexOf(t)+n+e.length)%e.length]??t,gh=e=>e===0?`关闭`:e<1e3?`${e} ms`:e%6e4==0?`${e/6e4} 分钟`:e%1e3==0?`${e/1e3} 秒`:`${(e/1e3).toFixed(2)} 秒`;function _h(){let[e,t]=(0,U.useState)(0),n=ih(),r=Mm(),i=t=>{let n=mh[e];n&&(n.type===`theme`?r.updateSettings({themePreset:hh(wm,r.themePreset,t)}):n.type===`trendColor`?r.updateSettings({trendColorMode:hh(bm,r.trendColorMode,t)}):n.type===`border`?r.updateSettings({borderStyle:hh(ym,r.borderStyle,t)}):r.adjustNumericSetting(n.setting,t))};mu((e,n)=>{n.ctrl||(n.upArrow?t(e=>(e-1+mh.length)%mh.length):n.downArrow?t(e=>(e+1)%mh.length):n.leftArrow?i(-1):n.rightArrow||n.return?i(1):e===`d`&&r.resetSettings())},{isActive:!n});let a=mh.map((t,n)=>({label:t.label,description:t.description,selected:n===e,value:t.type===`theme`?Cm[r.themePreset].label:t.type===`trendColor`?xm[r.trendColorMode]:t.type===`border`?r.borderStyle:gh(r[t.setting])}));return{overlayOpen:n,appearanceRows:a.slice(0,3),requestRows:a.slice(3)}}function vh({rows:e,highlight:t}){return e.map(e=>(0,Q.jsxs)(pl,{justifyContent:`space-between`,children:[(0,Q.jsxs)($,{color:e.selected?`black`:void 0,backgroundColor:e.selected?t:void 0,children:[e.selected?`› `:` `,e.label,(0,Q.jsxs)($,{color:`gray`,backgroundColor:e.selected?t:void 0,children:[`(`,e.description,`)`]})]}),(0,Q.jsx)($,{color:e.selected?t:`gray`,children:e.value})]},e.label))}function yh({title:e,hint:t}){let n=Nm(),{overlayOpen:r,appearanceRows:i,requestRows:a}=_h();return(0,Q.jsxs)(sh,{fullScreen:!0,bright:!r,title:(0,Q.jsx)($,{color:n.primary,children:e}),footer:(0,Q.jsx)(fh,{hint:t,bright:!r}),children:[(0,Q.jsx)($,{color:n.primary,children:`外观`}),(0,Q.jsx)(vh,{rows:i,highlight:n.highlight}),(0,Q.jsxs)(pl,{marginTop:1,flexDirection:`column`,children:[(0,Q.jsx)($,{color:n.primary,children:`请求与刷新`}),(0,Q.jsx)(vh,{rows:a,highlight:n.highlight})]}),(0,Q.jsx)(pl,{marginTop:1,flexDirection:`column`,children:(0,Q.jsx)($,{color:`gray`,children:`请求最短耗时用于避免加载状态闪烁, 且不会超过请求超时.`})})]})}var bh=vm()(e=>({screen:`stock-list`,goTo:t=>e({screen:t})})),xh={error:`red`,warning:`yellow`,success:`green`};function Sh({tone:e,msg:t}){return(0,Q.jsx)($,{bold:!0,color:xh[e],children:t})}function Ch({prompt:e,onSubmit:t,placeholder:n}){let r=ih(),[i,a]=(0,U.useState)(``),[o,s]=(0,U.useState)(!1);return mu((e,n)=>{o||(n.return?(s(!0),t(i)):n.backspace||n.delete?a(e=>e.slice(0,-1)):!n.ctrl&&!n.meta&&e&&a(t=>t+e))},{isActive:!r&&!o}),(0,Q.jsx)(pl,{children:(0,Q.jsxs)($,{children:[e,o?(0,Q.jsx)($,{color:`green`,children:i}):(0,Q.jsxs)($,{children:[i,(0,Q.jsx)($,{color:`gray`,children:`█`}),!i&&n?n:void 0]})]})})}function wh({tone:e,msg:t,to:n,onReturn:r}){let i=bh(e=>e.goTo);return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(Sh,{tone:e,msg:t}),(0,Q.jsx)(ql,{}),(0,Q.jsx)(Ch,{prompt:`按 Enter 返回操作页...`,onSubmit:()=>{r?.(),i(n)}})]})}var Th=e=>e>0?e.toFixed(2):`--`,Eh=e=>`${e>0?`+`:``}${e.toFixed(2)}`,Dh=e=>`${e>0?`+`:``}${e.toFixed(2)}%`,Oh=(e,t=Sm)=>e===0?`gray`:e>0==(t===`green-up`)?`green`:`red`,kh=e=>e>=1e4?`${(e/1e4).toFixed(1)}万手`:e>0?`${Math.round(e)}手`:`--`,Ah=e=>e>=1e4?`${(e/1e4).toFixed(2)}亿`:e>0?`${e.toFixed(1)}万`:`--`,jh=e=>e>0?`${e.toFixed(2)}%`:`--`,Mh=e=>e>0?e.toFixed(2):`--`,Nh=e=>e>0?`${e.toFixed(2)}亿`:`--`,Ph=/^(?:sh|sz|bj)\d{6}$/,Fh=(e,t)=>{if(typeof e!=`object`||!e)throw Error(`第 ${t+1} 项不是对象`);let n=e;if(typeof n.code!=`string`||!Ph.test(n.code))throw Error(`第 ${t+1} 项 code 无效`);if(typeof n.name!=`string`||n.name.trim()===``)throw Error(`第 ${t+1} 项 name 无效`);if(typeof n.addedAt!=`string`||!Number.isFinite(Date.parse(n.addedAt)))throw Error(`第 ${t+1} 项 addedAt 无效`);return{code:n.code,name:n.name,addedAt:n.addedAt}};function Ih(e){if(!Array.isArray(e))throw Error(`stocks 不是数组`);let t=e.map(Fh),n=new Set;for(let[e,r]of t.entries()){if(n.has(r.code))throw Error(`第 ${e+1} 项 code 重复: ${r.code}`);n.add(r.code)}return t}var Lh=25,Rh=2e3,zh=3e4,Bh=e=>typeof e==`object`&&!!e&&!Array.isArray(e),Vh=e=>{if(typeof e!=`string`||!wm.includes(e))throw Error(`theme.preset 无效`);return e},Hh=e=>{if(e===void 0)return Sm;if(typeof e!=`string`||!bm.includes(e))throw Error(`theme.trendColorMode 无效`);return e},Uh=(e,t,n)=>{if(typeof e!=`number`||!Number.isInteger(e)||e<n.min||e>n.max)throw Error(`${t} 无效`);return e};function Wh(e){if(!Bh(e))throw Error(`顶层数据不是对象`);let t=e.theme;if(!Bh(t))throw Error(`theme 无效`);let n=t.borderStyle;if(typeof n!=`string`||!ym.includes(n))throw Error(`theme.borderStyle 无效`);let r=e.request;if(!Bh(r))throw Error(`request 无效`);let i=Uh(r.timeoutMs,`request.timeoutMs`,Tm.requestTimeoutMs),a=Uh(r.minimumDurationMs,`request.minimumDurationMs`,Tm.minimumRequestDurationMs);if(a>i)throw Error(`request.minimumDurationMs 不能大于 request.timeoutMs`);return{theme:{preset:Vh(t.preset),trendColorMode:Hh(t.trendColorMode),borderStyle:n},request:{timeoutMs:i,minimumDurationMs:a,quotePollIntervalMs:Uh(r.quotePollIntervalMs,`request.quotePollIntervalMs`,Tm.quotePollIntervalMs),minuteChartPollIntervalMs:Uh(r.minuteChartPollIntervalMs,`request.minuteChartPollIntervalMs`,Tm.minuteChartPollIntervalMs),klinePollIntervalMs:Uh(r.klinePollIntervalMs,`request.klinePollIntervalMs`,Tm.klinePollIntervalMs)},stocks:Ih(e.stocks)}}function Gh(e){return{themePreset:e.theme.preset,trendColorMode:e.theme.trendColorMode,borderStyle:e.theme.borderStyle,requestTimeoutMs:e.request.timeoutMs,minimumRequestDurationMs:e.request.minimumDurationMs,quotePollIntervalMs:e.request.quotePollIntervalMs,minuteChartPollIntervalMs:e.request.minuteChartPollIntervalMs,klinePollIntervalMs:e.request.klinePollIntervalMs}}var Kh=(e,t)=>({theme:{preset:e.themePreset,trendColorMode:e.trendColorMode,borderStyle:e.borderStyle},request:{timeoutMs:e.requestTimeoutMs,minimumDurationMs:e.minimumRequestDurationMs,quotePollIntervalMs:e.quotePollIntervalMs,minuteChartPollIntervalMs:e.minuteChartPollIntervalMs,klinePollIntervalMs:e.klinePollIntervalMs},stocks:t}),qh=()=>{let e=n.env.XDG_CONFIG_HOME??C(c(),`.config`);return C(e,`leek-box-cli`)};function Jh(){return C(qh(),`settings.json`)}var Yh=async e=>{try{return JSON.parse(await A(e,`utf8`))}catch(e){if(e.code===`ENOENT`)return;throw e}},Xh=async()=>{let e=Jh();try{let t=await Yh(e);return t===void 0?void 0:Wh(t)}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`设置文件损坏: ${e} (${n})`)}},Zh=async e=>{let t=Wh(e),r=Jh();await k(S(r),{recursive:!0});let i=`${r}.${n.pid}.${D()}.tmp`;try{await P(i,`${JSON.stringify(t,null,2)}\n`,`utf8`),await j(i,r)}finally{await M(i,{force:!0})}},Qh=e=>new Promise(t=>setTimeout(t,e)),$h=e=>{try{return n.kill(e,0),!0}catch(e){return e.code!==`ESRCH`}},eg=async e=>{let t;try{t=await A(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return!0;throw e}let n=!1;try{let e=JSON.parse(t);if(!Bh(e)||typeof e.token!=`string`||typeof e.pid!=`number`||!Number.isInteger(e.pid)||e.pid<=0||typeof e.createdAt!=`number`||!Number.isFinite(e.createdAt))throw Error(`lock metadata 无效`);n=!$h(e.pid)||Date.now()-e.createdAt>=zh}catch{try{let t=await N(e);n=Date.now()-t.mtimeMs>=Rh}catch(e){if(e.code===`ENOENT`)return!0;throw e}}if(!n)return!1;try{return await A(e,`utf8`)===t&&(await M(e),!0)}catch(e){if(e.code===`ENOENT`)return!0;throw e}},tg=async(e,t)=>{let r=`${e}.${n.pid}.${D()}.tmp`;try{await P(r,t,{encoding:`utf8`,flag:`wx`}),await O(r,e)}finally{await M(r,{force:!0})}};async function ng(e){let t=Jh(),r=`${t}.lock`,i=D(),a=JSON.stringify({token:i,pid:n.pid,createdAt:Date.now()});await k(S(t),{recursive:!0});let o=Date.now(),s=!1;for(;!s;)try{await tg(r,a),s=!0}catch(e){if(e.code!==`EEXIST`)throw e;if(await eg(r))continue;if(Date.now()-o>=Rh)throw Error(`设置文件正被其他进程占用, 请稍后重试`);await Qh(Lh)}let c;try{c={ok:!0,value:await e()}}catch(e){c={ok:!1,error:e}}let l;try{await A(r,`utf8`)===a&&await M(r)}catch(e){e.code!==`ENOENT`&&(l=e)}if(!c.ok)throw c.error;if(l)throw l;return c.value}var rg=async()=>{let e=await Xh();if(e)return e;let t=Kh(Em,[]);return await Zh(t),t};async function ig(){return await Xh()??ng(rg)}var ag=ig;async function og(e){await ng(async()=>{let t=await rg();await Zh(Kh({...Gh(t),...e},t.stocks))})}async function sg(){return(await ag()).stocks}async function cg(e){let t=Ih(e);return ng(async()=>{let e=await rg(),n=new Set(e.stocks.map(e=>e.code)),r=t.filter(e=>!n.has(e.code));return r.length>0&&await Zh({...e,stocks:[...e.stocks,...r]}),r.length})}async function lg(e){let t=new Set(e);return t.size===0?0:ng(async()=>{let e=await rg(),n=e.stocks.filter(e=>!t.has(e.code)),r=e.stocks.length-n.length;return r>0&&await Zh({...e,stocks:n}),r})}function ug(e){let t=e.trim();if(t===`y`||t===`Y`)return`y`;if(t===`n`||t===`N`)return`n`}var dg=`错误: 必须选择 y (是) 或 n (否).`,fg={stocksAdd:cg,fetchQuotes:Km,normalizeCode:Gm,now:()=>new Date().toISOString()},pg={error:void 0,resetToken:0},mg=e=>{e(e=>({codeInput:{error:`无法识别股票代码, 请用英文逗号分隔 6 位股票代码.`,resetToken:e.codeInput.resetToken+1}}))};function hg(e=fg){let t=0,n=e=>e!==t;return vm()((r,i)=>({step:{type:`input-code`},codeInput:pg,confirmInput:pg,reset:()=>{t+=1,r({step:{type:`input-code`},codeInput:pg,confirmInput:pg})},handleCodeInput:async i=>{let a=t,o=i.split(`,`).map(e=>e.trim());if(o.length===0||o.some(e=>e===``)){mg(r);return}let s=o.map(t=>e.normalizeCode(t));if(s.some(e=>e===void 0)){mg(r);return}let c=[...new Set(s)];r(e=>({codeInput:{error:void 0,resetToken:e.codeInput.resetToken+1}})),r({step:{type:`checking`,codes:c}});try{let t=await e.fetchQuotes(c);if(n(a))return;let i=new Map(t.map(e=>[e.code,e])),o=c.filter(e=>!i.has(e));if(o.length>0){r({step:{type:`error`,message:`未找到股票代码: ${o.join(`, `)}.`}});return}r({step:{type:`confirm`,entries:c.map(e=>{let t=i.get(e);return{code:e,name:t.name,current:t.current}})}})}catch(e){n(a)||r({step:{type:`error`,message:Zm(e)}})}},handleConfirm:async a=>{let o=ug(a);if(!o){r(e=>({confirmInput:{error:dg,resetToken:e.confirmInput.resetToken+1}}));return}if(r(e=>({confirmInput:{error:void 0,resetToken:e.confirmInput.resetToken+1}})),o===`n`){r({step:{type:`done`,message:`已取消.`}});return}let s=t,c=i().step;if(c.type===`confirm`){r({step:{type:`saving`,entries:c.entries}});try{let t=e.now(),i=await e.stocksAdd(c.entries.map(e=>({code:e.code,name:e.name,addedAt:t})));if(n(s))return;if(i===0){r({step:{type:`already-exists`,entries:c.entries}});return}r({step:{type:`done`,message:`已添加 ${i} 个股票, ${c.entries.length-i} 个已在自选股中.`}})}catch(e){n(s)||r({step:{type:`error`,message:`写入自选股失败: ${Zm(e)}`}})}}}}))}var gg=hg();function _g(){let e=gg(e=>e.step),t=gg(e=>e.codeInput),n=gg(e=>e.confirmInput),r=gg(e=>e.handleCodeInput),i=gg(e=>e.handleConfirm),a=gg(e=>e.reset);return(0,U.useEffect)(()=>{a()},[a]),{step:e,codeInput:t,confirmInput:n,handleCodeInput:r,handleConfirm:i,reset:a}}function vg({title:e,hint:t}){let n=ih(),r=Nm(),{step:i,codeInput:a,confirmInput:o,handleCodeInput:s,handleConfirm:c,reset:l}=_g(),u;switch(i.type){case`input-code`:u=(0,Q.jsxs)(Q.Fragment,{children:[a.error&&(0,Q.jsx)($,{color:`red`,children:a.error}),(0,Q.jsx)(Ch,{prompt:`请输入股票代码, 用英文逗号分隔: `,placeholder:(0,Q.jsx)($,{color:`gray`,children:`支持 600000, sh600000, 600000.SH 等写法`}),onSubmit:s},`code-${a.resetToken}`)]});break;case`checking`:u=(0,Q.jsxs)($,{color:`cyan`,children:[`正在验证股票代码: `,i.codes.join(`, `),`...`]});break;case`confirm`:u=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)($,{color:`cyan`,children:`找到以下股票:`}),i.entries.map(e=>(0,Q.jsxs)($,{children:[e.name,` (`,e.code,`), 现价 `,Th(e.current)]},e.code)),o.error&&(0,Q.jsx)($,{color:`red`,children:o.error}),(0,Q.jsx)(Ch,{prompt:`确认添加到自选股? (y/n): `,onSubmit:c},`confirm-${o.resetToken}`)]});break;case`saving`:u=(0,Q.jsxs)($,{color:`cyan`,children:[`正在添加 `,i.entries.length,` 个股票...`]});break;case`already-exists`:u=(0,Q.jsx)(wh,{tone:`warning`,msg:`${i.entries.map(e=>`${e.name} (${e.code})`).join(`, `)} 已在自选股中.`,to:`stock-add`,onReturn:l});break;case`done`:u=(0,Q.jsx)(wh,{tone:`success`,msg:i.message,to:`stock-add`,onReturn:l});break;case`error`:u=(0,Q.jsx)(wh,{tone:`error`,msg:i.message,to:`stock-add`,onReturn:l})}return(0,Q.jsx)(sh,{fullScreen:!0,bright:!n,title:(0,Q.jsx)($,{color:r.primary,children:e}),footer:(0,Q.jsx)(fh,{hint:t,bright:!n}),children:u})}function yg(e){let{segments:t,selected:n,bright:r=!1}=e;return(0,Q.jsx)($,{bright:r,inverse:n,children:t.map((e,t)=>(0,Q.jsx)($,{bright:r,color:e.color,children:e.text},t))})}var bg=(e,t)=>e+` `.repeat(Math.max(0,t.width-Nt(e))),xg=e=>e.map((t,n)=>({...t,text:n<e.length-1?`${t.text} `:t.text})),Sg=new Map([{key:`code`,kind:`code`,title:`代码`,width:9,render:e=>e.code},{key:`name`,kind:`name`,title:`名称`,width:9,render:e=>e.name},{key:`current`,kind:`value`,title:`现价`,width:8,render:e=>Th(e.current),color:(e,t)=>Oh(e.change,t)},{key:`changePercent`,kind:`changePercent`,title:`涨跌幅`,width:9,render:e=>Dh(e.changePercent),color:(e,t)=>Oh(e.changePercent,t),suspendedText:`停牌`},{key:`change`,kind:`value`,title:`涨跌额`,width:8,render:e=>Eh(e.change),color:(e,t)=>Oh(e.change,t)},{key:`open`,kind:`value`,title:`今开`,width:7,render:e=>Th(e.open)},{key:`prevClose`,kind:`value`,title:`昨收`,width:7,render:e=>Th(e.prevClose)},{key:`high`,kind:`value`,title:`最高`,width:7,render:e=>Th(e.high)},{key:`low`,kind:`value`,title:`最低`,width:7,render:e=>Th(e.low)},{key:`volume`,kind:`value`,title:`成交量`,width:11,render:e=>kh(e.volume)},{key:`turnover`,kind:`value`,title:`成交额`,width:9,render:e=>Ah(e.turnover)},{key:`turnoverRate`,kind:`value`,title:`换手率`,width:7,render:e=>jh(e.turnoverRate)},{key:`amplitude`,kind:`value`,title:`振幅`,width:7,render:e=>jh(e.amplitude)},{key:`volumeRatio`,kind:`value`,title:`量比`,width:7,render:e=>Mh(e.volumeRatio)},{key:`marketCap`,kind:`value`,title:`总市值`,width:10,render:e=>Nh(e.marketCap)}].map(e=>[e.key,e])),Cg=e=>xg(e.map(e=>({text:bg(e.title,e),color:`gray`}))),wg=(e,t,n=Sm)=>{let r=t.current<=0;return xg(e.map(e=>({text:bg(r?e.suspendedText??`--`:e.render(t),e),color:r||!e.color?`gray`:e.color(t,n)})))},Tg=(e,t,n)=>xg(e.map(e=>({text:bg(e.kind===`code`?t:e.kind===`name`?n:e.kind===`changePercent`?`无数据`:`--`,e),color:`gray`}))),Eg=[`name`,`code`,`current`,`changePercent`,`change`,`open`,`high`,`low`,`volume`,`turnover`,`turnoverRate`,`marketCap`],Dg=[`open`,`prevClose`,`high`,`low`,`volume`,`turnover`,`turnoverRate`,`amplitude`,`volumeRatio`,`marketCap`],Og=Eg.reduce((e,t)=>{let n=Sg.get(t);return n&&e.push(n),e},[]),kg=Dg.reduce((e,t)=>{let n=Sg.get(t);return n&&e.push(n),e},[]),Ag=()=>Og.reduce((e,t)=>e+t.width,0)+(Og.length-1),jg=()=>kg.reduce((e,t)=>e+t.width,0)+(kg.length-1);function Mg(e,{enabled:t=!0,intervalMs:n,restartKey:r,onError:i}){let a=(0,U.useRef)(e),o=(0,U.useRef)(n),s=(0,U.useRef)(i),c=(0,U.useRef)({});(0,U.useEffect)(()=>{a.current=e,o.current=n,s.current=i},[e,n,i]);let l=(0,U.useCallback)(()=>c.current.refresh?.(),[]);return(0,U.useEffect)(()=>{if(!t){c.current={};return}let e=!0,n=!1,r,i,l=()=>{r&&=(clearTimeout(r),void 0)},u=(t=o.current)=>{!e||n||r||(r=setTimeout(()=>{r=void 0,f()},t))},d=async()=>{if(!e||n)return;let t=Date.now();n=!0,i=new AbortController;let r=i;try{await a.current(r.signal)}catch(e){r.signal.aborted||s.current?.(e)}finally{i===r&&(i=void 0),n=!1,u(Math.max(0,o.current-(Date.now()-t)))}},f=()=>void d();return c.current={refresh:()=>{n||(l(),f())},reschedule:()=>{n||(l(),u())}},f(),()=>{e=!1,c.current={},l(),i?.abort()}},[t,r]),(0,U.useEffect)(()=>{c.current.reschedule?.()},[n]),{refresh:l}}var Ng={fetchQuotes:Km,loadStocks:sg},Pg=(e,t)=>Math.min(Math.max(e,0),t-1),Fg=(e,t,n,r,i)=>{let a=Pg(t+e,n),o=Math.max(0,n-i);return e===1&&a>=r+i?Math.min(a-i+1,o):e===-1&&a<r?a:Math.min(r,o)},Ig=(e,t)=>{if(!t)return 0;let n=e.findIndex(e=>e.code===t);return n<0?0:n},Lg=(e,t)=>e.code===t.code&&e.name===t.name&&e.current===t.current&&e.prevClose===t.prevClose&&e.open===t.open&&e.high===t.high&&e.low===t.low&&e.change===t.change&&e.changePercent===t.changePercent&&e.timestamp===t.timestamp&&e.volume===t.volume&&e.turnover===t.turnover&&e.turnoverRate===t.turnoverRate&&e.amplitude===t.amplitude&&e.marketCap===t.marketCap&&e.volumeRatio===t.volumeRatio;function Rg(e=Ng){return vm()((t,n)=>({step:{type:`loading`},selectedCode:void 0,scrollOffset:0,refreshQuotes:async n=>{try{let r=await e.loadStocks();if(n?.aborted)return;if(r.length===0){t({step:{type:`empty`},selectedCode:void 0,scrollOffset:0});return}let i=await e.fetchQuotes(r.map(e=>e.code),n);if(n?.aborted)return;t(e=>{let t=e.step.type===`table`?e.step.rows:[],n=new Map(t.filter(e=>e.kind===`quote`).map(e=>[e.code,e.quote])),a=new Map(i.map(e=>{let t=n.get(e.code);return[e.code,t&&Lg(t,e)?t:e]})),o=r.map(e=>{let t=a.get(e.code);return t?{kind:`quote`,code:e.code,name:t.name,quote:t}:{kind:`missing`,code:e.code,name:e.name}}),s=Ig(t,e.selectedCode),c=e.selectedCode?o.findIndex(t=>t.code===e.selectedCode):-1,l=c>=0?c:Pg(s,o.length),u=Math.max(0,s-e.scrollOffset);return{step:{type:`table`,rows:o},selectedCode:o[l]?.code,scrollOffset:Math.max(0,l-u)}})}catch(e){if(n?.aborted)return;let r=Zm(e);t(e=>e.step.type===`table`?{step:{...e.step,errorLine:r}}:{step:{type:`error`,message:r}})}},moveSelection:(e,r)=>{let{step:i,selectedCode:a,scrollOffset:o}=n();if(i.type!==`table`||i.rows.length===0)return;let s=Ig(i.rows,a),c=Pg(s+e,i.rows.length);t({selectedCode:i.rows[c]?.code,scrollOffset:Fg(e,s,i.rows.length,o,r)})}}))}var zg=Rg(),Bg=(e,t,n)=>{if(e<=n)return{start:0,end:e};let r=e-n,i=Math.min(Math.max(t,0),r);return{start:i,end:i+n}};function Vg(){let e=(0,U.useRef)(null),t=bu(e),n=zg(e=>e.step),r=zg(e=>e.selectedCode),i=zg(e=>e.scrollOffset),a=Mm(e=>e.quotePollIntervalMs),o=zg(e=>e.moveSelection),s=ih(),c=t.hasMeasured?Math.max(1,Math.floor(t.height)):1,l=n.type===`table`?Bg(n.rows.length,i,c):{start:0,end:0};(0,U.useEffect)(()=>{zg.setState({step:{type:`loading`}})},[]);let{refresh:u}=Mg(e=>zg.getState().refreshQuotes(e),{intervalMs:a});return mu((e,t)=>{if(!t.ctrl){if(t.upArrow)o(-1,c);else if(t.downArrow)o(1,c);else if(t.return){let e=zg.getState();if(e.step.type!==`table`||!e.selectedCode)return;let t=e.step.rows.find(t=>t.code===e.selectedCode);t&&rh.getState().open(t.code,t.name)}else e===`r`&&u()}},{isActive:!s}),{rowsRef:e,step:n,selectedCode:r,window:l}}function Hg({title:e,hint:t}){let n=ih(),r=Nm(),i=Mm(e=>e.trendColorMode),{rowsRef:a,step:o,selectedCode:s,window:c}=Vg(),l;switch(o.type){case`loading`:l=(0,Q.jsx)($,{color:`cyan`,children:`正在获取行情数据...`});break;case`empty`:l=(0,Q.jsx)($,{color:`yellow`,children:`自选股为空, 按 esc 打开菜单添加自选股.`});break;case`error`:l=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)($,{color:`red`,children:o.message}),(0,Q.jsx)($,{color:`gray`,children:`行情接口异常, 稍后自动重试`})]});break;case`table`:l=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(yg,{segments:Cg(Og)}),(0,Q.jsx)(pl,{ref:a,flexDirection:`column`,flexGrow:1,overflow:`hidden`,children:o.rows.slice(c.start,c.end).map(e=>(0,Q.jsx)(yg,{segments:e.kind===`quote`?wg(Og,e.quote,i):Tg(Og,e.code,e.name),selected:e.code===s},e.code))}),o.errorLine?(0,Q.jsxs)($,{color:`yellow`,children:[`刷新失败: `,o.errorLine,`, 稍后自动重试`]}):void 0]})}return(0,Q.jsx)(sh,{fullScreen:!0,bright:!n,title:(0,Q.jsx)($,{color:r.primary,children:e}),footer:(0,Q.jsx)(fh,{hint:t,bright:!n}),children:l})}var Ug={loadStocks:sg,stocksRemove:lg},Wg={error:void 0,resetToken:0};function Gg(e=Ug){let t=0,n=e=>e!==t;return vm()((r,i)=>({step:{type:`loading`},indexInput:Wg,confirmInput:Wg,loadEntries:async()=>{let i=++t;r({step:{type:`loading`},indexInput:Wg,confirmInput:Wg});try{let t=await e.loadStocks();if(n(i))return;r({step:t.length===0?{type:`error`,message:`自选股为空, 请先添加股票.`}:{type:`select`,entries:t}})}catch(e){n(i)||r({step:{type:`error`,message:Zm(e)}})}},handleChoice:e=>{let t=i().step;if(t.type!==`select`)return;let n=e.split(`,`).map(e=>e.trim()),a=n.map(e=>Number(e));if(n.length===0||n.some(e=>e===``)||a.some(e=>!Number.isInteger(e)||e<1||e>t.entries.length)){r(e=>({indexInput:{error:`无效的序号, 请输入 1-${t.entries.length}, 用英文逗号分隔.`,resetToken:e.indexInput.resetToken+1}}));return}let o=[...new Set(a)].map(e=>t.entries[e-1]);r(e=>({indexInput:{error:void 0,resetToken:e.indexInput.resetToken+1}})),r({step:{type:`confirm`,entries:o}})},handleConfirm:async a=>{let o=ug(a);if(!o){r(e=>({confirmInput:{error:dg,resetToken:e.confirmInput.resetToken+1}}));return}if(r(e=>({confirmInput:{error:void 0,resetToken:e.confirmInput.resetToken+1}})),o===`n`){r({step:{type:`done`,message:`已取消.`}});return}let s=t,c=i().step;if(c.type===`confirm`){r({step:{type:`removing`,entries:c.entries}});try{let t=await e.stocksRemove(c.entries.map(e=>e.code));if(n(s))return;if(t===0){r({step:{type:`error`,message:`所选 ${c.entries.length} 个条目已不在自选股中.`}});return}r({step:{type:`done`,message:`已删除 ${t} 个股票, ${c.entries.length-t} 个条目已不在自选股中.`}})}catch(e){n(s)||r({step:{type:`error`,message:`删除失败: ${Zm(e)}`}})}}}}))}var Kg=Gg();function qg(){let e=Kg(e=>e.step),t=Kg(e=>e.indexInput),n=Kg(e=>e.confirmInput),r=Kg(e=>e.handleChoice),i=Kg(e=>e.handleConfirm),a=Kg(e=>e.loadEntries);return(0,U.useEffect)(()=>{a()},[a]),{step:e,indexInput:t,confirmInput:n,handleChoice:r,handleConfirm:i,loadEntries:a}}function Jg({title:e,hint:t}){let n=ih(),r=Nm(),{step:i,indexInput:a,confirmInput:o,handleChoice:s,handleConfirm:c,loadEntries:l}=qg(),u;switch(i.type){case`loading`:u=(0,Q.jsx)($,{color:`cyan`,children:`正在加载自选股...`});break;case`select`:u=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)($,{color:`gray`,children:`自选股列表:`}),i.entries.map((e,t)=>(0,Q.jsxs)($,{children:[t+1,`) `,e.name,` (`,e.code,`) `,(0,Q.jsxs)($,{color:`gray`,children:[`(`,e.addedAt.slice(0,10),`)`]})]},e.code)),a.error&&(0,Q.jsx)($,{color:`red`,children:a.error}),(0,Q.jsx)(ql,{}),(0,Q.jsx)(Ch,{prompt:`请输入要删除的序号, 用英文逗号分隔: `,onSubmit:s})]});break;case`confirm`:u=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)($,{color:`yellow`,children:`确定删除以下股票?`}),i.entries.map(e=>(0,Q.jsxs)($,{children:[e.name,` (`,e.code,`)`]},e.code)),o.error&&(0,Q.jsx)($,{color:`red`,children:o.error}),(0,Q.jsx)(Ch,{prompt:`确认删除? (y/n): `,onSubmit:c},`confirm-${o.resetToken}`)]});break;case`removing`:u=(0,Q.jsxs)($,{color:`cyan`,children:[`正在删除 `,i.entries.length,` 个股票...`]});break;case`done`:u=(0,Q.jsx)(wh,{tone:`success`,msg:i.message,to:`stock-remove`,onReturn:l});break;case`error`:u=(0,Q.jsx)(wh,{tone:`error`,msg:i.message,to:`stock-remove`,onReturn:l})}return(0,Q.jsx)(sh,{fullScreen:!0,bright:!n,title:(0,Q.jsx)($,{color:r.primary,children:e}),footer:(0,Q.jsx)(fh,{hint:t,bright:!n}),children:u})}var Yg={"stock-list":{Component:Hg,title:`自选股票看板`,description:`自选股票看板 (默认, 自动刷新)`,hint:`菜单(esc) 刷新(r) 选择(↑/↓) 详情(enter) 退出(q)`,menuLabel:`自选股票看板`},"stock-add":{Component:vg,title:`添加自选股`,description:`添加自选股`,hint:`菜单(esc) 退出(q)`,menuLabel:`添加自选股`},"stock-remove":{Component:Jg,title:`删除自选股`,description:`删除自选股`,hint:`菜单(esc) 退出(q)`,menuLabel:`删除自选股`},settings:{Component:yh,title:`设置`,description:`配置主题, 涨跌颜色与请求参数`,hint:`菜单(esc) 选择(↑/↓) 调整(←/→/enter) 默认值(d) 退出(q)`,menuLabel:`设置`}},Xg=Object.keys(Yg),Zg=e=>e!==void 0&&Object.hasOwn(Yg,e),Qg=e=>Zg(e)?e:`stock-list`,$g=[...Object.entries(Yg).map(([e,t],n)=>({label:`${n+1}) ${t.menuLabel}`,screen:e})),{label:`${Object.keys(Yg).length+1}) 退出程序`,screen:void 0}],e_=45;function t_(){let e=bh(e=>e.goTo),t=Pm(e=>e.close),{exit:n}=hu(),[r,i]=(0,U.useState)(0),a=r=>{r.screen?(t(),e(r.screen)):n()};return mu((e,t)=>{if(t.upArrow)i(e=>(e+$g.length-1)%$g.length);else if(t.downArrow)i(e=>(e+1)%$g.length);else if(t.return)a($g[r]);else if(/^[1-9]$/.test(e)){let t=Number(e)-1,n=$g[t];if(!n)return;i(t),a(n)}}),{width:e_,menuItems:$g,highlight:r}}function n_(){let{highlight:e,width:t,menuItems:n}=t_(),r=Nm();return(0,Q.jsx)(ph,{title:(0,Q.jsx)($,{bright:!0,color:r.primary,children:`菜单`}),width:t,children:n.map((t,n)=>(0,Q.jsxs)($,{bright:!0,color:n===e?`black`:void 0,backgroundColor:n===e?r.highlight:void 0,children:[n===e?`> `:` `,t.label]},t.label))})}var r_=e=>{if(!/^\d{4}$/.test(e))return;let t=Number(e.slice(0,2))*60+Number(e.slice(2))-570;return t<0?0:t>120?t-90:t},i_=(e,t)=>{if(t<=0)return[];let n=Array.from({length:t},()=>({sum:0,count:0,minPrice:0,maxPrice:0,lastPrice:0,volume:0})),r=-1,i=0;for(let a of e){let e=r_(a.time);if(e===void 0)continue;let o=Math.min(t-1,Math.floor(e/240*t)),s=n[o];s.sum+=a.price,s.count+=1,s.minPrice=s.count===1?a.price:Math.min(s.minPrice,a.price),s.maxPrice=s.count===1?a.price:Math.max(s.maxPrice,a.price),s.lastPrice=a.price,s.volume+=Math.max(0,a.volume-i),i=a.volume,r=Math.max(r,o)}let a=[],o=0;for(let e=0;e<t;e++){let t=n[e];t.count>0?(o=t.lastPrice,a.push({avgPrice:t.sum/t.count,maxPrice:t.maxPrice,minPrice:t.minPrice,lastPrice:t.lastPrice,volume:t.volume})):e<r?a.push({avgPrice:o,maxPrice:o,minPrice:o,lastPrice:o,volume:0}):a.push({avgPrice:0,maxPrice:0,minPrice:0,lastPrice:0,volume:0})}return a},a_=e=>`date`in e,o_=e=>`sessionDate`in e,s_=e=>!a_(e)&&!o_(e),c_=(e,t)=>{let n=new Map;for(let t of e){let e=n.get(t.sessionDate)??[];e.push(t),n.set(t.sessionDate,e)}let r=[...n.entries()].sort(([e],[t])=>e.localeCompare(t));if(r.length===0)return Array.from({length:t},()=>({avgPrice:0,maxPrice:0,minPrice:0,lastPrice:0,volume:0}));let i=[];for(let e=0;e<r.length;e++){let n=Math.floor(e/r.length*t),a=Math.floor((e+1)/r.length*t)-n;if(a<=0)continue;let o=r[e][1].sort((e,t)=>e.time.localeCompare(t.time));i.push(...i_(o,a))}return i},l_=(e,t)=>e.length===0?Array.from({length:t},()=>({avgPrice:0,maxPrice:0,minPrice:0,lastPrice:0,volume:0})):Array.from({length:t},(n,r)=>{let i=t<=1?0:r/(t-1)*(e.length-1),a=e[Math.floor(i)],o=e[Math.min(Math.ceil(i),e.length-1)],s=i-Math.floor(i),c=a.close+(o.close-a.close)*s,l=e[Math.round(i)];return{avgPrice:c,maxPrice:Math.max(a.high,o.high),minPrice:Math.min(a.low,o.low),lastPrice:c,volume:l.volume}}),u_=(e,t)=>t<3?1<<t+e*3:1<<6+e,d_=e=>String.fromCharCode(10240+e),f_=e=>{let{points:t,period:n,prevClose:r,width:i,priceHeight:a,volumeHeight:o,trendColorMode:s=Sm}=e,c=t.filter(s_),l=t.filter(o_),u=t.filter(a_),d=n===`intraday`,f=n===`five-day`,p=d?i_(c,i):f?c_(l,i):l_(u,i),m=d?r:f?l[0]?.prevClose:u[0]?.close,h=d?r:void 0,g=1/0,_=-1/0;for(let e of p)e.avgPrice<=0||(g=Math.min(g,e.minPrice),_=Math.max(_,e.maxPrice));h!==void 0&&(g=Math.min(g,h),_=Math.max(_,h)),Number.isFinite(g)||(g=0,_=1),_===g&&(_+=1);let v=a*4,y=i*2,b=e=>Math.round((_-e)/(_-g)*(v-1)),x=(e,t)=>t===void 0?`gray`:Oh(e-t,s),S=x(p.map(e=>e.lastPrice).filter(e=>e>0).at(-1)??0,m),C=p.map((e,t)=>{if(d)return S;if(e.lastPrice<=0)return`gray`;let n=p[t+1]?.lastPrice;if(n!==void 0&&n>0)return x(n,e.lastPrice);let r=p[t-1]?.lastPrice;return x(e.lastPrice,r!==void 0&&r>0?r:void 0)}),w=Array.from({length:a+o+1},()=>Array.from({length:i},()=>({ch:` `,color:void 0}))),T=Array.from({length:a},()=>new Uint16Array(i)),E=-1;for(let e=0;e<i;e++)p[e].avgPrice>0&&(E=e);let D;for(let e=0;e<y;e++){let t=e/2;if(t>E){D=void 0;continue}let n=p[Math.floor(t)];if(n.avgPrice<=0){D=void 0;continue}let r=p[Math.min(Math.floor(t)+1,i-1)],a=b(r.avgPrice>0?n.lastPrice+(r.lastPrice-n.lastPrice)*(t-Math.floor(t)):n.lastPrice),o=Math.floor(e/2),s=T[Math.floor(a/4)];if(s[o]=s[o]|u_(e%2,a%4),D!==void 0){let t=Math.min(D,a),n=Math.max(D,a);for(let r=t+1;r<n;r++){let t=T[Math.floor(r/4)];t[o]=t[o]|u_(e%2,r%4)}}D=a}let O=Array.from({length:a},()=>new Uint16Array(i));if(h!==void 0){let e=b(h),t=Math.floor(e/4);for(let n=0;n<y;n++){if(n%3==2)continue;let r=Math.floor(n/2);if(T[t][r]!==0)continue;let i=O[t];i[r]=i[r]|u_(n%2,e%4)}}for(let e=0;e<a;e++)for(let t=0;t<i;t++){let n=T[e][t]|O[e][t];n!==0&&(w[e][t]={ch:d_(n),color:T[e][t]===0?`gray`:C[t]})}let k=Array.from({length:o},()=>new Uint16Array(i)),A=Math.max(...p.map(e=>e.volume),0);for(let e=0;e<i;e++){let t=p[e];if(t.volume<=0||A<=0)continue;let n=o*4,r=Math.max(1,Math.round(t.volume/A*n));for(let t=n-r;t<n;t++){let n=k[Math.floor(t/4)];n[e]=n[e]|u_(0,t%4)|u_(1,t%4)}}let j=Array.from({length:i},()=>void 0),M=m;for(let e=0;e<i;e++){let t=p[e];t.lastPrice<=0||(j[e]=M===void 0?`gray`:Oh(t.lastPrice-M,s),M=t.lastPrice)}for(let e=0;e<o;e++)for(let t=0;t<i;t++){let n=k[e][t];n!==0&&(w[a+e][t]={ch:d_(n),color:j[t]})}let N=[],P=(e,t)=>Math.max(0,Math.min(i-t.length,e-Math.floor(t.length/2)));if(d)N.push({col:0,labelCol:0,label:`09:30`},{col:Math.floor(i/2),labelCol:Math.max(0,Math.floor((i-11)/2)),label:`11:30/13:00`},{col:i-1,labelCol:Math.max(0,i-5),label:`15:00`});else if(f&&l.length>0){let e=[...new Set(l.map(e=>e.sessionDate))].sort();for(let t=0;t<e.length;t++){let n=Math.min(i-1,Math.floor((t+.5)/e.length*i)),r=e[t].slice(5);N.push({col:n,labelCol:P(n,r),label:r})}}else if(u.length>0){let e=e=>n===`year`?e.date.slice(0,4):n===`month`?e.date.slice(0,7):n===`week`?e.date.slice(2):e.date.slice(5),t=e(u[0]),r=e(u[Math.floor((u.length-1)/2)]),a=e(u.at(-1));N.push({col:0,labelCol:0,label:t},{col:Math.floor(i/2),labelCol:Math.max(0,Math.floor((i-r.length)/2)),label:r},{col:i-1,labelCol:Math.max(0,i-a.length),label:a})}for(let{col:e}of N)for(let t=0;t<a+o;t++)w[t][e].ch===` `&&(w[t][e]={ch:`┊`,color:`gray`});let F=w[a+o],I=(e,t)=>{for(let n=0;n<t.length&&e+n<i;n++)F[e+n]={ch:t[n],color:`gray`}};for(let e of N)I(e.labelCol,e.label);return w},p_=9,m_=4;function h_({points:e,period:t,prevClose:n,width:r,priceHeight:i=p_,volumeHeight:a=m_,bright:o=!1,trendColorMode:s}){let c=f_({points:e,period:t,prevClose:n,width:r,priceHeight:i,volumeHeight:a,trendColorMode:s});return(0,Q.jsx)(pl,{flexDirection:`column`,children:c.map((e,t)=>{let n=[];for(let t of e){let e=n.at(-1);e&&e.color===t.color?e.text+=t.ch:n.push({text:t.ch,color:t.color})}return(0,Q.jsx)($,{bright:o,children:n.map((e,t)=>(0,Q.jsx)($,{bright:o,color:e.color,children:e.text},t))},t)})})}var g_=new Map([[`sh`,`沪`],[`sz`,`深`],[`bj`,`北`]]);function __({code:e,bright:t=!1}){let n=e.slice(0,2).toLowerCase(),r=g_.get(n);if(r)return(0,Q.jsx)($,{bright:t,color:`white`,backgroundColor:`red`,children:r})}var v_=[{key:`1`,value:`intraday`,label:`分时`},{key:`2`,value:`five-day`,label:`五日`},{key:`3`,value:`day`,label:`日K`},{key:`4`,value:`week`,label:`周K`},{key:`5`,value:`month`,label:`月K`},{key:`6`,value:`year`,label:`年K`}];function y_(){let e=rh(e=>e.stock),t=rh(e=>e.period),n=rh(e=>e.status),r=rh(e=>e.points),i=rh(e=>e.errorMessage),a=Mm(e=>e.minuteChartPollIntervalMs),o=Mm(e=>e.klinePollIntervalMs),s=Pm(e=>e.open),c=zg(t=>{if(t.step.type!==`table`)return;let n=t.step.rows.find(t=>t.code===e?.code);return n?.kind===`quote`?n.quote:void 0});if(mu((e,t)=>{if(t.ctrl)return;let n=v_.find(t=>t.key===e);n&&rh.getState().setPeriod(n.value)},{isActive:e!==void 0&&!s}),Mg(async n=>{e&&await rh.getState().refreshChart(e.code,t,n)},{enabled:e!==void 0,intervalMs:t===`intraday`||t===`five-day`?a:o,restartKey:e?`${e.code}:${t}`:void 0}),e)return{stock:e,quote:c,suspended:c?c.current<=0:!1,period:t,status:n,points:r,errorMessage:i}}var b_=jg()+4+6,x_=b_-4;function S_(){let e=Mm(e=>e.trendColorMode),t=y_();if(!t)return;let{stock:n,quote:r,suspended:i,period:a,status:o,points:s,errorMessage:c}=t,l=v_.find(e=>e.value===a)?.label??``;return(0,Q.jsxs)(ph,{title:(0,Q.jsxs)($,{bright:!0,children:[(0,Q.jsx)(__,{code:n.code,bright:!0}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,children:n.name}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,color:`gray`,children:n.code}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,color:!r||i?`gray`:Oh(r.change,e),children:r?Th(r.current):`--`}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,color:!r||i?`gray`:Oh(r.changePercent,e),children:r?i?`停牌`:Dh(r.changePercent):`--`}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,color:!r||i?`gray`:Oh(r.change,e),children:r?Eh(r.change):`--`})]}),extra:(0,Q.jsx)($,{bright:!0,children:v_.map((e,t)=>(0,Q.jsxs)($,{bright:!0,color:e.value===a?`cyan`:`gray`,children:[t>0?` `:``,`[`,e.key,`]`,e.label]},e.value))}),width:b_,children:[(0,Q.jsxs)(pl,{flexDirection:`column`,children:[(0,Q.jsx)(yg,{bright:!0,segments:Cg(kg)}),(0,Q.jsx)(yg,{bright:!0,segments:r?wg(kg,r,e):Tg(kg,n.code,n.name)})]}),(0,Q.jsx)(pl,{marginTop:1,height:14,children:o===`loading`?(0,Q.jsxs)($,{bright:!0,color:`gray`,children:[`正在获取`,l,`行情...`]}):o===`error`?(0,Q.jsx)($,{bright:!0,color:`red`,children:c}):s.length===0?(0,Q.jsxs)($,{bright:!0,color:`gray`,children:[`暂无`,l,`行情数据`]}):(0,Q.jsx)(h_,{bright:!0,points:s,period:a,prevClose:r?.prevClose,trendColorMode:e,width:x_})})]})}var C_=Ag()+4;function w_({children:e}){let{columns:t,rows:n}=_u(),r=t>=C_,i=n>=26;return r&&i?e:(0,Q.jsxs)(pl,{width:t,height:n,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,children:[(0,Q.jsx)($,{color:`yellow`,children:`终端尺寸过小:`}),(0,Q.jsxs)(pl,{children:[(0,Q.jsx)($,{color:r?`green`:`red`,children:`宽度 = ${t}`}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{color:i?`green`:`red`,children:`高度 = ${n}`})]}),(0,Q.jsx)(pl,{height:1}),(0,Q.jsx)($,{color:`gray`,children:`所需最小尺寸:`}),(0,Q.jsx)($,{color:`gray`,children:`宽度 = ${C_} 高度 = 26`})]})}function T_(){let{exit:e}=hu(),t=ih(),n=bh(e=>e.screen),r=Pm(e=>e.open),i=Pm(e=>e.toggle),a=rh(e=>e.stock),o=rh(e=>e.close),s=Yg[n];return mu((n,r)=>{r.escape?a?o():i():n===`q`&&!t&&e()}),(0,Q.jsxs)(w_,{children:[(0,Q.jsx)(s.Component,{title:s.title,hint:s.hint}),r&&(0,Q.jsx)(n_,{}),a&&(0,Q.jsx)(S_,{})]})}var E_=100,D_=e=>Object.keys(e).length>0;async function O_(e){let t=await ig();Mm.getState().hydrateSettings(Gh(t));let n={},r,i,a=Promise.resolve(),o=async()=>{if(!D_(n))return;let t=n;n={};try{await og(t),r=void 0}catch(i){n={...t,...n},r=i;try{e(i)}catch{}}},s=()=>(i&&=(clearTimeout(i),void 0),a=a.then(o),a),c=()=>{i&&clearTimeout(i),i=setTimeout(()=>{i=void 0,s()},E_)},l=Mm.subscribe((e,t)=>{Am(e,t)||(n={...n,...jm(e,t)},c())}),u,d=async()=>(l(),await s(),r&&D_(n)&&await o(),r===void 0);return{stop:()=>u??=d()}}var k_=fm(`
151
- 用法
150
+ `;let s=e=>{console.log(o),n.exit(typeof e==`number`?e:2)},c=()=>{console.log(r.version),n.exit(0)};a._.length===0&&r.argv.length===1&&(a.version===!0&&r.autoVersion?c():a.help===!0&&r.autoHelp&&s(0));let{command:l,input:u}=um(a._,r,i,s);if(delete a._,!r.allowUnknownFlags&&!r.commands){let e=u,t=r.argv.indexOf(`--`);t!==-1&&!Object.hasOwn(r.flags,`--`)&&(e=Iu(r.argv.slice(0,t),i)._),nm(e)}let d=ld(a,{exclude:[`--`,/^\w$/]}),f={...d};$p(d,r);for(let e of Object.values(r.flags)){if(Array.isArray(e.aliases))for(let t of e.aliases)delete d[t];delete d[e.shortFlag]}return om(r.flags,d,u),am(r,u),{input:u,command:l,flags:d,unnormalizedFlags:f,get pkg(){return t?t():e},help:o,showHelp:s,showVersion:c}},fm=(e,t={})=>{let r=Kp(e,t),i=dm(r,Yp(r));return n.title=cm(r.pkg),i},pm=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e))},o=t=e(r,i,a);return a},mm=(e=>e?pm(e):pm),hm=e=>e;function gm(e,t=hm){let n=U.useSyncExternalStore(e.subscribe,U.useCallback(()=>t(e.getState()),[e,t]),U.useCallback(()=>t(e.getInitialState()),[e,t]));return U.useDebugValue(n),n}var _m=e=>{let t=mm(e),n=e=>gm(t,e);return Object.assign(n,t),n},vm=(e=>e?_m(e):_m),ym=[`single`,`double`,`round`,`bold`,`singleDouble`,`doubleSingle`,`classic`,`arrow`],bm=[`red-up`,`green-up`],xm={"red-up":`涨红跌绿`,"green-up":`涨绿跌红`},Sm=`red-up`,Cm={classic:{label:`经典紫蓝`,primary:`magenta`,accent:`blue`,highlight:`cyan`,foreground:`white`},ocean:{label:`海洋青蓝`,primary:`cyan`,accent:`blue`,highlight:`cyan`,foreground:`white`},forest:{label:`森林绿`,primary:`green`,accent:`green`,highlight:`green`,foreground:`white`},sunset:{label:`日落黄红`,primary:`yellow`,accent:`red`,highlight:`yellow`,foreground:`white`},gray:{label:`低调灰`,primary:`gray`,accent:`gray`,highlight:`gray`,foreground:`white`}},wm=Object.keys(Cm),Tm={requestTimeoutMs:{min:1e3,max:6e4,step:1e3},minimumRequestDurationMs:{min:0,max:5e3,step:250},quotePollIntervalMs:{min:1e3,max:6e4,step:500},minuteChartPollIntervalMs:{min:5e3,max:3e5,step:5e3},klinePollIntervalMs:{min:3e4,max:18e5,step:3e4}},Em={themePreset:`classic`,trendColorMode:Sm,borderStyle:`round`,requestTimeoutMs:8e3,minimumRequestDurationMs:0,quotePollIntervalMs:5e3,minuteChartPollIntervalMs:3e4,klinePollIntervalMs:3e5},Dm=(e,t,n)=>Math.min(n,Math.max(t,Math.round(e))),Om=e=>{let t=Dm(e.requestTimeoutMs,Tm.requestTimeoutMs.min,Tm.requestTimeoutMs.max);return{...e,requestTimeoutMs:t,minimumRequestDurationMs:Math.min(t,Dm(e.minimumRequestDurationMs,Tm.minimumRequestDurationMs.min,Tm.minimumRequestDurationMs.max)),quotePollIntervalMs:Dm(e.quotePollIntervalMs,Tm.quotePollIntervalMs.min,Tm.quotePollIntervalMs.max),minuteChartPollIntervalMs:Dm(e.minuteChartPollIntervalMs,Tm.minuteChartPollIntervalMs.min,Tm.minuteChartPollIntervalMs.max),klinePollIntervalMs:Dm(e.klinePollIntervalMs,Tm.klinePollIntervalMs.min,Tm.klinePollIntervalMs.max)}},km=e=>({themePreset:e.themePreset,trendColorMode:e.trendColorMode,borderStyle:e.borderStyle,requestTimeoutMs:e.requestTimeoutMs,minimumRequestDurationMs:e.minimumRequestDurationMs,quotePollIntervalMs:e.quotePollIntervalMs,minuteChartPollIntervalMs:e.minuteChartPollIntervalMs,klinePollIntervalMs:e.klinePollIntervalMs}),Am=(e,t)=>e.themePreset===t.themePreset&&e.trendColorMode===t.trendColorMode&&e.borderStyle===t.borderStyle&&e.requestTimeoutMs===t.requestTimeoutMs&&e.minimumRequestDurationMs===t.minimumRequestDurationMs&&e.quotePollIntervalMs===t.quotePollIntervalMs&&e.minuteChartPollIntervalMs===t.minuteChartPollIntervalMs&&e.klinePollIntervalMs===t.klinePollIntervalMs,jm=(e,t)=>{let n={};return e.themePreset!==t.themePreset&&(n.themePreset=e.themePreset),e.trendColorMode!==t.trendColorMode&&(n.trendColorMode=e.trendColorMode),e.borderStyle!==t.borderStyle&&(n.borderStyle=e.borderStyle),e.requestTimeoutMs!==t.requestTimeoutMs&&(n.requestTimeoutMs=e.requestTimeoutMs),e.minimumRequestDurationMs!==t.minimumRequestDurationMs&&(n.minimumRequestDurationMs=e.minimumRequestDurationMs),e.quotePollIntervalMs!==t.quotePollIntervalMs&&(n.quotePollIntervalMs=e.quotePollIntervalMs),e.minuteChartPollIntervalMs!==t.minuteChartPollIntervalMs&&(n.minuteChartPollIntervalMs=e.minuteChartPollIntervalMs),e.klinePollIntervalMs!==t.klinePollIntervalMs&&(n.klinePollIntervalMs=e.klinePollIntervalMs),n},Mm=vm()(e=>({...Em,updateSettings:t=>e(e=>Om({...km(e),...t})),adjustNumericSetting:(t,n)=>e(e=>{let r=Tm[t],i=Dm(e[t]+r.step*n,r.min,r.max);return Om({...km(e),[t]:i})}),resetSettings:()=>e(Em),hydrateSettings:t=>e(Om(t))}));function Nm(){return Mm(e=>Cm[e.themePreset])}var Pm=vm()(e=>({open:!1,toggle:()=>e(e=>({open:!e.open})),close:()=>e({open:!1})})),Fm=e=>typeof e==`object`&&e?e:void 0,Im=(e,t)=>{let n=Number.parseFloat(e[t]??``);return Number.isFinite(n)?n:0},Lm=e=>{let t=Number.parseFloat(typeof e==`string`||typeof e==`number`?String(e):``);return Number.isFinite(t)?t:0},Rm=e=>{if(!Array.isArray(e))return[];let t=[];for(let n of e){if(typeof n!=`string`)continue;let[e=``,r=``,i=``]=n.split(` `);if(!/^(?:[01]\d|2[0-3])[0-5]\d$/.test(e)||e>`1500`)continue;let a=Number.parseFloat(r);if(!Number.isFinite(a)||a<=0)continue;let o=Number.parseFloat(i);t.push({time:e,price:a,volume:Number.isFinite(o)?o:0})}return t};function zm(e){let t=[];for(let n of e.split(`;`)){let e=/^v_([a-z]{2}\d{6})="([^"]*)"/.exec(n.trim());if(!e)continue;let r=e[2].split(`~`);if(r.length<50)continue;let i=r[1].trim();i&&t.push({code:e[1],name:i,current:Im(r,3),prevClose:Im(r,4),open:Im(r,5),high:Im(r,33),low:Im(r,34),change:Im(r,31),changePercent:Im(r,32),timestamp:r[30],volume:Im(r,36),turnover:Im(r,37),turnoverRate:Im(r,38),amplitude:Im(r,43),marketCap:Im(r,45),volumeRatio:Im(r,49)})}if(t.length===0)throw Error(`未查询到任何行情数据, 请检查股票代码`);return t}function Bm(e,t){return Rm(Fm(Fm(Fm(Fm(e)?.data)?.[t])?.data)?.data)}function Vm(e,t){let n=Fm(Fm(Fm(e)?.data)?.[t])?.data;return Array.isArray(n)?n.flatMap(e=>{let t=Fm(e),n=t?.date;if(typeof n!=`string`||!/^\d{8}$/.test(n))return[];let r=`${n.slice(0,4)}-${n.slice(4,6)}-${n.slice(6,8)}`,i=Lm(t?.prec);return[{sessionDate:r,points:Rm(t?.data).map(e=>({...e,sessionDate:r,prevClose:i}))}]}).sort((e,t)=>e.sessionDate.localeCompare(t.sessionDate)).slice(-5).flatMap(e=>e.points):[]}function Hm(e,t,n=`day`,r=`qfq`){let i=Fm(Fm(Fm(e)?.data)?.[t]),a=i?.[`${r}${n}`],o=Array.isArray(a)&&a.length>0?a:i?.[n];if(!Array.isArray(o))return[];let s=[];for(let e of o){if(!Array.isArray(e))continue;let[t,n,r,i,a,o]=e;if(typeof t!=`string`||!/^\d{4}-\d{2}-\d{2}$/.test(t))continue;let c=Lm(n),l=Lm(r),u=Lm(i),d=Lm(a),f=Lm(o);[c,l,u,d].some(e=>e<=0)||s.push({date:t,open:c,close:l,high:u,low:d,volume:Math.max(0,f)})}return s}var Um=(e,t)=>e<=0?Promise.resolve():t?.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let i=setTimeout(()=>{t?.removeEventListener(`abort`,a),n()},e),a=()=>{clearTimeout(i),r(t?.reason)};t?.addEventListener(`abort`,a,{once:!0})}),Wm=async(e,t)=>{let{requestTimeoutMs:n,minimumRequestDurationMs:r}=Mm.getState(),i=AbortSignal.timeout(n),a=e?AbortSignal.any([e,i]):i,o=Date.now(),s=await t(a);return await Um(r-(Date.now()-o),e),s};function Gm(e){let t=e.trim().toUpperCase();if(t=t.replace(/\.(SH|SZ|BJ)$/,``),t=t.replace(/^(SH|SZ|BJ)/,``),!/^\d{6}$/.test(t))return;let n;if(t.startsWith(`6`)||t.startsWith(`5`))n=`sh`;else if(t.startsWith(`0`)||t.startsWith(`1`)||t.startsWith(`3`))n=`sz`;else if(t.startsWith(`4`)||t.startsWith(`8`)||t.startsWith(`92`))n=`bj`;else return;return`${n}${t}`}async function Km(e,t){return e.length===0?[]:Wm(t,async t=>{let n=await fetch(`https://qt.gtimg.cn/q=${e.join(`,`)}`,{signal:t});if(!n.ok)throw Error(`行情接口请求失败: HTTP ${n.status}`);let r=await n.arrayBuffer();return zm(new TextDecoder(`gbk`).decode(r))})}async function qm(e,t){return Wm(t,async t=>{let n=await fetch(`https://web.ifzq.gtimg.cn/appstock/app/minute/query?code=${e}`,{signal:t});if(!n.ok)throw Error(`分时接口请求失败: HTTP ${n.status}`);return Bm(await n.json(),e)})}async function Jm(e,t){return Wm(t,async t=>{let n=await fetch(`https://web.ifzq.gtimg.cn/appstock/app/day/query?code=${e}`,{signal:t});if(!n.ok)throw Error(`五日行情接口请求失败: HTTP ${n.status}`);return Vm(await n.json(),e)})}var Ym=e=>{let t=new Map;for(let n of[...e].sort((e,t)=>e.date.localeCompare(t.date))){let e=n.date.slice(0,4),r=t.get(e);if(!r){t.set(e,{...n});continue}r.date=n.date,r.close=n.close,r.high=Math.max(r.high,n.high),r.low=Math.min(r.low,n.low),r.volume+=n.volume}return[...t.values()]};async function Xm(e,t){return Wm(t.signal,async n=>{let r=t.period===`year`?`month`:t.period,i=t.period===`year`?`hfq`:`qfq`,a=t.period===`year`?t.barCount*12:t.barCount,o=encodeURIComponent(`${e},${r},,,${a},${i}`),s=await fetch(`https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?param=${o}`,{signal:n});if(!s.ok)throw Error(`K 线行情接口请求失败: HTTP ${s.status}`);let c=Hm(await s.json(),e,r,i);return(t.period===`year`?Ym(c):c).slice(-t.barCount)})}function Zm(e){return e instanceof Error?e.message:String(e)}var Qm={day:{barCount:60},week:{barCount:60},month:{barCount:60},year:{barCount:30}},$m=`intraday`,eh=e=>e!==`intraday`&&e!==`five-day`,th={fetchIntraday:qm,fetchFiveDay:Jm,fetchHistorical:Xm};function nh(e=th){return vm()((t,n)=>({stock:void 0,period:$m,status:`loading`,points:[],open:(e,n)=>t({stock:{code:e,name:n},period:$m,status:`loading`,points:[],errorMessage:void 0}),close:()=>t({stock:void 0}),setPeriod:e=>{n().period!==e&&t({period:e,status:`loading`,points:[],errorMessage:void 0})},refreshChart:async(r,i,a)=>{try{let o;if(i===`intraday`)o=await e.fetchIntraday(r,a);else if(i===`five-day`)o=await e.fetchFiveDay?.(r,a);else if(eh(i)){let t=Qm[i];o=await e.fetchHistorical?.(r,{period:i,...t,signal:a})}if(!o)throw Error(`${i===`five-day`?`五日`:`K 线`}行情数据源不可用`);if(n().stock?.code!==r||n().period!==i||a?.aborted)return;t({status:`ready`,points:o,errorMessage:void 0})}catch(e){if(n().stock?.code!==r||n().period!==i||a?.aborted)return;t({status:`error`,errorMessage:Zm(e)})}}}))}var rh=nh();function ih(){let e=Pm(e=>e.open),t=rh(e=>e.stock!==void 0);return e||t}var ah=z((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),Q=z(((e,t)=>{t.exports=ah()}))();function $({bright:e=!1,color:t,...n}){let r=ih(),i=Nm(),a=!e&&r;return(0,Q.jsx)(ml,{...n,color:t??i.foreground,dimColor:a})}function oh({title:e,bright:t=!1,top:n,left:r,right:i}){return(0,Q.jsxs)(pl,{position:`absolute`,top:n,left:r,right:i,children:[(0,Q.jsx)($,{bright:t,children:`|`}),e,(0,Q.jsx)($,{bright:t,children:`|`})]})}function sh(e){let{bright:t=!1,fullScreen:n,title:r,extra:i,footer:a,children:o}=e,{width:s,height:c,backgroundColor:l}=e,{columns:u,rows:d}=_u(),f=Mm(e=>e.borderStyle),p=Nm();return(0,Q.jsxs)(pl,{flexDirection:`column`,width:n?u:s,height:n?d:c,borderStyle:f,borderColor:p.primary,borderDimColor:t===!1,children:[r?(0,Q.jsx)(oh,{title:r,bright:t,top:-1,left:1}):void 0,i?(0,Q.jsx)(oh,{title:i,bright:t,top:-1,right:1}):void 0,(0,Q.jsx)(pl,{flexGrow:1,flexDirection:`column`,padding:1,backgroundColor:l,children:o}),a]})}var ch=new Intl.DateTimeFormat(`en-CA`,{timeZone:`Asia/Shanghai`,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1});function lh(e,t){let n=ch.formatToParts(e),r=e=>n.find(t=>t.type===e)?.value??``,i=`${r(`year`)}-${r(`month`)}-${r(`day`)}`,a=`${r(`hour`)}:${r(`minute`)}`;switch(t){case`date-time`:return`${i} ${a}:${r(`second`)}`;case`date`:return i;case`time`:return`${a}:${r(`second`)}`;case`hour-minute`:return a}}var uh={"date-time":1e3,date:6e4,time:1e3,"hour-minute":6e4};function dh(e){let[t,n]=(0,U.useState)(()=>new Date);return(0,U.useEffect)(()=>{let t=setInterval(()=>n(new Date),uh[e]);return()=>clearInterval(t)},[e]),lh(t,e)}function fh(e){let{hint:t,bright:n=!1}=e,r=dh(`date-time`),i=Nm();return(0,Q.jsxs)(pl,{justifyContent:`space-between`,paddingX:1,backgroundColor:n?i.accent:`gray`,children:[(0,Q.jsx)(pl,{flexShrink:0,children:t&&(0,Q.jsx)($,{bright:n,color:`white`,children:t})}),(0,Q.jsx)(pl,{flexShrink:0,children:(0,Q.jsx)($,{bright:n,color:`white`,children:r})})]})}function ph(e){let{title:t,extra:n,width:r,children:i}=e,{rows:a,columns:o}=_u();return(0,Q.jsx)(pl,{position:`absolute`,top:0,left:0,width:o,height:a,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,children:(0,Q.jsx)(sh,{bright:!0,title:t,extra:n,width:r,backgroundColor:`black`,footer:(0,Q.jsx)(fh,{bright:!0}),children:i})})}var mh=[{type:`theme`,label:`主题色系`,description:`界面配色`},{type:`trendColor`,label:`涨跌颜色`,description:`选择涨绿或跌绿`},{type:`border`,label:`卡片边框`,description:`边框样式`},{type:`numeric`,label:`请求超时`,description:`单次请求最长等待`,setting:`requestTimeoutMs`},{type:`numeric`,label:`请求最短耗时`,description:`避免加载闪烁`,setting:`minimumRequestDurationMs`},{type:`numeric`,label:`看板刷新间隔`,description:`自选股票看板自动刷新频率`,setting:`quotePollIntervalMs`},{type:`numeric`,label:`分时图刷新间隔`,description:`分时与五日图自动刷新频率`,setting:`minuteChartPollIntervalMs`},{type:`numeric`,label:`K 线刷新间隔`,description:`日/周/月/年 K 线自动刷新频率`,setting:`klinePollIntervalMs`}],hh=(e,t,n)=>e[(e.indexOf(t)+n+e.length)%e.length]??t,gh=e=>e===0?`关闭`:e<1e3?`${e} ms`:e%6e4==0?`${e/6e4} 分钟`:e%1e3==0?`${e/1e3} 秒`:`${(e/1e3).toFixed(2)} 秒`;function _h(){let[e,t]=(0,U.useState)(0),n=ih(),r=Mm(),i=t=>{let n=mh[e];n&&(n.type===`theme`?r.updateSettings({themePreset:hh(wm,r.themePreset,t)}):n.type===`trendColor`?r.updateSettings({trendColorMode:hh(bm,r.trendColorMode,t)}):n.type===`border`?r.updateSettings({borderStyle:hh(ym,r.borderStyle,t)}):r.adjustNumericSetting(n.setting,t))};mu((e,n)=>{n.ctrl||(n.upArrow?t(e=>(e-1+mh.length)%mh.length):n.downArrow?t(e=>(e+1)%mh.length):n.leftArrow?i(-1):n.rightArrow||n.return?i(1):e===`d`&&r.resetSettings())},{isActive:!n});let a=mh.map((t,n)=>({label:t.label,description:t.description,selected:n===e,value:t.type===`theme`?Cm[r.themePreset].label:t.type===`trendColor`?xm[r.trendColorMode]:t.type===`border`?r.borderStyle:gh(r[t.setting])}));return{overlayOpen:n,appearanceRows:a.slice(0,3),requestRows:a.slice(3)}}function vh({rows:e,highlight:t}){return e.map(e=>(0,Q.jsxs)(pl,{justifyContent:`space-between`,children:[(0,Q.jsxs)($,{color:e.selected?`black`:void 0,backgroundColor:e.selected?t:void 0,children:[e.selected?`› `:` `,e.label,(0,Q.jsxs)($,{color:`gray`,backgroundColor:e.selected?t:void 0,children:[`(`,e.description,`)`]})]}),(0,Q.jsx)($,{color:e.selected?t:`gray`,children:e.value})]},e.label))}function yh({title:e,hint:t}){let n=Nm(),{overlayOpen:r,appearanceRows:i,requestRows:a}=_h();return(0,Q.jsxs)(sh,{fullScreen:!0,bright:!r,title:(0,Q.jsx)($,{color:n.primary,children:e}),footer:(0,Q.jsx)(fh,{hint:t,bright:!r}),children:[(0,Q.jsx)($,{color:n.primary,children:`外观`}),(0,Q.jsx)(vh,{rows:i,highlight:n.highlight}),(0,Q.jsxs)(pl,{marginTop:1,flexDirection:`column`,children:[(0,Q.jsx)($,{color:n.primary,children:`请求与刷新`}),(0,Q.jsx)(vh,{rows:a,highlight:n.highlight})]}),(0,Q.jsx)(pl,{marginTop:1,flexDirection:`column`,children:(0,Q.jsx)($,{color:`gray`,children:`请求最短耗时用于避免加载状态闪烁, 且不会超过请求超时.`})})]})}var bh=vm()(e=>({screen:`stock-list`,goTo:t=>e({screen:t})})),xh={error:`red`,warning:`yellow`,success:`green`};function Sh({tone:e,msg:t}){return(0,Q.jsx)($,{bold:!0,color:xh[e],children:t})}function Ch({prompt:e,onSubmit:t,placeholder:n}){let r=ih(),[i,a]=(0,U.useState)(``),[o,s]=(0,U.useState)(!1);return mu((e,n)=>{o||(n.return?(s(!0),t(i)):n.backspace||n.delete?a(e=>e.slice(0,-1)):!n.ctrl&&!n.meta&&e&&a(t=>t+e))},{isActive:!r&&!o}),(0,Q.jsx)(pl,{children:(0,Q.jsxs)($,{children:[e,o?(0,Q.jsx)($,{color:`green`,children:i}):(0,Q.jsxs)($,{children:[i,(0,Q.jsx)($,{color:`gray`,children:`█`}),!i&&n?n:void 0]})]})})}function wh({tone:e,msg:t,to:n,onReturn:r}){let i=bh(e=>e.goTo);return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(Sh,{tone:e,msg:t}),(0,Q.jsx)(ql,{}),(0,Q.jsx)(Ch,{prompt:`按 Enter 返回操作页...`,onSubmit:()=>{r?.(),i(n)}})]})}var Th=e=>e>0?e.toFixed(2):`--`,Eh=e=>`${e>0?`+`:``}${e.toFixed(2)}`,Dh=e=>`${e>0?`+`:``}${e.toFixed(2)}%`,Oh=(e,t=Sm)=>e===0?`gray`:e>0==(t===`green-up`)?`green`:`red`,kh=e=>e>=1e4?`${(e/1e4).toFixed(1)}万手`:e>0?`${Math.round(e)}手`:`--`,Ah=e=>e>=1e4?`${(e/1e4).toFixed(2)}亿`:e>0?`${e.toFixed(1)}万`:`--`,jh=e=>e>0?`${e.toFixed(2)}%`:`--`,Mh=e=>e>0?e.toFixed(2):`--`,Nh=e=>e>0?`${e.toFixed(2)}亿`:`--`,Ph=/^(?:sh|sz|bj)\d{6}$/,Fh=(e,t)=>{if(typeof e!=`object`||!e)throw Error(`第 ${t+1} 项不是对象`);let n=e;if(typeof n.code!=`string`||!Ph.test(n.code))throw Error(`第 ${t+1} 项 code 无效`);if(typeof n.name!=`string`||n.name.trim()===``)throw Error(`第 ${t+1} 项 name 无效`);if(typeof n.addedAt!=`string`||!Number.isFinite(Date.parse(n.addedAt)))throw Error(`第 ${t+1} 项 addedAt 无效`);return{code:n.code,name:n.name,addedAt:n.addedAt}};function Ih(e){if(!Array.isArray(e))throw Error(`stocks 不是数组`);let t=e.map(Fh),n=new Set;for(let[e,r]of t.entries()){if(n.has(r.code))throw Error(`第 ${e+1} 项 code 重复: ${r.code}`);n.add(r.code)}return t}var Lh=25,Rh=2e3,zh=3e4,Bh=e=>typeof e==`object`&&!!e&&!Array.isArray(e),Vh=e=>{if(typeof e!=`string`||!wm.includes(e))throw Error(`theme.preset 无效`);return e},Hh=e=>{if(e===void 0)return Sm;if(typeof e!=`string`||!bm.includes(e))throw Error(`theme.trendColorMode 无效`);return e},Uh=(e,t,n)=>{if(typeof e!=`number`||!Number.isInteger(e)||e<n.min||e>n.max)throw Error(`${t} 无效`);return e};function Wh(e){if(!Bh(e))throw Error(`顶层数据不是对象`);let t=e.theme;if(!Bh(t))throw Error(`theme 无效`);let n=t.borderStyle;if(typeof n!=`string`||!ym.includes(n))throw Error(`theme.borderStyle 无效`);let r=e.request;if(!Bh(r))throw Error(`request 无效`);let i=Uh(r.timeoutMs,`request.timeoutMs`,Tm.requestTimeoutMs),a=Uh(r.minimumDurationMs,`request.minimumDurationMs`,Tm.minimumRequestDurationMs);if(a>i)throw Error(`request.minimumDurationMs 不能大于 request.timeoutMs`);return{theme:{preset:Vh(t.preset),trendColorMode:Hh(t.trendColorMode),borderStyle:n},request:{timeoutMs:i,minimumDurationMs:a,quotePollIntervalMs:Uh(r.quotePollIntervalMs,`request.quotePollIntervalMs`,Tm.quotePollIntervalMs),minuteChartPollIntervalMs:Uh(r.minuteChartPollIntervalMs,`request.minuteChartPollIntervalMs`,Tm.minuteChartPollIntervalMs),klinePollIntervalMs:Uh(r.klinePollIntervalMs,`request.klinePollIntervalMs`,Tm.klinePollIntervalMs)},stocks:Ih(e.stocks)}}function Gh(e){return{themePreset:e.theme.preset,trendColorMode:e.theme.trendColorMode,borderStyle:e.theme.borderStyle,requestTimeoutMs:e.request.timeoutMs,minimumRequestDurationMs:e.request.minimumDurationMs,quotePollIntervalMs:e.request.quotePollIntervalMs,minuteChartPollIntervalMs:e.request.minuteChartPollIntervalMs,klinePollIntervalMs:e.request.klinePollIntervalMs}}var Kh=[{code:`sz002156`,name:`富通微电`},{code:`sh600584`,name:`长电科技`},{code:`sh688825`,name:`长鑫科技`}],qh=()=>{let e=new Date().toISOString();return Kh.map(t=>({...t,addedAt:e}))},Jh=(e,t)=>({theme:{preset:e.themePreset,trendColorMode:e.trendColorMode,borderStyle:e.borderStyle},request:{timeoutMs:e.requestTimeoutMs,minimumDurationMs:e.minimumRequestDurationMs,quotePollIntervalMs:e.quotePollIntervalMs,minuteChartPollIntervalMs:e.minuteChartPollIntervalMs,klinePollIntervalMs:e.klinePollIntervalMs},stocks:t}),Yh=()=>{let e=n.env.XDG_CONFIG_HOME??C(c(),`.config`);return C(e,`leek-box-cli`)};function Xh(){return C(Yh(),`settings.json`)}var Zh=async e=>{try{return JSON.parse(await A(e,`utf8`))}catch(e){if(e.code===`ENOENT`)return;throw e}},Qh=async()=>{let e=Xh();try{let t=await Zh(e);return t===void 0?void 0:Wh(t)}catch(t){let n=t instanceof Error?t.message:String(t);throw Error(`设置文件损坏: ${e} (${n})`)}},$h=async e=>{let t=Wh(e),r=Xh();await k(S(r),{recursive:!0});let i=`${r}.${n.pid}.${D()}.tmp`;try{await P(i,`${JSON.stringify(t,null,2)}\n`,`utf8`),await j(i,r)}finally{await M(i,{force:!0})}},eg=e=>new Promise(t=>setTimeout(t,e)),tg=e=>{try{return n.kill(e,0),!0}catch(e){return e.code!==`ESRCH`}},ng=async e=>{let t;try{t=await A(e,`utf8`)}catch(e){if(e.code===`ENOENT`)return!0;throw e}let n=!1;try{let e=JSON.parse(t);if(!Bh(e)||typeof e.token!=`string`||typeof e.pid!=`number`||!Number.isInteger(e.pid)||e.pid<=0||typeof e.createdAt!=`number`||!Number.isFinite(e.createdAt))throw Error(`lock metadata 无效`);n=!tg(e.pid)||Date.now()-e.createdAt>=zh}catch{try{let t=await N(e);n=Date.now()-t.mtimeMs>=Rh}catch(e){if(e.code===`ENOENT`)return!0;throw e}}if(!n)return!1;try{return await A(e,`utf8`)===t&&(await M(e),!0)}catch(e){if(e.code===`ENOENT`)return!0;throw e}},rg=async(e,t)=>{let r=`${e}.${n.pid}.${D()}.tmp`;try{await P(r,t,{encoding:`utf8`,flag:`wx`}),await O(r,e)}finally{await M(r,{force:!0})}};async function ig(e){let t=Xh(),r=`${t}.lock`,i=D(),a=JSON.stringify({token:i,pid:n.pid,createdAt:Date.now()});await k(S(t),{recursive:!0});let o=Date.now(),s=!1;for(;!s;)try{await rg(r,a),s=!0}catch(e){if(e.code!==`EEXIST`)throw e;if(await ng(r))continue;if(Date.now()-o>=Rh)throw Error(`设置文件正被其他进程占用, 请稍后重试`);await eg(Lh)}let c;try{c={ok:!0,value:await e()}}catch(e){c={ok:!1,error:e}}let l;try{await A(r,`utf8`)===a&&await M(r)}catch(e){e.code!==`ENOENT`&&(l=e)}if(!c.ok)throw c.error;if(l)throw l;return c.value}var ag=async()=>{let e=await Qh();if(e)return e;let t=Jh(Em,qh());return await $h(t),t};async function og(){return await Qh()??ig(ag)}var sg=og;async function cg(e){await ig(async()=>{let t=await ag();await $h(Jh({...Gh(t),...e},t.stocks))})}async function lg(){return(await sg()).stocks}async function ug(e){let t=Ih(e);return ig(async()=>{let e=await ag(),n=new Set(e.stocks.map(e=>e.code)),r=t.filter(e=>!n.has(e.code));return r.length>0&&await $h({...e,stocks:[...e.stocks,...r]}),r.length})}async function dg(e){let t=new Set(e);return t.size===0?0:ig(async()=>{let e=await ag(),n=e.stocks.filter(e=>!t.has(e.code)),r=e.stocks.length-n.length;return r>0&&await $h({...e,stocks:n}),r})}function fg(e){let t=e.trim();if(t===`y`||t===`Y`)return`y`;if(t===`n`||t===`N`)return`n`}var pg=`错误: 必须选择 y (是) 或 n (否).`,mg={stocksAdd:ug,fetchQuotes:Km,normalizeCode:Gm,now:()=>new Date().toISOString()},hg={error:void 0,resetToken:0},gg=e=>{e(e=>({codeInput:{error:`无法识别股票代码, 请用英文逗号分隔 6 位股票代码.`,resetToken:e.codeInput.resetToken+1}}))};function _g(e=mg){let t=0,n=e=>e!==t;return vm()((r,i)=>({step:{type:`input-code`},codeInput:hg,confirmInput:hg,reset:()=>{t+=1,r({step:{type:`input-code`},codeInput:hg,confirmInput:hg})},handleCodeInput:async i=>{let a=t,o=i.split(`,`).map(e=>e.trim());if(o.length===0||o.some(e=>e===``)){gg(r);return}let s=o.map(t=>e.normalizeCode(t));if(s.some(e=>e===void 0)){gg(r);return}let c=[...new Set(s)];r(e=>({codeInput:{error:void 0,resetToken:e.codeInput.resetToken+1}})),r({step:{type:`checking`,codes:c}});try{let t=await e.fetchQuotes(c);if(n(a))return;let i=new Map(t.map(e=>[e.code,e])),o=c.filter(e=>!i.has(e));if(o.length>0){r({step:{type:`error`,message:`未找到股票代码: ${o.join(`, `)}.`}});return}r({step:{type:`confirm`,entries:c.map(e=>{let t=i.get(e);return{code:e,name:t.name,current:t.current}})}})}catch(e){n(a)||r({step:{type:`error`,message:Zm(e)}})}},handleConfirm:async a=>{let o=fg(a);if(!o){r(e=>({confirmInput:{error:pg,resetToken:e.confirmInput.resetToken+1}}));return}if(r(e=>({confirmInput:{error:void 0,resetToken:e.confirmInput.resetToken+1}})),o===`n`){r({step:{type:`done`,message:`已取消.`}});return}let s=t,c=i().step;if(c.type===`confirm`){r({step:{type:`saving`,entries:c.entries}});try{let t=e.now(),i=await e.stocksAdd(c.entries.map(e=>({code:e.code,name:e.name,addedAt:t})));if(n(s))return;if(i===0){r({step:{type:`already-exists`,entries:c.entries}});return}r({step:{type:`done`,message:`已添加 ${i} 个股票, ${c.entries.length-i} 个已在自选股中.`}})}catch(e){n(s)||r({step:{type:`error`,message:`写入自选股失败: ${Zm(e)}`}})}}}}))}var vg=_g();function yg(){let e=vg(e=>e.step),t=vg(e=>e.codeInput),n=vg(e=>e.confirmInput),r=vg(e=>e.handleCodeInput),i=vg(e=>e.handleConfirm),a=vg(e=>e.reset);return(0,U.useEffect)(()=>{a()},[a]),{step:e,codeInput:t,confirmInput:n,handleCodeInput:r,handleConfirm:i,reset:a}}function bg({title:e,hint:t}){let n=ih(),r=Nm(),{step:i,codeInput:a,confirmInput:o,handleCodeInput:s,handleConfirm:c,reset:l}=yg(),u;switch(i.type){case`input-code`:u=(0,Q.jsxs)(Q.Fragment,{children:[a.error&&(0,Q.jsx)($,{color:`red`,children:a.error}),(0,Q.jsx)(Ch,{prompt:`请输入股票代码, 用英文逗号分隔: `,placeholder:(0,Q.jsx)($,{color:`gray`,children:`支持 600000, sh600000, 600000.SH 等写法`}),onSubmit:s},`code-${a.resetToken}`)]});break;case`checking`:u=(0,Q.jsxs)($,{color:`cyan`,children:[`正在验证股票代码: `,i.codes.join(`, `),`...`]});break;case`confirm`:u=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)($,{color:`cyan`,children:`找到以下股票:`}),i.entries.map(e=>(0,Q.jsxs)($,{children:[e.name,` (`,e.code,`), 现价 `,Th(e.current)]},e.code)),o.error&&(0,Q.jsx)($,{color:`red`,children:o.error}),(0,Q.jsx)(Ch,{prompt:`确认添加到自选股? (y/n): `,onSubmit:c},`confirm-${o.resetToken}`)]});break;case`saving`:u=(0,Q.jsxs)($,{color:`cyan`,children:[`正在添加 `,i.entries.length,` 个股票...`]});break;case`already-exists`:u=(0,Q.jsx)(wh,{tone:`warning`,msg:`${i.entries.map(e=>`${e.name} (${e.code})`).join(`, `)} 已在自选股中.`,to:`stock-add`,onReturn:l});break;case`done`:u=(0,Q.jsx)(wh,{tone:`success`,msg:i.message,to:`stock-add`,onReturn:l});break;case`error`:u=(0,Q.jsx)(wh,{tone:`error`,msg:i.message,to:`stock-add`,onReturn:l})}return(0,Q.jsx)(sh,{fullScreen:!0,bright:!n,title:(0,Q.jsx)($,{color:r.primary,children:e}),footer:(0,Q.jsx)(fh,{hint:t,bright:!n}),children:u})}function xg(e){let{segments:t,selected:n,bright:r=!1}=e;return(0,Q.jsx)($,{bright:r,inverse:n,children:t.map((e,t)=>(0,Q.jsx)($,{bright:r,color:e.color,children:e.text},t))})}var Sg=(e,t)=>e+` `.repeat(Math.max(0,t.width-Nt(e))),Cg=e=>e.map((t,n)=>({...t,text:n<e.length-1?`${t.text} `:t.text})),wg=new Map([{key:`code`,kind:`code`,title:`代码`,width:9,render:e=>e.code},{key:`name`,kind:`name`,title:`名称`,width:9,render:e=>e.name},{key:`current`,kind:`value`,title:`现价`,width:8,render:e=>Th(e.current),color:(e,t)=>Oh(e.change,t)},{key:`changePercent`,kind:`changePercent`,title:`涨跌幅`,width:9,render:e=>Dh(e.changePercent),color:(e,t)=>Oh(e.changePercent,t),suspendedText:`停牌`},{key:`change`,kind:`value`,title:`涨跌额`,width:8,render:e=>Eh(e.change),color:(e,t)=>Oh(e.change,t)},{key:`open`,kind:`value`,title:`今开`,width:7,render:e=>Th(e.open)},{key:`prevClose`,kind:`value`,title:`昨收`,width:7,render:e=>Th(e.prevClose)},{key:`high`,kind:`value`,title:`最高`,width:7,render:e=>Th(e.high)},{key:`low`,kind:`value`,title:`最低`,width:7,render:e=>Th(e.low)},{key:`volume`,kind:`value`,title:`成交量`,width:11,render:e=>kh(e.volume)},{key:`turnover`,kind:`value`,title:`成交额`,width:9,render:e=>Ah(e.turnover)},{key:`turnoverRate`,kind:`value`,title:`换手率`,width:7,render:e=>jh(e.turnoverRate)},{key:`amplitude`,kind:`value`,title:`振幅`,width:7,render:e=>jh(e.amplitude)},{key:`volumeRatio`,kind:`value`,title:`量比`,width:7,render:e=>Mh(e.volumeRatio)},{key:`marketCap`,kind:`value`,title:`总市值`,width:10,render:e=>Nh(e.marketCap)}].map(e=>[e.key,e])),Tg=e=>Cg(e.map(e=>({text:Sg(e.title,e),color:`gray`}))),Eg=(e,t,n=Sm)=>{let r=t.current<=0;return Cg(e.map(e=>({text:Sg(r?e.suspendedText??`--`:e.render(t),e),color:r||!e.color?`gray`:e.color(t,n)})))},Dg=(e,t,n)=>Cg(e.map(e=>({text:Sg(e.kind===`code`?t:e.kind===`name`?n:e.kind===`changePercent`?`无数据`:`--`,e),color:`gray`}))),Og=[`name`,`code`,`current`,`changePercent`,`change`,`open`,`high`,`low`,`volume`,`turnover`,`turnoverRate`,`marketCap`],kg=[`open`,`prevClose`,`high`,`low`,`volume`,`turnover`,`turnoverRate`,`amplitude`,`volumeRatio`,`marketCap`],Ag=Og.reduce((e,t)=>{let n=wg.get(t);return n&&e.push(n),e},[]),jg=kg.reduce((e,t)=>{let n=wg.get(t);return n&&e.push(n),e},[]),Mg=()=>Ag.reduce((e,t)=>e+t.width,0)+(Ag.length-1),Ng=()=>jg.reduce((e,t)=>e+t.width,0)+(jg.length-1);function Pg(e,{enabled:t=!0,intervalMs:n,restartKey:r,onError:i}){let a=(0,U.useRef)(e),o=(0,U.useRef)(n),s=(0,U.useRef)(i),c=(0,U.useRef)({});(0,U.useEffect)(()=>{a.current=e,o.current=n,s.current=i},[e,n,i]);let l=(0,U.useCallback)(()=>c.current.refresh?.(),[]);return(0,U.useEffect)(()=>{if(!t){c.current={};return}let e=!0,n=!1,r,i,l=()=>{r&&=(clearTimeout(r),void 0)},u=(t=o.current)=>{!e||n||r||(r=setTimeout(()=>{r=void 0,f()},t))},d=async()=>{if(!e||n)return;let t=Date.now();n=!0,i=new AbortController;let r=i;try{await a.current(r.signal)}catch(e){r.signal.aborted||s.current?.(e)}finally{i===r&&(i=void 0),n=!1,u(Math.max(0,o.current-(Date.now()-t)))}},f=()=>void d();return c.current={refresh:()=>{n||(l(),f())},reschedule:()=>{n||(l(),u())}},f(),()=>{e=!1,c.current={},l(),i?.abort()}},[t,r]),(0,U.useEffect)(()=>{c.current.reschedule?.()},[n]),{refresh:l}}var Fg={fetchQuotes:Km,loadStocks:lg},Ig=(e,t)=>Math.min(Math.max(e,0),t-1),Lg=(e,t,n,r,i)=>{let a=Ig(t+e,n),o=Math.max(0,n-i);return e===1&&a>=r+i?Math.min(a-i+1,o):e===-1&&a<r?a:Math.min(r,o)},Rg=(e,t)=>{if(!t)return 0;let n=e.findIndex(e=>e.code===t);return n<0?0:n},zg=(e,t)=>e.code===t.code&&e.name===t.name&&e.current===t.current&&e.prevClose===t.prevClose&&e.open===t.open&&e.high===t.high&&e.low===t.low&&e.change===t.change&&e.changePercent===t.changePercent&&e.timestamp===t.timestamp&&e.volume===t.volume&&e.turnover===t.turnover&&e.turnoverRate===t.turnoverRate&&e.amplitude===t.amplitude&&e.marketCap===t.marketCap&&e.volumeRatio===t.volumeRatio;function Bg(e=Fg){return vm()((t,n)=>({step:{type:`loading`},selectedCode:void 0,scrollOffset:0,refreshQuotes:async n=>{try{let r=await e.loadStocks();if(n?.aborted)return;if(r.length===0){t({step:{type:`empty`},selectedCode:void 0,scrollOffset:0});return}let i=await e.fetchQuotes(r.map(e=>e.code),n);if(n?.aborted)return;t(e=>{let t=e.step.type===`table`?e.step.rows:[],n=new Map(t.filter(e=>e.kind===`quote`).map(e=>[e.code,e.quote])),a=new Map(i.map(e=>{let t=n.get(e.code);return[e.code,t&&zg(t,e)?t:e]})),o=r.map(e=>{let t=a.get(e.code);return t?{kind:`quote`,code:e.code,name:t.name,quote:t}:{kind:`missing`,code:e.code,name:e.name}}),s=Rg(t,e.selectedCode),c=e.selectedCode?o.findIndex(t=>t.code===e.selectedCode):-1,l=c>=0?c:Ig(s,o.length),u=Math.max(0,s-e.scrollOffset);return{step:{type:`table`,rows:o},selectedCode:o[l]?.code,scrollOffset:Math.max(0,l-u)}})}catch(e){if(n?.aborted)return;let r=Zm(e);t(e=>e.step.type===`table`?{step:{...e.step,errorLine:r}}:{step:{type:`error`,message:r}})}},moveSelection:(e,r)=>{let{step:i,selectedCode:a,scrollOffset:o}=n();if(i.type!==`table`||i.rows.length===0)return;let s=Rg(i.rows,a),c=Ig(s+e,i.rows.length);t({selectedCode:i.rows[c]?.code,scrollOffset:Lg(e,s,i.rows.length,o,r)})}}))}var Vg=Bg(),Hg=(e,t,n)=>{if(e<=n)return{start:0,end:e};let r=e-n,i=Math.min(Math.max(t,0),r);return{start:i,end:i+n}};function Ug(){let e=(0,U.useRef)(null),t=bu(e),n=Vg(e=>e.step),r=Vg(e=>e.selectedCode),i=Vg(e=>e.scrollOffset),a=Mm(e=>e.quotePollIntervalMs),o=Vg(e=>e.moveSelection),s=ih(),c=t.hasMeasured?Math.max(1,Math.floor(t.height)):1,l=n.type===`table`?Hg(n.rows.length,i,c):{start:0,end:0};(0,U.useEffect)(()=>{Vg.setState({step:{type:`loading`}})},[]);let{refresh:u}=Pg(e=>Vg.getState().refreshQuotes(e),{intervalMs:a});return mu((e,t)=>{if(!t.ctrl){if(t.upArrow)o(-1,c);else if(t.downArrow)o(1,c);else if(t.return){let e=Vg.getState();if(e.step.type!==`table`||!e.selectedCode)return;let t=e.step.rows.find(t=>t.code===e.selectedCode);t&&rh.getState().open(t.code,t.name)}else e===`r`&&u()}},{isActive:!s}),{rowsRef:e,step:n,selectedCode:r,window:l}}function Wg({title:e,hint:t}){let n=ih(),r=Nm(),i=Mm(e=>e.trendColorMode),{rowsRef:a,step:o,selectedCode:s,window:c}=Ug(),l;switch(o.type){case`loading`:l=(0,Q.jsx)($,{color:`cyan`,children:`正在获取行情数据...`});break;case`empty`:l=(0,Q.jsx)($,{color:`yellow`,children:`自选股为空, 按 esc 打开菜单添加自选股.`});break;case`error`:l=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)($,{color:`red`,children:o.message}),(0,Q.jsx)($,{color:`gray`,children:`行情接口异常, 稍后自动重试`})]});break;case`table`:l=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(xg,{segments:Tg(Ag)}),(0,Q.jsx)(pl,{ref:a,flexDirection:`column`,flexGrow:1,overflow:`hidden`,children:o.rows.slice(c.start,c.end).map(e=>(0,Q.jsx)(xg,{segments:e.kind===`quote`?Eg(Ag,e.quote,i):Dg(Ag,e.code,e.name),selected:e.code===s},e.code))}),o.errorLine?(0,Q.jsxs)($,{color:`yellow`,children:[`刷新失败: `,o.errorLine,`, 稍后自动重试`]}):void 0]})}return(0,Q.jsx)(sh,{fullScreen:!0,bright:!n,title:(0,Q.jsx)($,{color:r.primary,children:e}),footer:(0,Q.jsx)(fh,{hint:t,bright:!n}),children:l})}var Gg={loadStocks:lg,stocksRemove:dg},Kg={error:void 0,resetToken:0};function qg(e=Gg){let t=0,n=e=>e!==t;return vm()((r,i)=>({step:{type:`loading`},indexInput:Kg,confirmInput:Kg,loadEntries:async()=>{let i=++t;r({step:{type:`loading`},indexInput:Kg,confirmInput:Kg});try{let t=await e.loadStocks();if(n(i))return;r({step:t.length===0?{type:`error`,message:`自选股为空, 请先添加股票.`}:{type:`select`,entries:t}})}catch(e){n(i)||r({step:{type:`error`,message:Zm(e)}})}},handleChoice:e=>{let t=i().step;if(t.type!==`select`)return;let n=e.split(`,`).map(e=>e.trim()),a=n.map(e=>Number(e));if(n.length===0||n.some(e=>e===``)||a.some(e=>!Number.isInteger(e)||e<1||e>t.entries.length)){r(e=>({indexInput:{error:`无效的序号, 请输入 1-${t.entries.length}, 用英文逗号分隔.`,resetToken:e.indexInput.resetToken+1}}));return}let o=[...new Set(a)].map(e=>t.entries[e-1]);r(e=>({indexInput:{error:void 0,resetToken:e.indexInput.resetToken+1}})),r({step:{type:`confirm`,entries:o}})},handleConfirm:async a=>{let o=fg(a);if(!o){r(e=>({confirmInput:{error:pg,resetToken:e.confirmInput.resetToken+1}}));return}if(r(e=>({confirmInput:{error:void 0,resetToken:e.confirmInput.resetToken+1}})),o===`n`){r({step:{type:`done`,message:`已取消.`}});return}let s=t,c=i().step;if(c.type===`confirm`){r({step:{type:`removing`,entries:c.entries}});try{let t=await e.stocksRemove(c.entries.map(e=>e.code));if(n(s))return;if(t===0){r({step:{type:`error`,message:`所选 ${c.entries.length} 个条目已不在自选股中.`}});return}r({step:{type:`done`,message:`已删除 ${t} 个股票, ${c.entries.length-t} 个条目已不在自选股中.`}})}catch(e){n(s)||r({step:{type:`error`,message:`删除失败: ${Zm(e)}`}})}}}}))}var Jg=qg();function Yg(){let e=Jg(e=>e.step),t=Jg(e=>e.indexInput),n=Jg(e=>e.confirmInput),r=Jg(e=>e.handleChoice),i=Jg(e=>e.handleConfirm),a=Jg(e=>e.loadEntries);return(0,U.useEffect)(()=>{a()},[a]),{step:e,indexInput:t,confirmInput:n,handleChoice:r,handleConfirm:i,loadEntries:a}}function Xg({title:e,hint:t}){let n=ih(),r=Nm(),{step:i,indexInput:a,confirmInput:o,handleChoice:s,handleConfirm:c,loadEntries:l}=Yg(),u;switch(i.type){case`loading`:u=(0,Q.jsx)($,{color:`cyan`,children:`正在加载自选股...`});break;case`select`:u=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)($,{color:`gray`,children:`自选股列表:`}),i.entries.map((e,t)=>(0,Q.jsxs)($,{children:[t+1,`) `,e.name,` (`,e.code,`) `,(0,Q.jsxs)($,{color:`gray`,children:[`(`,e.addedAt.slice(0,10),`)`]})]},e.code)),a.error&&(0,Q.jsx)($,{color:`red`,children:a.error}),(0,Q.jsx)(ql,{}),(0,Q.jsx)(Ch,{prompt:`请输入要删除的序号, 用英文逗号分隔: `,onSubmit:s})]});break;case`confirm`:u=(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)($,{color:`yellow`,children:`确定删除以下股票?`}),i.entries.map(e=>(0,Q.jsxs)($,{children:[e.name,` (`,e.code,`)`]},e.code)),o.error&&(0,Q.jsx)($,{color:`red`,children:o.error}),(0,Q.jsx)(Ch,{prompt:`确认删除? (y/n): `,onSubmit:c},`confirm-${o.resetToken}`)]});break;case`removing`:u=(0,Q.jsxs)($,{color:`cyan`,children:[`正在删除 `,i.entries.length,` 个股票...`]});break;case`done`:u=(0,Q.jsx)(wh,{tone:`success`,msg:i.message,to:`stock-remove`,onReturn:l});break;case`error`:u=(0,Q.jsx)(wh,{tone:`error`,msg:i.message,to:`stock-remove`,onReturn:l})}return(0,Q.jsx)(sh,{fullScreen:!0,bright:!n,title:(0,Q.jsx)($,{color:r.primary,children:e}),footer:(0,Q.jsx)(fh,{hint:t,bright:!n}),children:u})}var Zg={"stock-list":{Component:Wg,title:`自选股票看板`,description:`自选股票看板 (默认, 自动刷新)`,hint:`菜单(esc) 刷新(r) 选择(↑/↓) 详情(enter) 退出(q)`,menuLabel:`自选股票看板`},"stock-add":{Component:bg,title:`添加自选股`,description:`添加自选股`,hint:`菜单(esc) 退出(q)`,menuLabel:`添加自选股`},"stock-remove":{Component:Xg,title:`删除自选股`,description:`删除自选股`,hint:`菜单(esc) 退出(q)`,menuLabel:`删除自选股`},settings:{Component:yh,title:`设置`,description:`配置主题, 涨跌颜色与请求参数`,hint:`菜单(esc) 选择(↑/↓) 调整(←/→/enter) 默认值(d) 退出(q)`,menuLabel:`设置`}},Qg=Object.keys(Zg),$g=e=>e!==void 0&&Object.hasOwn(Zg,e),e_=e=>$g(e)?e:`stock-list`,t_=[...Object.entries(Zg).map(([e,t],n)=>({label:`${n+1}) ${t.menuLabel}`,screen:e})),{label:`${Object.keys(Zg).length+1}) 退出程序`,screen:void 0}],n_=45;function r_(){let e=bh(e=>e.goTo),t=Pm(e=>e.close),{exit:n}=hu(),[r,i]=(0,U.useState)(0),a=r=>{r.screen?(t(),e(r.screen)):n()};return mu((e,t)=>{if(t.upArrow)i(e=>(e+t_.length-1)%t_.length);else if(t.downArrow)i(e=>(e+1)%t_.length);else if(t.return)a(t_[r]);else if(/^[1-9]$/.test(e)){let t=Number(e)-1,n=t_[t];if(!n)return;i(t),a(n)}}),{width:n_,menuItems:t_,highlight:r}}function i_(){let{highlight:e,width:t,menuItems:n}=r_(),r=Nm();return(0,Q.jsx)(ph,{title:(0,Q.jsx)($,{bright:!0,color:r.primary,children:`菜单`}),width:t,children:n.map((t,n)=>(0,Q.jsxs)($,{bright:!0,color:n===e?`black`:void 0,backgroundColor:n===e?r.highlight:void 0,children:[n===e?`> `:` `,t.label]},t.label))})}var a_=e=>{if(!/^\d{4}$/.test(e))return;let t=Number(e.slice(0,2))*60+Number(e.slice(2))-570;return t<0?0:t>120?t-90:t},o_=(e,t)=>{if(t<=0)return[];let n=Array.from({length:t},()=>({sum:0,count:0,minPrice:0,maxPrice:0,lastPrice:0,volume:0})),r=-1,i=0;for(let a of e){let e=a_(a.time);if(e===void 0)continue;let o=Math.min(t-1,Math.floor(e/240*t)),s=n[o];s.sum+=a.price,s.count+=1,s.minPrice=s.count===1?a.price:Math.min(s.minPrice,a.price),s.maxPrice=s.count===1?a.price:Math.max(s.maxPrice,a.price),s.lastPrice=a.price,s.volume+=Math.max(0,a.volume-i),i=a.volume,r=Math.max(r,o)}let a=[],o=0;for(let e=0;e<t;e++){let t=n[e];t.count>0?(o=t.lastPrice,a.push({avgPrice:t.sum/t.count,maxPrice:t.maxPrice,minPrice:t.minPrice,lastPrice:t.lastPrice,volume:t.volume})):e<r?a.push({avgPrice:o,maxPrice:o,minPrice:o,lastPrice:o,volume:0}):a.push({avgPrice:0,maxPrice:0,minPrice:0,lastPrice:0,volume:0})}return a},s_=e=>`date`in e,c_=e=>`sessionDate`in e,l_=e=>!s_(e)&&!c_(e),u_=(e,t)=>{let n=new Map;for(let t of e){let e=n.get(t.sessionDate)??[];e.push(t),n.set(t.sessionDate,e)}let r=[...n.entries()].sort(([e],[t])=>e.localeCompare(t));if(r.length===0)return Array.from({length:t},()=>({avgPrice:0,maxPrice:0,minPrice:0,lastPrice:0,volume:0}));let i=[];for(let e=0;e<r.length;e++){let n=Math.floor(e/r.length*t),a=Math.floor((e+1)/r.length*t)-n;if(a<=0)continue;let o=r[e][1].sort((e,t)=>e.time.localeCompare(t.time));i.push(...o_(o,a))}return i},d_=(e,t)=>e.length===0?Array.from({length:t},()=>({avgPrice:0,maxPrice:0,minPrice:0,lastPrice:0,volume:0})):Array.from({length:t},(n,r)=>{let i=t<=1?0:r/(t-1)*(e.length-1),a=e[Math.floor(i)],o=e[Math.min(Math.ceil(i),e.length-1)],s=i-Math.floor(i),c=a.close+(o.close-a.close)*s,l=e[Math.round(i)];return{avgPrice:c,maxPrice:Math.max(a.high,o.high),minPrice:Math.min(a.low,o.low),lastPrice:c,volume:l.volume}}),f_=(e,t)=>t<3?1<<t+e*3:1<<6+e,p_=e=>String.fromCharCode(10240+e),m_=e=>{let{points:t,period:n,prevClose:r,width:i,priceHeight:a,volumeHeight:o,trendColorMode:s=Sm}=e,c=t.filter(l_),l=t.filter(c_),u=t.filter(s_),d=n===`intraday`,f=n===`five-day`,p=d?o_(c,i):f?u_(l,i):d_(u,i),m=d?r:f?l[0]?.prevClose:u[0]?.close,h=d?r:void 0,g=1/0,_=-1/0;for(let e of p)e.avgPrice<=0||(g=Math.min(g,e.minPrice),_=Math.max(_,e.maxPrice));h!==void 0&&(g=Math.min(g,h),_=Math.max(_,h)),Number.isFinite(g)||(g=0,_=1),_===g&&(_+=1);let v=a*4,y=i*2,b=e=>Math.round((_-e)/(_-g)*(v-1)),x=(e,t)=>t===void 0?`gray`:Oh(e-t,s),S=x(p.map(e=>e.lastPrice).filter(e=>e>0).at(-1)??0,m),C=p.map((e,t)=>{if(d)return S;if(e.lastPrice<=0)return`gray`;let n=p[t+1]?.lastPrice;if(n!==void 0&&n>0)return x(n,e.lastPrice);let r=p[t-1]?.lastPrice;return x(e.lastPrice,r!==void 0&&r>0?r:void 0)}),w=Array.from({length:a+o+1},()=>Array.from({length:i},()=>({ch:` `,color:void 0}))),T=Array.from({length:a},()=>new Uint16Array(i)),E=-1;for(let e=0;e<i;e++)p[e].avgPrice>0&&(E=e);let D;for(let e=0;e<y;e++){let t=e/2;if(t>E){D=void 0;continue}let n=p[Math.floor(t)];if(n.avgPrice<=0){D=void 0;continue}let r=p[Math.min(Math.floor(t)+1,i-1)],a=b(r.avgPrice>0?n.lastPrice+(r.lastPrice-n.lastPrice)*(t-Math.floor(t)):n.lastPrice),o=Math.floor(e/2),s=T[Math.floor(a/4)];if(s[o]=s[o]|f_(e%2,a%4),D!==void 0){let t=Math.min(D,a),n=Math.max(D,a);for(let r=t+1;r<n;r++){let t=T[Math.floor(r/4)];t[o]=t[o]|f_(e%2,r%4)}}D=a}let O=Array.from({length:a},()=>new Uint16Array(i));if(h!==void 0){let e=b(h),t=Math.floor(e/4);for(let n=0;n<y;n++){if(n%3==2)continue;let r=Math.floor(n/2);if(T[t][r]!==0)continue;let i=O[t];i[r]=i[r]|f_(n%2,e%4)}}for(let e=0;e<a;e++)for(let t=0;t<i;t++){let n=T[e][t]|O[e][t];n!==0&&(w[e][t]={ch:p_(n),color:T[e][t]===0?`gray`:C[t]})}let k=Array.from({length:o},()=>new Uint16Array(i)),A=Math.max(...p.map(e=>e.volume),0);for(let e=0;e<i;e++){let t=p[e];if(t.volume<=0||A<=0)continue;let n=o*4,r=Math.max(1,Math.round(t.volume/A*n));for(let t=n-r;t<n;t++){let n=k[Math.floor(t/4)];n[e]=n[e]|f_(0,t%4)|f_(1,t%4)}}let j=Array.from({length:i},()=>void 0),M=m;for(let e=0;e<i;e++){let t=p[e];t.lastPrice<=0||(j[e]=M===void 0?`gray`:Oh(t.lastPrice-M,s),M=t.lastPrice)}for(let e=0;e<o;e++)for(let t=0;t<i;t++){let n=k[e][t];n!==0&&(w[a+e][t]={ch:p_(n),color:j[t]})}let N=[],P=(e,t)=>Math.max(0,Math.min(i-t.length,e-Math.floor(t.length/2)));if(d)N.push({col:0,labelCol:0,label:`09:30`},{col:Math.floor(i/2),labelCol:Math.max(0,Math.floor((i-11)/2)),label:`11:30/13:00`},{col:i-1,labelCol:Math.max(0,i-5),label:`15:00`});else if(f&&l.length>0){let e=[...new Set(l.map(e=>e.sessionDate))].sort();for(let t=0;t<e.length;t++){let n=Math.min(i-1,Math.floor((t+.5)/e.length*i)),r=e[t].slice(5);N.push({col:n,labelCol:P(n,r),label:r})}}else if(u.length>0){let e=e=>n===`year`?e.date.slice(0,4):n===`month`?e.date.slice(0,7):n===`week`?e.date.slice(2):e.date.slice(5),t=e(u[0]),r=e(u[Math.floor((u.length-1)/2)]),a=e(u.at(-1));N.push({col:0,labelCol:0,label:t},{col:Math.floor(i/2),labelCol:Math.max(0,Math.floor((i-r.length)/2)),label:r},{col:i-1,labelCol:Math.max(0,i-a.length),label:a})}for(let{col:e}of N)for(let t=0;t<a+o;t++)w[t][e].ch===` `&&(w[t][e]={ch:`┊`,color:`gray`});let F=w[a+o],I=(e,t)=>{for(let n=0;n<t.length&&e+n<i;n++)F[e+n]={ch:t[n],color:`gray`}};for(let e of N)I(e.labelCol,e.label);return w},h_=9,g_=4;function __({points:e,period:t,prevClose:n,width:r,priceHeight:i=h_,volumeHeight:a=g_,bright:o=!1,trendColorMode:s}){let c=m_({points:e,period:t,prevClose:n,width:r,priceHeight:i,volumeHeight:a,trendColorMode:s});return(0,Q.jsx)(pl,{flexDirection:`column`,children:c.map((e,t)=>{let n=[];for(let t of e){let e=n.at(-1);e&&e.color===t.color?e.text+=t.ch:n.push({text:t.ch,color:t.color})}return(0,Q.jsx)($,{bright:o,children:n.map((e,t)=>(0,Q.jsx)($,{bright:o,color:e.color,children:e.text},t))},t)})})}var v_=new Map([[`sh`,`沪`],[`sz`,`深`],[`bj`,`北`]]);function y_({code:e,bright:t=!1}){let n=e.slice(0,2).toLowerCase(),r=v_.get(n);if(r)return(0,Q.jsx)($,{bright:t,color:`white`,backgroundColor:`red`,children:r})}var b_=[{key:`1`,value:`intraday`,label:`分时`},{key:`2`,value:`five-day`,label:`五日`},{key:`3`,value:`day`,label:`日K`},{key:`4`,value:`week`,label:`周K`},{key:`5`,value:`month`,label:`月K`},{key:`6`,value:`year`,label:`年K`}];function x_(){let e=rh(e=>e.stock),t=rh(e=>e.period),n=rh(e=>e.status),r=rh(e=>e.points),i=rh(e=>e.errorMessage),a=Mm(e=>e.minuteChartPollIntervalMs),o=Mm(e=>e.klinePollIntervalMs),s=Pm(e=>e.open),c=Vg(t=>{if(t.step.type!==`table`)return;let n=t.step.rows.find(t=>t.code===e?.code);return n?.kind===`quote`?n.quote:void 0});if(mu((e,t)=>{if(t.ctrl)return;let n=b_.find(t=>t.key===e);n&&rh.getState().setPeriod(n.value)},{isActive:e!==void 0&&!s}),Pg(async n=>{e&&await rh.getState().refreshChart(e.code,t,n)},{enabled:e!==void 0,intervalMs:t===`intraday`||t===`five-day`?a:o,restartKey:e?`${e.code}:${t}`:void 0}),e)return{stock:e,quote:c,suspended:c?c.current<=0:!1,period:t,status:n,points:r,errorMessage:i}}var S_=Ng()+4+6,C_=S_-4;function w_(){let e=Mm(e=>e.trendColorMode),t=x_();if(!t)return;let{stock:n,quote:r,suspended:i,period:a,status:o,points:s,errorMessage:c}=t,l=b_.find(e=>e.value===a)?.label??``;return(0,Q.jsxs)(ph,{title:(0,Q.jsxs)($,{bright:!0,children:[(0,Q.jsx)(y_,{code:n.code,bright:!0}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,children:n.name}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,color:`gray`,children:n.code}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,color:!r||i?`gray`:Oh(r.change,e),children:r?Th(r.current):`--`}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,color:!r||i?`gray`:Oh(r.changePercent,e),children:r?i?`停牌`:Dh(r.changePercent):`--`}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{bright:!0,color:!r||i?`gray`:Oh(r.change,e),children:r?Eh(r.change):`--`})]}),extra:(0,Q.jsx)($,{bright:!0,children:b_.map((e,t)=>(0,Q.jsxs)($,{bright:!0,color:e.value===a?`cyan`:`gray`,children:[t>0?` `:``,`[`,e.key,`]`,e.label]},e.value))}),width:S_,children:[(0,Q.jsxs)(pl,{flexDirection:`column`,children:[(0,Q.jsx)(xg,{bright:!0,segments:Tg(jg)}),(0,Q.jsx)(xg,{bright:!0,segments:r?Eg(jg,r,e):Dg(jg,n.code,n.name)})]}),(0,Q.jsx)(pl,{marginTop:1,height:14,children:o===`loading`?(0,Q.jsxs)($,{bright:!0,color:`gray`,children:[`正在获取`,l,`行情...`]}):o===`error`?(0,Q.jsx)($,{bright:!0,color:`red`,children:c}):s.length===0?(0,Q.jsxs)($,{bright:!0,color:`gray`,children:[`暂无`,l,`行情数据`]}):(0,Q.jsx)(__,{bright:!0,points:s,period:a,prevClose:r?.prevClose,trendColorMode:e,width:C_})})]})}var T_=Mg()+4;function E_({children:e}){let{columns:t,rows:n}=_u(),r=t>=T_,i=n>=26;return r&&i?e:(0,Q.jsxs)(pl,{width:t,height:n,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,children:[(0,Q.jsx)($,{color:`yellow`,children:`终端尺寸过小:`}),(0,Q.jsxs)(pl,{children:[(0,Q.jsx)($,{color:r?`green`:`red`,children:`宽度 = ${t}`}),(0,Q.jsx)($,{children:` `}),(0,Q.jsx)($,{color:i?`green`:`red`,children:`高度 = ${n}`})]}),(0,Q.jsx)(pl,{height:1}),(0,Q.jsx)($,{color:`gray`,children:`所需最小尺寸:`}),(0,Q.jsx)($,{color:`gray`,children:`宽度 = ${T_} 高度 = 26`})]})}function D_(){let{exit:e}=hu(),t=ih(),n=bh(e=>e.screen),r=Pm(e=>e.open),i=Pm(e=>e.toggle),a=rh(e=>e.stock),o=rh(e=>e.close),s=Zg[n];return mu((n,r)=>{r.escape?a?o():i():n===`q`&&!t&&e()}),(0,Q.jsxs)(E_,{children:[(0,Q.jsx)(s.Component,{title:s.title,hint:s.hint}),r&&(0,Q.jsx)(i_,{}),a&&(0,Q.jsx)(w_,{})]})}var O_=100,k_=e=>Object.keys(e).length>0;async function A_(e){let t=await og();Mm.getState().hydrateSettings(Gh(t));let n={},r,i,a=Promise.resolve(),o=async()=>{if(!k_(n))return;let t=n;n={};try{await cg(t),r=void 0}catch(i){n={...t,...n},r=i;try{e(i)}catch{}}},s=()=>(i&&=(clearTimeout(i),void 0),a=a.then(o),a),c=()=>{i&&clearTimeout(i),i=setTimeout(()=>{i=void 0,s()},O_)},l=Mm.subscribe((e,t)=>{Am(e,t)||(n={...n,...jm(e,t)},c())}),u,d=async()=>(l(),await s(),r&&k_(n)&&await o(),r===void 0);return{stop:()=>u??=d()}}var j_=`用法
152
151
  $ leek-box-cli [command]
153
152
 
154
153
  命令
155
- ${Object.entries(Yg).map(([e,t])=>` ${e.padEnd(13)}${t.description}`).join(`
154
+ ${Object.entries(Zg).map(([e,t])=>` ${e.padEnd(13)}${t.description}`).join(`
156
155
  `)}
157
156
 
158
157
  选项
159
158
  -v, --version 查看版本
160
- -h, --help 查看帮助
161
- `,{importMeta:import.meta,commands:Xg,flags:{help:{type:`boolean`,shortFlag:`h`},version:{type:`boolean`,shortFlag:`v`}}}),A_=async()=>{let e=await O_(e=>{let t=e instanceof Error?e.message:String(e);console.error(`设置保存失败: ${t}`)});try{bh.setState({screen:Qg(k_.command)}),await Wl((0,Q.jsx)(T_,{}),{alternateScreen:!0,concurrent:!0}).waitUntilExit()}finally{await e.stop()||(n.exitCode=1)}};try{await A_()}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`运行失败: ${t}`),n.exitCode=1}export{};
159
+ -h, --help 查看帮助`,M_=fm(j_,{importMeta:import.meta,commands:Qg,description:!1,autoHelp:!1,helpIndent:0,flags:{help:{type:`boolean`,shortFlag:`h`},version:{type:`boolean`,shortFlag:`v`}}});M_.flags.help&&(console.log(j_),n.exit(0));var N_=async()=>{let e=await A_(e=>{let t=e instanceof Error?e.message:String(e);console.error(`设置保存失败: ${t}`)});try{bh.setState({screen:e_(M_.command)}),await Wl((0,Q.jsx)(D_,{}),{alternateScreen:!0,concurrent:!0}).waitUntilExit()}finally{await e.stop()||(n.exitCode=1)}};try{await N_()}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`运行失败: ${t}`),n.exitCode=1}export{};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leek-box-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "韭菜盒子, 终端股票自选股看板, 基于 Ink 构建的交互式 CLI 工具",
5
5
  "keywords": [
6
6
  "a股",