@bobfrankston/rmfmail 1.2.3 → 1.2.5
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/bin/mailx.js +22 -2
- package/bin/mailx.js.map +1 -1
- package/bin/mailx.ts +21 -2
- package/client/app.bundle.js +18 -12
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +14 -12
- package/client/app.js.map +1 -1
- package/client/app.ts +11 -12
- package/client/components/message-viewer.js +9 -2
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +3 -2
- package/client/lib/mailxapi.js +23 -2
- package/package.json +3 -3
- package/packages/mailx-imap/index.d.ts +15 -0
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +146 -0
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +107 -0
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +17 -5
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +63 -171
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +58 -128
- package/packages/mailx-service/jsonrpc.js +2 -0
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +2 -0
- package/packages/mailx-service/package.json +1 -0
- package/packages/mailx-service/sync-worker-client.d.ts +33 -0
- package/packages/mailx-service/sync-worker-client.d.ts.map +1 -0
- package/packages/mailx-service/sync-worker-client.js +89 -0
- package/packages/mailx-service/sync-worker-client.js.map +1 -0
- package/packages/mailx-service/sync-worker-client.ts +92 -0
- package/packages/mailx-service/sync-worker.d.ts +33 -0
- package/packages/mailx-service/sync-worker.d.ts.map +1 -0
- package/packages/mailx-service/sync-worker.js +92 -0
- package/packages/mailx-service/sync-worker.js.map +1 -0
- package/packages/mailx-service/sync-worker.ts +101 -0
- package/packages/mailx-store/db.d.ts +1 -0
- package/packages/mailx-store/db.d.ts.map +1 -1
- package/packages/mailx-store/db.js +19 -0
- package/packages/mailx-store/db.js.map +1 -1
- package/packages/mailx-store/db.ts +20 -1
- package/packages/mailx-store/package.json +1 -1
- package/test/sync-worker-smoke.mjs +60 -0
|
@@ -17,6 +17,7 @@ import { Store } from "@bobfrankston/mailx-store";
|
|
|
17
17
|
import { SyncQueue } from "./sync-queue.js";
|
|
18
18
|
import { Reconciler } from "./reconciler.js";
|
|
19
19
|
import { spawnDbWorker, type SpawnedDbWorker } from "./db-worker-client.js";
|
|
20
|
+
export { spawnSyncWorker, type SpawnedSyncWorker } from "./sync-worker-client.js";
|
|
20
21
|
import { loadSettings, saveSettings, loadAccounts, loadAccountsAsync, saveAccounts, initCloudConfig, loadAllowlist, saveAllowlist, loadAutocomplete, saveAutocomplete, loadKeys, saveKeys, ensureKeysSectionExists, getStorePath, getStorageInfo, getConfigDir, loadUserDict, saveUserDict } from "@bobfrankston/mailx-settings";
|
|
21
22
|
import type { AccountConfig, Folder, AutocompleteRequest, AutocompleteResponse, AutocompleteSettings, AiTransformRequest, AiTransformResponse, ExtractedEvent, MailxApi } from "@bobfrankston/mailx-types";
|
|
22
23
|
import { sanitizeHtml, encodeQuotedPrintable, htmlToPlainText } from "@bobfrankston/mailx-types";
|
|
@@ -2485,25 +2486,14 @@ export class MailxService implements MailxApi {
|
|
|
2485
2486
|
const delimiter = parent?.delimiter || allFolders[0]?.delimiter || ".";
|
|
2486
2487
|
const fullPath = parentPath ? `${parentPath}${delimiter}${name}` : name;
|
|
2487
2488
|
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
// on a wedged/congested connection has returned without error while
|
|
2497
|
-
// the CREATE never reached the server — so the IPC reported success,
|
|
2498
|
-
// the optimistic row got dropped by the next reconcile, and the
|
|
2499
|
-
// folder silently never appeared (Bob 2026-06-12, Archive/dbgtrash).
|
|
2500
|
-
// A folder create is infrequent; correctness beats the fast return.
|
|
2501
|
-
await this.imapManager.syncFolders(accountId, client);
|
|
2502
|
-
const created = this.db.getFolders(accountId).some(f => f.path === fullPath);
|
|
2503
|
-
if (!created) {
|
|
2504
|
-
throw new Error(`Folder "${name}" was not created on the server — please try again (the connection may have been busy).`);
|
|
2505
|
-
}
|
|
2506
|
-
} finally { try { await client.logout(); } catch { /* */ } }
|
|
2489
|
+
// Server CREATE + local folder-row write + verify, all on the sync
|
|
2490
|
+
// worker (the verify catches the wedged-connection "returned OK but
|
|
2491
|
+
// never reached the server" case — Bob 2026-06-12 Archive/dbgtrash).
|
|
2492
|
+
const created = await this.imapManager.createFolderViaServer(accountId, fullPath, name, delimiter);
|
|
2493
|
+
this.imapManager.emit("folderCountsChanged", accountId, {});
|
|
2494
|
+
if (!created) {
|
|
2495
|
+
throw new Error(`Folder "${name}" was not created on the server — please try again (the connection may have been busy).`);
|
|
2496
|
+
}
|
|
2507
2497
|
}
|
|
2508
2498
|
|
|
2509
2499
|
async renameFolder(accountId: string, folderId: number, newName: string): Promise<void> {
|
|
@@ -2512,47 +2502,16 @@ export class MailxService implements MailxApi {
|
|
|
2512
2502
|
const parts = folder.path.split(folder.delimiter || ".");
|
|
2513
2503
|
parts[parts.length - 1] = newName;
|
|
2514
2504
|
const newPath = parts.join(folder.delimiter || ".");
|
|
2515
|
-
|
|
2516
|
-
try {
|
|
2517
|
-
if (client.renameMailbox) {
|
|
2518
|
-
await client.renameMailbox(folder.path, newPath);
|
|
2519
|
-
} else {
|
|
2520
|
-
await (client as any).withConnection(async () => {
|
|
2521
|
-
await (client as any).client.mailboxRename(folder.path, newPath);
|
|
2522
|
-
});
|
|
2523
|
-
}
|
|
2524
|
-
await this.imapManager.syncFolders(accountId, client);
|
|
2525
|
-
await client.logout();
|
|
2526
|
-
} finally { try { await client.logout(); } catch { /* */ } }
|
|
2505
|
+
await this.imapManager.renameFolderViaServer(accountId, folder.path, newPath);
|
|
2527
2506
|
}
|
|
2528
2507
|
|
|
2529
2508
|
async deleteFolder(accountId: string, folderId: number): Promise<void> {
|
|
2530
2509
|
const folder = this.db.getFolders(accountId).find(f => f.id === folderId);
|
|
2531
2510
|
if (!folder) throw new Error("Folder not found");
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
await client.deleteMailbox(folder.path);
|
|
2537
|
-
} else {
|
|
2538
|
-
await (client as any).withConnection(async () => {
|
|
2539
|
-
await (client as any).client.mailboxDelete(folder.path);
|
|
2540
|
-
});
|
|
2541
|
-
}
|
|
2542
|
-
} catch (e: any) {
|
|
2543
|
-
// Server already doesn't have this folder — common case when
|
|
2544
|
-
// the user deleted / renamed it from another client and mailx
|
|
2545
|
-
// is still showing the stale local row. Silently treat as
|
|
2546
|
-
// success and proceed with local cleanup; the user's intent
|
|
2547
|
-
// ("make this go away") is met either way.
|
|
2548
|
-
const msg = String(e?.message || e || "").toLowerCase();
|
|
2549
|
-
const alreadyGone = /nonexistent|does not exist|no such|not found|NO \[.*\] Mailbox|404/i.test(msg);
|
|
2550
|
-
if (!alreadyGone) throw e;
|
|
2551
|
-
console.log(` [folder] ${accountId} delete "${folder.path}": server says already gone — cleaning local DB`);
|
|
2552
|
-
}
|
|
2553
|
-
this.db.deleteFolder(folderId);
|
|
2554
|
-
try { await client.logout(); } catch { /* ignore */ }
|
|
2555
|
-
} finally { try { await client.logout(); } catch { /* */ } }
|
|
2511
|
+
// Server delete (tolerant of already-gone) on the worker, then drop the
|
|
2512
|
+
// local folder row here.
|
|
2513
|
+
await this.imapManager.deleteFolderViaServer(accountId, folder.path);
|
|
2514
|
+
this.db.deleteFolder(folderId);
|
|
2556
2515
|
}
|
|
2557
2516
|
|
|
2558
2517
|
/** Move a folder into the account's Trash. Default delete action; user
|
|
@@ -2600,73 +2559,10 @@ export class MailxService implements MailxApi {
|
|
|
2600
2559
|
}
|
|
2601
2560
|
if (!targetPath) throw new Error(`Too many "${baseName}" copies in Trash — empty Trash or use Delete permanently.`);
|
|
2602
2561
|
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
await client.renameMailbox(folder.path, targetPath);
|
|
2608
|
-
} else {
|
|
2609
|
-
await (client as any).withConnection(async () => {
|
|
2610
|
-
await (client as any).client.mailboxRename(folder.path, targetPath);
|
|
2611
|
-
});
|
|
2612
|
-
}
|
|
2613
|
-
console.log(` [folder] ${accountId} moved "${folder.path}" → "${targetPath}"`);
|
|
2614
|
-
} catch (e: any) {
|
|
2615
|
-
// Some Dovecot / Cyrus setups mark Trash \Noinferiors. Fall
|
|
2616
|
-
// back to messages-only move + folder delete. We do this
|
|
2617
|
-
// recursively for any child folders so the user's intent
|
|
2618
|
-
// ("get rid of this subtree") is met.
|
|
2619
|
-
const msg = String(e?.message || e || "").toLowerCase();
|
|
2620
|
-
const cantNest = /noinferiors|hierarchy|invalid (mailbox )?name|cannot rename|inferiors/i.test(msg);
|
|
2621
|
-
if (!cantNest) throw e;
|
|
2622
|
-
console.log(` [folder] ${accountId} cannot RENAME under Trash (${msg.split("\n")[0]}); falling back to message-move`);
|
|
2623
|
-
await this.spillFolderContentsToTrash(accountId, folder, trash, client);
|
|
2624
|
-
}
|
|
2625
|
-
await this.imapManager.syncFolders(accountId, client);
|
|
2626
|
-
try { await client.logout(); } catch { /* */ }
|
|
2627
|
-
} finally { try { await client.logout(); } catch { /* */ } }
|
|
2628
|
-
}
|
|
2629
|
-
|
|
2630
|
-
/** Fallback for `moveFolderToTrash` when the server rejects nesting
|
|
2631
|
-
* under Trash. Moves every message in `folder` (and recursively in
|
|
2632
|
-
* its children) into Trash root, then deletes the empty folders. */
|
|
2633
|
-
private async spillFolderContentsToTrash(
|
|
2634
|
-
accountId: string,
|
|
2635
|
-
folder: { id: number; path: string; delimiter?: string | null },
|
|
2636
|
-
trash: { id: number; path: string },
|
|
2637
|
-
client: any,
|
|
2638
|
-
): Promise<void> {
|
|
2639
|
-
const delim = folder.delimiter || "/";
|
|
2640
|
-
// Process children first so the parent ends up empty.
|
|
2641
|
-
const childPrefix = folder.path + delim;
|
|
2642
|
-
const allFolders = this.db.getFolders(accountId);
|
|
2643
|
-
const children = allFolders.filter(f => f.path.startsWith(childPrefix));
|
|
2644
|
-
for (const child of children) {
|
|
2645
|
-
await this.spillFolderContentsToTrash(accountId, child as any, trash, client);
|
|
2646
|
-
}
|
|
2647
|
-
// Move messages to Trash root via the Store + queue. withBatch
|
|
2648
|
-
// coalesces folder-count events into one re-render per topic.
|
|
2649
|
-
const uids = await client.getUids(folder.path).catch(() => [] as number[]);
|
|
2650
|
-
if (uids.length > 0) {
|
|
2651
|
-
this.localStore.bus.withBatch(() => {
|
|
2652
|
-
for (const uid of uids) {
|
|
2653
|
-
const result = this.localStore.trashMessage(accountId, uid, folder.id, trash.id);
|
|
2654
|
-
if (result === "moved-to-trash") this.syncQueue.enqueueMove(accountId, uid, folder.id, trash.id);
|
|
2655
|
-
else this.syncQueue.enqueueDelete(accountId, uid, folder.id, "delete");
|
|
2656
|
-
}
|
|
2657
|
-
});
|
|
2658
|
-
}
|
|
2659
|
-
// Folder should now be empty; delete it on the server.
|
|
2660
|
-
try {
|
|
2661
|
-
if (client.deleteMailbox) await client.deleteMailbox(folder.path);
|
|
2662
|
-
else await client.withConnection(async () => {
|
|
2663
|
-
await client.client.mailboxDelete(folder.path);
|
|
2664
|
-
});
|
|
2665
|
-
} catch (e: any) {
|
|
2666
|
-
const m = String(e?.message || e || "").toLowerCase();
|
|
2667
|
-
if (!/nonexistent|does not exist|no such/.test(m)) throw e;
|
|
2668
|
-
}
|
|
2669
|
-
this.db.deleteFolder(folder.id);
|
|
2562
|
+
// RENAME-into-Trash (or message-spill fallback) + folder-row cleanup,
|
|
2563
|
+
// all on the sync worker.
|
|
2564
|
+
await this.imapManager.moveFolderToTrashViaServer(accountId, folder.id, folder.path, targetPath, trash.id, trash.path, delim);
|
|
2565
|
+
this.imapManager.emit("folderCountsChanged", accountId, {});
|
|
2670
2566
|
}
|
|
2671
2567
|
|
|
2672
2568
|
markFolderRead(folderId: number): void {
|
|
@@ -2684,12 +2580,7 @@ export class MailxService implements MailxApi {
|
|
|
2684
2580
|
try {
|
|
2685
2581
|
(this.imapManager as any).emit?.("folderCountsChanged", accountId, {});
|
|
2686
2582
|
} catch { /* non-fatal */ }
|
|
2687
|
-
|
|
2688
|
-
try {
|
|
2689
|
-
const uids = await client.getUids(folder.path);
|
|
2690
|
-
for (const uid of uids) await client.deleteMessageByUid(folder.path, uid);
|
|
2691
|
-
await client.logout();
|
|
2692
|
-
} finally { try { await client.logout(); } catch { /* */ } }
|
|
2583
|
+
await this.imapManager.emptyFolderViaServer(accountId, folder.path);
|
|
2693
2584
|
}
|
|
2694
2585
|
|
|
2695
2586
|
// ── Attachments ──
|
|
@@ -2760,6 +2651,45 @@ export class MailxService implements MailxApi {
|
|
|
2760
2651
|
return { ok: true, path: target };
|
|
2761
2652
|
}
|
|
2762
2653
|
|
|
2654
|
+
/** Open an http/https/mailto URL in the OS default browser/handler from the
|
|
2655
|
+
* Node process. The UI used to rely on `window.open(url, "_blank")`, but
|
|
2656
|
+
* inside msger's WebView2 that opens a local in-app window (or no-ops)
|
|
2657
|
+
* rather than the system browser — so clicking a link in a message, or an
|
|
2658
|
+
* unsubscribe "click here", "stayed local" (Bob 2026-06-13, "old bug
|
|
2659
|
+
* back"). `mailxapi.openExternal` now routes here.
|
|
2660
|
+
*
|
|
2661
|
+
* Security: the URL comes from untrusted email. We (1) parse it and allow
|
|
2662
|
+
* ONLY http/https/mailto — no file:, javascript:, data:, etc. — and (2)
|
|
2663
|
+
* pass it as a single spawn ARG with no shell, and on Windows use rundll32
|
|
2664
|
+
* (not `cmd /c start`, which re-parses `&`/`^` in query strings and is
|
|
2665
|
+
* injection-prone). Same cross-platform spawn pattern as openAttachment. */
|
|
2666
|
+
async openExternal(url: string): Promise<{ ok: boolean; reason?: string }> {
|
|
2667
|
+
let u: URL;
|
|
2668
|
+
try { u = new URL(String(url)); }
|
|
2669
|
+
catch { return { ok: false, reason: "unparseable URL" }; }
|
|
2670
|
+
if (!["http:", "https:", "mailto:"].includes(u.protocol)) {
|
|
2671
|
+
console.error(` [openExternal] refused non-web scheme: ${u.protocol}`);
|
|
2672
|
+
return { ok: false, reason: `unsupported scheme ${u.protocol}` };
|
|
2673
|
+
}
|
|
2674
|
+
const target = u.href;
|
|
2675
|
+
try {
|
|
2676
|
+
const { spawn } = await import("node:child_process");
|
|
2677
|
+
if (process.platform === "win32") {
|
|
2678
|
+
// rundll32 receives the URL as a direct argv — no cmd, so query
|
|
2679
|
+
// strings with & can't break out into a second command.
|
|
2680
|
+
spawn("rundll32", ["url.dll,FileProtocolHandler", target], { detached: true, stdio: "ignore", windowsHide: true }).unref();
|
|
2681
|
+
} else if (process.platform === "darwin") {
|
|
2682
|
+
spawn("open", [target], { detached: true, stdio: "ignore" }).unref();
|
|
2683
|
+
} else {
|
|
2684
|
+
spawn("xdg-open", [target], { detached: true, stdio: "ignore" }).unref();
|
|
2685
|
+
}
|
|
2686
|
+
return { ok: true };
|
|
2687
|
+
} catch (e: any) {
|
|
2688
|
+
console.error(` [openExternal] spawn failed: ${e?.message || e}`);
|
|
2689
|
+
return { ok: false, reason: e?.message || String(e) };
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
|
|
2763
2693
|
// ── Drafts ──
|
|
2764
2694
|
|
|
2765
2695
|
async saveDraft(accountId: string, subject: string, bodyHtml: string, bodyText: string, to?: string, cc?: string, previousDraftUid?: number, draftId?: string): Promise<{ draftUid: number | null; draftId: string }> {
|
|
@@ -306,6 +306,8 @@ async function dispatchAction(svc, action, p) {
|
|
|
306
306
|
}
|
|
307
307
|
case "openAttachment":
|
|
308
308
|
return await svc.openAttachment(p.accountId, p.uid, p.attachmentId, p.folderId, p.filename);
|
|
309
|
+
case "openExternal":
|
|
310
|
+
return await svc.openExternal(p.url);
|
|
309
311
|
// Setup & Repair
|
|
310
312
|
case "setupAccount":
|
|
311
313
|
return svc.setupAccount(p.name, p.email, p.password);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonrpc.js","sourceRoot":"","sources":["jsonrpc.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"jsonrpc.js","sourceRoot":"","sources":["jsonrpc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAsBzG,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAgB,EAAE,GAAe;IAC5D,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,GAAG,GAAG,CAAC;IAC1C,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QACd,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/C,CAAC;AACL,CAAC;AAED;;;;;;gFAMgF;AAChF,SAAS,cAAc,CAAC,CAAM;IAC1B,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,eAAe,CAAC;IACtC,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM;aACjB,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;aACrD,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACzE,CAAC;IACD,IAAI,CAAC,GAAG;QAAE,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QAAE,GAAG,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;IAC5D,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC;QACX,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC;IAChD,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,GAAgB,EAAE,MAAc,EAAE,CAAsB;IAClF,QAAQ,MAAM,EAAE,CAAC;QACb,WAAW;QACX,KAAK,aAAa;YACd,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;QAC7B,KAAK,YAAY;YACb,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAEvC,WAAW;QACX,KAAK,aAAa;YACd,OAAO,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;QACpH,KAAK,iBAAiB;YAClB,OAAO,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QAC/E,KAAK,YAAY;YACb,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QAEzE,kBAAkB;QAClB,KAAK,aAAa;YACd,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YACnD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,eAAe;YAChB,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YACxD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,gBAAgB;YACjB,MAAM,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;YAC3D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9C,KAAK,iBAAiB;YAClB,MAAM,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC1D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,aAAa;YACd,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC;YAC/E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,cAAc;YACf,MAAM,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC;YAC9D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9C,KAAK,cAAc;YACf,MAAM,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC;YAC3E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9C,KAAK,oBAAoB;YACrB,OAAO,MAAM,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAE7D,UAAU;QACV,KAAK,gBAAgB;YACjB,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC/B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,cAAc;YACf,MAAM,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,cAAc;YACf,MAAM,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;YAC3D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,cAAc;YACf,MAAM,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YAChD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,mBAAmB;YACpB,MAAM,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YACrD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,aAAa;YACd,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC/C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAExB,sEAAsE;QACtE,mEAAmE;QACnE,qEAAqE;QACrE,wEAAwE;QACxE,mEAAmE;QACnE,8CAA8C;QAC9C,KAAK,aAAa;YACd,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,WAAW;YACZ,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QACpH,KAAK,aAAa;YACd,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;YAC1D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAExB,OAAO;QACP,KAAK,SAAS;YACV,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,aAAa;YACd,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACnC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,eAAe;YAChB,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YACjD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,gBAAgB;YACjB,OAAO,GAAG,CAAC,cAAc,EAAE,CAAC;QAChC,KAAK,gBAAgB;YACjB,OAAO,GAAG,CAAC,cAAc,EAAE,CAAC;QAChC,KAAK,mBAAmB;YACpB,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAE7C,kEAAkE;QAClE,8DAA8D;QAC9D,KAAK,mBAAmB;YACpB,OAAO,MAAM,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACzD,KAAK,cAAc;YACf,OAAO,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC;QACpC,KAAK,qBAAqB;YACtB,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,KAAK,qBAAqB;YACtB,MAAM,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAC7E,KAAK,qBAAqB;YACtB,MAAM,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACpE,KAAK,UAAU;YACX,OAAO,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;QACpD,KAAK,YAAY;YACb,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,KAAK,YAAY;YACb,MAAM,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACpE,KAAK,YAAY;YACb,MAAM,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAC3D,KAAK,gBAAgB;YACjB,MAAM,GAAG,CAAC,cAAc,EAAE,CAAC;YAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACpD,KAAK,kBAAkB;YACnB,OAAO,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QACtE,KAAK,iBAAiB;YAClB,OAAO,GAAG,CAAC,eAAe,EAAE,CAAC;QACjC,KAAK,oBAAoB;YACrB,OAAO,GAAG,CAAC,kBAAkB,EAAE,CAAC;QACpC,KAAK,sBAAsB;YACvB,OAAO,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC5C,KAAK,gBAAgB;YACjB,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;QACzD,KAAK,oBAAoB;YACrB,OAAO,GAAG,CAAC,kBAAkB,EAAE,CAAC;QAEpC,oBAAoB;QACpB,KAAK,gBAAgB;YACjB,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;QAC3G,KAAK,oBAAoB;YACrB,GAAG,CAAC,kBAAkB,EAAE,CAAC;YACzB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,gBAAgB;YACjB,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACvC,KAAK,gBAAgB;YACjB,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,KAAK,iBAAiB;YAClB,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,KAAK,YAAY;YACb,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,KAAK,cAAc;YACf,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;QAC3E,KAAK,eAAe;YAChB,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9C,KAAK,eAAe;YAChB,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACtC,KAAK,qBAAqB;YACtB,MAAM,GAAG,CAAC,mBAAmB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;YAChH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,eAAe;YAChB,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACjC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,kBAAkB;YACnB,OAAO,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAClC,KAAK,mBAAmB;YACpB,MAAM,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YACxD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,mBAAmB;YACpB,MAAM,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACjD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,oBAAoB;YACrB,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,kBAAkB,EAAE,EAAE,CAAC;QACtD,KAAK,eAAe;YAChB,OAAO,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC5C,KAAK,kBAAkB;YACnB,OAAO,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9C,KAAK,mBAAmB;YACpB,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC1D,KAAK,eAAe;YAChB,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QACxD,KAAK,gBAAgB;YACjB,MAAM,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;YAC5C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,aAAa;YACd,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QACzD,KAAK,gBAAgB;YACjB,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QACzD,KAAK,qBAAqB;YACtB,OAAO,MAAM,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAChD,KAAK,YAAY;YACb,OAAO,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAClD,KAAK,eAAe;YAChB,OAAO,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC7C,KAAK,mBAAmB;YACpB,OAAO,MAAM,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;QAC1C,KAAK,sBAAsB;YACvB,OAAO,GAAG,CAAC,oBAAoB,EAAE,CAAC;QAEtC,sEAAsE;QACtE,wEAAwE;QACxE,sEAAsE;QACtE,uEAAuE;QACvE,eAAe;QACf,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACpB,+DAA+D;YAC/D,8DAA8D;YAC9D,+DAA+D;YAC/D,iEAAiE;YACjE,sCAAsC;YACtC,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;YACzB,sDAAsD;YACtD,MAAM,KAAK,GAAG,GAAG,KAAK,eAAe,IAAI,GAAG,KAAK,cAAc,IAAI,GAAG,KAAK,2BAA2B,CAAC;YACvG,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;YAC/C,EAAE,CAAC,cAAc,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,CAAC;QAED,WAAW;QACX,KAAK,aAAa;YACd,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;QAC7B,KAAK,kBAAkB;YACnB,MAAM,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC1B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,oBAAoB;YACrB,+DAA+D;YAC/D,+DAA+D;YAC/D,+DAA+D;YAC/D,2DAA2D;YAC3D,yDAAyD;YACzD,MAAM,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,aAAa;YACd,OAAO,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;QACnC,KAAK,iBAAiB;YAClB,OAAO,MAAM,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7C,KAAK,kBAAkB;YACnB,OAAO,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC/C,KAAK,oBAAoB;YACrB,OAAO,MAAM,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChD,KAAK,oBAAoB;YACrB,OAAO,MAAM,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QACzD,KAAK,YAAY,CAAC,CAAC,CAAC;YAChB,IAAI,CAAC;gBACD,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;gBACnC,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,EAAE,CAAC;gBACrC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,IAAI,QAAQ,EAAE,OAAO,EAAE,CAAC;YACjG,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBACd,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC5D,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YAC/E,CAAC;QACL,CAAC;QAED,eAAe;QACf,KAAK,cAAc;YACf,OAAO,GAAG,CAAC,YAAY,CAAC,CAAQ,CAAC,CAAC;QACtC,KAAK,yBAAyB;YAC1B,OAAO,GAAG,CAAC,uBAAuB,EAAE,CAAC;QACzC,KAAK,0BAA0B;YAC3B,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC;YAChC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAExB,0EAA0E;QAC1E,wDAAwD;QACxD,KAAK,aAAa;YACd,OAAO,GAAG,CAAC,WAAW,CAAC,CAAQ,CAAC,CAAC;QAErC,cAAc;QACd,KAAK,eAAe,CAAC,CAAC,CAAC;YACnB,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YACpF,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7G,CAAC;QACD,KAAK,gBAAgB;YACjB,OAAO,MAAM,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QAChG,KAAK,cAAc;YACf,OAAO,MAAM,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAEzC,iBAAiB;QACjB,KAAK,cAAc;YACf,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QACzD,KAAK,gBAAgB;YACjB,OAAO,GAAG,CAAC,cAAc,EAAE,CAAC;QAEhC;YACI,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;AACL,CAAC"}
|
|
@@ -332,6 +332,8 @@ async function dispatchAction(svc: ServiceLike, action: string, p: Record<string
|
|
|
332
332
|
}
|
|
333
333
|
case "openAttachment":
|
|
334
334
|
return await svc.openAttachment(p.accountId, p.uid, p.attachmentId, p.folderId, p.filename);
|
|
335
|
+
case "openExternal":
|
|
336
|
+
return await svc.openExternal(p.url);
|
|
335
337
|
|
|
336
338
|
// Setup & Repair
|
|
337
339
|
case "setupAccount":
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"@bobfrankston/mailx-imap": "file:../mailx-imap",
|
|
14
14
|
"@bobfrankston/mailx-settings": "file:../mailx-settings",
|
|
15
15
|
"@bobfrankston/mailx-store": "file:../mailx-store",
|
|
16
|
+
"@bobfrankston/node-tcp-transport": "file:../../../../MailApps/node-tcp-transport",
|
|
16
17
|
"@bobfrankston/mailx-types": "file:../mailx-types",
|
|
17
18
|
"html-to-docx": "^1.8.0",
|
|
18
19
|
"mailparser": "^3.7.2",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main-thread client for the sync factor worker.
|
|
3
|
+
*
|
|
4
|
+
* Spawns `sync-worker.js`, performs the init handshake, and returns a
|
|
5
|
+
* `SyncProxy` that is a DROP-IN for `ImapManager` from the main thread's point
|
|
6
|
+
* of view: it's an EventEmitter (so `bin`'s `.on(...)` forwarders and the
|
|
7
|
+
* service's `.emit(...)` keep working locally), and any *other* method call is
|
|
8
|
+
* forwarded to the worker over the bus as `{method, args}` and returns the
|
|
9
|
+
* worker's result as a Promise.
|
|
10
|
+
*
|
|
11
|
+
* Two method names are handled locally instead of being forwarded:
|
|
12
|
+
* - the EventEmitter surface (on/once/off/emit/…) — local event routing.
|
|
13
|
+
* - getBodyStore() — returns a local FileMessageStore (a path wrapper; the
|
|
14
|
+
* bytes live on disk, so main can read them without crossing the bus).
|
|
15
|
+
*
|
|
16
|
+
* Worker → main events arrive on the bus topic `sync:event` and are re-emitted
|
|
17
|
+
* on the local EventEmitter, so a `syncProgress` raised inside the worker fires
|
|
18
|
+
* bin's listener exactly as before.
|
|
19
|
+
*/
|
|
20
|
+
import { Worker } from "node:worker_threads";
|
|
21
|
+
import type { ImapManager } from "@bobfrankston/mailx-imap";
|
|
22
|
+
export interface SpawnedSyncWorker {
|
|
23
|
+
/** Drop-in for ImapManager. Method calls return Promises (forwarded to the
|
|
24
|
+
* worker); event methods are local. */
|
|
25
|
+
proxy: ImapManager;
|
|
26
|
+
worker: Worker;
|
|
27
|
+
close(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export declare function spawnSyncWorker(opts: {
|
|
30
|
+
configDir: string;
|
|
31
|
+
storePath: string;
|
|
32
|
+
}): Promise<SpawnedSyncWorker>;
|
|
33
|
+
//# sourceMappingURL=sync-worker-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-worker-client.d.ts","sourceRoot":"","sources":["sync-worker-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAM7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAC9B;4CACwC;IACxC,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAQD,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiDhH"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main-thread client for the sync factor worker.
|
|
3
|
+
*
|
|
4
|
+
* Spawns `sync-worker.js`, performs the init handshake, and returns a
|
|
5
|
+
* `SyncProxy` that is a DROP-IN for `ImapManager` from the main thread's point
|
|
6
|
+
* of view: it's an EventEmitter (so `bin`'s `.on(...)` forwarders and the
|
|
7
|
+
* service's `.emit(...)` keep working locally), and any *other* method call is
|
|
8
|
+
* forwarded to the worker over the bus as `{method, args}` and returns the
|
|
9
|
+
* worker's result as a Promise.
|
|
10
|
+
*
|
|
11
|
+
* Two method names are handled locally instead of being forwarded:
|
|
12
|
+
* - the EventEmitter surface (on/once/off/emit/…) — local event routing.
|
|
13
|
+
* - getBodyStore() — returns a local FileMessageStore (a path wrapper; the
|
|
14
|
+
* bytes live on disk, so main can read them without crossing the bus).
|
|
15
|
+
*
|
|
16
|
+
* Worker → main events arrive on the bus topic `sync:event` and are re-emitted
|
|
17
|
+
* on the local EventEmitter, so a `syncProgress` raised inside the worker fires
|
|
18
|
+
* bin's listener exactly as before.
|
|
19
|
+
*/
|
|
20
|
+
import { Worker } from "node:worker_threads";
|
|
21
|
+
import { EventEmitter } from "node:events";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
import { dirname, join } from "node:path";
|
|
24
|
+
import { WorkerBus } from "@bobfrankston/mailx-bus";
|
|
25
|
+
import { FileMessageStore } from "@bobfrankston/mailx-store";
|
|
26
|
+
const EMITTER_METHODS = new Set([
|
|
27
|
+
"on", "once", "off", "addListener", "removeListener", "removeAllListeners",
|
|
28
|
+
"emit", "listeners", "rawListeners", "listenerCount", "eventNames",
|
|
29
|
+
"prependListener", "prependOnceListener", "setMaxListeners", "getMaxListeners",
|
|
30
|
+
]);
|
|
31
|
+
export async function spawnSyncWorker(opts) {
|
|
32
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
33
|
+
const workerPath = join(here, "sync-worker.js");
|
|
34
|
+
const worker = new Worker(workerPath);
|
|
35
|
+
worker.unref();
|
|
36
|
+
await new Promise((resolve, reject) => {
|
|
37
|
+
const onMessage = (msg) => {
|
|
38
|
+
if (!msg || typeof msg !== "object")
|
|
39
|
+
return;
|
|
40
|
+
if (msg.kind === "init-ok") {
|
|
41
|
+
worker.off("message", onMessage);
|
|
42
|
+
resolve();
|
|
43
|
+
}
|
|
44
|
+
else if (msg.kind === "init-error") {
|
|
45
|
+
worker.off("message", onMessage);
|
|
46
|
+
reject(new Error(`sync-worker init: ${msg.error}`));
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
worker.on("message", onMessage);
|
|
50
|
+
worker.on("error", (e) => { worker.off("message", onMessage); reject(e); });
|
|
51
|
+
worker.postMessage({ kind: "init", configDir: opts.configDir, storePath: opts.storePath });
|
|
52
|
+
});
|
|
53
|
+
const bus = new WorkerBus(worker);
|
|
54
|
+
const emitter = new EventEmitter();
|
|
55
|
+
emitter.setMaxListeners(0);
|
|
56
|
+
const localBodyStore = new FileMessageStore(opts.storePath);
|
|
57
|
+
// Worker events → local re-emit (drives bin's WebView forwarders).
|
|
58
|
+
bus.subscribe("sync:event", ({ event, args }) => {
|
|
59
|
+
try {
|
|
60
|
+
emitter.emit(event, ...(args || []));
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
console.error(` [sync-worker] event '${event}' handler threw: ${e?.message || e}`);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
const proxy = new Proxy(emitter, {
|
|
67
|
+
get(target, prop) {
|
|
68
|
+
if (typeof prop === "string" && EMITTER_METHODS.has(prop)) {
|
|
69
|
+
const v = target[prop];
|
|
70
|
+
return typeof v === "function" ? v.bind(target) : v;
|
|
71
|
+
}
|
|
72
|
+
if (prop === "getBodyStore")
|
|
73
|
+
return () => localBodyStore;
|
|
74
|
+
if (prop === "then")
|
|
75
|
+
return undefined; // not a thenable
|
|
76
|
+
// Everything else is an ImapManager method → forward to the worker.
|
|
77
|
+
// structured-clone turns a returned Node Buffer into a plain
|
|
78
|
+
// Uint8Array; re-wrap so callers that test Buffer.isBuffer / hand
|
|
79
|
+
// the bytes to simpleParser (fetchMessageBody) still work.
|
|
80
|
+
return (...args) => bus.request("sync:call", { method: prop, args }).then((r) => (r instanceof Uint8Array && !Buffer.isBuffer(r)) ? Buffer.from(r.buffer, r.byteOffset, r.byteLength) : r);
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
proxy,
|
|
85
|
+
worker,
|
|
86
|
+
async close() { await worker.terminate(); },
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=sync-worker-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-worker-client.js","sourceRoot":"","sources":["sync-worker-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main-thread client for the sync factor worker.
|
|
3
|
+
*
|
|
4
|
+
* Spawns `sync-worker.js`, performs the init handshake, and returns a
|
|
5
|
+
* `SyncProxy` that is a DROP-IN for `ImapManager` from the main thread's point
|
|
6
|
+
* of view: it's an EventEmitter (so `bin`'s `.on(...)` forwarders and the
|
|
7
|
+
* service's `.emit(...)` keep working locally), and any *other* method call is
|
|
8
|
+
* forwarded to the worker over the bus as `{method, args}` and returns the
|
|
9
|
+
* worker's result as a Promise.
|
|
10
|
+
*
|
|
11
|
+
* Two method names are handled locally instead of being forwarded:
|
|
12
|
+
* - the EventEmitter surface (on/once/off/emit/…) — local event routing.
|
|
13
|
+
* - getBodyStore() — returns a local FileMessageStore (a path wrapper; the
|
|
14
|
+
* bytes live on disk, so main can read them without crossing the bus).
|
|
15
|
+
*
|
|
16
|
+
* Worker → main events arrive on the bus topic `sync:event` and are re-emitted
|
|
17
|
+
* on the local EventEmitter, so a `syncProgress` raised inside the worker fires
|
|
18
|
+
* bin's listener exactly as before.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { Worker } from "node:worker_threads";
|
|
22
|
+
import { EventEmitter } from "node:events";
|
|
23
|
+
import { fileURLToPath } from "node:url";
|
|
24
|
+
import { dirname, join } from "node:path";
|
|
25
|
+
import { WorkerBus, type MessagePortLike } from "@bobfrankston/mailx-bus";
|
|
26
|
+
import { FileMessageStore } from "@bobfrankston/mailx-store";
|
|
27
|
+
import type { ImapManager } from "@bobfrankston/mailx-imap";
|
|
28
|
+
|
|
29
|
+
export interface SpawnedSyncWorker {
|
|
30
|
+
/** Drop-in for ImapManager. Method calls return Promises (forwarded to the
|
|
31
|
+
* worker); event methods are local. */
|
|
32
|
+
proxy: ImapManager;
|
|
33
|
+
worker: Worker;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const EMITTER_METHODS = new Set([
|
|
38
|
+
"on", "once", "off", "addListener", "removeListener", "removeAllListeners",
|
|
39
|
+
"emit", "listeners", "rawListeners", "listenerCount", "eventNames",
|
|
40
|
+
"prependListener", "prependOnceListener", "setMaxListeners", "getMaxListeners",
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
export async function spawnSyncWorker(opts: { configDir: string; storePath: string }): Promise<SpawnedSyncWorker> {
|
|
44
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
45
|
+
const workerPath = join(here, "sync-worker.js");
|
|
46
|
+
const worker = new Worker(workerPath);
|
|
47
|
+
worker.unref();
|
|
48
|
+
|
|
49
|
+
await new Promise<void>((resolve, reject) => {
|
|
50
|
+
const onMessage = (msg: any): void => {
|
|
51
|
+
if (!msg || typeof msg !== "object") return;
|
|
52
|
+
if (msg.kind === "init-ok") { worker.off("message", onMessage); resolve(); }
|
|
53
|
+
else if (msg.kind === "init-error") { worker.off("message", onMessage); reject(new Error(`sync-worker init: ${msg.error}`)); }
|
|
54
|
+
};
|
|
55
|
+
worker.on("message", onMessage);
|
|
56
|
+
worker.on("error", (e: Error) => { worker.off("message", onMessage); reject(e); });
|
|
57
|
+
worker.postMessage({ kind: "init", configDir: opts.configDir, storePath: opts.storePath });
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const bus = new WorkerBus(worker as unknown as MessagePortLike);
|
|
61
|
+
const emitter = new EventEmitter();
|
|
62
|
+
emitter.setMaxListeners(0);
|
|
63
|
+
const localBodyStore = new FileMessageStore(opts.storePath);
|
|
64
|
+
|
|
65
|
+
// Worker events → local re-emit (drives bin's WebView forwarders).
|
|
66
|
+
bus.subscribe<{ event: string; args: any[] }>("sync:event", ({ event, args }) => {
|
|
67
|
+
try { emitter.emit(event, ...(args || [])); } catch (e: any) { console.error(` [sync-worker] event '${event}' handler threw: ${e?.message || e}`); }
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const proxy = new Proxy(emitter, {
|
|
71
|
+
get(target, prop: string) {
|
|
72
|
+
if (typeof prop === "string" && EMITTER_METHODS.has(prop)) {
|
|
73
|
+
const v = (target as any)[prop];
|
|
74
|
+
return typeof v === "function" ? v.bind(target) : v;
|
|
75
|
+
}
|
|
76
|
+
if (prop === "getBodyStore") return () => localBodyStore;
|
|
77
|
+
if (prop === "then") return undefined; // not a thenable
|
|
78
|
+
// Everything else is an ImapManager method → forward to the worker.
|
|
79
|
+
// structured-clone turns a returned Node Buffer into a plain
|
|
80
|
+
// Uint8Array; re-wrap so callers that test Buffer.isBuffer / hand
|
|
81
|
+
// the bytes to simpleParser (fetchMessageBody) still work.
|
|
82
|
+
return (...args: any[]) => bus.request("sync:call", { method: prop, args }).then((r: any) =>
|
|
83
|
+
(r instanceof Uint8Array && !Buffer.isBuffer(r)) ? Buffer.from(r.buffer, r.byteOffset, r.byteLength) : r);
|
|
84
|
+
},
|
|
85
|
+
}) as unknown as ImapManager;
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
proxy,
|
|
89
|
+
worker,
|
|
90
|
+
async close(): Promise<void> { await worker.terminate(); },
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync factor — Node worker thread.
|
|
3
|
+
*
|
|
4
|
+
* Hosts the entire network/sync backend (`ImapManager`: IMAP + Gmail sync,
|
|
5
|
+
* body prefetch, the outbox SMTP/IMAP-append drain, IDLE) on its OWN thread,
|
|
6
|
+
* with its OWN write connection to the SQLite file. The main thread keeps the
|
|
7
|
+
* IPC pump and fast local reads (read-worker); it drives this worker through
|
|
8
|
+
* a proxy (`sync-worker-client.ts`) and receives ImapManager's events back
|
|
9
|
+
* over the bus.
|
|
10
|
+
*
|
|
11
|
+
* **Why.** Until now sync ran on the main event loop. A hung Dovecot FETCH, a
|
|
12
|
+
* 30 MB body pull, a dead-network reconnect storm, a 5-minute outbox hang —
|
|
13
|
+
* any of them froze the main loop, which starved the IPC relay, so clicks and
|
|
14
|
+
* the message list timed out even though the read-worker had the answer ready.
|
|
15
|
+
* On its own thread, sync can stall or thrash forever and the UI never feels
|
|
16
|
+
* it (Bob 2026-06-13: "shouldn't it be a worker for any such operation").
|
|
17
|
+
*
|
|
18
|
+
* **DB.** Opens with `{skipMigrations:true}` — main built the schema before we
|
|
19
|
+
* spawned. WAL + busy_timeout let this writer and the main thread's
|
|
20
|
+
* local-first writer coexist; the read-worker reads concurrently.
|
|
21
|
+
*
|
|
22
|
+
* **RPC.** One generic handler: the proxy sends `{method, args}` and we invoke
|
|
23
|
+
* `imapManager[method](...args)`. Return values must be structured-clone-safe
|
|
24
|
+
* (they are — JSON-ish status objects, tokens, bodies-as-strings). Methods
|
|
25
|
+
* that hand back live objects (createPublicClient) are NOT called this way;
|
|
26
|
+
* the service uses dedicated server-side folder-op methods instead.
|
|
27
|
+
*
|
|
28
|
+
* **Events.** We wrap `imapManager.emit` to also `bus.publish("sync:event")`,
|
|
29
|
+
* so every event ImapManager/Reconciler raise on this thread reaches the main
|
|
30
|
+
* proxy, which re-emits them locally for bin's WebView forwarders.
|
|
31
|
+
*/
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=sync-worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-worker.d.ts","sourceRoot":"","sources":["sync-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG"}
|