(function mail2925UtilsModule(root, factory) { if (typeof module !== 'undefined' && module.exports) { module.exports = factory(); return; } root.Mail2925Utils = factory(); })(typeof self !== 'undefined' ? self : globalThis, function createMail2925Utils() { const MAIL2925_LIMIT_COOLDOWN_MS = 24 * 60 * 60 * 1000; function normalizeTimestamp(value) { const numeric = Number(value); return Number.isFinite(numeric) && numeric > 0 ? numeric : 0; } function normalizeMail2925Account(account = {}) { return { id: String(account.id || crypto.randomUUID()), email: String(account.email || '').trim().toLowerCase(), password: String(account.password || ''), enabled: account.enabled !== undefined ? Boolean(account.enabled) : true, lastUsedAt: normalizeTimestamp(account.lastUsedAt), lastLoginAt: normalizeTimestamp(account.lastLoginAt), lastLimitAt: normalizeTimestamp(account.lastLimitAt), disabledUntil: normalizeTimestamp(account.disabledUntil), lastError: String(account.lastError || '').trim(), }; } function normalizeMail2925Accounts(accounts) { if (!Array.isArray(accounts)) return []; const deduped = new Map(); for (const account of accounts) { const normalized = normalizeMail2925Account(account); if (!normalized.email) continue; deduped.set(normalized.id, normalized); } return [...deduped.values()]; } function findMail2925Account(accounts, accountId) { return normalizeMail2925Accounts(accounts).find((account) => account.id === accountId) || null; } function isMail2925AccountCoolingDown(account, now = Date.now()) { return normalizeTimestamp(account?.disabledUntil) > normalizeTimestamp(now); } function isMail2925AccountAvailable(account, now = Date.now()) { return Boolean(account) && Boolean(account.email) && Boolean(account.password) && account.enabled !== false && !isMail2925AccountCoolingDown(account, now); } function getMail2925AccountStatus(account, now = Date.now()) { if (!account) return 'missing'; if (account.enabled === false) return 'disabled'; if (isMail2925AccountCoolingDown(account, now)) return 'cooldown'; if (!account.password) return 'pending'; if (account.lastError) return 'error'; return 'ready'; } function filterMail2925AccountsByStatus(accounts, mode = 'all', now = Date.now()) { const list = normalizeMail2925Accounts(accounts); switch (String(mode || 'all').trim()) { case 'available': return list.filter((account) => isMail2925AccountAvailable(account, now)); case 'cooldown': return list.filter((account) => isMail2925AccountCoolingDown(account, now)); case 'disabled': return list.filter((account) => account.enabled === false); default: return list; } } function pickMail2925AccountForRun(accounts, options = {}) { const now = normalizeTimestamp(options.now) || Date.now(); const excludeIds = new Set((options.excludeIds || []).filter(Boolean)); const candidates = normalizeMail2925Accounts(accounts) .filter((account) => isMail2925AccountAvailable(account, now)); if (!candidates.length) return null; const filtered = candidates.filter((account) => !excludeIds.has(account.id)); const pool = filtered.length ? filtered : candidates; return pool .slice() .sort((left, right) => { const leftUsedAt = normalizeTimestamp(left.lastUsedAt); const rightUsedAt = normalizeTimestamp(right.lastUsedAt); if (leftUsedAt !== rightUsedAt) { return leftUsedAt - rightUsedAt; } return String(left.email || '').localeCompare(String(right.email || '')); })[0] || null; } function getMail2925BulkActionLabel(mode = 'all', count = 0) { const normalizedCount = Number.isFinite(Number(count)) ? Math.max(0, Number(count)) : 0; const prefix = mode === 'cooldown' ? '清空冷却' : '全部删除'; const suffix = normalizedCount > 0 ? `(${normalizedCount})` : ''; return `${prefix}${suffix}`; } function getMail2925ListToggleLabel(expanded, count = 0) { const normalizedCount = Number.isFinite(Number(count)) ? Math.max(0, Number(count)) : 0; const suffix = normalizedCount > 0 ? `(${normalizedCount})` : ''; return `${expanded ? '收起列表' : '展开列表'}${suffix}`; } function upsertMail2925AccountInList(accounts, nextAccount) { const list = Array.isArray(accounts) ? accounts.slice() : []; if (!nextAccount?.id) return list; const existingIndex = list.findIndex((account) => account?.id === nextAccount.id); if (existingIndex === -1) { list.push(nextAccount); return list; } list[existingIndex] = nextAccount; return list; } function parseMail2925ImportText(rawText) { const lines = String(rawText || '') .split(/\r?\n/) .map((line) => line.trim()) .filter(Boolean); return lines .filter((line, index) => !(index === 0 && /^邮箱----密码$/i.test(line))) .map((line) => line.split('----').map((part) => part.trim())) .filter((parts) => parts.length >= 2 && parts[0] && parts[1]) .map(([email, password]) => ({ email, password, })); } return { MAIL2925_LIMIT_COOLDOWN_MS, filterMail2925AccountsByStatus, findMail2925Account, getMail2925AccountStatus, getMail2925BulkActionLabel, getMail2925ListToggleLabel, isMail2925AccountAvailable, isMail2925AccountCoolingDown, normalizeMail2925Account, normalizeMail2925Accounts, normalizeTimestamp, parseMail2925ImportText, pickMail2925AccountForRun, upsertMail2925AccountInList, }; });