dsh-pet-live2d 3.2.0 → 3.3.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/CHANGELOG.md +10 -0
- package/README.md +13 -1
- package/icon.svg +45 -0
- package/lib/client.js +125 -7
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
+
## 3.3.0(2026-10-09)
|
|
4
|
+
|
|
5
|
+
### 新:官方「插件」页里有自己的图标和常用设置
|
|
6
|
+
|
|
7
|
+
侧栏「插件」页上这张卡片以前是默认插画加包名,现在有自己的图标、中文与英文标题/描述
|
|
8
|
+
(「设置 → 内置插件」那份列表同样受益)。点进详情页多了一节配置区:常用开关(气泡 /
|
|
9
|
+
提示音 / 摸头 / 摸尾巴 / 转圈 / 记住装扮)、四根手感滑杆(注视满偏、收回倍数、摸鱼静置、
|
|
10
|
+
提示音音量)和「显示位置」。它写的是与 **设置 → 桌宠** 同一份配置,改哪边都一样;
|
|
11
|
+
相位台词、池子编辑器、装扮与文案仍在设置页里改。
|
|
12
|
+
|
|
3
13
|
## 3.2.0(2026-10-09)
|
|
4
14
|
|
|
5
15
|
### 新:会话状态提示音
|
package/README.md
CHANGED
|
@@ -68,10 +68,22 @@ dsh plugin --profile web add "link:./dsh-pet-live2d/dsh-live2d-pet"
|
|
|
68
68
|
|
|
69
69
|
- **右键点宠物** 呼出面板:「动作」「装扮」两个页签,底部是大小滑杆和「归位」。
|
|
70
70
|
平时画面上没有常驻 UI。
|
|
71
|
-
- **改配置**
|
|
71
|
+
- **改配置** 两个入口:**DSH 设置页 → 桌宠**(完整设置),或**侧栏「插件」→ 本插件**(常用开关)。
|
|
72
72
|
|
|
73
73
|
## 设置说明
|
|
74
74
|
|
|
75
|
+
### 官方「插件」页上的那一节
|
|
76
|
+
|
|
77
|
+
侧栏点「插件」,「已安装」里那张带图标的卡片就是本插件。点进详情,描述与插件行之间是它
|
|
78
|
+
自己的配置区:
|
|
79
|
+
|
|
80
|
+
- **常用开关**:气泡、会话提示音、摸头 / 摸尾巴 / 转圈、跨启动记住装扮;
|
|
81
|
+
- **四根滑杆**:注视满偏、收回倍数、静置多久开始摸鱼、提示音音量;
|
|
82
|
+
- **显示位置**:自动 / 页面内 / 桌面。
|
|
83
|
+
|
|
84
|
+
改的是与设置页**同一份**配置(`%DSH_HOME%\pet-settings.json`),两边随时一致。相位台词、
|
|
85
|
+
池子编辑器、装扮与台词文案仍在 **设置 → 桌宠** 里改 —— 那里才是完整设置。
|
|
86
|
+
|
|
75
87
|
### 摸鱼:每个槽位一张条目表
|
|
76
88
|
|
|
77
89
|
摸鱼 = 静置一会儿之后,宠物自己换个样子。**每个槽位各掷一次骰子**(不是"这次只动一两个"),
|
package/icon.svg
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
dsh-pet-live2d 的插件图标(原创几何图形,不含模型的任何美术素材 ——
|
|
3
|
+
模型是 B站@氵六青 的 DS鲸鱼娘,授权与这个图标无关)。
|
|
4
|
+
|
|
5
|
+
用途:DSH 侧栏「插件」页、设置 → 内置插件列表里这张卡片的图标。
|
|
6
|
+
宿主的读法(`dsh-app-boot` 的 `readPluginMeta` → `iconOf`):
|
|
7
|
+
package.json 的 `"icon": "./icon.svg"`,或导出的 `./icon` 子路径;
|
|
8
|
+
必须是**包目录内的相对路径**,SVG / PNG / JPEG / WebP,≤256 KiB。
|
|
9
|
+
它以 `data:image/svg+xml;base64,…` 塞进 `<img width=36 height=36>`,
|
|
10
|
+
`object-fit:contain` —— 所以画布按 36×36 画、图形留一点边距,
|
|
11
|
+
且**不能依赖 currentColor**(img 里没有继承),颜色一律写死。
|
|
12
|
+
|
|
13
|
+
几何约定:所有图形都在 0…36 的 viewBox 内;尾鳍画在身体**之前**,
|
|
14
|
+
它靠左下那只角(10,20.4)藏在身体里,看起来才是连着的。
|
|
15
|
+
-->
|
|
16
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" width="36" height="36" role="img" aria-label="Live2D pet">
|
|
17
|
+
<title>Live2D 桌宠</title>
|
|
18
|
+
<defs>
|
|
19
|
+
<linearGradient id="pet-tile" x1="0" y1="0" x2="0.45" y2="1">
|
|
20
|
+
<stop offset="0" stop-color="#7FB0FF"/>
|
|
21
|
+
<stop offset="1" stop-color="#3B5DD4"/>
|
|
22
|
+
</linearGradient>
|
|
23
|
+
</defs>
|
|
24
|
+
|
|
25
|
+
<!-- 底:一块圆角砖。浅色与深色主题下都要能看见,所以自带底色而不是只描线。 -->
|
|
26
|
+
<rect x="0.6" y="0.6" width="34.8" height="34.8" rx="9.4" fill="url(#pet-tile)"/>
|
|
27
|
+
|
|
28
|
+
<!-- 头顶冒出来的那颗心(对应她的「冒爱心」表情) -->
|
|
29
|
+
<g fill="#FFB4D2">
|
|
30
|
+
<circle cx="12.7" cy="7.7" r="2"/>
|
|
31
|
+
<circle cx="16.5" cy="7.7" r="2"/>
|
|
32
|
+
<path d="M10.6 8.4h8l-4 4.3z"/>
|
|
33
|
+
</g>
|
|
34
|
+
|
|
35
|
+
<!-- 尾鳍(左下角压在身体下面) -->
|
|
36
|
+
<path d="M10 20.4 2.2 12.4l8.6.8z" fill="#D8E6FF"/>
|
|
37
|
+
|
|
38
|
+
<!-- 身体 -->
|
|
39
|
+
<ellipse cx="17.6" cy="21" rx="13" ry="7.4" fill="#FFFFFF"/>
|
|
40
|
+
|
|
41
|
+
<!-- 眼睛 / 嘴 / 腮红 -->
|
|
42
|
+
<circle cx="23.6" cy="19.9" r="1.7" fill="#1E2A4C"/>
|
|
43
|
+
<path d="M21.7 23.6c1 1 2.3 1 3.3 0" fill="none" stroke="#1E2A4C" stroke-width="1" stroke-linecap="round" opacity=".9"/>
|
|
44
|
+
<ellipse cx="18.9" cy="24" rx="1.9" ry="1.1" fill="#FFA6C8"/>
|
|
45
|
+
</svg>
|
package/lib/client.js
CHANGED
|
@@ -26,6 +26,15 @@ window.__ModuleLoader__.load({ id: "dsh-pet-live2d", factory: (require) => {
|
|
|
26
26
|
const { useCallback, useEffect, useRef, useState } = react;
|
|
27
27
|
|
|
28
28
|
const name = "live2d-pet";
|
|
29
|
+
/**
|
|
30
|
+
* 本包的 npm 包名。
|
|
31
|
+
*
|
|
32
|
+
* 官方「插件」页按**包名**派发组合包的配置区(`plugins.bundle.config` 的 key 就是
|
|
33
|
+
* 组合包的包名,见 `dsh-client-ui-plugin-manager` 的 `configLedgerSource`),所以这个
|
|
34
|
+
* 字符串必须与 `package.json` 的 `name` 逐字相同 —— 写错的表现是"注册没报错、
|
|
35
|
+
* 页面上什么都没多出来"(页面按包名查不到这个键就不渲染那一节)。
|
|
36
|
+
*/
|
|
37
|
+
const PACKAGE_NAME = "dsh-pet-live2d";
|
|
29
38
|
// "slots" 是 DSH 客户端界面给插件的扩展点(设置页就是这么挂进去的)。
|
|
30
39
|
const inject = ["slots"];
|
|
31
40
|
|
|
@@ -3550,7 +3559,20 @@ window.__ModuleLoader__.load({ id: "dsh-pet-live2d", factory: (require) => {
|
|
|
3550
3559
|
+ SETTINGS_SEL + " [data-setting=phases]{grid-template-columns:minmax(0,1fr)}",
|
|
3551
3560
|
"}",
|
|
3552
3561
|
];
|
|
3553
|
-
|
|
3562
|
+
/**
|
|
3563
|
+
* 官方「插件」页那一节的微调(作用域 = 两个属性同时在的那个根节点)。
|
|
3564
|
+
*
|
|
3565
|
+
* 只有两条,都是有理由的:
|
|
3566
|
+
* * 状态行("她现在在哪")本来借的是 `[data-note]` 的灰度 —— 那是给补充说明用的,
|
|
3567
|
+
* 而这一行是这一节**最先要回答**的问题,按 55% 透明度画就太虚了;
|
|
3568
|
+
* * 插件页是窄栏,卡片间距收一档,四张卡不至于要滚半天。
|
|
3569
|
+
*/
|
|
3570
|
+
const PLUGIN_PAGE_CSS = [
|
|
3571
|
+
SETTINGS_SEL + "[data-pet-plugin-page]>[data-plugin-status]{font-size:11px;opacity:.85;padding:0 0 9px}",
|
|
3572
|
+
SETTINGS_SEL + "[data-pet-plugin-page] [data-card]{margin-bottom:8px}",
|
|
3573
|
+
];
|
|
3574
|
+
const STYLE_TEXT = CSS + "\n" + SETTINGS_CSS.join("\n") + "\n" + PLUGIN_PAGE_CSS.join("\n")
|
|
3575
|
+
+ "\n" + PAGE_PHASE_CSS.join("\n");
|
|
3554
3576
|
|
|
3555
3577
|
function ensureStyle() {
|
|
3556
3578
|
if (document.getElementById(STYLE_ID) !== null) return;
|
|
@@ -4752,8 +4774,13 @@ window.__ModuleLoader__.load({ id: "dsh-pet-live2d", factory: (require) => {
|
|
|
4752
4774
|
function TuningControls(props) {
|
|
4753
4775
|
useSettings();
|
|
4754
4776
|
const only = props?.group;
|
|
4755
|
-
|
|
4756
|
-
|
|
4777
|
+
// 也能按**具体键**挑几根滑杆(官方插件页那一节只放最常用的四项,
|
|
4778
|
+
// 不想把八根手感滑杆整套搬过去)。给了 keys 就按 keys 过滤,忽略 group。
|
|
4779
|
+
const keys = Array.isArray(props?.keys) ? props.keys : null;
|
|
4780
|
+
const fields = TUNING_FIELDS.filter((field) => keys === null
|
|
4781
|
+
? (only === undefined || tuningGroupOf(field) === only)
|
|
4782
|
+
: keys.includes(field.key));
|
|
4783
|
+
return h("div", { "data-settings": "", "data-setting": only ?? (keys === null ? "all" : "subset") },
|
|
4757
4784
|
fields.map((field) => h("label", {
|
|
4758
4785
|
key: field.key,
|
|
4759
4786
|
"data-field": field.key,
|
|
@@ -4773,13 +4800,14 @@ window.__ModuleLoader__.load({ id: "dsh-pet-live2d", factory: (require) => {
|
|
|
4773
4800
|
h("code", { "data-value": field.key }, String(TUNING[field.key])),
|
|
4774
4801
|
)),
|
|
4775
4802
|
// 恢复默认单独一行:它是"这一组"的动作,混在滑杆行里会看着像又一个控件。
|
|
4803
|
+
// 只挑了四项时按钮说"全部" —— 它恢复的确实是整份 TUNING,不含糊。
|
|
4776
4804
|
only === undefined || only === "feel"
|
|
4777
4805
|
? h("div", { "data-add-row": "" },
|
|
4778
4806
|
h("button", {
|
|
4779
4807
|
type: "button",
|
|
4780
4808
|
"data-reset": "tuning",
|
|
4781
4809
|
onClick: () => applyTuning(Object.assign({}, TUNING_DEFAULTS)),
|
|
4782
|
-
}, "恢复默认"))
|
|
4810
|
+
}, keys === null ? "恢复默认" : "全部恢复默认"))
|
|
4783
4811
|
: null,
|
|
4784
4812
|
);
|
|
4785
4813
|
}
|
|
@@ -8621,15 +8649,25 @@ window.__ModuleLoader__.load({ id: "dsh-pet-live2d", factory: (require) => {
|
|
|
8621
8649
|
);
|
|
8622
8650
|
}
|
|
8623
8651
|
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8652
|
+
/**
|
|
8653
|
+
* 一张设置卡片:标题条(+ 右上角提示)+ 内容区。
|
|
8654
|
+
*
|
|
8655
|
+
* 提到模块作用域是因为现在**两个地方**要画同一种卡片:DSH 设置页那一节,和官方
|
|
8656
|
+
* 「插件」页上这一组合包的配置区。各写一份的下场是两边慢慢长得不一样。
|
|
8657
|
+
*/
|
|
8658
|
+
function settingsCard(key, title, hint, body) {
|
|
8659
|
+
return h("div", { key, "data-card": key },
|
|
8627
8660
|
h("div", { "data-card-head": "" },
|
|
8628
8661
|
h("span", { "data-card-title": "" }, title),
|
|
8629
8662
|
hint === null || hint === undefined ? null : h("span", { "data-card-hint": "" }, hint),
|
|
8630
8663
|
),
|
|
8631
8664
|
h("div", { "data-card-body": "" }, body),
|
|
8632
8665
|
);
|
|
8666
|
+
}
|
|
8667
|
+
|
|
8668
|
+
function PetSettingsBody({ compact = false } = {}) {
|
|
8669
|
+
useSettings();
|
|
8670
|
+
const card = settingsCard;
|
|
8633
8671
|
return [
|
|
8634
8672
|
...TUNING_GROUPS.filter((group) => !TUNING_GROUPS_INLINE.includes(group.id)).map((group) => card(
|
|
8635
8673
|
"tune-" + group.id, group.label, group.hint, h(TuningControls, { group: group.id }))),
|
|
@@ -8680,6 +8718,61 @@ window.__ModuleLoader__.load({ id: "dsh-pet-live2d", factory: (require) => {
|
|
|
8680
8718
|
return h("div", { "data-pet-settings": "" }, h(PetSettingsBody, null));
|
|
8681
8719
|
}
|
|
8682
8720
|
|
|
8721
|
+
/**
|
|
8722
|
+
* 侧栏「插件」页上这一组合包的配置区(`plugins.bundle.config`,键 = 包名)。
|
|
8723
|
+
*
|
|
8724
|
+
* 为什么要有它:官方插件页把"插件自带配置"渲染在**组合包详情页**的描述与行之间
|
|
8725
|
+
* (`dsh-client-ui-plugin-manager`;页面只在有人注册了这个键时才画那一节)。我们的
|
|
8726
|
+
* 组合包只有一行(`live2d-pet`),所以"这一行的配置"就是"这只宠物的配置"。
|
|
8727
|
+
*
|
|
8728
|
+
* 它**不是**设置正文的第二个家:相位台词、池子编辑器、装扮与文案仍然只在
|
|
8729
|
+
* 「设置 → 桌宠」里改(正文只写一份,这条是 2.0.0 定下来的)。这里是插件页上最常用的
|
|
8730
|
+
* 那几项 —— 开关、四根滑杆、显示位置 —— 写进去的还是**同一份共享设置**
|
|
8731
|
+
* (`persistShared` → `%DSH_HOME%\pet-settings.json`),所以两个界面永远一致。
|
|
8732
|
+
*
|
|
8733
|
+
* 样式直接复用设置正文那一套(`[data-pet-settings]` 作用域):卡片、行、滑杆、药丸
|
|
8734
|
+
* 按钮的观感与设置页逐字相同,不需要新写一份 CSS。
|
|
8735
|
+
*/
|
|
8736
|
+
function PetPluginConfig() {
|
|
8737
|
+
useSettings();
|
|
8738
|
+
const layer = useLayerState();
|
|
8739
|
+
const pet = MANIFEST.current ?? {};
|
|
8740
|
+
const petLabel = typeof pet.label === "string" && pet.label !== ""
|
|
8741
|
+
? pet.label
|
|
8742
|
+
: (typeof pet.id === "string" && pet.id !== "" ? pet.id : "还没加载");
|
|
8743
|
+
const modeLabel = layer.mode === "inline" ? "页面内" : (layer.mode === "desktop" ? "桌面" : "自动");
|
|
8744
|
+
const ownerLabel = layer.owner === "desktop" ? "现在在桌面上" : "现在在页面里";
|
|
8745
|
+
const flagRow = (key, label, note) => h("label", { key, "data-flag-row": key },
|
|
8746
|
+
h("input", {
|
|
8747
|
+
type: "checkbox",
|
|
8748
|
+
checked: FLAGS[key] === true,
|
|
8749
|
+
"data-flag": key,
|
|
8750
|
+
onChange: (event) => applyFlag(key, event.target.checked),
|
|
8751
|
+
}),
|
|
8752
|
+
h("span", { "data-row-label": "" }, label),
|
|
8753
|
+
note === undefined ? null : h("span", { "data-note-inline": "" }, note),
|
|
8754
|
+
);
|
|
8755
|
+
return h("div", { "data-pet-settings": "", "data-pet-plugin-page": "" },
|
|
8756
|
+
// 第一行先说"这只宠物现在在哪":它比任何开关都更该先回答,
|
|
8757
|
+
// 而且换过显示位置的人回来第一眼就是找这一句。
|
|
8758
|
+
h("div", { "data-plugin-status": "" },
|
|
8759
|
+
"当前宠物:" + petLabel + " · 显示位置:" + modeLabel + "(" + ownerLabel + ")"),
|
|
8760
|
+
settingsCard("plugin-flags", "常用开关", "点一下立刻生效", [
|
|
8761
|
+
flagRow("bubbleEnabled", "显示气泡", FLAGS.bubbleEnabled ? undefined : "已关:任何台词都不弹"),
|
|
8762
|
+
flagRow("soundEnabled", "会话提示音", FLAGS.soundEnabled ? undefined : "默认静音"),
|
|
8763
|
+
flagRow("patEnabled", "摸头有反应", undefined),
|
|
8764
|
+
flagRow("tailEnabled", "摸尾巴有反应", undefined),
|
|
8765
|
+
flagRow("spinEnabled", "鼠标绕着转圈会晕", undefined),
|
|
8766
|
+
flagRow("outfitArchive", "跨启动记住装扮", FLAGS.outfitArchive ? undefined : "已关:也不再记录"),
|
|
8767
|
+
]),
|
|
8768
|
+
settingsCard("plugin-tuning", "手感", "注视范围 · 摸鱼节奏 · 音量",
|
|
8769
|
+
h(TuningControls, { keys: ["gazeRangePx", "gazeWatchingRatio", "fidgetQuietMs", "soundVolume"] })),
|
|
8770
|
+
settingsCard("plugin-layer", "显示位置", "页面内 / 桌面上", h(LayerControls, null)),
|
|
8771
|
+
h("div", { "data-note": "" },
|
|
8772
|
+
"相位台词、池子编辑器、装扮与台词文案在「设置 → 桌宠」里改。"),
|
|
8773
|
+
);
|
|
8774
|
+
}
|
|
8775
|
+
|
|
8683
8776
|
function applySettings(ctx) {
|
|
8684
8777
|
if (ctx === null || ctx === undefined) return;
|
|
8685
8778
|
const slots = ctx.slots;
|
|
@@ -8696,6 +8789,30 @@ window.__ModuleLoader__.load({ id: "dsh-pet-live2d", factory: (require) => {
|
|
|
8696
8789
|
}
|
|
8697
8790
|
}
|
|
8698
8791
|
|
|
8792
|
+
/**
|
|
8793
|
+
* 侧栏「插件」页里的配置区。
|
|
8794
|
+
*
|
|
8795
|
+
* 两个容易踩的点:
|
|
8796
|
+
*
|
|
8797
|
+
* * **键必须写包名**(`PACKAGE_NAME`)—— 页面按组合包的包名派发这一格,写错的表现是
|
|
8798
|
+
* "注册成功、页面什么都不多"。
|
|
8799
|
+
* * **`slots.inject` 而不是"现在就注册"**:插件页是懒挂载的面板,它的子 slot 在页面
|
|
8800
|
+
* 注册时才声明;`inject` 会等到那一刻再跑(页面重开/销毁也跟着走)。
|
|
8801
|
+
*/
|
|
8802
|
+
function applyPluginPage(ctx) {
|
|
8803
|
+
if (ctx === null || ctx === undefined) return;
|
|
8804
|
+
const slots = ctx.slots;
|
|
8805
|
+
if (slots === undefined || slots === null) return;
|
|
8806
|
+
try {
|
|
8807
|
+
slots.inject("plugins.bundle.config", () => slots.register({
|
|
8808
|
+
name: "plugins.bundle.config",
|
|
8809
|
+
key: PACKAGE_NAME,
|
|
8810
|
+
}, () => h(PetPluginConfig, null)));
|
|
8811
|
+
} catch {
|
|
8812
|
+
/* 老版本 DSH 没有这条 slot:设置页那一节还在,不影响使用 */
|
|
8813
|
+
}
|
|
8814
|
+
}
|
|
8815
|
+
|
|
8699
8816
|
function apply(ctx) {
|
|
8700
8817
|
ensureStyle();
|
|
8701
8818
|
// 先按本地存档起来(宿主不在时这就是全部)。
|
|
@@ -8742,6 +8859,7 @@ window.__ModuleLoader__.load({ id: "dsh-pet-live2d", factory: (require) => {
|
|
|
8742
8859
|
}, SHARED_POLL_MS);
|
|
8743
8860
|
}
|
|
8744
8861
|
applySettings(ctx);
|
|
8862
|
+
applyPluginPage(ctx);
|
|
8745
8863
|
// Takeover: an earlier instance — a hot reload, or one left behind by a
|
|
8746
8864
|
// crashed reload — must not leave a second floating pet on the page.
|
|
8747
8865
|
teardown();
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-pet-live2d",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Live2D 桌宠插件:为 DSH Web GUI 挂一只可拖动、会跟随鼠标、能换动作与表情的 Live2D 宠物。",
|
|
5
|
+
"icon": "./icon.svg",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"main": "lib/index.js",
|
|
7
8
|
"license": "MIT",
|
|
@@ -18,6 +19,8 @@
|
|
|
18
19
|
"src",
|
|
19
20
|
"docs",
|
|
20
21
|
"pets",
|
|
22
|
+
"locale",
|
|
23
|
+
"icon.svg",
|
|
21
24
|
"cordis.patch.yml",
|
|
22
25
|
"screenshots.json",
|
|
23
26
|
"README.md",
|
|
@@ -31,6 +34,7 @@
|
|
|
31
34
|
"./client": "./lib/client.js",
|
|
32
35
|
"./desktop": "./lib/desktop.js",
|
|
33
36
|
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
37
|
+
"./locale/*.json": "./locale/*.json",
|
|
34
38
|
"./package.json": "./package.json"
|
|
35
39
|
},
|
|
36
40
|
"scripts": {
|
|
@@ -49,8 +53,8 @@
|
|
|
49
53
|
}
|
|
50
54
|
},
|
|
51
55
|
"optionalDependencies": {
|
|
52
|
-
"dsh-pet-live2d-desktop-darwin-arm64": "3.
|
|
53
|
-
"dsh-pet-live2d-desktop-win32-x64": "3.
|
|
56
|
+
"dsh-pet-live2d-desktop-darwin-arm64": "3.3.0",
|
|
57
|
+
"dsh-pet-live2d-desktop-win32-x64": "3.3.0"
|
|
54
58
|
},
|
|
55
59
|
"devDependencies": {
|
|
56
60
|
"esbuild": "^0.25.10",
|