From 3e94afb222d5306bd84783f35cd828fbe56ea5ba Mon Sep 17 00:00:00 2001 From: toast-ts <96593068+toast-ts@users.noreply.github.com> Date: Fri, 18 Nov 2022 22:29:03 +1100 Subject: [PATCH] im bit bored now, automod needs investigating. --- .gitignore | 4 +- package.json | 6 +- src/Sharding.ts | 5 - src/client.ts | 63 +++++++++-- src/commands/botlog.ts | 2 +- src/commands/case.ts | 83 ++++++++++++++ src/commands/contributors.ts | 3 +- src/commands/faq.ts | 39 +++++++ src/commands/fsurl.ts | 2 +- src/commands/purge.ts | 37 ++++++ src/commands/rank.ts | 192 ++++++++++++++++++++++++++++++++ src/commands/roleinfo.ts | 25 +++++ src/commands/smell.ts | 11 ++ src/database/MPPlayerData.json | 2 +- src/database/dailyMsgs.json | 2 +- src/database/userLevels.json | 86 +++++++------- src/events/messageDelete.ts | 8 +- src/events/messageDeleteBulk.ts | 6 +- src/index.ts | 17 +-- 19 files changed, 506 insertions(+), 87 deletions(-) delete mode 100644 src/Sharding.ts create mode 100644 src/commands/case.ts create mode 100644 src/commands/faq.ts create mode 100644 src/commands/purge.ts create mode 100644 src/commands/rank.ts create mode 100644 src/commands/roleinfo.ts create mode 100644 src/commands/smell.ts diff --git a/.gitignore b/.gitignore index e0183c9..17fbbc8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,4 @@ package-lock.json dist/ # Bot stuff src/database/MPDB.dat -src/commands/disabled -src/commands/roleinfo.ts -src/commands/rank.ts \ No newline at end of file +src/commands/disabled \ No newline at end of file diff --git a/package.json b/package.json index 63fcecd..79014e5 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,7 @@ { "name": "daggerbot-ts", "description": "TypeScript version of the original JavaScript-based bot for Official Daggerwin Discord.", - "main": "src/Sharding.ts", - "scripts": { - "start": "ts-node src/Sharding.ts", - "startDev": "ts-node src/index.ts" - }, + "main": "src/index.ts", "repository": { "type": "git", "url": "git+https://github.com/AnxietyisReal/Daggerbot-TS.git" diff --git a/src/Sharding.ts b/src/Sharding.ts deleted file mode 100644 index a23789d..0000000 --- a/src/Sharding.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {token_toast} from './tokens.json'; -import {ShardingManager} from 'discord.js'; -const sharder = new ShardingManager('src/index.ts',{token: token_toast, totalShards: 1, mode: 'worker'}); -sharder.on('shardCreate',async(shard)=>{console.log(`Shard ${shard.id} launched`)}); -sharder.spawn(); \ No newline at end of file diff --git a/src/client.ts b/src/client.ts index 97e28e5..42353fe 100644 --- a/src/client.ts +++ b/src/client.ts @@ -174,7 +174,7 @@ export class TClient extends Client { {name: '\u200b', value: '\u200b', inline: true} ) } - if (data.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites Case #${cancels.id} \`${cancels.reason}\``}); + if (data.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites Case #${cancels.id}\n\`${cancels.reason}\``}); // send embed to log channel (client.channels.cache.get(client.config.mainServer.channels.logs) as Discord.TextChannel).send({embeds: [embed]}) } @@ -263,7 +263,7 @@ class punishments extends Database { switch (type) { case 'ban': const banData:Punishment={type, id: this.createId(), member: member.id, moderator, time: now}; - const dm1: Discord.Message = await member.send(`You've been banned from ${interaction.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${banData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')}) + const dm1: Discord.Message = await member.send(`You've been banned from ${interaction.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${banData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')}) const banResult = await interaction.guild.bans.create(member.id, {reason: `${reason || 'Reason unspecified'} | Case #${banData.id}`}).catch((err:Error)=>err.message); if (typeof banResult === 'string'){ dm1.delete() @@ -278,13 +278,13 @@ class punishments extends Database { this.addData(banData).forceSave(); return new this.client.embed().setColor(this.client.config.embedColor).setTitle(`Case #${banData.id}: Ban`).setDescription(`${member?.user?.tag ?? member?.tag}\n<@${member.id}>\n(\`${member.id}\`)`).addFields( {name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``}, - {name: 'Duration', value: `${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'}`} + {name: 'Duration', value: `${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'}`} ) } case 'softban': const guild = member.guild; const softbanData:Punishment={type, id: this.createId(), member: member.user.id, moderator, time: now}; - const dm2 = Discord.Message = await member.send(`You've been softbanned from ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${softbanData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')}) + const dm2 = Discord.Message = await member.send(`You've been softbanned from ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${softbanData.id})`).catch(()=>{return interaction.channel.send('Failed to DM user.')}) const softbanResult = await member.ban({deleteMessageDays: 3, reason: `${reason || 'Reason unspecified'} | Case #${softbanData.id}`}).catch((err:Error)=>err.message); if (typeof softbanResult === 'string') { dm2.delete(); @@ -335,7 +335,7 @@ class punishments extends Database { const muteData:Punishment={type, id: this.createId(), member: member.user.id, moderator, time: now}; let muteResult; if (this.client.isStaff(member)) return 'Staff cannot be muted.' - const dm4: Discord.Message = await member.send(`You've been muted in ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${muteData.id})`).catch(()=>{interaction.channel.send('Failed to DM user.'); return null}); + const dm4: Discord.Message = await member.send(`You've been muted in ${member.guild.name} ${timeInMillis ? `for ${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${muteData.id})`).catch(()=>{interaction.channel.send('Failed to DM user.'); return null}); if (timeInMillis) { muteResult = await member.timeout(timeInMillis, `${reason || 'Reason unspecified'} | Case #${muteData.id}`).catch((err:Error)=>err.message); } else { @@ -354,16 +354,57 @@ class punishments extends Database { this.addData(muteData).forceSave(); const embedm = new this.client.embed().setColor(this.client.config.embedColor).setTitle(`Case #${muteData.id}: Mute`).setDescription(`${member.user.tag}\n<@${member.user.id}>\n(\`${member.user.id}\`)`).addFields( {name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``}, - {name: 'Duration', - value: `${this.client.formatTime(timeInMillis, 4, { - longNames: true, - commas: true - })} (${timeInMillis}ms)`}) + {name: 'Duration', value: `${this.client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}`}) if (moderator !== '795443537356521502') {return embedm}; } } } - async removePunishment(caseId:number, moderator:any, reason:string):Promise{} + async removePunishment(caseId:number, moderator:any, reason:string):Promise{ + const now = Date.now() + const punishment = this._content.find((x:Punishment)=>x.id === caseId); + const id = this.createId(); + if (!punishment) return 'Punishment not found'; + if (['ban','mute'].includes(punishment.type)) { + const guild = this.client.guilds.cache.get(this.client.config.mainServer.id) as Discord.Guild; + let removePunishmentResult; + if (punishment.type === 'ban'){ + removePunishmentResult = await guild.members.unban(punishment.member, `${reason || 'Reason unspecified'} | Case #${id}`).catch((err:TypeError)=>err.message); + } else if (punishment.type === 'mute'){ + const member = await guild.members.fetch(punishment.member).catch(err=>undefined); + if (member){ + removePunishmentResult = await member + if (typeof removePunishmentResult !== 'string'){ + member.timeout(null, `${reason || 'Reason unspecified'} | Case #${id}`) + removePunishmentResult.send(`You've been unmuted in ${removePunishmentResult.guild.name}.`); + removePunishmentResult = removePunishmentResult.user; + } + } else { + // user probably left, quietly remove punishment + const removePunishmentData = {type: `un${punishment.type}`, id, cancels: punishment.id, member: punishment.member, reason, moderator, time: now}; + this._content[this._content.findIndex((x:Punishment)=>x.id === punishment.id)].expired = true + this.addData(removePunishmentData).forceSave(); + } + } + if (typeof removePunishmentResult === 'string') return `Un${punishment.type} was unsuccessful: ${removePunishmentResult}`; + else { + const removePunishmentData = {type: `un${punishment.type}`, id, cancels: punishment.id, member: punishment.member, reason, moderator, time: now}; + this.client.makeModlogEntry(removePunishmentData, this.client); + this._content[this._content.findIndex((x:Punishment)=>x.id === punishment.id)].expired = true; + this.addData(removePunishmentData).forceSave(); + return `Successfully ${punishment.type === 'ban' ? 'unbanned' : 'unmuted'} **${removePunishmentResult?.tag}** (${removePunishmentResult?.id}) for reason \`${reason || 'Reason unspecified'}\`` + } + } else { + try { + const removePunishmentData = {type: 'removeOtherPunishment', id, cancels: punishment.id, member: punishment.member, reason, moderator, time: now}; + this.client.makeModlogEntry(removePunishmentData, this.client); + this._content[this._content.findIndex((x:Punishment)=>x.id === punishment.id)].expired = true; + this.addData(removePunishmentData).forceSave(); + return `Successfully removed Case #${punishment.id} (type: ${punishment.type}, user: ${punishment.member}).`; + } catch (error:any){ + return `${punishment.type[0].toUpperCase() + punishment.type.slice(1)} removal was unsuccessful: ${error.message}`; + } + } + } } class userLevels extends Database { client: TClient; diff --git a/src/commands/botlog.ts b/src/commands/botlog.ts index 95165e6..7240158 100644 --- a/src/commands/botlog.ts +++ b/src/commands/botlog.ts @@ -8,5 +8,5 @@ export default { }, data: new SlashCommandBuilder() .setName('botlog') - .setDescription('Retrieves the log from host and sends it to appropriate channel.') + .setDescription('Retrieves the log from host and sends it to development server.') } \ No newline at end of file diff --git a/src/commands/case.ts b/src/commands/case.ts new file mode 100644 index 0000000..9a17352 --- /dev/null +++ b/src/commands/case.ts @@ -0,0 +1,83 @@ +import Discord,{SlashCommandBuilder} from "discord.js"; +import { TClient } from 'src/client'; +import { Punishment } from "src/typings/interfaces"; +export default { + async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ + if (!interaction.member.roles.cache.has(client.config.mainServer.roles.dcmod)) return client.youNeedRole(interaction, 'dcmod') + const Subb = interaction.options.getSubcommand(); + const caseId = interaction.options.getInteger('id'); + if (Subb == 'update'){ + const reason = interaction.options.getString('reason') + client.punishments._content.find((x:Punishment)=>x.id==caseId).reason = reason; + client.punishments.forceSave(); + const embed = new client.embed().setColor(client.config.embedColorGreen).setTitle('Case updated').setDescription(`Case #${caseId} has been successfully updated with new reason:\n\`${reason}\``); + await interaction.reply({embeds: [embed]}) + } else if (Subb == 'view'){ + const punishment = client.punishments._content.find((x:Punishment)=>x.id==caseId); + if (!punishment) return interaction.reply('Invalid case #'); + const cancelledBy = punishment.expired ? client.punishments._content.find((x:Punishment)=>x.cancels==punishment.id) : null; + const cancels = punishment.cancels ? client.punishments._content.find((x:Punishment)=>x.id==punishment.cancels) : null; + const embed = new client.embed().setColor(client.config.embedColor).setTimestamp(punishment.time).setTitle(`${client.formatPunishmentType(punishment, client, cancels)} | Case #${punishment.id}`).addFields( + {name: '🔹 User', value: `<@${punishment.member}> \`${punishment.member}\``, inline: true}, + {name: '🔹 Moderator', value: `<@${punishment.moderator}> \`${punishment.moderator}\``, inline: true}, + {name: '\u200b', value: '\u200b', inline: true}, + {name: '🔹 Reason', value: `\`${punishment.reason || 'Reason unspecified'}\``, inline: true}) + if (punishment.duration){ + embed.addFields({name: '🔹 Duration', value: client.formatTime(punishment.duration, 100)}) + } + if (punishment.expired) embed.addFields({name: '🔹 Expired', value: `This case has been overwritten by case #${cancelledBy.id} for reason \`${cancelledBy.reason}\``}) + if (punishment.cancels) embed.addFields({name: '🔹 Overwrites', value: `This case overwrites case #${cancels.id} with reason \`${cancels.reason}\``}) + interaction.reply({embeds: [embed]}); + } else { + // if caseid is user id, show their punishment history sorted by most recent. + const userId = (interaction.options.getUser('user') as Discord.User).id; + const userName = (interaction.options.getUser('user') as Discord.User).username; + const punishment = client.punishments._content.find((x:Punishment)=>x.member===userId); + if (!punishment) return interaction.reply(`<@${userId}> has a clean record.`) + const cancels = punishment.cancels ? client.punishments._content.find((x:Punishment)=>x.id==punishment.cancels) : null; + const userPunishment = client.punishments._content.filter((x:Punishment)=>x.member==userId).sort((a:Punishment,b:Punishment)=>a.time-b.time).map((punishment:Punishment)=>{ + return { + name: `${client.formatPunishmentType(punishment, client, cancels)} | Case #${punishment.id}`, + value: `Reason: \`${punishment.reason}\`\n${punishment.duration ? `Duration: ${client.formatTime(punishment.duration, 3)}\n` : ''}Moderator: <@${punishment.moderator}>${punishment.expired ? `\nOverwritten by case #${client.punishments._content.find((x:Punishment)=>x.cancels==punishment.id).id}` : ''}${punishment.cancels ? `\nOverwrites case #${punishment.cancels}` : ''}` + } + }); + // if caseid is not a punishment nor a user, failed + if (!userPunishment || userPunishment.length == 0) return interaction.reply('No punishments found for that case # or User ID'); + + const pageNum = interaction.options.getInteger('page') ?? 1; + const embed = new client.embed().setColor(client.config.embedColor).setTitle(`${userName}'s punishment history`).setDescription(`**ID:** \`${userId}\``).setFooter({text: `${userPunishment.length} total punishments. Viewing page ${pageNum} out of ${Math.ceil(userPunishment.length/6)}.`}).addFields(userPunishment.slice((pageNum - 1) * 6, pageNum * 6)); + return interaction.reply({embeds: [embed]}); + } + }, + data: new SlashCommandBuilder() + .setName('case') + .setDescription('Retrieve case information or user\'s punishment history') + .addSubcommand((opt)=>opt + .setName('view') + .setDescription('View a single case.') + .addIntegerOption((optt)=>optt + .setName('id') + .setDescription('Case #') + .setRequired(true))) + .addSubcommand((opt)=>opt + .setName('member') + .setDescription('View member\'s punishment history') + .addUserOption((optt)=>optt + .setName('user') + .setDescription('Which user do you want to view their punishment history?') + .setRequired(true)) + .addIntegerOption((optt)=>optt + .setName('page') + .setDescription('Select the page number'))) + .addSubcommand((opt)=>opt + .setName('update') + .setDescription('Update the case with new reason') + .addIntegerOption((optt)=>optt + .setName('id') + .setDescription('Case # to be updated') + .setRequired(true)) + .addStringOption((optt)=>optt + .setName('reason') + .setDescription('New reason for the case') + .setRequired(true))) +}; \ No newline at end of file diff --git a/src/commands/contributors.ts b/src/commands/contributors.ts index aec7072..563f5a7 100644 --- a/src/commands/contributors.ts +++ b/src/commands/contributors.ts @@ -3,6 +3,7 @@ import { TClient } from 'src/client'; export default { async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ const embed = new client.embed().setColor(client.config.embedColor).setTitle('Daggerbot contributors').setDescription([ + '**Thanks to those below that contributed to the bot!**', 'Toast <@190407856527376384>', 'TÆMBØ <@615761944154210305>', 'Buzz <@593696856165449749>', @@ -16,5 +17,5 @@ export default { }, data: new SlashCommandBuilder() .setName('contributors') - .setDescription('List of people who helped and worked on the bot.') + .setDescription('List of people who contributed to the bot.') } \ No newline at end of file diff --git a/src/commands/faq.ts b/src/commands/faq.ts new file mode 100644 index 0000000..dcb9c86 --- /dev/null +++ b/src/commands/faq.ts @@ -0,0 +1,39 @@ +import Discord,{SlashCommandBuilder} from 'discord.js'; +import { TClient } from 'src/client'; +export default { + async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ + const options = interaction.options.getString('question') + if (options == 'srp'){ + const embed = new client.embed().setColor(client.config.embedColor).setTitle('When will SRP (Survival Roleplay) return?').setImage('https://cdn.discordapp.com/attachments/898252602603610142/1013097505094893698/Screenshot_20220827-153617_YouTube.jpg'); + interaction.reply({embeds: [embed]}) + } else if (options == 'dlskin'){ + const embed1 = new client.embed().setColor(client.config.embedColor).setTitle('Hex code for Daggerwin Logistics').setDescription('The main color will be Onyx (`#353839`) with red bumpers').setImage('https://cdn.discordapp.com/attachments/801965516947324969/806871878736019456/image0.png'); + interaction.reply({embeds: [embed1]}) + } else if (options == 'vtcR'){ + interaction.reply(`You can get the <@&${client.config.mainServer.roles.vtcmember}> role from <#802283932430106624> by reacting the ProBot\'s message with :truck:\n*VTC skin can also be found in <#801975222609641472> as well.*`) + } else if (options == 'mpR'){ + interaction.reply(`You can get the <@&${client.config.mainServer.roles.mpplayer}> role from <#802283932430106624> by reacting the ProBot\'s message with :tractor:`) + } else if (options == 'fsShader'){ + const embed2 = new client.embed().setColor(client.config.embedColor).setTitle('Clearing your shader cache folder').setDescription('If your game kees crashing shortly after opening your game, then the shaders might be an issue.\nTo resolve this, you can go to `Documents/My Games/FarmingSimulator2022` and delete the folder called `shader_cache`').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1015195687970943016/unknown.png'); + interaction.reply({embeds: [embed2]}) + } else if (options == 'fsLogfile'){ + const embed3 = new client.embed().setColor(client.config.embedColor).setTitle('Uploading your log file').setDescription('You can find `log.txt` in `Documents/My Games/FarmingSimulator2022` and upload it into <#596989522395398144> along with your issue, so people can assist you further and help you resolve.').setImage('https://cdn.discordapp.com/attachments/1015195575693627442/1015195643528101958/unknown.png'); + interaction.reply({embeds: [embed3]}) + } + }, + data: new SlashCommandBuilder() + .setName('faq') + .setDescription('List of FAQ for users') + .addStringOption((opt)=>opt + .setName('question') + .setDescription('What question do you want answered?') + .addChoices( + { name: 'Survival Roleplay', value: 'srp' }, + { name: 'Daggerwin Logistics hex code', value: 'dlskin' }, + { name: 'VTC Role', value: 'vtcR' }, + { name: 'MP Role', value: 'mpR' }, + { name: '[FS22] Resolve shader_cache issue', value: 'fsShader' }, + { name: '[FS22] Log file location', value: 'fsLogfile' } + )) + +} \ No newline at end of file diff --git a/src/commands/fsurl.ts b/src/commands/fsurl.ts index 2724b97..72f6e8b 100644 --- a/src/commands/fsurl.ts +++ b/src/commands/fsurl.ts @@ -3,7 +3,7 @@ import { TClient } from 'src/client'; import MPDB from '../models/MPServer'; export default { async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ - if (interaction.guildId !== client.config.mainServer.id) return interaction.reply('This command doesn\'t work in this server.'); + if (interaction.guildId !== client.config.mainServer.id) return interaction.reply({content: 'This command doesn\'t work in this server.', ephemeral: true}); if (!interaction.member.roles.cache.has(client.config.mainServer.roles.mpmanager) && !interaction.member.roles.cache.has(client.config.mainServer.roles.bottech) && !interaction.member.roles.cache.has(client.config.mainServer.roles.admin)) return client.youNeedRole(interaction, 'mpmanager'); MPDB.sync(); diff --git a/src/commands/purge.ts b/src/commands/purge.ts new file mode 100644 index 0000000..5723901 --- /dev/null +++ b/src/commands/purge.ts @@ -0,0 +1,37 @@ +import Discord,{SlashCommandBuilder} from 'discord.js'; +import { TClient } from 'src/client'; +export default { + async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ + if (!client.isStaff(interaction.member)) return client.youNeedRole(interaction, 'dcmod'); + const amount = interaction.options.getInteger('amount') as number; + if (amount > 100) return interaction.reply({content: 'Discord API limits purging up to 100 messages.', ephemeral: true}) + const user = interaction.options.getUser('user'); + + let messagesArray: Array = []; + + if (user){ + (interaction.channel as Discord.TextChannel).messages.fetch({limit: 100}).then((msgs)=>{ + const msgList = msgs.filter(x=>x.author.id == user.id); + (interaction.channel as Discord.TextChannel).bulkDelete(msgList); + }) + } else { + (interaction.channel as Discord.TextChannel).messages.fetch({limit: amount}).then(async messages=>{ + messages.forEach(message=>{ + messagesArray.push(message.id); + }); + await (interaction.channel as Discord.TextChannel).bulkDelete(messagesArray); + }) + } + await interaction.reply({content: `Successfully purged ${amount} messages.`, ephemeral: true}) + }, + data: new SlashCommandBuilder() + .setName('purge') + .setDescription('Purge the amount of messages in this channel') + .addIntegerOption((opt)=>opt + .setName('amount') + .setDescription('Amount of messages to be obliterated') + .setRequired(true)) + .addUserOption((opt)=>opt + .setName('user') + .setDescription('Which user to have their messages obliterated?')) +} \ No newline at end of file diff --git a/src/commands/rank.ts b/src/commands/rank.ts new file mode 100644 index 0000000..f7440fc --- /dev/null +++ b/src/commands/rank.ts @@ -0,0 +1,192 @@ +interface UserLevels { + messages: number, + level: number +} +import Discord,{SlashCommandBuilder} from 'discord.js'; +import { TClient } from 'src/client'; +export default { + async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ + if (interaction.guildId !== client.config.mainServer.id) return interaction.reply({content: 'This command doesn\'t work in this server.', ephemeral: true}); + const subCmd = interaction.options.getSubcommand(); + + if (subCmd === "leaderboard") { + const messageCountsTotal = Object.values(client.userLevels._content).reduce((a, b) => a + b.messages, 0); + const timeActive = Math.floor((Date.now() - client.config.LRSstart)/1000/60/60/24); + + const data = require('../database/dailyMsgs.json').map((x: Array, i: number, a: any) => { + const yesterday = a[i - 1] || []; + return x[1] - (yesterday[1] || x[1]); + }).slice(1).slice(-60); + + // handle negative days + data.forEach((change: number, i: number) => { + if (change < 0) data[i] = data[i - 1] || data[i + 1] || 0; + }); + + const maxValue = Math.max(...data); + const maxValueArr = maxValue.toString().split(''); + + const first_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 1)) * 10 ** (maxValueArr.length - 1); + // console.log({ first_graph_top }); + + const second_graph_top = Math.ceil(maxValue * 10 ** (-maxValueArr.length + 2)) * 10 ** (maxValueArr.length - 2); + // console.log({ second_graph_top }); + + const textSize = 32; + + const canvas = require('canvas'); + const img = canvas.createCanvas(950, 450); + const ctx = img.getContext('2d'); + + const graphOrigin = [10, 50]; + const graphSize = [700, 360]; + const nodeWidth = graphSize[0] / (data.length - 1); + ctx.fillStyle = '#36393f'; + ctx.fillRect(0, 0, img.width, img.height); + + // grey horizontal lines + ctx.lineWidth = 3; + + let interval_candidates = []; + for (let i = 4; i < 10; i++) { + const interval = first_graph_top / i; + if (Number.isInteger(interval)) { + let intervalString = interval.toString(); + const reference_number = i * Math.max(intervalString.split('').filter(x => x === '0').length / intervalString.length, 0.3) * (['1', '2', '4', '5', '6', '8'].includes(intervalString[0]) ? 1.5 : 0.67) + interval_candidates.push([interval, i, reference_number]); + } + } + // console.log({ interval_candidates }); + const chosen_interval = interval_candidates.sort((a, b) => b[2] - a[2])[0]; + // console.log({ chosen_interval }); + + let previousY: Array = []; + + ctx.strokeStyle = '#202225'; + for (let i = 0; i <= chosen_interval[1]; i++) { + const y = graphOrigin[1] + graphSize[1] - (i * (chosen_interval[0] / second_graph_top) * graphSize[1]); + if (y < graphOrigin[1]) continue; + const even = ((i + 1) % 2) === 0; + if (even) ctx.strokeStyle = '#2c2f33'; + ctx.beginPath(); + ctx.lineTo(graphOrigin[0], y); + ctx.lineTo(graphOrigin[0] + graphSize[0], y); + ctx.stroke(); + ctx.closePath(); + if (even) ctx.strokeStyle = '#202225'; + previousY = [y, i * chosen_interval[0]]; + } + + // 30d mark + ctx.setLineDash([8, 16]); + ctx.beginPath(); + const lastMonthStart = graphOrigin[0] + (nodeWidth * (data.length - 30)); + ctx.lineTo(lastMonthStart, graphOrigin[1]); + ctx.lineTo(lastMonthStart, graphOrigin[1] + graphSize[1]); + ctx.stroke(); + ctx.closePath(); + ctx.setLineDash([]); + + // draw points + ctx.strokeStyle = client.config.embedColor; + ctx.fillStyle = client.config.embedColor; + ctx.lineWidth = 3; + + + function getYCoordinate(value: number) { + return ((1 - (value / second_graph_top)) * graphSize[1]) + graphOrigin[1]; + } + + let lastCoords: Array = []; + data.forEach((val: number, i: number) => { + ctx.beginPath(); + if (lastCoords) ctx.moveTo(...lastCoords); + if (val < 0) val = 0; + const x = i * nodeWidth + graphOrigin[0]; + const y = getYCoordinate(val); + ctx.lineTo(x, y); + lastCoords = [x, y]; + ctx.stroke(); + ctx.closePath(); + + // ball + ctx.beginPath(); + ctx.arc(x, y, ctx.lineWidth * 1.2, 0, 2 * Math.PI) + ctx.closePath(); + ctx.fill(); + }); + + // draw text + ctx.font = '400 ' + textSize + 'px sans-serif'; + ctx.fillStyle = 'white'; + + // highest value + //console.log(previousY) + const maxx = graphOrigin[0] + graphSize[0] + textSize; + const maxy = previousY[0] + (textSize / 3); + ctx.fillText(previousY[1].toLocaleString('en-US'), maxx, maxy); + + // lowest value + const lowx = graphOrigin[0] + graphSize[0] + textSize; + const lowy = graphOrigin[1] + graphSize[1] + (textSize / 3); + ctx.fillText('0 msgs/day', lowx, lowy); + + // 30d + ctx.fillText('30d ago', lastMonthStart, graphOrigin[1] - (textSize / 3)); + + // time -> + const tx = graphOrigin[0] + (textSize / 2); + const ty = graphOrigin[1] + graphSize[1] + (textSize); + ctx.fillText('time ->', tx, ty); + + const yeahok = new client.attachmentBuilder(img.toBuffer(), {name: "dailymsgs.png"}) + const embed = new client.embed() + .setTitle('Ranking leaderboard') + .setDescription(`Level System was created **${timeActive}** days ago. Since then, a total of **${messageCountsTotal.toLocaleString('en-US')}** messages have been sent in this server.`) + .addFields({name: 'Top users by messages sent:', value: Object.entries(client.userLevels._content).sort((a, b) => b[1].messages - a[1].messages).slice(0, 10).map((x, i) => `\`${i + 1}.\` <@${x[0]}>: ${x[1].messages.toLocaleString('en-US')}`).join('\n')}) + .setImage('attachment://dailymsgs.png') + .setColor(client.config.embedColor) + interaction.reply({embeds: [embed], files: [yeahok]}); + return; + } else if (subCmd === "view") { + + // fetch user or user interaction sender + const member = interaction.options.getMember("member") ?? interaction.member as Discord.GuildMember; + + const embed = new client.embed().setColor(member.displayColor) + + // information about users progress on level roles + const information = client.userLevels._content[member.user.id]; + + const pronounBool = (you: string, they: string) => { // takes 2 words and chooses which to use based on if user did this command on themself + if (interaction.user.id === member.user.id) return you || true; + else return they || false; + }; + + if (!information) { + return interaction.reply(`${pronounBool('You', 'They')} currently don't have a level, send some messages to level up.`) + } + + const index = Object.entries(client.userLevels._content).sort((a, b) => b[1].messages - a[1].messages).map(x => x[0]).indexOf(member.id) + 1; + const memberDifference = information.messages - client.userLevels.algorithm(information.level); + const levelDifference = client.userLevels.algorithm(information.level+1) - client.userLevels.algorithm(information.level); + + embed.setThumbnail(member.user.avatarURL({ extension: 'png', size: 256}) || member.user.defaultAvatarURL) + embed.setAuthor({name: `Ranking for ${member.user.tag}`}) + embed.setTitle(`Level: **${information.level}**\nRank: **${index ? '#' + index : 'last'}**\nProgress: **${information.messages - client.userLevels.algorithm(information.level)}/${client.userLevels.algorithm(information.level+1) - client.userLevels.algorithm(information.level)} (${(memberDifference/levelDifference*100).toFixed(2)}%)**\nTotal: **${information.messages}**`); + interaction.reply({embeds: [embed]}); + } + }, + data: new SlashCommandBuilder() + .setName('rank') + .setDescription('Level system') + .addSubcommand((optt)=>optt + .setName('view') + .setDescription('View your rank, someone else\'s rank') + .addUserOption((opt)=>opt + .setName('member') + .setDescription('Which member do you want to view?'))) + .addSubcommand((optt)=>optt + .setName('leaderboard') + .setDescription('View top 10 users on leaderboard')) +} \ No newline at end of file diff --git a/src/commands/roleinfo.ts b/src/commands/roleinfo.ts new file mode 100644 index 0000000..abd6359 --- /dev/null +++ b/src/commands/roleinfo.ts @@ -0,0 +1,25 @@ +import Discord,{SlashCommandBuilder} from 'discord.js'; +import { TClient } from 'src/client'; +export default { + async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ + const role = interaction.options.getRole('role') as Discord.Role; + const keyPerms = ['Administrator', 'KickMembers', 'BanMembers', 'ManageChannels', 'ManageGuild', 'ViewAuditLog', 'ManageMessages', 'MentionEveryone', 'UseExternalEmojis', 'ManageRoles', 'Manage EmojiandStickers', 'ModerateMembers'] + const permissions = role.permissions.toArray(); + const Role = role.members.map((e:Discord.GuildMember)=>`**${e.user.tag}**`).join('\n') || ''; + const embed = new client.embed().setColor(role.color || '#fefefe').setThumbnail(role?.iconURL()).setTitle(`Role Info: ${role.name}`).addFields( + {name: '🔹 ID', value: `\`${role.id}\``, inline: true}, + {name: '🔹 Color', value: `\`${role.hexColor}\``, inline: true}, + {name: '🔹 Creation Date', value: `\n`, inline: true}, + {name: '🔹 Misc', value: `Hoist: \`${role.hoist}\`\nMentionable: \`${role.mentionable}\`\nPosition: \`${role.position}\` from bottom\nMembers: \`${role.members.size}\`\n${role.members.size < 21 ? Role : ''}`, inline: true}, + {name: '🔹 Permissions', value: (permissions.includes('Administrator') ? ['Administrator'] : permissions.filter((x:string)=>keyPerms.includes(x))).map((x:string)=>{return x.split('_').map((y,i)=>y).join(' ')}).join(', ') || 'None', inline: true} + ) + interaction.reply({embeds: [embed]}) + }, + data: new SlashCommandBuilder() + .setName('roleinfo') + .setDescription('View information about the selected role') + .addRoleOption((opt)=>opt + .setName('role') + .setDescription('Role name to view information') + .setRequired(true)) +} \ No newline at end of file diff --git a/src/commands/smell.ts b/src/commands/smell.ts new file mode 100644 index 0000000..d932b6c --- /dev/null +++ b/src/commands/smell.ts @@ -0,0 +1,11 @@ +import Discord,{SlashCommandBuilder} from 'discord.js'; +import { TClient } from 'src/client'; +export default { + async run(client: TClient, interaction: Discord.ChatInputCommandInteraction<'cached'>){ + const embed = new client.embed().setColor(client.config.embedColor).setTitle('Who smells?').setDescription('Dave and Monster! (Monster smells of staircases)').setImage('https://media.tenor.com/QW9S-Oq9INQAAAAC/patrick-smell.gif') + interaction.reply({embeds: [embed]}); + }, + data: new SlashCommandBuilder() + .setName('smell') + .setDescription('Who smells?') +} \ No newline at end of file diff --git a/src/database/MPPlayerData.json b/src/database/MPPlayerData.json index 79019e6..ca62ce0 100644 --- a/src/database/MPPlayerData.json +++ b/src/database/MPPlayerData.json @@ -1 +1 @@ -[1,2,3,4,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,4,3,3,4,5,4,4,4,4,4,4,4,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,4,4,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,2,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,5,5,5,6,6,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,6,6,5,5,5,5,5,5,7,6,6,7,7,7,7,7,8,7,8,8,8,8,8,8,8,9,9,9,9,9,10,9,9,9,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,6,6,6,6,6,6,6,6,5,5,4,3,3,3,3,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,1,1,1,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,5,5,5,5,4,4,4,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,1,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,9,9,9,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,9,10,11,11,11,11,11,11,11,11,12,12,12,12,13,13,13,13,13,11,11,11,11,11,11,12,12,12,12,11,11,11,11,11,10,11,11,11,10,11,11,11,11,11,12,12,12,12,12,12,12,12,11,11,11,10,10,9,9,9,8,8,8,8,8,8,9,9,9,9,9,9,8,8,8,8,8,8,8,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,4,4,5,5,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,3,3,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,2,3,3,4,4,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,4,4,4,4,3,3,3,3,4,4,3,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,4,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,2,1,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,3,2,2,3,3,3,3,2,2,2,3,3,2,2,2,2,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4] \ No newline at end of file +[1,2,3,4,5,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,4,4,3,3,4,5,4,4,4,4,4,4,4,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,3,3,4,4,5,5,5,5,5,5,5,5,5,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,0,0,0,2,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,5,5,5,5,6,6,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,6,6,5,5,5,5,5,5,7,6,6,7,7,7,7,7,8,7,8,8,8,8,8,8,8,9,9,9,9,9,10,9,9,9,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,6,6,6,6,6,6,6,6,5,5,4,3,3,3,3,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,1,1,1,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,4,4,4,4,4,4,4,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,4,4,4,4,4,4,4,4,4,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,5,5,5,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,5,5,5,5,5,4,4,4,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,1,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,5,5,5,5,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,9,9,9,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10,9,10,11,11,11,11,11,11,11,11,12,12,12,12,13,13,13,13,13,11,11,11,11,11,11,12,12,12,12,11,11,11,11,11,10,11,11,11,10,11,11,11,11,11,12,12,12,12,12,12,12,12,11,11,11,10,10,9,9,9,8,8,8,8,8,8,9,9,9,9,9,9,8,8,8,8,8,8,8,7,7,7,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,5,5,4,4,5,5,3,4,4,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,4,4,4,4,3,3,4,4,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,2,3,3,4,4,3,3,3,3,3,3,3,3,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,3,3,3,3,4,4,4,4,3,3,3,3,4,4,3,4,4,4,3,3,3,4,3,3,3,3,3,3,3,3,4,4,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,1,1,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,2,1,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,3,2,2,3,3,3,3,2,2,2,3,3,2,2,2,2,3,3,3,4,4,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,3,3,3,3,3,3,3,3,3,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,2,2,1,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,2,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,3,2,2,2,2,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] \ No newline at end of file diff --git a/src/database/dailyMsgs.json b/src/database/dailyMsgs.json index 9b40716..69dc649 100644 --- a/src/database/dailyMsgs.json +++ b/src/database/dailyMsgs.json @@ -1 +1 @@ -[[0,674965],[1,675885],[2,676639],[3,677245],[4,677609],[5,678188],[6,678916],[7,679465],[8,679938],[9,680540],[10,681614],[11,682079],[12,682780],[13,683187],[14,683547],[15,683900],[16,684592],[17,685466],[18,686078],[19,686481],[20,676748],[21,676968],[22,677427],[23,677592],[24,677894],[25,678116],[26,676785],[27,677570],[28,678491],[29,679137],[30,679818],[31,680094],[32,680417],[33,680783],[34,681563],[35,682070],[36,682670],[37,683504],[38,684078],[39,684383],[40,684692],[41,685448],[42,685664],[43,685994],[44,686366],[45,687118],[46,687626],[47,688008],[48,688754],[49,688942],[50,689107],[51,689472],[52,690143],[53,690644],[54,691124],[55,692196],[56,692624],[57,692906],[58,693456],[59,693952],[60,694586],[61,695070],[62,696163],[63,696564],[64,697315],[65,698548],[66,699138],[67,699558],[68,700307],[69,701063],[70,701394],[71,701868],[72,702453],[73,702917],[76,705187],[77,705243],[78,705488],[79,705961],[80,706585],[81,707467],[82,708212],[83,709024],[84,709773],[85,710256],[86,710980]] \ No newline at end of file +[[0,674965],[1,675885],[2,676639],[3,677245],[4,677609],[5,678188],[6,678916],[7,679465],[8,679938],[9,680540],[10,681614],[11,682079],[12,682780],[13,683187],[14,683547],[15,683900],[16,684592],[17,685466],[18,686078],[19,686481],[20,676748],[21,676968],[22,677427],[23,677592],[24,677894],[25,678116],[26,676785],[27,677570],[28,678491],[29,679137],[30,679818],[31,680094],[32,680417],[33,680783],[34,681563],[35,682070],[36,682670],[37,683504],[38,684078],[39,684383],[40,684692],[41,685448],[42,685664],[43,685994],[44,686366],[45,687118],[46,687626],[47,688008],[48,688754],[49,688942],[50,689107],[51,689472],[52,690143],[53,690644],[54,691124],[55,692196],[56,692624],[57,692906],[58,693456],[59,693952],[60,694586],[61,695070],[62,696163],[63,696564],[64,697315],[65,698548],[66,699138],[67,699558],[68,700307],[69,701063],[70,701394],[71,701868],[72,702453],[73,702917],[76,705187],[77,705243],[78,705488],[79,705961],[80,706585],[81,707467],[82,708212],[83,709024],[84,709773],[85,710256],[86,710980],[87,711220]] \ No newline at end of file diff --git a/src/database/userLevels.json b/src/database/userLevels.json index 1a06870..2f6478d 100644 --- a/src/database/userLevels.json +++ b/src/database/userLevels.json @@ -1,30 +1,30 @@ { "190407856527376384": { - "messages": 53029, + "messages": 53026, "level": 59 }, "593696856165449749": { - "messages": 51456, + "messages": 51467, "level": 58 }, "141304507249197057": { - "messages": 67631, + "messages": 67632, "level": 67 }, "533707949831487488": { - "messages": 57038, + "messages": 57042, "level": 61 }, "532662366354276352": { - "messages": 33775, + "messages": 33785, "level": 47 }, "824043915539513406": { - "messages": 18452, + "messages": 18457, "level": 35 }, "178941218510602240": { - "messages": 6394, + "messages": 6396, "level": 20 }, "215497515934416896": { @@ -32,15 +32,15 @@ "level": 46 }, "301350210926280704": { - "messages": 14334, + "messages": 14343, "level": 30 }, "695323013813633076": { - "messages": 14090, + "messages": 14092, "level": 30 }, "389237487094071337": { - "messages": 12254, + "messages": 12256, "level": 28 }, "716355511552966737": { @@ -68,7 +68,7 @@ "level": 20 }, "475037861725339649": { - "messages": 10201, + "messages": 10207, "level": 26 }, "392699530912727041": { @@ -76,15 +76,15 @@ "level": 18 }, "468837263577579524": { - "messages": 7695, + "messages": 7696, "level": 22 }, "734703851558535188": { - "messages": 20211, + "messages": 20224, "level": 36 }, "488683638310043677": { - "messages": 15477, + "messages": 15478, "level": 32 }, "606595407769894995": { @@ -92,7 +92,7 @@ "level": 39 }, "322835877027905547": { - "messages": 10019, + "messages": 10021, "level": 25 }, "485793265568841728": { @@ -100,7 +100,7 @@ "level": 50 }, "837979120142778388": { - "messages": 3636, + "messages": 3637, "level": 15 }, "509467946146332682": { @@ -112,7 +112,7 @@ "level": 18 }, "690090143008555064": { - "messages": 9978, + "messages": 9981, "level": 25 }, "849633082440941628": { @@ -124,7 +124,7 @@ "level": 6 }, "452576735494406175": { - "messages": 1684, + "messages": 1685, "level": 10 }, "763055599654666291": { @@ -148,8 +148,8 @@ "level": 0 }, "169891949464125441": { - "messages": 538, - "level": 5 + "messages": 541, + "level": 6 }, "718453763932946432": { "messages": 13549, @@ -164,7 +164,7 @@ "level": 6 }, "931816463113814066": { - "messages": 673, + "messages": 674, "level": 6 }, "958108557503524904": { @@ -224,11 +224,11 @@ "level": 0 }, "528003225375473674": { - "messages": 79, + "messages": 80, "level": 2 }, "645342896312156181": { - "messages": 693, + "messages": 696, "level": 6 }, "488505753133645826": { @@ -236,7 +236,7 @@ "level": 0 }, "313461397457600512": { - "messages": 79, + "messages": 80, "level": 2 }, "848489550065827850": { @@ -272,8 +272,8 @@ "level": 1 }, "771433946890108989": { - "messages": 21, - "level": 0 + "messages": 22, + "level": 1 }, "847575717369872384": { "messages": 10, @@ -348,7 +348,7 @@ "level": 0 }, "549295707304099846": { - "messages": 46, + "messages": 47, "level": 1 }, "759390179064283178": { @@ -512,7 +512,7 @@ "level": 0 }, "660117183699091506": { - "messages": 9, + "messages": 10, "level": 0 }, "634416842152345630": { @@ -524,7 +524,7 @@ "level": 0 }, "398164488077180938": { - "messages": 8, + "messages": 9, "level": 0 }, "818595993121062974": { @@ -540,7 +540,7 @@ "level": 0 }, "869718328313278555": { - "messages": 98, + "messages": 101, "level": 2 }, "772197160372404234": { @@ -1340,7 +1340,7 @@ "level": 0 }, "98464148379148288": { - "messages": 1504, + "messages": 1507, "level": 10 }, "1025723411680460840": { @@ -1472,7 +1472,7 @@ "level": 0 }, "889624632724963329": { - "messages": 51, + "messages": 54, "level": 1 }, "687692546314600530": { @@ -1856,7 +1856,7 @@ "level": 0 }, "1031950921233600662": { - "messages": 17, + "messages": 19, "level": 1 }, "907951346769092618": { @@ -1924,7 +1924,7 @@ "level": 0 }, "813866707365265419": { - "messages": 114, + "messages": 119, "level": 2 }, "726188513518813275": { @@ -2048,7 +2048,7 @@ "level": 0 }, "1023915974690340946": { - "messages": 21, + "messages": 22, "level": 1 }, "871113268633174128": { @@ -2312,7 +2312,7 @@ "level": 0 }, "231907580748759040": { - "messages": 2, + "messages": 3, "level": 0 }, "461177771801182223": { @@ -2320,7 +2320,7 @@ "level": 0 }, "1029465066174677132": { - "messages": 11, + "messages": 12, "level": 0 }, "387345064927428611": { @@ -2544,7 +2544,7 @@ "level": 0 }, "697953686487564348": { - "messages": 123, + "messages": 128, "level": 2 }, "664233182941413427": { @@ -2592,7 +2592,7 @@ "level": 0 }, "340587045250531358": { - "messages": 86, + "messages": 90, "level": 2 }, "911709434554777660": { @@ -2680,7 +2680,7 @@ "level": 0 }, "999736341220839464": { - "messages": 9, + "messages": 11, "level": 0 }, "901565970974392331": { @@ -2700,7 +2700,7 @@ "level": 0 }, "995622955897864272": { - "messages": 92, + "messages": 96, "level": 2 }, "153323923633733632": { @@ -2772,6 +2772,10 @@ "level": 0 }, "248226483967885312": { + "messages": 3, + "level": 0 + }, + "985545842368864326": { "messages": 2, "level": 0 } diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts index 7191565..1a5b100 100644 --- a/src/events/messageDelete.ts +++ b/src/events/messageDelete.ts @@ -7,10 +7,12 @@ export default { const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel; if (msg.partial) return; if (msg.author.bot) return; - const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${msg.author.tag} (${msg.author.id})`, iconURL: `${msg.author.displayAvatarURL()}`}).setTitle('Message deleted').setDescription(`<@${msg.author.id}>\nContent:\n\`\`\`\n${msg.content}\n\`\`\`\nChannel: <#${msg.channelId}>`) - channel.send({embeds: [embed]}) + const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setAuthor({name: `Author: ${msg.author.tag} (${msg.author.id})`, iconURL: `${msg.author.displayAvatarURL()}`}).setTitle('Message deleted').setDescription(`<@${msg.author.id}>\nContent:\n\`\`\`\n${msg?.content}\n\`\`\`\nChannel: <#${msg.channelId}>`) + let image; if (msg.attachments?.first()?.width && ['png', 'jpeg', 'jpg', 'gif', 'webp'].some(x=>((msg.attachments.first() as Discord.Attachment).name as string).endsWith(x))) { - embed.setImage(`${[msg.attachments?.first() as Discord.Attachment]}`) + image = msg.attachments?.first().url + embed.setImage(image) } + channel.send({embeds: [embed]}) } } \ No newline at end of file diff --git a/src/events/messageDeleteBulk.ts b/src/events/messageDeleteBulk.ts index ef10c41..7e6c006 100644 --- a/src/events/messageDeleteBulk.ts +++ b/src/events/messageDeleteBulk.ts @@ -5,11 +5,11 @@ export default { execute: async(client:TClient, messages:Discord.Collection)=>{ const channel = client.channels.resolve(client.config.mainServer.channels.logs) as Discord.TextChannel; if (!client.config.botSwitches.logs) return; - let text = ''; + let msgArray: Array = []; messages.forEach((m)=>{ - text += `${m.author.username}: ${m.content}\n`; + msgArray.push(`${m.author.username}: ${m.content}`); }); - const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setTitle(`${messages.size} messages were purged`).setDescription(`\`\`\`${text}\`\`\``.slice(0,3900)).addFields({name: 'Channel', value: `<#${(messages.first() as Discord.Message).channel.id}>`}); + const embed = new client.embed().setColor(client.config.embedColorRed).setTimestamp().setTitle(`${messages.size} messages were purged`).setDescription(`\`\`\`${msgArray.reverse().join('\n')}\`\`\``.slice(0,3900)).addFields({name: 'Channel', value: `<#${(messages.first() as Discord.Message).channel.id}>`}); channel.send({embeds: [embed]}) } } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 1b13846..9ccb93d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,10 @@ -interface punOpt { - time?: string, - reason?: string, - interaction?: any -} import Discord from 'discord.js'; import { TClient } from './client'; const client = new TClient; client.init(); import fs from 'node:fs'; import MPDB from './models/MPServer'; -import { Punishment } from './typings/interfaces'; +import { Punishment, punOpt } from './typings/interfaces'; client.on('ready', async()=>{ client.guilds.cache.forEach(async(e: { members: { fetch: () => any; }; })=>{await e.members.fetch()}); @@ -190,7 +185,7 @@ Object.assign(client.punishments,{ const banData: Punishment = {type, id: this.createId(), member: member.id, moderator, time: now}; let dm1:any; try { - dm1 = await member.send(`You've been banned from ${interaction.guild.name} ${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${banData.id})`) + dm1 = await member.send(`You've been banned from ${interaction.guild.name} ${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${banData.id})`) } catch (err) { setTimeout(()=>interaction.channel.send('Failed to DM user.'), 500) } @@ -209,7 +204,7 @@ Object.assign(client.punishments,{ this.forceSave(); return new client.embed().setColor(client.config.embedColor).setTitle(`Case #${banData.id}: Ban`).setDescription(`${member.tag}\n<@${member.id}>\n(\`${member.id}\`)`).addFields( {name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``}, - {name: 'Duration', value: `${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'}`} + {name: 'Duration', value: `${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'}`} ) } case 'softban': @@ -253,7 +248,7 @@ Object.assign(client.punishments,{ case 'mute': const muteData: Punishment = {type, id: this.createId(), member: member.user.id, moderator, time: now}; let muteResult; - const dm4 = await member.send(`You've been muted in ${member.guild.name} ${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${muteData.id})`).catch((err:Error)=>setTimeout(()=>interaction.channel.send('Failed to DM user.'), 500)); + const dm4 = await member.send(`You've been muted in ${member.guild.name} ${timeInMillis ? `for ${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}` : 'forever'} for reason \`${reason || 'Reason unspecified'}\` (Case #${muteData.id})`).catch((err:Error)=>setTimeout(()=>interaction.channel.send('Failed to DM user.'), 500)); if (timeInMillis){ muteResult = await member.timeout(timeInMillis, `${reason || 'Reason unspecified'} | Case #${muteData.id}`).catch((err: Error)=>err.message); } else { @@ -273,7 +268,7 @@ Object.assign(client.punishments,{ this.forceSave(); const embedm = new client.embed().setColor(client.config.embedColor).setTitle(`Case #${muteData.id}: Mute`).setDescription(`${member.user.tag}\n<@${member.user.id}>\n(\`${member.user.id}\`)`).addFields( {name: 'Reason', value: `\`${reason || 'Reason unspecified'}\``}, - {name: 'Duration', value: `${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})} (${timeInMillis}ms)`} + {name: 'Duration', value: `${client.formatTime(timeInMillis, 4, {longNames: true, commas: true})}`} ) if (moderator !== '795443537356521502') {return embedm}; } @@ -328,7 +323,7 @@ Object.assign(client.punishments,{ client.makeModlogEntry(removePunishmentData, client); this._content[this._content.findIndex(x=>x.id === punishment.id)].expired = true; this.addData(removePunishmentData).forceSave(); - return `Successfully ${punishment.type === 'ban' ? 'unbanned' : 'unmuted'} ${removePunishmentResult?.tag} (\`${removePunishmentResult?.id}\`) for reason \`${reason || 'Reason unspecified'}\``; + return `Successfully ${punishment.type === 'ban' ? 'unbanned' : 'unmuted'} **${removePunishmentResult?.tag}** (\`${removePunishmentResult?.id}\`) for reason \`${reason || 'Reason unspecified'}\``; } } else { try {