const { promisify } = require('util'); const yes = ['yes', 'y', 'ye', 'yeah', 'yup', 'yea']; const no = ['no', 'n', 'nah', 'nope']; class Util { static wait(time) { return promisify(setTimeout)(time); } static shuffle(array) { const arr = array.slice(0); for (let i = arr.length - 1; i >= 0; i--) { const j = Math.floor(Math.random() * (i + 1)); const temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } return arr; } static list(arr, conj = 'and') { const len = arr.length; return `${arr.slice(0, -1).join(', ')}${len > 1 ? `${len > 2 ? ',' : ''} ${conj} ` : ''}${arr.slice(-1)}`; } static shorten(text, maxLen = 2000) { return text.length > maxLen ? `${text.substr(0, maxLen - 3)}...` : text; } static filterPkmn(arr) { const filtered = arr.filter(entry => entry.language.name === 'en'); return filtered[Math.floor(Math.random() * filtered.length)]; } static duration(ms) { const sec = Math.floor((ms / 1000) % 60); const min = Math.floor((ms / (1000 * 60)) % 60); const hrs = Math.floor(ms / (1000 * 60 * 60)); return { hours: hrs, minutes: min, seconds: sec, format: () => `${hrs < 10 ? `0${hrs}` : hrs}:${min < 10 ? `0${min}` : min}:${sec < 10 ? `0${sec}` : sec}` }; } static pad(text, prefix) { return `${prefix.slice(text.length)}${text}`; } static promisifyAll(obj, suffix = 'Async') { for (const key of Object.keys(obj)) { if (typeof obj[key] !== 'function') continue; obj[`${key}${suffix}`] = promisify(obj[key]); } return obj; } static cleanXML(text) { return text .replace(/
/g, '') .replace(/'|�?39;/g, '\'') .replace(/—/g, '—') .replace(/–/g, '–') .replace(/"|�?34;/g, '"') .replace(/<|�?60;/g, '<') .replace(/>|�?62;/g, '>') .replace(/&|�?38;/g, '&') .replace(/\[i\]|\[\/i\]/g, '*'); } static greyscale(ctx, x, y, width, height) { const data = ctx.getImageData(x, y, width, height); for (let i = 0; i < data.data.length; i += 4) { const brightness = (0.34 * data.data[i]) + (0.5 * data.data[i + 1]) + (0.16 * data.data[i + 2]); data.data[i] = brightness; data.data[i + 1] = brightness; data.data[i + 2] = brightness; } ctx.putImageData(data, x, y); return ctx; } static invert(ctx, x, y, width, height) { const data = ctx.getImageData(x, y, width, height); for (let i = 0; i < data.data.length; i += 4) { data.data[i] = 255 - data.data[i]; data.data[i + 1] = 255 - data.data[i + 1]; data.data[i + 2] = 255 - data.data[i + 2]; } ctx.putImageData(data, x, y); return ctx; } static silhouette(ctx, x, y, width, height) { const data = ctx.getImageData(x, y, width, height); for (let i = 0; i < data.data.length; i += 4) { data.data[i] = 0; data.data[i + 1] = 0; data.data[i + 2] = 0; } ctx.putImageData(data, x, y); return ctx; } static sepia(ctx, x, y, width, height) { const data = ctx.getImageData(x, y, width, height); for (let i = 0; i < data.data.length; i += 4) { const brightness = (0.34 * data.data[i]) + (0.5 * data.data[i + 1]) + (0.16 * data.data[i + 2]); data.data[i] = brightness + 100; data.data[i + 1] = brightness + 50; data.data[i + 2] = brightness; } ctx.putImageData(data, x, y); return ctx; } static distort(ctx, x, y, width, height, amplitude, strideLevel = 4) { const data = ctx.getImageData(x, y, width, height); const temp = ctx.getImageData(x, y, width, height); const stride = width * strideLevel; for (let i = 0; i < width; i++) { for (let j = 0; j < height; j++) { const xs = Math.round(amplitude * Math.sin(2 * Math.PI * 3 * (j / height))); const ys = Math.round(amplitude * Math.cos(2 * Math.PI * 3 * (i / width))); const dest = (j * stride) + (i * strideLevel); const src = ((j + ys) * stride) + ((i + xs) * strideLevel); data.data[dest] = temp.data[src]; data.data[dest + 1] = temp.data[src + 1]; data.data[dest + 2] = temp.data[src + 2]; } } ctx.putImageData(data, x, y); return ctx; } static async verify(channel, user, time = 30000) { const filter = res => { const value = res.content.toLowerCase(); return res.author.id === user.id && (yes.includes(value) || no.includes(value)); }; const verify = await channel.awaitMessages(filter, { max: 1, time }); if (!verify.size) return 0; const choice = verify.first().content.toLowerCase(); if (yes.includes(choice)) return true; if (no.includes(choice)) return false; return false; } } module.exports = Util;