// code from goatstore // api: https://store.agi.bd /** * funny.js — GoatBot command * অনেকগুলো ফানি ভিডিও-স্টাইল (animated GIF) ইফেক্ট। কোনো API key / extra install লাগে না * (শুধু canvas, axios, fs-extra — GoatBot এ আগে থেকেই থাকে) * Author: Zihad * * ব্যবহার: * funny list -> সব ইফেক্টের লিস্ট * funny <নাম/নম্বর> -> নির্দিষ্ট ইফেক্ট (নিজের ছবি) * funny <নাম/নম্বর> @tag -> অন্যজনের ছবিতে * (কারো মেসেজে/ছবিতে reply করেও দেওয়া যায়) * funny random -> যেকোনো একটা * funny mix -> ৬টা ইফেক্ট একসাথে এক ভিডিওতে * funny all -> সবগুলো ইফেক্ট এক ভিডিওতে */ const fs = require("fs-extra"); const path = require("path"); const axios = require("axios"); const { createCanvas, loadImage } = require("canvas"); const TAU = Math.PI * 2; const S = 256; // drawing size /* ───────────── GIF encoder (no extra package) ───────────── */ // function lzw(px) { const CLEAR = 256, EOI = 257; const bytes = []; let cur = 0, nb = 0, size = 9, next = 258; const dict = new Map(); const emit = (c) => { cur |= c << nb; nb += size; while (nb >= 8) { bytes.push(cur & 255); cur >>>= 8; nb -= 8; } if (next > (1 << size) - 1 && size < 12) size++; }; emit(CLEAR); let prefix = px[0]; for (let i = 1; i < px.length; i++) { const k = px[i], key = (prefix << 8) | k; const hit = dict.get(key); if (hit !== undefined) { prefix = hit; continue; } emit(prefix); if (next < 4096) dict.set(key, next++); else { emit(CLEAR); dict.clear(); next = 258; size = 9; } prefix = k; } emit(prefix); emit(EOI); if (nb > 0) bytes.push(cur & 255); return bytes; } function encodeGIF(frames, w, h, delayCs) { const out = []; const b = (...a) => { for (const x of a) out.push(x & 255); }; const w16 = (v) => b(v, v >> 8); for (const ch of "GIF89a") out.push(ch.charCodeAt(0)); w16(w); w16(h); b(0xF7, 0, 0); for (let i = 0; i < 256; i++) { b(Math.round(((i >> 5) & 7) * 255 / 7), Math.round(((i >> 2) & 7) * 255 / 7), Math.round((i & 3) * 255 / 3)); } b(0x21, 0xFF, 11); for (const ch of "NETSCAPE2.0") out.push(ch.charCodeAt(0)); b(3, 1, 0, 0, 0); for (const px of frames) { b(0x21, 0xF9, 4, 0x04); w16(delayCs); b(0, 0); b(0x2C); w16(0); w16(0); w16(w); w16(h); b(0); b(8); const data = lzw(px); for (let i = 0; i < data.length; i += 255) { const n = Math.min(255, data.length - i); out.push(n); for (let j = 0; j < n; j++) out.push(data[i + j]); } out.push(0); } out.push(0x3B); return Buffer.from(out); } const BAY = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5]; function quant(data, w, h) { const px = new Uint8Array(w * h); for (let y = 0, p = 0; y < h; y++) { for (let x = 0; x < w; x++, p++) { const d = (BAY[(y & 3) * 4 + (x & 3)] - 7.5) / 16; const o = p * 4; const r = Math.min(7, Math.max(0, Math.round((data[o] + d * 36) * 7 / 255))); const g = Math.min(7, Math.max(0, Math.round((data[o + 1] + d * 36) * 7 / 255))); const bl = Math.min(3, Math.max(0, Math.round((data[o + 2] + d * 85) * 3 / 255))); px[p] = (r << 5) | (g << 2) | bl; } } return px; } // /* ───────────── drawing helpers ───────────── */ const rnd = (n) => { const x = Math.sin(n * 127.1 + 311.7) * 43758.5453; return x - Math.floor(x); }; const lerp = (a, b, t) => a + (b - a) * t; const clamp = (v, a = 0, b = 1) => Math.min(b, Math.max(a, v)); const tmp = () => createCanvas(S, S); function bg(g, c1, c2) { const gr = g.createLinearGradient(0, 0, 0, S); gr.addColorStop(0, c1); gr.addColorStop(1, c2 || c1); g.fillStyle = gr; g.fillRect(0, 0, S, S); } function face(g, im, cx, cy, w, h, rot, ring) { h = h || w; rot = rot || 0; g.save(); g.translate(cx, cy); g.rotate(rot); g.beginPath(); g.ellipse(0, 0, Math.abs(w) / 2, Math.abs(h) / 2, 0, 0, TAU); g.save(); g.clip(); g.drawImage(im, -w / 2, -h / 2, w, h); g.restore(); g.lineWidth = 5; g.strokeStyle = ring || "#fff"; g.stroke(); g.restore(); } function txt(g, s, x, y, size, fill, rot) { g.save(); g.translate(x, y); g.rotate(rot || 0); g.font = `bold ${size}px sans-serif`; g.textAlign = "center"; g.textBaseline = "middle"; g.lineJoin = "round"; g.lineWidth = size / 5; g.strokeStyle = "#000"; g.strokeText(s, 0, 0); g.fillStyle = fill || "#fff"; g.fillText(s, 0, 0); g.restore(); } function star(g, x, y, r, rot, col) { g.save(); g.translate(x, y); g.rotate(rot || 0); g.beginPath(); for (let i = 0; i < 10; i++) { const a = i * Math.PI / 5 - Math.PI / 2, rr = i % 2 ? r * 0.45 : r; g.lineTo(Math.cos(a) * rr, Math.sin(a) * rr); } g.closePath(); g.fillStyle = col; g.fill(); g.restore(); } function heart(g, x, y, s, col) { g.save(); g.translate(x, y); g.scale(s / 10, s / 10); g.beginPath(); g.moveTo(0, 8); g.bezierCurveTo(-14, -2, -8, -14, 0, -5); g.bezierCurveTo(8, -14, 14, -2, 0, 8); g.fillStyle = col; g.fill(); g.restore(); } function cache(im) { return im._c || (im._c = {}); } function tint(im, col) { const C = cache(im); if (C["t" + col]) return C["t" + col]; const c = tmp(), g = c.getContext("2d"); g.drawImage(im, 0, 0, S, S); g.globalCompositeOperation = "multiply"; g.fillStyle = col; g.fillRect(0, 0, S, S); return (C["t" + col] = c); } function gray(im) { const C = cache(im); if (C.gray) return C.gray; const c = tmp(), g = c.getContext("2d"); g.drawImage(im, 0, 0, S, S); const d = g.getImageData(0, 0, S, S), a = d.data; for (let i = 0; i < a.length; i += 4) { const v = a[i] * 0.3 + a[i + 1] * 0.59 + a[i + 2] * 0.11; a[i] = a[i + 1] = a[i + 2] = v; } g.putImageData(d, 0, 0); return (C.gray = c); } /* ───────────── the funny effects (t = 0..1 loop) ───────────── */ const FX = { shake(g, t, im) { bg(g, "#2b2d42", "#8d99ae"); const a = t * TAU * 10; for (let i = 0; i < 6; i++) { g.fillStyle = "rgba(255,255,255,.15)"; g.fillRect(0, 60 + i * 30 + Math.sin(a + i) * 6, S, 3); } face(g, im, 128 + Math.sin(a) * 14, 125 + Math.cos(a * 1.3) * 10, 150, 150, Math.sin(a * 0.7) * 0.15); txt(g, "EARTHQUAKE!", 128, 232, 26, "#ffd60a"); }, spin(g, t, im) { bg(g, `hsl(${Math.round(t * 360)},70%,45%)`, `hsl(${Math.round(t * 360 + 80)},70%,25%)`); const s = 1 + 0.2 * Math.sin(t * TAU * 2); face(g, im, 128, 128, 140 * s, 140 * s, t * TAU * 2); txt(g, "SPIN!", 128, 232, 28, "#fff"); }, love(g, t, im) { bg(g, "#ff8fa3", "#590d22"); const p = Math.pow(Math.max(0, Math.sin(t * TAU * 3)), 3), s = 1 + 0.16 * p; for (let k = 0; k < 8; k++) { const y = S + 20 - ((t * 2 + k / 8) % 1) * (S + 40); heart(g, 20 + k * 30 + Math.sin(t * TAU * 2 + k) * 10, y, 10 + (k % 3) * 5, "rgba(255,255,255,.85)"); } face(g, im, 128, 128, 140 * s, 140 * s, 0, "#ff4d6d"); txt(g, "LOVE <3", 128, 232, 28, "#fff"); }, bounce(g, t, im) { bg(g, "#a8dadc", "#457b9d"); g.fillStyle = "#2d6a4f"; g.fillRect(0, 208, S, 48); const h = Math.abs(Math.sin(t * TAU)); const sq = 1 - 0.28 * Math.pow(1 - h, 8), sx = 2 - sq; g.fillStyle = "rgba(0,0,0,.3)"; g.beginPath(); g.ellipse(128, 216, 60 * (1 - h * 0.5), 9, 0, 0, TAU); g.fill(); face(g, im, 128, 208 - 70 * sq - h * 100, 140 * sx, 140 * sq); txt(g, "BOING!", 128, 36, 28, "#fff"); }, glitch(g, t, im, fi) { const T = tmp(), c = T.getContext("2d"); c.fillStyle = "#000"; c.fillRect(0, 0, S, S); c.globalCompositeOperation = "lighter"; const d = (rnd(fi) > 0.5 ? 1 : 0.3) * 10; c.drawImage(tint(im, "#ff0000"), -d, 0, S, S); c.drawImage(tint(im, "#00ff00"), 0, 0, S, S); c.drawImage(tint(im, "#0000ff"), d, 0, S, S); g.drawImage(T, 0, 0); for (let k = 0; k < 5; k++) { if (rnd(fi * 7 + k) > 0.45) { const sy = rnd(fi * 3 + k * 11) * S, sh = 8 + rnd(fi + k) * 30, sx = (rnd(fi * 5 + k) - 0.5) * 70; g.drawImage(T, 0, sy, S, sh, sx, sy, S, sh); } } g.fillStyle = "rgba(0,0,0,.18)"; for (let y = 0; y < S; y += 4) g.fillRect(0, y, S, 1); txt(g, "GLITCH", 128 + (rnd(fi) - 0.5) * 12, 230, 28, "#0ff"); }, wasted(g, t, im) { const k = clamp(t * 2.5); bg(g, "#222", "#555"); face(g, im, 128, 120 + k * 40, 150, 150, -k * 1.1); g.globalAlpha = k; face(g, gray(im), 128, 120 + k * 40, 150, 150, -k * 1.1); g.globalAlpha = 1; if (t > 0.3) { const a = clamp((t - 0.3) * 5); g.fillStyle = `rgba(0,0,0,${0.75 * a})`; g.fillRect(0, 100, S, 58); g.globalAlpha = a; txt(g, "WASTED", 128, 129, 46, "#c1121f"); g.globalAlpha = 1; } }, dizzy(g, t, im) { bg(g, "#ffe066", "#f4a261"); const w = Math.sin(t * TAU * 2); face(g, im, 128 + w * 10, 145, 140, 140, w * 0.25); for (let k = 0; k < 5; k++) { const a = t * TAU * 2 + k * TAU / 5; star(g, 128 + Math.cos(a) * 80, 62 + Math.sin(a) * 16, 11, a, "#d62828"); } txt(g, "DIZZY...", 128, 232, 28, "#fff"); }, rocket(g, t, im) { bg(g, "#03071e", "#370617"); g.fillStyle = "#fff"; for (let k = 0; k < 30; k++) g.fillRect(rnd(k) * S, (rnd(k + 99) * S + t * S * (1 + (k % 3))) % S, 2, 2); const x = -10 + t * 276, y = 266 - t * 276; for (let j = 6; j >= 0; j--) { g.beginPath(); g.arc(x - j * 13, y + j * 13, 26 - j * 3, 0, TAU); g.fillStyle = `hsla(${50 - j * 8},100%,55%,.85)`; g.fill(); } face(g, im, x, y, 90, 90, 0.4); txt(g, "TO THE MOON!", 128, 30, 24, "#ffd60a"); }, flush(g, t, im) { bg(g, "#caf0f8", "#90e0ef"); for (let k = 0; k < 6; k++) { const a0 = t * TAU * (k % 2 ? -1 : 1); g.beginPath(); g.arc(128, 128, 20 + k * 20, a0, a0 + Math.PI * 1.2); g.strokeStyle = "rgba(255,255,255,.85)"; g.lineWidth = 5; g.stroke(); } const s = 1 - t * t; if (s > 0.03) face(g, im, 128, 128, 150 * s, 150 * s, t * TAU * 4); txt(g, "FLUSHED!", 128, 232, 28, "#0077b6"); }, bonk(g, t, im) { bg(g, "#ffe5ec", "#ffb3c6"); let ang; if (t < 0.4) ang = 1.15 * Math.PI + Math.sin(t * TAU * 4) * 0.03; else if (t < 0.5) ang = lerp(1.15, 0.75, (t - 0.4) / 0.1) * Math.PI; else if (t < 0.75) ang = 0.75 * Math.PI; else ang = lerp(0.75, 1.15, (t - 0.75) / 0.25) * Math.PI; const dec = t >= 0.5 ? 1 - clamp((t - 0.5) / 0.25) : 0; const sx = 1 + 0.35 * dec, sy = 1 - 0.35 * dec; face(g, im, 128 + Math.sin(t * TAU * 20) * 8 * dec, 135 + (1 - sy) * 70, 140 * sx, 140 * sy); g.save(); g.translate(215, 45); g.rotate(ang); g.fillStyle = "#8b5a2b"; g.fillRect(0, -9, 120, 18); g.fillStyle = "#6f4518"; g.fillRect(96, -12, 26, 24); g.restore(); if (t > 0.5 && t < 0.78) { const r = 30 + (t - 0.5) * 300; for (let k = 0; k < 6; k++) star(g, 128 + Math.cos(k * TAU / 6) * r, 128 + Math.sin(k * TAU / 6) * r, 12, k, "#ffd60a"); txt(g, "BONK!", 78, 40, 38, "#fff", -0.2); } }, cry(g, t, im) { bg(g, "#bde0fe", "#a2d2ff"); const p = 0.5 - 0.5 * Math.cos(t * TAU), w = Math.sin(t * TAU * 8) * 3; g.fillStyle = "#4cc9f0"; g.beginPath(); g.ellipse(128, 238, 40 + p * 90, 9 + p * 6, 0, 0, TAU); g.fill(); face(g, im, 128 + w, 120, 140, 140, w * 0.02); g.fillStyle = "#4cc9f0"; for (const ex of [100, 156]) { for (let k = 0; k < 3; k++) { const y = 125 + ((t * 2 + k / 3) % 1) * 105; g.beginPath(); g.arc(ex, y, 6, 0, TAU); g.fill(); } } txt(g, "WAAAH!", 128, 24, 30, "#fff"); }, zoom(g, t, im) { const p = (t * 2) % 1, s = 0.35 + Math.pow(p, 3) * 1.5; g.fillStyle = "#000"; g.fillRect(0, 0, S, S); g.save(); g.translate(128, 128); g.strokeStyle = "rgba(255,255,255,.55)"; g.lineWidth = 2; for (let k = 0; k < 28; k++) { const a = k * TAU / 28 + rnd(k) * 0.1, r1 = 60 + rnd(k + 5) * 60; g.beginPath(); g.moveTo(Math.cos(a) * r1, Math.sin(a) * r1); g.lineTo(Math.cos(a) * 400, Math.sin(a) * 400); g.stroke(); } g.restore(); face(g, im, 128, 128, 150 * s, 150 * s); if (p > 0.88) { g.fillStyle = "rgba(255,255,255,.5)"; g.fillRect(0, 0, S, S); } txt(g, "WHAT?!", 128, 232, 30, "#ff006e"); }, rainbow(g, t, im) { for (let k = 0; k < 12; k++) { g.beginPath(); g.moveTo(128, 128); g.arc(128, 128, 260, t * TAU + k * TAU / 12, t * TAU + (k + 1) * TAU / 12); g.closePath(); g.fillStyle = `hsl(${k * 30},90%,55%)`; g.fill(); } const T = tmp(), c = T.getContext("2d"); face(c, im, 128, 128, 160, 160, Math.sin(t * TAU) * 0.1, "#fff"); c.globalCompositeOperation = "source-atop"; c.globalAlpha = 0.5; c.fillStyle = `hsl(${Math.round(t * 360)},100%,50%)`; c.fillRect(0, 0, S, S); g.drawImage(T, 0, 0); txt(g, "RAINBOW", 128, 234, 28, "#fff"); }, kaleido(g, t, im) { bg(g, "#10002b"); const z = 1 + 0.15 * Math.sin(t * TAU * 2); for (let qy = 0; qy < 2; qy++) { for (let qx = 0; qx < 2; qx++) { g.save(); g.beginPath(); g.rect(qx * 128, qy * 128, 128, 128); g.clip(); g.translate(qx * 128 + 64, qy * 128 + 64); g.scale(qx ? -1 : 1, qy ? -1 : 1); g.rotate(t * TAU); g.scale(z, z); g.drawImage(im, -90, -90, 180, 180); g.restore(); } } txt(g, "KALEIDO", 128, 128, 28, "#fff"); }, wave(g, t, im) { bg(g, "#7209b7", "#3a0ca3"); for (let y = 0; y < 200; y += 2) { const dx = Math.sin(y / 16 - t * TAU * 2) * 16, sy = y * S / 200; g.drawImage(im, 0, sy, S, 2 * S / 200, 28 + dx, 14 + y, 200, 2); } txt(g, "WOBBLY", 128, 238, 24, "#fff"); }, jail(g, t, im) { bg(g, "#8d99ae", "#2b2d42"); face(g, im, 128 + Math.sin(t * TAU * 3) * 3, 130, 150, 150, 0, "#ddd"); const off = -S * (1 - clamp(t * 5)); g.save(); g.translate(0, off); for (let k = 0; k < 9; k++) { const x = 14 + k * 28; g.fillStyle = "#222"; g.fillRect(x, 0, 10, S); g.fillStyle = "rgba(255,255,255,.35)"; g.fillRect(x + 2, 0, 3, S); } g.fillStyle = "#222"; g.fillRect(0, 20, S, 10); g.fillRect(0, S - 30, S, 10); g.restore(); txt(g, "BUSTED!", 128, 238, 28, "#ffd60a"); }, ufo(g, t, im) { bg(g, "#0b132b", "#1c2541"); for (let k = 0; k < 25; k++) { g.fillStyle = `rgba(255,255,255,${0.4 + 0.6 * Math.abs(Math.sin(t * TAU + k))})`; g.fillRect(rnd(k) * S, rnd(k + 50) * 130, 2, 2); } g.fillStyle = "rgba(255,255,150,.25)"; g.beginPath(); g.moveTo(98, 58); g.lineTo(158, 58); g.lineTo(215, S); g.lineTo(41, S); g.closePath(); g.fill(); const s = 1 - 0.45 * t; face(g, im, 128 + Math.sin(t * TAU * 3) * 8, 215 - t * 150, 140 * s, 140 * s, Math.sin(t * TAU * 2) * 0.3); g.fillStyle = "#adb5bd"; g.beginPath(); g.ellipse(128, 52, 70, 16, 0, 0, TAU); g.fill(); g.fillStyle = "#8ecae6"; g.beginPath(); g.ellipse(128, 46, 32, 24, 0, Math.PI, TAU); g.fill(); for (let k = 0; k < 5; k++) { g.fillStyle = (k + Math.floor(t * 8)) % 2 ? "#ffd60a" : "#ef233c"; g.beginPath(); g.arc(84 + k * 22, 56, 4, 0, TAU); g.fill(); } txt(g, "ABDUCTED!", 128, 238, 26, "#caffbf"); } }; const META = [ ["shake", "ভূমিকম্প"], ["spin", "ঘূর্ণি"], ["love", "ভালোবাসা"], ["bounce", "লাফালাফি"], ["glitch", "গ্লিচ"], ["wasted", "ওয়েস্টেড"], ["dizzy", "মাথা ঘুরছে"], ["rocket", "রকেট"], ["flush", "ফ্লাশ"], ["bonk", "বনক"], ["cry", "কান্না"], ["zoom", "ড্রামা জুম"], ["rainbow", "রংধনু"], ["kaleido", "ক্যালাইডোস্কোপ"], ["wave", "ঢেউ"], ["jail", "জেল"], ["ufo", "এলিয়েন চুরি"] ]; const KEYS = META.map((m) => m[0]); /* ───────────── render ───────────── */ function render(list, base, W, nf, delay) { const c = createCanvas(S, S), g = c.getContext("2d"); const o = createCanvas(W, W), og = o.getContext("2d"); const frames = []; for (const key of list) { for (let i = 0; i < nf; i++) { g.setTransform(1, 0, 0, 1, 0, 0); g.globalAlpha = 1; g.globalCompositeOperation = "source-over"; g.clearRect(0, 0, S, S); FX[key](g, i / nf, base, i); og.clearRect(0, 0, W, W); og.drawImage(c, 0, 0, S, S, 0, 0, W, W); frames.push(quant(og.getImageData(0, 0, W, W).data, W, W)); } } return encodeGIF(frames, W, W, delay); } async function makeBase(buf) { const c = createCanvas(S, S), g = c.getContext("2d"); try { const im = await loadImage(buf); const m = Math.min(im.width, im.height); g.drawImage(im, (im.width - m) / 2, (im.height - m) / 2, m, m, 0, 0, S, S); } catch (e) { const gr = g.createLinearGradient(0, 0, S, S); gr.addColorStop(0, "#f72585"); gr.addColorStop(1, "#4361ee"); g.fillStyle = gr; g.fillRect(0, 0, S, S); g.fillStyle = "#fff"; g.font = "bold 120px sans-serif"; g.textAlign = "center"; g.textBaseline = "middle"; g.fillText(":D", 128, 128); } return c; } const avatarUrl = (uid) => `https://graph.facebook.com/${uid}/picture?width=512&height=512&access_token=6628568379%7Cc1e620fa708a1d5696fb991c1bde5662`; async function download(url) { const r = await axios.get(url, { responseType: "arraybuffer", timeout: 20000 }); return Buffer.from(r.data); } /* ───────────── command ───────────── */ module.exports = { config: { name: "funny", aliases: ["fun", "funvideo", "fv"], version: "1.0", author: "Zihad", countDown: 8, role: 0, category: "fun", shortDescription: { en: "অনেক রকম ফানি ভিডিও-স্টাইল GIF ইফেক্ট" }, longDescription: { en: "প্রোফাইল পিকচার বা reply করা ছবিতে ১৭ রকম ফানি অ্যানিমেটেড ইফেক্ট বানায়" }, guide: { en: "{pn} list\n{pn} <নাম/নম্বর> [@tag | reply]\n{pn} random\n{pn} mix\n{pn} all" } }, onStart: async function ({ message, event, args, usersData }) { const a0 = (args[0] || "random").toLowerCase(); if (a0 === "list" || a0 === "help") { const lines = META.map((m, i) => `${i + 1}. ${m[0]} — ${m[1]}`).join("\n"); return message.reply( `🎬 ফানি ভিডিও লিস্ট (${META.length}টা)\n\n${lines}\n\n` + `📌 funny <নাম/নম্বর> [@tag বা reply]\n🎲 funny random\n🎞 funny mix (৬টা একসাথে)\n🎞 funny all (সবগুলো এক ভিডিওতে)` ); } // ── কার ছবি? ── const mentions = event.mentions || {}; const mentionIds = Object.keys(mentions); let uid = event.senderID, imgUrl = null; if (mentionIds.length) uid = mentionIds[0]; else if (event.messageReply) { uid = event.messageReply.senderID; const att = (event.messageReply.attachments || []).find((x) => x.type === "photo" || x.type === "animated_image"); if (att) imgUrl = att.url || att.largePreviewUrl; } else { const n = args.find((x) => /^\d{8,}$/.test(x)); if (n) uid = n; } // ── কোন ইফেক্ট? ── let list, mode = "single"; if (a0 === "all") { list = KEYS.slice(); mode = "all"; } else if (a0 === "mix") { list = KEYS.slice().sort(() => Math.random() - 0.5).slice(0, 6); mode = "mix"; } else if (a0 === "random") { list = [KEYS[Math.floor(Math.random() * KEYS.length)]]; } else { let key = KEYS.includes(a0) ? a0 : null; if (!key && /^\d+$/.test(a0)) key = KEYS[parseInt(a0) - 1] || null; if (!key) { const m = META.find((x) => x[1] === args[0]); if (m) key = m[0]; } if (!key) return message.reply("❌ এই নামে কোনো ইফেক্ট নেই। `funny list` দিয়ে লিস্ট দেখো।"); list = [key]; } let name = ""; try { name = await usersData.getName(uid); } catch (e) { name = ""; } try { let buf = null; try { buf = await download(imgUrl || avatarUrl(uid)); } catch (e) { buf = null; } const base = await makeBase(buf); const W = mode === "all" ? 176 : mode === "mix" ? 224 : 256; const nf = mode === "all" ? 14 : mode === "mix" ? 18 : 28; const gif = render(list, base, W, nf, 5); const dir = path.join(__dirname, "cache"); await fs.ensureDir(dir); const file = path.join(dir, `funny_${Date.now()}.gif`); await fs.writeFile(file, gif); const title = mode === "single" ? `😂 ${META.find((m) => m[0] === list[0])[1]} — ${name || "ফানি"}` : `🎬 ${name || "ফানি"} এর ফানি ভিডিও মিক্স (${list.length}টা ইফেক্ট)`; await message.reply({ body: title, attachment: fs.createReadStream(file) }); fs.remove(file).catch(() => { }); } catch (err) { console.error("[funny]", err); return message.reply("❌ ভিডিও বানাতে সমস্যা হয়েছে, আবার চেষ্টা করো।"); } } };