spora 0.3.2 → 0.3.4
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/dist/{account-creator-SETL5CGT.js → account-creator-AABUY2JU.js} +5 -5
- package/dist/{chunk-Q7YS3AIK.js → chunk-6KCIAMHL.js} +5 -6
- package/dist/chunk-6KCIAMHL.js.map +1 -0
- package/dist/{chunk-HERI4RPY.js → chunk-A6R5ZGK6.js} +2 -2
- package/dist/{chunk-QHFM2YW6.js → chunk-B6VI6L4D.js} +9 -44
- package/dist/chunk-B6VI6L4D.js.map +1 -0
- package/dist/{chunk-GJFBWIW3.js → chunk-FTFTB5Y5.js} +2 -2
- package/dist/{chunk-SXMDYUK3.js → chunk-GMSK775L.js} +29 -6
- package/dist/chunk-GMSK775L.js.map +1 -0
- package/dist/{chunk-POEDIDM6.js → chunk-H62HH5ZI.js} +2 -2
- package/dist/{chunk-NLWU5432.js → chunk-KQ37VL54.js} +5 -5
- package/dist/{chunk-JWMADEQO.js → chunk-ML4EMUZC.js} +3 -3
- package/dist/chunk-N5TBL3NY.js +86 -0
- package/dist/chunk-N5TBL3NY.js.map +1 -0
- package/dist/chunk-PNZ3XK2N.js +358 -0
- package/dist/chunk-PNZ3XK2N.js.map +1 -0
- package/dist/{chunk-J7J557HV.js → chunk-UCCAF2ZO.js} +2 -2
- package/dist/{chunk-RNVEWVDN.js → chunk-V6ZNR2SI.js} +2 -26
- package/dist/chunk-V6ZNR2SI.js.map +1 -0
- package/dist/cli.js +46 -46
- package/dist/cli.js.map +1 -1
- package/dist/{client-NVI3ZD4G.js → client-BGLXHLID.js} +10 -20
- package/dist/client-BGLXHLID.js.map +1 -0
- package/dist/client-TWYR2IIQ.js +373 -0
- package/dist/client-TWYR2IIQ.js.map +1 -0
- package/dist/{colony-J4EZQI37.js → colony-JVBCMZTK.js} +7 -7
- package/dist/{config-QRBOL4NX.js → config-5EPXA325.js} +3 -3
- package/dist/{crypto-ZVWJLD2J.js → crypto-HS4CGS4A.js} +3 -3
- package/dist/heartbeat-B2CZKMUF.js +901 -0
- package/dist/heartbeat-B2CZKMUF.js.map +1 -0
- package/dist/{identity-LN2R4KJU.js → identity-6CXRCXJQ.js} +3 -3
- package/dist/{init-ANGLSI2L.js → init-KXNLBFMG.js} +21 -21
- package/dist/init-KXNLBFMG.js.map +1 -0
- package/dist/llm-CUCO24K7.js +16 -0
- package/dist/mcp-server.js +24 -24
- package/dist/{memory-JMXU3UXR.js → memory-2OI3JXY2.js} +3 -3
- package/dist/{memory-J6AYZ5Y2.js → memory-LPU2I6NI.js} +3 -5
- package/dist/{paths-KXOWF2B2.js → paths-Q4TJEOMQ.js} +2 -2
- package/dist/prompt-builder-VHGZFBL6.js +19 -0
- package/dist/queue-LNBQWMFX.js +14 -0
- package/dist/web-chat/chat.html +38 -958
- package/dist/web-chat-DHHJTGFZ.js +253 -0
- package/dist/web-chat-DHHJTGFZ.js.map +1 -0
- package/dist/x-client-W5IB7XOM.js +12 -0
- package/package.json +2 -1
- package/dist/chunk-DFSYD45Q.js +0 -665
- package/dist/chunk-DFSYD45Q.js.map +0 -1
- package/dist/chunk-FCAK5FYQ.js +0 -127
- package/dist/chunk-FCAK5FYQ.js.map +0 -1
- package/dist/chunk-LRKBNKMQ.js +0 -79
- package/dist/chunk-LRKBNKMQ.js.map +0 -1
- package/dist/chunk-Q7YS3AIK.js.map +0 -1
- package/dist/chunk-QHFM2YW6.js.map +0 -1
- package/dist/chunk-R7PAD4OL.js +0 -44
- package/dist/chunk-R7PAD4OL.js.map +0 -1
- package/dist/chunk-RNVEWVDN.js.map +0 -1
- package/dist/chunk-SUFTVQME.js +0 -82
- package/dist/chunk-SUFTVQME.js.map +0 -1
- package/dist/chunk-SXMDYUK3.js.map +0 -1
- package/dist/chunk-YZ7RWJ6Z.js +0 -262
- package/dist/chunk-YZ7RWJ6Z.js.map +0 -1
- package/dist/client-23THPNVL.js +0 -382
- package/dist/client-23THPNVL.js.map +0 -1
- package/dist/client-NVI3ZD4G.js.map +0 -1
- package/dist/decision-engine-WBD36PZI.js +0 -19
- package/dist/goals-IM4AEHS4.js +0 -12
- package/dist/heartbeat-35HVB5PB.js +0 -317
- package/dist/heartbeat-35HVB5PB.js.map +0 -1
- package/dist/image-search-SZVMGWLN.js +0 -45
- package/dist/image-search-SZVMGWLN.js.map +0 -1
- package/dist/init-ANGLSI2L.js.map +0 -1
- package/dist/llm-MHZG2VHU.js +0 -16
- package/dist/performance-7G6R6ELJ.js +0 -18
- package/dist/prompt-builder-NSU4IFPB.js +0 -28
- package/dist/prompt-builder-NSU4IFPB.js.map +0 -1
- package/dist/queue-MLRTMJRE.js +0 -14
- package/dist/queue-MLRTMJRE.js.map +0 -1
- package/dist/strategy-TOVFBIZQ.js +0 -12
- package/dist/strategy-TOVFBIZQ.js.map +0 -1
- package/dist/web-chat/logo.png +0 -0
- package/dist/web-chat-N2AYUWT7.js +0 -802
- package/dist/web-chat-N2AYUWT7.js.map +0 -1
- package/dist/x-client-HUXCQOAW.js +0 -12
- package/dist/x-client-HUXCQOAW.js.map +0 -1
- /package/dist/{account-creator-SETL5CGT.js.map → account-creator-AABUY2JU.js.map} +0 -0
- /package/dist/{chunk-HERI4RPY.js.map → chunk-A6R5ZGK6.js.map} +0 -0
- /package/dist/{chunk-GJFBWIW3.js.map → chunk-FTFTB5Y5.js.map} +0 -0
- /package/dist/{chunk-POEDIDM6.js.map → chunk-H62HH5ZI.js.map} +0 -0
- /package/dist/{chunk-NLWU5432.js.map → chunk-KQ37VL54.js.map} +0 -0
- /package/dist/{chunk-JWMADEQO.js.map → chunk-ML4EMUZC.js.map} +0 -0
- /package/dist/{chunk-J7J557HV.js.map → chunk-UCCAF2ZO.js.map} +0 -0
- /package/dist/{colony-J4EZQI37.js.map → colony-JVBCMZTK.js.map} +0 -0
- /package/dist/{config-QRBOL4NX.js.map → config-5EPXA325.js.map} +0 -0
- /package/dist/{crypto-ZVWJLD2J.js.map → crypto-HS4CGS4A.js.map} +0 -0
- /package/dist/{decision-engine-WBD36PZI.js.map → identity-6CXRCXJQ.js.map} +0 -0
- /package/dist/{goals-IM4AEHS4.js.map → llm-CUCO24K7.js.map} +0 -0
- /package/dist/{identity-LN2R4KJU.js.map → memory-2OI3JXY2.js.map} +0 -0
- /package/dist/{llm-MHZG2VHU.js.map → memory-LPU2I6NI.js.map} +0 -0
- /package/dist/{memory-J6AYZ5Y2.js.map → paths-Q4TJEOMQ.js.map} +0 -0
- /package/dist/{memory-JMXU3UXR.js.map → prompt-builder-VHGZFBL6.js.map} +0 -0
- /package/dist/{paths-KXOWF2B2.js.map → queue-LNBQWMFX.js.map} +0 -0
- /package/dist/{performance-7G6R6ELJ.js.map → x-client-W5IB7XOM.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
logger
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-UCCAF2ZO.js";
|
|
4
|
+
import "./chunk-6KCIAMHL.js";
|
|
5
5
|
|
|
6
6
|
// src/account-creator/x-signup.ts
|
|
7
7
|
import { chromium } from "playwright";
|
|
@@ -71,7 +71,7 @@ async function checkInbox(inboxId, waitMs = 6e4) {
|
|
|
71
71
|
// src/account-creator/x-signup.ts
|
|
72
72
|
async function debugScreenshot(page, step) {
|
|
73
73
|
try {
|
|
74
|
-
const { paths, ensureDirectories } = await import("./paths-
|
|
74
|
+
const { paths, ensureDirectories } = await import("./paths-Q4TJEOMQ.js");
|
|
75
75
|
ensureDirectories();
|
|
76
76
|
const screenshotPath = `${paths.dataDir}/debug-${step}.png`;
|
|
77
77
|
await page.screenshot({ path: screenshotPath });
|
|
@@ -465,7 +465,7 @@ async function createXAccount(options) {
|
|
|
465
465
|
async function saveSession(context) {
|
|
466
466
|
const storageState = await context.storageState();
|
|
467
467
|
const { writeFileSync } = await import("fs");
|
|
468
|
-
const { paths, ensureDirectories } = await import("./paths-
|
|
468
|
+
const { paths, ensureDirectories } = await import("./paths-Q4TJEOMQ.js");
|
|
469
469
|
ensureDirectories();
|
|
470
470
|
writeFileSync(paths.browserAuth, JSON.stringify(storageState));
|
|
471
471
|
logger.info("Browser session saved.");
|
|
@@ -495,4 +495,4 @@ async function provisionAccount(options) {
|
|
|
495
495
|
export {
|
|
496
496
|
provisionAccount
|
|
497
497
|
};
|
|
498
|
-
//# sourceMappingURL=account-creator-
|
|
498
|
+
//# sourceMappingURL=account-creator-AABUY2JU.js.map
|
|
@@ -17,6 +17,8 @@ var paths = {
|
|
|
17
17
|
learnings: join(SPORA_DIR, "memory", "learnings.json"),
|
|
18
18
|
relationships: join(SPORA_DIR, "memory", "relationships.json"),
|
|
19
19
|
compacted: join(SPORA_DIR, "memory", "compacted"),
|
|
20
|
+
mood: join(SPORA_DIR, "memory", "mood.json"),
|
|
21
|
+
missions: join(SPORA_DIR, "missions"),
|
|
20
22
|
queue: join(SPORA_DIR, "queue"),
|
|
21
23
|
pendingPosts: join(SPORA_DIR, "queue", "pending-posts.json"),
|
|
22
24
|
logs: join(SPORA_DIR, "logs"),
|
|
@@ -25,11 +27,7 @@ var paths = {
|
|
|
25
27
|
llmKey: join(SPORA_DIR, "llm-key"),
|
|
26
28
|
runtimePid: join(SPORA_DIR, "runtime.pid"),
|
|
27
29
|
stopSignal: join(SPORA_DIR, "stop"),
|
|
28
|
-
connectionToken: join(SPORA_DIR, "connection-token")
|
|
29
|
-
lastChatMessage: join(SPORA_DIR, "last-chat-message.json"),
|
|
30
|
-
performance: join(SPORA_DIR, "memory", "performance.json"),
|
|
31
|
-
strategy: join(SPORA_DIR, "memory", "strategy.json"),
|
|
32
|
-
goals: join(SPORA_DIR, "memory", "goals.json")
|
|
30
|
+
connectionToken: join(SPORA_DIR, "connection-token")
|
|
33
31
|
};
|
|
34
32
|
function ensureDirectories() {
|
|
35
33
|
const dirs = [
|
|
@@ -38,6 +36,7 @@ function ensureDirectories() {
|
|
|
38
36
|
paths.memory,
|
|
39
37
|
paths.interactions,
|
|
40
38
|
paths.compacted,
|
|
39
|
+
paths.missions,
|
|
41
40
|
paths.queue,
|
|
42
41
|
paths.logs
|
|
43
42
|
];
|
|
@@ -60,4 +59,4 @@ export {
|
|
|
60
59
|
sporaExists,
|
|
61
60
|
hasXCredentials
|
|
62
61
|
};
|
|
63
|
-
//# sourceMappingURL=chunk-
|
|
62
|
+
//# sourceMappingURL=chunk-6KCIAMHL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/paths.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { mkdirSync, existsSync } from \"node:fs\";\n\nconst SPORA_DIR = join(homedir(), \".spora\");\n\nexport const paths = {\n root: SPORA_DIR,\n config: join(SPORA_DIR, \"config.json\"),\n credentials: join(SPORA_DIR, \"credentials.json\"),\n spore: join(SPORA_DIR, \"spore.json\"),\n identity: join(SPORA_DIR, \"identity.json\"),\n colonyToken: join(SPORA_DIR, \"colony-token.json\"),\n browser: join(SPORA_DIR, \"browser\"),\n browserAuth: join(SPORA_DIR, \"browser\", \"auth-state.json\"),\n memory: join(SPORA_DIR, \"memory\"),\n interactions: join(SPORA_DIR, \"memory\", \"interactions\"),\n learnings: join(SPORA_DIR, \"memory\", \"learnings.json\"),\n relationships: join(SPORA_DIR, \"memory\", \"relationships.json\"),\n compacted: join(SPORA_DIR, \"memory\", \"compacted\"),\n mood: join(SPORA_DIR, \"memory\", \"mood.json\"),\n missions: join(SPORA_DIR, \"missions\"),\n queue: join(SPORA_DIR, \"queue\"),\n pendingPosts: join(SPORA_DIR, \"queue\", \"pending-posts.json\"),\n logs: join(SPORA_DIR, \"logs\"),\n logFile: join(SPORA_DIR, \"logs\", \"spora.log\"),\n dataDir: SPORA_DIR,\n llmKey: join(SPORA_DIR, \"llm-key\"),\n runtimePid: join(SPORA_DIR, \"runtime.pid\"),\n stopSignal: join(SPORA_DIR, \"stop\"),\n connectionToken: join(SPORA_DIR, \"connection-token\"),\n} as const;\n\nexport function ensureDirectories(): void {\n const dirs = [\n paths.root,\n paths.browser,\n paths.memory,\n paths.interactions,\n paths.compacted,\n paths.missions,\n paths.queue,\n paths.logs,\n ];\n\n for (const dir of dirs) {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n }\n}\n\nexport function sporaExists(): boolean {\n return existsSync(paths.config) && existsSync(paths.identity);\n}\n\nexport function hasXCredentials(): boolean {\n return existsSync(paths.credentials);\n}\n"],"mappings":";AAAA,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,WAAW,kBAAkB;AAEtC,IAAM,YAAY,KAAK,QAAQ,GAAG,QAAQ;AAEnC,IAAM,QAAQ;AAAA,EACnB,MAAM;AAAA,EACN,QAAQ,KAAK,WAAW,aAAa;AAAA,EACrC,aAAa,KAAK,WAAW,kBAAkB;AAAA,EAC/C,OAAO,KAAK,WAAW,YAAY;AAAA,EACnC,UAAU,KAAK,WAAW,eAAe;AAAA,EACzC,aAAa,KAAK,WAAW,mBAAmB;AAAA,EAChD,SAAS,KAAK,WAAW,SAAS;AAAA,EAClC,aAAa,KAAK,WAAW,WAAW,iBAAiB;AAAA,EACzD,QAAQ,KAAK,WAAW,QAAQ;AAAA,EAChC,cAAc,KAAK,WAAW,UAAU,cAAc;AAAA,EACtD,WAAW,KAAK,WAAW,UAAU,gBAAgB;AAAA,EACrD,eAAe,KAAK,WAAW,UAAU,oBAAoB;AAAA,EAC7D,WAAW,KAAK,WAAW,UAAU,WAAW;AAAA,EAChD,MAAM,KAAK,WAAW,UAAU,WAAW;AAAA,EAC3C,UAAU,KAAK,WAAW,UAAU;AAAA,EACpC,OAAO,KAAK,WAAW,OAAO;AAAA,EAC9B,cAAc,KAAK,WAAW,SAAS,oBAAoB;AAAA,EAC3D,MAAM,KAAK,WAAW,MAAM;AAAA,EAC5B,SAAS,KAAK,WAAW,QAAQ,WAAW;AAAA,EAC5C,SAAS;AAAA,EACT,QAAQ,KAAK,WAAW,SAAS;AAAA,EACjC,YAAY,KAAK,WAAW,aAAa;AAAA,EACzC,YAAY,KAAK,WAAW,MAAM;AAAA,EAClC,iBAAiB,KAAK,WAAW,kBAAkB;AACrD;AAEO,SAAS,oBAA0B;AACxC,QAAM,OAAO;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAEA,aAAW,OAAO,MAAM;AACtB,QAAI,CAAC,WAAW,GAAG,GAAG;AACpB,gBAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACpC;AAAA,EACF;AACF;AAEO,SAAS,cAAuB;AACrC,SAAO,WAAW,MAAM,MAAM,KAAK,WAAW,MAAM,QAAQ;AAC9D;AAEO,SAAS,kBAA2B;AACzC,SAAO,WAAW,MAAM,WAAW;AACrC;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6KCIAMHL.js";
|
|
5
5
|
|
|
6
6
|
// src/colony/memory.ts
|
|
7
7
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
@@ -153,4 +153,4 @@ export {
|
|
|
153
153
|
getTodayEntries,
|
|
154
154
|
renderColonyBriefing
|
|
155
155
|
};
|
|
156
|
-
//# sourceMappingURL=chunk-
|
|
156
|
+
//# sourceMappingURL=chunk-A6R5ZGK6.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GMSK775L.js";
|
|
4
4
|
import {
|
|
5
5
|
logger
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UCCAF2ZO.js";
|
|
7
7
|
import {
|
|
8
8
|
ensureDirectories,
|
|
9
9
|
paths
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-6KCIAMHL.js";
|
|
11
11
|
|
|
12
12
|
// src/scheduler/queue.ts
|
|
13
13
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
@@ -48,15 +48,14 @@ function nextScheduledTime() {
|
|
|
48
48
|
}
|
|
49
49
|
return next.toISOString();
|
|
50
50
|
}
|
|
51
|
-
function addToQueue(content, scheduledFor
|
|
51
|
+
function addToQueue(content, scheduledFor) {
|
|
52
52
|
const queue = loadQueue();
|
|
53
53
|
const entry = {
|
|
54
54
|
id: `post-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
55
55
|
content,
|
|
56
56
|
scheduledFor: scheduledFor ?? nextScheduledTime(),
|
|
57
57
|
status: "pending",
|
|
58
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
59
|
-
...imageQuery ? { imageQuery } : {}
|
|
58
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
60
59
|
};
|
|
61
60
|
queue.entries.push(entry);
|
|
62
61
|
saveQueue(queue);
|
|
@@ -68,52 +67,18 @@ async function flushQueue() {
|
|
|
68
67
|
const now = /* @__PURE__ */ new Date();
|
|
69
68
|
let posted = 0;
|
|
70
69
|
let failed = 0;
|
|
71
|
-
const { getXClient } = await import("./x-client-
|
|
70
|
+
const { getXClient } = await import("./x-client-W5IB7XOM.js");
|
|
72
71
|
const client = await getXClient();
|
|
73
|
-
const STALE_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
74
|
-
for (const entry of queue.entries) {
|
|
75
|
-
if (entry.status !== "pending") continue;
|
|
76
|
-
const scheduledTime = new Date(entry.scheduledFor).getTime();
|
|
77
|
-
if (scheduledTime < now.getTime() - STALE_THRESHOLD_MS) {
|
|
78
|
-
entry.status = "expired";
|
|
79
|
-
logger.info(`Expired stale post: ${entry.id} (was scheduled for ${entry.scheduledFor})`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
72
|
for (const entry of queue.entries) {
|
|
83
73
|
if (entry.status !== "pending") continue;
|
|
84
74
|
if (new Date(entry.scheduledFor) > now) continue;
|
|
85
75
|
try {
|
|
86
|
-
|
|
87
|
-
if (entry.imageQuery) {
|
|
88
|
-
try {
|
|
89
|
-
const { searchImage, downloadImage } = await import("./image-search-SZVMGWLN.js");
|
|
90
|
-
const imageUrl = await searchImage(entry.imageQuery);
|
|
91
|
-
if (imageUrl) {
|
|
92
|
-
const imageBuffer = await downloadImage(imageUrl);
|
|
93
|
-
result = await client.postTweetWithMedia(entry.content, imageBuffer);
|
|
94
|
-
if (result.success) {
|
|
95
|
-
logger.info(`Posted with image: ${entry.id}`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
} catch (imgErr) {
|
|
99
|
-
logger.warn(`Image attach failed for ${entry.id}, posting text only: ${imgErr.message}`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (!result) {
|
|
103
|
-
result = await client.postTweet(entry.content);
|
|
104
|
-
}
|
|
76
|
+
const result = await client.postTweet(entry.content);
|
|
105
77
|
if (result.success) {
|
|
106
78
|
entry.status = "posted";
|
|
107
79
|
entry.postedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
108
80
|
posted++;
|
|
109
|
-
|
|
110
|
-
if (result.tweetId) {
|
|
111
|
-
try {
|
|
112
|
-
const { trackPost } = await import("./performance-7G6R6ELJ.js");
|
|
113
|
-
trackPost(result.tweetId, entry.content, "post");
|
|
114
|
-
} catch {
|
|
115
|
-
}
|
|
116
|
-
}
|
|
81
|
+
logger.info(`Posted: ${entry.id}`);
|
|
117
82
|
} else {
|
|
118
83
|
entry.status = "failed";
|
|
119
84
|
entry.error = result.error;
|
|
@@ -156,4 +121,4 @@ export {
|
|
|
156
121
|
flushQueue,
|
|
157
122
|
showQueue
|
|
158
123
|
};
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
124
|
+
//# sourceMappingURL=chunk-B6VI6L4D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/scheduler/queue.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { paths, ensureDirectories } from \"../utils/paths.js\";\nimport { loadConfig, saveConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport interface QueueEntry {\n id: string;\n content: string;\n scheduledFor: string;\n status: \"pending\" | \"posted\" | \"failed\" | \"expired\";\n createdAt: string;\n postedAt?: string;\n error?: string;\n}\n\ninterface QueueData {\n entries: QueueEntry[];\n}\n\nfunction loadQueue(): QueueData {\n if (!existsSync(paths.pendingPosts)) {\n return { entries: [] };\n }\n return JSON.parse(readFileSync(paths.pendingPosts, \"utf-8\")) as QueueData;\n}\n\nfunction saveQueue(data: QueueData): void {\n ensureDirectories();\n writeFileSync(paths.pendingPosts, JSON.stringify(data, null, 2));\n}\n\nfunction nextScheduledTime(): string {\n const config = loadConfig();\n const now = new Date();\n const queue = loadQueue();\n\n // Find the latest scheduled time in the queue\n const pendingEntries = queue.entries.filter((e) => e.status === \"pending\");\n let lastScheduled = now;\n\n if (pendingEntries.length > 0) {\n const latest = new Date(\n pendingEntries.reduce((max, e) =>\n new Date(e.scheduledFor) > new Date(max.scheduledFor) ? e : max\n ).scheduledFor\n );\n if (latest > lastScheduled) lastScheduled = latest;\n }\n\n // Add a random interval within the active hours\n const intervalMinutes = Math.floor(\n ((config.schedule.activeHoursEnd - config.schedule.activeHoursStart) * 60) /\n config.schedule.postsPerDay\n );\n\n const next = new Date(lastScheduled.getTime() + intervalMinutes * 60 * 1000);\n\n // Clamp to active hours\n if (next.getHours() >= config.schedule.activeHoursEnd) {\n next.setDate(next.getDate() + 1);\n next.setHours(config.schedule.activeHoursStart, Math.floor(Math.random() * 60), 0, 0);\n }\n if (next.getHours() < config.schedule.activeHoursStart) {\n next.setHours(config.schedule.activeHoursStart, Math.floor(Math.random() * 60), 0, 0);\n }\n\n return next.toISOString();\n}\n\nexport function addToQueue(content: string, scheduledFor?: string): QueueEntry {\n const queue = loadQueue();\n\n const entry: QueueEntry = {\n id: `post-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,\n content,\n scheduledFor: scheduledFor ?? nextScheduledTime(),\n status: \"pending\",\n createdAt: new Date().toISOString(),\n };\n\n queue.entries.push(entry);\n saveQueue(queue);\n\n logger.info(`Post queued: ${entry.id} scheduled for ${entry.scheduledFor}`);\n return entry;\n}\n\nexport async function flushQueue(): Promise<{\n posted: number;\n failed: number;\n remaining: number;\n}> {\n const queue = loadQueue();\n const now = new Date();\n let posted = 0;\n let failed = 0;\n\n const { getXClient } = await import(\"../x-client/index.js\");\n const client = await getXClient();\n\n for (const entry of queue.entries) {\n if (entry.status !== \"pending\") continue;\n if (new Date(entry.scheduledFor) > now) continue;\n\n try {\n const result = await client.postTweet(entry.content);\n if (result.success) {\n entry.status = \"posted\";\n entry.postedAt = new Date().toISOString();\n posted++;\n logger.info(`Posted: ${entry.id}`);\n } else {\n entry.status = \"failed\";\n entry.error = result.error;\n failed++;\n logger.warn(`Failed to post: ${entry.id} - ${result.error}`);\n }\n } catch (error) {\n entry.status = \"failed\";\n entry.error = (error as Error).message;\n failed++;\n }\n\n // Small delay between posts to avoid rate limits\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n\n saveQueue(queue);\n\n const remaining = queue.entries.filter((e) => e.status === \"pending\").length;\n return { posted, failed, remaining };\n}\n\nexport function showQueue(): void {\n const queue = loadQueue();\n const pending = queue.entries.filter((e) => e.status === \"pending\");\n\n if (pending.length === 0) {\n console.log(\"Queue is empty.\");\n return;\n }\n\n console.log(`\\n${pending.length} posts queued:\\n`);\n for (const entry of pending.sort(\n (a, b) => new Date(a.scheduledFor).getTime() - new Date(b.scheduledFor).getTime()\n )) {\n const time = new Date(entry.scheduledFor).toLocaleString();\n const preview = entry.content.length > 60 ? entry.content.slice(0, 60) + \"...\" : entry.content;\n console.log(` [${time}] ${preview}`);\n }\n console.log();\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6KCIAMHL.js";
|
|
5
5
|
|
|
6
6
|
// src/identity/index.ts
|
|
7
7
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
@@ -619,4 +619,4 @@ export {
|
|
|
619
619
|
mutateIdentity,
|
|
620
620
|
renderIdentityDocument
|
|
621
621
|
};
|
|
622
|
-
//# sourceMappingURL=chunk-
|
|
622
|
+
//# sourceMappingURL=chunk-FTFTB5Y5.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6KCIAMHL.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/config.ts
|
|
7
7
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
@@ -22,13 +22,36 @@ var ConfigSchema = z.object({
|
|
|
22
22
|
timezone: z.string()
|
|
23
23
|
}),
|
|
24
24
|
llm: z.object({
|
|
25
|
-
provider: z.enum(["anthropic", "openai"]).default("
|
|
26
|
-
model: z.string().default("
|
|
25
|
+
provider: z.enum(["anthropic", "openai", "deepseek"]).default("deepseek"),
|
|
26
|
+
model: z.string().default("deepseek-v3.2-speciale"),
|
|
27
|
+
baseUrl: z.string().default("https://api.llm-stats.com/v1")
|
|
27
28
|
}).optional(),
|
|
28
29
|
runtime: z.object({
|
|
29
|
-
heartbeatIntervalMs: z.number().default(
|
|
30
|
+
heartbeatIntervalMs: z.number().default(3e5),
|
|
30
31
|
actionsPerHeartbeat: z.number().default(3),
|
|
31
|
-
enabled: z.boolean().default(false)
|
|
32
|
+
enabled: z.boolean().default(false),
|
|
33
|
+
// Mode system configuration
|
|
34
|
+
modeSystem: z.object({
|
|
35
|
+
enabled: z.boolean().default(true),
|
|
36
|
+
allowRestMode: z.boolean().default(true),
|
|
37
|
+
modeWeightOverrides: z.record(z.number()).optional()
|
|
38
|
+
}).optional(),
|
|
39
|
+
// Curiosity system configuration
|
|
40
|
+
curiositySystem: z.object({
|
|
41
|
+
enabled: z.boolean().default(true),
|
|
42
|
+
explorationChance: z.number().default(0.15),
|
|
43
|
+
maxSearchesPerHeartbeat: z.number().default(3)
|
|
44
|
+
}).optional(),
|
|
45
|
+
// Mission system configuration
|
|
46
|
+
missionSystem: z.object({
|
|
47
|
+
enabled: z.boolean().default(true),
|
|
48
|
+
maxActiveMissions: z.number().default(5)
|
|
49
|
+
}).optional(),
|
|
50
|
+
// Variation/mood system configuration
|
|
51
|
+
variationSystem: z.object({
|
|
52
|
+
enabled: z.boolean().default(true),
|
|
53
|
+
moodDriftRate: z.number().default(0.1)
|
|
54
|
+
}).optional()
|
|
32
55
|
}).optional(),
|
|
33
56
|
connection: z.object({
|
|
34
57
|
token: z.string().optional(),
|
|
@@ -77,4 +100,4 @@ export {
|
|
|
77
100
|
saveConfig,
|
|
78
101
|
createDefaultConfig
|
|
79
102
|
};
|
|
80
|
-
//# sourceMappingURL=chunk-
|
|
103
|
+
//# sourceMappingURL=chunk-GMSK775L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/config.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { z } from \"zod\";\nimport { paths, ensureDirectories } from \"./paths.js\";\n\nexport const ConfigSchema = z.object({\n version: z.literal(1),\n xMethod: z.enum([\"api\", \"browser\"]),\n xApiTier: z.enum([\"free\", \"basic\"]).optional(),\n\n credits: z.object({\n monthlyPostLimit: z.number(),\n postsUsedThisMonth: z.number(),\n resetDate: z.string(),\n }),\n\n schedule: z.object({\n postsPerDay: z.number(),\n activeHoursStart: z.number().min(0).max(23),\n activeHoursEnd: z.number().min(0).max(23),\n timezone: z.string(),\n }),\n\n llm: z.object({\n provider: z.enum([\"anthropic\", \"openai\", \"deepseek\"]).default(\"deepseek\"),\n model: z.string().default(\"deepseek-v3.2-speciale\"),\n baseUrl: z.string().default(\"https://api.llm-stats.com/v1\"),\n }).optional(),\n\n runtime: z.object({\n heartbeatIntervalMs: z.number().default(300_000),\n actionsPerHeartbeat: z.number().default(3),\n enabled: z.boolean().default(false),\n\n // Mode system configuration\n modeSystem: z.object({\n enabled: z.boolean().default(true),\n allowRestMode: z.boolean().default(true),\n modeWeightOverrides: z.record(z.number()).optional(),\n }).optional(),\n\n // Curiosity system configuration\n curiositySystem: z.object({\n enabled: z.boolean().default(true),\n explorationChance: z.number().default(0.15),\n maxSearchesPerHeartbeat: z.number().default(3),\n }).optional(),\n\n // Mission system configuration\n missionSystem: z.object({\n enabled: z.boolean().default(true),\n maxActiveMissions: z.number().default(5),\n }).optional(),\n\n // Variation/mood system configuration\n variationSystem: z.object({\n enabled: z.boolean().default(true),\n moodDriftRate: z.number().default(0.1),\n }).optional(),\n }).optional(),\n\n connection: z.object({\n token: z.string().optional(),\n apiEndpoint: z.string().default(\"https://spora.dev/api/v1\"),\n lastSync: z.string().optional(),\n configVersion: z.number().default(0),\n }).optional(),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nexport function loadConfig(): Config {\n if (!existsSync(paths.config)) {\n throw new Error(\"Spora not initialized. Run `spora init` first.\");\n }\n const raw = readFileSync(paths.config, \"utf-8\");\n return ConfigSchema.parse(JSON.parse(raw));\n}\n\nexport function saveConfig(config: Config): void {\n ensureDirectories();\n ConfigSchema.parse(config);\n writeFileSync(paths.config, JSON.stringify(config, null, 2));\n}\n\nexport function createDefaultConfig(overrides: {\n xMethod: \"api\" | \"browser\";\n xApiTier?: \"free\" | \"basic\";\n timezone?: string;\n}): Config {\n const monthlyLimit = overrides.xApiTier === \"basic\" ? 10000 : 500;\n const now = new Date();\n const resetDate = new Date(now.getFullYear(), now.getMonth() + 1, 1).toISOString();\n\n return {\n version: 1,\n xMethod: overrides.xMethod,\n xApiTier: overrides.xApiTier,\n credits: {\n monthlyPostLimit: monthlyLimit,\n postsUsedThisMonth: 0,\n resetDate,\n },\n schedule: {\n postsPerDay: Math.floor(monthlyLimit / 30),\n activeHoursStart: 8,\n activeHoursEnd: 22,\n timezone: overrides.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone,\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6KCIAMHL.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/crypto.ts
|
|
7
7
|
import { createCipheriv, createDecipheriv, randomBytes, createHash } from "crypto";
|
|
@@ -53,4 +53,4 @@ export {
|
|
|
53
53
|
saveCredentials,
|
|
54
54
|
loadCredentials
|
|
55
55
|
};
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
56
|
+
//# sourceMappingURL=chunk-H62HH5ZI.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GMSK775L.js";
|
|
4
4
|
import {
|
|
5
5
|
logger
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UCCAF2ZO.js";
|
|
7
7
|
|
|
8
8
|
// src/x-client/index.ts
|
|
9
9
|
var clientInstance = null;
|
|
@@ -11,11 +11,11 @@ async function getXClient() {
|
|
|
11
11
|
if (clientInstance) return clientInstance;
|
|
12
12
|
const config = loadConfig();
|
|
13
13
|
if (config.xMethod === "api") {
|
|
14
|
-
const { XApiClient } = await import("./client-
|
|
14
|
+
const { XApiClient } = await import("./client-TWYR2IIQ.js");
|
|
15
15
|
clientInstance = new XApiClient();
|
|
16
16
|
logger.info("X client initialized: API mode");
|
|
17
17
|
} else {
|
|
18
|
-
const { XBrowserClient } = await import("./client-
|
|
18
|
+
const { XBrowserClient } = await import("./client-BGLXHLID.js");
|
|
19
19
|
clientInstance = new XBrowserClient();
|
|
20
20
|
logger.info("X client initialized: Browser mode");
|
|
21
21
|
}
|
|
@@ -29,4 +29,4 @@ export {
|
|
|
29
29
|
getXClient,
|
|
30
30
|
resetXClient
|
|
31
31
|
};
|
|
32
|
-
//# sourceMappingURL=chunk-
|
|
32
|
+
//# sourceMappingURL=chunk-KQ37VL54.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig,
|
|
3
3
|
saveConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GMSK775L.js";
|
|
5
5
|
import {
|
|
6
6
|
logger
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-UCCAF2ZO.js";
|
|
8
8
|
|
|
9
9
|
// src/x-client/rate-limiter.ts
|
|
10
10
|
var RateLimiter = class {
|
|
@@ -54,4 +54,4 @@ var rateLimiter = new RateLimiter();
|
|
|
54
54
|
export {
|
|
55
55
|
rateLimiter
|
|
56
56
|
};
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-ML4EMUZC.js.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadConfig
|
|
3
|
+
} from "./chunk-GMSK775L.js";
|
|
4
|
+
import {
|
|
5
|
+
logger
|
|
6
|
+
} from "./chunk-UCCAF2ZO.js";
|
|
7
|
+
import {
|
|
8
|
+
paths
|
|
9
|
+
} from "./chunk-6KCIAMHL.js";
|
|
10
|
+
|
|
11
|
+
// src/runtime/llm.ts
|
|
12
|
+
import OpenAI from "openai";
|
|
13
|
+
import { readFileSync, existsSync } from "fs";
|
|
14
|
+
var client = null;
|
|
15
|
+
var DEFAULT_MODEL = "deepseek-v3.2-speciale";
|
|
16
|
+
var DEFAULT_BASE_URL = "https://api.llm-stats.com/v1";
|
|
17
|
+
function getLLMApiKey() {
|
|
18
|
+
if (process.env.LLM_API_KEY) {
|
|
19
|
+
return process.env.LLM_API_KEY;
|
|
20
|
+
}
|
|
21
|
+
if (process.env.ANTHROPIC_API_KEY) {
|
|
22
|
+
return process.env.ANTHROPIC_API_KEY;
|
|
23
|
+
}
|
|
24
|
+
if (existsSync(paths.llmKey)) {
|
|
25
|
+
return readFileSync(paths.llmKey, "utf-8").trim();
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
function hasLLMKey() {
|
|
30
|
+
return getLLMApiKey() !== null;
|
|
31
|
+
}
|
|
32
|
+
function getClient() {
|
|
33
|
+
if (client) return client;
|
|
34
|
+
const apiKey = getLLMApiKey();
|
|
35
|
+
if (!apiKey) {
|
|
36
|
+
throw new Error("No LLM API key configured. Run `spora set-llm-key` first.");
|
|
37
|
+
}
|
|
38
|
+
const config = loadConfig();
|
|
39
|
+
const baseURL = config.llm?.baseUrl ?? DEFAULT_BASE_URL;
|
|
40
|
+
client = new OpenAI({ apiKey, baseURL });
|
|
41
|
+
return client;
|
|
42
|
+
}
|
|
43
|
+
async function generateResponse(systemPrompt, userMessage) {
|
|
44
|
+
const config = loadConfig();
|
|
45
|
+
const model = config.llm?.model ?? DEFAULT_MODEL;
|
|
46
|
+
logger.info(`Calling LLM (${model})...`);
|
|
47
|
+
const openai = getClient();
|
|
48
|
+
const response = await openai.chat.completions.create({
|
|
49
|
+
model,
|
|
50
|
+
max_tokens: 2048,
|
|
51
|
+
messages: [
|
|
52
|
+
{ role: "system", content: systemPrompt },
|
|
53
|
+
{ role: "user", content: userMessage }
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
const content = response.choices[0]?.message?.content ?? "";
|
|
57
|
+
const inputTokens = response.usage?.prompt_tokens ?? 0;
|
|
58
|
+
const outputTokens = response.usage?.completion_tokens ?? 0;
|
|
59
|
+
logger.info(`LLM response: ${inputTokens} in, ${outputTokens} out`);
|
|
60
|
+
return { content, inputTokens, outputTokens };
|
|
61
|
+
}
|
|
62
|
+
async function chat(systemPrompt, messages) {
|
|
63
|
+
const config = loadConfig();
|
|
64
|
+
const model = config.llm?.model ?? DEFAULT_MODEL;
|
|
65
|
+
const openai = getClient();
|
|
66
|
+
const response = await openai.chat.completions.create({
|
|
67
|
+
model,
|
|
68
|
+
max_tokens: 2048,
|
|
69
|
+
messages: [
|
|
70
|
+
{ role: "system", content: systemPrompt },
|
|
71
|
+
...messages
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
const content = response.choices[0]?.message?.content ?? "";
|
|
75
|
+
const inputTokens = response.usage?.prompt_tokens ?? 0;
|
|
76
|
+
const outputTokens = response.usage?.completion_tokens ?? 0;
|
|
77
|
+
return { content, inputTokens, outputTokens };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export {
|
|
81
|
+
getLLMApiKey,
|
|
82
|
+
hasLLMKey,
|
|
83
|
+
generateResponse,
|
|
84
|
+
chat
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=chunk-N5TBL3NY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/llm.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { paths } from \"../utils/paths.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\n\nlet client: OpenAI | null = null;\n\nconst DEFAULT_MODEL = \"deepseek-v3.2-speciale\";\nconst DEFAULT_BASE_URL = \"https://api.llm-stats.com/v1\";\n\nexport function getLLMApiKey(): string | null {\n // Check env first (support both old and new env var names), then file\n if (process.env.LLM_API_KEY) {\n return process.env.LLM_API_KEY;\n }\n if (process.env.ANTHROPIC_API_KEY) {\n return process.env.ANTHROPIC_API_KEY;\n }\n if (existsSync(paths.llmKey)) {\n return readFileSync(paths.llmKey, \"utf-8\").trim();\n }\n return null;\n}\n\nexport function hasLLMKey(): boolean {\n return getLLMApiKey() !== null;\n}\n\nfunction getClient(): OpenAI {\n if (client) return client;\n const apiKey = getLLMApiKey();\n if (!apiKey) {\n throw new Error(\"No LLM API key configured. Run `spora set-llm-key` first.\");\n }\n const config = loadConfig();\n const baseURL = config.llm?.baseUrl ?? DEFAULT_BASE_URL;\n client = new OpenAI({ apiKey, baseURL });\n return client;\n}\n\nexport interface LLMResponse {\n content: string;\n inputTokens: number;\n outputTokens: number;\n}\n\nexport async function generateResponse(\n systemPrompt: string,\n userMessage: string,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const model = config.llm?.model ?? DEFAULT_MODEL;\n\n logger.info(`Calling LLM (${model})...`);\n\n const openai = getClient();\n const response = await openai.chat.completions.create({\n model,\n max_tokens: 2048,\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userMessage },\n ],\n });\n\n const content = response.choices[0]?.message?.content ?? \"\";\n const inputTokens = response.usage?.prompt_tokens ?? 0;\n const outputTokens = response.usage?.completion_tokens ?? 0;\n\n logger.info(`LLM response: ${inputTokens} in, ${outputTokens} out`);\n\n return { content, inputTokens, outputTokens };\n}\n\nexport async function chat(\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const model = config.llm?.model ?? DEFAULT_MODEL;\n\n const openai = getClient();\n const response = await openai.chat.completions.create({\n model,\n max_tokens: 2048,\n messages: [\n { role: \"system\", content: systemPrompt },\n ...messages,\n ],\n });\n\n const content = response.choices[0]?.message?.content ?? \"\";\n const inputTokens = response.usage?.prompt_tokens ?? 0;\n const outputTokens = response.usage?.completion_tokens ?? 0;\n\n return { content, inputTokens, outputTokens };\n}\n"],"mappings":";;;;;;;;;;;AAAA,OAAO,YAAY;AACnB,SAAS,cAAc,kBAAkB;AAKzC,IAAI,SAAwB;AAE5B,IAAM,gBAAgB;AACtB,IAAM,mBAAmB;AAElB,SAAS,eAA8B;AAE5C,MAAI,QAAQ,IAAI,aAAa;AAC3B,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,MAAI,QAAQ,IAAI,mBAAmB;AACjC,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,MAAI,WAAW,MAAM,MAAM,GAAG;AAC5B,WAAO,aAAa,MAAM,QAAQ,OAAO,EAAE,KAAK;AAAA,EAClD;AACA,SAAO;AACT;AAEO,SAAS,YAAqB;AACnC,SAAO,aAAa,MAAM;AAC5B;AAEA,SAAS,YAAoB;AAC3B,MAAI,OAAQ,QAAO;AACnB,QAAM,SAAS,aAAa;AAC5B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,QAAM,SAAS,WAAW;AAC1B,QAAM,UAAU,OAAO,KAAK,WAAW;AACvC,WAAS,IAAI,OAAO,EAAE,QAAQ,QAAQ,CAAC;AACvC,SAAO;AACT;AAQA,eAAsB,iBACpB,cACA,aACsB;AACtB,QAAM,SAAS,WAAW;AAC1B,QAAM,QAAQ,OAAO,KAAK,SAAS;AAEnC,SAAO,KAAK,gBAAgB,KAAK,MAAM;AAEvC,QAAM,SAAS,UAAU;AACzB,QAAM,WAAW,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,IACpD;AAAA,IACA,YAAY;AAAA,IACZ,UAAU;AAAA,MACR,EAAE,MAAM,UAAU,SAAS,aAAa;AAAA,MACxC,EAAE,MAAM,QAAQ,SAAS,YAAY;AAAA,IACvC;AAAA,EACF,CAAC;AAED,QAAM,UAAU,SAAS,QAAQ,CAAC,GAAG,SAAS,WAAW;AACzD,QAAM,cAAc,SAAS,OAAO,iBAAiB;AACrD,QAAM,eAAe,SAAS,OAAO,qBAAqB;AAE1D,SAAO,KAAK,iBAAiB,WAAW,QAAQ,YAAY,MAAM;AAElE,SAAO,EAAE,SAAS,aAAa,aAAa;AAC9C;AAEA,eAAsB,KACpB,cACA,UACsB;AACtB,QAAM,SAAS,WAAW;AAC1B,QAAM,QAAQ,OAAO,KAAK,SAAS;AAEnC,QAAM,SAAS,UAAU;AACzB,QAAM,WAAW,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,IACpD;AAAA,IACA,YAAY;AAAA,IACZ,UAAU;AAAA,MACR,EAAE,MAAM,UAAU,SAAS,aAAa;AAAA,MACxC,GAAG;AAAA,IACL;AAAA,EACF,CAAC;AAED,QAAM,UAAU,SAAS,QAAQ,CAAC,GAAG,SAAS,WAAW;AACzD,QAAM,cAAc,SAAS,OAAO,iBAAiB;AACrD,QAAM,eAAe,SAAS,OAAO,qBAAqB;AAE1D,SAAO,EAAE,SAAS,aAAa,aAAa;AAC9C;","names":[]}
|