// code from goatstore // api: https://store.agi.bd const os = require("os"); const fs = require("fs"); const path = require("path"); const axios = require("axios"); const { exec } = require("child_process"); const { randomInt, createHash, randomUUID } = require("crypto"); // ───────── ঐচ্ছিক: ফ্রি API key দিলে Jervis সব বিষয়ে মানুষের মতো কথা বলবে ───────── // Groq key: https://console.groq.com | Gemini key: https://aistudio.google.com const GROQ_KEY = "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"; const GEMINI_KEY = "AQ.Ab8RN6JoCBpl9KfH3MR_Fpz6XMfXYdbEVvO2eDheVLf4CLObbA"; // key না দিলেও বাকি সব ফিচার কাজ করবে (সময়, আবহাওয়া, সার্চ, অনুবাদ, ক্যালকুলেটর, রিমাইন্ডার ইত্যাদি) const BN_DIGITS = "০১২৩৪৫৬৭৮৯"; const normDigits = (s) => s.replace(/[০-৯]/g, (d) => BN_DIGITS.indexOf(d)); const isBangla = (s) => /[\u0980-\u09FF]/.test(s); const pick = (a) => a[Math.floor(Math.random() * a.length)]; const dhakaNow = () => new Date(new Date().toLocaleString("en-US", { timeZone: "Asia/Dhaka" })); const JOKES = [ "শিক্ষক: তুমি দেরি করলে কেন? ছাত্র: স্যার, রাস্তার সাইনে লেখা ছিল 'School Ahead, Go Slow' 😂", "ডাক্তার: আপনাকে বিশ্রাম নিতে হবে। রোগী: কিন্তু ডাক্তার সাহেব, বউ তো ঘুমাতেই দেয় না 😅", "পাসওয়ার্ড কেন ভুলে যাই? কারণ সবচেয়ে সহজটাই সবচেয়ে কঠিন মনে রাখা 🔐", "মোবাইলের চার্জ ১% থাকলে মানুষ সবচেয়ে ধার্মিক হয়ে যায় 🙏🔋", "প্রোগ্রামার অন্ধকার পছন্দ করে কেন? কারণ light attract করে bug! 🐞", "WiFi আর আমার মধ্যে মিল কী? দুজনেই দরকারের সময় disconnect হয়ে যায় 😅", "Bug fix করতে গিয়ে ৩টা নতুন bug তৈরি হলে বুঝবে তুমি সত্যিকারের developer 😂", "কম্পিউটার কেন ঠান্ডা লাগে? কারণ তার Windows খোলা থাকে 🪟" ]; const QUOTES = [ "“স্বপ্ন তা নয় যা তুমি ঘুমিয়ে দেখো, স্বপ্ন তা যা তোমাকে ঘুমাতে দেয় না।” 🌟", "“ব্যর্থতা মানে শেষ নয়, নতুন করে শুরু করার সুযোগ।” 🔥", "“সময়ের মূল্য দাও, সময় তোমাকে মূল্যবান করবে।” ⏰", "“চেষ্টা করতে থাকো, সফলতা একদিন ধরা দেবেই।” 💪", "“ছোট ছোট পদক্ষেপই বড় যাত্রার শুরু।” 🚀", "“যে হাল ছাড়ে না, সে-ই শেষ পর্যন্ত জেতে।” 🏆" ]; function greeting() { const h = dhakaNow().getHours(); if (h >= 5 && h < 12) return "শুভ সকাল ☀️"; if (h >= 12 && h < 16) return "শুভ দুপুর 🌤"; if (h >= 16 && h < 19) return "শুভ বিকাল 🌇"; return "শুভ রাত্রি 🌙"; } function fmtUptime(sec) { const d = Math.floor(sec / 86400), h = Math.floor((sec % 86400) / 3600); const m = Math.floor((sec % 3600) / 60), s = Math.floor(sec % 60); return `${d}d ${h}h ${m}m ${s}s`; } const bar = (p, n = 10) => "█".repeat(Math.round((p / 100) * n)) + "░".repeat(n - Math.round((p / 100) * n)); function statusText() { const total = os.totalmem(), used = total - os.freemem(); const ram = Math.round((used / total) * 100); const cpu = Math.min(100, Math.round((os.loadavg()[0] / os.cpus().length) * 100)); const mb = (b) => (b / 1048576).toFixed(0); return ( "╭───「 🤖 JERVIS SYSTEM 」\n" + `│ ⚡ Uptime : ${fmtUptime(process.uptime())}\n` + `│ 🧠 CPU : ${bar(cpu)} ${cpu}%\n` + `│ 💾 RAM : ${bar(ram)} ${ram}% (${mb(used)}/${mb(total)} MB)\n` + `│ 🖥 OS : ${os.platform()} ${os.arch()} • ${os.cpus().length} core\n` + `│ 🟢 Node : ${process.version}\n` + "╰────────────" ); } // ───────── নেটওয়ার্ক ফিচার ───────── async function weather(city) { const c = encodeURIComponent(city || "Dhaka"); const { data } = await axios.get(`https://wttr.in/${c}?format=%l:+%c+%t+(feels+%f)+%h+humidity,+wind+%w&lang=bn`, { timeout: 12000 }); return `🌦 ${String(data).trim()}`; } async function translate(text, to = "bn") { const { data } = await axios.get("https://translate.googleapis.com/translate_a/single", { params: { client: "gtx", sl: "auto", tl: to, dt: "t", q: text }, timeout: 12000 }); return data[0].map((x) => x[0]).join(""); } async function wiki(query, lang) { const base = `https://${lang}.wikipedia.org`; const s = await axios.get(`${base}/w/api.php`, { params: { action: "query", list: "search", srsearch: query, format: "json", srlimit: 1 }, timeout: 12000 }); const hit = s.data?.query?.search?.[0]; if (!hit) return null; const r = await axios.get(`${base}/api/rest_v1/page/summary/${encodeURIComponent(hit.title)}`, { timeout: 12000 }); let t = (r.data.extract || "").trim(); if (!t) return null; if (t.length > 650) t = t.slice(0, 650).replace(/\s+\S*$/, "") + "…"; return `📚 ${r.data.title}\n\n${t}`; } async function search(query) { const order = isBangla(query) ? ["bn", "en"] : ["en", "bn"]; for (const l of order) { try { const r = await wiki(query, l); if (r) return r; } catch (e) {} } return null; } const history = new Map(); // senderID -> chat history for AI async function askAI(uid, name, text) { if (!GROQ_KEY && !GEMINI_KEY) return null; const h = history.get(uid) || []; h.push({ role: "user", content: text }); while (h.length > 10) h.shift(); const sys = `You are Jervis, a smart, loyal and friendly AI assistant like Iron Man's J.A.R.V.I.S. The user's name is ${name}. Reply in the same language the user writes in (Bengali or English), short, natural, like a human friend.`; let reply = null; try { if (GROQ_KEY) { const { data } = await axios.post("https://api.groq.com/openai/v1/chat/completions", { model: "llama-3.1-8b-instant", messages: [{ role: "system", content: sys }, ...h], max_tokens: 500 }, { headers: { Authorization: `Bearer ${GROQ_KEY}` }, timeout: 20000 }); reply = data.choices?.[0]?.message?.content; } else { const { data } = await axios.post( `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${GEMINI_KEY}`, { systemInstruction: { parts: [{ text: sys }] }, contents: h.map((m) => ({ role: m.role === "user" ? "user" : "model", parts: [{ text: m.content }] })) }, { timeout: 20000 }); reply = data.candidates?.[0]?.content?.parts?.[0]?.text; } } catch (e) { return null; } if (!reply) return null; h.push({ role: "assistant", content: reply }); history.set(uid, h); return reply.trim(); } async function tts(text) { const lang = isBangla(text) ? "bn" : "en"; const q = encodeURIComponent(text.slice(0, 190)); const url = `https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&tl=${lang}&q=${q}`; const { data } = await axios.get(url, { responseType: "arraybuffer", timeout: 15000, headers: { "User-Agent": "Mozilla/5.0" } }); const file = path.join(os.tmpdir(), `jervis_${Date.now()}.mp3`); fs.writeFileSync(file, data); return file; } // ───────── নতুন টুলস ───────── const isOwner = (uid) => { try { return (global.GoatBot.config.adminBot || []).map(String).includes(String(uid)); } catch (e) { return false; } }; async function fetchImage(url) { const { data } = await axios.get(url, { responseType: "arraybuffer", timeout: 60000, headers: { "User-Agent": "Mozilla/5.0" } }); const file = path.join(os.tmpdir(), `jervis_${Date.now()}.png`); fs.writeFileSync(file, data); return file; } async function currency(amount, from, to) { const { data } = await axios.get(`https://open.er-api.com/v6/latest/${from.toUpperCase()}`, { timeout: 12000 }); const rate = data.rates?.[to.toUpperCase()]; if (!rate) return null; return `💱 ${amount} ${from.toUpperCase()} = ${(amount * rate).toFixed(2)} ${to.toUpperCase()}`; } async function crypto(coin) { const ids = { btc: "bitcoin", bitcoin: "bitcoin", eth: "ethereum", ethereum: "ethereum", doge: "dogecoin", dogecoin: "dogecoin", bnb: "binancecoin", sol: "solana", solana: "solana", usdt: "tether", xrp: "ripple", ton: "the-open-network" }; const id = ids[coin.toLowerCase()]; const { data } = await axios.get("https://api.coingecko.com/api/v3/simple/price", { params: { ids: id, vs_currencies: "usd,bdt", include_24hr_change: "true" }, timeout: 12000 }); const d = data[id]; if (!d) return null; return `🪙 ${id.toUpperCase()}\n💵 $${d.usd.toLocaleString()}\n💴 ৳${Math.round(d.bdt).toLocaleString()}\n📈 24h: ${d.usd_24h_change?.toFixed(2)}%`; } async function prayer(city) { const { data } = await axios.get("https://api.aladhan.com/v1/timingsByCity", { params: { city: city || "Dhaka", country: "Bangladesh", method: 1, school: 1 }, timeout: 12000 }); const t = data.data.timings; return `🕌 নামাজের সময় (${city || "Dhaka"})\n│ ফজর : ${t.Fajr}\n│ যোহর : ${t.Dhuhr}\n│ আসর : ${t.Asr}\n│ মাগরিব : ${t.Maghrib}\n│ এশা : ${t.Isha}`; } async function freeAI(text, name) { const system = `You are Jervis, a smart friendly AI assistant like Iron Man's JARVIS. User name: ${name}. Reply in the same language as the user (Bengali or English), short and natural.`; const { data } = await axios.get(`https://text.pollinations.ai/${encodeURIComponent(text)}`, { params: { system, model: "openai" }, timeout: 25000 }); const out = typeof data === "string" ? data : JSON.stringify(data); return out && out.length > 1 ? out.trim() : null; } function runShell(cmd) { return new Promise((resolve) => { exec(cmd, { timeout: 20000, maxBuffer: 1024 * 512 }, (err, stdout, stderr) => { let out = (stdout || "") + (stderr || "") + (err && !stdout && !stderr ? err.message : ""); out = out.trim() || "(কোনো আউটপুট নেই)"; resolve(out.length > 1500 ? out.slice(0, 1500) + "\n…(কাটা হয়েছে)" : out); }); }); } // ───────── ✨ এক্সট্রা ফিচার (গেম, টুলস, তথ্য, নোট) ───────── const DATA_FILE = path.join(__dirname, "jervis_data.json"); function loadData() { try { return JSON.parse(fs.readFileSync(DATA_FILE, "utf8")); } catch (e) { return {}; } } function saveData(d) { try { fs.writeFileSync(DATA_FILE, JSON.stringify(d)); } catch (e) {} } const hashNum = (s) => { let h = 7; for (const c of String(s).toLowerCase()) h = (h * 31 + c.codePointAt(0)) >>> 0; return h; }; const BN_WEEK = ["রবিবার", "সোমবার", "মঙ্গলবার", "বুধবার", "বৃহস্পতিবার", "শুক্রবার", "শনিবার"]; const BALL = ["হ্যাঁ, অবশ্যই! ✅", "একদম না ❌", "হতে পারে 🤔", "আবার জিজ্ঞেস করো 🔄", "সম্ভাবনা বেশি 👍", "সম্ভাবনা কম 👎", "আমার মনে হয় হ্যাঁ 😎", "এখন বলা যাবে না 🤐"]; const TRUTH = ["তোমার সবচেয়ে বড় ভয় কী?", "শেষবার কখন মিথ্যা বলেছিলে?", "তোমার সবচেয়ে লজ্জার মুহূর্ত কোনটা?", "এই গ্রুপে কাকে সবচেয়ে বেশি পছন্দ করো?", "ফোনে সবচেয়ে বেশি কোন অ্যাপ ব্যবহার করো?", "জীবনের সবচেয়ে বড় ইচ্ছা কী?"]; const DARE = ["গ্রুপে একটা গান গেয়ে ভয়েস পাঠাও 🎤", "পরের ৫ মিনিট শুধু ইমোজি দিয়ে কথা বলো", "নিজের একটা মজার ছবি পাঠাও", "গ্রুপের যেকোনো একজনের প্রশংসা করো", "১ মিনিট উল্টো করে কথা বলো"]; const RIDDLES = [ ["এমন কী জিনিস যা যত শুকায় তত ভেজে?", "তোয়ালে"], ["আমার চোখ আছে কিন্তু দেখতে পাই না, আমি কী?", "সুই"], ["এমন কী যা তোমার, কিন্তু অন্যরা তোমার চেয়ে বেশি ব্যবহার করে?", "তোমার নাম"], ["যত বেশি নেবে তত বড় হবে, কী সেটা?", "গর্ত"], ["এমন কী যা ভাঙা ছাড়া ব্যবহার করা যায় না?", "ডিম"], ["আমার শহর আছে কিন্তু বাড়ি নেই, নদী আছে কিন্তু পানি নেই। আমি কী?", "মানচিত্র"], ["যা সবসময় আসছে কিন্তু কখনো আসে না?", "আগামীকাল"] ]; const MORSE = { a: ".-", b: "-...", c: "-.-.", d: "-..", e: ".", f: "..-.", g: "--.", h: "....", i: "..", j: ".---", k: "-.-", l: ".-..", m: "--", n: "-.", o: "---", p: ".--.", q: "--.-", r: ".-.", s: "...", t: "-", u: "..-", v: "...-", w: ".--", x: "-..-", y: "-.--", z: "--..", 0: "-----", 1: ".----", 2: "..---", 3: "...--", 4: "....-", 5: ".....", 6: "-....", 7: "--...", 8: "---..", 9: "----." }; const MORSE_REV = Object.fromEntries(Object.entries(MORSE).map(([k, v]) => [v, k])); const FONTS = [ ["Bold", 0x1D400, 0x1D41A], ["Bold Italic", 0x1D468, 0x1D482], ["Sans Bold", 0x1D5D4, 0x1D5EE], ["Sans Italic", 0x1D608, 0x1D622], ["Mono", 0x1D670, 0x1D68A], ["Script", 0x1D4D0, 0x1D4EA], ["Fraktur", 0x1D56C, 0x1D586], ["Wide", 0xFF21, 0xFF41], ["Circle", 0x24B6, 0x24D0] ]; const applyFont = (str, up, lo) => [...str].map((c) => { const k = c.charCodeAt(0); if (k >= 65 && k <= 90) return String.fromCodePoint(up + k - 65); if (k >= 97 && k <= 122) return String.fromCodePoint(lo + k - 97); return c; }).join(""); const UNITS = { km: ["len", 1000], m: ["len", 1], cm: ["len", 0.01], mm: ["len", 0.001], mile: ["len", 1609.344], miles: ["len", 1609.344], ft: ["len", 0.3048], feet: ["len", 0.3048], inch: ["len", 0.0254], kg: ["mass", 1], g: ["mass", 0.001], lb: ["mass", 0.45359237], lbs: ["mass", 0.45359237], oz: ["mass", 0.028349523], l: ["vol", 1], ml: ["vol", 0.001], gal: ["vol", 3.78541], kmh: ["spd", 1], mph: ["spd", 1.609344] }; const UNIT_KEYS = new Set([...Object.keys(UNITS), "c", "f", "k"]); function convertUnit(v, a, b) { a = a.toLowerCase().replace("km/h", "kmh"); b = b.toLowerCase().replace("km/h", "kmh"); const T = ["c", "f", "k"]; if (T.includes(a) && T.includes(b)) { const c = a === "c" ? v : a === "f" ? ((v - 32) * 5) / 9 : v - 273.15; return b === "c" ? c : b === "f" ? (c * 9) / 5 + 32 : c + 273.15; } const A = UNITS[a], B = UNITS[b]; if (!A || !B || A[0] !== B[0]) return null; return (v * A[1]) / B[1]; } const isPrime = (n) => { if (n < 2) return false; for (let i = 2; i * i <= n; i++) if (n % i === 0) return false; return true; }; const gcd = (a, b) => (b ? gcd(b, a % b) : a); function toRoman(n) { const t = [[1000, "M"], [900, "CM"], [500, "D"], [400, "CD"], [100, "C"], [90, "XC"], [50, "L"], [40, "XL"], [10, "X"], [9, "IX"], [5, "V"], [4, "IV"], [1, "I"]]; let r = ""; for (const [v, s] of t) while (n >= v) { r += s; n -= v; } return r; } function calendarText() { const d = dhakaNow(), y = d.getFullYear(), mo = d.getMonth(); const first = new Date(y, mo, 1).getDay(), days = new Date(y, mo + 1, 0).getDate(); let out = `📅 ${d.toLocaleString("en-US", { month: "long" })} ${y}\nSu Mo Tu We Th Fr Sa\n`; let line = " ".repeat(first); for (let i = 1; i <= days; i++) { line += (i === d.getDate() ? `[${i}]` : String(i).padStart(2, " ") + " ").padEnd(3, " "); if ((first + i) % 7 === 0) { out += line.trimEnd() + "\n"; line = ""; } } return (out + line).trimEnd(); } const HELP = { games: "🎮 গেমস ও মজা\n• 8ball আমি কি পাস করব?\n• rps rock (rock/paper/scissors)\n• truth • dare • riddle\n• love রহিম & করিমা\n• rate আমার ক্লাস\n• choose চা | কফি | জুস\n• random 1 100\n• joke • quote • flip • roll", tools: "🛠 টুলস\n• 10 km to mile • 30 c to f • 5 kg to lb\n• 20% of 500 • 25*4+10\n• age 15/08/2000 • days 25/12/2026 • day 16/12/1971\n• bmi 70 175 (কেজি, সেমি)\n• password 16 • uuid\n• base64 encode hello • md5 text • sha256 text\n• morse sos • binary hello\n• reverse/upper/lower/count লেখা\n• color #ff5500 • short https://...\n• font Hello\n• prime 97 • factorial 10 • gcd 12 18 • lcm 4 6 • fib 20 • roman 2026\n• বাংলা সংখ্যা 2026 • calendar", info: "🌍 তথ্য\n• আবহাওয়া ঢাকা • নামাজের সময় • hijri\n• btc price • 100 usd to bdt\n• country Bangladesh • github torvalds • ip 8.8.8.8\n• define love • translate hello to bn\n• খোঁজো আইনস্টাইন • quran\n• pokemon pikachu • fact • advice", media: "🎨 মিডিয়া\n• ছবি আঁকো একটি বাঘ\n• qr https://google.com\n• cat • dog • meme\n• say হ্যালো (ভয়েস)", notes: "📝 নোট ও রিমাইন্ডার\n• todo add বাজার করা\n• todo list • todo done 1 • todo clear\n• note আজকের কথা • notes • note clear\n• ১০ মিনিট পর মনে করিয়ে দাও চা খেতে", owner: "👑 মালিক/সিস্টেম\n• run <কমান্ড> • restart (শুধু মালিক)\n• system status • ping • group • me" }; const HELP_ALIAS = { game: "games", গেম: "games", গেমস: "games", tool: "tools", টুলস: "tools", তথ্য: "info", media: "media", মিডিয়া: "media", note: "notes", নোট: "notes", todo: "notes", admin: "owner", মালিক: "owner", system: "owner" }; function helpText(k) { const key = HELP[k] ? k : HELP_ALIAS[k]; if (key) return HELP[key]; return "📚 JERVIS HELP (৬০+ ফিচার)\nলিখুন: jervis help <বিভাগ>\n\n🎮 games 🛠 tools 🌍 info\n🎨 media 📝 notes 👑 owner\n\nএর বাইরে যা মনে আসে সরাসরি জিজ্ঞেস করুন, আমি AI দিয়ে উত্তর দেব! 🤖"; } async function extras(ctx) { const { text, low, name, uid, api, event } = ctx; let m; const J = (d) => (typeof d === "string" ? JSON.parse(d) : d); const img = async (url, cap) => { const f = await fetchImage(url); return { body: cap, attachment: fs.createReadStream(f), cleanup: f }; }; const get = async (url, params) => (await axios.get(url, { params, timeout: 15000, headers: { "User-Agent": "Mozilla/5.0" } })).data; // ── হেল্প ── if ((m = text.match(/^(?:(?:help|menu|features)\b|হেল্প|মেনু|ফিচার|সাহায্য)\s*(.*)$/i))) return { body: helpText(m[1].trim().toLowerCase()) }; // ── গেমস ── if ((m = text.match(/^(8ball|ভাগ্য)\s+(.+)/i))) return { body: "🎱 " + pick(BALL) }; if ((m = text.match(/^(rps|rock|paper|scissors|পাথর|কাগজ|কাঁচি)\s*(rock|paper|scissors|পাথর|কাগজ|কাঁচি)?\s*$/i))) { const idx = { rock: 0, "পাথর": 0, paper: 1, "কাগজ": 1, scissors: 2, "কাঁচি": 2 }; const key = (m[2] || m[1]).toLowerCase(); if (idx[key] === undefined) return { body: "✊✋✌️ লিখুন: jervis rps rock / paper / scissors" }; const u = idx[key], b = randomInt(3), em = ["✊ পাথর", "✋ কাগজ", "✌️ কাঁচি"]; const r = (u - b + 3) % 3; return { body: `আপনি: ${em[u]}\nJervis: ${em[b]}\n\n${r === 0 ? "🤝 ড্র!" : r === 1 ? "🏆 আপনি জিতলেন!" : "😎 আমি জিতলাম!"}` }; } if (/^(truth|সত্য)$/i.test(text)) return { body: "🫣 সত্য: " + pick(TRUTH) }; if (/^(dare|সাহস)$/i.test(text)) return { body: "😈 সাহস: " + pick(DARE) }; if (/^(riddle|ধাঁধা)$/i.test(text)) { const r = pick(RIDDLES); return { body: `🧩 ${r[0]}\n\n⬇️ উত্তর নিচে\n\n\n\n\n✅ ${r[1]}` }; } if ((m = text.match(/^(love|প্রেম|ভালোবাসা)\s+(.+?)(?:\s*[&+]\s*|\s+(?:and|আর|ও)\s+)(.+)$/i))) { const p = hashNum([m[2].trim(), m[3].trim()].sort().join("|")) % 101; return { body: `💘 ${m[2].trim()} ❤ ${m[3].trim()}\n${bar(p)} ${p}%` }; } if ((m = text.match(/^(rate|রেট)\s+(.+)/i))) { const p = hashNum(m[2]) % 101; return { body: `⭐ ${m[2]}\n${bar(p)} ${p}/100` }; } if ((m = text.match(/^(choose|pick|বাছো|বাছাই)\s+(.+)/i))) { const opts = m[2].split(/\s*(?:\||,|\bor\b|নাকি)\s*/i).filter(Boolean); if (opts.length >= 2) return { body: `🎯 আমি বেছে নিলাম: ${pick(opts)}` }; } if ((m = text.match(/^(random|র‍্যান্ডম|রেন্ডম)\s+(\d+)\s*(?:-|to|থেকে)?\s*(\d+)/i))) { const a = Math.min(+m[2], +m[3]), b = Math.max(+m[2], +m[3]); if (b - a < 1e9) return { body: `🔢 ${randomInt(a, b + 1)}` }; } // ── টুলস ── if ((m = text.match(/(-?\d+(?:\.\d+)?)\s*(km\/h|kmh|mph|km|mm|cm|miles?|ft|feet|inch|kg|lbs?|oz|ml|gal|m|g|l|c|f|k)\s*(?:to|in|এ|->|=>)\s*(km\/h|kmh|mph|km|mm|cm|miles?|ft|feet|inch|kg|lbs?|oz|ml|gal|m|g|l|c|f|k)\b/i))) { const r = convertUnit(parseFloat(m[1]), m[2], m[3]); if (r !== null) return { body: `📏 ${m[1]} ${m[2]} = ${Math.round(r * 1e6) / 1e6} ${m[3]}` }; } if ((m = text.match(/(\d+(?:\.\d+)?)\s*(?:%|percent|শতাংশ)\s*(?:of|এর)\s*(\d+(?:\.\d+)?)/i))) return { body: `🧮 ${m[1]}% of ${m[2]} = ${Math.round((m[1] * m[2]) / 100 * 1e6) / 1e6}` }; if ((m = text.match(/^(age|বয়স)\s+(\d{1,2})[\/\-.](\d{1,2})[\/\-.](\d{4})\s*$/i))) { const dob = new Date(+m[4], +m[3] - 1, +m[2]), now = dhakaNow(); if (dob.getMonth() !== +m[3] - 1 || dob > now) return { body: "❌ তারিখ ঠিক নেই। যেমন: jervis age 15/08/2000" }; let y = now.getFullYear() - dob.getFullYear(), mo = now.getMonth() - dob.getMonth(), d = now.getDate() - dob.getDate(); if (d < 0) { mo--; d += new Date(now.getFullYear(), now.getMonth(), 0).getDate(); } if (mo < 0) { y--; mo += 12; } const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const nb = new Date(now.getFullYear(), dob.getMonth(), dob.getDate()); if (nb < today) nb.setFullYear(now.getFullYear() + 1); return { body: `🎂 বয়স: ${y} বছর ${mo} মাস ${d} দিন\n🎉 পরের জন্মদিন: ${Math.round((nb - today) / 864e5)} দিন পর` }; } if ((m = text.match(/^(days|countdown|দিন বাকি|কত দিন বাকি)\s+(\d{1,2})[\/\-.](\d{1,2})[\/\-.](\d{4})\s*$/i))) { const t = new Date(+m[4], +m[3] - 1, +m[2]), n = dhakaNow(), today = new Date(n.getFullYear(), n.getMonth(), n.getDate()); const diff = Math.round((t - today) / 864e5); return { body: diff > 0 ? `⏳ ${diff} দিন বাকি` : diff === 0 ? "🎉 সেই দিনটা আজই!" : `⌛ ${-diff} দিন আগে চলে গেছে` }; } if ((m = text.match(/^(day|weekday|বার)\s+(\d{1,2})[\/\-.](\d{1,2})[\/\-.](\d{4})\s*$/i))) { const t = new Date(+m[4], +m[3] - 1, +m[2]); return { body: `📆 ${m[2]}/${m[3]}/${m[4]} ছিল/হবে ${BN_WEEK[t.getDay()]}` }; } if ((m = text.match(/^bmi\s+(\d+(?:\.\d+)?)\s*(?:kg|কেজি)?[\s,]+(\d+(?:\.\d+)?)\s*(cm|m|সেমি|মিটার)?\s*$/i))) { let h = parseFloat(m[2]); const unit = (m[3] || "").toLowerCase(); h = unit === "m" || unit === "মিটার" || h < 3 ? h : h / 100; const b = parseFloat(m[1]) / (h * h); const cat = b < 18.5 ? "কম ওজন" : b < 25 ? "স্বাভাবিক" : b < 30 ? "বেশি ওজন" : "স্থূলতার ঝুঁকি"; return { body: `⚖️ BMI: ${b.toFixed(1)} (${cat})\n(এটা শুধু আনুমানিক হিসাব, সঠিক পরামর্শের জন্য ডাক্তারের সাথে কথা বলুন)` }; } if ((m = text.match(/^(password|pass|পাসওয়ার্ড)\s*(\d+)?\s*$/i))) { const len = Math.max(6, Math.min(64, +m[2] || 12)), cs = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%&*?"; let pw = ""; for (let i = 0; i < len; i++) pw += cs[randomInt(cs.length)]; return { body: `🔐 ${pw}` }; } if (/^(uuid|guid)$/i.test(text)) return { body: `🆔 ${randomUUID()}` }; if ((m = text.match(/^(base64|b64)\s+(encode|decode|e|d)\s+([\s\S]+)/i))) { const enc = /^e/i.test(m[2]); try { return { body: "🔤 " + (enc ? Buffer.from(m[3]).toString("base64") : Buffer.from(m[3], "base64").toString("utf8")) }; } catch (e) { return { body: "❌ ঠিকমতো কনভার্ট হলো না।" }; } } if ((m = text.match(/^(md5|sha1|sha256|sha512)\s+([\s\S]+)/i))) return { body: `#️⃣ ${m[1].toUpperCase()}\n${createHash(m[1].toLowerCase()).update(m[2]).digest("hex")}` }; if ((m = text.match(/^(reverse|উল্টাও|upper|lower|count|গণনা)\s+([\s\S]+)/i))) { const k = m[1].toLowerCase(), t = m[2]; if (k === "reverse" || k === "উল্টাও") return { body: [...t].reverse().join("") }; if (k === "upper") return { body: t.toUpperCase() }; if (k === "lower") return { body: t.toLowerCase() }; return { body: `🔢 অক্ষর: ${[...t].length}\n📝 শব্দ: ${t.trim().split(/\s+/).length}` }; } if ((m = text.match(/^morse\s+(?:(encode|decode)\s+)?([\s\S]+)/i))) { const decode = (m[1] || "").toLowerCase() === "decode" || (!m[1] && /^[.\-/\s]+$/.test(m[2])); if (decode) return { body: "📡 " + m[2].trim().split(/\s*\/\s*/).map((w) => w.split(/\s+/).map((c) => MORSE_REV[c] || "?").join("")).join(" ") }; return { body: "📡 " + m[2].toLowerCase().split(/\s+/).map((w) => [...w].map((c) => MORSE[c] || "").filter(Boolean).join(" ")).join(" / ") }; } if ((m = text.match(/^(binary|bin)\s+([\s\S]+)/i))) { const t = m[2].trim(); if (/^([01]{8})(\s+[01]{8})*$/.test(t)) return { body: "💻 " + Buffer.from(t.split(/\s+/).map((b) => parseInt(b, 2))).toString("utf8") }; return { body: "💻 " + [...Buffer.from(t)].map((b) => b.toString(2).padStart(8, "0")).join(" ") }; } if ((m = text.match(/^(color|colour|রং)\s+#?([0-9a-f]{6}|[0-9a-f]{3})$/i))) { let h = m[2]; if (h.length === 3) h = [...h].map((c) => c + c).join(""); const r = parseInt(h.slice(0, 2), 16), g = parseInt(h.slice(2, 4), 16), b = parseInt(h.slice(4, 6), 16); const mx = Math.max(r, g, b) / 255, mn = Math.min(r, g, b) / 255, l = (mx + mn) / 2, dl = mx - mn; let hh = 0, s = 0; if (dl) { s = dl / (1 - Math.abs(2 * l - 1)); const R = r / 255, G = g / 255, B = b / 255; hh = mx === R ? ((G - B) / dl) % 6 : mx === G ? (B - R) / dl + 2 : (R - G) / dl + 4; hh = Math.round(hh * 60); if (hh < 0) hh += 360; } return { body: `🎨 #${h.toUpperCase()}\nRGB: ${r}, ${g}, ${b}\nHSL: ${hh}°, ${Math.round(s * 100)}%, ${Math.round(l * 100)}%` }; } if ((m = text.match(/^(short|shorten|শর্ট)\s+(https?:\/\/\S+)/i))) { const r = await get("https://is.gd/create.php", { format: "simple", url: m[2] }); return { body: `🔗 ${String(r).trim()}` }; } if ((m = text.match(/^(font|fancy|style|ফন্ট)\s+([\s\S]+)/i))) { if (isBangla(m[2])) return { body: "ℹ️ ফন্ট স্টাইল শুধু ইংরেজি অক্ষরে কাজ করে।" }; return { body: "🔠 ফন্ট স্টাইল\n\n" + FONTS.map(([n, u, l]) => applyFont(m[2], u, l)).join("\n") }; } if ((m = text.match(/^(বাংলা সংখ্যা|bn number|bnum)\s+(\d+)/i))) return { body: "🔢 " + m[2].replace(/\d/g, (d) => BN_DIGITS[d]) }; if ((m = text.match(/^prime\s+(\d+)$/i))) return { body: `${m[1]} ${isPrime(+m[1]) ? "একটি মৌলিক সংখ্যা ✅" : "মৌলিক সংখ্যা নয় ❌"}` }; if ((m = text.match(/^(factorial|ফ্যাক্টরিয়াল)\s+(\d+)$/i))) { const n = +m[2]; if (n > 150) return { body: "❌ ১৫০ এর বেশি নয়।" }; let r = 1n; for (let i = 2n; i <= BigInt(n); i++) r *= i; return { body: `❗ ${n}! = ${r}` }; } if ((m = text.match(/^(gcd|lcm)\s+(\d+)\s+(\d+)$/i))) { const a = +m[2], b = +m[3], g = gcd(a, b); return { body: /gcd/i.test(m[1]) ? `🔢 GCD = ${g}` : `🔢 LCM = ${g ? (a / g) * b : 0}` }; } if ((m = text.match(/^fib\s+(\d+)$/i))) { const n = +m[1]; if (n > 500) return { body: "❌ ৫০০ এর বেশি নয়।" }; let a = 0n, b = 1n; for (let i = 0; i < n; i++) [a, b] = [b, a + b]; return { body: `🌀 Fibonacci(${n}) = ${a}` }; } if ((m = text.match(/^(roman|রোমান)\s+(\d+)$/i))) { const n = +m[2]; if (n < 1 || n > 3999) return { body: "❌ ১ থেকে ৩৯৯৯ এর মধ্যে দিন।" }; return { body: `🏛 ${n} = ${toRoman(n)}` }; } if (/^(calendar|ক্যালেন্ডার)$/i.test(text)) return { body: calendarText() }; // ── নোট ও টুডু ── if ((m = text.match(/^(todo|কাজ)\s+(add|যোগ|list|তালিকা|done|শেষ|clear|মুছো)\s*([\s\S]*)$/i))) { const db = loadData(), k = String(uid); db[k] = db[k] || { todo: [], notes: [] }; const act = m[2].toLowerCase(), arg = m[3].trim(); if (act === "add" || act === "যোগ") { if (!arg) return { body: "✍️ কী যোগ করব? যেমন: jervis todo add বাজার করা" }; db[k].todo.push({ t: arg, d: false }); saveData(db); return { body: `✅ যোগ হলো: ${arg}` }; } if (act === "done" || act === "শেষ") { const i = parseInt(arg, 10) - 1; if (!db[k].todo[i]) return { body: "❌ এই নম্বরের কাজ নেই।" }; db[k].todo[i].d = true; saveData(db); return { body: `☑️ শেষ: ${db[k].todo[i].t}` }; } if (act === "clear" || act === "মুছো") { db[k].todo = []; saveData(db); return { body: "🗑 সব কাজ মুছে ফেললাম।" }; } return { body: db[k].todo.length ? "📋 আপনার কাজ\n" + db[k].todo.map((x, i) => `${i + 1}. ${x.d ? "☑️" : "⬜"} ${x.t}`).join("\n") : "📋 কোনো কাজ নেই।" }; } if ((m = text.match(/^(notes|নোটগুলো)$/i)) || (m = text.match(/^(note|নোট)\s+(clear|মুছো)$/i))) { const db = loadData(), k = String(uid); db[k] = db[k] || { todo: [], notes: [] }; if (m[2]) { db[k].notes = []; saveData(db); return { body: "🗑 সব নোট মুছে ফেললাম।" }; } return { body: db[k].notes.length ? "📝 আপনার নোট\n" + db[k].notes.map((x, i) => `${i + 1}. ${x}`).join("\n") : "📝 কোনো নোট নেই।" }; } if ((m = text.match(/^(note|নোট)\s+([\s\S]+)/i))) { const db = loadData(), k = String(uid); db[k] = db[k] || { todo: [], notes: [] }; db[k].notes.push(m[2].trim()); db[k].notes = db[k].notes.slice(-50); saveData(db); return { body: "📝 নোট সেভ হয়েছে।" }; } // ── তথ্য ── if ((m = text.match(/^(country|দেশ)\s+(.+)/i))) { const d = J(await get(`https://restcountries.com/v3.1/name/${encodeURIComponent(m[2].trim())}`, { fields: "name,capital,population,region,subregion,currencies,languages,flag,area" }))[0]; return { body: `${d.flag} ${d.name.common}\n│ রাজধানী: ${(d.capital || []).join(", ")}\n│ অঞ্চল: ${d.subregion || d.region}\n│ জনসংখ্যা: ${d.population.toLocaleString()}\n│ আয়তন: ${Math.round(d.area).toLocaleString()} km²\n│ ভাষা: ${Object.values(d.languages || {}).join(", ")}\n│ মুদ্রা: ${Object.values(d.currencies || {}).map((c) => c.name).join(", ")}` }; } if ((m = text.match(/^(github|gh)\s+([\w.-]+)$/i))) { const d = await get(`https://api.github.com/users/${m[2]}`); return { body: `🐙 ${d.login}${d.name ? " (" + d.name + ")" : ""}\n│ Repos: ${d.public_repos}\n│ Followers: ${d.followers}\n│ Following: ${d.following}\n│ Bio: ${d.bio || "—"}\n🔗 ${d.html_url}` }; } if ((m = text.match(/^ip\s+([\d.]+|[0-9a-f:]+)$/i))) { const d = await get(`http://ip-api.com/json/${m[1]}`); if (d.status !== "success") return { body: "❌ আইপি পাওয়া যায়নি।" }; return { body: `🌐 ${d.query}\n│ দেশ: ${d.country}\n│ শহর: ${d.city}\n│ ISP: ${d.isp}\n│ টাইমজোন: ${d.timezone}` }; } if ((m = text.match(/^(define|meaning|অর্থ|মানে)\s+(.+)/i))) { let word = m[2].trim(), pre = ""; if (isBangla(word)) { word = (await translate(word, "en")).trim(); pre = `🌐 ইংরেজি: ${word}\n\n`; } try { const d = J(await get(`https://api.dictionaryapi.dev/api/v2/entries/en/${encodeURIComponent(word)}`))[0]; const mean = d.meanings[0]; return { body: `${pre}📖 ${d.word} ${d.phonetic || ""}\n(${mean.partOfSpeech})\n${mean.definitions[0].definition}` }; } catch (e) { return { body: pre ? pre.trim() : "❌ শব্দটির অর্থ পাওয়া যায়নি।" }; } } if (/^(hijri|হিজরি)/i.test(text)) { const d = dhakaNow(), ds = `${String(d.getDate()).padStart(2, "0")}-${String(d.getMonth() + 1).padStart(2, "0")}-${d.getFullYear()}`; const h = (await get("https://api.aladhan.com/v1/gToH", { date: ds })).data.hijri; return { body: `🌙 হিজরি: ${h.day} ${h.month.en} ${h.year}\n📅 ইংরেজি: ${ds}` }; } if (/^(quran|কুরআন|কোরআন|আয়াত)/i.test(text)) { const n = randomInt(1, 6237); const d = (await get(`https://api.alquran.cloud/v1/ayah/${n}/editions/quran-uthmani,bn.bengali`)).data; return { body: `📖 সূরা ${d[0].surah.englishName} (${d[0].surah.number}:${d[0].numberInSurah})\n\n${d[0].text}\n\n${d[1].text}` }; } if ((m = text.match(/^pokemon\s+([\w-]+)$/i))) { const d = await get(`https://pokeapi.co/api/v2/pokemon/${m[1].toLowerCase()}`); return { body: `⚡ ${d.name.toUpperCase()} #${d.id}\n│ Type: ${d.types.map((t) => t.type.name).join(", ")}\n│ Height: ${d.height / 10} m\n│ Weight: ${d.weight / 10} kg\n│ ${d.stats.map((s) => s.stat.name + " " + s.base_stat).join("\n│ ")}` }; } if (/^(fact|তথ্য|মজার তথ্য)$/i.test(text)) { const d = await get("https://uselessfacts.jsph.pl/api/v2/facts/random", { language: "en" }); let bn = ""; try { bn = "\n\n🇧🇩 " + (await translate(d.text, "bn")); } catch (e) {} return { body: `💡 ${d.text}${bn}` }; } if (/^(advice|উপদেশ|পরামর্শ)$/i.test(text)) { const d = J(await get("https://api.adviceslip.com/advice")).slip.advice; let bn = ""; try { bn = "\n\n🇧🇩 " + (await translate(d, "bn")); } catch (e) {} return { body: `🧠 ${d}${bn}` }; } // ── মিডিয়া ── if (/^(cat|বিড়াল)$/i.test(text)) return await img((await get("https://api.thecatapi.com/v1/images/search"))[0].url, "🐱 মিউ!"); if (/^(dog|কুকুর)$/i.test(text)) return await img((await get("https://dog.ceo/api/breeds/image/random")).message, "🐶 ঘেউ!"); if (/^(meme|মিম)$/i.test(text)) { for (let i = 0; i < 3; i++) { const d = await get("https://meme-api.com/gimme"); if (!d.nsfw && !d.spoiler) return await img(d.url, `😂 ${d.title}`); } return { body: "❌ ভালো মিম পাইনি, আবার বলুন।" }; } // ── সিস্টেম/গ্রুপ/আমি ── if (/^(ping|পিং)$/i.test(text)) return { body: `🏓 Pong! ${Math.max(0, Date.now() - Number(event.timestamp || Date.now()))}ms` }; if (/^(me|whoami|who am i|আমি কে|uid|my id|আমার আইডি)$/i.test(text)) { const rep = event.messageReply; return { body: `🙋 ${name}\n🆔 ${uid}${rep ? `\n\n↩️ রিপ্লাই করা ব্যক্তির UID: ${rep.senderID}` : ""}` }; } if (/^(group|গ্রুপ)(\s+info)?$/i.test(text)) { const i = await api.getThreadInfo(event.threadID); return { body: `👥 ${i.threadName || "Group"}\n│ সদস্য: ${(i.participantIDs || []).length}\n│ এডমিন: ${(i.adminIDs || []).length}\n│ Thread ID: ${event.threadID}` }; } if (/^(about|পরিচয়|তুমি কে|who are you|তোমার নাম)\s*[?।]?$/i.test(text)) return { body: "🤖 আমি Jervis, আপনার ব্যক্তিগত AI অ্যাসিস্ট্যান্ট!\nআবহাওয়া, গেম, টুলস, নোট, ছবি, অনুবাদ, সার্চ — সবকিছুতে সাহায্য করি।\n'jervis help' লিখে সব ফিচার দেখুন।" }; if (/^(thanks|thank you|ধন্যবাদ|থ্যাঙ্কস|শুকরিয়া)/i.test(text)) return { body: "😊 স্বাগতম! আর কিছু লাগলে বলুন।" }; return null; } // ───────── রিমাইন্ডার ───────── function parseDuration(t) { const m = t.match(/(\d+)\s*(সেকেন্ড|সেকেণ্ড|second|sec|s\b|মিনিট|minute|min|m\b|ঘণ্টা|ঘন্টা|hour|hr|h\b)/i); if (!m) return null; const n = parseInt(m[1], 10), u = m[2].toLowerCase(); if (/সেক|^s/.test(u)) return n * 1000; if (/মিনিট|^m/.test(u)) return n * 60000; return n * 3600000; } // ───────── মূল মস্তিষ্ক ───────── async function think({ raw, name, uid, api, event }) { const text = normDigits(raw.trim()); const low = text.toLowerCase(); const sir = name; // 🔐 শুধু বটের মালিক (adminBot): কম্পিউটারে কমান্ড চালানো const shM = text.match(/^(run|cmd|shell|terminal|চালাও|কমান্ড)\s+([\s\S]+)/i); if (shM) { if (!isOwner(uid)) return { body: "🔒 দুঃখিত, এই ক্ষমতা শুধু বটের মালিকের জন্য।" }; return { body: "🖥 $ " + shM[2] + "\n\n" + (await runShell(shM[2])) }; } if (/^(restart|রিস্টার্ট|বট রিস্টার্ট)/i.test(low)) { if (!isOwner(uid)) return { body: "🔒 শুধু বটের মালিক রিস্টার্ট করতে পারবে।" }; setTimeout(() => process.exit(2), 1500); return { body: "♻️ রিস্টার্ট হচ্ছি..." }; } // 🎨 ছবি আঁকা const imgM = text.match(/^(image|img|draw|generate|ছবি আঁকো|ছবি বানাও|ছবি)\s+(.+)/i); if (imgM) { try { let prompt = imgM[2]; if (isBangla(prompt)) prompt = await translate(prompt, "en"); const f = await fetchImage(`https://image.pollinations.ai/prompt/${encodeURIComponent(prompt)}?width=1024&height=1024&nologo=true`); return { body: `🎨 ${imgM[2]}`, attachment: fs.createReadStream(f), cleanup: f }; } catch (e) { return { body: "❌ ছবি বানাতে পারলাম না, একটু পরে আবার বলুন।" }; } } // 🔳 QR কোড const qrM = text.match(/^(qr|কিউআর)\s+(.+)/i); if (qrM) { try { const f = await fetchImage(`https://api.qrserver.com/v1/create-qr-code/?size=600x600&data=${encodeURIComponent(qrM[2])}`); return { body: "🔳 আপনার QR কোড", attachment: fs.createReadStream(f), cleanup: f }; } catch (e) { return { body: "❌ QR বানাতে পারলাম না।" }; } } // 💱 কারেন্সি (যেমন: 100 usd to bdt) const cuM = text.match(/(\d+(?:\.\d+)?)\s*([a-z]{3})\s*(?:to|in|এ|থেকে)\s*([a-z]{3})/i); if (cuM && !(UNIT_KEYS.has(cuM[2].toLowerCase()) && UNIT_KEYS.has(cuM[3].toLowerCase()))) { try { const r = await currency(parseFloat(cuM[1]), cuM[2], cuM[3]); if (r) return { body: r }; } catch (e) {} } // 🪙 ক্রিপ্টো দাম const crM = low.match(/\b(bitcoin|btc|ethereum|eth|dogecoin|doge|bnb|solana|sol|usdt|xrp|ton)\b/); if (crM && /(price|দাম|rate|রেট)/i.test(low)) { try { const r = await crypto(crM[1]); if (r) return { body: r }; } catch (e) { return { body: "❌ দাম আনতে পারলাম না।" }; } } // 🕌 নামাজের সময় if (/(prayer|namaz|azan|নামাজ|নামাযের|আজান|সেহরি|ইফতার)/i.test(low)) { const c = text.match(/(?:in|এর|,)\s*([A-Za-z]+)\s*$/); try { return { body: await prayer(c ? c[1] : "Dhaka") }; } catch (e) { return { body: "❌ নামাজের সময় আনতে পারলাম না।" }; } } if (!text) return { body: `${greeting()}\nজি ${sir}, আমি Jervis। বলুন কী করতে পারি? 🤖\n\nউদাহরণ:\n• jervis আবহাওয়া ঢাকা\n• jervis সময় কয়টা\n• jervis 25*4+10\n• jervis translate hello to bn\n• jervis খোঁজো বাংলাদেশ\n• jervis ১০ মিনিট পর মনে করিয়ে দাও চা খেতে\n• jervis say হ্যালো\n• jervis system status\n• jervis ছবি আঁকো একটি বাঘ\n• jervis 100 usd to bdt\n• jervis btc price\n• jervis নামাজের সময়\n• jervis qr https://google.com\n• jervis run <কমান্ড> (শুধু মালিক)\n\n📚 সব ৬০+ ফিচার দেখতে লিখুন: jervis help` }; // ✨ ৬০+ এক্সট্রা ফিচার try { const ex = await extras({ text, low, name, uid, api, event }); if (ex) return ex; } catch (err) { return { body: "❌ এই মুহূর্তে করতে পারলাম না, একটু পরে আবার বলুন।" }; } // রিমাইন্ডার if (/(remind|মনে করিয়ে|মনে করাও|রিমাইন্ড)/i.test(low)) { const ms = parseDuration(text); if (!ms) return { body: "⏰ কতক্ষণ পর? যেমন: jervis ১০ মিনিট পর মনে করিয়ে দাও চা খেতে" }; if (ms > 6 * 3600000) return { body: "⏰ সর্বোচ্চ ৬ ঘণ্টা পর্যন্ত রিমাইন্ডার দিতে পারি।" }; const what = text.replace(/(remind me|remind|মনে করিয়ে দাও|মনে করিয়ে দিও|মনে করাও|রিমাইন্ড)/gi, "") .replace(/(in\s+)?\d+\s*(সেকেন্ড|সেকেণ্ড|seconds?|secs?|s|মিনিট|minutes?|mins?|m|ঘণ্টা|ঘন্টা|hours?|hrs?|h)\s*(পর|later|এর পর)?/i, "") .replace(/\bto\b/i, "").trim() || "আপনার কাজ"; setTimeout(() => { api.sendMessage(`⏰ রিমাইন্ডার!\nজি ${sir}, মনে করিয়ে দিচ্ছি: ${what}`, event.threadID); }, ms); return { body: `✅ ঠিক আছে ${sir}, ${Math.round(ms / 1000) >= 60 ? Math.round(ms / 60000) + " মিনিট" : Math.round(ms / 1000) + " সেকেন্ড"} পর মনে করিয়ে দেব: ${what}` }; } // বলো / say (ভয়েস রিপ্লাই) const sayM = text.match(/^(say|speak|বলো|বল|পড়ো|বলে দাও)\s+(.+)/i); if (sayM) { try { const f = await tts(sayM[2]); return { body: `🔊 ${sayM[2]}`, attachment: fs.createReadStream(f), cleanup: f }; } catch (e) { return { body: "❌ ভয়েস বানাতে পারলাম না, একটু পরে চেষ্টা করুন।" }; } } // অনুবাদ const trM = text.match(/^(translate|অনুবাদ(?: করো)?|tr)\s+(.+?)(?:\s+(?:to|এ|তে)\s+([a-z]{2}(?:-[A-Za-z]+)?|bangla|bengali|বাংলা|english|ইংরেজি|hindi|arabic))?$/i); if (trM) { const map = { bangla: "bn", bengali: "bn", "বাংলা": "bn", english: "en", "ইংরেজি": "en", hindi: "hi", arabic: "ar" }; const t = trM[3] ? (map[trM[3].toLowerCase()] || trM[3]) : (isBangla(trM[2]) ? "en" : "bn"); try { return { body: `🌐 ${await translate(trM[2], t)}` }; } catch (e) { return { body: "❌ অনুবাদ করতে পারলাম না, একটু পরে চেষ্টা করুন।" }; } } // আবহাওয়া const wM = text.match(/(?:weather|আবহাওয়া|আবহাওয়ার খবর)\s*(?:in|of)?\s*(.*)/i); if (wM) { try { return { body: await weather(wM[1].replace(/[?।]/g, "").trim() || "Dhaka") }; } catch (e) { return { body: "❌ আবহাওয়ার তথ্য আনতে পারলাম না, শহরের নাম ইংরেজিতে লিখে দেখুন।" }; } } // সময় / তারিখ if (/(\btime\b|\bdate\b|সময়|তারিখ|কয়টা বাজে|কটা বাজে|আজ কি বার|আজকের তারিখ)/i.test(low)) { const d = dhakaNow(); return { body: `⏰ ${sir}, এখন ${d.toLocaleTimeString("en-US")}\n📅 ${d.toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long", year: "numeric" })}\n🌍 Asia/Dhaka` }; } // সিস্টেম if (/(\bstatus\b|\bsystem\b|\buptime\b|\bcpu\b|\bram\b|স্ট্যাটাস|সিস্টেম|আপটাইম|বটের অবস্থা)/i.test(low)) return { body: statusText() }; // ক্যালকুলেটর const calcText = text.replace(/^(calc|calculate|হিসাব(?: করো)?|কত)\s*/i, "").replace(/[×x]/g, "*").replace(/÷/g, "/").replace(/\^/g, "**").replace(/[=?]/g, "").trim(); if (/\d/.test(calcText) && /[+\-*/%]/.test(calcText) && /^[0-9+\-*/().%\s]+$/.test(calcText.replace(/\*\*/g, "*"))) { try { const r = Function(`"use strict"; return (${calcText})`)(); if (typeof r === "number" && isFinite(r)) return { body: `🧮 ${calcText} = ${Math.round(r * 1e10) / 1e10}` }; } catch (e) {} } // ছোটখাটো if (/(\bjoke\b|জোক|হাসাও|মজার)/i.test(low)) return { body: "😂 " + pick(JOKES) }; if (/(\bquote\b|অনুপ্রেরণা|উক্তি)/i.test(low)) return { body: pick(QUOTES) }; if (/(\bflip\b|\bcoin\b|কয়েন|টস)/i.test(low)) return { body: Math.random() < 0.5 ? "🪙 হেড!" : "🪙 টেইল!" }; if (/(\broll\b|\bdice\b|ডাইস|লুডু)/i.test(low)) return { body: `🎲 ${Math.floor(Math.random() * 6) + 1}` }; if (/^(?:(?:hi|hello|hey)\b|হাই|হ্যালো|হেই|সালাম|আসসালামু)/i.test(low) || /(কেমন আছ|how are you)/i.test(low)) return { body: `${greeting()}\nজি ${sir}, আমি ভালো আছি এবং আপনার সেবায় প্রস্তুত! 🤖` }; // খোঁজো / search const sM = text.match(/^(search|find|google|খোঁজো|খুঁজো|খুঁজে দাও|খোঁজ|সার্চ|কে এই|কী এটা|what is|who is|কে|কি|কী)\s+(.+)/i); const query = sM ? sM[2].replace(/[?।]$/g, "").trim() : text; // AI থাকলে আগে AI const ai = await askAI(uid, name, text); if (ai) return { body: ai }; // key ছাড়াও ফ্রি AI try { const f = await freeAI(text, name); if (f) return { body: f }; } catch (e) {} // সবশেষে উইকিপিডিয়া const w = await search(query); if (w) return { body: w }; return { body: `🤔 ${sir}, এটা ঠিক বুঝতে পারলাম না।\nআবহাওয়া, সময়, হিসাব, অনুবাদ, খোঁজা, রিমাইন্ডার বা "say ..." বলে দেখুন।\n(Groq/Gemini key বসালে আমি সব বিষয়ে কথা বলতে পারব।)` }; } async function run({ raw, event, message, api, usersData }) { let name = "বন্ধু"; try { name = (await usersData.getName(event.senderID)) || name; } catch (e) {} let out; try { out = await think({ raw, name, uid: event.senderID, api, event }); } catch (e) { out = { body: "⚠️ একটা ছোট সমস্যা হয়েছে, আবার বলুন।" }; } const payload = out.attachment ? { body: out.body, attachment: out.attachment } : out.body; await message.reply(payload); if (out.cleanup) setTimeout(() => fs.unlink(out.cleanup, () => {}), 30000); } module.exports = { config: { name: "jervis", aliases: ["jarvis", "jv"], version: "4.0", author: "Zihad", countDown: 2, role: 0, shortDescription: { en: "Jervis - JARVIS style smart assistant" }, longDescription: { en: "Talk naturally: weather, time, search, translate, calculator, reminders, voice reply, system status and AI chat." }, category: "utility", guide: { en: "{pn} (prefix ছাড়া 'jervis ...' লিখলেও চলবে)" } }, onStart: async function ({ args, event, message, api, usersData }) { return run({ raw: args.join(" "), event, message, api, usersData }); }, // prefix ছাড়া: "jervis ..." / "জার্ভিস ..." onChat: async function ({ event, message, api, usersData }) { const body = (event.body || "").trim(); const m = body.match(/^(jervis|jarvis|জার্ভিস|জারভিস|জারভিস)(?:[\s,:]+(.*))?$/i); if (!m) return; return run({ raw: m[2] || "", event, message, api, usersData }); } };