petdex-cc 0.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 +21 -0
- package/README.md +247 -0
- package/README_CN.md +247 -0
- package/dist/bin/cli.d.ts +3 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +78 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/src/assets/tray-icon.png +0 -0
- package/dist/src/cli/config.d.ts +9 -0
- package/dist/src/cli/config.d.ts.map +1 -0
- package/dist/src/cli/config.js +41 -0
- package/dist/src/cli/config.js.map +1 -0
- package/dist/src/cli/install.d.ts +2 -0
- package/dist/src/cli/install.d.ts.map +1 -0
- package/dist/src/cli/install.js +62 -0
- package/dist/src/cli/install.js.map +1 -0
- package/dist/src/cli/list.d.ts +2 -0
- package/dist/src/cli/list.d.ts.map +1 -0
- package/dist/src/cli/list.js +20 -0
- package/dist/src/cli/list.js.map +1 -0
- package/dist/src/cli/start.d.ts +3 -0
- package/dist/src/cli/start.d.ts.map +1 -0
- package/dist/src/cli/start.js +37 -0
- package/dist/src/cli/start.js.map +1 -0
- package/dist/src/cli/status.d.ts +2 -0
- package/dist/src/cli/status.d.ts.map +1 -0
- package/dist/src/cli/status.js +8 -0
- package/dist/src/cli/status.js.map +1 -0
- package/dist/src/cli/stop.d.ts +2 -0
- package/dist/src/cli/stop.d.ts.map +1 -0
- package/dist/src/cli/stop.js +39 -0
- package/dist/src/cli/stop.js.map +1 -0
- package/dist/src/cli/switch.d.ts +2 -0
- package/dist/src/cli/switch.d.ts.map +1 -0
- package/dist/src/cli/switch.js +34 -0
- package/dist/src/cli/switch.js.map +1 -0
- package/dist/src/cli/uninstall.d.ts +2 -0
- package/dist/src/cli/uninstall.d.ts.map +1 -0
- package/dist/src/cli/uninstall.js +18 -0
- package/dist/src/cli/uninstall.js.map +1 -0
- package/dist/src/hooks/register.d.ts +3 -0
- package/dist/src/hooks/register.d.ts.map +1 -0
- package/dist/src/hooks/register.js +113 -0
- package/dist/src/hooks/register.js.map +1 -0
- package/dist/src/hooks/write-scripts.d.ts +2 -0
- package/dist/src/hooks/write-scripts.d.ts.map +1 -0
- package/dist/src/hooks/write-scripts.js +39 -0
- package/dist/src/hooks/write-scripts.js.map +1 -0
- package/dist/src/main/ai-speech.d.ts +22 -0
- package/dist/src/main/ai-speech.d.ts.map +1 -0
- package/dist/src/main/ai-speech.js +131 -0
- package/dist/src/main/ai-speech.js.map +1 -0
- package/dist/src/main/event-mapper.d.ts +10 -0
- package/dist/src/main/event-mapper.d.ts.map +1 -0
- package/dist/src/main/event-mapper.js +92 -0
- package/dist/src/main/event-mapper.js.map +1 -0
- package/dist/src/main/index.d.ts +2 -0
- package/dist/src/main/index.d.ts.map +1 -0
- package/dist/src/main/index.js +175 -0
- package/dist/src/main/index.js.map +1 -0
- package/dist/src/main/server.d.ts +8 -0
- package/dist/src/main/server.d.ts.map +1 -0
- package/dist/src/main/server.js +81 -0
- package/dist/src/main/server.js.map +1 -0
- package/dist/src/main/storage.d.ts +15 -0
- package/dist/src/main/storage.d.ts.map +1 -0
- package/dist/src/main/storage.js +90 -0
- package/dist/src/main/storage.js.map +1 -0
- package/dist/src/main/tray.d.ts +3 -0
- package/dist/src/main/tray.d.ts.map +1 -0
- package/dist/src/main/tray.js +156 -0
- package/dist/src/main/tray.js.map +1 -0
- package/dist/src/petdex-api/client.d.ts +21 -0
- package/dist/src/petdex-api/client.d.ts.map +1 -0
- package/dist/src/petdex-api/client.js +23 -0
- package/dist/src/petdex-api/client.js.map +1 -0
- package/dist/src/petdex-api/download.d.ts +8 -0
- package/dist/src/petdex-api/download.d.ts.map +1 -0
- package/dist/src/petdex-api/download.js +45 -0
- package/dist/src/petdex-api/download.js.map +1 -0
- package/dist/src/renderer/bubble.d.ts +30 -0
- package/dist/src/renderer/bubble.d.ts.map +1 -0
- package/dist/src/renderer/bubble.js +69 -0
- package/dist/src/renderer/bubble.js.map +1 -0
- package/dist/src/renderer/click-through.d.ts +21 -0
- package/dist/src/renderer/click-through.d.ts.map +1 -0
- package/dist/src/renderer/click-through.js +29 -0
- package/dist/src/renderer/click-through.js.map +1 -0
- package/dist/src/renderer/context-menu.d.ts +24 -0
- package/dist/src/renderer/context-menu.d.ts.map +1 -0
- package/dist/src/renderer/context-menu.js +83 -0
- package/dist/src/renderer/context-menu.js.map +1 -0
- package/dist/src/renderer/drag.d.ts +3 -0
- package/dist/src/renderer/drag.d.ts.map +1 -0
- package/dist/src/renderer/drag.js +57 -0
- package/dist/src/renderer/drag.js.map +1 -0
- package/dist/src/renderer/index.html +264 -0
- package/dist/src/renderer/pet-sprite.d.ts +25 -0
- package/dist/src/renderer/pet-sprite.d.ts.map +1 -0
- package/dist/src/renderer/pet-sprite.js +59 -0
- package/dist/src/renderer/pet-sprite.js.map +1 -0
- package/dist/src/renderer/renderer.d.ts +2 -0
- package/dist/src/renderer/renderer.d.ts.map +1 -0
- package/dist/src/renderer/renderer.js +244 -0
- package/dist/src/renderer/renderer.js.map +1 -0
- package/dist/src/renderer/wander.d.ts +8 -0
- package/dist/src/renderer/wander.d.ts.map +1 -0
- package/dist/src/renderer/wander.js +137 -0
- package/dist/src/renderer/wander.js.map +1 -0
- package/dist/src/shared/events.d.ts +62 -0
- package/dist/src/shared/events.d.ts.map +1 -0
- package/dist/src/shared/events.js +2 -0
- package/dist/src/shared/events.js.map +1 -0
- package/dist/src/shared/levels.d.ts +18 -0
- package/dist/src/shared/levels.d.ts.map +1 -0
- package/dist/src/shared/levels.js +20 -0
- package/dist/src/shared/levels.js.map +1 -0
- package/dist/src/shared/pet-states.d.ts +72 -0
- package/dist/src/shared/pet-states.d.ts.map +1 -0
- package/dist/src/shared/pet-states.js +20 -0
- package/dist/src/shared/pet-states.js.map +1 -0
- package/package.json +48 -0
- package/src/assets/tray-icon.png +0 -0
- package/src/hooks/bridge.ps1 +11 -0
- package/src/hooks/bridge.sh +9 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import machineId from "node-machine-id";
|
|
6
|
+
const { machineIdSync } = machineId;
|
|
7
|
+
const DATA_DIR = join(homedir(), ".petdex-cc", "data");
|
|
8
|
+
const STATE_FILE = join(DATA_DIR, "state.json");
|
|
9
|
+
const SIG_FILE = join(DATA_DIR, "state.sig");
|
|
10
|
+
function getHmacKey() {
|
|
11
|
+
return `petdex-cc-${machineIdSync()}`;
|
|
12
|
+
}
|
|
13
|
+
function signState(state) {
|
|
14
|
+
const key = getHmacKey();
|
|
15
|
+
return createHmac("sha256", key).update(JSON.stringify(state)).digest("hex");
|
|
16
|
+
}
|
|
17
|
+
function verifySignature(state, sig) {
|
|
18
|
+
const expected = signState(state);
|
|
19
|
+
if (expected.length !== sig.length)
|
|
20
|
+
return false;
|
|
21
|
+
try {
|
|
22
|
+
return timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function getDefaultState(slug = "") {
|
|
29
|
+
return {
|
|
30
|
+
petSlug: slug,
|
|
31
|
+
totalEvents: 0,
|
|
32
|
+
level: 1,
|
|
33
|
+
levelName: "Byte",
|
|
34
|
+
createdAt: new Date().toISOString(),
|
|
35
|
+
lastActiveAt: new Date().toISOString(),
|
|
36
|
+
version: 1,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function loadState() {
|
|
40
|
+
if (!existsSync(STATE_FILE) || !existsSync(SIG_FILE)) {
|
|
41
|
+
return getDefaultState();
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const raw = readFileSync(STATE_FILE, "utf8");
|
|
45
|
+
const sig = readFileSync(SIG_FILE, "utf8").trim();
|
|
46
|
+
const state = JSON.parse(raw);
|
|
47
|
+
if (!verifySignature(state, sig)) {
|
|
48
|
+
return getDefaultState(state.petSlug);
|
|
49
|
+
}
|
|
50
|
+
return state;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return getDefaultState();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function saveState(state) {
|
|
57
|
+
mkdirSync(DATA_DIR, { recursive: true });
|
|
58
|
+
const sig = signState(state);
|
|
59
|
+
writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
|
|
60
|
+
writeFileSync(SIG_FILE, sig);
|
|
61
|
+
}
|
|
62
|
+
export function incrementEvents(state, count = 1) {
|
|
63
|
+
const updated = {
|
|
64
|
+
...state,
|
|
65
|
+
totalEvents: state.totalEvents + count,
|
|
66
|
+
lastActiveAt: new Date().toISOString(),
|
|
67
|
+
};
|
|
68
|
+
const levels = [
|
|
69
|
+
{ level: 1, name: "Byte", threshold: 0 },
|
|
70
|
+
{ level: 2, name: "Process", threshold: 50 },
|
|
71
|
+
{ level: 3, name: "Thread", threshold: 200 },
|
|
72
|
+
{ level: 4, name: "Module", threshold: 500 },
|
|
73
|
+
{ level: 5, name: "Kernel", threshold: 1000 },
|
|
74
|
+
{ level: 6, name: "Neural", threshold: 2000 },
|
|
75
|
+
{ level: 7, name: "Quantum", threshold: 5000 },
|
|
76
|
+
{ level: 8, name: "Singularity", threshold: 10000 },
|
|
77
|
+
];
|
|
78
|
+
for (let i = levels.length - 1; i >= 0; i--) {
|
|
79
|
+
if (updated.totalEvents >= levels[i].threshold) {
|
|
80
|
+
updated.level = levels[i].level;
|
|
81
|
+
updated.levelName = levels[i].name;
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return updated;
|
|
86
|
+
}
|
|
87
|
+
export function detectLevelUp(oldState, newState) {
|
|
88
|
+
return newState.level > oldState.level;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/main/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tray.d.ts","sourceRoot":"","sources":["../../../src/main/tray.ts"],"names":[],"mappings":"AAEA,OAAO,EAAO,aAAa,EAAQ,IAAI,EAAe,MAAM,UAAU,CAAC;AAsGvE,wBAAgB,UAAU,CAAC,UAAU,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CA8DjE"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { join, dirname } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { app, Menu, Tray, nativeImage } from "electron";
|
|
4
|
+
let tray = null;
|
|
5
|
+
function generateTrayIcon() {
|
|
6
|
+
const S = 32;
|
|
7
|
+
const buf = Buffer.alloc(S * S * 4);
|
|
8
|
+
const cx = S / 2;
|
|
9
|
+
const cy = S / 2;
|
|
10
|
+
for (let y = 0; y < S; y++) {
|
|
11
|
+
for (let x = 0; x < S; x++) {
|
|
12
|
+
const i = (y * S + x) * 4;
|
|
13
|
+
const dx = x - cx + 0.5;
|
|
14
|
+
const dy = y - cy + 0.5;
|
|
15
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
16
|
+
// Outer circle: cat face background
|
|
17
|
+
const outerR = 14;
|
|
18
|
+
if (dist <= outerR) {
|
|
19
|
+
// Gradient: top-left lighter, bottom-right darker
|
|
20
|
+
const t = (dx / outerR + dy / outerR) / 2;
|
|
21
|
+
const r = Math.round(139 + (1 - t) * 40);
|
|
22
|
+
const g = Math.round(92 + (1 - t) * 40);
|
|
23
|
+
const b = Math.round(246);
|
|
24
|
+
// Anti-aliased edge
|
|
25
|
+
const edge = Math.max(0, Math.min(1, outerR - dist));
|
|
26
|
+
const alpha = Math.round(edge * 255);
|
|
27
|
+
// Highlight spot (upper-left)
|
|
28
|
+
const hx = dx + 4, hy = dy + 4;
|
|
29
|
+
const hDist = Math.sqrt(hx * hx + hy * hy);
|
|
30
|
+
const highlight = Math.max(0, 1 - hDist / 8) * 0.25;
|
|
31
|
+
buf[i] = Math.min(255, Math.round(r + highlight * 80));
|
|
32
|
+
buf[i + 1] = Math.min(255, Math.round(g + highlight * 80));
|
|
33
|
+
buf[i + 2] = Math.min(255, Math.round(b + highlight * 40));
|
|
34
|
+
buf[i + 3] = alpha;
|
|
35
|
+
}
|
|
36
|
+
// Cat ears (two triangles)
|
|
37
|
+
const earPoints = [
|
|
38
|
+
// Left ear
|
|
39
|
+
[{ x: -9, y: -8 }, { x: -5, y: -15 }, { x: -2, y: -7 }],
|
|
40
|
+
// Right ear
|
|
41
|
+
[{ x: 2, y: -7 }, { x: 5, y: -15 }, { x: 9, y: -8 }],
|
|
42
|
+
];
|
|
43
|
+
for (const ear of earPoints) {
|
|
44
|
+
const [a, b2, c] = ear;
|
|
45
|
+
const px = x - cx + 0.5, py = y - cy + 0.5;
|
|
46
|
+
// Point-in-triangle test
|
|
47
|
+
const d1 = (px - b2.x) * (a.y - b2.y) - (a.x - b2.x) * (py - b2.y);
|
|
48
|
+
const d2 = (px - c.x) * (b2.y - c.y) - (b2.x - c.x) * (py - c.y);
|
|
49
|
+
const d3 = (px - a.x) * (c.y - a.y) - (c.x - a.x) * (py - a.y);
|
|
50
|
+
const hasNeg = d1 < 0 || d2 < 0 || d3 < 0;
|
|
51
|
+
const hasPos = d1 > 0 || d2 > 0 || d3 > 0;
|
|
52
|
+
if (!(hasNeg && hasPos)) {
|
|
53
|
+
// Inside ear — slightly darker purple
|
|
54
|
+
buf[i] = 0x7c;
|
|
55
|
+
buf[i + 1] = 0x3a;
|
|
56
|
+
buf[i + 2] = 0xed;
|
|
57
|
+
buf[i + 3] = 0xff;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Eyes (two small white circles)
|
|
61
|
+
const eyes = [{ x: -4.5, y: -1 }, { x: 4.5, y: -1 }];
|
|
62
|
+
for (const eye of eyes) {
|
|
63
|
+
const ed = Math.sqrt((dx - eye.x) ** 2 + (dy - eye.y) ** 2);
|
|
64
|
+
if (ed <= 2.2) {
|
|
65
|
+
const edge = Math.max(0, Math.min(1, 2.2 - ed));
|
|
66
|
+
buf[i] = 0xff;
|
|
67
|
+
buf[i + 1] = 0xff;
|
|
68
|
+
buf[i + 2] = 0xff;
|
|
69
|
+
buf[i + 3] = Math.max(buf[i + 3], Math.round(edge * 255));
|
|
70
|
+
}
|
|
71
|
+
// Pupils
|
|
72
|
+
const pd = Math.sqrt((dx - eye.x) ** 2 + (dy - eye.y + 0.3) ** 2);
|
|
73
|
+
if (pd <= 1.2) {
|
|
74
|
+
buf[i] = 0x2d;
|
|
75
|
+
buf[i + 1] = 0x1b;
|
|
76
|
+
buf[i + 2] = 0x69;
|
|
77
|
+
buf[i + 3] = 0xff;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Mouth (small curved line)
|
|
81
|
+
const mouthY = 4;
|
|
82
|
+
if (Math.abs(dy - mouthY) < 1.2 && Math.abs(dx) < 4) {
|
|
83
|
+
const mouthCurve = (dx * dx) / 8;
|
|
84
|
+
if (dy > mouthY + mouthCurve - 1.5 && dy < mouthY + mouthCurve + 0.5) {
|
|
85
|
+
buf[i] = 0x3b;
|
|
86
|
+
buf[i + 1] = 0x1f;
|
|
87
|
+
buf[i + 2] = 0x6e;
|
|
88
|
+
buf[i + 3] = 0xff;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return nativeImage.createFromBuffer(buf, { width: S, height: S });
|
|
94
|
+
}
|
|
95
|
+
export function createTray(mainWindow) {
|
|
96
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
97
|
+
const iconPath = join(__dirname, "..", "assets", "tray-icon.png");
|
|
98
|
+
let icon;
|
|
99
|
+
try {
|
|
100
|
+
icon = nativeImage.createFromPath(iconPath);
|
|
101
|
+
if (icon.isEmpty())
|
|
102
|
+
throw new Error("empty");
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
icon = generateTrayIcon();
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
tray = new Tray(icon);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
console.warn("Tray creation failed:", err);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
tray.setToolTip("petdex-cc");
|
|
115
|
+
const contextMenu = Menu.buildFromTemplate([
|
|
116
|
+
{
|
|
117
|
+
label: "Show Pet",
|
|
118
|
+
click: () => mainWindow.show(),
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
label: "Hide Pet",
|
|
122
|
+
click: () => mainWindow.hide(),
|
|
123
|
+
},
|
|
124
|
+
{ type: "separator" },
|
|
125
|
+
{
|
|
126
|
+
label: "About",
|
|
127
|
+
click: async () => {
|
|
128
|
+
const { dialog } = await import("electron");
|
|
129
|
+
dialog.showMessageBox({
|
|
130
|
+
type: "info",
|
|
131
|
+
title: "petdex-cc",
|
|
132
|
+
message: "petdex-cc v0.1.0",
|
|
133
|
+
detail: "Desktop pet companion for Claude Code.\nPets from https://petdex.crafter.run",
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{ type: "separator" },
|
|
138
|
+
{
|
|
139
|
+
label: "Quit",
|
|
140
|
+
click: () => {
|
|
141
|
+
app.quit();
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
]);
|
|
145
|
+
tray.setContextMenu(contextMenu);
|
|
146
|
+
tray.on("click", () => {
|
|
147
|
+
if (mainWindow.isVisible()) {
|
|
148
|
+
mainWindow.hide();
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
mainWindow.show();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return tray;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=tray.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tray.js","sourceRoot":"","sources":["../../../src/main/tray.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface PetManifestEntry {
|
|
2
|
+
id: string;
|
|
3
|
+
slug: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
description: string;
|
|
6
|
+
spritesheetUrl: string;
|
|
7
|
+
petJsonUrl: string;
|
|
8
|
+
zipUrl: string;
|
|
9
|
+
kind: string;
|
|
10
|
+
vibes: string[];
|
|
11
|
+
tags: string[];
|
|
12
|
+
dominantColor: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function fetchManifest(): Promise<PetManifestEntry[]>;
|
|
15
|
+
export declare function findPetBySlug(slug: string): Promise<PetManifestEntry | null>;
|
|
16
|
+
export declare function listPets(): Promise<{
|
|
17
|
+
slug: string;
|
|
18
|
+
displayName: string;
|
|
19
|
+
kind: string;
|
|
20
|
+
}[]>;
|
|
21
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/petdex-api/client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAWjE;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAIlC;AAED,wBAAsB,QAAQ,IAAI,OAAO,CACvC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CACtD,CAOA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const MANIFEST_URL = "https://petdex.crafter.run/api/manifest";
|
|
2
|
+
export async function fetchManifest() {
|
|
3
|
+
const response = await fetch(MANIFEST_URL);
|
|
4
|
+
if (!response.ok) {
|
|
5
|
+
throw new Error(`Failed to fetch manifest: ${response.status} ${response.statusText}`);
|
|
6
|
+
}
|
|
7
|
+
const data = await response.json();
|
|
8
|
+
return (data.pets ?? data);
|
|
9
|
+
}
|
|
10
|
+
export async function findPetBySlug(slug) {
|
|
11
|
+
const manifest = await fetchManifest();
|
|
12
|
+
const lowerSlug = slug.toLowerCase();
|
|
13
|
+
return manifest.find((pet) => pet.slug.toLowerCase() === lowerSlug) ?? null;
|
|
14
|
+
}
|
|
15
|
+
export async function listPets() {
|
|
16
|
+
const manifest = await fetchManifest();
|
|
17
|
+
return manifest.map((pet) => ({
|
|
18
|
+
slug: pet.slug,
|
|
19
|
+
displayName: pet.displayName,
|
|
20
|
+
kind: pet.kind,
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/petdex-api/client.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,yCAAyC,CAAC;AAgB/D,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,CAAC;IAE3C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,6BAA6B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACtE,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAuB,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAY;IAEZ,MAAM,QAAQ,GAAG,MAAM,aAAa,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,IAAI,IAAI,CAAC;AAC9E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAG5B,MAAM,QAAQ,GAAG,MAAM,aAAa,EAAE,CAAC;IACvC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,IAAI,EAAE,GAAG,CAAC,IAAI;KACf,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PetManifestEntry } from "./client.js";
|
|
2
|
+
export declare function getPetDir(slug: string): string;
|
|
3
|
+
export declare function downloadPetAssets(pet: PetManifestEntry): Promise<{
|
|
4
|
+
spritesheetPath: string;
|
|
5
|
+
petJsonPath: string;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function isPetDownloaded(slug: string): boolean;
|
|
8
|
+
//# sourceMappingURL=download.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../../src/petdex-api/download.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAQD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA8B3D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAWrD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const PETDEX_DIR = path.join(homedir(), ".petdex-cc");
|
|
5
|
+
export function getPetDir(slug) {
|
|
6
|
+
return path.join(PETDEX_DIR, "pets", slug);
|
|
7
|
+
}
|
|
8
|
+
function resolveExtension(url) {
|
|
9
|
+
const pathname = new URL(url).pathname;
|
|
10
|
+
if (pathname.endsWith(".png"))
|
|
11
|
+
return ".png";
|
|
12
|
+
return ".webp";
|
|
13
|
+
}
|
|
14
|
+
export async function downloadPetAssets(pet) {
|
|
15
|
+
const petDir = getPetDir(pet.slug);
|
|
16
|
+
fs.mkdirSync(petDir, { recursive: true });
|
|
17
|
+
const spritesheetExt = resolveExtension(pet.spritesheetUrl);
|
|
18
|
+
const spritesheetPath = path.join(petDir, `spritesheet${spritesheetExt}`);
|
|
19
|
+
const petJsonPath = path.join(petDir, "pet.json");
|
|
20
|
+
// Download spritesheet
|
|
21
|
+
const spritesheetResponse = await fetch(pet.spritesheetUrl);
|
|
22
|
+
if (!spritesheetResponse.ok) {
|
|
23
|
+
throw new Error(`Failed to download spritesheet for ${pet.slug}: ${spritesheetResponse.status} ${spritesheetResponse.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
const spritesheetBuffer = Buffer.from(await spritesheetResponse.arrayBuffer());
|
|
26
|
+
fs.writeFileSync(spritesheetPath, spritesheetBuffer);
|
|
27
|
+
// Download pet.json
|
|
28
|
+
const petJsonResponse = await fetch(pet.petJsonUrl);
|
|
29
|
+
if (!petJsonResponse.ok) {
|
|
30
|
+
throw new Error(`Failed to download pet.json for ${pet.slug}: ${petJsonResponse.status} ${petJsonResponse.statusText}`);
|
|
31
|
+
}
|
|
32
|
+
const petJsonBuffer = Buffer.from(await petJsonResponse.arrayBuffer());
|
|
33
|
+
fs.writeFileSync(petJsonPath, petJsonBuffer);
|
|
34
|
+
return { spritesheetPath, petJsonPath };
|
|
35
|
+
}
|
|
36
|
+
export function isPetDownloaded(slug) {
|
|
37
|
+
const petDir = getPetDir(slug);
|
|
38
|
+
if (!fs.existsSync(petDir))
|
|
39
|
+
return false;
|
|
40
|
+
const files = fs.readdirSync(petDir);
|
|
41
|
+
const hasSpritesheet = files.some((f) => f.startsWith("spritesheet.") && (f.endsWith(".webp") || f.endsWith(".png")));
|
|
42
|
+
const hasPetJson = files.includes("pet.json");
|
|
43
|
+
return hasSpritesheet && hasPetJson;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=download.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../../src/petdex-api/download.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Speech bubble module.
|
|
3
|
+
*
|
|
4
|
+
* Manages the cartoon speech bubble displayed above the pet. Only one bubble
|
|
5
|
+
* is visible at a time; new bubbles immediately replace existing ones.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Truncates text to `maxLen` characters, appending "..." when truncated.
|
|
9
|
+
*/
|
|
10
|
+
export declare function truncateText(text: string, maxLen?: number): string;
|
|
11
|
+
/**
|
|
12
|
+
* Immediately hides the speech bubble.
|
|
13
|
+
*/
|
|
14
|
+
export declare function hideBubble(): void;
|
|
15
|
+
/**
|
|
16
|
+
* Shows a speech bubble with the given text for the specified duration.
|
|
17
|
+
*
|
|
18
|
+
* A new bubble replaces any currently-visible bubble. The bubble fades in
|
|
19
|
+
* over 200 ms and fades out after `durationMs`.
|
|
20
|
+
*
|
|
21
|
+
* @param text Text to display (will be truncated to 60 chars).
|
|
22
|
+
* @param durationMs How long to keep the bubble visible (default 3000 ms).
|
|
23
|
+
*/
|
|
24
|
+
export declare function showBubble(text: string, durationMs?: number): void;
|
|
25
|
+
/**
|
|
26
|
+
* Shows an AI-generated speech bubble. These last 8 seconds, longer than
|
|
27
|
+
* regular event bubbles.
|
|
28
|
+
*/
|
|
29
|
+
export declare function showAiBubble(text: string): void;
|
|
30
|
+
//# sourceMappingURL=bubble.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bubble.d.ts","sourceRoot":"","sources":["../../../src/renderer/bubble.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAW,GAAG,MAAM,CAGtE;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CASjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,MAA4B,GAAG,IAAI,CAiBvF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE/C"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Speech bubble module.
|
|
3
|
+
*
|
|
4
|
+
* Manages the cartoon speech bubble displayed above the pet. Only one bubble
|
|
5
|
+
* is visible at a time; new bubbles immediately replace existing ones.
|
|
6
|
+
*/
|
|
7
|
+
const BUBBLE_ELEMENT_ID = "bubble";
|
|
8
|
+
const HIDDEN_CLASS = "bubble-hidden";
|
|
9
|
+
const DEFAULT_DURATION_MS = 3000;
|
|
10
|
+
const AI_DURATION_MS = 8000;
|
|
11
|
+
const FADE_MS = 200;
|
|
12
|
+
let bubbleTimer = null;
|
|
13
|
+
function getBubble() {
|
|
14
|
+
return document.getElementById(BUBBLE_ELEMENT_ID);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Truncates text to `maxLen` characters, appending "..." when truncated.
|
|
18
|
+
*/
|
|
19
|
+
export function truncateText(text, maxLen = 60) {
|
|
20
|
+
if (text.length <= maxLen)
|
|
21
|
+
return text;
|
|
22
|
+
return text.slice(0, maxLen - 3) + "...";
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Immediately hides the speech bubble.
|
|
26
|
+
*/
|
|
27
|
+
export function hideBubble() {
|
|
28
|
+
const el = getBubble();
|
|
29
|
+
if (el) {
|
|
30
|
+
el.classList.add(HIDDEN_CLASS);
|
|
31
|
+
}
|
|
32
|
+
if (bubbleTimer !== null) {
|
|
33
|
+
clearTimeout(bubbleTimer);
|
|
34
|
+
bubbleTimer = null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Shows a speech bubble with the given text for the specified duration.
|
|
39
|
+
*
|
|
40
|
+
* A new bubble replaces any currently-visible bubble. The bubble fades in
|
|
41
|
+
* over 200 ms and fades out after `durationMs`.
|
|
42
|
+
*
|
|
43
|
+
* @param text Text to display (will be truncated to 60 chars).
|
|
44
|
+
* @param durationMs How long to keep the bubble visible (default 3000 ms).
|
|
45
|
+
*/
|
|
46
|
+
export function showBubble(text, durationMs = DEFAULT_DURATION_MS) {
|
|
47
|
+
const el = getBubble();
|
|
48
|
+
if (!el)
|
|
49
|
+
return;
|
|
50
|
+
// Cancel any existing timer so the new bubble takes over.
|
|
51
|
+
if (bubbleTimer !== null) {
|
|
52
|
+
clearTimeout(bubbleTimer);
|
|
53
|
+
bubbleTimer = null;
|
|
54
|
+
}
|
|
55
|
+
el.textContent = truncateText(text);
|
|
56
|
+
el.classList.remove(HIDDEN_CLASS);
|
|
57
|
+
bubbleTimer = setTimeout(() => {
|
|
58
|
+
el.classList.add(HIDDEN_CLASS);
|
|
59
|
+
bubbleTimer = null;
|
|
60
|
+
}, durationMs);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Shows an AI-generated speech bubble. These last 8 seconds, longer than
|
|
64
|
+
* regular event bubbles.
|
|
65
|
+
*/
|
|
66
|
+
export function showAiBubble(text) {
|
|
67
|
+
showBubble(text, AI_DURATION_MS);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=bubble.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bubble.js","sourceRoot":"","sources":["../../../src/renderer/bubble.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AACnC,MAAM,YAAY,GAAG,eAAe,CAAC;AACrC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACjC,MAAM,cAAc,GAAG,IAAI,CAAC;AAC5B,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB,IAAI,WAAW,GAAyC,IAAI,CAAC;AAE7D,SAAS,SAAS;IAChB,OAAO,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,SAAiB,EAAE;IAC5D,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IACvB,IAAI,EAAE,EAAE,CAAC;QACP,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,YAAY,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,aAAqB,mBAAmB;IAC/E,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE;QAAE,OAAO;IAEhB,0DAA0D;IAC1D,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,YAAY,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,EAAE,CAAC,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAElC,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC/B,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC,EAAE,UAAU,CAAC,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,UAAU,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Click-through module.
|
|
3
|
+
*
|
|
4
|
+
* Makes the BrowserWindow click-through (transparent to mouse events) by
|
|
5
|
+
* default, and disables click-through only when the cursor is over the pet
|
|
6
|
+
* sprite area so the user can interact with the pet.
|
|
7
|
+
*/
|
|
8
|
+
import type { BrowserWindow } from "electron";
|
|
9
|
+
/**
|
|
10
|
+
* Initialises click-through behaviour.
|
|
11
|
+
*
|
|
12
|
+
* - By default, `window.setIgnoreMouseEvents(true, { forward: true })` so
|
|
13
|
+
* clicks pass through transparent areas.
|
|
14
|
+
* - When the mouse enters the pet element bounds, click-through is disabled.
|
|
15
|
+
* - When the mouse leaves the pet element bounds, click-through is re-enabled.
|
|
16
|
+
*
|
|
17
|
+
* @param win The Electron BrowserWindow.
|
|
18
|
+
* @param petEl The pet sprite DOM element used for hit-testing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function initClickThrough(win: BrowserWindow, petEl: HTMLElement): void;
|
|
21
|
+
//# sourceMappingURL=click-through.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click-through.d.ts","sourceRoot":"","sources":["../../../src/renderer/click-through.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,WAAW,GACjB,IAAI,CAWN"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Click-through module.
|
|
3
|
+
*
|
|
4
|
+
* Makes the BrowserWindow click-through (transparent to mouse events) by
|
|
5
|
+
* default, and disables click-through only when the cursor is over the pet
|
|
6
|
+
* sprite area so the user can interact with the pet.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Initialises click-through behaviour.
|
|
10
|
+
*
|
|
11
|
+
* - By default, `window.setIgnoreMouseEvents(true, { forward: true })` so
|
|
12
|
+
* clicks pass through transparent areas.
|
|
13
|
+
* - When the mouse enters the pet element bounds, click-through is disabled.
|
|
14
|
+
* - When the mouse leaves the pet element bounds, click-through is re-enabled.
|
|
15
|
+
*
|
|
16
|
+
* @param win The Electron BrowserWindow.
|
|
17
|
+
* @param petEl The pet sprite DOM element used for hit-testing.
|
|
18
|
+
*/
|
|
19
|
+
export function initClickThrough(win, petEl) {
|
|
20
|
+
// Default: click-through enabled.
|
|
21
|
+
win.setIgnoreMouseEvents(true, { forward: true });
|
|
22
|
+
petEl.addEventListener("mouseenter", () => {
|
|
23
|
+
win.setIgnoreMouseEvents(false);
|
|
24
|
+
});
|
|
25
|
+
petEl.addEventListener("mouseleave", () => {
|
|
26
|
+
win.setIgnoreMouseEvents(true, { forward: true });
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=click-through.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click-through.js","sourceRoot":"","sources":["../../../src/renderer/click-through.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAkB,EAClB,KAAkB;IAElB,kCAAkC;IAClC,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAElD,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;QACxC,GAAG,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE;QACxC,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context menu module.
|
|
3
|
+
*
|
|
4
|
+
* Builds the right-click context menu for the pet. Electron Menu is
|
|
5
|
+
* available via the preload bridge in the renderer process.
|
|
6
|
+
*/
|
|
7
|
+
import { BrowserWindow } from "electron";
|
|
8
|
+
/**
|
|
9
|
+
* Creates the pet context menu.
|
|
10
|
+
*
|
|
11
|
+
* Menu items:
|
|
12
|
+
* - "Show Pet" / "Hide Pet" toggle
|
|
13
|
+
* - Separator
|
|
14
|
+
* - "Switch Pet..."
|
|
15
|
+
* - "Settings..."
|
|
16
|
+
* - "About"
|
|
17
|
+
* - Separator
|
|
18
|
+
* - "Quit"
|
|
19
|
+
*
|
|
20
|
+
* @param win The BrowserWindow this menu controls.
|
|
21
|
+
* @returns An Electron Menu instance.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createContextMenu(win: BrowserWindow): Electron.Menu;
|
|
24
|
+
//# sourceMappingURL=context-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-menu.d.ts","sourceRoot":"","sources":["../../../src/renderer/context-menu.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAa,aAAa,EAAE,MAAM,UAAU,CAAC;AAEpD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,QAAQ,CAAC,IAAI,CA2DnE"}
|