spora 0.3.2 → 0.3.3
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/package.json +1 -1
- package/dist/account-creator-SETL5CGT.js +0 -498
- package/dist/account-creator-SETL5CGT.js.map +0 -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-GJFBWIW3.js +0 -622
- package/dist/chunk-GJFBWIW3.js.map +0 -1
- package/dist/chunk-HERI4RPY.js +0 -156
- package/dist/chunk-HERI4RPY.js.map +0 -1
- package/dist/chunk-J7J557HV.js +0 -47
- package/dist/chunk-J7J557HV.js.map +0 -1
- package/dist/chunk-JWMADEQO.js +0 -57
- package/dist/chunk-JWMADEQO.js.map +0 -1
- package/dist/chunk-LRKBNKMQ.js +0 -79
- package/dist/chunk-LRKBNKMQ.js.map +0 -1
- package/dist/chunk-NLWU5432.js +0 -32
- package/dist/chunk-NLWU5432.js.map +0 -1
- package/dist/chunk-POEDIDM6.js +0 -56
- package/dist/chunk-POEDIDM6.js.map +0 -1
- package/dist/chunk-Q7YS3AIK.js +0 -63
- package/dist/chunk-Q7YS3AIK.js.map +0 -1
- package/dist/chunk-QHFM2YW6.js +0 -159
- 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 +0 -129
- 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 +0 -80
- 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/cli.js +0 -654
- package/dist/cli.js.map +0 -1
- package/dist/client-23THPNVL.js +0 -382
- package/dist/client-23THPNVL.js.map +0 -1
- package/dist/client-NVI3ZD4G.js +0 -411
- package/dist/client-NVI3ZD4G.js.map +0 -1
- package/dist/colony-J4EZQI37.js +0 -229
- package/dist/colony-J4EZQI37.js.map +0 -1
- package/dist/config-QRBOL4NX.js +0 -14
- package/dist/config-QRBOL4NX.js.map +0 -1
- package/dist/crypto-ZVWJLD2J.js +0 -14
- package/dist/crypto-ZVWJLD2J.js.map +0 -1
- package/dist/decision-engine-WBD36PZI.js +0 -19
- package/dist/decision-engine-WBD36PZI.js.map +0 -1
- package/dist/goals-IM4AEHS4.js +0 -12
- package/dist/goals-IM4AEHS4.js.map +0 -1
- package/dist/heartbeat-35HVB5PB.js +0 -317
- package/dist/heartbeat-35HVB5PB.js.map +0 -1
- package/dist/identity-LN2R4KJU.js +0 -26
- package/dist/identity-LN2R4KJU.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 +0 -403
- package/dist/init-ANGLSI2L.js.map +0 -1
- package/dist/llm-MHZG2VHU.js +0 -16
- package/dist/llm-MHZG2VHU.js.map +0 -1
- package/dist/mcp-server.js +0 -773
- package/dist/mcp-server.js.map +0 -1
- package/dist/memory-J6AYZ5Y2.js +0 -26
- package/dist/memory-J6AYZ5Y2.js.map +0 -1
- package/dist/memory-JMXU3UXR.js +0 -26
- package/dist/memory-JMXU3UXR.js.map +0 -1
- package/dist/paths-KXOWF2B2.js +0 -13
- package/dist/paths-KXOWF2B2.js.map +0 -1
- package/dist/performance-7G6R6ELJ.js +0 -18
- package/dist/performance-7G6R6ELJ.js.map +0 -1
- 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/chat.html +0 -1343
- 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/package.json
CHANGED
|
@@ -1,498 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
logger
|
|
3
|
-
} from "./chunk-J7J557HV.js";
|
|
4
|
-
import "./chunk-Q7YS3AIK.js";
|
|
5
|
-
|
|
6
|
-
// src/account-creator/x-signup.ts
|
|
7
|
-
import { chromium } from "playwright";
|
|
8
|
-
|
|
9
|
-
// src/account-creator/email.ts
|
|
10
|
-
var SPORA_AGENTMAIL_KEY = process.env.SPORA_AGENTMAIL_KEY ?? "am_955344daf4d85d72dec6b97d9a5a6817b76d4a5ce09bfc66842bd0a5ef5b1657";
|
|
11
|
-
async function createAgentEmail(preferredUsername) {
|
|
12
|
-
const username = preferredUsername ?? `spore-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
|
|
13
|
-
try {
|
|
14
|
-
const response = await fetch("https://api.agentmail.to/v0/inboxes", {
|
|
15
|
-
method: "POST",
|
|
16
|
-
headers: {
|
|
17
|
-
"Content-Type": "application/json",
|
|
18
|
-
Authorization: `Bearer ${SPORA_AGENTMAIL_KEY}`
|
|
19
|
-
},
|
|
20
|
-
body: JSON.stringify({
|
|
21
|
-
username,
|
|
22
|
-
domain: "agentmail.to"
|
|
23
|
-
})
|
|
24
|
-
});
|
|
25
|
-
if (!response.ok) {
|
|
26
|
-
const error = await response.text();
|
|
27
|
-
throw new Error(`AgentMail API error: ${response.status} ${error}`);
|
|
28
|
-
}
|
|
29
|
-
const data = await response.json();
|
|
30
|
-
const address = `${username}@agentmail.to`;
|
|
31
|
-
logger.info(`Created email inbox: ${address}`);
|
|
32
|
-
return {
|
|
33
|
-
address,
|
|
34
|
-
inboxId: data.inbox_id
|
|
35
|
-
};
|
|
36
|
-
} catch (error) {
|
|
37
|
-
logger.error("Failed to create email via AgentMail", error);
|
|
38
|
-
throw error;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
async function checkInbox(inboxId, waitMs = 6e4) {
|
|
42
|
-
const startTime = Date.now();
|
|
43
|
-
while (Date.now() - startTime < waitMs) {
|
|
44
|
-
try {
|
|
45
|
-
const response = await fetch(
|
|
46
|
-
`https://api.agentmail.to/v0/inboxes/${encodeURIComponent(inboxId)}/messages`,
|
|
47
|
-
{
|
|
48
|
-
headers: {
|
|
49
|
-
Authorization: `Bearer ${SPORA_AGENTMAIL_KEY}`
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
);
|
|
53
|
-
if (!response.ok) continue;
|
|
54
|
-
const data = await response.json();
|
|
55
|
-
for (const msg of data.messages) {
|
|
56
|
-
if (msg.subject.toLowerCase().includes("verify") || msg.subject.toLowerCase().includes("confirmation") || msg.subject.toLowerCase().includes("code")) {
|
|
57
|
-
const body = msg.body_text || msg.text_content || "";
|
|
58
|
-
const codeMatch = body.match(/\b(\d{5,8})\b/);
|
|
59
|
-
if (codeMatch) {
|
|
60
|
-
return codeMatch[1];
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
} catch {
|
|
65
|
-
}
|
|
66
|
-
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
67
|
-
}
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// src/account-creator/x-signup.ts
|
|
72
|
-
async function debugScreenshot(page, step) {
|
|
73
|
-
try {
|
|
74
|
-
const { paths, ensureDirectories } = await import("./paths-KXOWF2B2.js");
|
|
75
|
-
ensureDirectories();
|
|
76
|
-
const screenshotPath = `${paths.dataDir}/debug-${step}.png`;
|
|
77
|
-
await page.screenshot({ path: screenshotPath });
|
|
78
|
-
logger.info(`Debug screenshot saved: ${screenshotPath}`);
|
|
79
|
-
} catch {
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
function randomDelay(min, max) {
|
|
83
|
-
const ms = Math.floor(Math.random() * (max - min)) + min;
|
|
84
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
85
|
-
}
|
|
86
|
-
async function humanTypeLocator(locator, text) {
|
|
87
|
-
await locator.click();
|
|
88
|
-
await randomDelay(200, 400);
|
|
89
|
-
for (const char of text) {
|
|
90
|
-
await locator.type(char, { delay: Math.floor(Math.random() * 120) + 30 });
|
|
91
|
-
if (Math.random() < 0.1) {
|
|
92
|
-
await randomDelay(200, 500);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
async function humanClick(page, locator) {
|
|
97
|
-
const box = await locator.boundingBox();
|
|
98
|
-
if (box) {
|
|
99
|
-
const x = box.x + Math.random() * box.width;
|
|
100
|
-
const y = box.y + Math.random() * box.height;
|
|
101
|
-
await page.mouse.move(x, y, { steps: Math.floor(Math.random() * 10) + 5 });
|
|
102
|
-
await randomDelay(100, 300);
|
|
103
|
-
}
|
|
104
|
-
await locator.click();
|
|
105
|
-
}
|
|
106
|
-
var STEALTH_SCRIPT = `
|
|
107
|
-
// Override navigator.webdriver
|
|
108
|
-
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
|
|
109
|
-
|
|
110
|
-
// Override chrome runtime
|
|
111
|
-
window.chrome = {
|
|
112
|
-
runtime: {},
|
|
113
|
-
loadTimes: function() { return {}; },
|
|
114
|
-
csi: function() { return {}; },
|
|
115
|
-
app: { isInstalled: false },
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
// Override permissions
|
|
119
|
-
const originalQuery = window.navigator.permissions.query;
|
|
120
|
-
window.navigator.permissions.query = (parameters) => (
|
|
121
|
-
parameters.name === 'notifications' ?
|
|
122
|
-
Promise.resolve({ state: Notification.permission }) :
|
|
123
|
-
originalQuery(parameters)
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
// Override plugins (make it look like a real browser)
|
|
127
|
-
Object.defineProperty(navigator, 'plugins', {
|
|
128
|
-
get: () => [
|
|
129
|
-
{ name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer' },
|
|
130
|
-
{ name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai' },
|
|
131
|
-
{ name: 'Native Client', filename: 'internal-nacl-plugin' },
|
|
132
|
-
],
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// Override languages
|
|
136
|
-
Object.defineProperty(navigator, 'languages', {
|
|
137
|
-
get: () => ['en-US', 'en'],
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Override platform
|
|
141
|
-
Object.defineProperty(navigator, 'platform', {
|
|
142
|
-
get: () => 'MacIntel',
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// Override hardware concurrency
|
|
146
|
-
Object.defineProperty(navigator, 'hardwareConcurrency', {
|
|
147
|
-
get: () => 8,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
// Override device memory
|
|
151
|
-
Object.defineProperty(navigator, 'deviceMemory', {
|
|
152
|
-
get: () => 8,
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
// Prevent detection of automation via toString
|
|
156
|
-
const origToString = Function.prototype.toString;
|
|
157
|
-
Function.prototype.toString = function() {
|
|
158
|
-
if (this === Function.prototype.toString) return 'function toString() { [native code] }';
|
|
159
|
-
if (this === navigator.permissions.query) return 'function query() { [native code] }';
|
|
160
|
-
return origToString.call(this);
|
|
161
|
-
};
|
|
162
|
-
`;
|
|
163
|
-
async function createXAccount(options) {
|
|
164
|
-
let browser = null;
|
|
165
|
-
try {
|
|
166
|
-
logger.info("Creating email inbox...");
|
|
167
|
-
const inbox = await createAgentEmail();
|
|
168
|
-
logger.info(`Email created: ${inbox.address}`);
|
|
169
|
-
logger.info("Launching browser with stealth mode...");
|
|
170
|
-
browser = await chromium.launch({
|
|
171
|
-
headless: false,
|
|
172
|
-
args: [
|
|
173
|
-
"--no-sandbox",
|
|
174
|
-
"--disable-blink-features=AutomationControlled",
|
|
175
|
-
"--disable-features=IsolateOrigins,site-per-process",
|
|
176
|
-
"--disable-dev-shm-usage",
|
|
177
|
-
"--disable-accelerated-2d-canvas",
|
|
178
|
-
"--no-first-run",
|
|
179
|
-
"--no-zygote",
|
|
180
|
-
"--disable-gpu",
|
|
181
|
-
"--lang=en-US,en",
|
|
182
|
-
"--disable-background-timer-throttling",
|
|
183
|
-
"--disable-backgrounding-occluded-windows",
|
|
184
|
-
"--disable-renderer-backgrounding"
|
|
185
|
-
]
|
|
186
|
-
});
|
|
187
|
-
const context = await browser.newContext({
|
|
188
|
-
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
|
189
|
-
viewport: { width: 1280, height: 800 },
|
|
190
|
-
locale: "en-US",
|
|
191
|
-
timezoneId: "America/New_York",
|
|
192
|
-
colorScheme: "light",
|
|
193
|
-
hasTouch: false,
|
|
194
|
-
isMobile: false,
|
|
195
|
-
javaScriptEnabled: true
|
|
196
|
-
});
|
|
197
|
-
await context.addInitScript(STEALTH_SCRIPT);
|
|
198
|
-
const page = await context.newPage();
|
|
199
|
-
const simulateHumanPresence = async () => {
|
|
200
|
-
for (let i = 0; i < 3; i++) {
|
|
201
|
-
const x = Math.floor(Math.random() * 1200) + 40;
|
|
202
|
-
const y = Math.floor(Math.random() * 700) + 50;
|
|
203
|
-
await page.mouse.move(x, y, { steps: Math.floor(Math.random() * 5) + 3 });
|
|
204
|
-
await randomDelay(300, 800);
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
logger.info("Navigating to X signup...");
|
|
208
|
-
await page.goto("https://x.com/i/flow/signup", {
|
|
209
|
-
waitUntil: "domcontentloaded",
|
|
210
|
-
timeout: 6e4
|
|
211
|
-
});
|
|
212
|
-
await randomDelay(3e3, 6e3);
|
|
213
|
-
await simulateHumanPresence();
|
|
214
|
-
logger.info(`Page loaded. URL: ${page.url()}`);
|
|
215
|
-
await debugScreenshot(page, "01-page-loaded");
|
|
216
|
-
logger.info("Step 3: Looking for 'Create account' button...");
|
|
217
|
-
const createSelectors = [
|
|
218
|
-
'button:has-text("Create account")',
|
|
219
|
-
'[role="button"]:has-text("Create account")',
|
|
220
|
-
'a:has-text("Create account")',
|
|
221
|
-
'text="Create account"'
|
|
222
|
-
];
|
|
223
|
-
let clicked = false;
|
|
224
|
-
for (const sel of createSelectors) {
|
|
225
|
-
try {
|
|
226
|
-
const btn = page.locator(sel).first();
|
|
227
|
-
await btn.waitFor({ state: "visible", timeout: 5e3 });
|
|
228
|
-
await humanClick(page, btn);
|
|
229
|
-
logger.info(`Clicked 'Create account' via: ${sel}`);
|
|
230
|
-
clicked = true;
|
|
231
|
-
await randomDelay(2e3, 3500);
|
|
232
|
-
break;
|
|
233
|
-
} catch {
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
if (!clicked) {
|
|
237
|
-
try {
|
|
238
|
-
const btn = page.getByText("Create account", { exact: false }).first();
|
|
239
|
-
await humanClick(page, btn);
|
|
240
|
-
logger.info("Clicked 'Create account' via getByText.");
|
|
241
|
-
clicked = true;
|
|
242
|
-
await randomDelay(2e3, 3500);
|
|
243
|
-
} catch {
|
|
244
|
-
logger.warn("Could not find 'Create account' button.");
|
|
245
|
-
await debugScreenshot(page, "03-no-create-btn");
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
await debugScreenshot(page, "02-after-create-click");
|
|
249
|
-
logger.info("Step 4: Waiting for name input...");
|
|
250
|
-
const nameInput = page.locator('input[name="name"]').first();
|
|
251
|
-
try {
|
|
252
|
-
await nameInput.waitFor({ state: "visible", timeout: 15e3 });
|
|
253
|
-
} catch {
|
|
254
|
-
await debugScreenshot(page, "04-name-not-found");
|
|
255
|
-
throw new Error("Could not find name input. Check ~/.spora/debug-04-name-not-found.png");
|
|
256
|
-
}
|
|
257
|
-
await randomDelay(500, 1e3);
|
|
258
|
-
await humanTypeLocator(nameInput, options.name);
|
|
259
|
-
logger.info(`Filled name: ${options.name}`);
|
|
260
|
-
await randomDelay(800, 1500);
|
|
261
|
-
logger.info("Step 5: Clicking 'Use email instead'...");
|
|
262
|
-
const useEmailLink = page.locator('span:has-text("Use email instead")').first();
|
|
263
|
-
try {
|
|
264
|
-
await useEmailLink.waitFor({ state: "visible", timeout: 5e3 });
|
|
265
|
-
await humanClick(page, useEmailLink);
|
|
266
|
-
logger.info("Clicked 'Use email instead'.");
|
|
267
|
-
} catch {
|
|
268
|
-
logger.info("'Use email instead' not found \u2014 email field may already be visible.");
|
|
269
|
-
}
|
|
270
|
-
await randomDelay(800, 1500);
|
|
271
|
-
logger.info("Step 6: Filling email...");
|
|
272
|
-
const emailInput = page.locator('input[name="email"][type="email"], input[name="email"]').first();
|
|
273
|
-
try {
|
|
274
|
-
await emailInput.waitFor({ state: "visible", timeout: 5e3 });
|
|
275
|
-
} catch {
|
|
276
|
-
await debugScreenshot(page, "06-email-not-found");
|
|
277
|
-
throw new Error("Could not find email input. Check ~/.spora/debug-06-email-not-found.png");
|
|
278
|
-
}
|
|
279
|
-
await randomDelay(300, 700);
|
|
280
|
-
await humanTypeLocator(emailInput, inbox.address);
|
|
281
|
-
logger.info(`Filled email: ${inbox.address}`);
|
|
282
|
-
await randomDelay(800, 1500);
|
|
283
|
-
logger.info("Step 7: Setting birthdate...");
|
|
284
|
-
const month = String(Math.floor(Math.random() * 12) + 1);
|
|
285
|
-
const monthSelect = page.locator("select#SELECTOR_1");
|
|
286
|
-
await monthSelect.waitFor({ state: "visible", timeout: 5e3 });
|
|
287
|
-
await randomDelay(400, 800);
|
|
288
|
-
await monthSelect.selectOption(month);
|
|
289
|
-
logger.info(`Set month: ${month}`);
|
|
290
|
-
await randomDelay(500, 1e3);
|
|
291
|
-
const day = String(Math.floor(Math.random() * 28) + 1);
|
|
292
|
-
const daySelect = page.locator("select#SELECTOR_2");
|
|
293
|
-
await daySelect.waitFor({ state: "visible", timeout: 5e3 });
|
|
294
|
-
await randomDelay(300, 600);
|
|
295
|
-
await daySelect.selectOption(day);
|
|
296
|
-
logger.info(`Set day: ${day}`);
|
|
297
|
-
await randomDelay(500, 1e3);
|
|
298
|
-
const year = String(Math.floor(Math.random() * 21) + 1980);
|
|
299
|
-
const yearSelect = page.locator("select#SELECTOR_3");
|
|
300
|
-
await yearSelect.waitFor({ state: "visible", timeout: 5e3 });
|
|
301
|
-
await randomDelay(300, 600);
|
|
302
|
-
await yearSelect.selectOption(year);
|
|
303
|
-
logger.info(`Set year: ${year}`);
|
|
304
|
-
await randomDelay(1e3, 2e3);
|
|
305
|
-
await simulateHumanPresence();
|
|
306
|
-
await debugScreenshot(page, "07-form-filled");
|
|
307
|
-
logger.info("Step 8: Clicking Next...");
|
|
308
|
-
const nextBtn = page.locator('[data-testid="ocfSignupNextLink"]').first();
|
|
309
|
-
await nextBtn.waitFor({ state: "visible", timeout: 5e3 });
|
|
310
|
-
await randomDelay(500, 1e3);
|
|
311
|
-
await humanClick(page, nextBtn);
|
|
312
|
-
logger.info("Clicked Next.");
|
|
313
|
-
await randomDelay(3e3, 5e3);
|
|
314
|
-
await debugScreenshot(page, "08-after-next");
|
|
315
|
-
for (let attempt = 0; attempt < 3; attempt++) {
|
|
316
|
-
const nextBtn2 = page.locator('[data-testid="ocfSignupNextLink"]').first();
|
|
317
|
-
const nextBtn2Visible = await nextBtn2.isVisible().catch(() => false);
|
|
318
|
-
if (nextBtn2Visible) {
|
|
319
|
-
await randomDelay(1e3, 2e3);
|
|
320
|
-
await humanClick(page, nextBtn2);
|
|
321
|
-
logger.info(`Clicked Next (additional screen ${attempt + 1}).`);
|
|
322
|
-
await randomDelay(2e3, 4e3);
|
|
323
|
-
} else {
|
|
324
|
-
break;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
const signupBtn = page.locator('[data-testid="ocfSignupButton"], button:has-text("Sign up")').first();
|
|
328
|
-
const signupVisible = await signupBtn.isVisible().catch(() => false);
|
|
329
|
-
if (signupVisible) {
|
|
330
|
-
await randomDelay(500, 1e3);
|
|
331
|
-
await humanClick(page, signupBtn);
|
|
332
|
-
logger.info("Clicked 'Sign up'.");
|
|
333
|
-
await randomDelay(3e3, 5e3);
|
|
334
|
-
}
|
|
335
|
-
await debugScreenshot(page, "09-before-verification");
|
|
336
|
-
logger.info("Step 9: Waiting for verification code input...");
|
|
337
|
-
const codeInput = page.locator('input[name="verfication_code"], input[name="verification_code"]').first();
|
|
338
|
-
const codeInputVisible = await codeInput.isVisible({ timeout: 15e3 }).catch(() => false);
|
|
339
|
-
if (codeInputVisible) {
|
|
340
|
-
logger.info("Verification code input visible. Polling AgentMail...");
|
|
341
|
-
const code = await checkInbox(inbox.inboxId, 9e4);
|
|
342
|
-
if (code) {
|
|
343
|
-
logger.info(`Verification code received: ${code}`);
|
|
344
|
-
await randomDelay(500, 1e3);
|
|
345
|
-
await humanTypeLocator(codeInput, code);
|
|
346
|
-
logger.info("Filled verification code.");
|
|
347
|
-
await randomDelay(1e3, 2e3);
|
|
348
|
-
const nextAfterCode = page.locator('[data-testid="ocfSignupNextLink"], button:has-text("Next")').first();
|
|
349
|
-
const nextAfterCodeVisible = await nextAfterCode.isVisible({ timeout: 5e3 }).catch(() => false);
|
|
350
|
-
if (nextAfterCodeVisible) {
|
|
351
|
-
await humanClick(page, nextAfterCode);
|
|
352
|
-
logger.info("Clicked Next after verification code.");
|
|
353
|
-
await randomDelay(3e3, 5e3);
|
|
354
|
-
}
|
|
355
|
-
} else {
|
|
356
|
-
logger.warn("No verification code received within 90s.");
|
|
357
|
-
console.log(JSON.stringify({
|
|
358
|
-
status: "waiting_for_manual_verification",
|
|
359
|
-
message: "Could not auto-retrieve verification code. Check the browser and enter it manually.",
|
|
360
|
-
email: inbox.address
|
|
361
|
-
}));
|
|
362
|
-
}
|
|
363
|
-
} else {
|
|
364
|
-
logger.warn("Verification code input not found.");
|
|
365
|
-
await debugScreenshot(page, "09-no-verification-input");
|
|
366
|
-
}
|
|
367
|
-
const password = generatePassword();
|
|
368
|
-
const passwordInput = page.locator('input[name="password"], input[type="password"]').first();
|
|
369
|
-
const passwordVisible = await passwordInput.isVisible({ timeout: 1e4 }).catch(() => false);
|
|
370
|
-
if (passwordVisible) {
|
|
371
|
-
logger.info("Setting password...");
|
|
372
|
-
await randomDelay(500, 1e3);
|
|
373
|
-
await humanTypeLocator(passwordInput, password);
|
|
374
|
-
logger.info("Filled password.");
|
|
375
|
-
await randomDelay(1e3, 2e3);
|
|
376
|
-
const nextAfterPassword = page.locator('[data-testid="ocfSignupNextLink"], button:has-text("Next")').first();
|
|
377
|
-
const nextPwVisible = await nextAfterPassword.isVisible({ timeout: 5e3 }).catch(() => false);
|
|
378
|
-
if (nextPwVisible) {
|
|
379
|
-
await humanClick(page, nextAfterPassword);
|
|
380
|
-
logger.info("Clicked Next after password.");
|
|
381
|
-
await randomDelay(3e3, 5e3);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
let username;
|
|
385
|
-
const usernameInput = page.locator('input[name="username"]').first();
|
|
386
|
-
const usernameVisible = await usernameInput.isVisible({ timeout: 5e3 }).catch(() => false);
|
|
387
|
-
if (usernameVisible) {
|
|
388
|
-
username = await usernameInput.inputValue() || void 0;
|
|
389
|
-
logger.info(`Username: ${username}`);
|
|
390
|
-
const nextAfterUsername = page.locator('[data-testid="ocfSignupNextLink"], button:has-text("Next"), button:has-text("Skip")').first();
|
|
391
|
-
const nextUVisible = await nextAfterUsername.isVisible({ timeout: 3e3 }).catch(() => false);
|
|
392
|
-
if (nextUVisible) {
|
|
393
|
-
await humanClick(page, nextAfterUsername);
|
|
394
|
-
await randomDelay(2e3, 3e3);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
logger.info("Skipping onboarding screens...");
|
|
398
|
-
for (let i = 0; i < 8; i++) {
|
|
399
|
-
let skipped = false;
|
|
400
|
-
for (const text of ["Skip for now", "Skip", "Not now", "Next"]) {
|
|
401
|
-
const btn = page.locator(`button:has-text("${text}"), [role="button"]:has-text("${text}")`).first();
|
|
402
|
-
const visible = await btn.isVisible({ timeout: 2e3 }).catch(() => false);
|
|
403
|
-
if (visible) {
|
|
404
|
-
await randomDelay(500, 1e3);
|
|
405
|
-
await humanClick(page, btn);
|
|
406
|
-
logger.info(`Skipped: "${text}"`);
|
|
407
|
-
await randomDelay(1500, 2500);
|
|
408
|
-
skipped = true;
|
|
409
|
-
break;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
if (!skipped) break;
|
|
413
|
-
}
|
|
414
|
-
logger.info("Checking if signup completed...");
|
|
415
|
-
const homeNav = page.locator('[data-testid="SideNav_AccountSwitcher_Button"], [data-testid="AppTabBar_Home_Link"]');
|
|
416
|
-
const isLoggedIn = await homeNav.first().isVisible({ timeout: 15e3 }).catch(() => false);
|
|
417
|
-
if (isLoggedIn) {
|
|
418
|
-
logger.info("X account created successfully!");
|
|
419
|
-
await saveSession(context);
|
|
420
|
-
await browser.close();
|
|
421
|
-
return {
|
|
422
|
-
success: true,
|
|
423
|
-
username: username ?? inbox.address.split("@")[0],
|
|
424
|
-
password,
|
|
425
|
-
email: inbox.address
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
logger.warn("Waiting for manual completion (up to 5 minutes)...");
|
|
429
|
-
console.log(JSON.stringify({
|
|
430
|
-
status: "waiting_for_manual_completion",
|
|
431
|
-
message: "Browser is open. Complete any remaining steps (CAPTCHAs, phone verification). Auto-detects when done."
|
|
432
|
-
}));
|
|
433
|
-
for (let i = 0; i < 60; i++) {
|
|
434
|
-
const loggedIn = await homeNav.first().isVisible({ timeout: 5e3 }).catch(() => false);
|
|
435
|
-
if (loggedIn) {
|
|
436
|
-
logger.info("Login detected!");
|
|
437
|
-
await saveSession(context);
|
|
438
|
-
await browser.close();
|
|
439
|
-
return {
|
|
440
|
-
success: true,
|
|
441
|
-
username: username ?? inbox.address.split("@")[0],
|
|
442
|
-
password,
|
|
443
|
-
email: inbox.address,
|
|
444
|
-
requiresManual: true
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
await browser.close();
|
|
449
|
-
return {
|
|
450
|
-
success: false,
|
|
451
|
-
error: "Account creation timed out after 5 minutes.",
|
|
452
|
-
requiresManual: true
|
|
453
|
-
};
|
|
454
|
-
} catch (error) {
|
|
455
|
-
logger.error("Account creation failed", error);
|
|
456
|
-
if (browser) await browser.close().catch(() => {
|
|
457
|
-
});
|
|
458
|
-
return {
|
|
459
|
-
success: false,
|
|
460
|
-
error: error.message,
|
|
461
|
-
requiresManual: true
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
async function saveSession(context) {
|
|
466
|
-
const storageState = await context.storageState();
|
|
467
|
-
const { writeFileSync } = await import("fs");
|
|
468
|
-
const { paths, ensureDirectories } = await import("./paths-KXOWF2B2.js");
|
|
469
|
-
ensureDirectories();
|
|
470
|
-
writeFileSync(paths.browserAuth, JSON.stringify(storageState));
|
|
471
|
-
logger.info("Browser session saved.");
|
|
472
|
-
}
|
|
473
|
-
function generatePassword() {
|
|
474
|
-
const upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
475
|
-
const lower = "abcdefghijklmnopqrstuvwxyz";
|
|
476
|
-
const digits = "0123456789";
|
|
477
|
-
const special = "!@#$%^&*";
|
|
478
|
-
const all = upper + lower + digits + special;
|
|
479
|
-
let password = "";
|
|
480
|
-
password += upper[Math.floor(Math.random() * upper.length)];
|
|
481
|
-
password += lower[Math.floor(Math.random() * lower.length)];
|
|
482
|
-
password += digits[Math.floor(Math.random() * digits.length)];
|
|
483
|
-
password += special[Math.floor(Math.random() * special.length)];
|
|
484
|
-
for (let i = 4; i < 20; i++) {
|
|
485
|
-
password += all[Math.floor(Math.random() * all.length)];
|
|
486
|
-
}
|
|
487
|
-
return password.split("").sort(() => Math.random() - 0.5).join("");
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// src/account-creator/index.ts
|
|
491
|
-
async function provisionAccount(options) {
|
|
492
|
-
logger.info("Starting automated X account creation...");
|
|
493
|
-
return createXAccount(options);
|
|
494
|
-
}
|
|
495
|
-
export {
|
|
496
|
-
provisionAccount
|
|
497
|
-
};
|
|
498
|
-
//# sourceMappingURL=account-creator-SETL5CGT.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/account-creator/x-signup.ts","../src/account-creator/email.ts","../src/account-creator/index.ts"],"sourcesContent":["import { chromium, type Browser, type Page, type BrowserContext } from \"playwright\";\nimport { logger } from \"../utils/logger.js\";\nimport { createAgentEmail, checkInbox } from \"./email.js\";\n\nexport interface SignupResult {\n success: boolean;\n username?: string;\n password?: string;\n email?: string;\n error?: string;\n requiresManual?: boolean;\n}\n\n// ===== Stealth & human-like helpers =====\n\nasync function debugScreenshot(page: Page, step: string): Promise<void> {\n try {\n const { paths, ensureDirectories } = await import(\"../utils/paths.js\");\n ensureDirectories();\n const screenshotPath = `${paths.dataDir}/debug-${step}.png`;\n await page.screenshot({ path: screenshotPath });\n logger.info(`Debug screenshot saved: ${screenshotPath}`);\n } catch {\n // Non-critical\n }\n}\n\n/** Random delay between min and max ms */\nfunction randomDelay(min: number, max: number): Promise<void> {\n const ms = Math.floor(Math.random() * (max - min)) + min;\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Type text character by character with human-like delays */\nasync function humanType(page: Page, selector: string, text: string): Promise<void> {\n const el = page.locator(selector).first();\n await el.click();\n for (const char of text) {\n await el.type(char, { delay: Math.floor(Math.random() * 120) + 30 });\n // Occasional longer pause (thinking)\n if (Math.random() < 0.1) {\n await randomDelay(200, 500);\n }\n }\n}\n\n/** Type into a Playwright locator with human-like delays */\nasync function humanTypeLocator(locator: ReturnType<Page[\"locator\"]>, text: string): Promise<void> {\n await locator.click();\n await randomDelay(200, 400);\n for (const char of text) {\n await locator.type(char, { delay: Math.floor(Math.random() * 120) + 30 });\n if (Math.random() < 0.1) {\n await randomDelay(200, 500);\n }\n }\n}\n\n/** Move mouse to element naturally before clicking */\nasync function humanClick(page: Page, locator: ReturnType<Page[\"locator\"]>): Promise<void> {\n const box = await locator.boundingBox();\n if (box) {\n // Move to a random point within the element\n const x = box.x + Math.random() * box.width;\n const y = box.y + Math.random() * box.height;\n await page.mouse.move(x, y, { steps: Math.floor(Math.random() * 10) + 5 });\n await randomDelay(100, 300);\n }\n await locator.click();\n}\n\n/** Stealth init script to hide automation signals */\nconst STEALTH_SCRIPT = `\n // Override navigator.webdriver\n Object.defineProperty(navigator, 'webdriver', { get: () => undefined });\n\n // Override chrome runtime\n window.chrome = {\n runtime: {},\n loadTimes: function() { return {}; },\n csi: function() { return {}; },\n app: { isInstalled: false },\n };\n\n // Override permissions\n const originalQuery = window.navigator.permissions.query;\n window.navigator.permissions.query = (parameters) => (\n parameters.name === 'notifications' ?\n Promise.resolve({ state: Notification.permission }) :\n originalQuery(parameters)\n );\n\n // Override plugins (make it look like a real browser)\n Object.defineProperty(navigator, 'plugins', {\n get: () => [\n { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer' },\n { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai' },\n { name: 'Native Client', filename: 'internal-nacl-plugin' },\n ],\n });\n\n // Override languages\n Object.defineProperty(navigator, 'languages', {\n get: () => ['en-US', 'en'],\n });\n\n // Override platform\n Object.defineProperty(navigator, 'platform', {\n get: () => 'MacIntel',\n });\n\n // Override hardware concurrency\n Object.defineProperty(navigator, 'hardwareConcurrency', {\n get: () => 8,\n });\n\n // Override device memory\n Object.defineProperty(navigator, 'deviceMemory', {\n get: () => 8,\n });\n\n // Prevent detection of automation via toString\n const origToString = Function.prototype.toString;\n Function.prototype.toString = function() {\n if (this === Function.prototype.toString) return 'function toString() { [native code] }';\n if (this === navigator.permissions.query) return 'function query() { [native code] }';\n return origToString.call(this);\n };\n`;\n\nexport async function createXAccount(options: {\n name: string;\n}): Promise<SignupResult> {\n let browser: Browser | null = null;\n\n try {\n // Step 1: Create email inbox via Spora's AgentMail\n logger.info(\"Creating email inbox...\");\n const inbox = await createAgentEmail();\n logger.info(`Email created: ${inbox.address}`);\n\n // Step 2: Launch browser with stealth settings\n logger.info(\"Launching browser with stealth mode...\");\n browser = await chromium.launch({\n headless: false,\n args: [\n \"--no-sandbox\",\n \"--disable-blink-features=AutomationControlled\",\n \"--disable-features=IsolateOrigins,site-per-process\",\n \"--disable-dev-shm-usage\",\n \"--disable-accelerated-2d-canvas\",\n \"--no-first-run\",\n \"--no-zygote\",\n \"--disable-gpu\",\n \"--lang=en-US,en\",\n \"--disable-background-timer-throttling\",\n \"--disable-backgrounding-occluded-windows\",\n \"--disable-renderer-backgrounding\",\n ],\n });\n\n const context = await browser.newContext({\n userAgent: \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36\",\n viewport: { width: 1280, height: 800 },\n locale: \"en-US\",\n timezoneId: \"America/New_York\",\n colorScheme: \"light\",\n hasTouch: false,\n isMobile: false,\n javaScriptEnabled: true,\n });\n\n // Apply stealth script before any page loads\n await context.addInitScript(STEALTH_SCRIPT);\n\n const page = await context.newPage();\n\n // Add random mouse movements to look human\n const simulateHumanPresence = async () => {\n for (let i = 0; i < 3; i++) {\n const x = Math.floor(Math.random() * 1200) + 40;\n const y = Math.floor(Math.random() * 700) + 50;\n await page.mouse.move(x, y, { steps: Math.floor(Math.random() * 5) + 3 });\n await randomDelay(300, 800);\n }\n };\n\n // Navigate to X signup\n logger.info(\"Navigating to X signup...\");\n await page.goto(\"https://x.com/i/flow/signup\", {\n waitUntil: \"domcontentloaded\",\n timeout: 60000,\n });\n\n // Wait for page to settle and simulate human browsing\n await randomDelay(3000, 6000);\n await simulateHumanPresence();\n logger.info(`Page loaded. URL: ${page.url()}`);\n await debugScreenshot(page, \"01-page-loaded\");\n\n // ===== Step 3: Click \"Create account\" button =====\n logger.info(\"Step 3: Looking for 'Create account' button...\");\n const createSelectors = [\n 'button:has-text(\"Create account\")',\n '[role=\"button\"]:has-text(\"Create account\")',\n 'a:has-text(\"Create account\")',\n 'text=\"Create account\"',\n ];\n let clicked = false;\n for (const sel of createSelectors) {\n try {\n const btn = page.locator(sel).first();\n await btn.waitFor({ state: \"visible\", timeout: 5000 });\n await humanClick(page, btn);\n logger.info(`Clicked 'Create account' via: ${sel}`);\n clicked = true;\n await randomDelay(2000, 3500);\n break;\n } catch {\n // Try next selector\n }\n }\n if (!clicked) {\n try {\n const btn = page.getByText(\"Create account\", { exact: false }).first();\n await humanClick(page, btn);\n logger.info(\"Clicked 'Create account' via getByText.\");\n clicked = true;\n await randomDelay(2000, 3500);\n } catch {\n logger.warn(\"Could not find 'Create account' button.\");\n await debugScreenshot(page, \"03-no-create-btn\");\n }\n }\n\n await debugScreenshot(page, \"02-after-create-click\");\n\n // ===== Step 4: Fill name =====\n logger.info(\"Step 4: Waiting for name input...\");\n const nameInput = page.locator('input[name=\"name\"]').first();\n try {\n await nameInput.waitFor({ state: \"visible\", timeout: 15000 });\n } catch {\n await debugScreenshot(page, \"04-name-not-found\");\n throw new Error(\"Could not find name input. Check ~/.spora/debug-04-name-not-found.png\");\n }\n await randomDelay(500, 1000);\n await humanTypeLocator(nameInput, options.name);\n logger.info(`Filled name: ${options.name}`);\n await randomDelay(800, 1500);\n\n // ===== Step 5: Click \"Use email instead\" =====\n logger.info(\"Step 5: Clicking 'Use email instead'...\");\n const useEmailLink = page.locator('span:has-text(\"Use email instead\")').first();\n try {\n await useEmailLink.waitFor({ state: \"visible\", timeout: 5000 });\n await humanClick(page, useEmailLink);\n logger.info(\"Clicked 'Use email instead'.\");\n } catch {\n // May already be showing email field\n logger.info(\"'Use email instead' not found — email field may already be visible.\");\n }\n await randomDelay(800, 1500);\n\n // ===== Step 6: Fill email =====\n logger.info(\"Step 6: Filling email...\");\n const emailInput = page.locator('input[name=\"email\"][type=\"email\"], input[name=\"email\"]').first();\n try {\n await emailInput.waitFor({ state: \"visible\", timeout: 5000 });\n } catch {\n await debugScreenshot(page, \"06-email-not-found\");\n throw new Error(\"Could not find email input. Check ~/.spora/debug-06-email-not-found.png\");\n }\n await randomDelay(300, 700);\n await humanTypeLocator(emailInput, inbox.address);\n logger.info(`Filled email: ${inbox.address}`);\n await randomDelay(800, 1500);\n\n // ===== Step 7: Fill birthdate =====\n logger.info(\"Step 7: Setting birthdate...\");\n\n const month = String(Math.floor(Math.random() * 12) + 1);\n const monthSelect = page.locator('select#SELECTOR_1');\n await monthSelect.waitFor({ state: \"visible\", timeout: 5000 });\n await randomDelay(400, 800);\n await monthSelect.selectOption(month);\n logger.info(`Set month: ${month}`);\n await randomDelay(500, 1000);\n\n const day = String(Math.floor(Math.random() * 28) + 1);\n const daySelect = page.locator('select#SELECTOR_2');\n await daySelect.waitFor({ state: \"visible\", timeout: 5000 });\n await randomDelay(300, 600);\n await daySelect.selectOption(day);\n logger.info(`Set day: ${day}`);\n await randomDelay(500, 1000);\n\n const year = String(Math.floor(Math.random() * 21) + 1980);\n const yearSelect = page.locator('select#SELECTOR_3');\n await yearSelect.waitFor({ state: \"visible\", timeout: 5000 });\n await randomDelay(300, 600);\n await yearSelect.selectOption(year);\n logger.info(`Set year: ${year}`);\n await randomDelay(1000, 2000);\n\n await simulateHumanPresence();\n await debugScreenshot(page, \"07-form-filled\");\n\n // ===== Step 8: Click Next =====\n logger.info(\"Step 8: Clicking Next...\");\n const nextBtn = page.locator('[data-testid=\"ocfSignupNextLink\"]').first();\n await nextBtn.waitFor({ state: \"visible\", timeout: 5000 });\n await randomDelay(500, 1000);\n await humanClick(page, nextBtn);\n logger.info(\"Clicked Next.\");\n await randomDelay(3000, 5000);\n await debugScreenshot(page, \"08-after-next\");\n\n // Handle additional screens (customize experience, etc.)\n for (let attempt = 0; attempt < 3; attempt++) {\n const nextBtn2 = page.locator('[data-testid=\"ocfSignupNextLink\"]').first();\n const nextBtn2Visible = await nextBtn2.isVisible().catch(() => false);\n if (nextBtn2Visible) {\n await randomDelay(1000, 2000);\n await humanClick(page, nextBtn2);\n logger.info(`Clicked Next (additional screen ${attempt + 1}).`);\n await randomDelay(2000, 4000);\n } else {\n break;\n }\n }\n\n // Check for \"Sign up\" button\n const signupBtn = page.locator('[data-testid=\"ocfSignupButton\"], button:has-text(\"Sign up\")').first();\n const signupVisible = await signupBtn.isVisible().catch(() => false);\n if (signupVisible) {\n await randomDelay(500, 1000);\n await humanClick(page, signupBtn);\n logger.info(\"Clicked 'Sign up'.\");\n await randomDelay(3000, 5000);\n }\n\n await debugScreenshot(page, \"09-before-verification\");\n\n // ===== Step 9: Get verification code and enter it =====\n logger.info(\"Step 9: Waiting for verification code input...\");\n\n // X has a typo: \"verfication_code\" (missing 'i')\n const codeInput = page.locator('input[name=\"verfication_code\"], input[name=\"verification_code\"]').first();\n const codeInputVisible = await codeInput.isVisible({ timeout: 15000 }).catch(() => false);\n\n if (codeInputVisible) {\n logger.info(\"Verification code input visible. Polling AgentMail...\");\n\n const code = await checkInbox(inbox.inboxId, 90000);\n\n if (code) {\n logger.info(`Verification code received: ${code}`);\n await randomDelay(500, 1000);\n await humanTypeLocator(codeInput, code);\n logger.info(\"Filled verification code.\");\n await randomDelay(1000, 2000);\n\n const nextAfterCode = page.locator('[data-testid=\"ocfSignupNextLink\"], button:has-text(\"Next\")').first();\n const nextAfterCodeVisible = await nextAfterCode.isVisible({ timeout: 5000 }).catch(() => false);\n if (nextAfterCodeVisible) {\n await humanClick(page, nextAfterCode);\n logger.info(\"Clicked Next after verification code.\");\n await randomDelay(3000, 5000);\n }\n } else {\n logger.warn(\"No verification code received within 90s.\");\n console.log(JSON.stringify({\n status: \"waiting_for_manual_verification\",\n message: \"Could not auto-retrieve verification code. Check the browser and enter it manually.\",\n email: inbox.address,\n }));\n }\n } else {\n logger.warn(\"Verification code input not found.\");\n await debugScreenshot(page, \"09-no-verification-input\");\n }\n\n // ===== Step 10: Set password =====\n const password = generatePassword();\n const passwordInput = page.locator('input[name=\"password\"], input[type=\"password\"]').first();\n const passwordVisible = await passwordInput.isVisible({ timeout: 10000 }).catch(() => false);\n if (passwordVisible) {\n logger.info(\"Setting password...\");\n await randomDelay(500, 1000);\n await humanTypeLocator(passwordInput, password);\n logger.info(\"Filled password.\");\n await randomDelay(1000, 2000);\n\n const nextAfterPassword = page.locator('[data-testid=\"ocfSignupNextLink\"], button:has-text(\"Next\")').first();\n const nextPwVisible = await nextAfterPassword.isVisible({ timeout: 5000 }).catch(() => false);\n if (nextPwVisible) {\n await humanClick(page, nextAfterPassword);\n logger.info(\"Clicked Next after password.\");\n await randomDelay(3000, 5000);\n }\n }\n\n // ===== Step 11: Handle username =====\n let username: string | undefined;\n const usernameInput = page.locator('input[name=\"username\"]').first();\n const usernameVisible = await usernameInput.isVisible({ timeout: 5000 }).catch(() => false);\n if (usernameVisible) {\n username = (await usernameInput.inputValue()) || undefined;\n logger.info(`Username: ${username}`);\n const nextAfterUsername = page.locator('[data-testid=\"ocfSignupNextLink\"], button:has-text(\"Next\"), button:has-text(\"Skip\")').first();\n const nextUVisible = await nextAfterUsername.isVisible({ timeout: 3000 }).catch(() => false);\n if (nextUVisible) {\n await humanClick(page, nextAfterUsername);\n await randomDelay(2000, 3000);\n }\n }\n\n // ===== Step 12: Skip onboarding =====\n logger.info(\"Skipping onboarding screens...\");\n for (let i = 0; i < 8; i++) {\n let skipped = false;\n for (const text of [\"Skip for now\", \"Skip\", \"Not now\", \"Next\"]) {\n const btn = page.locator(`button:has-text(\"${text}\"), [role=\"button\"]:has-text(\"${text}\")`).first();\n const visible = await btn.isVisible({ timeout: 2000 }).catch(() => false);\n if (visible) {\n await randomDelay(500, 1000);\n await humanClick(page, btn);\n logger.info(`Skipped: \"${text}\"`);\n await randomDelay(1500, 2500);\n skipped = true;\n break;\n }\n }\n if (!skipped) break;\n }\n\n // ===== Step 13: Check if logged in =====\n logger.info(\"Checking if signup completed...\");\n const homeNav = page.locator('[data-testid=\"SideNav_AccountSwitcher_Button\"], [data-testid=\"AppTabBar_Home_Link\"]');\n const isLoggedIn = await homeNav.first().isVisible({ timeout: 15000 }).catch(() => false);\n\n if (isLoggedIn) {\n logger.info(\"X account created successfully!\");\n await saveSession(context);\n await browser.close();\n return {\n success: true,\n username: username ?? inbox.address.split(\"@\")[0],\n password,\n email: inbox.address,\n };\n }\n\n // Wait for manual completion (up to 5 minutes)\n logger.warn(\"Waiting for manual completion (up to 5 minutes)...\");\n console.log(JSON.stringify({\n status: \"waiting_for_manual_completion\",\n message: \"Browser is open. Complete any remaining steps (CAPTCHAs, phone verification). Auto-detects when done.\",\n }));\n\n for (let i = 0; i < 60; i++) {\n const loggedIn = await homeNav.first().isVisible({ timeout: 5000 }).catch(() => false);\n if (loggedIn) {\n logger.info(\"Login detected!\");\n await saveSession(context);\n await browser.close();\n return {\n success: true,\n username: username ?? inbox.address.split(\"@\")[0],\n password,\n email: inbox.address,\n requiresManual: true,\n };\n }\n }\n\n await browser.close();\n return {\n success: false,\n error: \"Account creation timed out after 5 minutes.\",\n requiresManual: true,\n };\n } catch (error) {\n logger.error(\"Account creation failed\", error);\n if (browser) await browser.close().catch(() => {});\n return {\n success: false,\n error: (error as Error).message,\n requiresManual: true,\n };\n }\n}\n\nasync function saveSession(context: BrowserContext): Promise<void> {\n const storageState = await context.storageState();\n const { writeFileSync } = await import(\"node:fs\");\n const { paths, ensureDirectories } = await import(\"../utils/paths.js\");\n ensureDirectories();\n writeFileSync(paths.browserAuth, JSON.stringify(storageState));\n logger.info(\"Browser session saved.\");\n}\n\nfunction generatePassword(): string {\n const upper = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n const lower = \"abcdefghijklmnopqrstuvwxyz\";\n const digits = \"0123456789\";\n const special = \"!@#$%^&*\";\n const all = upper + lower + digits + special;\n\n let password = \"\";\n password += upper[Math.floor(Math.random() * upper.length)];\n password += lower[Math.floor(Math.random() * lower.length)];\n password += digits[Math.floor(Math.random() * digits.length)];\n password += special[Math.floor(Math.random() * special.length)];\n\n for (let i = 4; i < 20; i++) {\n password += all[Math.floor(Math.random() * all.length)];\n }\n\n return password.split(\"\").sort(() => Math.random() - 0.5).join(\"\");\n}\n","import { logger } from \"../utils/logger.js\";\n\n// Spora-owned AgentMail API key — users never need to provide this\nconst SPORA_AGENTMAIL_KEY = process.env.SPORA_AGENTMAIL_KEY ?? \"am_955344daf4d85d72dec6b97d9a5a6817b76d4a5ce09bfc66842bd0a5ef5b1657\";\n\nexport interface EmailInbox {\n address: string;\n inboxId: string;\n}\n\nexport async function createAgentEmail(\n preferredUsername?: string\n): Promise<EmailInbox> {\n const username =\n preferredUsername ?? `spore-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;\n\n try {\n const response = await fetch(\"https://api.agentmail.to/v0/inboxes\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${SPORA_AGENTMAIL_KEY}`,\n },\n body: JSON.stringify({\n username,\n domain: \"agentmail.to\",\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`AgentMail API error: ${response.status} ${error}`);\n }\n\n const data = (await response.json()) as { inbox_id: string; username?: string; display_name?: string };\n const address = `${username}@agentmail.to`;\n\n logger.info(`Created email inbox: ${address}`);\n\n return {\n address,\n inboxId: data.inbox_id,\n };\n } catch (error) {\n logger.error(\"Failed to create email via AgentMail\", error);\n throw error;\n }\n}\n\nexport async function checkInbox(\n inboxId: string,\n waitMs: number = 60000\n): Promise<string | null> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < waitMs) {\n try {\n const response = await fetch(\n `https://api.agentmail.to/v0/inboxes/${encodeURIComponent(inboxId)}/messages`,\n {\n headers: {\n Authorization: `Bearer ${SPORA_AGENTMAIL_KEY}`,\n },\n }\n );\n\n if (!response.ok) continue;\n\n const data = (await response.json()) as { messages: Array<{\n subject: string;\n body_text: string;\n text_content?: string;\n }> };\n\n // Look for verification email from X\n for (const msg of data.messages) {\n if (\n msg.subject.toLowerCase().includes(\"verify\") ||\n msg.subject.toLowerCase().includes(\"confirmation\") ||\n msg.subject.toLowerCase().includes(\"code\")\n ) {\n // Extract verification code (usually 5-8 digits)\n const body = msg.body_text || msg.text_content || \"\";\n const codeMatch = body.match(/\\b(\\d{5,8})\\b/);\n if (codeMatch) {\n return codeMatch[1];\n }\n }\n }\n } catch {\n // Continue polling\n }\n\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n\n return null;\n}\n","import { createXAccount, type SignupResult } from \"./x-signup.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport async function provisionAccount(options: {\n name: string;\n}): Promise<SignupResult> {\n logger.info(\"Starting automated X account creation...\");\n return createXAccount(options);\n}\n\nexport { type SignupResult } from \"./x-signup.js\";\n"],"mappings":";;;;;;AAAA,SAAS,gBAA8D;;;ACGvE,IAAM,sBAAsB,QAAQ,IAAI,uBAAuB;AAO/D,eAAsB,iBACpB,mBACqB;AACrB,QAAM,WACJ,qBAAqB,SAAS,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAEjG,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,uCAAuC;AAAA,MAClE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,mBAAmB;AAAA,MAC9C;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,YAAM,IAAI,MAAM,wBAAwB,SAAS,MAAM,IAAI,KAAK,EAAE;AAAA,IACpE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAM,UAAU,GAAG,QAAQ;AAE3B,WAAO,KAAK,wBAAwB,OAAO,EAAE;AAE7C,WAAO;AAAA,MACL;AAAA,MACA,SAAS,KAAK;AAAA,IAChB;AAAA,EACF,SAAS,OAAO;AACd,WAAO,MAAM,wCAAwC,KAAK;AAC1D,UAAM;AAAA,EACR;AACF;AAEA,eAAsB,WACpB,SACA,SAAiB,KACO;AACxB,QAAM,YAAY,KAAK,IAAI;AAE3B,SAAO,KAAK,IAAI,IAAI,YAAY,QAAQ;AACtC,QAAI;AACF,YAAM,WAAW,MAAM;AAAA,QACrB,uCAAuC,mBAAmB,OAAO,CAAC;AAAA,QAClE;AAAA,UACE,SAAS;AAAA,YACP,eAAe,UAAU,mBAAmB;AAAA,UAC9C;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,GAAI;AAElB,YAAM,OAAQ,MAAM,SAAS,KAAK;AAOlC,iBAAW,OAAO,KAAK,UAAU;AAC/B,YACE,IAAI,QAAQ,YAAY,EAAE,SAAS,QAAQ,KAC3C,IAAI,QAAQ,YAAY,EAAE,SAAS,cAAc,KACjD,IAAI,QAAQ,YAAY,EAAE,SAAS,MAAM,GACzC;AAEA,gBAAM,OAAO,IAAI,aAAa,IAAI,gBAAgB;AAClD,gBAAM,YAAY,KAAK,MAAM,eAAe;AAC5C,cAAI,WAAW;AACb,mBAAO,UAAU,CAAC;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAI,CAAC;AAAA,EAC1D;AAEA,SAAO;AACT;;;ADlFA,eAAe,gBAAgB,MAAY,MAA6B;AACtE,MAAI;AACF,UAAM,EAAE,OAAO,kBAAkB,IAAI,MAAM,OAAO,qBAAmB;AACrE,sBAAkB;AAClB,UAAM,iBAAiB,GAAG,MAAM,OAAO,UAAU,IAAI;AACrD,UAAM,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC9C,WAAO,KAAK,2BAA2B,cAAc,EAAE;AAAA,EACzD,QAAQ;AAAA,EAER;AACF;AAGA,SAAS,YAAY,KAAa,KAA4B;AAC5D,QAAM,KAAK,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,IAAI,IAAI;AACrD,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAgBA,eAAe,iBAAiB,SAAsC,MAA6B;AACjG,QAAM,QAAQ,MAAM;AACpB,QAAM,YAAY,KAAK,GAAG;AAC1B,aAAW,QAAQ,MAAM;AACvB,UAAM,QAAQ,KAAK,MAAM,EAAE,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC;AACxE,QAAI,KAAK,OAAO,IAAI,KAAK;AACvB,YAAM,YAAY,KAAK,GAAG;AAAA,IAC5B;AAAA,EACF;AACF;AAGA,eAAe,WAAW,MAAY,SAAqD;AACzF,QAAM,MAAM,MAAM,QAAQ,YAAY;AACtC,MAAI,KAAK;AAEP,UAAM,IAAI,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI;AACtC,UAAM,IAAI,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI;AACtC,UAAM,KAAK,MAAM,KAAK,GAAG,GAAG,EAAE,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE,IAAI,EAAE,CAAC;AACzE,UAAM,YAAY,KAAK,GAAG;AAAA,EAC5B;AACA,QAAM,QAAQ,MAAM;AACtB;AAGA,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0DvB,eAAsB,eAAe,SAEX;AACxB,MAAI,UAA0B;AAE9B,MAAI;AAEF,WAAO,KAAK,yBAAyB;AACrC,UAAM,QAAQ,MAAM,iBAAiB;AACrC,WAAO,KAAK,kBAAkB,MAAM,OAAO,EAAE;AAG7C,WAAO,KAAK,wCAAwC;AACpD,cAAU,MAAM,SAAS,OAAO;AAAA,MAC9B,UAAU;AAAA,MACV,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,UAAU,MAAM,QAAQ,WAAW;AAAA,MACvC,WAAW;AAAA,MACX,UAAU,EAAE,OAAO,MAAM,QAAQ,IAAI;AAAA,MACrC,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,MACV,mBAAmB;AAAA,IACrB,CAAC;AAGD,UAAM,QAAQ,cAAc,cAAc;AAE1C,UAAM,OAAO,MAAM,QAAQ,QAAQ;AAGnC,UAAM,wBAAwB,YAAY;AACxC,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI,IAAI;AAC7C,cAAM,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG,IAAI;AAC5C,cAAM,KAAK,MAAM,KAAK,GAAG,GAAG,EAAE,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACxE,cAAM,YAAY,KAAK,GAAG;AAAA,MAC5B;AAAA,IACF;AAGA,WAAO,KAAK,2BAA2B;AACvC,UAAM,KAAK,KAAK,+BAA+B;AAAA,MAC7C,WAAW;AAAA,MACX,SAAS;AAAA,IACX,CAAC;AAGD,UAAM,YAAY,KAAM,GAAI;AAC5B,UAAM,sBAAsB;AAC5B,WAAO,KAAK,qBAAqB,KAAK,IAAI,CAAC,EAAE;AAC7C,UAAM,gBAAgB,MAAM,gBAAgB;AAG5C,WAAO,KAAK,gDAAgD;AAC5D,UAAM,kBAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,UAAU;AACd,eAAW,OAAO,iBAAiB;AACjC,UAAI;AACF,cAAM,MAAM,KAAK,QAAQ,GAAG,EAAE,MAAM;AACpC,cAAM,IAAI,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAK,CAAC;AACrD,cAAM,WAAW,MAAM,GAAG;AAC1B,eAAO,KAAK,iCAAiC,GAAG,EAAE;AAClD,kBAAU;AACV,cAAM,YAAY,KAAM,IAAI;AAC5B;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AACA,QAAI,CAAC,SAAS;AACZ,UAAI;AACF,cAAM,MAAM,KAAK,UAAU,kBAAkB,EAAE,OAAO,MAAM,CAAC,EAAE,MAAM;AACrE,cAAM,WAAW,MAAM,GAAG;AAC1B,eAAO,KAAK,yCAAyC;AACrD,kBAAU;AACV,cAAM,YAAY,KAAM,IAAI;AAAA,MAC9B,QAAQ;AACN,eAAO,KAAK,yCAAyC;AACrD,cAAM,gBAAgB,MAAM,kBAAkB;AAAA,MAChD;AAAA,IACF;AAEA,UAAM,gBAAgB,MAAM,uBAAuB;AAGnD,WAAO,KAAK,mCAAmC;AAC/C,UAAM,YAAY,KAAK,QAAQ,oBAAoB,EAAE,MAAM;AAC3D,QAAI;AACF,YAAM,UAAU,QAAQ,EAAE,OAAO,WAAW,SAAS,KAAM,CAAC;AAAA,IAC9D,QAAQ;AACN,YAAM,gBAAgB,MAAM,mBAAmB;AAC/C,YAAM,IAAI,MAAM,uEAAuE;AAAA,IACzF;AACA,UAAM,YAAY,KAAK,GAAI;AAC3B,UAAM,iBAAiB,WAAW,QAAQ,IAAI;AAC9C,WAAO,KAAK,gBAAgB,QAAQ,IAAI,EAAE;AAC1C,UAAM,YAAY,KAAK,IAAI;AAG3B,WAAO,KAAK,yCAAyC;AACrD,UAAM,eAAe,KAAK,QAAQ,oCAAoC,EAAE,MAAM;AAC9E,QAAI;AACF,YAAM,aAAa,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAK,CAAC;AAC9D,YAAM,WAAW,MAAM,YAAY;AACnC,aAAO,KAAK,8BAA8B;AAAA,IAC5C,QAAQ;AAEN,aAAO,KAAK,0EAAqE;AAAA,IACnF;AACA,UAAM,YAAY,KAAK,IAAI;AAG3B,WAAO,KAAK,0BAA0B;AACtC,UAAM,aAAa,KAAK,QAAQ,wDAAwD,EAAE,MAAM;AAChG,QAAI;AACF,YAAM,WAAW,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAK,CAAC;AAAA,IAC9D,QAAQ;AACN,YAAM,gBAAgB,MAAM,oBAAoB;AAChD,YAAM,IAAI,MAAM,yEAAyE;AAAA,IAC3F;AACA,UAAM,YAAY,KAAK,GAAG;AAC1B,UAAM,iBAAiB,YAAY,MAAM,OAAO;AAChD,WAAO,KAAK,iBAAiB,MAAM,OAAO,EAAE;AAC5C,UAAM,YAAY,KAAK,IAAI;AAG3B,WAAO,KAAK,8BAA8B;AAE1C,UAAM,QAAQ,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE,IAAI,CAAC;AACvD,UAAM,cAAc,KAAK,QAAQ,mBAAmB;AACpD,UAAM,YAAY,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAK,CAAC;AAC7D,UAAM,YAAY,KAAK,GAAG;AAC1B,UAAM,YAAY,aAAa,KAAK;AACpC,WAAO,KAAK,cAAc,KAAK,EAAE;AACjC,UAAM,YAAY,KAAK,GAAI;AAE3B,UAAM,MAAM,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE,IAAI,CAAC;AACrD,UAAM,YAAY,KAAK,QAAQ,mBAAmB;AAClD,UAAM,UAAU,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAK,CAAC;AAC3D,UAAM,YAAY,KAAK,GAAG;AAC1B,UAAM,UAAU,aAAa,GAAG;AAChC,WAAO,KAAK,YAAY,GAAG,EAAE;AAC7B,UAAM,YAAY,KAAK,GAAI;AAE3B,UAAM,OAAO,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE,IAAI,IAAI;AACzD,UAAM,aAAa,KAAK,QAAQ,mBAAmB;AACnD,UAAM,WAAW,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAK,CAAC;AAC5D,UAAM,YAAY,KAAK,GAAG;AAC1B,UAAM,WAAW,aAAa,IAAI;AAClC,WAAO,KAAK,aAAa,IAAI,EAAE;AAC/B,UAAM,YAAY,KAAM,GAAI;AAE5B,UAAM,sBAAsB;AAC5B,UAAM,gBAAgB,MAAM,gBAAgB;AAG5C,WAAO,KAAK,0BAA0B;AACtC,UAAM,UAAU,KAAK,QAAQ,mCAAmC,EAAE,MAAM;AACxE,UAAM,QAAQ,QAAQ,EAAE,OAAO,WAAW,SAAS,IAAK,CAAC;AACzD,UAAM,YAAY,KAAK,GAAI;AAC3B,UAAM,WAAW,MAAM,OAAO;AAC9B,WAAO,KAAK,eAAe;AAC3B,UAAM,YAAY,KAAM,GAAI;AAC5B,UAAM,gBAAgB,MAAM,eAAe;AAG3C,aAAS,UAAU,GAAG,UAAU,GAAG,WAAW;AAC5C,YAAM,WAAW,KAAK,QAAQ,mCAAmC,EAAE,MAAM;AACzE,YAAM,kBAAkB,MAAM,SAAS,UAAU,EAAE,MAAM,MAAM,KAAK;AACpE,UAAI,iBAAiB;AACnB,cAAM,YAAY,KAAM,GAAI;AAC5B,cAAM,WAAW,MAAM,QAAQ;AAC/B,eAAO,KAAK,mCAAmC,UAAU,CAAC,IAAI;AAC9D,cAAM,YAAY,KAAM,GAAI;AAAA,MAC9B,OAAO;AACL;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,QAAQ,6DAA6D,EAAE,MAAM;AACpG,UAAM,gBAAgB,MAAM,UAAU,UAAU,EAAE,MAAM,MAAM,KAAK;AACnE,QAAI,eAAe;AACjB,YAAM,YAAY,KAAK,GAAI;AAC3B,YAAM,WAAW,MAAM,SAAS;AAChC,aAAO,KAAK,oBAAoB;AAChC,YAAM,YAAY,KAAM,GAAI;AAAA,IAC9B;AAEA,UAAM,gBAAgB,MAAM,wBAAwB;AAGpD,WAAO,KAAK,gDAAgD;AAG5D,UAAM,YAAY,KAAK,QAAQ,iEAAiE,EAAE,MAAM;AACxG,UAAM,mBAAmB,MAAM,UAAU,UAAU,EAAE,SAAS,KAAM,CAAC,EAAE,MAAM,MAAM,KAAK;AAExF,QAAI,kBAAkB;AACpB,aAAO,KAAK,uDAAuD;AAEnE,YAAM,OAAO,MAAM,WAAW,MAAM,SAAS,GAAK;AAElD,UAAI,MAAM;AACR,eAAO,KAAK,+BAA+B,IAAI,EAAE;AACjD,cAAM,YAAY,KAAK,GAAI;AAC3B,cAAM,iBAAiB,WAAW,IAAI;AACtC,eAAO,KAAK,2BAA2B;AACvC,cAAM,YAAY,KAAM,GAAI;AAE5B,cAAM,gBAAgB,KAAK,QAAQ,4DAA4D,EAAE,MAAM;AACvG,cAAM,uBAAuB,MAAM,cAAc,UAAU,EAAE,SAAS,IAAK,CAAC,EAAE,MAAM,MAAM,KAAK;AAC/F,YAAI,sBAAsB;AACxB,gBAAM,WAAW,MAAM,aAAa;AACpC,iBAAO,KAAK,uCAAuC;AACnD,gBAAM,YAAY,KAAM,GAAI;AAAA,QAC9B;AAAA,MACF,OAAO;AACL,eAAO,KAAK,2CAA2C;AACvD,gBAAQ,IAAI,KAAK,UAAU;AAAA,UACzB,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,OAAO,MAAM;AAAA,QACf,CAAC,CAAC;AAAA,MACJ;AAAA,IACF,OAAO;AACL,aAAO,KAAK,oCAAoC;AAChD,YAAM,gBAAgB,MAAM,0BAA0B;AAAA,IACxD;AAGA,UAAM,WAAW,iBAAiB;AAClC,UAAM,gBAAgB,KAAK,QAAQ,gDAAgD,EAAE,MAAM;AAC3F,UAAM,kBAAkB,MAAM,cAAc,UAAU,EAAE,SAAS,IAAM,CAAC,EAAE,MAAM,MAAM,KAAK;AAC3F,QAAI,iBAAiB;AACnB,aAAO,KAAK,qBAAqB;AACjC,YAAM,YAAY,KAAK,GAAI;AAC3B,YAAM,iBAAiB,eAAe,QAAQ;AAC9C,aAAO,KAAK,kBAAkB;AAC9B,YAAM,YAAY,KAAM,GAAI;AAE5B,YAAM,oBAAoB,KAAK,QAAQ,4DAA4D,EAAE,MAAM;AAC3G,YAAM,gBAAgB,MAAM,kBAAkB,UAAU,EAAE,SAAS,IAAK,CAAC,EAAE,MAAM,MAAM,KAAK;AAC5F,UAAI,eAAe;AACjB,cAAM,WAAW,MAAM,iBAAiB;AACxC,eAAO,KAAK,8BAA8B;AAC1C,cAAM,YAAY,KAAM,GAAI;AAAA,MAC9B;AAAA,IACF;AAGA,QAAI;AACJ,UAAM,gBAAgB,KAAK,QAAQ,wBAAwB,EAAE,MAAM;AACnE,UAAM,kBAAkB,MAAM,cAAc,UAAU,EAAE,SAAS,IAAK,CAAC,EAAE,MAAM,MAAM,KAAK;AAC1F,QAAI,iBAAiB;AACnB,iBAAY,MAAM,cAAc,WAAW,KAAM;AACjD,aAAO,KAAK,aAAa,QAAQ,EAAE;AACnC,YAAM,oBAAoB,KAAK,QAAQ,qFAAqF,EAAE,MAAM;AACpI,YAAM,eAAe,MAAM,kBAAkB,UAAU,EAAE,SAAS,IAAK,CAAC,EAAE,MAAM,MAAM,KAAK;AAC3F,UAAI,cAAc;AAChB,cAAM,WAAW,MAAM,iBAAiB;AACxC,cAAM,YAAY,KAAM,GAAI;AAAA,MAC9B;AAAA,IACF;AAGA,WAAO,KAAK,gCAAgC;AAC5C,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,UAAU;AACd,iBAAW,QAAQ,CAAC,gBAAgB,QAAQ,WAAW,MAAM,GAAG;AAC9D,cAAM,MAAM,KAAK,QAAQ,oBAAoB,IAAI,iCAAiC,IAAI,IAAI,EAAE,MAAM;AAClG,cAAM,UAAU,MAAM,IAAI,UAAU,EAAE,SAAS,IAAK,CAAC,EAAE,MAAM,MAAM,KAAK;AACxE,YAAI,SAAS;AACX,gBAAM,YAAY,KAAK,GAAI;AAC3B,gBAAM,WAAW,MAAM,GAAG;AAC1B,iBAAO,KAAK,aAAa,IAAI,GAAG;AAChC,gBAAM,YAAY,MAAM,IAAI;AAC5B,oBAAU;AACV;AAAA,QACF;AAAA,MACF;AACA,UAAI,CAAC,QAAS;AAAA,IAChB;AAGA,WAAO,KAAK,iCAAiC;AAC7C,UAAM,UAAU,KAAK,QAAQ,qFAAqF;AAClH,UAAM,aAAa,MAAM,QAAQ,MAAM,EAAE,UAAU,EAAE,SAAS,KAAM,CAAC,EAAE,MAAM,MAAM,KAAK;AAExF,QAAI,YAAY;AACd,aAAO,KAAK,iCAAiC;AAC7C,YAAM,YAAY,OAAO;AACzB,YAAM,QAAQ,MAAM;AACpB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU,YAAY,MAAM,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,QAChD;AAAA,QACA,OAAO,MAAM;AAAA,MACf;AAAA,IACF;AAGA,WAAO,KAAK,oDAAoD;AAChE,YAAQ,IAAI,KAAK,UAAU;AAAA,MACzB,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC,CAAC;AAEF,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,WAAW,MAAM,QAAQ,MAAM,EAAE,UAAU,EAAE,SAAS,IAAK,CAAC,EAAE,MAAM,MAAM,KAAK;AACrF,UAAI,UAAU;AACZ,eAAO,KAAK,iBAAiB;AAC7B,cAAM,YAAY,OAAO;AACzB,cAAM,QAAQ,MAAM;AACpB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,UAAU,YAAY,MAAM,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,UAChD;AAAA,UACA,OAAO,MAAM;AAAA,UACb,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM;AACpB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,gBAAgB;AAAA,IAClB;AAAA,EACF,SAAS,OAAO;AACd,WAAO,MAAM,2BAA2B,KAAK;AAC7C,QAAI,QAAS,OAAM,QAAQ,MAAM,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AACjD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAQ,MAAgB;AAAA,MACxB,gBAAgB;AAAA,IAClB;AAAA,EACF;AACF;AAEA,eAAe,YAAY,SAAwC;AACjE,QAAM,eAAe,MAAM,QAAQ,aAAa;AAChD,QAAM,EAAE,cAAc,IAAI,MAAM,OAAO,IAAS;AAChD,QAAM,EAAE,OAAO,kBAAkB,IAAI,MAAM,OAAO,qBAAmB;AACrE,oBAAkB;AAClB,gBAAc,MAAM,aAAa,KAAK,UAAU,YAAY,CAAC;AAC7D,SAAO,KAAK,wBAAwB;AACtC;AAEA,SAAS,mBAA2B;AAClC,QAAM,QAAQ;AACd,QAAM,QAAQ;AACd,QAAM,SAAS;AACf,QAAM,UAAU;AAChB,QAAM,MAAM,QAAQ,QAAQ,SAAS;AAErC,MAAI,WAAW;AACf,cAAY,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAC1D,cAAY,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAC1D,cAAY,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,OAAO,MAAM,CAAC;AAC5D,cAAY,QAAQ,KAAK,MAAM,KAAK,OAAO,IAAI,QAAQ,MAAM,CAAC;AAE9D,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,gBAAY,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,IAAI,MAAM,CAAC;AAAA,EACxD;AAEA,SAAO,SAAS,MAAM,EAAE,EAAE,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG,EAAE,KAAK,EAAE;AACnE;;;AEtgBA,eAAsB,iBAAiB,SAEb;AACxB,SAAO,KAAK,0CAA0C;AACtD,SAAO,eAAe,OAAO;AAC/B;","names":[]}
|