dsh-splash-launcher 1.0.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/DSH-GUI.exe ADDED
Binary file
package/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Isilsolme and 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.
22
+
23
+ ---
24
+
25
+ Brand assets notice: `whale.png`, `deepseek-wordmark.svg` and `whale-anim.svg`
26
+ are derived from the DeepSeek Harness (`@deepseek-ai/dsh`, MIT, © 2026 DeepSeek)
27
+ web frontend favicon / wordmark assets. They remain DeepSeek brand assets; the
28
+ DeepSeek name and whale logo are trademarks of their respective owner.
package/README.en.md ADDED
@@ -0,0 +1,30 @@
1
+ # DSH GUI
2
+
3
+ A one-click Windows launcher for the DeepSeek Harness (`dsh`) Web GUI with a borderless WPF startup animation (stroke-by-stroke "HARNESS" lettering inspired by SPlayer-Next). It starts `dsh web` in the background, preloads the real GUI behind the animation, and fades into it only when the GUI is actually ready. Closing the window stops the service it started.
4
+
5
+ ## Build
6
+
7
+ ```bat
8
+ build.cmd
9
+ ```
10
+
11
+ Produces `DSH-GUI.exe` using the Windows built-in `csc.exe` (no external toolchain).
12
+
13
+ ## Requirements
14
+
15
+ - Windows 10/11
16
+ - Node.js + global `npm install -g @deepseek-ai/dsh`
17
+ - Microsoft Edge or Google Chrome
18
+
19
+ ## Configuration
20
+
21
+ - `DSH_GUI_WORKSPACE` env var, or a `workspace.txt` next to the exe — working directory for `dsh web` (default `D:\VSCode`)
22
+ - `DSH_GUI_PORT` — port (default `3080`)
23
+
24
+ ## Known issues
25
+
26
+ 1. The taskbar briefly shows the Chrome/Edge default icon before the page favicon (black whale) loads; this is a browser-level placeholder and cannot be preset via command line.
27
+ 2. Startup takes a while (dsh boot + browser cold start + plugin loading). The animation covers the whole wait and only fades out when the GUI is ready.
28
+ 3. Unsigned launchers that start hidden processes / stop process trees may trigger behavior-based antivirus heuristics; add the folder to your AV exclusions or code-sign the exe.
29
+
30
+ See the Chinese [README](README.md) for full details. Code is MIT; brand assets derive from DeepSeek Harness (MIT, © 2026 DeepSeek).
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # DSH GUI
2
+
3
+ > DeepSeek Harness(dsh)Web GUI 的 Windows 一键启动器:双击即弹出无边框启动动画,后台拉起 `dsh web`,GUI 真正加载完成后无缝淡入;关闭窗口自动停服务。
4
+
5
+ 启动动画借鉴 [SPlayer-Next](https://github.com/SPlayer-Dev/SPlayer-Next) 的思路:SVG `stroke-dashoffset` “一笔一划”书写效果——鲸鱼 Logo 升起呼吸,`deepseek` 官方字标浮现,`HARNESS` 七个字母逐笔描边。
6
+
7
+ ![license](https://img.shields.io/badge/license-MIT-blue) ![windows](https://img.shields.io/badge/platform-Windows%2010%2F11-blue)
8
+
9
+ ## 效果截图
10
+
11
+ **启动动画(WPF 无边框,HARNESS 逐笔描边)**
12
+
13
+ ![启动动画](docs/screenshots/startup-animation.png)
14
+
15
+ **进入后的 GUI 界面**
16
+
17
+ ![GUI 界面](docs/screenshots/gui.png)
18
+
19
+ ---
20
+
21
+ ## 功能特性
22
+
23
+ - **点击即出动画**:WPF 原生动画窗口,不等待浏览器冷启动,双击后立刻播放;
24
+ - **一笔一划描边**:`HARNESS` 七个字母按 CSS `cubic-bezier(0.25,0.1,0.25,1)` 缓动逐笔书写,笔尖连续、首帧空白;
25
+ - **后台加载、就绪切换**:启动动画期间,真实 GUI 在浏览器后台(同源 iframe)完成加载,检测到官方启动页(`Loading plugins…`)消失后才淡出动画,不会出现“动画播完又加载”的断档;
26
+ - **无 PowerShell**:启动器是单个 C#/WPF 程序,无脚本进程,规避“PowerShell 木马”类安全软件启发式误报;
27
+ - **开即启动、关即退出**:窗口关闭后自动结束本次启动的 `dsh web` 服务;端口已有服务时只开窗口、不接管生命周期;
28
+ - **可配置**:工作目录与端口可通过环境变量或 `workspace.txt` 修改;
29
+ - **开源友好**:单文件 C# 源码 + `build.cmd`,使用 Windows 自带 `csc.exe` 编译,无需外部工具链。
30
+
31
+ ## 快速开始
32
+
33
+ ### 环境要求
34
+
35
+ - Windows 10 / 11;
36
+ - 已通过 npm 全局安装 DeepSeek Harness:`npm install -g @deepseek-ai/dsh`(`dsh web` 可用);
37
+ - Node.js(npm 全局安装 dsh 时自带依赖);
38
+ - Microsoft Edge 或 Google Chrome(二选一,自动探测)。
39
+
40
+ ### 构建
41
+
42
+ 双击或命令行运行:
43
+
44
+ ```bat
45
+ build.cmd
46
+ ```
47
+
48
+ 生成 `DSH-GUI.exe`(黑鲸图标)。构建仅使用 Windows 自带的 `C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe`。
49
+
50
+ > 也可以直接下载 GitHub Releases 里 Actions 构建的产物。
51
+
52
+ ### 使用
53
+
54
+ 1. 把整个目录放在任意位置(例如 `D:\dsh-gui`);
55
+ 2. 运行 `DSH-GUI.exe`;
56
+ 3. 如需桌面快捷方式:右键 `DSH-GUI.exe` → 发送到 → 桌面快捷方式(图标会自动使用黑鲸)。
57
+
58
+ ### 作为 dsh 插件安装(可选)
59
+
60
+ 本项目同时是一个可安装的 dsh bundle:随包携带 `DSH-GUI.exe`,并在宿主机注册 `desktop_launch` 工具,在对话中直接让 agent 打开带动画的 GUI 窗口:
61
+
62
+ ```sh
63
+ dsh plugin --profile web add dsh-splash-launcher
64
+ ```
65
+
66
+ 安装后重启 `dsh web`,agent 可使用 `desktop_launch` 工具(参数 `workspace` 可选,指定会话工作目录)。
67
+
68
+ ### 配置
69
+
70
+ | 项 | 默认值 | 修改方式 |
71
+ |---|---|---|
72
+ | 工作目录(`dsh web` 启动目录) | `D:\VSCode` | 环境变量 `DSH_GUI_WORKSPACE`,或在 exe 同目录新建 `workspace.txt` 写入路径 |
73
+ | 端口 | `3080` | 环境变量 `DSH_GUI_PORT` |
74
+ | 启动动画版式 | HARNESS 描边 | 源码 `SplashStyle` 改为 `"&logo=draw"` 可切换为“鲸鱼本体一笔一划”版 |
75
+
76
+ ## 启动流程
77
+
78
+ ```
79
+ 双击 DSH-GUI.exe
80
+ ├─ 端口已占用 ────────────────→ 直接打开 GUI 窗口(不显示动画、不接管服务)
81
+ └─ 端口空闲
82
+ ├─ 立即显示 WPF 无边框启动动画(≈0ms,不等浏览器)
83
+ ├─ 解析 dsh 安装路径(npm root -g + node require.resolve)
84
+ ├─ 将 splash 素材同步进 dsh-web-frontend/dist(同源 iframe 探测的前提)
85
+ ├─ 后台启动 `node <dsh>/lib/bin.js web`(隐藏窗口)
86
+ ├─ 轮询端口就绪(最多 90s)
87
+ ├─ 以相同尺寸/位置在动画背后打开浏览器 `--app` 窗口
88
+ │ └─ splash.html(hold) 用隐藏 iframe 加载 `/`
89
+ │ └─ 检测到官方启动卡片消失 → 揭示 iframe,并同步标题
90
+ ├─ WPF 检测到浏览器标题包含 "DeepSeek Harness" → 淡出动画
91
+ └─ 浏览器窗口关闭 → taskkill 结束本次 dsh web 进程树
92
+ ```
93
+
94
+ ## 项目结构
95
+
96
+ ```
97
+ dsh-gui/
98
+ ├─ DSH-GUI.cs # 启动器全部源码(C# 5 / WPF,单文件)
99
+ ├─ build.cmd # 构建脚本(Windows 自带 csc.exe)
100
+ ├─ splash.html # 浏览器侧启动页(hold 态 + 后台 iframe 预加载 + 就绪检测)
101
+ ├─ deepseek-wordmark.svg # 官方 deepseek 字标(提取自 dsh 前端)
102
+ ├─ whale.png # 黑鲸 Logo(256px,透明底)
103
+ ├─ whale-anim.svg # 鲸鱼描边动画(可选版式 logo=draw)
104
+ ├─ icons/
105
+ │ └─ whale-black.ico # 黑鲸图标(exe 与快捷方式共用)
106
+ ├─ LICENSE # MIT + 品牌素材说明
107
+ └─ README.md
108
+ ```
109
+
110
+ ## 开发
111
+
112
+ ```bat
113
+ :: 构建
114
+ build.cmd
115
+
116
+ :: 自检(校验素材路径、dsh 安装路径与前端 dist,不弹窗)
117
+ DSH-GUI.exe --selftest
118
+ :: 结果写入 selftest.txt,退出码 0 为通过
119
+ ```
120
+
121
+ 常用调节点(`DSH-GUI.cs`):
122
+
123
+ | 想调什么 | 位置 |
124
+ |---|---|
125
+ | 描边速度 | `SplashWindow.DrawSeconds`(默认 1.25s/字母) |
126
+ | 字母间隔 | `SplashWindow.LetterGap`(默认 0.24s) |
127
+ | 动画窗口尺寸 | `Program.WinW / WinH`(默认 1100×720) |
128
+ | 最短动画时长 | `SplashWindow.MinShowSec` |
129
+ | 就绪判定标题 | `SplashWindow.AppTitle`(按“包含”匹配) |
130
+
131
+ ## 已知问题
132
+
133
+ ### 1. 任务栏图标会先闪一下 Chrome/Edge 默认图标
134
+ 浏览器 `--app` 窗口创建时,任务栏按钮先使用浏览器进程自带图标,页面 `favicon`(黑鲸)加载完成后才切换,因此会出现极短暂的一闪。这是浏览器自身的图标占位机制,没有命令行参数可预设;当前动画窗口会盖住这段过程,实际看到界面时已是黑鲸图标。彻底隐藏需要 Win32 控制窗口显隐,可能引起页面节流、拖慢启动,暂不实现。
135
+
136
+ ### 2. 启动有一定等待时间
137
+ 启动时长主要来自:`dsh web` 服务引导 + 浏览器冷启动 + 前端插件装载。动画会覆盖全部等待过程并持续到 GUI 就绪,属于“可见但不可压缩”的时间。首次运行、杀毒软件实时扫描、机械硬盘会进一步加长。可通过 WPF 描边速度(见上)让动画与等待时长更匹配。
138
+
139
+ ### 3. 安全软件可能误报(未签名 exe)
140
+ 本程序会启动隐藏进程、结束后台进程、复制文件,这类“类管理工具”行为可能触发启发式防护(例如卡巴斯基 PDM:Trojan.Win32.Generic 对旧版 PowerShell 脚本的误报)。建议:
141
+ - 将 `dsh-gui` 目录加入杀软排除项/受信任应用程序;
142
+ - 正式分发时对 `DSH-GUI.exe` 做代码签名(本程序已不使用 PowerShell,命中率大幅降低)。
143
+
144
+ ### 4. 端口已被占用时直接进入 GUI
145
+ 如果 `3080` 端口已有 `dsh web`(例如正在终端里使用),双击只会打开 GUI 窗口,不会显示启动动画,也不会在关窗时停止该服务——这是刻意设计,避免误杀已有会话。
146
+
147
+ ### 5. 同源预加载依赖 dist 写入权限
148
+ 启动器需要把 `splash.html` 等素材复制到 npm 全局的 `dsh-web-frontend/dist` 目录。若该目录不可写,会自动退回“文件页动画 → 就绪后直接跳转 GUI”模式,此时会短暂看到官方 HARNESS 加载页。
149
+
150
+ ### 6. 就绪判定依赖标题
151
+ WPF 以浏览器窗口标题包含 `DeepSeek Harness` 判定 GUI 就绪;若官方前端修改标题结构,可能需要同步更新 `SplashWindow.AppTitle`。
152
+
153
+ ## 许可证
154
+
155
+ - 代码:MIT,见 [LICENSE](LICENSE)。
156
+ - `whale.png`、`deepseek-wordmark.svg`、`whale-anim.svg` 派生自 DeepSeek Harness(`@deepseek-ai/dsh`,MIT © 2026 DeepSeek)前端素材,保留 DeepSeek 品牌权利;DeepSeek 名称与鲸鱼 Logo 为各自权利人的商标。
157
+
158
+ ## 致谢
159
+
160
+ - 启动动画的“一笔一划”与时长编排思路借鉴 [SPlayer-Next](https://github.com/SPlayer-Dev/SPlayer-Next)(AGPL-3.0;本项目未复制其代码,仅参考交互思路)。
161
+ - DeepSeek Harness(`dsh`,npm 包 `@deepseek-ai/dsh`)及其 Web GUI。
@@ -0,0 +1,6 @@
1
+ # dsh-splash-launcher bundle patch: inserts the host plugin row into the
2
+ # profile roster. Install with:
3
+ # dsh plugin --profile web add dsh-splash-launcher
4
+ - insert:
5
+ - id: splash-launcher
6
+ name: 'dsh-splash-launcher'
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="26 0 97 24" width="97" height="24" fill="none">
2
+ <g fill="#E7ECFF">
3
+ <path d="M68.416 18.2447H67.0501V16.1272H68.416C69.2619 16.1272 70.1166 15.9163 70.6671 15.3304C71.2181 14.7444 71.426 13.8455 71.426 12.9471C71.426 12.0487 71.2268 11.1498 70.6671 10.5643C70.1083 9.97831 69.2619 9.76744 68.416 9.76744C67.5701 9.76744 66.7154 9.97831 66.1639 10.5643C65.6129 11.1503 65.4049 12.0487 65.4049 12.9471V21.6435H63.009V7.6582H65.4049V8.54883H65.8442C65.8918 8.49393 65.9394 8.44728 65.9875 8.40064C66.5871 7.85353 67.5049 7.6582 68.4072 7.6582C69.8212 7.6582 71.2341 8.00998 72.1607 8.98662C73.0868 9.96325 73.4143 11.4632 73.4143 12.9558C73.4143 14.4485 73.0785 15.9406 72.1607 16.925C71.2424 17.9094 69.8212 18.2457 68.416 18.2457V18.2447Z" />
4
+ <path d="M31.9551 8.03497H33.3204V10.1525H31.9551C31.1087 10.1525 30.2545 10.3633 29.7035 10.9493C29.1525 11.5353 28.945 12.4342 28.945 13.3326C28.945 14.231 29.1447 15.1294 29.7035 15.7154C30.2623 16.3014 31.1087 16.5122 31.9551 16.5122C32.8015 16.5122 33.6562 16.3014 34.2072 15.7154C34.7582 15.1294 34.9657 14.231 34.9657 13.3326V4.62842H37.3611V18.6219H34.9657V17.7313H34.5264C34.4783 17.7857 34.4307 17.8329 34.3826 17.8795C33.7835 18.4261 32.8652 18.6219 31.9629 18.6219C30.5494 18.6219 29.136 18.2707 28.2099 17.294C27.2838 16.3174 26.9563 14.817 26.9563 13.3248C26.9563 11.8327 27.2916 10.34 28.2099 9.35561C29.136 8.37898 30.5494 8.03497 31.9551 8.03497Z" />
5
+ <path d="M49.3786 13.1431V13.9948H42.9984V12.2996H47.2305C47.1348 11.6825 46.9113 11.1043 46.5119 10.682C45.9371 10.0727 45.0503 9.85409 44.1723 9.85409C43.2943 9.85409 42.4076 10.0727 41.8328 10.682C41.258 11.2913 41.05 12.2213 41.05 13.1435C41.05 14.0658 41.2575 15.003 41.8328 15.6046C42.4076 16.2061 43.2939 16.433 44.1723 16.433C45.0508 16.433 45.9371 16.2143 46.5119 15.6046C46.5916 15.5186 46.6635 15.4248 46.7354 15.331H49.0992C48.8918 16.0657 48.5643 16.7299 48.0691 17.2454C47.111 18.2531 45.6339 18.6205 44.1723 18.6205C42.7108 18.6205 41.2337 18.2609 40.2755 17.2454C39.3174 16.2299 38.9661 14.6828 38.9661 13.1435C38.9661 11.6043 39.3096 10.0494 40.2755 9.04168C41.242 8.03396 42.7108 7.66663 44.1723 7.66663C45.6339 7.66663 47.111 8.02618 48.0691 9.04168C49.0351 10.0572 49.3786 11.6043 49.3786 13.1435V13.1431Z" />
6
+ <path d="M61.4045 13.1431V13.9948H55.0243V12.2996H59.2564C59.1602 11.6825 58.9372 11.1043 58.5378 10.682C57.963 10.0727 57.0762 9.85409 56.1982 9.85409C55.3202 9.85409 54.4335 10.0727 53.8587 10.682C53.2839 11.2913 53.0759 12.2213 53.0759 13.1435C53.0759 14.0658 53.2834 15.003 53.8587 15.6046C54.4335 16.2061 55.3202 16.433 56.1982 16.433C57.0762 16.433 57.963 16.2143 58.5378 15.6046C58.6179 15.5186 58.6894 15.4248 58.7608 15.331H61.1251C60.9171 16.0657 60.5897 16.7299 60.0945 17.2454C59.1364 18.2531 57.6593 18.6205 56.1982 18.6205C54.7372 18.6205 53.2596 18.2609 52.3014 17.2454C51.3432 16.2299 50.9919 14.6828 50.9919 13.1435C50.9919 11.6043 51.3355 10.0494 52.3014 9.04168C53.2678 8.03396 54.7367 7.66663 56.1982 7.66663C57.6598 7.66663 59.1364 8.02618 60.0945 9.04168C61.061 10.0572 61.4045 11.6043 61.4045 13.1435V13.1431Z" />
7
+ <path d="M80.242 18.6214C81.7035 18.6214 83.1801 18.4105 84.1383 17.809C85.0965 17.2075 85.4482 16.2931 85.4482 15.3869C85.4482 14.4807 85.1042 13.5585 84.1383 12.9647C83.1801 12.371 81.703 12.1518 80.242 12.1518C79.6186 12.1518 79.0438 12.0658 78.6366 11.8394C78.2294 11.6047 78.0778 11.2534 78.0778 10.9017C78.0778 10.5499 78.2216 10.1908 78.6366 9.9639C79.0438 9.72921 79.6749 9.65147 80.2973 9.65147C80.9198 9.65147 81.5509 9.73747 81.9591 9.9639C82.3663 10.1986 82.5179 10.5499 82.5179 10.9017H84.9531C84.9531 9.99499 84.6421 9.07327 83.7719 8.47951C82.9017 7.88576 81.5679 7.66663 80.2424 7.66663C78.9169 7.66663 77.5837 7.8775 76.713 8.47951C75.8427 9.08104 75.5308 9.99499 75.5308 10.9017C75.5308 11.8083 75.8423 12.73 76.713 13.3238C77.5832 13.9176 78.9165 14.1367 80.2424 14.1367C80.929 14.1367 81.688 14.2227 82.1428 14.4491C82.5985 14.676 82.7579 15.0351 82.7579 15.3869C82.7579 15.7387 82.5985 16.0977 82.1428 16.3246C81.688 16.5511 80.9931 16.6371 80.3066 16.6371C79.62 16.6371 78.9169 16.5511 78.4694 16.3246C78.0224 16.0982 77.8543 15.7387 77.8543 15.3869H75.0435C75.0435 16.2935 75.3865 17.2153 76.3534 17.809C77.3194 18.4028 78.7809 18.6214 80.2424 18.6214H80.242Z" />
8
+ <path d="M97.4733 13.1431V13.9948H91.0932V12.2996H95.3252C95.23 11.6825 95.006 11.1043 94.6071 10.682C94.0313 10.0727 93.1456 9.85409 92.2666 9.85409C91.3876 9.85409 90.5018 10.0727 89.927 10.682C89.3522 11.2913 89.1452 12.2213 89.1452 13.1435C89.1452 14.0658 89.3522 15.003 89.927 15.6046C90.5018 16.2061 91.3886 16.433 92.2666 16.433C93.1446 16.433 94.0313 16.2143 94.6071 15.6046C94.6863 15.5186 94.7587 15.4248 94.8301 15.331H97.1935C96.9855 16.0657 96.6585 16.7299 96.1639 17.2454C95.2057 18.2531 93.7281 18.6205 92.2666 18.6205C90.805 18.6205 89.3284 18.2609 88.3703 17.2454C87.4121 16.2299 87.0613 14.6828 87.0613 13.1435C87.0613 11.6043 87.4043 10.0494 88.3703 9.04168C89.3367 8.03396 90.806 7.66663 92.2666 7.66663C93.7272 7.66663 95.2057 8.02618 96.1639 9.04168C97.1298 10.0572 97.4729 11.6043 97.4729 13.1435L97.4733 13.1431Z" />
9
+ <path d="M109.499 13.1431V13.9948H103.119V12.2996H107.351C107.256 11.6825 107.032 11.1043 106.632 10.682C106.057 10.0727 105.172 9.85409 104.293 9.85409C103.414 9.85409 102.528 10.0727 101.953 10.682C101.378 11.2913 101.17 12.2213 101.17 13.1435C101.17 14.0658 101.378 15.003 101.953 15.6046C102.528 16.2061 103.415 16.433 104.293 16.433C105.171 16.433 106.057 16.2143 106.632 15.6046C106.712 15.5186 106.784 15.4248 106.856 15.331H109.22C109.012 16.0657 108.685 16.7299 108.19 17.2454C107.231 18.2531 105.754 18.6205 104.293 18.6205C102.831 18.6205 101.355 18.2609 100.396 17.2454C99.4382 16.2299 99.0864 14.6828 99.0864 13.1435C99.0864 11.6043 99.4295 10.0494 100.396 9.04168C101.362 8.03396 102.832 7.66663 104.293 7.66663C105.754 7.66663 107.231 8.02618 108.19 9.04168C109.156 10.0572 109.499 11.6043 109.499 13.1435V13.1431Z" />
10
+ <path d="M113.5 4.62817H111.104V18.6217H113.5V4.62817Z" />
11
+ <path d="M117.589 12.8154L121.517 18.6208H118.554L114.625 12.8154L118.554 8.15088H121.517L117.589 12.8154Z" />
12
+ </g>
13
+ </svg>
Binary file
package/lib/index.js ADDED
@@ -0,0 +1,64 @@
1
+ /**
2
+ * dsh-splash-launcher — host half.
3
+ * Ships the Windows DSH-GUI.exe startup-animation launcher inside the npm
4
+ * package and registers a desktop_launch agent tool so the GUI can be opened
5
+ * from a conversation with one tool call.
6
+ */
7
+ import { defineTool } from '@deepseek-ai/dsh-tools'
8
+ import { spawn } from 'node:child_process'
9
+ import { dirname, join } from 'node:path'
10
+ import { fileURLToPath } from 'node:url'
11
+
12
+ const here = dirname(fileURLToPath(import.meta.url))
13
+ const exe = join(here, '..', 'DSH-GUI.exe')
14
+
15
+ export const name = 'splash-launcher'
16
+ export const inject = ['tools']
17
+
18
+ export function apply(ctx) {
19
+ ctx.effect(() => {
20
+ const dispose = ctx.tools.register(defineTool({
21
+ name: 'desktop_launch',
22
+ description:
23
+ 'Launch the DSH Web GUI in a desktop window with the splash startup animation (Windows only). ' +
24
+ 'Use when the user asks to open/start the DSH GUI, web interface, or desktop window.',
25
+ parameters: {
26
+ workspace: {
27
+ type: 'string',
28
+ description:
29
+ 'Optional workspace directory for the launched dsh web session. ' +
30
+ 'Defaults to the launcher config (DSH_GUI_WORKSPACE / workspace.txt / D:\\VSCode).',
31
+ },
32
+ },
33
+ output: {
34
+ schema: {
35
+ type: 'object',
36
+ additionalProperties: false,
37
+ properties: {
38
+ ok: { type: 'boolean', required: true },
39
+ pid: { type: 'integer' },
40
+ hint: { type: 'string' },
41
+ },
42
+ },
43
+ render(_args, value) {
44
+ return [{ type: 'text', text: value.hint ?? (value.ok ? 'DSH GUI launched.' : 'launch failed.') }]
45
+ },
46
+ },
47
+ async execute(args) {
48
+ if (process.platform !== 'win32') {
49
+ return { ok: false, hint: 'desktop_launch is Windows-only; this platform is not supported.' }
50
+ }
51
+ try {
52
+ const env = { ...process.env }
53
+ if (args && args.workspace) env.DSH_GUI_WORKSPACE = args.workspace
54
+ const child = spawn(exe, [], { detached: true, stdio: 'ignore', cwd: dirname(exe), env })
55
+ child.unref()
56
+ return { ok: true, pid: child.pid, hint: 'DSH GUI launcher started; the splash shows immediately and the GUI window appears when ready.' }
57
+ } catch (err) {
58
+ return { ok: false, hint: String(err && err.message ? err.message : err) }
59
+ }
60
+ },
61
+ }))
62
+ return dispose
63
+ }, 'dsh-splash-launcher: desktop_launch tool')
64
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "dsh-splash-launcher",
3
+ "version": "1.0.0",
4
+ "description": "DSH Windows one-click launcher with a stroke-by-stroke startup animation: ships DSH-GUI.exe and registers the desktop_launch agent tool.",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "exports": {
8
+ ".": "./lib/index.js",
9
+ "./package.json": "./package.json"
10
+ },
11
+ "engines": {
12
+ "node": ">=22"
13
+ },
14
+ "dsh": {
15
+ "bundle": {
16
+ "patch": "./cordis.patch.yml"
17
+ }
18
+ },
19
+ "peerDependencies": {
20
+ "@deepseek-ai/dsh-tools": "^0.1.0-rc.6"
21
+ },
22
+ "files": [
23
+ "lib/index.js",
24
+ "cordis.patch.yml",
25
+ "DSH-GUI.exe",
26
+ "splash.html",
27
+ "deepseek-wordmark.svg",
28
+ "whale.png",
29
+ "whale-anim.svg",
30
+ "icons/whale-black.ico",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/Isilsolme/dsh-splash-launcher.git"
38
+ }
39
+ }
package/splash.html ADDED
@@ -0,0 +1,379 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <link rel="icon" type="image/png" href="whale.png" />
7
+ <title>DSH</title>
8
+ <style>
9
+ :root {
10
+ --bg: #070b18;
11
+ --accent: #4d6bfe;
12
+ --cyan: #22d3ee;
13
+ --text: #e7ecff;
14
+ --muted: #8b96bb;
15
+ }
16
+
17
+ * { margin: 0; padding: 0; box-sizing: border-box; }
18
+
19
+ html, body {
20
+ height: 100%;
21
+ overflow: hidden;
22
+ background: var(--bg);
23
+ color: var(--text);
24
+ font-family: "Segoe UI", "Microsoft YaHei", system-ui, -apple-system, sans-serif;
25
+ user-select: none;
26
+ -webkit-user-select: none;
27
+ cursor: default;
28
+ }
29
+
30
+ /* 真实 GUI 在后台 iframe 中加载,就绪后揭示 */
31
+ #appFrame {
32
+ position: fixed;
33
+ inset: 0;
34
+ width: 100%;
35
+ height: 100%;
36
+ border: 0;
37
+ background: #070b18;
38
+ visibility: hidden;
39
+ z-index: 1;
40
+ }
41
+
42
+ /* ---------- splash 覆盖层 ---------- */
43
+ #app-loading {
44
+ position: fixed;
45
+ inset: 0;
46
+ z-index: 9999;
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ background: var(--bg);
51
+ color: var(--text);
52
+ transition: opacity 0.3s;
53
+ }
54
+ #app-loading.hidden {
55
+ opacity: 0;
56
+ pointer-events: none;
57
+ }
58
+
59
+ /* 背景柔光 */
60
+ .bg {
61
+ position: absolute;
62
+ inset: 0;
63
+ overflow: hidden;
64
+ background:
65
+ radial-gradient(1100px 750px at 78% -8%, rgba(77, 107, 254, 0.24), transparent 60%),
66
+ radial-gradient(850px 650px at 10% 112%, rgba(34, 211, 238, 0.12), transparent 55%),
67
+ linear-gradient(180deg, #070b18 0%, #0a1024 55%, #070b18 100%);
68
+ }
69
+ .bg::before {
70
+ content: "";
71
+ position: absolute;
72
+ width: 520px; height: 520px;
73
+ left: -130px; top: -120px;
74
+ border-radius: 50%;
75
+ background: radial-gradient(circle, rgba(77, 107, 254, 0.30), transparent 65%);
76
+ filter: blur(28px);
77
+ animation: drift-a 11s ease-in-out infinite alternate;
78
+ }
79
+ .bg::after {
80
+ content: "";
81
+ position: absolute;
82
+ width: 580px; height: 580px;
83
+ right: -160px; bottom: -180px;
84
+ border-radius: 50%;
85
+ background: radial-gradient(circle, rgba(34, 211, 238, 0.18), transparent 65%);
86
+ filter: blur(34px);
87
+ animation: drift-b 13s ease-in-out infinite alternate;
88
+ }
89
+ @keyframes drift-a {
90
+ from { transform: translate(0, 0) scale(1); }
91
+ to { transform: translate(110px, 60px) scale(1.12); }
92
+ }
93
+ @keyframes drift-b {
94
+ from { transform: translate(0, 0) scale(1); }
95
+ to { transform: translate(-120px, -70px) scale(1.08); }
96
+ }
97
+
98
+ /* ---------- 居中布局 ---------- */
99
+ .splash {
100
+ position: relative;
101
+ z-index: 1;
102
+ display: flex;
103
+ flex-direction: column;
104
+ align-items: center;
105
+ gap: 18px;
106
+ transform: translateZ(0);
107
+ }
108
+
109
+ .splash-logo {
110
+ width: 72px;
111
+ height: 72px;
112
+ filter: brightness(0) invert(1) drop-shadow(0 0 18px rgba(77, 107, 254, 0.55));
113
+ will-change: transform, opacity;
114
+ animation:
115
+ splash-rise 0.5s cubic-bezier(0.16, 1, 0.3, 1) both,
116
+ splash-flicker 1.8s ease-in-out 0.5s infinite;
117
+ }
118
+ .splash-logo.draw {
119
+ width: 96px;
120
+ height: 96px;
121
+ filter: none;
122
+ animation: splash-rise 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
123
+ }
124
+
125
+ .splash-brand {
126
+ display: flex;
127
+ flex-direction: row;
128
+ align-items: center;
129
+ gap: 14px;
130
+ }
131
+
132
+ .splash-deepseek {
133
+ width: 234px;
134
+ height: auto;
135
+ display: block;
136
+ margin-top: 4px;
137
+ will-change: transform, opacity;
138
+ animation: splash-rise 0.5s cubic-bezier(0.16, 1, 0.3, 1) 0.1s both;
139
+ }
140
+
141
+ /* “HARNESS”七个字母:与 SPlayer-Next 的 Next 相同的描边动画,作为视觉重点 */
142
+ .splash-harness {
143
+ width: 310px;
144
+ height: 62px;
145
+ filter: drop-shadow(0 0 12px rgba(77, 107, 254, 0.45));
146
+ }
147
+ .splash-harness .letter {
148
+ stroke-width: 10;
149
+ fill: none;
150
+ stroke-linecap: square;
151
+ stroke-linejoin: round;
152
+ stroke-dasharray: 400;
153
+ stroke-dashoffset: 400;
154
+ will-change: stroke-dashoffset;
155
+ animation: splash-draw 1s ease forwards;
156
+ }
157
+ .splash-harness path:nth-of-type(1) { animation-delay: 0.20s; }
158
+ .splash-harness path:nth-of-type(2) { animation-delay: 0.42s; }
159
+ .splash-harness path:nth-of-type(3) { animation-delay: 0.64s; }
160
+ .splash-harness path:nth-of-type(4) { animation-delay: 0.86s; }
161
+ .splash-harness path:nth-of-type(5) { animation-delay: 1.08s; }
162
+ .splash-harness path:nth-of-type(6) { animation-delay: 1.30s; }
163
+ .splash-harness path:nth-of-type(7) { animation-delay: 1.52s; }
164
+
165
+ .splash-footer {
166
+ position: absolute;
167
+ left: 0;
168
+ right: 0;
169
+ bottom: 32px;
170
+ z-index: 1;
171
+ text-align: center;
172
+ font-size: 12px;
173
+ letter-spacing: 2px;
174
+ color: var(--muted);
175
+ animation: splash-rise-footer 0.5s cubic-bezier(0.16, 1, 0.3, 1) 0.36s both;
176
+ }
177
+
178
+ /* hold 模式:直接呈现动画结束态(WPF 即时启动页 → 浏览器启动页无缝衔接) */
179
+ body.hold .splash-logo {
180
+ animation: splash-flicker 1.8s ease-in-out 0.5s infinite;
181
+ }
182
+ body.hold .splash-deepseek {
183
+ animation: none;
184
+ opacity: 1;
185
+ }
186
+ body.hold .splash-harness .letter {
187
+ animation: none;
188
+ stroke-dashoffset: 0;
189
+ }
190
+ body.hold .splash-footer {
191
+ animation: none;
192
+ opacity: 0.4;
193
+ }
194
+
195
+ /* ---------- keyframes ---------- */
196
+ @keyframes splash-rise {
197
+ from { opacity: 0; transform: translateY(12px); }
198
+ to { opacity: 1; transform: translateY(0); }
199
+ }
200
+ @keyframes splash-rise-footer {
201
+ from { opacity: 0; transform: translateY(12px); }
202
+ to { opacity: 0.4; transform: translateY(0); }
203
+ }
204
+ @keyframes splash-flicker {
205
+ 0%, 100% { opacity: 1; }
206
+ 50% { opacity: 0.6; }
207
+ }
208
+ @keyframes splash-draw {
209
+ to { stroke-dashoffset: 0; }
210
+ }
211
+ </style>
212
+ </head>
213
+ <body>
214
+ <iframe id="appFrame" title="DeepSeek Harness" src="about:blank"></iframe>
215
+
216
+ <div id="app-loading">
217
+ <div class="bg"></div>
218
+
219
+ <div class="splash">
220
+ <img id="logo" class="splash-logo" src="whale.png" alt="DeepSeek" draggable="false" />
221
+ <div class="splash-brand">
222
+ <img class="splash-deepseek" src="deepseek-wordmark.svg" alt="deepseek" draggable="false" />
223
+ <svg class="splash-harness" viewBox="0 0 700 140" aria-hidden="true">
224
+ <defs>
225
+ <linearGradient id="harnessGrad" x1="0" y1="20" x2="700" y2="120" gradientUnits="userSpaceOnUse">
226
+ <stop offset="0" stop-color="#a7c0ff" />
227
+ <stop offset="0.5" stop-color="#4d6bfe" />
228
+ <stop offset="1" stop-color="#22d3ee" />
229
+ </linearGradient>
230
+ </defs>
231
+ <path class="letter" pathLength="400" stroke="url(#harnessGrad)" d="M15 20 L15 120 M85 20 L85 120 M15 70 L85 70" />
232
+ <path class="letter" pathLength="400" stroke="url(#harnessGrad)" d="M115 120 L150 20 L185 120 M132 72 L168 72" />
233
+ <path class="letter" pathLength="400" stroke="url(#harnessGrad)" d="M215 20 L215 120 M215 20 C242 16 285 19 285 45 C285 62 270 70 245 70 L215 70 M258 71 L285 120" />
234
+ <path class="letter" pathLength="400" stroke="url(#harnessGrad)" d="M315 120 L315 20 L385 120 L385 20" />
235
+ <path class="letter" pathLength="400" stroke="url(#harnessGrad)" d="M415 20 L415 120 M415 20 L485 20 M415 70 L465 70 M415 120 L485 120" />
236
+ <path class="letter" pathLength="400" stroke="url(#harnessGrad)" d="M585 20 L515 20 L515 70 L585 70 L585 120 L515 120" />
237
+ <path class="letter" pathLength="400" stroke="url(#harnessGrad)" d="M685 20 L615 20 L615 70 L685 70 L685 120 L615 120" />
238
+ </svg>
239
+ </div>
240
+ </div>
241
+
242
+ <div class="splash-footer">DeepSeek Harness · DSH GUI</div>
243
+ </div>
244
+
245
+ <script>
246
+ (function () {
247
+ var qs = new URLSearchParams(location.search);
248
+ var target = qs.get('target') || 'http://127.0.0.1:3080';
249
+ var timeoutSec = Math.max(15, parseInt(qs.get('timeout') || '90', 10) || 90);
250
+ // 双击 splash.html 打开(无参数)= 动画循环预览
251
+ var demo = qs.get('demo') === '1' || !qs.has('target');
252
+ // logo=draw:切换成鲸鱼本体一笔一划的旧版式
253
+ var drawLogo = qs.get('logo') === 'draw';
254
+ // 由 dsh 服务托管(同源):可后台 iframe 加载真实 GUI 并检测就绪
255
+ var served = location.protocol === 'http:' || location.protocol === 'https:';
256
+ // hold:直接呈现结束态,用于 WPF 即时启动页 → 浏览器启动页的无缝衔接
257
+ var hold = qs.get('hold') === '1';
258
+ if (hold) { document.body.classList.add('hold'); }
259
+ // handoff=0:dist 同步失败时的兜底——端口就绪后直接进 GUI(会短暂看到官方加载页)
260
+ var handoff = qs.get('handoff') !== '0';
261
+
262
+ if (drawLogo) {
263
+ var logo = document.getElementById('logo');
264
+ logo.src = 'whale-anim.svg';
265
+ logo.classList.add('draw');
266
+ }
267
+
268
+ var startedAt = performance.now();
269
+ var splashAnimMs = drawLogo ? 3000 : 2700;
270
+ var leaving = false;
271
+
272
+ if (demo) {
273
+ setInterval(function () { location.reload(); }, 9000);
274
+ return;
275
+ }
276
+
277
+ var frame = document.getElementById('appFrame');
278
+ frame.setAttribute('allow', 'clipboard-read; clipboard-write; fullscreen; autoplay');
279
+
280
+ /* 静默端口探测(仅 file:// 阶段使用) */
281
+ function probe() {
282
+ return new Promise(function (resolve) {
283
+ var settled = false;
284
+ var timer = setTimeout(function () { finish(false); }, 1500);
285
+ function finish(v) {
286
+ if (!settled) { settled = true; clearTimeout(timer); resolve(v); }
287
+ }
288
+ try {
289
+ fetch(target, { mode: 'no-cors', cache: 'no-store' })
290
+ .then(function () { finish(true); })
291
+ .catch(function () {});
292
+ } catch (e) {}
293
+ var img = new Image();
294
+ img.onload = function () { finish(true); };
295
+ img.onerror = function () { finish(false); };
296
+ img.src = target + '/favicon.svg?probe=' + Date.now();
297
+ });
298
+ }
299
+
300
+ function fadeAndGo(url) {
301
+ if (leaving) return;
302
+ leaving = true;
303
+ var overlay = document.getElementById('app-loading');
304
+ overlay.classList.add('hidden');
305
+ var done = false;
306
+ var go = function () {
307
+ if (done) return;
308
+ done = true;
309
+ location.replace(url);
310
+ };
311
+ overlay.addEventListener('transitionend', go, { once: true });
312
+ setTimeout(go, 400);
313
+ }
314
+
315
+ function appReady() {
316
+ var doc = null;
317
+ try { doc = frame.contentDocument; } catch (e) { return false; }
318
+ if (!doc || !doc.getElementById('root')) return false;
319
+ var root = doc.getElementById('root');
320
+ // 官方 shell 的启动卡片 class 形如 _boot_xxx;消失即插件装载完成
321
+ if (root.querySelector('[class*="_boot_"]')) return false;
322
+ if (root.querySelector('[class*="_failed_"]')) return true; // 失败态也揭示,由应用自己展示错误
323
+ return root.childElementCount > 0;
324
+ }
325
+
326
+ function revealApp() {
327
+ if (leaving) return;
328
+ leaving = true;
329
+ frame.style.visibility = 'visible';
330
+ var overlay = document.getElementById('app-loading');
331
+ overlay.classList.add('hidden');
332
+ overlay.addEventListener('transitionend', function () { overlay.remove(); }, { once: true });
333
+ setTimeout(function () {
334
+ try { frame.focus(); frame.contentWindow.focus(); } catch (e) {}
335
+ setInterval(function () {
336
+ try { var d = frame.contentDocument; if (d) document.title = d.title; } catch (e) {}
337
+ }, 1000);
338
+ }, 350);
339
+ }
340
+
341
+ if (served) {
342
+ /* 同源模式:后台加载真实 GUI,真正就绪后再揭示 */
343
+ frame.src = '/';
344
+ var minBeforeReveal = hold ? 250 : splashAnimMs;
345
+ var revealDeadline = startedAt + timeoutSec * 1000;
346
+ (function watch() {
347
+ if (leaving) return;
348
+ var now = performance.now();
349
+ if ((appReady() && now - startedAt >= minBeforeReveal) || now >= revealDeadline) {
350
+ revealApp();
351
+ return;
352
+ }
353
+ setTimeout(watch, 150);
354
+ })();
355
+ } else {
356
+ /* file:// 阶段:探测端口;就绪后转到同源 splash(hold 态,保持画面连续) */
357
+ (function poll() {
358
+ if (leaving) return;
359
+ probe().then(function (up) {
360
+ var elapsed = performance.now() - startedAt;
361
+ if (up && elapsed >= splashAnimMs) {
362
+ if (handoff) {
363
+ var base = target.replace(/\/+$/, '');
364
+ fadeAndGo(base + '/splash.html?hold=1&timeout=60' + (drawLogo ? '&logo=draw' : ''));
365
+ } else {
366
+ fadeAndGo(target);
367
+ }
368
+ } else if (elapsed > timeoutSec * 1000) {
369
+ fadeAndGo(target); // 兜底:交给浏览器显示结果
370
+ } else {
371
+ setTimeout(poll, 300);
372
+ }
373
+ });
374
+ })();
375
+ }
376
+ })();
377
+ </script>
378
+ </body>
379
+ </html>
package/whale-anim.svg ADDED
@@ -0,0 +1,48 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="200" height="200" fill="none">
2
+ <defs>
3
+ <linearGradient id="inkGrad" x1="4" y1="8" x2="46" y2="44" gradientUnits="userSpaceOnUse">
4
+ <stop offset="0" stop-color="#a7c0ff"/>
5
+ <stop offset="0.45" stop-color="#4d6bfe"/>
6
+ <stop offset="0.75" stop-color="#7c5cff"/>
7
+ <stop offset="1" stop-color="#22d3ee"/>
8
+ </linearGradient>
9
+ <linearGradient id="fillGrad" x1="14" y1="12" x2="34" y2="40" gradientUnits="userSpaceOnUse">
10
+ <stop offset="0" stop-color="#ffffff"/>
11
+ <stop offset="0.55" stop-color="#dbeafe"/>
12
+ <stop offset="1" stop-color="#9db8ff"/>
13
+ </linearGradient>
14
+ <filter id="softGlow" x="-40%" y="-40%" width="180%" height="180%">
15
+ <feGaussianBlur stdDeviation="1.6" result="b"/>
16
+ <feMerge>
17
+ <feMergeNode in="b"/>
18
+ <feMergeNode in="SourceGraphic"/>
19
+ </feMerge>
20
+ </filter>
21
+ </defs>
22
+ <style>
23
+ .ink {
24
+ stroke-dasharray: 1000;
25
+ stroke-dashoffset: 1000;
26
+ animation: draw 2.35s cubic-bezier(0.4, 0, 0.2, 1) forwards;
27
+ }
28
+ @keyframes draw { to { stroke-dashoffset: 0; } }
29
+ .fill {
30
+ animation: fill-in 0.55s ease 2.4s forwards;
31
+ }
32
+ @keyframes fill-in { from { opacity: 0; } to { opacity: 1; } }
33
+ .breathe {
34
+ transform-origin: 50% 50%;
35
+ animation: breathe 3.2s ease-in-out 2.8s infinite;
36
+ }
37
+ @keyframes breathe {
38
+ 0%, 100% { transform: scale(1); }
39
+ 50% { transform: scale(1.045); }
40
+ }
41
+ </style>
42
+ <g class="breathe">
43
+ <path class="ink" d="M48.8354 10.0479C48.3232 9.79199 48.1025 10.2798 47.8032 10.5278C47.7007 10.6079 47.6143 10.7119 47.5273 10.8076C46.7793 11.624 45.9048 12.1597 44.7622 12.0957C43.0923 12 41.666 12.5356 40.4058 13.8398C40.1377 12.2319 39.2476 11.272 37.8926 10.6558C37.1836 10.3359 36.4668 10.0156 35.9702 9.31982C35.6235 8.82373 35.5293 8.27197 35.356 7.72754C35.2456 7.3999 35.1353 7.06396 34.7651 7.00781C34.3633 6.94385 34.2056 7.2876 34.0479 7.57568C33.418 8.75195 33.1733 10.0479 33.1973 11.3599C33.2524 14.312 34.4736 16.6641 36.8999 18.3359C37.1758 18.5278 37.2466 18.7197 37.1597 19C36.9946 19.5757 36.7974 20.1357 36.624 20.7119C36.5137 21.0801 36.3486 21.1597 35.9624 21C34.6309 20.4321 33.481 19.5918 32.4644 18.5757C30.7393 16.8721 29.1792 14.9917 27.2334 13.52C26.7764 13.1758 26.3193 12.856 25.8467 12.5518C23.8618 10.584 26.1069 8.96777 26.627 8.77588C27.1704 8.57568 26.8159 7.8877 25.0591 7.896C23.3022 7.90381 21.6953 8.50391 19.647 9.30371C19.3477 9.42383 19.0322 9.51172 18.7095 9.58398C16.8501 9.22363 14.9199 9.14355 12.9033 9.37598C9.10596 9.80762 6.07275 11.6396 3.84326 14.7681C1.16455 18.5278 0.53418 22.7998 1.30664 27.2559C2.11768 31.9521 4.46582 35.8398 8.07373 38.8799C11.8159 42.0322 16.1255 43.5762 21.041 43.2803C24.0269 43.104 27.3516 42.6963 31.1016 39.4561C32.0469 39.936 33.0396 40.1279 34.686 40.272C35.9546 40.3921 37.1758 40.208 38.1211 40.0078C39.6021 39.688 39.4995 38.2881 38.9639 38.0322C34.623 35.9678 35.5762 36.8081 34.71 36.1279C36.9155 33.4639 40.2402 30.6958 41.54 21.728C41.6426 21.0161 41.5557 20.5679 41.54 19.9917C41.5322 19.6396 41.6108 19.5039 42.0049 19.4639C43.0923 19.3359 44.1479 19.0317 45.1167 18.4878C47.9292 16.9199 49.064 14.3438 49.3315 11.2559C49.3711 10.7837 49.3237 10.2959 48.8354 10.0479ZM24.3262 37.8398C20.1196 34.4639 18.0791 33.3521 17.2358 33.3999C16.4482 33.4482 16.5898 34.3682 16.7632 34.9678C16.9443 35.5601 17.1812 35.9683 17.5117 36.4878C17.7402 36.832 17.8979 37.3442 17.2832 37.728C15.9282 38.584 13.5728 37.4399 13.4624 37.3838C10.7207 35.7358 8.42822 33.5601 6.81348 30.584C5.25342 27.7197 4.34766 24.6479 4.19775 21.3677C4.1582 20.5757 4.38672 20.2959 5.15869 20.1519C6.17529 19.96 7.22314 19.9199 8.23926 20.0718C12.5327 20.7119 16.1885 22.6719 19.2529 25.7759C21.002 27.5439 22.3252 29.6558 23.6885 31.7202C25.1377 33.9121 26.6978 36 28.6831 37.7119C29.3843 38.312 29.9434 38.7681 30.479 39.104C28.8643 39.2881 26.1699 39.3281 24.3262 37.8398ZM26.3433 24.6001C26.3433 24.248 26.6191 23.9678 26.9658 23.9678C27.0444 23.9678 27.1152 23.9839 27.1782 24.0078C27.2651 24.04 27.3438 24.0879 27.4067 24.1602C27.5171 24.272 27.5801 24.4321 27.5801 24.6001C27.5801 24.9521 27.3042 25.2319 26.9575 25.2319C26.6108 25.2319 26.3433 24.9521 26.3433 24.6001ZM32.6064 27.8799C32.2046 28.0479 31.8027 28.1919 31.4165 28.208C30.8179 28.2397 30.1641 27.9922 29.8096 27.688C29.2583 27.2158 28.8643 26.9521 28.6987 26.1279C28.6279 25.7759 28.6675 25.2319 28.7305 24.9199C28.8721 24.248 28.7144 23.8159 28.2495 23.4238C27.8716 23.104 27.3911 23.0161 26.8633 23.0161C26.666 23.0161 26.4849 22.9277 26.3511 22.856C26.1304 22.7441 25.9492 22.4639 26.1226 22.1201C26.1777 22.0078 26.4458 21.7358 26.5088 21.688C27.2256 21.272 28.0527 21.4077 28.8169 21.7197C29.5259 22.0161 30.0615 22.5601 30.834 23.3281C31.6216 24.2559 31.7632 24.5117 32.2124 25.208C32.5669 25.752 32.8901 26.312 33.1104 26.9521C33.2446 27.3521 33.0713 27.6802 32.6064 27.8799Z" pathLength="1000"
44
+ stroke="url(#inkGrad)" stroke-width="0.85"
45
+ stroke-linecap="round" stroke-linejoin="round" fill="none"/>
46
+ <path class="fill" d="M48.8354 10.0479C48.3232 9.79199 48.1025 10.2798 47.8032 10.5278C47.7007 10.6079 47.6143 10.7119 47.5273 10.8076C46.7793 11.624 45.9048 12.1597 44.7622 12.0957C43.0923 12 41.666 12.5356 40.4058 13.8398C40.1377 12.2319 39.2476 11.272 37.8926 10.6558C37.1836 10.3359 36.4668 10.0156 35.9702 9.31982C35.6235 8.82373 35.5293 8.27197 35.356 7.72754C35.2456 7.3999 35.1353 7.06396 34.7651 7.00781C34.3633 6.94385 34.2056 7.2876 34.0479 7.57568C33.418 8.75195 33.1733 10.0479 33.1973 11.3599C33.2524 14.312 34.4736 16.6641 36.8999 18.3359C37.1758 18.5278 37.2466 18.7197 37.1597 19C36.9946 19.5757 36.7974 20.1357 36.624 20.7119C36.5137 21.0801 36.3486 21.1597 35.9624 21C34.6309 20.4321 33.481 19.5918 32.4644 18.5757C30.7393 16.8721 29.1792 14.9917 27.2334 13.52C26.7764 13.1758 26.3193 12.856 25.8467 12.5518C23.8618 10.584 26.1069 8.96777 26.627 8.77588C27.1704 8.57568 26.8159 7.8877 25.0591 7.896C23.3022 7.90381 21.6953 8.50391 19.647 9.30371C19.3477 9.42383 19.0322 9.51172 18.7095 9.58398C16.8501 9.22363 14.9199 9.14355 12.9033 9.37598C9.10596 9.80762 6.07275 11.6396 3.84326 14.7681C1.16455 18.5278 0.53418 22.7998 1.30664 27.2559C2.11768 31.9521 4.46582 35.8398 8.07373 38.8799C11.8159 42.0322 16.1255 43.5762 21.041 43.2803C24.0269 43.104 27.3516 42.6963 31.1016 39.4561C32.0469 39.936 33.0396 40.1279 34.686 40.272C35.9546 40.3921 37.1758 40.208 38.1211 40.0078C39.6021 39.688 39.4995 38.2881 38.9639 38.0322C34.623 35.9678 35.5762 36.8081 34.71 36.1279C36.9155 33.4639 40.2402 30.6958 41.54 21.728C41.6426 21.0161 41.5557 20.5679 41.54 19.9917C41.5322 19.6396 41.6108 19.5039 42.0049 19.4639C43.0923 19.3359 44.1479 19.0317 45.1167 18.4878C47.9292 16.9199 49.064 14.3438 49.3315 11.2559C49.3711 10.7837 49.3237 10.2959 48.8354 10.0479ZM24.3262 37.8398C20.1196 34.4639 18.0791 33.3521 17.2358 33.3999C16.4482 33.4482 16.5898 34.3682 16.7632 34.9678C16.9443 35.5601 17.1812 35.9683 17.5117 36.4878C17.7402 36.832 17.8979 37.3442 17.2832 37.728C15.9282 38.584 13.5728 37.4399 13.4624 37.3838C10.7207 35.7358 8.42822 33.5601 6.81348 30.584C5.25342 27.7197 4.34766 24.6479 4.19775 21.3677C4.1582 20.5757 4.38672 20.2959 5.15869 20.1519C6.17529 19.96 7.22314 19.9199 8.23926 20.0718C12.5327 20.7119 16.1885 22.6719 19.2529 25.7759C21.002 27.5439 22.3252 29.6558 23.6885 31.7202C25.1377 33.9121 26.6978 36 28.6831 37.7119C29.3843 38.312 29.9434 38.7681 30.479 39.104C28.8643 39.2881 26.1699 39.3281 24.3262 37.8398ZM26.3433 24.6001C26.3433 24.248 26.6191 23.9678 26.9658 23.9678C27.0444 23.9678 27.1152 23.9839 27.1782 24.0078C27.2651 24.04 27.3438 24.0879 27.4067 24.1602C27.5171 24.272 27.5801 24.4321 27.5801 24.6001C27.5801 24.9521 27.3042 25.2319 26.9575 25.2319C26.6108 25.2319 26.3433 24.9521 26.3433 24.6001ZM32.6064 27.8799C32.2046 28.0479 31.8027 28.1919 31.4165 28.208C30.8179 28.2397 30.1641 27.9922 29.8096 27.688C29.2583 27.2158 28.8643 26.9521 28.6987 26.1279C28.6279 25.7759 28.6675 25.2319 28.7305 24.9199C28.8721 24.248 28.7144 23.8159 28.2495 23.4238C27.8716 23.104 27.3911 23.0161 26.8633 23.0161C26.666 23.0161 26.4849 22.9277 26.3511 22.856C26.1304 22.7441 25.9492 22.4639 26.1226 22.1201C26.1777 22.0078 26.4458 21.7358 26.5088 21.688C27.2256 21.272 28.0527 21.4077 28.8169 21.7197C29.5259 22.0161 30.0615 22.5601 30.834 23.3281C31.6216 24.2559 31.7632 24.5117 32.2124 25.208C32.5669 25.752 32.8901 26.312 33.1104 26.9521C33.2446 27.3521 33.0713 27.6802 32.6064 27.8799Z" fill="url(#fillGrad)" opacity="0" filter="url(#softGlow)"/>
47
+ </g>
48
+ </svg>
package/whale.png ADDED
Binary file