dsh-timeband 1.1.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DSH TimeBand contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # DSH TimeBand
2
+
3
+ DeepSeek Harness 桌面端头像右侧的峰谷时段插件。状态、切换倒计时、迷你时间轴常驻;点击查看北京时间 24 小时时间轴。没有价格、消费金额、Token、余额或预计节省功能,也不读取账户或 API Key。
4
+
5
+ 支持浅色 / 深色、中英文、侧栏折叠与节假日全天谷时段。节假日卡片精简重复时段说明,规则与日历默认折叠;关键时间与刻度使用更清晰的字号和颜色。离线运行,采用宿主共享的 React 和 Cordis 原生插件接口。
6
+
7
+ v1.1.0 增加本地日历导入与恢复、到期前 30 天提示,并缓存时段计算。倒计时仍每秒刷新;时间切换、跨天、休眠唤醒和日历替换会刷新对应判断。
8
+
9
+ ## 展示
10
+
11
+ 以下截图使用插件真实构建产物,宿主布局和账户区域为模拟,日期与时间固定;不是实际桌面端截图。
12
+
13
+ ![工作日峰时段,头像旁的状态与展开时间轴](https://raw.githubusercontent.com/a961282799-crypto/dsh-timeband/main/docs/images/peak-light.png)
14
+
15
+ <details>
16
+ <summary>午间谷时段:分钟与小字号秒数</summary>
17
+
18
+ ![午间谷时段](https://raw.githubusercontent.com/a961282799-crypto/dsh-timeband/main/docs/images/offpeak-light.png)
19
+
20
+ </details>
21
+
22
+ <details>
23
+ <summary>国庆假期:全天绿色,跨天倒计时</summary>
24
+
25
+ ![国庆假期全天谷时段](https://raw.githubusercontent.com/a961282799-crypto/dsh-timeband/main/docs/images/holiday-light.png)
26
+
27
+ </details>
28
+
29
+ <details>
30
+ <summary>深色模式:不足一分钟只显示秒</summary>
31
+
32
+ ![深色模式](https://raw.githubusercontent.com/a961282799-crypto/dsh-timeband/main/docs/images/peak-dark.png)
33
+
34
+ </details>
35
+
36
+ <details>
37
+ <summary>日历更新:导入、恢复与来源</summary>
38
+
39
+ ![日历更新入口](https://raw.githubusercontent.com/a961282799-crypto/dsh-timeband/main/docs/images/calendar-update.png)
40
+
41
+ </details>
42
+
43
+ ## 安装
44
+
45
+ 已针对 **DeepSeek Harness 0.2.0-rc.2** 制作。2026-10-03 核对 npm `latest` 仍为此版本,四个宿主测试依赖与随附桌面 CLI 版本一致。版本声明只覆盖此版本,宿主升级后应重新验证并更新 peer 范围。
46
+
47
+ npm 包名可用后,可在桌面端「插件 → 添加插件」输入 `dsh-timeband@1.1.0`;或在退出桌面端后执行 `dsh plugin --profile desktop add dsh-timeband@1.1.0`。若 npm 包名尚不可用,请使用下方的 GitHub 安装包。
48
+
49
+ 从 [GitHub Releases](https://github.com/a961282799-crypto/dsh-timeband/releases/tag/v1.1.0) 下载预构建安装包 `dsh-timeband-1.1.0.tgz`。不需要安装开发依赖或自行编译。
50
+
51
+ 从托盘完全退出 Harness,在下载目录执行:
52
+
53
+ ```powershell
54
+ dsh plugin --profile desktop add ./dsh-timeband-1.1.0.tgz
55
+ ```
56
+
57
+ 如果 `dsh` 不在 PATH,使用桌面端安装目录中随附的命令,例如:
58
+
59
+ ```powershell
60
+ & 'C:\path\to\DeepSeek Harness\resources\runtime\cli\bin\dsh.cmd' plugin --profile desktop add ./dsh-timeband-1.1.0.tgz
61
+ ```
62
+
63
+ 安装后重新打开 Harness,侧栏底部即可看到插件。卸载:
64
+
65
+ ```powershell
66
+ dsh plugin --profile desktop remove dsh-timeband
67
+ ```
68
+
69
+ ### 从源码打包
70
+
71
+ ```powershell
72
+ npm ci
73
+ npm run build
74
+ npm pack --pack-destination artifacts
75
+ ```
76
+
77
+ 先从托盘完全退出 Harness,再在本目录执行:
78
+
79
+ ```powershell
80
+ powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\install-desktop.ps1
81
+ ```
82
+
83
+ 脚本默认使用 PATH 中的 `dsh`,也可传入 `-DshCommand` 指定随附 `dsh.cmd` 的完整路径。脚本通过官方 CLI 安装,不修改应用文件;如应用仍运行会停止并提示退出,不强制结束进程。重新打开 Harness 后生效。
84
+
85
+ Web 版可改成 `--profile web`,组件显示在侧栏底部原生插槽。
86
+
87
+ ## 界面与兼容边界
88
+
89
+ - 桌面端侧栏展开:头像右侧显示时段、倒计时和今日迷你时间轴。倒计时按剩余时间显示「天、小时、分钟」,秒以较小字号跟随;不足一天省略天,不足一小时只显示分钟和秒,不足一分钟只显示秒。
90
+ - 侧栏收起:紧凑图标和状态点;点击仍可查看完整卡片。
91
+ - 原生 Popover 提供顶层显示、外部点击关闭;Escape 关闭并回到触发按钮。卡片会限制在窗口内,支持中英文与宿主颜色变量。
92
+ - 头像右侧没有独立的官方插槽。插件注册到 `sidebar.footer.action`,以带严格结构条件的 CSS 调整 rc.2 的两个底部容器,保留原头像按钮及其事件。若同一插槽有其他插件或宿主布局不匹配,保留原生上下排列,不强行修改 DOM。
93
+ - 当前信息只表示 **DeepSeek 官方 API 的时间规则**;第三方中转服务是否采用这些规则由其自行决定。
94
+
95
+ ## 规则与日历
96
+
97
+ 2026-09-30 核实:[DeepSeek 官方定价说明](https://api-docs.deepseek.com/quick_start/pricing/)。北京时间周一至周五 09:00–12:00、14:00–18:00 为峰时段,开始包含、结束不包含;其他时间为谷时段。周末即使是调休上班日也保持谷时段。
98
+
99
+ `calendars/2026.json` 是内置日历的唯一数据源,取自[国务院办公厅通知的政府转载](https://www.lufengshi.gov.cn/swlfsjj/gkmlpt/content/1/1199/mpost_1199727.html),覆盖完整放假区间。尚未收录 2027 年官方假期,不预测下一年安排。
100
+
101
+ 点击时间轴,在「时段规则与日历」内选择「获取新日历」,从本项目下载对应 JSON,再选择「导入日历」。日历覆盖年份与核对日期会随文件更新,侧栏和弹窗立即刷新;导入结果保存在当前 Harness 网页来源的本地存储,重启后继续使用,同来源的多个窗口同步。也可选择「恢复内置」。Web 与桌面端的来源不同,需要各自导入。
102
+
103
+ 导入日历替换整份当前日历;文件未包含的年份仍为待核实。到当前连续覆盖年份结束前 30 天,会在弹窗提示到期日期。错误文件、超过 64 KB、无效日期、范围重叠、覆盖年份缺少条目或非 HTTPS 政府来源的文件会被拒绝;保存失败保留原日历。来源字段校验只检查地址格式,不代表插件已在线核验公告内容,请使用本项目发布并人工核对的文件。日历格式及维护步骤见[日历维护说明](https://github.com/a961282799-crypto/dsh-timeband/blob/main/docs/calendar-maintenance.md)。
104
+
105
+ 未收录年份的工作日峰时段显示「待核实」,不推断假日。倒计时遇到未知日历区间会停止给出确定峰谷切换时间。插件离线计算,不自动抓网页、联网更新或收集数据;仅用户点击外部链接时打开浏览器。
106
+
107
+ ## 架构
108
+
109
+ TypeScript 7 + React 18(宿主共享实例)+ Cordis 官方插槽生命周期;esbuild 生成 DSH 的 `__ModuleLoader__.load({ id, factory })` 格式。发布包没有运行时 npm 依赖,也不打包另一份 React。
110
+
111
+ `src/schedule.ts` 是纯时间逻辑及按时段复用的日程读取器;`calendar.ts` 校验日历,`calendar-store.ts` 负责本地持久化与窗口同步;`clock.ts` 是单一可订阅时钟,隐藏时暂停,唤醒时重读系统时间;`client.ts` 持有注册、字典、样式及清理;`view.tsx` 接收宿主注入的时钟、日历存储和翻译函数。`cordis.patch.yml` 与 `dsh.bundle` 负责安装后进入宿主配置。
112
+
113
+ 接口依据:[官方 Client Slots](https://deepseek-harness.github.io/deepseek-harness/en/reference/subsystems/slots)、npm 发布的 `0.2.0-rc.2` 类型与 SlotRegistry;源码布局参照上游提交 `639ed015397290b3745d163aafe02ffee4aa3f84`。不承诺未测试版本兼容。
114
+
115
+ ## 开发与验证
116
+
117
+ ```powershell
118
+ npm ci
119
+ npm run check
120
+ npm run compatibility
121
+ npm run preview
122
+ npm pack --pack-destination artifacts
123
+ ```
124
+
125
+ 浏览器测试使用本机 Chrome。预览地址 `http://127.0.0.1:4173`,支持切换普通工作日、国庆、调休周六和未知年份。预览加载真实构建产物,宿主布局和账户按钮为模拟,时间固定用于检查。
126
+
127
+ 预览运行时,在另一个终端执行 `npm run screenshots`,可重建 `docs/images/` 中的四张展示截图。
128
+
129
+ 测试覆盖四个毫秒级切换边界、2026 全年时间轴一致性、多日假期、时区、跨年未知日历、休眠恢复和清理;使用真实 rc.2 Cordis/SlotRegistry 验证延迟插槽声明、移除重建及卸载;Chrome 检查头像右侧排列、弹层、键盘、外部关闭、窄窗口、中英文与浅深色截图。
130
+
131
+ 当前验证:类型检查、15 项 Node 测试、10 项 Chrome 测试通过。新增验证覆盖日历导入与恢复、持久化、窗口同步、损坏文件、存储失败、到期提示、窄窗口与缓存失效。v1.0.2 的官方桌面 CLI 安装、bundle 启用与安装产物一致性已验证;v1.1.0 完成构建产物及真实 rc.2 注册器检查,独立预览和注册器测试不等同于新版桌面安装验收。
132
+
133
+ `npm run compatibility` 核对 npm 最新正式标签与已验证版本,并检查四个宿主依赖版本。GitHub 的 Plugin checks 在提交、PR 或手动运行时执行此检查和功能测试;新宿主出现时会提示重新验证,不自动扩大兼容版本。详情见[兼容性记录](https://github.com/a961282799-crypto/dsh-timeband/blob/main/docs/compatibility.md)。
134
+
135
+ ## 许可证
136
+
137
+ [MIT](LICENSE)
@@ -0,0 +1,15 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "years": [2026],
4
+ "verifiedOn": "2026-09-30",
5
+ "source": "https://www.lufengshi.gov.cn/swlfsjj/gkmlpt/content/1/1199/mpost_1199727.html",
6
+ "holidays": [
7
+ ["2026-01-01", "2026-01-03"],
8
+ ["2026-02-15", "2026-02-23"],
9
+ ["2026-04-04", "2026-04-06"],
10
+ ["2026-05-01", "2026-05-05"],
11
+ ["2026-06-19", "2026-06-21"],
12
+ ["2026-09-25", "2026-09-27"],
13
+ ["2026-10-01", "2026-10-07"]
14
+ ]
15
+ }
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: dsh-timeband
3
+ name: dsh-timeband
package/dist/client.js ADDED
@@ -0,0 +1,95 @@
1
+ window.__ModuleLoader__.load({id:"dsh-timeband",factory:function(require){var module={exports:{}};var exports=module.exports;
2
+ "use strict";var A=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var xe=(n,r)=>{for(var e in r)A(n,e,{get:r[e],enumerable:!0})},ye=(n,r,e,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of he(r))!ge.call(n,i)&&i!==e&&A(n,i,{get:()=>r[i],enumerable:!(a=fe(r,i))||a.enumerable});return n};var ve=n=>ye(A({},"__esModule",{value:!0}),n);var Le={};xe(Le,{apply:()=>$e,inject:()=>De});module.exports=ve(Le);function q(){let n=Date.now(),r=new Set,e=()=>{n=Date.now();for(let a of r)a()};return{getSnapshot:()=>n,subscribe(a){return r.add(a),()=>{r.delete(a)}},start(){let a,i=()=>{clearInterval(a),a=void 0,e(),document.visibilityState!=="hidden"&&(a=setInterval(e,1e3))};return document.addEventListener("visibilitychange",i),window.addEventListener("focus",i),window.addEventListener("pageshow",i),i(),()=>{clearInterval(a),document.removeEventListener("visibilitychange",i),window.removeEventListener("focus",i),window.removeEventListener("pageshow",i)}}}}var Q={schemaVersion:1,years:[2026],verifiedOn:"2026-09-30",source:"https://www.lufengshi.gov.cn/swlfsjj/gkmlpt/content/1/1199/mpost_1199727.html",holidays:[["2026-01-01","2026-01-03"],["2026-02-15","2026-02-23"],["2026-04-04","2026-04-06"],["2026-05-01","2026-05-05"],["2026-06-19","2026-06-21"],["2026-09-25","2026-09-27"],["2026-10-01","2026-10-07"]]};var ee="https://github.com/a961282799-crypto/dsh-timeband/tree/main/calendars",H=64*1024,f=class extends Error{kind;constructor(r){super(r),this.kind=r}};function B(n){if(typeof n!="string"||!/^\d{4}-\d{2}-\d{2}$/.test(n))return!1;let r=new Date(`${n}T00:00:00Z`);return Number.isFinite(r.getTime())&&r.toISOString().slice(0,10)===n}function E(n){try{if(new TextEncoder().encode(n).length>H)throw new Error;let r=JSON.parse(n);if(!r||typeof r!="object")throw new Error;let e=r;if(e.schemaVersion!==1||!Array.isArray(e.years)||!e.years.length||e.years.length>20)throw new Error;let a=e.years;if(a.some((l,s)=>!Number.isInteger(l)||l<2e3||l>9998||s>0&&l<=a[s-1]))throw new Error;if(!B(e.verifiedOn)||typeof e.source!="string")throw new Error;let i=new URL(e.source);if(i.protocol!=="https:"||i.username||i.password||!(i.hostname==="gov.cn"||i.hostname.endsWith(".gov.cn")))throw new Error;if(!Array.isArray(e.holidays)||e.holidays.length>400)throw new Error;let o=[];for(let l of e.holidays){if(!Array.isArray(l)||l.length!==2)throw new Error;let[s,p]=l;if(!B(s)||!B(p)||s>p||s.slice(0,4)!==p.slice(0,4)||!a.includes(Number(s.slice(0,4))))throw new Error;if(o.length&&s<=o.at(-1)[1])throw new Error;o.push([s,p])}if(a.some(l=>!o.some(([s])=>Number(s.slice(0,4))===l)))throw new Error;return{schemaVersion:1,years:[...a],verifiedOn:e.verifiedOn,source:i.href,holidays:o}}catch{throw new f("invalid")}}var m=E(JSON.stringify(Q));var T="dsh-timeband/calendar/v1";function te(n=()=>window.localStorage){let r=new Set,e=()=>{try{let o=n().getItem(T);return o===null?{data:m,imported:!1,issue:null}:{data:E(o),imported:!0,issue:null}}catch(o){return{data:m,imported:!1,issue:o instanceof f?o.kind:"storage"}}},a=e(),i=o=>{a=o;for(let l of r)l()};return{getSnapshot:()=>a,subscribe(o){return r.add(o),()=>{r.delete(o)}},import(o){let l=E(o);try{n().setItem(T,JSON.stringify(l))}catch{throw new f("storage")}i({data:l,imported:!0,issue:null})},restore(){try{n().removeItem(T)}catch{throw new f("storage")}i({data:m,imported:!1,issue:null})},start(){let o=()=>i(e()),l=s=>{(s.key===T||s.key===null)&&o()};return window.addEventListener("storage",l),window.addEventListener("focus",o),()=>{window.removeEventListener("storage",l),window.removeEventListener("focus",o)}}}}var c=require("react"),de=require("react-dom");var ae="https://api-docs.deepseek.com/quick_start/pricing/",x=36e5,ne=24*x,ke=8*x,j=[0,9,12,14,18,24];function k(n,r=m){if(!Number.isFinite(n)||!Number.isFinite(new Date(n).getTime()))throw new RangeError("Invalid timestamp");let e=new Date(n+ke),a=e.toISOString().slice(0,10),i=Date.parse(`${a}T00:00:00+08:00`),o=r.holidays.some(([u,g])=>a>=u&&a<=g),l=e.getUTCDay()===0||e.getUTCDay()===6,s=r.years.includes(e.getUTCFullYear());return{key:a,midnight:i,kind:o?"holiday":l?"weekend":s?"weekday":"unverified",covered:s,hour:(n-i)/x}}function Se(n,r=m){let{kind:e}=k(n,r);if(e==="holiday"||e==="weekend")return[{start:0,end:24,band:"offpeak"}];let a=e==="unverified"?"unknown":"peak";return[{start:0,end:9,band:"offpeak"},{start:9,end:12,band:a},{start:12,end:14,band:"offpeak"},{start:14,end:18,band:a},{start:18,end:24,band:"offpeak"}]}function M(n,r=m){let{hour:e,kind:a}=k(n,r);return a==="holiday"||a==="weekend"||e<9||e>=12&&e<14||e>=18?"offpeak":a==="unverified"?"unknown":"peak"}function Ne(n,r=m){let e=M(n,r),{midnight:a}=k(n,r);for(let i=0;i<370;i++)for(let o of j){let l=a+i*ne+o*x;if(l<=n)continue;let s=M(l,r);if(s!==e)return{at:l,band:s}}return null}function Ce(n,r=m){let e=k(n,r),a=Number(e.key.slice(0,4));if(!e.covered)return{expiresOn:null,notice:"uncovered"};for(;r.years.includes(a+1);)a++;let i=`${a}-12-31`,o=Date.parse(`${a+1}-01-01T00:00:00+08:00`);return{expiresOn:i,notice:o-e.midnight<=30*ne?"expiresSoon":null}}function re(){let n,r=0,e=0,a;return(i,o=m)=>{if(!Number.isFinite(i))throw new RangeError("Invalid timestamp");if(a&&n===o&&i>=r&&i<e)return a;let{hour:l,...s}=k(i,o),p=s.kind==="holiday"||s.kind==="weekend",u=p?0:j.findLast(y=>y<=l),g=p?24:j.find(y=>y>l);return r=s.midnight+u*x,e=s.midnight+g*x,n=o,a={day:s,band:M(i,o),next:Ne(i,o),segments:Se(i,o),coverage:Ce(i,o)},a}}function oe(n){let r=Math.max(0,Math.ceil(n/1e3)),e=Math.floor(r/86400),a=Math.floor(r/3600)%24,i=Math.floor(r/60)%60,o=[];return e>0&&o.push({value:e,unit:"days"}),r>=3600&&o.push({value:a,unit:"hours"}),r>=60&&o.push({value:i,unit:"minutes"}),{major:o,seconds:r%60}}var t=require("react/jsx-runtime"),Ee=new Intl.DateTimeFormat("zh-CN",{timeZone:"Asia/Shanghai",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23"}),Te=new Intl.DateTimeFormat("en-GB",{timeZone:"Asia/Shanghai",hour:"2-digit",minute:"2-digit",hourCycle:"h23"});function ie({segments:n,hour:r,small:e=!1}){return(0,t.jsxs)("div",{className:`dtb-track${e?" dtb-track-small":""}`,"aria-hidden":"true",children:[n.map(a=>(0,t.jsx)("span",{className:`dtb-segment dtb-${a.band}`,style:{left:`${a.start/24*100}%`,width:`${(a.end-a.start)/24*100}%`}},a.start)),(0,t.jsx)("span",{className:"dtb-cursor",style:{left:`${r/24*100}%`}})]})}function se({wide:n,useClock:r,t:e,calendarStore:a}){let i=r(d=>d),o=(0,c.useSyncExternalStore)(a.subscribe,a.getSnapshot),l=(0,c.useMemo)(()=>re(),[]),{day:s,band:p,next:u,segments:g,coverage:y}=l(i,o.data),I=(i-s.midnight)/x,S=u!==null&&u.band!=="unknown"&&p!=="unknown",[D,P]=(0,c.useState)(!1),h=(0,c.useRef)(null),v=(0,c.useRef)(null),U=(0,c.useRef)(null),_=(0,c.useRef)(null),[F,N]=(0,c.useState)(null),[K,V]=(0,c.useState)(!1),w=(0,c.useId)(),$=S?oe(u.at-i):null,L=$?.major.map(d=>`${d.value}${e(d.unit)}`).join("")??"",R=$?`${$.seconds}${e("seconds")}`:"\u2014",z=`${L}${R}`,Y=(0,t.jsxs)("span",{className:"dtb-countdown",children:[(0,t.jsx)("span",{className:"dtb-count-main",children:L||R}),L&&(0,t.jsx)("small",{className:"dtb-count-seconds",children:R})]}),C=S?u.band==="peak"?"nextPeak":"nextOffpeak":"nextUnknown",W=(0,c.useMemo)(()=>S&&u?Ee.format(u.at):"",[S,u]),G=Te.format(i),J=d=>N(d instanceof f&&d.kind==="storage"?"calendarStorageError":"calendarInvalid"),ue=async d=>{V(!0),N(null);try{if(d.size>H)throw new f("invalid");a.import(await d.text()),N("calendarImported")}catch(b){J(b)}finally{V(!1)}};(0,c.useEffect)(()=>{let d=h.current;if(!d)return;let b=()=>P(d.matches(":popover-open"));return d.addEventListener("toggle",b),()=>d.removeEventListener("toggle",b)},[]),(0,c.useLayoutEffect)(()=>{if(!D)return;let d=()=>{if(!h.current||!v.current)return;let Z=v.current.getBoundingClientRect(),O=h.current.getBoundingClientRect(),be=Math.max(12,Math.min(Z.left,window.innerWidth-O.width-12)),me=Math.max(12,Math.min(Z.top-O.height-12,window.innerHeight-O.height-12));h.current.style.left=`${be}px`,h.current.style.top=`${me}px`};d(),U.current?.focus({preventScroll:!0});let b=new ResizeObserver(d);return h.current&&b.observe(h.current),v.current&&b.observe(v.current),window.addEventListener("resize",d),window.addEventListener("scroll",d,!0),()=>{b.disconnect(),window.removeEventListener("resize",d),window.removeEventListener("scroll",d,!0)}},[D,n]);let X=()=>{h.current?.hidePopover(),P(!1),v.current?.focus({preventScroll:!0})};return(0,t.jsxs)("div",{className:"dtb-root dtb-theme","data-wide":n,"data-band":p,children:[(0,t.jsxs)("button",{type:"button",className:"dtb-chip",ref:v,popovertarget:w,popovertargetaction:"toggle","aria-label":`${e("open")} \xB7 ${e(p)} \xB7 ${e(C)} ${z}`,"aria-expanded":D,"aria-haspopup":"dialog","aria-controls":w,title:`${e(p)} \xB7 ${e(C)} ${z}`,children:[(0,t.jsxs)("span",{className:"dtb-chip-top",children:[(0,t.jsx)("span",{className:`dtb-dot dtb-${p}`}),n&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"dtb-chip-label",children:e(p)}),(0,t.jsx)("span",{className:"dtb-chip-count",children:Y})]})]}),n?(0,t.jsx)(ie,{segments:g,hour:I,small:!0}):(0,t.jsx)("svg",{viewBox:"0 0 24 24",className:"dtb-rail-icon","aria-hidden":"true",children:(0,t.jsx)("path",{d:"M3 17 8 7l5 10 4-7 4 7"})})]}),(0,de.createPortal)((0,t.jsxs)("div",{ref:h,id:w,popover:"auto",role:"dialog","aria-labelledby":`${w}-title`,className:"dtb-card dtb-theme","data-band":p,onKeyDown:d=>{d.key==="Escape"&&(d.preventDefault(),d.stopPropagation(),X())},children:[(0,t.jsxs)("header",{className:"dtb-header",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"dtb-eyebrow",children:"DEEPSEEK / TIMEBAND"}),(0,t.jsx)("h2",{id:`${w}-title`,children:e("title")})]}),(0,t.jsx)("button",{type:"button",className:"dtb-close",ref:U,"aria-label":e("close"),onClick:X,children:"\xD7"})]}),(0,t.jsxs)("div",{className:"dtb-status",children:[(0,t.jsx)("span",{className:`dtb-dot dtb-${p}`}),(0,t.jsx)("strong",{children:e(p)})]}),(0,t.jsxs)("div",{className:"dtb-next",children:[(0,t.jsx)("span",{children:e(C)}),(0,t.jsx)("strong",{"aria-label":`${e(C)} ${z}`,children:Y})]}),(0,t.jsxs)("div",{className:"dtb-date",children:[(0,t.jsx)("span",{children:e("zone")}),(0,t.jsx)("span",{children:W&&(0,t.jsxs)(t.Fragment,{children:[e("nextSwitch")," ",W]})})]}),(0,t.jsxs)("div",{className:"dtb-axis",role:"img","aria-label":`${e("timeline")}\uFF1A${g.map(d=>`${d.start}:00\u2013${d.end}:00 ${e(d.band)}`).join("\uFF1B")}\u3002${e("now")} ${G}`,children:[(0,t.jsxs)("div",{className:"dtb-now",style:{left:`${Math.min(91,Math.max(9,I/24*100))}%`},children:[e("now")," ",G]}),(0,t.jsx)(ie,{segments:g,hour:I}),(0,t.jsxs)("div",{className:"dtb-ticks",children:[(0,t.jsx)("span",{children:"00"}),(0,t.jsx)("span",{children:"06"}),(0,t.jsx)("span",{children:"12"}),(0,t.jsx)("span",{children:"18"}),(0,t.jsx)("span",{children:"24"})]})]}),(0,t.jsxs)("div",{className:"dtb-day-kind",children:[s.key," ",(0,t.jsx)("span",{children:"\xB7"})," ",e(s.kind)]}),g.length>1&&(0,t.jsxs)("div",{className:"dtb-periods",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("span",{children:[(0,t.jsx)("i",{className:`dtb-dot dtb-${s.covered?"peak":"unknown"}`}),e(s.covered?"peak":"unknown")]}),(0,t.jsx)("b",{children:"09:00\u201312:00 \xB7 14:00\u201318:00"})]}),(0,t.jsxs)("div",{children:[(0,t.jsxs)("span",{children:[(0,t.jsx)("i",{className:"dtb-dot dtb-offpeak"}),e("offpeak")]}),(0,t.jsx)("b",{children:e("rest")})]})]}),!s.covered&&(0,t.jsx)("p",{className:"dtb-note",children:e("unknownNote")}),y.notice==="expiresSoon"&&(0,t.jsxs)("p",{className:"dtb-note dtb-calendar-notice",children:[e("calendarExpiresSoon")," ",y.expiresOn]}),(0,t.jsxs)("details",{className:"dtb-details",children:[(0,t.jsx)("summary",{children:e("details")}),(0,t.jsx)("p",{className:"dtb-note",children:e("note")}),(0,t.jsxs)("div",{className:"dtb-calendar-meta",children:[(0,t.jsxs)("span",{children:[e("calendar")," ",o.data.years.join("\u3001")," \xB7 ",e(o.imported?"calendarLocal":"calendarBuiltin")]}),(0,t.jsxs)("span",{children:[e("calendarVerified")," ",o.data.verifiedOn]})]}),(0,t.jsxs)("div",{className:"dtb-calendar-actions",children:[(0,t.jsx)("button",{type:"button",className:"dtb-button",disabled:K,onClick:()=>_.current?.click(),children:e("calendarImport")}),(0,t.jsx)("button",{type:"button",className:"dtb-button",disabled:K||!o.imported&&!o.issue,onClick:()=>{try{a.restore(),N("calendarRestored")}catch(d){J(d)}},children:e("calendarRestore")}),(0,t.jsxs)("a",{href:ee,target:"_blank",rel:"noreferrer",children:[e("calendarDownload")," \u2197"]}),(0,t.jsx)("input",{type:"file",accept:".json,application/json",ref:_,hidden:!0,"aria-label":e("calendarImport"),onChange:d=>{let b=d.currentTarget.files?.[0];d.currentTarget.value="",b&&ue(b)}})]}),(0,t.jsx)("p",{className:"dtb-note",children:e("calendarImportHint")}),(0,t.jsx)("p",{className:"dtb-note dtb-calendar-feedback",role:"status",children:F?e(F):o.issue?e(o.issue==="invalid"?"calendarSavedInvalid":"calendarStorageError"):""}),(0,t.jsxs)("footer",{className:"dtb-footer",children:[(0,t.jsxs)("a",{href:o.data.source,target:"_blank",rel:"noreferrer",children:[e("calendarSource")," \u2197"]}),(0,t.jsxs)("a",{href:ae,target:"_blank",rel:"noreferrer",children:[e("rule")," \u2197"]})]})]})]}),document.body)]})}var le={title:"\u4ECA\u65E5\u65F6\u6BB5",zone:"\u5317\u4EAC\u65F6\u95F4 \xB7 UTC+8",peak:"\u5CF0\u65F6\u6BB5",offpeak:"\u8C37\u65F6\u6BB5",unknown:"\u5F85\u6838\u5B9E",nextPeak:"\u8DDD\u79BB\u5CF0\u65F6\u6BB5",nextOffpeak:"\u8DDD\u79BB\u8C37\u65F6\u6BB5",nextUnknown:"\u540E\u7EED\u65E5\u5386\u5F85\u66F4\u65B0",weekday:"\u5468\u4E00\u81F3\u5468\u4E94",weekend:"\u5468\u672B \xB7 \u5168\u5929\u8C37\u65F6\u6BB5",holiday:"\u516C\u5171\u5047\u671F \xB7 \u5168\u5929\u8C37\u65F6\u6BB5",unverified:"\u672C\u5E74\u5EA6\u8282\u5047\u65E5\u65E5\u5386\u5F85\u66F4\u65B0",allDay:"\u5168\u5929",rest:"\u5176\u4F59\u65F6\u6BB5",now:"\u73B0\u5728",nextSwitch:"\u4E0B\u6B21\u5207\u6362\uFF1A",close:"\u5173\u95ED\u65F6\u95F4\u8F74",open:"\u67E5\u770B\u5CF0\u8C37\u65F6\u95F4\u8F74",rule:"DeepSeek \u5B98\u65B9\u65F6\u6BB5\u89C4\u5219",details:"\u65F6\u6BB5\u89C4\u5219\u4E0E\u65E5\u5386",calendar:"\u65E5\u5386\u8986\u76D6\uFF1A",note:"\u5468\u672B\uFF08\u542B\u8C03\u4F11\u4E0A\u73ED\u65E5\uFF09\u53CA\u516C\u5171\u5047\u671F\u5168\u5929\u4E3A\u8C37\u65F6\u6BB5\u3002",calendarBuiltin:"\u5185\u7F6E",calendarLocal:"\u672C\u5730\u5BFC\u5165",calendarVerified:"\u6838\u5BF9\u65E5\u671F\uFF1A",calendarImport:"\u5BFC\u5165\u65E5\u5386",calendarRestore:"\u6062\u590D\u5185\u7F6E",calendarDownload:"\u83B7\u53D6\u65B0\u65E5\u5386",calendarSource:"\u5047\u671F\u516C\u544A\u6765\u6E90",calendarImportHint:"\u9009\u62E9\u4ECE\u9879\u76EE\u83B7\u53D6\u7684\u65E5\u5386\u6587\u4EF6\u3002\u5BFC\u5165\u540E\u6309\u6587\u4EF6\u8986\u76D6\u7684\u5E74\u4EFD\u5224\u65AD\uFF1B\u672A\u6536\u5F55\u5E74\u4EFD\u4ECD\u63D0\u793A\u5F85\u6838\u5B9E\u3002",calendarImported:"\u65E5\u5386\u5DF2\u5BFC\u5165\u5E76\u4FDD\u5B58\uFF0C\u65F6\u95F4\u8F74\u5DF2\u66F4\u65B0\u3002",calendarRestored:"\u5DF2\u6062\u590D\u5185\u7F6E\u65E5\u5386\u3002",calendarInvalid:"\u65E5\u5386\u683C\u5F0F\u6216\u6765\u6E90\u4E0D\u7B26\u5408\u8981\u6C42\uFF0C\u8BF7\u4F7F\u7528\u9879\u76EE\u63D0\u4F9B\u7684\u6587\u4EF6\uFF08\u6700\u5927 64 KB\uFF09\u3002\u539F\u65E5\u5386\u4FDD\u6301\u4E0D\u53D8\u3002",calendarStorageError:"\u65E0\u6CD5\u4FDD\u5B58\u65E5\u5386\uFF0C\u8BF7\u68C0\u67E5\u5E94\u7528\u7684\u672C\u5730\u5B58\u50A8\u6743\u9650\u540E\u91CD\u8BD5\u3002",calendarSavedInvalid:"\u5DF2\u4FDD\u5B58\u7684\u65E5\u5386\u65E0\u6CD5\u8BFB\u53D6\uFF0C\u5F53\u524D\u4F7F\u7528\u5185\u7F6E\u65E5\u5386\uFF1B\u53EF\u91CD\u65B0\u5BFC\u5165\u6216\u6062\u590D\u5185\u7F6E\u3002",calendarExpiresSoon:"\u65E5\u5386\u5373\u5C06\u5230\u671F\uFF0C\u8BF7\u53CA\u65F6\u66F4\u65B0\u3002\u6709\u6548\u81F3\uFF1A",unknownNote:"\u7F3A\u5C11\u672C\u5E74\u5EA6\u5047\u671F\u6570\u636E\uFF0C\u5DE5\u4F5C\u65E5\u5CF0\u65F6\u6BB5\u6682\u4E0D\u4F5C\u786E\u5B9A\u5224\u65AD\u3002",timeline:"\u5317\u4EAC\u65F6\u95F4 24 \u5C0F\u65F6\u65F6\u95F4\u8F74",days:"\u5929",hours:"\u5C0F\u65F6",minutes:"\u5206\u949F",seconds:"\u79D2"},ce={title:"Today\u2019s schedule",zone:"Beijing time \xB7 UTC+8",peak:"Peak",offpeak:"Off-peak",unknown:"Unverified",nextPeak:"Until peak hours",nextOffpeak:"Until off-peak",nextUnknown:"Calendar update needed",weekday:"Monday\u2013Friday",weekend:"Weekend \xB7 off-peak all day",holiday:"Public holiday \xB7 off-peak all day",unverified:"Holiday calendar needs an update",allDay:"All day",rest:"All other hours",now:"Now",nextSwitch:"Next change:",close:"Close timeline",open:"View peak hours timeline",rule:"DeepSeek official schedule",details:"Schedule rules and calendar",calendar:"Calendar coverage:",note:"Weekends (including makeup workdays) and public holidays are off-peak all day.",calendarBuiltin:"Built-in",calendarLocal:"Local import",calendarVerified:"Checked on:",calendarImport:"Import calendar",calendarRestore:"Restore built-in",calendarDownload:"Get new calendar",calendarSource:"Holiday notice source",calendarImportHint:"Choose a calendar file from this project. Imported coverage replaces the current calendar; other years remain unverified.",calendarImported:"Calendar saved. The timeline is updated.",calendarRestored:"Built-in calendar restored.",calendarInvalid:"Invalid calendar format or source. Use a project calendar file (up to 64 KB). Your current calendar is unchanged.",calendarStorageError:"Calendar could not be saved. Check local storage permissions and try again.",calendarSavedInvalid:"Saved calendar is unreadable; using the built-in calendar. Import again or restore it.",calendarExpiresSoon:"Calendar expires soon. Please update. Valid until:",unknownNote:"Holiday data for this year is unavailable; weekday peak periods are unverified.",timeline:"24-hour timeline in Beijing time",days:"d",hours:"h",minutes:"min",seconds:"s"};var pe=`.dtb-theme {
3
+ --dtb-bg: var(--dsw-alias-bg-base, #fff);
4
+ --dtb-text: var(--dsw-alias-label-primary, #252925);
5
+ --dtb-muted: var(--dsw-alias-label-tertiary, #798079);
6
+ --dtb-secondary: var(--dsw-alias-label-secondary, #596459);
7
+ --dtb-line: var(--dsw-alias-border-primary, #e7ebe7);
8
+ --dtb-hover: var(--dsw-alias-interactive-bg-hover, #f4f6f3);
9
+ --dtb-green: #338468; --dtb-peak: #cf7850; --dtb-unknown: #909897;
10
+ color: var(--dtb-text); font-family: inherit; font-size: 12px; box-sizing: border-box;
11
+ }
12
+ .dtb-theme *, .dtb-theme *::before, .dtb-theme *::after { box-sizing: border-box; }
13
+ .dtb-root { min-width: 0; width: 100%; }
14
+ .dtb-chip { display: flex; flex-direction: column; justify-content: center; gap: 4px; width: 100%; min-width: 126px; height: 44px; padding: 5px 9px; border: 0; border-radius: 8px; background: transparent; color: inherit; font: inherit; cursor: pointer; }
15
+ .dtb-chip:hover, .dtb-chip[aria-expanded='true'], .dtb-close:hover, .dtb-button:hover:enabled { background: var(--dtb-hover); }
16
+ .dtb-chip:focus-visible, .dtb-close:focus-visible, .dtb-button:focus-visible, .dtb-card a:focus-visible, .dtb-details summary:focus-visible { outline: 2px solid var(--dtb-green); outline-offset: 3px; }
17
+ .dtb-chip-top { display: flex; flex-wrap: wrap; align-items: center; width: 100%; gap: 2px 6px; }
18
+ .dtb-chip-label { white-space: nowrap; font-size: 11px; }
19
+ .dtb-chip-count { flex-shrink: 0; margin-left: auto; color: var(--dtb-muted); font-size: 9px; font-variant-numeric: tabular-nums; }
20
+ .dtb-countdown { display: inline-flex; align-items: baseline; gap: 4px; white-space: nowrap; }
21
+ .dtb-count-seconds { font-size: .58em; color: var(--dtb-muted); letter-spacing: 0; }
22
+ .dtb-chip-count .dtb-countdown { gap: 2px; }
23
+ .dtb-chip-count .dtb-count-seconds { font-size: .8em; }
24
+ .dtb-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; flex: none; }
25
+ .dtb-offpeak { background: var(--dtb-green); }
26
+ .dtb-peak { background: var(--dtb-peak); }
27
+ .dtb-unknown { background: repeating-linear-gradient(135deg, var(--dtb-unknown) 0 3px, transparent 3px 5px); }
28
+ .dtb-track { width: 100%; height: 12px; position: relative; border-radius: 4px; }
29
+ .dtb-segment { position: absolute; height: 100%; opacity: .8; border-left: 2px solid var(--dtb-bg); }
30
+ .dtb-segment:first-child { border-radius: 3px 0 0 3px; border-left: 0; }
31
+ .dtb-segment:nth-last-child(2) { border-radius: 0 3px 3px 0; }
32
+ .dtb-segment:first-child:nth-last-child(2) { border-radius: 3px; }
33
+ .dtb-cursor { position: absolute; top: -5px; bottom: -5px; width: 2px; background: var(--dtb-text); box-shadow: 0 0 0 2px var(--dtb-bg); transform: translateX(-1px); }
34
+ .dtb-track-small { height: 4px; }
35
+ .dtb-track-small .dtb-segment { border-left-width: 1px; }
36
+ .dtb-track-small .dtb-cursor { top: -2px; bottom: -2px; width: 1px; box-shadow: 0 0 0 1px var(--dtb-bg); }
37
+ .dtb-root[data-wide='false'] { width: 36px; }
38
+ .dtb-root[data-wide='false'] .dtb-chip { min-width: 0; width: 36px; height: 36px; padding: 6px; position: relative; }
39
+ .dtb-root[data-wide='false'] .dtb-chip-top { position: absolute; right: 4px; top: 5px; width: auto; }
40
+ .dtb-rail-icon { width: 23px; height: 23px; stroke: currentColor; stroke-width: 1.5; fill: none; }
41
+ /* DSH rc.2 layout adapter: only reflow the two native footer containers when
42
+ this plugin is their sole action and the Desktop account launcher exists.
43
+ No DOM mutation, private class names, account replacement or hidden labels.
44
+ Other footer plugins / unknown layouts retain the native stacked layout. */
45
+ div:has(> div > .dtb-root[data-wide='true']:only-child):has(> div button[data-collapsed='false']) {
46
+ display: flex; flex-direction: row-reverse; flex-wrap: wrap; align-items: center; gap: 4px;
47
+ }
48
+ div:has(> div > .dtb-root[data-wide='true']:only-child):has(> div button[data-collapsed='false']) > div:has(> .dtb-root) {
49
+ flex: 1 1 126px; width: auto; min-width: 126px;
50
+ }
51
+ div:has(> div > .dtb-root[data-wide='true']:only-child):has(> div button[data-collapsed='false']) > div:not(:has(> .dtb-root)) {
52
+ flex: 1 1 40px; width: auto; min-width: 40px;
53
+ }
54
+ .dtb-card { position: fixed; inset: auto; margin: 0; padding: 22px; width: 362px; max-width: calc(100vw - 24px); max-height: calc(100dvh - 24px); overflow-y: auto; background: var(--dtb-bg); border: 1px solid var(--dtb-line); border-radius: 16px; box-shadow: 0 12px 48px #0002, 0 2px 6px #0001; }
55
+ .dtb-card::backdrop { background: transparent; }
56
+ .dtb-header { display: flex; justify-content: space-between; align-items: start; }
57
+ .dtb-eyebrow { font-size: 9px; letter-spacing: .16em; color: var(--dtb-muted); }
58
+ .dtb-header h2 { margin: 6px 0 0; font-size: 15px; font-weight: 550; letter-spacing: .02em; }
59
+ .dtb-close { border: 0; background: transparent; color: var(--dtb-muted); width: 28px; height: 28px; border-radius: 7px; font-size: 22px; line-height: 24px; cursor: pointer; }
60
+ .dtb-status { display: flex; gap: 9px; align-items: center; margin-top: 28px; }
61
+ .dtb-status .dtb-dot { width: 8px; height: 8px; }
62
+ .dtb-status strong { font-weight: 550; font-size: 25px; letter-spacing: -.04em; }
63
+ .dtb-next { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px; margin-top: 17px; }
64
+ .dtb-next > span { color: var(--dtb-secondary); font-size: 12px; }
65
+ .dtb-next strong { margin-left: auto; max-width: 100%; font-size: 24px; font-weight: 400; letter-spacing: -.045em; font-variant-numeric: tabular-nums; }
66
+ .dtb-date { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 8px; color: var(--dtb-secondary); font-size: 11px; margin-top: 6px; }
67
+ .dtb-date > span:last-child { margin-left: auto; }
68
+ .dtb-axis { position: relative; margin: 39px 0 19px; }
69
+ .dtb-now { position: absolute; top: -12px; transform: translate(-50%, -100%); font-size: 11px; white-space: nowrap; color: var(--dtb-secondary); }
70
+ .dtb-ticks { display: flex; justify-content: space-between; margin-top: 10px; color: var(--dtb-secondary); font-size: 11px; font-variant-numeric: tabular-nums; }
71
+ .dtb-day-kind { border-top: 1px solid var(--dtb-line); padding-top: 16px; margin-bottom: 13px; font-size: 11px; color: var(--dtb-secondary); }
72
+ .dtb-day-kind > span { padding: 0 4px; }
73
+ .dtb-periods > div { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin: 11px 0; font-size: 11px; }
74
+ .dtb-periods span { display: flex; align-items: center; gap: 7px; white-space: nowrap; }
75
+ .dtb-periods b { font-weight: 400; font-size: 11px; font-variant-numeric: tabular-nums; text-align: right; }
76
+ .dtb-note { font-size: 11px; color: var(--dtb-secondary); line-height: 1.7; margin: 13px 0; }
77
+ .dtb-details { border-top: 1px solid var(--dtb-line); margin-top: 16px; padding-top: 12px; }
78
+ .dtb-details summary { width: fit-content; cursor: pointer; font-size: 11px; color: var(--dtb-secondary); line-height: 1.8; }
79
+ .dtb-calendar-meta { display: flex; flex-direction: column; gap: 5px; font-size: 11px; color: var(--dtb-secondary); }
80
+ .dtb-calendar-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; font-size: 11px; }
81
+ .dtb-button { padding: 5px 9px; border: 1px solid var(--dtb-line); border-radius: 6px; background: transparent; color: inherit; font: inherit; cursor: pointer; }
82
+ .dtb-button:disabled { opacity: .5; cursor: default; }
83
+ .dtb-calendar-actions a { color: var(--dtb-green); text-decoration: none; }
84
+ .dtb-calendar-feedback:empty { display: none; }
85
+ .dtb-calendar-notice { border-left: 2px solid var(--dtb-peak); padding-left: 9px; }
86
+ .dtb-footer { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; padding-top: 3px; font-size: 10px; color: var(--dtb-muted); }
87
+ .dtb-footer a { color: inherit; text-decoration: none; }
88
+ .dtb-footer a:hover { text-decoration: underline; }
89
+ @media (prefers-color-scheme: dark) {
90
+ .dtb-theme { --dtb-secondary: var(--dsw-alias-label-secondary, #b6bfb6); }
91
+ .dtb-theme { --dtb-bg: var(--dsw-alias-bg-base, #242624); --dtb-text: var(--dsw-alias-label-primary, #e5eae5); --dtb-muted: var(--dsw-alias-label-tertiary, #9aa59e); --dtb-line: var(--dsw-alias-border-primary, #3b413c); --dtb-hover: var(--dsw-alias-interactive-bg-hover, #303630); --dtb-green: #6cbd9e; --dtb-peak: #eaa77a; }
92
+ }
93
+ `;var De=["slots","locale"];function $e(n){n.effect(()=>n.locale.register("timeband",{zh:le,en:ce})),n.effect(()=>{let a=document.createElement("style");return a.dataset.plugin="dsh-timeband",a.textContent=pe,document.head.append(a),()=>a.remove()});let r=q(),e=te();n.effect(()=>r.start()),n.effect(()=>e.start()),n.slots.inject("sidebar.footer.action",()=>n.slots.register({name:"sidebar.footer.action",id:"dsh-timeband",order:100,locale:"timeband",inject:()=>({hooks:{clock:r},props:{calendarStore:e}})},se))}
94
+ return module.exports;}});
95
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/client.ts", "../src/clock.ts", "../calendars/2026.json", "../src/calendar.ts", "../src/calendar-store.ts", "../src/view.tsx", "../src/schedule.ts", "../src/locales.ts", "../src/style.css"],
4
+ "sourcesContent": ["import type { Context } from '@deepseek-ai/cordis';\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client';\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client';\nimport type {} from '@deepseek-ai/dsh-client-locale/client';\nimport { createClock } from './clock.ts';\nimport { createCalendarStore } from './calendar-store.ts';\nimport { TimeBand } from './view.tsx';\nimport { zh, en } from './locales.ts';\nimport css from './style.css';\n\nexport const inject = ['slots', 'locale'];\nexport function apply(ctx: Context): void {\n ctx.effect(() => ctx.locale.register('timeband', { zh, en }));\n ctx.effect(() => {\n const style = document.createElement('style');\n style.dataset.plugin = 'dsh-timeband';\n style.textContent = css;\n document.head.append(style);\n return () => style.remove();\n });\n const clock = createClock();\n const calendarStore = createCalendarStore();\n ctx.effect(() => clock.start());\n ctx.effect(() => calendarStore.start());\n ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({\n name: 'sidebar.footer.action', id: 'dsh-timeband', order: 100, locale: 'timeband',\n inject: () => ({ hooks: { clock }, props: { calendarStore } }),\n }, TimeBand));\n}\n", "/** One Cordis-owned clock for every mounted view. Always re-read wall time after sleep. */\nexport function createClock() {\n let snapshot = Date.now();\n const listeners = new Set<() => void>();\n const update = () => {\n snapshot = Date.now();\n for (const listener of listeners) listener();\n };\n return {\n getSnapshot: () => snapshot,\n subscribe(listener: () => void) { listeners.add(listener); return () => { listeners.delete(listener); }; },\n start() {\n let timer: ReturnType<typeof setInterval> | undefined;\n const resume = () => {\n clearInterval(timer);\n timer = undefined;\n update();\n if (document.visibilityState !== 'hidden') timer = setInterval(update, 1000);\n };\n document.addEventListener('visibilitychange', resume);\n window.addEventListener('focus', resume);\n window.addEventListener('pageshow', resume);\n resume();\n return () => {\n clearInterval(timer);\n document.removeEventListener('visibilitychange', resume);\n window.removeEventListener('focus', resume);\n window.removeEventListener('pageshow', resume);\n };\n },\n };\n}\n", "{\n \"schemaVersion\": 1,\n \"years\": [2026],\n \"verifiedOn\": \"2026-09-30\",\n \"source\": \"https://www.lufengshi.gov.cn/swlfsjj/gkmlpt/content/1/1199/mpost_1199727.html\",\n \"holidays\": [\n [\"2026-01-01\", \"2026-01-03\"],\n [\"2026-02-15\", \"2026-02-23\"],\n [\"2026-04-04\", \"2026-04-06\"],\n [\"2026-05-01\", \"2026-05-05\"],\n [\"2026-06-19\", \"2026-06-21\"],\n [\"2026-09-25\", \"2026-09-27\"],\n [\"2026-10-01\", \"2026-10-07\"]\n ]\n}\n", "import bundled from '../calendars/2026.json' with { type: 'json' };\n\nexport interface HolidayCalendar {\n readonly schemaVersion: 1;\n readonly years: readonly number[];\n readonly verifiedOn: string;\n readonly source: string;\n readonly holidays: readonly (readonly [string, string])[];\n}\nexport const CALENDAR_DOWNLOAD = 'https://github.com/a961282799-crypto/dsh-timeband/tree/main/calendars';\nexport const MAX_CALENDAR_BYTES = 64 * 1024;\n\nexport class CalendarError extends Error {\n readonly kind: 'invalid' | 'storage';\n constructor(kind: 'invalid' | 'storage') { super(kind); this.kind = kind; }\n}\n\nfunction validDate(value: unknown): value is string {\n if (typeof value !== 'string' || !/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return false;\n const parsed = new Date(`${value}T00:00:00Z`);\n return Number.isFinite(parsed.getTime()) && parsed.toISOString().slice(0, 10) === value;\n}\n\n/** Import only data, with valid dates, explicit coverage and a government source. */\nexport function parseCalendar(text: string): HolidayCalendar {\n try {\n if (new TextEncoder().encode(text).length > MAX_CALENDAR_BYTES) throw new Error();\n const value: unknown = JSON.parse(text);\n if (!value || typeof value !== 'object') throw new Error();\n const data = value as Record<string, unknown>;\n if (data.schemaVersion !== 1 || !Array.isArray(data.years) || !data.years.length || data.years.length > 20) throw new Error();\n const years: number[] = data.years;\n if (years.some((year, index) => !Number.isInteger(year) || year < 2000 || year > 9998 || (index > 0 && year <= years[index - 1]!))) throw new Error();\n if (!validDate(data.verifiedOn) || typeof data.source !== 'string') throw new Error();\n const source = new URL(data.source);\n if (source.protocol !== 'https:' || source.username || source.password || !(source.hostname === 'gov.cn' || source.hostname.endsWith('.gov.cn'))) throw new Error();\n if (!Array.isArray(data.holidays) || data.holidays.length > 400) throw new Error();\n const holidays: [string, string][] = [];\n for (const interval of data.holidays) {\n if (!Array.isArray(interval) || interval.length !== 2) throw new Error();\n const [start, end] = interval;\n if (!validDate(start) || !validDate(end) || start > end || start.slice(0, 4) !== end.slice(0, 4) || !years.includes(Number(start.slice(0, 4)))) throw new Error();\n if (holidays.length && start <= holidays.at(-1)![1]) throw new Error();\n holidays.push([start, end]);\n }\n // A covered year must have actual holiday entries, rather than an empty claim.\n if (years.some(year => !holidays.some(([start]) => Number(start.slice(0, 4)) === year))) throw new Error();\n return { schemaVersion: 1, years: [...years], verifiedOn: data.verifiedOn, source: source.href, holidays };\n } catch { throw new CalendarError('invalid'); }\n}\n\n/** Verified public-holiday intervals, inclusive; makeup weekends remain off-peak. */\nexport const calendar = parseCalendar(JSON.stringify(bundled));\n", "import { calendar, CalendarError, parseCalendar } from './calendar.ts';\nimport type { HolidayCalendar } from './calendar.ts';\n\nexport const CALENDAR_STORAGE_KEY = 'dsh-timeband/calendar/v1';\ntype CalendarStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;\nexport interface CalendarState {\n readonly data: HolidayCalendar;\n readonly imported: boolean;\n readonly issue: 'invalid' | 'storage' | null;\n}\n\n/** One persisted calendar shared by the plugin views, scoped to this web origin. */\nexport function createCalendarStore(getStorage: () => CalendarStorage = () => window.localStorage) {\n const listeners = new Set<() => void>();\n const read = (): CalendarState => {\n try {\n const saved = getStorage().getItem(CALENDAR_STORAGE_KEY);\n return saved === null ? { data: calendar, imported: false, issue: null } : { data: parseCalendar(saved), imported: true, issue: null };\n } catch (error) {\n return { data: calendar, imported: false, issue: error instanceof CalendarError ? error.kind : 'storage' };\n }\n };\n let snapshot = read();\n const update = (state: CalendarState) => { snapshot = state; for (const listener of listeners) listener(); };\n return {\n getSnapshot: () => snapshot,\n subscribe(listener: () => void) { listeners.add(listener); return () => { listeners.delete(listener); }; },\n import(text: string) {\n const data = parseCalendar(text);\n try { getStorage().setItem(CALENDAR_STORAGE_KEY, JSON.stringify(data)); }\n catch { throw new CalendarError('storage'); }\n update({ data, imported: true, issue: null });\n },\n restore() {\n try { getStorage().removeItem(CALENDAR_STORAGE_KEY); }\n catch { throw new CalendarError('storage'); }\n update({ data: calendar, imported: false, issue: null });\n },\n start() {\n const refresh = () => update(read());\n const onStorage = (event: StorageEvent) => { if (event.key === CALENDAR_STORAGE_KEY || event.key === null) refresh(); };\n window.addEventListener('storage', onStorage);\n window.addEventListener('focus', refresh);\n return () => { window.removeEventListener('storage', onStorage); window.removeEventListener('focus', refresh); };\n },\n };\n}\nexport type CalendarStore = ReturnType<typeof createCalendarStore>;\n", "import { useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client';\nimport { countdown, createScheduleReader, HOUR, PRICING_SOURCE } from './schedule.ts';\nimport { CalendarError, CALENDAR_DOWNLOAD, MAX_CALENDAR_BYTES } from './calendar.ts';\nimport type { CalendarStore } from './calendar-store.ts';\nimport type { Segment } from './schedule.ts';\nimport type { TextKey } from './locales.ts';\n\nexport type TimeBandProps = PropsRuntime<'sidebar.footer.action'> & PropsLocale<'timeband'> & {\n useClock: (select: (now: number) => number) => number;\n calendarStore: CalendarStore;\n};\n\nconst dateFormatter = new Intl.DateTimeFormat('zh-CN', {\n timeZone: 'Asia/Shanghai', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hourCycle: 'h23',\n});\nconst timeFormatter = new Intl.DateTimeFormat('en-GB', { timeZone: 'Asia/Shanghai', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' });\n\nfunction Track({ segments, hour, small = false }: { segments: Segment[]; hour: number; small?: boolean }) {\n return <div className={`dtb-track${small ? ' dtb-track-small' : ''}`} aria-hidden=\"true\">\n {segments.map(segment => <span key={segment.start} className={`dtb-segment dtb-${segment.band}`}\n style={{ left: `${segment.start / 24 * 100}%`, width: `${(segment.end - segment.start) / 24 * 100}%` }} />)}\n <span className=\"dtb-cursor\" style={{ left: `${hour / 24 * 100}%` }} />\n </div>;\n}\n\nexport function TimeBand({ wide, useClock, t, calendarStore }: TimeBandProps) {\n const now = useClock(value => value);\n const calendarState = useSyncExternalStore(calendarStore.subscribe, calendarStore.getSnapshot);\n const readSchedule = useMemo(() => createScheduleReader(), []);\n const { day, band, next, segments, coverage } = readSchedule(now, calendarState.data);\n const hour = (now - day.midnight) / HOUR;\n const knownNext = next !== null && next.band !== 'unknown' && band !== 'unknown';\n const [open, setOpen] = useState(false);\n const panel = useRef<HTMLDivElement>(null);\n const trigger = useRef<HTMLButtonElement>(null);\n const close = useRef<HTMLButtonElement>(null);\n const calendarInput = useRef<HTMLInputElement>(null);\n const [feedback, setFeedback] = useState<TextKey | null>(null);\n const [importing, setImporting] = useState(false);\n const id = useId();\n const remaining = knownNext ? countdown(next.at - now) : null;\n const mainText = remaining?.major.map(part => `${part.value}${t(part.unit)}`).join('') ?? '';\n const secondsText = remaining ? `${remaining.seconds}${t('seconds')}` : '\u2014';\n const countdownText = `${mainText}${secondsText}`;\n const countdownView = <span className=\"dtb-countdown\"><span className=\"dtb-count-main\">{mainText || secondsText}</span>\n {mainText && <small className=\"dtb-count-seconds\">{secondsText}</small>}</span>;\n const nextLabel: TextKey = !knownNext ? 'nextUnknown' : next.band === 'peak' ? 'nextPeak' : 'nextOffpeak';\n const nextDate = useMemo(() => knownNext && next ? dateFormatter.format(next.at) : '', [knownNext, next]);\n const time = timeFormatter.format(now);\n const showError = (error: unknown) => setFeedback(error instanceof CalendarError && error.kind === 'storage' ? 'calendarStorageError' : 'calendarInvalid');\n const importCalendar = async (file: File) => {\n setImporting(true); setFeedback(null);\n try {\n if (file.size > MAX_CALENDAR_BYTES) throw new CalendarError('invalid');\n calendarStore.import(await file.text()); setFeedback('calendarImported');\n } catch (error) { showError(error); }\n finally { setImporting(false); }\n };\n\n useEffect(() => {\n const element = panel.current;\n if (!element) return;\n const onToggle = () => setOpen(element.matches(':popover-open'));\n element.addEventListener('toggle', onToggle);\n return () => element.removeEventListener('toggle', onToggle);\n }, []);\n\n useLayoutEffect(() => {\n if (!open) return;\n const position = () => {\n if (!panel.current || !trigger.current) return;\n const anchor = trigger.current.getBoundingClientRect();\n const box = panel.current.getBoundingClientRect();\n const left = Math.max(12, Math.min(anchor.left, window.innerWidth - box.width - 12));\n const top = Math.max(12, Math.min(anchor.top - box.height - 12, window.innerHeight - box.height - 12));\n panel.current.style.left = `${left}px`;\n panel.current.style.top = `${top}px`;\n };\n position();\n close.current?.focus({ preventScroll: true });\n const observer = new ResizeObserver(position);\n if (panel.current) observer.observe(panel.current);\n if (trigger.current) observer.observe(trigger.current);\n window.addEventListener('resize', position);\n window.addEventListener('scroll', position, true);\n return () => { observer.disconnect(); window.removeEventListener('resize', position); window.removeEventListener('scroll', position, true); };\n }, [open, wide]);\n\n const hide = () => { panel.current?.hidePopover(); setOpen(false); trigger.current?.focus({ preventScroll: true }); };\n return <div className=\"dtb-root dtb-theme\" data-wide={wide} data-band={band}>\n <button type=\"button\" className=\"dtb-chip\" ref={trigger} popovertarget={id} popovertargetaction=\"toggle\"\n aria-label={`${t('open')} \u00B7 ${t(band)} \u00B7 ${t(nextLabel)} ${countdownText}`}\n aria-expanded={open} aria-haspopup=\"dialog\" aria-controls={id} title={`${t(band)} \u00B7 ${t(nextLabel)} ${countdownText}`}>\n <span className=\"dtb-chip-top\"><span className={`dtb-dot dtb-${band}`} />\n {wide && <><span className=\"dtb-chip-label\">{t(band)}</span><span className=\"dtb-chip-count\">{countdownView}</span></>}\n </span>\n {wide ? <Track segments={segments} hour={hour} small /> : <svg viewBox=\"0 0 24 24\" className=\"dtb-rail-icon\" aria-hidden=\"true\"><path d=\"M3 17 8 7l5 10 4-7 4 7\" /></svg>}\n </button>\n {createPortal(<div ref={panel} id={id} popover=\"auto\" role=\"dialog\" aria-labelledby={`${id}-title`}\n className=\"dtb-card dtb-theme\" data-band={band}\n onKeyDown={event => { if (event.key === 'Escape') { event.preventDefault(); event.stopPropagation(); hide(); } }}>\n <header className=\"dtb-header\"><div><div className=\"dtb-eyebrow\">DEEPSEEK / TIMEBAND</div><h2 id={`${id}-title`}>{t('title')}</h2></div>\n <button type=\"button\" className=\"dtb-close\" ref={close} aria-label={t('close')} onClick={hide}>\u00D7</button></header>\n <div className=\"dtb-status\"><span className={`dtb-dot dtb-${band}`} /><strong>{t(band)}</strong></div>\n <div className=\"dtb-next\"><span>{t(nextLabel)}</span><strong aria-label={`${t(nextLabel)} ${countdownText}`}>{countdownView}</strong></div>\n <div className=\"dtb-date\"><span>{t('zone')}</span><span>{nextDate && <>{t('nextSwitch')} {nextDate}</>}</span></div>\n <div className=\"dtb-axis\" role=\"img\" aria-label={`${t('timeline')}\uFF1A${segments.map(s => `${s.start}:00\u2013${s.end}:00 ${t(s.band)}`).join('\uFF1B')}\u3002${t('now')} ${time}`}>\n <div className=\"dtb-now\" style={{ left: `${Math.min(91, Math.max(9, hour / 24 * 100))}%` }}>{t('now')} {time}</div>\n <Track segments={segments} hour={hour} />\n <div className=\"dtb-ticks\"><span>00</span><span>06</span><span>12</span><span>18</span><span>24</span></div>\n </div>\n <div className=\"dtb-day-kind\">{day.key} <span>\u00B7</span> {t(day.kind)}</div>\n {segments.length > 1 && <div className=\"dtb-periods\">\n <div><span><i className={`dtb-dot dtb-${day.covered ? 'peak' : 'unknown'}`} />{t(day.covered ? 'peak' : 'unknown')}</span><b>09:00\u201312:00 \u00B7 14:00\u201318:00</b></div>\n <div><span><i className=\"dtb-dot dtb-offpeak\" />{t('offpeak')}</span><b>{t('rest')}</b></div>\n </div>}\n {!day.covered && <p className=\"dtb-note\">{t('unknownNote')}</p>}\n {coverage.notice === 'expiresSoon' && <p className=\"dtb-note dtb-calendar-notice\">{t('calendarExpiresSoon')} {coverage.expiresOn}</p>}\n <details className=\"dtb-details\">\n <summary>{t('details')}</summary>\n <p className=\"dtb-note\">{t('note')}</p>\n <div className=\"dtb-calendar-meta\">\n <span>{t('calendar')} {calendarState.data.years.join('\u3001')} \u00B7 {t(calendarState.imported ? 'calendarLocal' : 'calendarBuiltin')}</span>\n <span>{t('calendarVerified')} {calendarState.data.verifiedOn}</span>\n </div>\n <div className=\"dtb-calendar-actions\">\n <button type=\"button\" className=\"dtb-button\" disabled={importing} onClick={() => calendarInput.current?.click()}>{t('calendarImport')}</button>\n <button type=\"button\" className=\"dtb-button\" disabled={importing || (!calendarState.imported && !calendarState.issue)} onClick={() => {\n try { calendarStore.restore(); setFeedback('calendarRestored'); } catch (error) { showError(error); }\n }}>{t('calendarRestore')}</button>\n <a href={CALENDAR_DOWNLOAD} target=\"_blank\" rel=\"noreferrer\">{t('calendarDownload')} \u2197</a>\n <input type=\"file\" accept=\".json,application/json\" ref={calendarInput} hidden aria-label={t('calendarImport')} onChange={event => {\n const file = event.currentTarget.files?.[0]; event.currentTarget.value = ''; if (file) void importCalendar(file);\n }} />\n </div>\n <p className=\"dtb-note\">{t('calendarImportHint')}</p>\n <p className=\"dtb-note dtb-calendar-feedback\" role=\"status\">{feedback ? t(feedback) : calendarState.issue ? t(calendarState.issue === 'invalid' ? 'calendarSavedInvalid' : 'calendarStorageError') : ''}</p>\n <footer className=\"dtb-footer\"><a href={calendarState.data.source} target=\"_blank\" rel=\"noreferrer\">{t('calendarSource')} \u2197</a><a href={PRICING_SOURCE} target=\"_blank\" rel=\"noreferrer\">{t('rule')} \u2197</a></footer>\n </details>\n </div>, document.body)}\n </div>;\n}\n", "import { calendar } from './calendar.ts';\nimport type { HolidayCalendar } from './calendar.ts';\n\nexport const PRICING_SOURCE = 'https://api-docs.deepseek.com/quick_start/pricing/';\nexport const HOUR = 3_600_000;\nexport const DAY = 24 * HOUR;\nconst CHINA_OFFSET = 8 * HOUR;\nconst BOUNDARIES = [0, 9, 12, 14, 18, 24] as const;\nexport type Band = 'peak' | 'offpeak' | 'unknown';\nexport type DayKind = 'weekday' | 'weekend' | 'holiday' | 'unverified';\nexport interface Segment { start: number; end: number; band: Band }\nexport interface Transition { at: number; band: Band }\n\n/** Shanghai has no daylight-saving transitions in the supported calendar. */\nexport function chinaDay(now: number, data: HolidayCalendar = calendar) {\n if (!Number.isFinite(now) || !Number.isFinite(new Date(now).getTime())) throw new RangeError('Invalid timestamp');\n const date = new Date(now + CHINA_OFFSET);\n const key = date.toISOString().slice(0, 10);\n const midnight = Date.parse(`${key}T00:00:00+08:00`);\n const holiday = data.holidays.some(([start, end]) => key >= start && key <= end);\n const weekend = date.getUTCDay() === 0 || date.getUTCDay() === 6;\n const covered = data.years.includes(date.getUTCFullYear());\n const kind: DayKind = holiday ? 'holiday' : weekend ? 'weekend' : covered ? 'weekday' : 'unverified';\n return { key, midnight, kind, covered, hour: (now - midnight) / HOUR };\n}\n\nexport function todaySegments(now: number, data: HolidayCalendar = calendar): Segment[] {\n const { kind } = chinaDay(now, data);\n if (kind === 'holiday' || kind === 'weekend') return [{ start: 0, end: 24, band: 'offpeak' }];\n const peak: Band = kind === 'unverified' ? 'unknown' : 'peak';\n return [\n { start: 0, end: 9, band: 'offpeak' }, { start: 9, end: 12, band: peak },\n { start: 12, end: 14, band: 'offpeak' }, { start: 14, end: 18, band: peak },\n { start: 18, end: 24, band: 'offpeak' },\n ];\n}\n\nexport function bandAt(now: number, data: HolidayCalendar = calendar): Band {\n const { hour, kind } = chinaDay(now, data);\n if (kind === 'holiday' || kind === 'weekend' || hour < 9 || (hour >= 12 && hour < 14) || hour >= 18) return 'offpeak';\n return kind === 'unverified' ? 'unknown' : 'peak';\n}\n\n/** First real band change, skipping nights, weekends and multi-day public holidays.\n * Stop at an uncertain interval: never promise a peak date beyond calendar coverage.\n */\nexport function nextTransition(now: number, data: HolidayCalendar = calendar): Transition | null {\n const current = bandAt(now, data);\n const { midnight } = chinaDay(now, data);\n for (let day = 0; day < 370; day++) {\n for (const hour of BOUNDARIES) {\n const at = midnight + day * DAY + hour * HOUR;\n if (at <= now) continue;\n const band = bandAt(at, data);\n if (band !== current) return { at, band };\n }\n }\n return null;\n}\n\nexport function calendarCoverage(now: number, data: HolidayCalendar = calendar) {\n const day = chinaDay(now, data);\n let endYear = Number(day.key.slice(0, 4));\n if (!day.covered) return { expiresOn: null, notice: 'uncovered' as const };\n while (data.years.includes(endYear + 1)) endYear++;\n const expiresOn = `${endYear}-12-31`;\n const until = Date.parse(`${endYear + 1}-01-01T00:00:00+08:00`);\n return { expiresOn, notice: until - day.midnight <= 30 * DAY ? 'expiresSoon' as const : null };\n}\n\nexport interface ScheduleSnapshot {\n day: Omit<ReturnType<typeof chinaDay>, 'hour'>;\n band: Band;\n next: Transition | null;\n segments: Segment[];\n coverage: ReturnType<typeof calendarCoverage>;\n}\n\n/** Reuse a schedule within an interval; invalidate at boundaries, midnight,\n * calendar replacement, clock rewind, or a jump after sleep. */\nexport function createScheduleReader() {\n let previous: HolidayCalendar | undefined;\n let start = 0, end = 0;\n let cached: ScheduleSnapshot | undefined;\n return (now: number, data: HolidayCalendar = calendar): ScheduleSnapshot => {\n if (!Number.isFinite(now)) throw new RangeError('Invalid timestamp');\n if (cached && previous === data && now >= start && now < end) return cached;\n const { hour, ...day } = chinaDay(now, data);\n const daily = day.kind === 'holiday' || day.kind === 'weekend';\n const before = daily ? 0 : BOUNDARIES.findLast(boundary => boundary <= hour)!;\n const after = daily ? 24 : BOUNDARIES.find(boundary => boundary > hour)!;\n start = day.midnight + before * HOUR;\n end = day.midnight + after * HOUR;\n previous = data;\n cached = { day, band: bandAt(now, data), next: nextTransition(now, data), segments: todaySegments(now, data), coverage: calendarCoverage(now, data) };\n return cached;\n };\n}\n\n/** Ceiling avoids displaying zero before the boundary actually arrives. */\nexport function countdown(milliseconds: number) {\n const total = Math.max(0, Math.ceil(milliseconds / 1000));\n const days = Math.floor(total / 86400);\n const hours = Math.floor(total / 3600) % 24;\n const minutes = Math.floor(total / 60) % 60;\n const major: { value: number; unit: 'days' | 'hours' | 'minutes' }[] = [];\n if (days > 0) major.push({ value: days, unit: 'days' });\n if (total >= 3600) major.push({ value: hours, unit: 'hours' });\n if (total >= 60) major.push({ value: minutes, unit: 'minutes' });\n return { major, seconds: total % 60 };\n}\n", "export const zh = {\n title: '\u4ECA\u65E5\u65F6\u6BB5', zone: '\u5317\u4EAC\u65F6\u95F4 \u00B7 UTC+8', peak: '\u5CF0\u65F6\u6BB5', offpeak: '\u8C37\u65F6\u6BB5', unknown: '\u5F85\u6838\u5B9E',\n nextPeak: '\u8DDD\u79BB\u5CF0\u65F6\u6BB5', nextOffpeak: '\u8DDD\u79BB\u8C37\u65F6\u6BB5', nextUnknown: '\u540E\u7EED\u65E5\u5386\u5F85\u66F4\u65B0',\n weekday: '\u5468\u4E00\u81F3\u5468\u4E94', weekend: '\u5468\u672B \u00B7 \u5168\u5929\u8C37\u65F6\u6BB5', holiday: '\u516C\u5171\u5047\u671F \u00B7 \u5168\u5929\u8C37\u65F6\u6BB5',\n unverified: '\u672C\u5E74\u5EA6\u8282\u5047\u65E5\u65E5\u5386\u5F85\u66F4\u65B0', allDay: '\u5168\u5929', rest: '\u5176\u4F59\u65F6\u6BB5', now: '\u73B0\u5728',\n nextSwitch: '\u4E0B\u6B21\u5207\u6362\uFF1A', close: '\u5173\u95ED\u65F6\u95F4\u8F74', open: '\u67E5\u770B\u5CF0\u8C37\u65F6\u95F4\u8F74', rule: 'DeepSeek \u5B98\u65B9\u65F6\u6BB5\u89C4\u5219',\n details: '\u65F6\u6BB5\u89C4\u5219\u4E0E\u65E5\u5386', calendar: '\u65E5\u5386\u8986\u76D6\uFF1A', note: '\u5468\u672B\uFF08\u542B\u8C03\u4F11\u4E0A\u73ED\u65E5\uFF09\u53CA\u516C\u5171\u5047\u671F\u5168\u5929\u4E3A\u8C37\u65F6\u6BB5\u3002',\n calendarBuiltin: '\u5185\u7F6E', calendarLocal: '\u672C\u5730\u5BFC\u5165', calendarVerified: '\u6838\u5BF9\u65E5\u671F\uFF1A',\n calendarImport: '\u5BFC\u5165\u65E5\u5386', calendarRestore: '\u6062\u590D\u5185\u7F6E', calendarDownload: '\u83B7\u53D6\u65B0\u65E5\u5386', calendarSource: '\u5047\u671F\u516C\u544A\u6765\u6E90',\n calendarImportHint: '\u9009\u62E9\u4ECE\u9879\u76EE\u83B7\u53D6\u7684\u65E5\u5386\u6587\u4EF6\u3002\u5BFC\u5165\u540E\u6309\u6587\u4EF6\u8986\u76D6\u7684\u5E74\u4EFD\u5224\u65AD\uFF1B\u672A\u6536\u5F55\u5E74\u4EFD\u4ECD\u63D0\u793A\u5F85\u6838\u5B9E\u3002',\n calendarImported: '\u65E5\u5386\u5DF2\u5BFC\u5165\u5E76\u4FDD\u5B58\uFF0C\u65F6\u95F4\u8F74\u5DF2\u66F4\u65B0\u3002', calendarRestored: '\u5DF2\u6062\u590D\u5185\u7F6E\u65E5\u5386\u3002',\n calendarInvalid: '\u65E5\u5386\u683C\u5F0F\u6216\u6765\u6E90\u4E0D\u7B26\u5408\u8981\u6C42\uFF0C\u8BF7\u4F7F\u7528\u9879\u76EE\u63D0\u4F9B\u7684\u6587\u4EF6\uFF08\u6700\u5927 64 KB\uFF09\u3002\u539F\u65E5\u5386\u4FDD\u6301\u4E0D\u53D8\u3002',\n calendarStorageError: '\u65E0\u6CD5\u4FDD\u5B58\u65E5\u5386\uFF0C\u8BF7\u68C0\u67E5\u5E94\u7528\u7684\u672C\u5730\u5B58\u50A8\u6743\u9650\u540E\u91CD\u8BD5\u3002',\n calendarSavedInvalid: '\u5DF2\u4FDD\u5B58\u7684\u65E5\u5386\u65E0\u6CD5\u8BFB\u53D6\uFF0C\u5F53\u524D\u4F7F\u7528\u5185\u7F6E\u65E5\u5386\uFF1B\u53EF\u91CD\u65B0\u5BFC\u5165\u6216\u6062\u590D\u5185\u7F6E\u3002',\n calendarExpiresSoon: '\u65E5\u5386\u5373\u5C06\u5230\u671F\uFF0C\u8BF7\u53CA\u65F6\u66F4\u65B0\u3002\u6709\u6548\u81F3\uFF1A',\n unknownNote: '\u7F3A\u5C11\u672C\u5E74\u5EA6\u5047\u671F\u6570\u636E\uFF0C\u5DE5\u4F5C\u65E5\u5CF0\u65F6\u6BB5\u6682\u4E0D\u4F5C\u786E\u5B9A\u5224\u65AD\u3002',\n timeline: '\u5317\u4EAC\u65F6\u95F4 24 \u5C0F\u65F6\u65F6\u95F4\u8F74', days: '\u5929', hours: '\u5C0F\u65F6', minutes: '\u5206\u949F', seconds: '\u79D2',\n};\nexport type TextKey = keyof typeof zh;\nexport const en: Record<TextKey, string> = {\n title: 'Today\u2019s schedule', zone: 'Beijing time \u00B7 UTC+8', peak: 'Peak', offpeak: 'Off-peak', unknown: 'Unverified',\n nextPeak: 'Until peak hours', nextOffpeak: 'Until off-peak', nextUnknown: 'Calendar update needed',\n weekday: 'Monday\u2013Friday', weekend: 'Weekend \u00B7 off-peak all day', holiday: 'Public holiday \u00B7 off-peak all day',\n unverified: 'Holiday calendar needs an update', allDay: 'All day', rest: 'All other hours', now: 'Now',\n nextSwitch: 'Next change:', close: 'Close timeline', open: 'View peak hours timeline', rule: 'DeepSeek official schedule',\n details: 'Schedule rules and calendar', calendar: 'Calendar coverage:', note: 'Weekends (including makeup workdays) and public holidays are off-peak all day.',\n calendarBuiltin: 'Built-in', calendarLocal: 'Local import', calendarVerified: 'Checked on:',\n calendarImport: 'Import calendar', calendarRestore: 'Restore built-in', calendarDownload: 'Get new calendar', calendarSource: 'Holiday notice source',\n calendarImportHint: 'Choose a calendar file from this project. Imported coverage replaces the current calendar; other years remain unverified.',\n calendarImported: 'Calendar saved. The timeline is updated.', calendarRestored: 'Built-in calendar restored.',\n calendarInvalid: 'Invalid calendar format or source. Use a project calendar file (up to 64 KB). Your current calendar is unchanged.',\n calendarStorageError: 'Calendar could not be saved. Check local storage permissions and try again.',\n calendarSavedInvalid: 'Saved calendar is unreadable; using the built-in calendar. Import again or restore it.',\n calendarExpiresSoon: 'Calendar expires soon. Please update. Valid until:',\n unknownNote: 'Holiday data for this year is unavailable; weekday peak periods are unverified.',\n timeline: '24-hour timeline in Beijing time', days: 'd', hours: 'h', minutes: 'min', seconds: 's',\n};\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap { timeband: TextKey }\n}\n", ".dtb-theme {\n --dtb-bg: var(--dsw-alias-bg-base, #fff);\n --dtb-text: var(--dsw-alias-label-primary, #252925);\n --dtb-muted: var(--dsw-alias-label-tertiary, #798079);\n --dtb-secondary: var(--dsw-alias-label-secondary, #596459);\n --dtb-line: var(--dsw-alias-border-primary, #e7ebe7);\n --dtb-hover: var(--dsw-alias-interactive-bg-hover, #f4f6f3);\n --dtb-green: #338468; --dtb-peak: #cf7850; --dtb-unknown: #909897;\n color: var(--dtb-text); font-family: inherit; font-size: 12px; box-sizing: border-box;\n}\n.dtb-theme *, .dtb-theme *::before, .dtb-theme *::after { box-sizing: border-box; }\n.dtb-root { min-width: 0; width: 100%; }\n.dtb-chip { display: flex; flex-direction: column; justify-content: center; gap: 4px; width: 100%; min-width: 126px; height: 44px; padding: 5px 9px; border: 0; border-radius: 8px; background: transparent; color: inherit; font: inherit; cursor: pointer; }\n.dtb-chip:hover, .dtb-chip[aria-expanded='true'], .dtb-close:hover, .dtb-button:hover:enabled { background: var(--dtb-hover); }\n.dtb-chip:focus-visible, .dtb-close:focus-visible, .dtb-button:focus-visible, .dtb-card a:focus-visible, .dtb-details summary:focus-visible { outline: 2px solid var(--dtb-green); outline-offset: 3px; }\n.dtb-chip-top { display: flex; flex-wrap: wrap; align-items: center; width: 100%; gap: 2px 6px; }\n.dtb-chip-label { white-space: nowrap; font-size: 11px; }\n.dtb-chip-count { flex-shrink: 0; margin-left: auto; color: var(--dtb-muted); font-size: 9px; font-variant-numeric: tabular-nums; }\n.dtb-countdown { display: inline-flex; align-items: baseline; gap: 4px; white-space: nowrap; }\n.dtb-count-seconds { font-size: .58em; color: var(--dtb-muted); letter-spacing: 0; }\n.dtb-chip-count .dtb-countdown { gap: 2px; }\n.dtb-chip-count .dtb-count-seconds { font-size: .8em; }\n.dtb-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; flex: none; }\n.dtb-offpeak { background: var(--dtb-green); }\n.dtb-peak { background: var(--dtb-peak); }\n.dtb-unknown { background: repeating-linear-gradient(135deg, var(--dtb-unknown) 0 3px, transparent 3px 5px); }\n.dtb-track { width: 100%; height: 12px; position: relative; border-radius: 4px; }\n.dtb-segment { position: absolute; height: 100%; opacity: .8; border-left: 2px solid var(--dtb-bg); }\n.dtb-segment:first-child { border-radius: 3px 0 0 3px; border-left: 0; }\n.dtb-segment:nth-last-child(2) { border-radius: 0 3px 3px 0; }\n.dtb-segment:first-child:nth-last-child(2) { border-radius: 3px; }\n.dtb-cursor { position: absolute; top: -5px; bottom: -5px; width: 2px; background: var(--dtb-text); box-shadow: 0 0 0 2px var(--dtb-bg); transform: translateX(-1px); }\n.dtb-track-small { height: 4px; }\n.dtb-track-small .dtb-segment { border-left-width: 1px; }\n.dtb-track-small .dtb-cursor { top: -2px; bottom: -2px; width: 1px; box-shadow: 0 0 0 1px var(--dtb-bg); }\n.dtb-root[data-wide='false'] { width: 36px; }\n.dtb-root[data-wide='false'] .dtb-chip { min-width: 0; width: 36px; height: 36px; padding: 6px; position: relative; }\n.dtb-root[data-wide='false'] .dtb-chip-top { position: absolute; right: 4px; top: 5px; width: auto; }\n.dtb-rail-icon { width: 23px; height: 23px; stroke: currentColor; stroke-width: 1.5; fill: none; }\n/* DSH rc.2 layout adapter: only reflow the two native footer containers when\n this plugin is their sole action and the Desktop account launcher exists.\n No DOM mutation, private class names, account replacement or hidden labels.\n Other footer plugins / unknown layouts retain the native stacked layout. */\ndiv:has(> div > .dtb-root[data-wide='true']:only-child):has(> div button[data-collapsed='false']) {\n display: flex; flex-direction: row-reverse; flex-wrap: wrap; align-items: center; gap: 4px;\n}\ndiv:has(> div > .dtb-root[data-wide='true']:only-child):has(> div button[data-collapsed='false']) > div:has(> .dtb-root) {\n flex: 1 1 126px; width: auto; min-width: 126px;\n}\ndiv:has(> div > .dtb-root[data-wide='true']:only-child):has(> div button[data-collapsed='false']) > div:not(:has(> .dtb-root)) {\n flex: 1 1 40px; width: auto; min-width: 40px;\n}\n.dtb-card { position: fixed; inset: auto; margin: 0; padding: 22px; width: 362px; max-width: calc(100vw - 24px); max-height: calc(100dvh - 24px); overflow-y: auto; background: var(--dtb-bg); border: 1px solid var(--dtb-line); border-radius: 16px; box-shadow: 0 12px 48px #0002, 0 2px 6px #0001; }\n.dtb-card::backdrop { background: transparent; }\n.dtb-header { display: flex; justify-content: space-between; align-items: start; }\n.dtb-eyebrow { font-size: 9px; letter-spacing: .16em; color: var(--dtb-muted); }\n.dtb-header h2 { margin: 6px 0 0; font-size: 15px; font-weight: 550; letter-spacing: .02em; }\n.dtb-close { border: 0; background: transparent; color: var(--dtb-muted); width: 28px; height: 28px; border-radius: 7px; font-size: 22px; line-height: 24px; cursor: pointer; }\n.dtb-status { display: flex; gap: 9px; align-items: center; margin-top: 28px; }\n.dtb-status .dtb-dot { width: 8px; height: 8px; }\n.dtb-status strong { font-weight: 550; font-size: 25px; letter-spacing: -.04em; }\n.dtb-next { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px; margin-top: 17px; }\n.dtb-next > span { color: var(--dtb-secondary); font-size: 12px; }\n.dtb-next strong { margin-left: auto; max-width: 100%; font-size: 24px; font-weight: 400; letter-spacing: -.045em; font-variant-numeric: tabular-nums; }\n.dtb-date { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 8px; color: var(--dtb-secondary); font-size: 11px; margin-top: 6px; }\n.dtb-date > span:last-child { margin-left: auto; }\n.dtb-axis { position: relative; margin: 39px 0 19px; }\n.dtb-now { position: absolute; top: -12px; transform: translate(-50%, -100%); font-size: 11px; white-space: nowrap; color: var(--dtb-secondary); }\n.dtb-ticks { display: flex; justify-content: space-between; margin-top: 10px; color: var(--dtb-secondary); font-size: 11px; font-variant-numeric: tabular-nums; }\n.dtb-day-kind { border-top: 1px solid var(--dtb-line); padding-top: 16px; margin-bottom: 13px; font-size: 11px; color: var(--dtb-secondary); }\n.dtb-day-kind > span { padding: 0 4px; }\n.dtb-periods > div { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin: 11px 0; font-size: 11px; }\n.dtb-periods span { display: flex; align-items: center; gap: 7px; white-space: nowrap; }\n.dtb-periods b { font-weight: 400; font-size: 11px; font-variant-numeric: tabular-nums; text-align: right; }\n.dtb-note { font-size: 11px; color: var(--dtb-secondary); line-height: 1.7; margin: 13px 0; }\n.dtb-details { border-top: 1px solid var(--dtb-line); margin-top: 16px; padding-top: 12px; }\n.dtb-details summary { width: fit-content; cursor: pointer; font-size: 11px; color: var(--dtb-secondary); line-height: 1.8; }\n.dtb-calendar-meta { display: flex; flex-direction: column; gap: 5px; font-size: 11px; color: var(--dtb-secondary); }\n.dtb-calendar-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; font-size: 11px; }\n.dtb-button { padding: 5px 9px; border: 1px solid var(--dtb-line); border-radius: 6px; background: transparent; color: inherit; font: inherit; cursor: pointer; }\n.dtb-button:disabled { opacity: .5; cursor: default; }\n.dtb-calendar-actions a { color: var(--dtb-green); text-decoration: none; }\n.dtb-calendar-feedback:empty { display: none; }\n.dtb-calendar-notice { border-left: 2px solid var(--dtb-peak); padding-left: 9px; }\n.dtb-footer { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; padding-top: 3px; font-size: 10px; color: var(--dtb-muted); }\n.dtb-footer a { color: inherit; text-decoration: none; }\n.dtb-footer a:hover { text-decoration: underline; }\n@media (prefers-color-scheme: dark) {\n .dtb-theme { --dtb-secondary: var(--dsw-alias-label-secondary, #b6bfb6); }\n .dtb-theme { --dtb-bg: var(--dsw-alias-bg-base, #242624); --dtb-text: var(--dsw-alias-label-primary, #e5eae5); --dtb-muted: var(--dsw-alias-label-tertiary, #9aa59e); --dtb-line: var(--dsw-alias-border-primary, #3b413c); --dtb-hover: var(--dsw-alias-interactive-bg-hover, #303630); --dtb-green: #6cbd9e; --dtb-peak: #eaa77a; }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["client_exports", "__export", "apply", "inject", "__toCommonJS", "createClock", "snapshot", "listeners", "update", "listener", "timer", "resume", "__default", "CALENDAR_DOWNLOAD", "MAX_CALENDAR_BYTES", "CalendarError", "kind", "validDate", "value", "parsed", "parseCalendar", "text", "data", "years", "year", "index", "source", "holidays", "interval", "start", "end", "calendar", "__default", "CALENDAR_STORAGE_KEY", "createCalendarStore", "getStorage", "listeners", "read", "saved", "calendar", "parseCalendar", "error", "CalendarError", "snapshot", "update", "state", "listener", "text", "data", "refresh", "onStorage", "event", "import_react", "import_react_dom", "PRICING_SOURCE", "HOUR", "DAY", "CHINA_OFFSET", "BOUNDARIES", "chinaDay", "now", "data", "calendar", "date", "key", "midnight", "holiday", "start", "end", "weekend", "covered", "todaySegments", "kind", "peak", "bandAt", "hour", "nextTransition", "current", "day", "at", "band", "calendarCoverage", "endYear", "expiresOn", "until", "createScheduleReader", "previous", "cached", "daily", "before", "boundary", "after", "countdown", "milliseconds", "total", "days", "hours", "minutes", "major", "import_jsx_runtime", "dateFormatter", "timeFormatter", "Track", "segments", "hour", "small", "segment", "TimeBand", "wide", "useClock", "t", "calendarStore", "now", "value", "calendarState", "readSchedule", "createScheduleReader", "day", "band", "next", "coverage", "HOUR", "knownNext", "open", "setOpen", "panel", "trigger", "close", "calendarInput", "feedback", "setFeedback", "importing", "setImporting", "id", "remaining", "countdown", "mainText", "part", "secondsText", "countdownText", "countdownView", "nextLabel", "nextDate", "time", "showError", "error", "CalendarError", "importCalendar", "file", "MAX_CALENDAR_BYTES", "element", "onToggle", "position", "anchor", "box", "left", "top", "observer", "hide", "event", "s", "CALENDAR_DOWNLOAD", "PRICING_SOURCE", "zh", "en", "style_default", "inject", "apply", "ctx", "zh", "en", "style", "style_default", "clock", "createClock", "calendarStore", "createCalendarStore", "TimeBand"]
7
+ }
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ function apply() {
2
+ }
3
+ export {
4
+ apply
5
+ };
package/package.json ADDED
@@ -0,0 +1,83 @@
1
+ {
2
+ "name": "dsh-timeband",
3
+ "version": "1.1.0",
4
+ "description": "头像旁的 DeepSeek 峰谷时段与今日时间轴",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/a961282799-crypto/dsh-timeband.git"
10
+ },
11
+ "homepage": "https://github.com/a961282799-crypto/dsh-timeband#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/a961282799-crypto/dsh-timeband/issues"
14
+ },
15
+ "main": "./dist/index.js",
16
+ "exports": {
17
+ ".": "./dist/index.js",
18
+ "./client": "./dist/client.js",
19
+ "./package.json": "./package.json"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "calendars",
24
+ "cordis.patch.yml",
25
+ "README.md",
26
+ "LICENSE"
27
+ ],
28
+ "keywords": [
29
+ "dsh-plugin",
30
+ "deepseek-harness",
31
+ "timeline"
32
+ ],
33
+ "engines": {
34
+ "node": ">=22"
35
+ },
36
+ "dsh": {
37
+ "bundle": {
38
+ "patch": "./cordis.patch.yml"
39
+ },
40
+ "client": {
41
+ "platform": "web",
42
+ "inject": [
43
+ "@deepseek-ai/dsh-client-ui-renderer",
44
+ "@deepseek-ai/dsh-client-ui-sidebar",
45
+ "@deepseek-ai/dsh-client-locale"
46
+ ]
47
+ }
48
+ },
49
+ "peerDependencies": {
50
+ "@deepseek-ai/dsh": "0.2.0-rc.2"
51
+ },
52
+ "peerDependenciesMeta": {
53
+ "@deepseek-ai/dsh": {
54
+ "optional": true
55
+ }
56
+ },
57
+ "scripts": {
58
+ "build": "node scripts/build.mjs",
59
+ "typecheck": "tsc --noEmit",
60
+ "test": "node --experimental-strip-types --test tests/*.test.ts tests/*.test.mjs",
61
+ "test:browser": "playwright test",
62
+ "preview": "node scripts/preview.mjs",
63
+ "screenshots": "node scripts/screenshots.mjs",
64
+ "compatibility": "node scripts/check-compatibility.mjs",
65
+ "check": "npm run typecheck && npm run build && npm test && npm run test:browser",
66
+ "prepack": "npm run typecheck && npm run build"
67
+ },
68
+ "devDependencies": {
69
+ "@deepseek-ai/cordis": "4.0.4",
70
+ "@deepseek-ai/dsh-client-locale": "0.2.0-rc.2",
71
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.2",
72
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.2.0-rc.2",
73
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2",
74
+ "@playwright/test": "1.63.0",
75
+ "@types/node": "^24.0.0",
76
+ "@types/react": "~18.3.1",
77
+ "@types/react-dom": "~18.3.0",
78
+ "esbuild": "0.28.2",
79
+ "react": "18.3.1",
80
+ "react-dom": "18.3.1",
81
+ "typescript": "7.0.2"
82
+ }
83
+ }