{ "version": 3, "sources": ["../../../server/chat-plugins/permalocks.ts"], "sourcesContent": ["/**\n * Wrapper to facilitate posting / interacting with Smogon.\n * By Mia.\n * @author mia-pi-git\n */\nimport { Net, FS, Utils } from '../../lib';\n\nexport interface Nomination {\n\tby: ID;\n\tips: string[];\n\tinfo: string;\n\tdate: number;\n\tstanding: string;\n\talts: string[];\n\tprimaryID: ID;\n\tclaimed?: ID;\n\tpost?: string;\n}\n\ninterface IPData {\n\tcountry: string;\n\tisp: string;\n\tcity: string;\n\tregionName: string;\n\tlat: number;\n\tlon: number;\n}\n\nexport function getIPData(ip: string) {\n\ttry {\n\t\treturn Net(\"https://miapi.dev/api/ip/\" + ip).get().then(JSON.parse) as Promise;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport const Smogon = new class {\n\tasync post(threadNum: string, postText: string) {\n\t\tif (!Config.smogon) return null;\n\t\ttry {\n\t\t\tconst raw = await Net(`https://www.smogon.com/forums/api/posts`).get({\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tthread_id: threadNum,\n\t\t\t\t\tmessage: postText,\n\t\t\t\t}).toString(),\n\t\t\t\theaders: {\n\t\t\t\t\t'XF-Api-Key': Config.smogon,\n\t\t\t\t\t'Content-Type': 'application/x-www-form-urlencoded',\n\t\t\t\t},\n\t\t\t});\n\t\t\t// todo return URL of post\n\t\t\tconst data = JSON.parse(raw);\n\t\t\tif (data.errors?.length) {\n\t\t\t\tconst errData = data.errors.pop();\n\t\t\t\tthrow new Error(errData.message);\n\t\t\t}\n\t\t\treturn data;\n\t\t} catch (e: any) {\n\t\t\tif (e.message.includes('Not Found')) {\n\t\t\t\t// special case to be loud\n\t\t\t\tthrow new Error(\"WHO DELETED THE PERMA THREAD\");\n\t\t\t}\n\t\t\treturn { error: e.message };\n\t\t}\n\t}\n};\n\nexport const Nominations = new class {\n\tnoms: Nomination[] = [];\n\ticons: Record = {};\n\tconstructor() {\n\t\tthis.load();\n\t}\n\tload() {\n\t\ttry {\n\t\t\tlet data = JSON.parse(FS('config/chat-plugins/permas.json').readSync());\n\t\t\tif (Array.isArray(data)) {\n\t\t\t\tdata = { noms: data, icons: {} };\n\t\t\t\tFS('config/chat-plugins/permas.json').writeSync(JSON.stringify(data));\n\t\t\t}\n\t\t\tthis.noms = data.noms;\n\t\t\tthis.icons = data.icons;\n\t\t} catch {}\n\t}\n\tfetchModlog(id: string) {\n\t\treturn Rooms.Modlog.search('global', {\n\t\t\tuser: [{ search: id, isExact: true }],\n\t\t\tnote: [],\n\t\t\tip: [],\n\t\t\taction: [],\n\t\t\tactionTaker: [],\n\t\t}, undefined, true);\n\t}\n\tsave() {\n\t\tFS('config/chat-plugins/permas.json').writeUpdate(() => JSON.stringify({ noms: this.noms, icons: this.icons }));\n\t}\n\tnotifyStaff() {\n\t\tconst usRoom = Rooms.get('upperstaff');\n\t\tif (!usRoom) return;\n\t\tusRoom.send(`|uhtml|permanoms|${this.getDisplayButton()}`);\n\t\tChat.refreshPageFor('permalocks', usRoom);\n\t}\n\tasync add(target: string, connection: Connection) {\n\t\tconst user = connection.user;\n\t\tconst [primary, rawAlts, rawIps, type, details] = Utils.splitFirst(target, '|', 4).map(f => f.trim());\n\t\tconst primaryID = toID(primary);\n\t\tconst alts = rawAlts.split(',').map(toID).filter(Boolean);\n\t\tconst ips = rawIps.split(',').map(f => f.trim()).filter(Boolean);\n\t\tfor (const ip of ips) {\n\t\t\tif (!IPTools.ipRegex.test(ip)) this.error(`Invalid IP: ${ip}`, connection);\n\t\t}\n\t\tconst standings = this.getStandings();\n\t\tif (!standings[type]) {\n\t\t\tthis.error(`Invalid standing: ${type}.`, connection);\n\t\t}\n\t\tif (!details) {\n\t\t\tthis.error(\"Details must be provided. Explain why this user should be permalocked.\", connection);\n\t\t}\n\t\tif (!primaryID) {\n\t\t\tthis.error(\"A primary username must be provided. Use one of their alts if necessary.\", connection);\n\t\t}\n\t\tfor (const nom of this.noms) {\n\t\t\tif (nom.primaryID === primaryID) {\n\t\t\t\tthis.error(`'${primaryID}' was already nominated for permalock by ${nom.by}.`, connection);\n\t\t\t}\n\t\t}\n\t\tconst ipTable = new Set(ips);\n\t\tconst altTable = new Set([...alts]);\n\t\tfor (const alt of [primaryID, ...alts]) {\n\t\t\tconst modlog = await this.fetchModlog(alt);\n\t\t\tif (!modlog?.results.length) continue;\n\t\t\tfor (const entry of modlog.results) {\n\t\t\t\tif (entry.ip) ipTable.add(entry.ip);\n\t\t\t\tif (entry.autoconfirmedID) altTable.add(entry.autoconfirmedID);\n\t\t\t\tif (entry.alts) {\n\t\t\t\t\tfor (const id of entry.alts) altTable.add(id);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\taltTable.delete(primaryID);\n\t\tthis.noms.push({\n\t\t\tby: user.id,\n\t\t\talts: [...altTable],\n\t\t\tips: Utils.sortBy([...ipTable], z => -(IPTools.ipToNumber(z) || Infinity)),\n\t\t\tinfo: details,\n\t\t\tprimaryID,\n\t\t\tstanding: type,\n\t\t\tdate: Date.now(),\n\t\t});\n\t\tUtils.sortBy(this.noms, nom => -nom.date);\n\t\tthis.save();\n\t\tthis.notifyStaff();\n\t\tRooms.get('staff')?.addByUser(user, `${user.name} submitted a perma nomination for ${primaryID}`);\n\t}\n\tfind(id: string) {\n\t\treturn this.noms.find(f => f.primaryID === id);\n\t}\n\terror(message: string, conn: Connection): never {\n\t\tconn.popup(message);\n\t\tthrow new Chat.Interruption();\n\t}\n\tclose(target: string, context: Chat.CommandContext) {\n\t\tconst entry = this.find(target);\n\t\tif (!entry) {\n\t\t\tthis.error(`There is no nomination pending for '${toID(target)}'.`, context.connection);\n\t\t}\n\t\tthis.noms.splice(this.noms.findIndex(f => f.primaryID === entry.primaryID), 1);\n\t\tthis.save();\n\t\tthis.notifyStaff();\n\t\t// todo fix when on good comp\n\t\treturn context.closePage(`permalocks-view-${entry.primaryID}`);\n\t}\n\tdisplay(nom: Nomination, canEdit?: boolean) {\n\t\tlet buf = `
`;\n\t\tlet title = nom.primaryID as string;\n\t\tif (canEdit) {\n\t\t\ttitle = `${nom.primaryID}`;\n\t\t}\n\t\tbuf += `${title} (submitted by ${nom.by})
`;\n\t\tbuf += `Submitted ${Chat.toTimestamp(new Date(nom.date), { human: true })}
`;\n\t\tbuf += `${Chat.count(nom.alts, 'alts')}, ${Chat.count(nom.ips, 'IPs')}`;\n\t\tbuf += `
`;\n\t\treturn buf;\n\t}\n\tdisplayModlog(results: import('../modlog').ModlogEntry[] | null) {\n\t\tif (!results) return '';\n\t\tlet curDate = '';\n\t\treturn results.map(result => {\n\t\t\tconst date = new Date(result.time || Date.now());\n\t\t\tconst entryRoom = result.visualRoomID || result.roomID || 'global';\n\t\t\tlet [dateString, timestamp] = Chat.toTimestamp(date, { human: true }).split(' ');\n\t\t\tlet line = `[${timestamp}] (${entryRoom}) ${result.action}`;\n\t\t\tif (result.userid) {\n\t\t\t\tline += `: [${result.userid}]`;\n\t\t\t\tif (result.autoconfirmedID) line += ` ac: [${result.autoconfirmedID}]`;\n\t\t\t\tif (result.alts.length) line += ` alts: [${result.alts.join('], [')}]`;\n\t\t\t\tif (result.ip) line += ` [${result.ip}]`;\n\t\t\t}\n\n\t\t\tif (result.loggedBy) line += `: by ${result.loggedBy}`;\n\t\t\tif (result.note) line += Utils.html`: ${result.note}`;\n\n\t\t\tif (dateString !== curDate) {\n\t\t\t\tcurDate = dateString;\n\t\t\t\tdateString = `

[${dateString}]
`;\n\t\t\t} else {\n\t\t\t\tdateString = ``;\n\t\t\t}\n\t\t\tconst thisRoomID = entryRoom?.split(' ')[0];\n\t\t\tif (thisRoomID.startsWith('battle-')) {\n\t\t\t\ttimestamp = `${timestamp}`;\n\t\t\t} else {\n\t\t\t\tconst [day, time] = Chat.toTimestamp(date).split(' ');\n\t\t\t\ttimestamp = `${timestamp}`;\n\t\t\t}\n\t\t\treturn `${dateString}${line}`;\n\t\t}).join(`
`);\n\t}\n\tasync displayActionPage(nom: Nomination) {\n\t\tlet buf = `

`;\n\t\tconst standings = this.getStandings();\n\t\tbuf += ``;\n\t\tbuf += `

Nomination: ${nom.primaryID}


`;\n\t\tbuf += `By: ${nom.by} (on ${Chat.toTimestamp(new Date(nom.date))})
`;\n\t\tbuf += `Recommended punishment: ${standings[nom.standing]}
`;\n\t\tbuf += `
Modlog`;\n\t\tbuf += `
`;\n\t\tconst modlog = await this.fetchModlog(nom.primaryID);\n\t\tif (!modlog) {\n\t\t\tbuf += `None found.`;\n\t\t} else {\n\t\t\tbuf += this.displayModlog(modlog.results);\n\t\t}\n\t\tbuf += `
`;\n\t\tif (nom.alts.length) {\n\t\t\tbuf += `
Listed alts`;\n\t\t\tfor (const [i, alt] of nom.alts.entries()) {\n\t\t\t\tbuf += `- ${alt}: `;\n\t\t\t\tbuf += `
`;\n\t\t\t\tbuf += this.standingDropdown(\"standing\");\n\t\t\t\tbuf += ` `;\n\t\t\t\tbuf += ` `;\n\t\t\t\tbuf += `
`;\n\t\t\t\tif (nom.alts[i + 1]) buf += `
`;\n\t\t\t}\n\t\t\tbuf += `
`;\n\t\t}\n\t\tif (nom.ips.length) {\n\t\t\tbuf += `
Listed IPs`;\n\t\t\tfor (const [i, ip] of nom.ips.entries()) {\n\t\t\t\tconst ipData = await getIPData(ip);\n\t\t\t\tbuf += `- ${ip}`;\n\t\t\t\tif (ipData) {\n\t\t\t\t\tbuf += `(ISP: ${ipData.isp}, loc: ${ipData.city}, ${ipData.regionName} in ${ipData.country})`;\n\t\t\t\t}\n\t\t\t\tbuf += `: `;\n\t\t\t\tbuf += `
`;\n\t\t\t\tbuf += this.standingDropdown(\"standing\");\n\t\t\t\tbuf += ` `;\n\t\t\t\tbuf += ` `;\n\t\t\t\tbuf += `
`;\n\t\t\t\tif (nom.ips[i + 1]) buf += `
`;\n\t\t\t}\n\t\t\tbuf += `
`;\n\t\t}\n\t\tconst [matches] = await LoginServer.request('ipmatches', {\n\t\t\tid: nom.primaryID,\n\t\t});\n\t\tif (matches?.results?.length) {\n\t\t\tbuf += `
Registration IP matches`;\n\t\t\tfor (const [i, { userid, banstate }] of matches.results.entries()) {\n\t\t\t\tbuf += `- ${userid}: `;\n\t\t\t\tbuf += `
`;\n\t\t\t\tbuf += this.standingDropdown(\"standing\", `${banstate}`);\n\t\t\t\tbuf += `
`;\n\t\t\t\tif (matches.results[i + 1]) buf += `
`;\n\t\t\t}\n\t\t\tbuf += `
`;\n\t\t}\n\t\tbuf += `

Staff notes:

`;\n\t\tbuf += `

${Chat.formatText(nom.info).replace(/\\n/ig, '
')}

`;\n\t\tbuf += `
Act on primary:`;\n\t\tbuf += `
`;\n\t\tbuf += `Standing: ${this.standingDropdown('standing')}`;\n\t\tbuf += `
Notes:
`;\n\t\tbuf += `
`;\n\t\tbuf += ``;\n\t\tbuf += `

`;\n\t\tbuf += ``;\n\t\treturn buf;\n\t}\n\tstandingDropdown(elemName: string, curStanding: string | null = null) {\n\t\tlet buf = ``;\n\t\treturn buf;\n\t}\n\tgetStandings() {\n\t\tif (Config.standings) return Config.standings;\n\t\tConfig.standings = {\n\t\t\t'-20': \"Confirmed\",\n\t\t\t'-10': \"Autoconfirmed\",\n\t\t\t'0': \"New\",\n\t\t\t\"20\": \"Permalock\",\n\t\t\t\"30\": \"Permaban\",\n\t\t\t\"100\": \"Disabled\",\n\t\t};\n\t\treturn Config.standings;\n\t}\n\tdisplayAll(canEdit: boolean) {\n\t\tlet buf = `
`;\n\t\tbuf += ``;\n\t\tbuf += `

Pending perma nominations


`;\n\t\tif (!this.noms.length) {\n\t\t\tbuf += `None found.`;\n\t\t\treturn buf;\n\t\t}\n\t\tfor (const nom of this.noms) {\n\t\t\tbuf += this.display(nom, canEdit);\n\t\t\tbuf += `
`;\n\t\t}\n\t\treturn buf;\n\t}\n\tdisplayNomPage() {\n\t\tlet buf = `

Make a nomination for a permanent punishment.


`;\n\t\t// const [primary, rawAlts, rawIps, details] = Utils.splitFirst(target, '|', 3).map(f => f.trim());\n\t\tbuf += `
`;\n\t\tbuf += `
`;\n\t\tbuf += `Primary userid:
`;\n\t\tbuf += `Alts:

(Separated by commas)
`;\n\t\tbuf += `Static IPs:

(Separated by commas)

`;\n\t\tbuf += `Punishment: `;\n\t\tbuf += ``;\n\t\tbuf += `
`;\n\t\tbuf += `Please explain why this user deserves a permanent punishment
`;\n\t\tbuf += `Note: Modlogs are automatically included in review and do not need to be added here.
`;\n\t\tbuf += `
`;\n\t\tbuf += ``;\n\t\treturn buf;\n\t}\n\tgetDisplayButton() {\n\t\tconst unclaimed = this.noms.filter(f => !f.claimed);\n\t\tlet buf = `
`;\n\t\tif (!this.noms.length) {\n\t\t\tbuf += `No permalock nominations active.`;\n\t\t} else {\n\t\t\tlet className = 'button';\n\t\t\tif (unclaimed.length) className += ' notifying';\n\t\t\tbuf += ``;\n\t\t}\n\t\tbuf += `
`;\n\t\treturn buf;\n\t}\n};\n\nexport const commands: Chat.ChatCommands = {\n\tperma: {\n\t\t''(target, room, user) {\n\t\t\tthis.checkCan('lock');\n\t\t\tif (!user.can('rangeban')) {\n\t\t\t\treturn this.parse(`/j view-permalocks-submit`);\n\t\t\t} else {\n\t\t\t\treturn this.parse(`/j view-permalocks-list`);\n\t\t\t}\n\t\t},\n\t\tviewnom(target) {\n\t\t\tthis.checkCan('rangeban');\n\t\t\treturn this.parse(`/j view-permalocks-view-${toID(target)}`);\n\t\t},\n\t\tsubmit(target, room, user) {\n\t\t\tthis.checkCan('lock');\n\t\t\treturn Nominations.add(target, this.connection);\n\t\t},\n\t\tlist() {\n\t\t\tthis.checkCan('lock');\n\t\t\treturn this.parse(`/j view-permalocks-list`);\n\t\t},\n\t\tnom() {\n\t\t\tthis.checkCan('lock');\n\t\t\treturn this.parse(`/j view-permalocks-submit`);\n\t\t},\n\t\tasync actmain(target, room, user) {\n\t\t\tthis.checkCan('rangeban');\n\t\t\tconst [primaryName, standingName, postReason] = Utils.splitFirst(target, ',', 2).map(f => f.trim());\n\t\t\tconst primary = toID(primaryName);\n\t\t\tif (!primary) return this.popupReply(`Invalid primary username.`);\n\t\t\tconst nom = Nominations.find(primary);\n\t\t\tif (!nom) return this.popupReply(`No permalock nomination found for ${primary}.`);\n\t\t\tconst standing = parseInt(standingName);\n\t\t\tconst standings = Nominations.getStandings();\n\t\t\tif (!standings[standing]) return this.popupReply(`Invalid standing.`);\n\t\t\tif (!toID(postReason)) return this.popupReply(`A reason must be given.`);\n\t\t\t// todo thread num\n\t\t\tconst threadNum = Config.permathread;\n\t\t\tif (!threadNum) {\n\t\t\t\tthrow new Chat.ErrorMessage(\"The link to the perma has not been set - the post could not be made.\");\n\t\t\t}\n\t\t\tlet postBuf = `[b][url=\"https://${Config.routes.root}/users/${primary}\"]${primary}[/url][/b]`;\n\t\t\tconst icon = Nominations.icons[user.id] ? `:${Nominations.icons[user.id]}: - ` : ``;\n\t\t\tpostBuf += ` was added to ${standings[standing]} by ${user.name} (${icon}${postReason}).\\n`;\n\t\t\tpostBuf += `Nominated by ${nom.by}.\\n[spoiler=Nomination notes]${nom.info}[/spoiler]\\n`;\n\t\t\tpostBuf += `${nom.alts.length ? `[spoiler=Alts]${nom.alts.join(', ')}[/spoiler]` : \"\"}\\n`;\n\t\t\tif (nom.ips.length) {\n\t\t\t\tpostBuf += `[spoiler=IPs]`;\n\t\t\t\tfor (const ip of nom.ips) {\n\t\t\t\t\tconst ipData = await getIPData(ip);\n\t\t\t\t\tpostBuf += `- [url=https://whatismyipaddress.com/ip/${ip}]${ip}[/url]`;\n\t\t\t\t\tif (ipData) {\n\t\t\t\t\t\tpostBuf += ` (ISP: ${ipData.isp}, loc: ${ipData.city}, ${ipData.regionName} in ${ipData.country})`;\n\t\t\t\t\t}\n\t\t\t\t\tpostBuf += '\\n';\n\t\t\t\t}\n\t\t\t\tpostBuf += `[/spoiler]`;\n\t\t\t}\n\n\t\t\tconst modlog = await Nominations.fetchModlog(nom.primaryID);\n\t\t\tif (modlog?.results.length) {\n\t\t\t\tlet rawHTML = Nominations.displayModlog(modlog.results);\n\t\t\t\trawHTML = rawHTML.replace(/
/g, '\\n');\n\t\t\t\trawHTML = Utils.stripHTML(rawHTML);\n\t\t\t\trawHTML = rawHTML.replace(///g, '/');\n\t\t\t\tpostBuf += `\\n[spoiler=Modlog]${rawHTML}[/spoiler]`;\n\t\t\t}\n\n\t\t\tconst res = await Smogon.post(\n\t\t\t\tthreadNum,\n\t\t\t\tpostBuf,\n\t\t\t);\n\t\t\tif (!res || res.error) {\n\t\t\t\treturn this.popupReply(`Error making post: ${res?.error}`);\n\t\t\t}\n\t\t\tconst url = `https://smogon.com/forums/threads/${threadNum}/post-${res.post.post_id}`;\n\t\t\tconst result = await LoginServer.request('setstanding', {\n\t\t\t\tuser: primary,\n\t\t\t\tstanding,\n\t\t\t\treason: url,\n\t\t\t\tactor: user.id,\n\t\t\t});\n\t\t\tif (result[1]) {\n\t\t\t\treturn this.popupReply(`Error changing standing: ${result[1].message}`);\n\t\t\t}\n\t\t\tnom.post = url;\n\t\t\tthis.popupReply(`|html|Standing successfully changed. Smogon post can be found at this link.`);\n\t\t},\n\t\tasync standing(target) {\n\t\t\tthis.checkCan('rangeban');\n\t\t\tconst [name, rawStanding, reason] = Utils.splitFirst(target, ',', 2).map(f => f.trim());\n\t\t\tconst id = toID(name);\n\t\t\tif (!id || id.length > 18) {\n\t\t\t\treturn this.popupReply('Invalid username: ' + name);\n\t\t\t}\n\t\t\tconst standingNum = parseInt(rawStanding);\n\t\t\tif (!standingNum) {\n\t\t\t\treturn this.popupReply(`Invalid standing: ` + rawStanding);\n\t\t\t}\n\t\t\tif (!reason.length) {\n\t\t\t\treturn this.popupReply(`A reason must be given.`);\n\t\t\t}\n\t\t\tconst res = await LoginServer.request('setstanding', {\n\t\t\t\tuser: id,\n\t\t\t\tstanding: standingNum,\n\t\t\t\treason,\n\t\t\t\tactor: this.user.id,\n\t\t\t});\n\t\t\tif (res[1]) {\n\t\t\t\treturn this.popupReply(`Error in standing change: ` + res[1].message);\n\t\t\t}\n\t\t\tthis.popupReply(`Standing successfully changed to ${standingNum} for ${id}.`);\n\t\t\t// no need to modlog, is in usermodlog already\n\t\t},\n\t\tasync ipstanding(target) {\n\t\t\tthis.checkCan('rangeban');\n\t\t\tconst [ip, standingName, reason] = Utils.splitFirst(target, ',', 2).map(f => f.trim());\n\t\t\tif (!IPTools.ipToNumber(ip)) {\n\t\t\t\treturn this.popupReply(`Invalid IP: ${ip}`);\n\t\t\t}\n\t\t\tconst standingNum = parseInt(standingName);\n\t\t\tif (!Config.standings[`${standingNum}`]) {\n\t\t\t\treturn this.popupReply(`Invalid standing: ${standingName}.`);\n\t\t\t}\n\t\t\tif (!reason.length) {\n\t\t\t\treturn this.popupReply('Specify a reason.');\n\t\t\t}\n\t\t\tconst res = await LoginServer.request('ipstanding', {\n\t\t\t\treason,\n\t\t\t\tstanding: standingNum,\n\t\t\t\tip,\n\t\t\t\tactor: this.user.id,\n\t\t\t});\n\t\t\tif (res[1]) {\n\t\t\t\treturn this.popupReply(`Error changing standing: ${res[1].message}`);\n\t\t\t}\n\t\t\tthis.popupReply(`All standings on the IP ${ip} changed successfully to ${standingNum}.`);\n\t\t\tthis.globalModlog(`IPSTANDING`, null, `${standingNum}${reason ? ` (${reason})` : \"\"}`, ip);\n\t\t},\n\t\tresolve(target) {\n\t\t\tthis.checkCan('rangeban');\n\t\t\tNominations.close(target, this);\n\t\t},\n\t\tseticon(target, room, user) {\n\t\t\tthis.checkCan('rangeban');\n\t\t\tlet [monName, targetId] = target.split(',');\n\t\t\tif (!targetId) targetId = user.id;\n\t\t\tconst mon = Dex.species.get(monName);\n\t\t\tif (!mon.exists) {\n\t\t\t\treturn this.errorReply(`Species ${monName} does not exist.`);\n\t\t\t}\n\t\t\tNominations.icons[targetId] = mon.name.toLowerCase();\n\t\t\tNominations.save();\n\t\t\tthis.sendReply(\n\t\t\t\t`|html|Updated ${targetId === user.id ? 'your' : `${targetId}'s`} permalock post icon to ` +\n\t\t\t\t``\n\t\t\t);\n\t\t},\n\t\tdeleteicon(target, room, user) {\n\t\t\tthis.checkCan('rangeban');\n\t\t\tconst targetID = toID(target);\n\t\t\tif (!Nominations.icons[targetID]) {\n\t\t\t\treturn this.errorReply(`${targetID} does not have an icon set.`);\n\t\t\t}\n\t\t\tdelete Nominations.icons[targetID];\n\t\t\tNominations.save();\n\t\t\tthis.sendReply(`Removed ${targetID}'s permalock post icon.`);\n\t\t},\n\t\thelp: [\n\t\t\t'/perma nom OR /perma - Open the page to make a nomination for a permanent punishment. Requires: % @ ~',\n\t\t\t'/perma list - View open nominations. Requires: % @ ~',\n\t\t\t'/perma viewnom [userid] - View a nomination for the given [userid]. Requires: ~',\n\t\t],\n\t},\n};\n\nexport const pages: Chat.PageTable = {\n\tpermalocks: {\n\t\tlist(query, user, conn) {\n\t\t\tthis.checkCan('lock');\n\t\t\tthis.title = '[Permalock Nominations]';\n\t\t\treturn Nominations.displayAll(user.can('rangeban'));\n\t\t},\n\t\tview(query, user) {\n\t\t\tthis.checkCan('rangeban');\n\t\t\tconst id = toID(query.shift());\n\t\t\tif (!id) return this.errorReply(`Invalid userid.`);\n\t\t\tconst nom = Nominations.find(id);\n\t\t\tif (!nom) return this.errorReply(`No nomination found for '${id}'.`);\n\t\t\tthis.title = `[Perma Nom] ${nom.primaryID}`;\n\t\t\treturn Nominations.displayActionPage(nom);\n\t\t},\n\t\tsubmit() {\n\t\t\tthis.checkCan('lock');\n\t\t\tthis.title = '[Perma Nom] Create';\n\t\t\treturn Nominations.displayNomPage();\n\t\t},\n\t},\n};\n\nprocess.nextTick(() => {\n\tChat.multiLinePattern.register('/perma(noms?)? ');\n});\n"], "mappings": "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", "names": [] }