From 446510d021e28449de459fcfbc2515b39e5558a0 Mon Sep 17 00:00:00 2001 From: Avril Date: Sun, 21 Jun 2020 06:36:22 +0100 Subject: [PATCH] test --- common.js | 1530 ++++++++++++++++++++++--------------------- server/amusement.js | 294 +++++---- 2 files changed, 920 insertions(+), 904 deletions(-) diff --git a/common.js b/common.js index a3bb030..e8fdf39 100644 --- a/common.js +++ b/common.js @@ -42,159 +42,159 @@ DEFINES.S_QUOTE = 2; DEFINES.S_BIG = 4; function initial_state() { - // state[0] = output mode - // state[1] = number of spoiler tags we're inside - return [DEFINES.S_BOL, 0]; + // state[0] = output mode + // state[1] = number of spoiler tags we're inside + return [DEFINES.S_BOL, 0]; } exports.initial_state = initial_state; if (typeof mediaURL == 'undefined' || !mediaURL) - mediaURL = imagerConfig.MEDIA_URL; + mediaURL = imagerConfig.MEDIA_URL; function is_pubsub(t) { - return t > 0 && t < 30; + return t > 0 && t < 30; } exports.is_pubsub = is_pubsub; function FSM(start) { - this.state = start; - this.spec = {acts: {}, ons: {}, wilds: {}, preflights: {}}; + this.state = start; + this.spec = {acts: {}, ons: {}, wilds: {}, preflights: {}}; } exports.FSM = FSM; FSM.prototype.clone = function () { - var second = new FSM(this.state); - second.spec = this.spec; - return second; + var second = new FSM(this.state); + second.spec = this.spec; + return second; }; // Handlers on arriving to a new state FSM.prototype.on = function (key, f) { - var ons = this.spec.ons[key]; - if (ons) - ons.push(f); - else - this.spec.ons[key] = [f]; - return this; + var ons = this.spec.ons[key]; + if (ons) + ons.push(f); + else + this.spec.ons[key] = [f]; + return this; }; // Sanity checks before attempting a transition FSM.prototype.preflight = function (key, f) { - var pres = this.spec.preflights[key]; - if (pres) - pres.push(f); - else - this.spec.preflights[key] = [f]; + var pres = this.spec.preflights[key]; + if (pres) + pres.push(f); + else + this.spec.preflights[key] = [f]; }; // Specify transitions and an optional handler function FSM.prototype.act = function (trans_spec, on_func) { - var halves = trans_spec.split('->'); - if (halves.length != 2) - throw new Error("Bad FSM spec: " + trans_spec); - var parts = halves[0].split(','); - var dest = halves[1].match(/^\s*(\w+)\s*$/)[1]; - var tok; - for (var i = parts.length-1; i >= 0; i--) { - var part = parts[i]; - var m = part.match(/^\s*(\*|\w+)\s*(?:\+\s*(\w+)\s*)?$/); - if (!m) - throw new Error("Bad FSM spec portion: " + part); - if (m[2]) - tok = m[2]; - if (!tok) - throw new Error("Tokenless FSM action: " + part); - var src = m[1]; - if (src == '*') - this.spec.wilds[tok] = dest; - else { - var acts = this.spec.acts[src]; - if (!acts) - this.spec.acts[src] = acts = {}; - acts[tok] = dest; - } + var halves = trans_spec.split('->'); + if (halves.length != 2) + throw new Error("Bad FSM spec: " + trans_spec); + var parts = halves[0].split(','); + var dest = halves[1].match(/^\s*(\w+)\s*$/)[1]; + var tok; + for (var i = parts.length-1; i >= 0; i--) { + var part = parts[i]; + var m = part.match(/^\s*(\*|\w+)\s*(?:\+\s*(\w+)\s*)?$/); + if (!m) + throw new Error("Bad FSM spec portion: " + part); + if (m[2]) + tok = m[2]; + if (!tok) + throw new Error("Tokenless FSM action: " + part); + var src = m[1]; + if (src == '*') + this.spec.wilds[tok] = dest; + else { + var acts = this.spec.acts[src]; + if (!acts) + this.spec.acts[src] = acts = {}; + acts[tok] = dest; } - if (on_func) - this.on(dest, on_func); - return this; + } + if (on_func) + this.on(dest, on_func); + return this; }; FSM.prototype.feed = function (ev, param) { - var spec = this.spec; - var from = this.state, acts = spec.acts[from]; - var to = (acts && acts[ev]) || spec.wilds[ev]; - if (to && from != to) { - var ps = spec.preflights[to]; - for (var i = 0; ps && i < ps.length; i++) - if (!ps[i].call(this, param)) - return false; - this.state = to; - var fs = spec.ons[to]; - for (var i = 0; fs && i < fs.length; i++) - fs[i].call(this, param); - } - return true; + var spec = this.spec; + var from = this.state, acts = spec.acts[from]; + var to = (acts && acts[ev]) || spec.wilds[ev]; + if (to && from != to) { + var ps = spec.preflights[to]; + for (var i = 0; ps && i < ps.length; i++) + if (!ps[i].call(this, param)) + return false; + this.state = to; + var fs = spec.ons[to]; + for (var i = 0; fs && i < fs.length; i++) + fs[i].call(this, param); + } + return true; }; FSM.prototype.feeder = function (ev) { - var self = this; - return function (param) { - self.feed(ev, param); - }; + var self = this; + return function (param) { + self.feed(ev, param); + }; }; var entities = {'&' : '&', '<': '<', '>': '>', '"': '"'}; function escape_html(html) { - return html.replace(/[&<>"]/g, function (c) { - return entities[c]; - }); + return html.replace(/[&<>"]/g, function (c) { + return entities[c]; + }); } exports.escape_html = escape_html; function escape_fragment(frag) { - var t = typeof(frag); - if (t == 'object' && frag && typeof(frag.safe) == 'string') - return frag.safe; - else if (t == 'string') - return escape_html(frag); - else if (t == 'number') - return frag.toString(); - else - return '???'; + var t = typeof(frag); + if (t == 'object' && frag && typeof(frag.safe) == 'string') + return frag.safe; + else if (t == 'string') + return escape_html(frag); + else if (t == 'number') + return frag.toString(); + else + return '???'; } exports.escape_fragment = escape_fragment; function flatten(frags) { - var out = []; - for (var i = 0; i < frags.length; i++) { - var frag = frags[i]; - if (Array.isArray(frag)) - out = out.concat(flatten(frag)); - else - out.push(escape_fragment(frag)); - } - return out; + var out = []; + for (var i = 0; i < frags.length; i++) { + var frag = frags[i]; + if (Array.isArray(frag)) + out = out.concat(flatten(frag)); + else + out.push(escape_fragment(frag)); + } + return out; } exports.flatten = flatten; function safe(frag) { - return {safe: frag}; + return {safe: frag}; } exports.safe = safe; function is_noko(email) { - return email && email.indexOf('@') == -1 && /noko/i.test(email); + return email && email.indexOf('@') == -1 && /noko/i.test(email); } exports.is_noko = is_noko; function is_sage(email) { - return config.SAGE_ENABLED && email && - email.indexOf('@') == -1 && /sage/i.test(email); + return config.SAGE_ENABLED && email && + email.indexOf('@') == -1 && /sage/i.test(email); } exports.is_sage = is_sage; var OneeSama = function (t) { - this.tamashii = t; - this.hooks = {}; + this.tamashii = t; + this.hooks = {}; }; exports.OneeSama = OneeSama; var OS = OneeSama.prototype; @@ -204,478 +204,482 @@ var break_re = new RegExp("(\\S{" + DEFINES.WORD_LENGTH_LIMIT + "})"); var ref_re = />>(\d+|>\/s\/.+|>\/music\/s\/.+|>\/watch\?v=[\w-]{11}(?:#t=[\dhms]{1,9})?|>\/soundcloud\/[\w-]{1,40}\/[\w-]{1,80}|>\/@\w{1,15}\/\d{4,20}(?:\?s=\d+)?|>\/(?:a|sysint|nap)\/\d{0,10})/; OS.hook = function (name, func) { - var hs = this.hooks[name]; - if (!hs) - this.hooks[name] = hs = [func]; - else if (hs.indexOf(func) < 0) - hs.push(func); + var hs = this.hooks[name]; + if (!hs) + this.hooks[name] = hs = [func]; + else if (hs.indexOf(func) < 0) + hs.push(func); }; OS.trigger = function (name, param) { - var hs = this.hooks[name]; - if (hs) - for (var i = 0; i < hs.length; i++) - hs[i].call(this, param); + var hs = this.hooks[name]; + if (hs) + for (var i = 0; i < hs.length; i++) + hs[i].call(this, param); }; function override(obj, orig, upgrade) { - var origFunc = obj[orig]; - obj[orig] = function () { - var args = [].slice.apply(arguments); - args.unshift(origFunc); - return upgrade.apply(this, args); - }; + var origFunc = obj[orig]; + obj[orig] = function () { + var args = [].slice.apply(arguments); + args.unshift(origFunc); + return upgrade.apply(this, args); + }; } /// converts one >>ref to html OS.red_string = function (ref) { - var prefix = ref.slice(0, 3); - var prefix2 = ref.slice(0, 5); - var dest, linkClass; - if(prefix2 == '>/sys') - { - var num = parseInt(ref.slice(4+5), 10); - dest = '../outbound/sysint/' + (num ? ''+num : ''); - } - else if (prefix == '>/w') { - dest = 'https://www.youtube.com/' + ref.slice(2); - linkClass = 'embed watch'; - } - else if (prefix2 == '>/sou') { - dest = 'https://soundcloud.com/' + ref.slice(13); - linkClass = 'embed soundcloud'; - } - else if (prefix == '>/s') { - dest ="/"+ ref.slice(2); - linkClass = 'embed' - } - else if (prefix == '>/@') { - var bits = ref.slice(3).split('/'); - dest = 'https://twitter.com/' + bits[0] + '/status/' + bits[1]; - linkClass = 'embed tweet'; - } - else if (prefix == '>/a') { - var num = parseInt(ref.slice(4), 10); - dest = '../outbound/a/' + (num ? ''+num : ''); - } - else if (prefix == '>/n') { - var num = parseInt(ref.slice(4+2), 10); - dest = '../outbound/nap/' + (num ? ''+num : ''); - } - else { - this.tamashii(parseInt(ref, 10)); - return; - } - this.callback(new_tab_link(encodeURI(dest), '>>' + ref, linkClass)); + var prefix = ref.slice(0, 3); + var prefix2 = ref.slice(0, 5); + var dest, linkClass; + if(prefix2 == '>/sys') + { + var num = parseInt(ref.slice(4+5), 10); + dest = '../outbound/sysint/' + (num ? ''+num : ''); + } + else if (prefix == '>/w') { + dest = 'https://www.youtube.com/' + ref.slice(2); + linkClass = 'embed watch'; + } + else if (prefix2 == '>/sou') { + dest = 'https://soundcloud.com/' + ref.slice(13); + linkClass = 'embed soundcloud'; + } + else if (prefix == '>/s') { + dest ="/"+ ref.slice(2); + linkClass = 'embed' + } + else if (prefix == '>/@') { + var bits = ref.slice(3).split('/'); + dest = 'https://twitter.com/' + bits[0] + '/status/' + bits[1]; + linkClass = 'embed tweet'; + } + else if (prefix == '>/a') { + var num = parseInt(ref.slice(4), 10); + dest = '../outbound/a/' + (num ? ''+num : ''); + } + else if (prefix == '>/n') { + var num = parseInt(ref.slice(4+2), 10); + dest = '../outbound/nap/' + (num ? ''+num : ''); + } + else { + this.tamashii(parseInt(ref, 10)); + return; + } + this.callback(new_tab_link(encodeURI(dest), '>>' + ref, linkClass)); }; /// 3rd tokenization stage; breaks text into chunks and >>refs OS.break_heart = function (frag) { - if (frag.safe) - return this.callback(frag); - // break long words - var bits = frag.split(break_re); - for (var i = 0; i < bits.length; i++) { - // anchor >>refs - var morsels = bits[i].split(ref_re); - for (var j = 0; j < morsels.length; j++) { - var m = morsels[j]; - if (j % 2) - this.red_string(m); - else if (i % 2) { - this.geimu(m); - this.callback(safe('')); - } - else - this.geimu(m); - } + if (frag.safe) + return this.callback(frag); + // break long words + var bits = frag.split(break_re); + for (var i = 0; i < bits.length; i++) { + // anchor >>refs + var morsels = bits[i].split(ref_re); + for (var j = 0; j < morsels.length; j++) { + var m = morsels[j]; + if (j % 2) + this.red_string(m); + else if (i % 2) { + this.geimu(m); + this.callback(safe('')); + } + else + this.geimu(m); } + } }; /// 2nd tokenization stage; as we transition our state[0] flag, emits html tags as necessary OS.iku = function (token, to) { - var state = this.state; - if (state[0] & DEFINES.S_QUOTE && !(to & DEFINES.S_QUOTE)) - this.callback(safe('')); - if (state[0] & DEFINES.S_BIG && !(to & DEFINES.S_BIG)) { - if (token && token.safe == '
') - token = ''; - this.callback(safe('')); - } - - if (to & DEFINES.S_BIG && !(state[0] & DEFINES.S_BIG)) { - this.callback(safe('

')); - state[0] |= DEFINES.S_BIG; - } - if (to & DEFINES.S_QUOTE && !(state[0] & DEFINES.S_QUOTE)) { - this.callback(safe('')); - state[0] |= DEFINES.S_QUOTE; - } - - if (to == 'SPOIL') { - if (token[1] == '/') { - state[1]--; - this.callback(safe('')); - } - else { - var del = {html: ''}; - this.trigger('spoilerTag', del); - this.callback(safe(del.html)); - state[1]++; - } + var state = this.state; + if (state[0] & DEFINES.S_QUOTE && !(to & DEFINES.S_QUOTE)) + this.callback(safe('')); + if (state[0] & DEFINES.S_BIG && !(to & DEFINES.S_BIG)) { + if (token && token.safe == '
') + token = ''; + this.callback(safe('

')); + } + + if (to & DEFINES.S_BIG && !(state[0] & DEFINES.S_BIG)) { + this.callback(safe('

')); + state[0] |= DEFINES.S_BIG; + } + if (to & DEFINES.S_QUOTE && !(state[0] & DEFINES.S_QUOTE)) { + this.callback(safe('')); + state[0] |= DEFINES.S_QUOTE; + } + + if (to == 'SPOIL') { + if (token[1] == '/') { + state[1]--; + this.callback(safe('')); } else { - this.break_heart(token); + var del = {html: ''}; + this.trigger('spoilerTag', del); + this.callback(safe(del.html)); + state[1]++; } + } + else { + this.break_heart(token); + } - state[0] = to; + state[0] = to; } /// 1st tokenization stage, breaking up [spoiler]s, >quotes, and line breaks OS.fragment = function (frag) { - var chunks = frag.split(/(\[\/?spoiler\])/i); - var state = this.state; - for (var i = 0; i < chunks.length; i++) { - var chunk = chunks[i]; - if (i % 2) { - var to = 'SPOIL'; - if (chunk[1] == '/' && state[1] < 1) - to = state[0] & DEFINES.S_QUOTE; - this.iku(chunk, to); - continue; - } - lines = chunk.split(/(\n)/); - for (var l = 0; l < lines.length; l++) { - var line = lines[l]; - var is_bol = state[0] === DEFINES.S_BOL; - if (l % 2) - this.iku(safe('
'), DEFINES.S_BOL); - else if (is_bol && !state[1] && /^[##]{2}[^##]/.test(line)) { - var to = DEFINES.S_BIG; - if (/[>>]/.test(line[2])) - to |= DEFINES.S_QUOTE; - this.iku(line.slice(2), to); - } - else if (is_bol && /^[>>]/.test(line)) - this.iku(line, DEFINES.S_QUOTE); - else if (line) - this.iku(line, state[0] & (DEFINES.S_QUOTE | DEFINES.S_BIG)); - } + var chunks = frag.split(/(\[\/?spoiler\])/i); + var state = this.state; + for (var i = 0; i < chunks.length; i++) { + var chunk = chunks[i]; + if (i % 2) { + var to = 'SPOIL'; + if (chunk[1] == '/' && state[1] < 1) + to = state[0] & DEFINES.S_QUOTE; + this.iku(chunk, to); + continue; + } + lines = chunk.split(/(\n)/); + for (var l = 0; l < lines.length; l++) { + var line = lines[l]; + var is_bol = state[0] === DEFINES.S_BOL; + if (l % 2) + this.iku(safe('
'), DEFINES.S_BOL); + else if (is_bol && !state[1] && /^[##]{2}[^##]/.test(line)) { + var to = DEFINES.S_BIG; + if (/[>>]/.test(line[2])) + to |= DEFINES.S_QUOTE; + this.iku(line.slice(2), to); + } + else if (is_bol && /^[>>]/.test(line)) + this.iku(line, DEFINES.S_QUOTE); + else if (line) + this.iku(line, state[0] & (DEFINES.S_QUOTE | DEFINES.S_BIG)); } + } }; OS.close_out = function () { - if (this.state[0] & DEFINES.S_QUOTE) { - this.callback(safe('
')); - this.state[0] -= DEFINES.S_QUOTE; - } - - if (this.state[0] & DEFINES.S_BIG) { - this.callback(safe('

')); - this.state[0] -= DEFINES.S_BIG; - } - - while (this.state[1] > 0) { - this.callback(safe('')); - this.state[1]--; - } + if (this.state[0] & DEFINES.S_QUOTE) { + this.callback(safe('')); + this.state[0] -= DEFINES.S_QUOTE; + } + + if (this.state[0] & DEFINES.S_BIG) { + this.callback(safe('')); + this.state[0] -= DEFINES.S_BIG; + } + + while (this.state[1] > 0) { + this.callback(safe('')); + this.state[1]--; + } }; /// converts one post body to HTML OS.karada = function (body) { - var output = []; - this.state = initial_state(); - this.callback = function (frag) { output.push(frag); } - this.fragment(body); - this.close_out(); - this.callback = null; - return output; + var output = []; + this.state = initial_state(); + this.callback = function (frag) { output.push(frag); } + this.fragment(body); + this.close_out(); + this.callback = null; + return output; } -var dice_re = /(#dame|#tutturu|#muri|#flip|#when|#du|#pyu|#pcount|#test|#sleep|#janken|#8ball|#imfey|#\?(?:\[(?:\w,*)+\])?|#\d{0,2}d\d{1,4}(?:[+-]\d{1,4})?)/i; +var dice_re = /(#tea|#dame|#tutturu|#muri|#flip|#when|#du|#pyu|#pcount|#test|#sleep|#janken|#8ball|#imfey|#\?(?:\[(?:\w,*)+\])?|#\d{0,2}d\d{1,4}(?:[+-]\d{1,4})?)/i; exports.dice_re = dice_re; var WHEN = [ - 'Now', null, null, null, null, - 'Later', null, null, null, null, - 'In 5 minutes', null, null, null, null, - '5 minutes ago', null, null, - 'In exactly 2.54 seconds', null, null, - 'At midnight tonight', null, null, - 'on fridey nite', null, - 'Tomorrow', null, null, null, - 'Next week', null, null, - 'I\'m not at liberty to say', null, - 'Whenever you want', null, null, null, - 'Never', null, null, null, - 'Immediately', null, null, - 'Always', null, - 'NEVER EVER', null, - 'A̵҉̞͚̦̖͔̰̣̱t҉̡̤͚ ̮̱͇́͞͝t̺̺̮h̵̜̠̘̩̮̥͓̀e͇̮͎̻ ͔̪̻̙̦̭̼h̸̭̬̭͉̱̝̖̝̰͠͡e̻͍͈̕͝à̢͈͜ṭ̵̳̩̲̩͚-̤̝͓͍͜ͅḓ͍̥͉̝͜͝e͖͎͓a̸̡̘̠̯̻̩͝t̛̻̗̤͘h͍̺ ̶̧͏̗̖̺ơ̹͍f͓͓̘̻̤͉̤̺ ̨̪̗̻̝̹͞t͈̮͜͢h̰̥̞̹ͅȩ̥̹͇̩̼̻ ̸̡̤̙̯͟ͅú̺̬̘̩͞n͖̣͕̲̦̟̼͡͞į̛̻͇̹͚͡v͈̫͚̜͘̕͠é͔̯̲̤͉̱̫͟͝r̷̛͉̮s̷͔͍̰̹e̤̖̙͝', + 'Now', null, null, null, null, + 'Later', null, null, null, null, + 'In 5 minutes', null, null, null, null, + '5 minutes ago', null, null, + 'In exactly 2.54 seconds', null, null, + 'At midnight tonight', null, null, + 'on fridey nite', null, + 'Tomorrow', null, null, null, + 'Next week', null, null, + 'I\'m not at liberty to say', null, + 'Whenever you want', null, null, null, + 'Never', null, null, null, + 'Immediately', null, null, + 'Always', null, + 'NEVER EVER', null, + 'A̵҉̞͚̦̖͔̰̣̱t҉̡̤͚ ̮̱͇́͞͝t̺̺̮h̵̜̠̘̩̮̥͓̀e͇̮͎̻ ͔̪̻̙̦̭̼h̸̭̬̭͉̱̝̖̝̰͠͡e̻͍͈̕͝à̢͈͜ṭ̵̳̩̲̩͚-̤̝͓͍͜ͅḓ͍̥͉̝͜͝e͖͎͓a̸̡̘̠̯̻̩͝t̛̻̗̤͘h͍̺ ̶̧͏̗̖̺ơ̹͍f͓͓̘̻̤͉̤̺ ̨̪̗̻̝̹͞t͈̮͜͢h̰̥̞̹ͅȩ̥̹͇̩̼̻ ̸̡̤̙̯͟ͅú̺̬̘̩͞n͖̣͕̲̦̟̼͡͞į̛̻͇̹͚͡v͈̫͚̜͘̕͠é͔̯̲̤͉̱̫͟͝r̷̛͉̮s̷͔͍̰̹e̤̖̙͝', ]; var EIGHT_BALL = [ - 'Yes', - 'No', - 'Maybe', - 'Ara ara', - 'Why this', - 'Help', - 'git gud', - 'Okay', - 'My condolences', - 'Praise be', - 'EEEEEEH?!', - 'Try again never', - '100%', - 'Can you repeat the question', - 'lol', - '0.1%', - 'agreedo', - 'nope.avi', - 'Would you kindly?', + 'Yes', + 'No', + 'Maybe', + 'Ara ara', + 'Why this', + 'Help', + 'git gud', + 'Okay', + 'My condolences', + 'Praise be', + 'EEEEEEH?!', + 'Try again never', + '100%', + 'Can you repeat the question', + 'lol', + '0.1%', + 'agreedo', + 'nope.avi', + 'Would you kindly?', ]; var IMFEY = [ - 'wowme2', - 'u do u', - "go get 'em champ", - 'my child...', - '✨', - 'Kooloo Limpah!', - 'Invigorating.', - 'sproink', - 'elwind!', + 'wowme2', + 'u do u', + "go get 'em champ", + 'my child...', + '✨', + 'Kooloo Limpah!', + 'Invigorating.', + 'sproink', + 'elwind!', ]; function parse_dice(frag) { - if(/^#(dame|muri|tutturu)$/i.test(frag)) - return {n:1, faces:2}; - if(frag == '#loli') { - return {n:1, faces:3}; - } - if(frag == '#?') - { - return {n:1, faces:2}; - } - if (/^#\?/.test(frag)) + if(/^#(dame|muri|tutturu)$/i.test(frag)) + return {n:1, faces:2}; + if(frag == '#loli') { + return {n:1, faces:3}; + } + if(frag == '#?') + { + return {n:1, faces:2}; + } + if (/^#\?/.test(frag)) + { + var l = frag.slice(2).split(/(\[|\]|,)/); + var j =0; + for(var i=0;i0) j+=1; - } - return {n:1, faces: j}; + if(/(\[|\]|,)/.test(l[i])) continue; + if(l[i].length>0) j+=1; } - if (frag == '#pyu' || frag == '#pcount' || frag == '#du') - return {n: 1, faces: 2}; - if (frag == '#flip') - return {n: 1, faces: 2}; - if (frag == '#imfey') - return {n: 1, faces: IMFEY.length}; - if (frag == '#8ball') - return {n: 1, faces: EIGHT_BALL.length}; - if (frag == '#when') - return {n: 1, faces: WHEN.length}; - if (frag == '#test') - return {n: 1, faces: 2}; - if (frag == '#sleep') - return {n: 1, faces: 2}; - if (frag == '#janken') - return {n: 1, faces: 3}; - var m = frag.match(/^#(\d*)d(\d+)([+-]\d+)?$/i); - if (!m) - return false; - var n = parseInt(m[1], 10) || 1, faces = parseInt(m[2], 10); - if (n < 1 || n > 10 || faces < 2 || faces > 100) - return false; - var info = {n: n, faces: faces}; - if (m[3]) - info.bias = parseInt(m[3], 10); - return info; + return {n:1, faces: j}; + } + if (frag == '#pyu' || frag == '#pcount' || frag == '#du') + return {n: 1, faces: 2}; + if (frag == '#tea') + return {n: 1, faces: 2}; + if (frag == '#flip') + return {n: 1, faces: 2}; + if (frag == '#imfey') + return {n: 1, faces: IMFEY.length}; + if (frag == '#8ball') + return {n: 1, faces: EIGHT_BALL.length}; + if (frag == '#when') + return {n: 1, faces: WHEN.length}; + if (frag == '#test') + return {n: 1, faces: 2}; + if (frag == '#sleep') + return {n: 1, faces: 2}; + if (frag == '#janken') + return {n: 1, faces: 3}; + var m = frag.match(/^#(\d*)d(\d+)([+-]\d+)?$/i); + if (!m) + return false; + var n = parseInt(m[1], 10) || 1, faces = parseInt(m[2], 10); + if (n < 1 || n > 10 || faces < 2 || faces > 100) + return false; + var info = {n: n, faces: faces}; + if (m[3]) + info.bias = parseInt(m[3], 10); + return info; } exports.parse_dice = parse_dice; const audio_root = "/s/audio"; function readable_audio(bit, d) { - if (bit=='#dame') - return "dame.wav"; - else if (bit=='#muri') - return "muri.wav"; - else if (bit=='#tutturu') - return "tutturu.wav"; + if (bit=='#dame') + return "dame.wav"; + else if (bit=='#muri') + return "muri.wav"; + else if (bit=='#tutturu') + return "tutturu.wav"; } function readable_dice(bit, d) { - if(bit == '#loli') { - return "you should not see this"; - } - if(bit == '#?') - { - if(d[0] === 0) return '#? (I have no input)'; - if(d[0] === -1) return '#? (You have no post)'; - return '#? ('+d[0]+')'; - } - if (/^#\?/.test(bit)) - { - var list = []; - var l = bit.slice(2).split(/(\[|\]|,)/); - if(!!l) { - for(var i=0;i0) - list.push(l[i]); - } - if(d[1]>list.length) return bit + " (error)"; - else return bit + " (" + list[ d[1]-1] + ")"; - } + if(bit == '#loli') { + return "you should not see this"; + } + if(bit == '#?') + { + if(d[0] === 0) return '#? (I have no input)'; + if(d[0] === -1) return '#? (You have no post)'; + return '#? ('+d[0]+')'; + } + if (/^#\?/.test(bit)) + { + var list = []; + var l = bit.slice(2).split(/(\[|\]|,)/); + if(!!l) { + for(var i=0;i0) + list.push(l[i]); + } + if(d[1]>list.length) return bit + " (error)"; + else return bit + " (" + list[ d[1]-1] + ")"; } - if (bit == '#du') - { - if(d[0]>=0) - return '#du ('+d[0]+'%)'; - else - return '#du (Try asking again)'; - } - if (bit == '#pyu') - return '#pyu (' + d[0]+ ')'; - if (bit == '#pcount') - return '#pcount (' + d[0] + ')'; - if (bit == '#flip') - return '#flip (' + (d[1] == 2) + ')'; - if (bit == '#imfey') - return '#imfey (' + IMFEY[d[1] - 1] + ')'; - if (bit == '#8ball') - return '#8ball (' + EIGHT_BALL[d[1] - 1] + ')'; - if (bit == '#when') - { - var f = function(n) { - if(WHEN[n] === null) - return f(n-1); - else return WHEN[n]; - }; - return '#when (' + f(d[1]-1) + ')'; - } - if (bit == '#test') - return '#test (it worked!)'; - if (bit == '#sleep') - return '#sleep (Yes)'; - if (bit == '#janken') - return '#janken ('+ ["Rock", "Paper", "Scissors"][d[1]-1]+')'; - var f = d[0], n = d.length, b = 0; - if (d[n-1] && typeof d[n-1] == 'object') { - b = d[n-1].bias; - n--; - } - var r = d.slice(1, n); - n = r.length; - bit += ' ('; - var eq = n > 1 || b; - if (eq) - bit += r.join(', '); - if (b) - bit += (b < 0 ? ' - ' + (-b) : ' + ' + b); - var sum = b; - for (var j = 0; j < n; j++) - sum += r[j]; - return bit + (eq ? ' = ' : '') + sum + ')'; + } + if (bit == '#du') + { + if(d[0]>=0) + return '#du ('+d[0]+'%)'; + else + return '#du (Try asking again)'; + } + if (bit == '#pyu') + return '#pyu (' + d[0]+ ')'; + if (bit == '#pcount') + return '#pcount (' + d[0] + ')'; + if (bit == '#tea') + return '#tea (' + ((d[0] === true)?"now!":d[0]+" hours") + ')'; + if (bit == '#flip') + return '#flip (' + (d[1] == 2) + ')'; + if (bit == '#imfey') + return '#imfey (' + IMFEY[d[1] - 1] + ')'; + if (bit == '#8ball') + return '#8ball (' + EIGHT_BALL[d[1] - 1] + ')'; + if (bit == '#when') + { + const f = (n) => { + if(WHEN[n] === null) + return f(n-1); + else return WHEN[n]; + }; + return '#when (' + f(d[1]-1) + ')'; + } + if (bit == '#test') + return '#test (it worked!)'; + if (bit == '#sleep') + return '#sleep (Yes)'; + if (bit == '#janken') + return '#janken ('+ ["Rock", "Paper", "Scissors"][d[1]-1]+')'; + var f = d[0], n = d.length, b = 0; + if (d[n-1] && typeof d[n-1] == 'object') { + b = d[n-1].bias; + n--; + } + var r = d.slice(1, n); + n = r.length; + bit += ' ('; + var eq = n > 1 || b; + if (eq) + bit += r.join(', '); + if (b) + bit += (b < 0 ? ' - ' + (-b) : ' + ' + b); + var sum = b; + for (var j = 0; j < n; j++) + sum += r[j]; + return bit + (eq ? ' = ' : '') + sum + ')'; } /// 4th tokenization stage; populates dice rolls OS.geimu = function (text) { - if (!this.dice) { - this.kinpira(text); - return; - } + if (!this.dice) { + this.kinpira(text); + return; + } - var bits = text.split(dice_re); - for (var i = 0; i < bits.length; i++) { - var bit = bits[i]; - if (!(i % 2) || !parse_dice(bit)) { - this.kinpira(bit); - } - else if (this.queueRoll) { - this.queueRoll(bit); - } - else if (!this.dice[0]) { - this.kinpira(bit); - } - else { - var d = this.dice.shift(); - this.callback(safe('')); - this.strong = true; // for client DOM insertion - var audio = readable_audio(bit,d); - if(audio) - { - this.callback(safe(""+bit+"")); - this.callback(safe("")); - } - else if(bit == "#loli") { - this.callback(safe("")); - } - else - this.callback(readable_dice(bit, d)); - this.strong = false; - this.callback(safe('')); - } + var bits = text.split(dice_re); + for (var i = 0; i < bits.length; i++) { + var bit = bits[i]; + if (!(i % 2) || !parse_dice(bit)) { + this.kinpira(bit); + } + else if (this.queueRoll) { + this.queueRoll(bit); + } + else if (!this.dice[0]) { + this.kinpira(bit); } + else { + var d = this.dice.shift(); + this.callback(safe('')); + this.strong = true; // for client DOM insertion + var audio = readable_audio(bit,d); + if(audio) + { + this.callback(safe(""+bit+"")); + this.callback(safe("")); + } + else if(bit == "#loli") { + this.callback(safe("")); + } + else + this.callback(readable_dice(bit, d)); + this.strong = false; + this.callback(safe('')); + } + } }; /// 5th tokenization stage; parses ^s OS.kinpira = function (text) { + this.itameshi(text); + return; + + if (!/[^^]/.test(text) || /^([^^]_|:[^^])/.test(text)) { this.itameshi(text); return; - - if (!/[^^]/.test(text) || /^([^^]_|:[^^])/.test(text)) { - this.itameshi(text); - return; - } - var bits = text.split(/[^^]/); - // remove trailing ^s - while (bits.length && bits[bits.length-1] == '') - bits.pop(); - - var soup = safe(''); - this.sup_level = 0; - for (var i = 0; i < bits.length; i++) { - if (bits[i]) - this.itameshi(bits[i]); - if (i + 1 < bits.length && i < 5) { - // if there's more text, open a - this.itameshi(soup); - this.sup_level++; - } + } + var bits = text.split(/[^^]/); + // remove trailing ^s + while (bits.length && bits[bits.length-1] == '') + bits.pop(); + + var soup = safe(''); + this.sup_level = 0; + for (var i = 0; i < bits.length; i++) { + if (bits[i]) + this.itameshi(bits[i]); + if (i + 1 < bits.length && i < 5) { + // if there's more text, open a + this.itameshi(soup); + this.sup_level++; } - // close all the sups we opened - var n = this.sup_level; - this.sup_level = 0; - soup = safe(''); - for (var i = 0; i < n; i++) - this.itameshi(soup); + } + // close all the sups we opened + var n = this.sup_level; + this.sup_level = 0; + soup = safe(''); + for (var i = 0; i < n; i++) + this.itameshi(soup); }; /// 6th tokenization stage; parses individual *italic* *words* OS.itameshi = function (text) { - while (true) { - var m = /(^|[ .,;:?!(-])\*([^ *]+)\*($|[ .,;:?!)-])/.exec(text); - if (!m) - break; - if (m.index > 0) { - var before = text.slice(0, m.index); - LINKIFY ? this.linkify(before) : this.callback(before); - } - if (m[1]) - this.callback(m[1]); - this.callback(safe('' + escape_html(m[2]) + '')); - text = text.slice(m.index + m[0].length - m[3].length); + while (true) { + var m = /(^|[ .,;:?!(-])\*([^ *]+)\*($|[ .,;:?!)-])/.exec(text); + if (!m) + break; + if (m.index > 0) { + var before = text.slice(0, m.index); + LINKIFY ? this.linkify(before) : this.callback(before); } - if (text) - LINKIFY ? this.linkify(text) : this.callback(text); + if (m[1]) + this.callback(m[1]); + this.callback(safe('' + escape_html(m[2]) + '')); + text = text.slice(m.index + m[0].length - m[3].length); + } + if (text) + LINKIFY ? this.linkify(text) : this.callback(text); }; // Convert text URLs to clickable links @@ -685,384 +689,384 @@ var LINKIFY = false; /// optional 7th tokenization stage if (LINKIFY) { OS.linkify = function (text) { - var bits = text.split(/(https?:\/\/[^\s"<>^]*[^\s"<>'.,!?:;^])/); - for (var i = 0; i < bits.length; i++) { - if (i % 2) { - var e = escape_html(bits[i]); - // open in new tab, and disavow target - this.callback(safe('' + - e + '')); - } - else - this.callback(bits[i]); + var bits = text.split(/(https?:\/\/[^\s"<>^]*[^\s"<>'.,!?:;^])/); + for (var i = 0; i < bits.length; i++) { + if (i % 2) { + var e = escape_html(bits[i]); + // open in new tab, and disavow target + this.callback(safe('' + + e + '')); } + else + this.callback(bits[i]); + } }; } function chibi(imgnm, src) { - var name = '', ext = ''; - var m = imgnm.match(/^(.*)(\.\w{3,4})$/); - if (m) { - name = m[1]; - ext = m[2]; - } - var bits = [safe(''), imgnm, safe('')); - return bits; + var name = '', ext = ''; + var m = imgnm.match(/^(.*)(\.\w{3,4})$/); + if (m) { + name = m[1]; + ext = m[2]; + } + var bits = [safe(''), imgnm, safe('')); + return bits; } OS.spoiler_info = function (index, toppu) { - var large = toppu || this.thumbStyle == 'large'; - var hd = toppu || this.thumbStyle != 'small'; - return { - thumb: encodeURI(mediaURL + 'kana/spoiler' + (hd ? '' : 's') - + index + '.png'), - dims: large ? imagerConfig.THUMB_DIMENSIONS - : imagerConfig.PINKY_DIMENSIONS, - }; + var large = toppu || this.thumbStyle == 'large'; + var hd = toppu || this.thumbStyle != 'small'; + return { + thumb: encodeURI(mediaURL + 'kana/spoiler' + (hd ? '' : 's') + + index + '.png'), + dims: large ? imagerConfig.THUMB_DIMENSIONS + : imagerConfig.PINKY_DIMENSIONS, + }; }; var spoilerImages = imagerConfig.SPOILER_IMAGES; function pick_spoiler(metaIndex) { - var imgs = spoilerImages; - var n = imgs.normal.length; - var count = n + imgs.trans.length; - var i; - if (metaIndex < 0) - i = Math.floor(Math.random() * count); - else - i = metaIndex % count; - var spoiler = i < n ? imgs.normal[i] : imgs.trans[i - n]; - return {index: spoiler, next: (i+1) % count}; + var imgs = spoilerImages; + var n = imgs.normal.length; + var count = n + imgs.trans.length; + var i; + if (metaIndex < 0) + i = Math.floor(Math.random() * count); + else + i = metaIndex % count; + var spoiler = i < n ? imgs.normal[i] : imgs.trans[i - n]; + return {index: spoiler, next: (i+1) % count}; } exports.pick_spoiler = pick_spoiler; function new_tab_link(srcEncoded, inside, cls) { - return [safe(''), inside, safe('')]; + return [safe(''), inside, safe('')]; } OS.image_paths = function () { - if (!this._imgPaths) { - this._imgPaths = { - src: mediaURL + 'src/', - thumb: mediaURL + 'thumb/', - mid: mediaURL + 'mid/', - vint: mediaURL + 'vint/', - }; - this.trigger('mediaPaths', this._imgPaths); - } - return this._imgPaths; + if (!this._imgPaths) { + this._imgPaths = { + src: mediaURL + 'src/', + thumb: mediaURL + 'thumb/', + mid: mediaURL + 'mid/', + vint: mediaURL + 'vint/', + }; + this.trigger('mediaPaths', this._imgPaths); + } + return this._imgPaths; }; var audioIndicator = "\u266B"; // musical note OS.gazou = function (info, toppu) { - var src, name, caption, video; - if (info.vint) { - src = encodeURI('../outbound/hash/' + info.MD5); - var google = encodeURI('../outbound/g/' + info.vint); - var iqdb = encodeURI('../outbound/iqdb/' + info.vint); - caption = ['Search ', new_tab_link(google, '[Google]'), ' ', - new_tab_link(iqdb, '[iqdb]'), ' ', - new_tab_link(src, '[foolz]')]; - } - else { - src = encodeURI(this.image_paths().src + info.src); - video = info.video || (/\.webm$/i.test(src) && 'webm'); // webm check is legacy - caption = [video ? 'Video ' : 'Image ', new_tab_link(src, info.src)]; - } - - var img = this.gazou_img(info, toppu); - var dims = info.dims[0] + 'x' + info.dims[1]; - - return [safe('
'), - caption, safe(' ('), - info.audio ? (audioIndicator + ', ') : '', - info.duration ? (info.duration + ', ') : '', - readable_filesize(info.size), ', ', - dims, (info.apng ? ', APNG' : ''), - this.full ? [', ', chibi(info.imgnm, img.src)] : '', - safe(')
'), - this.thumbStyle == 'hide' ? '' : img.html, - safe('
\n\t')]; + var src, name, caption, video; + if (info.vint) { + src = encodeURI('../outbound/hash/' + info.MD5); + var google = encodeURI('../outbound/g/' + info.vint); + var iqdb = encodeURI('../outbound/iqdb/' + info.vint); + caption = ['Search ', new_tab_link(google, '[Google]'), ' ', + new_tab_link(iqdb, '[iqdb]'), ' ', + new_tab_link(src, '[foolz]')]; + } + else { + src = encodeURI(this.image_paths().src + info.src); + video = info.video || (/\.webm$/i.test(src) && 'webm'); // webm check is legacy + caption = [video ? 'Video ' : 'Image ', new_tab_link(src, info.src)]; + } + + var img = this.gazou_img(info, toppu); + var dims = info.dims[0] + 'x' + info.dims[1]; + + return [safe('
'), + caption, safe(' ('), + info.audio ? (audioIndicator + ', ') : '', + info.duration ? (info.duration + ', ') : '', + readable_filesize(info.size), ', ', + dims, (info.apng ? ', APNG' : ''), + this.full ? [', ', chibi(info.imgnm, img.src)] : '', + safe(')
'), + this.thumbStyle == 'hide' ? '' : img.html, + safe('
\n\t')]; }; exports.thumbStyles = ['small', 'sharp', 'large', 'hide']; OS.gazou_img = function (info, toppu) { - var src, thumb; - var imgPaths = this.image_paths(); - if (!info.vint) - src = thumb = encodeURI(imgPaths.src + info.src); - - var d = info.dims; - var w = d[0], h = d[1], tw = d[2], th = d[3]; - if (info.spoiler) { - var sp = this.spoiler_info(info.spoiler, toppu); - thumb = sp.thumb; - tw = sp.dims[0]; - th = sp.dims[1]; - } - else if (info.vint) { - tw = tw || w; - th = th || h; - src = encodeURI('../outbound/hash/' + info.MD5); - thumb = imgPaths.vint + info.vint; - } - else if (this.thumbStyle != 'small' && info.mid) { - thumb = encodeURI(imgPaths.mid + info.mid); - if (!toppu && this.thumbStyle == 'large') { - tw *= 2; - th *= 2; - } - } - else if (info.thumb) - thumb = encodeURI(imgPaths.thumb + info.thumb); - else { - tw = w; - th = h; + var src, thumb; + var imgPaths = this.image_paths(); + if (!info.vint) + src = thumb = encodeURI(imgPaths.src + info.src); + + var d = info.dims; + var w = d[0], h = d[1], tw = d[2], th = d[3]; + if (info.spoiler) { + var sp = this.spoiler_info(info.spoiler, toppu); + thumb = sp.thumb; + tw = sp.dims[0]; + th = sp.dims[1]; + } + else if (info.vint) { + tw = tw || w; + th = th || h; + src = encodeURI('../outbound/hash/' + info.MD5); + thumb = imgPaths.vint + info.vint; + } + else if (this.thumbStyle != 'small' && info.mid) { + thumb = encodeURI(imgPaths.mid + info.mid); + if (!toppu && this.thumbStyle == 'large') { + tw *= 2; + th *= 2; } - - var img = ''; - else - img += '>'; - if (imagerConfig.IMAGE_HATS) - img = '' + img; - img = new_tab_link(src, safe(img)); - return {html: img, src: src}; + } + else if (info.thumb) + thumb = encodeURI(imgPaths.thumb + info.thumb); + else { + tw = w; + th = h; + } + + var img = ''; + else + img += '>'; + if (imagerConfig.IMAGE_HATS) + img = '' + img; + img = new_tab_link(src, safe(img)); + return {html: img, src: src}; }; function readable_filesize(size) { - /* Dealt with it. */ - if (size < 1024) - return size + ' B'; - if (size < 1048576) - return Math.round(size / 1024) + ' KB'; - size = Math.round(size / 104857.6).toString(); - return size.slice(0, -1) + '.' + size.slice(-1) + ' MB'; + /* Dealt with it. */ + if (size < 1024) + return size + ' B'; + if (size < 1048576) + return Math.round(size / 1024) + ' KB'; + size = Math.round(size / 104857.6).toString(); + return size.slice(0, -1) + '.' + size.slice(-1) + ' MB'; } exports.readable_filesize = readable_filesize; function pad(n) { - return (n < 10 ? '0' : '') + n; + return (n < 10 ? '0' : '') + n; } OS.readable_time = function (time) { - var h = this.tz_offset; - var offset; - if (h || h == 0) - offset = h * 60 * 60 * 1000; - else /* would be nice not to construct new Dates all the time */ - offset = new Date().getTimezoneOffset() * -60 * 1000; - var d = new Date(time + offset); - var k = "日月火水木金土"[d.getUTCDay()]; - return (d.getUTCFullYear() + '/' + pad(d.getUTCMonth()+1) + '/' + - pad(d.getUTCDate()) + ' (' + k + ') ' + - pad(d.getUTCHours()) + ':' + - pad(d.getUTCMinutes())); + var h = this.tz_offset; + var offset; + if (h || h == 0) + offset = h * 60 * 60 * 1000; + else /* would be nice not to construct new Dates all the time */ + offset = new Date().getTimezoneOffset() * -60 * 1000; + var d = new Date(time + offset); + var k = "日月火水木金土"[d.getUTCDay()]; + return (d.getUTCFullYear() + '/' + pad(d.getUTCMonth()+1) + '/' + + pad(d.getUTCDate()) + ' (' + k + ') ' + + pad(d.getUTCHours()) + ':' + + pad(d.getUTCMinutes())); }; function datetime(time) { - var d = new Date(time); - return (d.getUTCFullYear() + '-' + pad(d.getUTCMonth()+1) + '-' + - pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + - pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + 'Z'); + var d = new Date(time); + return (d.getUTCFullYear() + '-' + pad(d.getUTCMonth()+1) + '-' + + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + 'Z'); } OS.post_url = function (num, op, quote) { - op = op || num; - return (this.op == op ? '' : op) + (quote ? '#q' : '#') + num; + op = op || num; + return (this.op == op ? '' : op) + (quote ? '#q' : '#') + num; }; OS.post_ref = function (num, op, desc_html) { - var ref = '>>' + num; - if (desc_html) - ref += ' ' + desc_html; - else if (this.op && this.op != op) - ref += ' \u2192'; - else if (num == op && this.op == op) - ref += ' (OP)'; - return safe(''+ref+''); + var ref = '>>' + num; + if (desc_html) + ref += ' ' + desc_html; + else if (this.op && this.op != op) + ref += ' \u2192'; + else if (num == op && this.op == op) + ref += ' (OP)'; + return safe(''+ref+''); }; OS.post_nav = function (post) { - var n = post.num, o = post.op; - return safe(''); + var n = post.num, o = post.op; + return safe(''); }; function action_link_html(href, name, id) { - var span = ''; - return span + ''+name+''; + var span = ''; + return span + ''+name+''; } exports.action_link_html = action_link_html; exports.reasonable_last_n = function (n) { - return n >= 5 && n <= 500; + return n >= 5 && n <= 500; }; OS.last_n_html = function (num) { - return action_link_html(num + '?last' + this.lastN, - 'Last ' + this.lastN); + return action_link_html(num + '?last' + this.lastN, + 'Last ' + this.lastN); }; OS.expansion_links_html = function (num, omit) { - var html = '   ' + action_link_html(num, 'Expand'); - if (omit > this.lastN) - html += ' ' + this.last_n_html(num); - return html; + var html = '   ' + action_link_html(num, 'Expand'); + if (omit > this.lastN) + html += ' ' + this.last_n_html(num); + return html; }; OS.atama = function (data) { - var auth = data.auth; - var header = auth ? [safe('')] - : [safe('')]; - if (data.subject) - header.unshift(safe('

「'), data.subject, safe('」

')); - if (data.name || !data.trip) { - header.push(data.name || DEFINES.ANON); - if (data.trip) - header.push(' '); - } + var auth = data.auth; + var header = auth ? [safe('')] + : [safe('')]; + if (data.subject) + header.unshift(safe('

「'), data.subject, safe('」

')); + if (data.name || !data.trip) { + header.push(data.name || DEFINES.ANON); if (data.trip) - header.push(safe('' + data.trip + '')); - if (auth) - header.push(' ## ' + auth); - this.trigger('headerName', {header: header, data: data}); - header.push(safe('
')); - if (data.email) { - header.unshift(safe('')); - } - header.push(safe(' '), - this.post_nav(data)); - if (!this.full && !data.op) { - var ex = this.expansion_links_html(data.num, data.omit); - header.push(safe(ex)); - } - this.trigger('headerFinish', {header: header, data: data}); - header.unshift(safe('
')); - header.push(safe('
\n\t')); - return header; + header.push(' '); + } + if (data.trip) + header.push(safe('' + data.trip + '')); + if (auth) + header.push(' ## ' + auth); + this.trigger('headerName', {header: header, data: data}); + header.push(safe('
')); + if (data.email) { + header.unshift(safe('')); + } + header.push(safe(' '), + this.post_nav(data)); + if (!this.full && !data.op) { + var ex = this.expansion_links_html(data.num, data.omit); + header.push(safe(ex)); + } + this.trigger('headerFinish', {header: header, data: data}); + header.unshift(safe('
')); + header.push(safe('
\n\t')); + return header; }; OS.monogatari = function (data, toppu) { - var tale = {header: this.atama(data)}; - this.dice = data.dice; - var body = this.karada(data.body); - tale.body = [safe('
'), body, safe('
')]; - if (data.num == MILLION) { - tale.body.splice(1, 0, safe('')); - } - if (data.image && !data.hideimg) - tale.image = this.gazou(data.image, toppu); - return tale; + var tale = {header: this.atama(data)}; + this.dice = data.dice; + var body = this.karada(data.body); + tale.body = [safe('
'), body, safe('
')]; + if (data.num == MILLION) { + tale.body.splice(1, 0, safe('')); + } + if (data.image && !data.hideimg) + tale.image = this.gazou(data.image, toppu); + return tale; }; var MILLION = 1000000; function gravitas_body() { - $('body').css({margin: 0}); + $('body').css({margin: 0}); } OS.gravitas_style = function (idata, cssy) { - var src = this.image_paths().src + idata.src; - src = "url('" + encodeURI(src) + "')"; - return cssy ? ("background-image: " + src + ";") : src; + var src = this.image_paths().src + idata.src; + src = "url('" + encodeURI(src) + "')"; + return cssy ? ("background-image: " + src + ";") : src; }; OS.mono = function (data) { - var info = { - data: data, - classes: data.editing ? ['editing'] : [], - style: '' - }; - if (data.flavor) - info.classes.push(data.flavor); - if (data.num == MILLION) { - info.classes.push('gravitas'); - if (data.image) - info.style = this.gravitas_style(data.image, true); - } - this.trigger('openArticle', info); - var cls = info.classes.length && info.classes.join(' '), - o = [safe('\t
')], - c = safe('
\n'), - gen = this.monogatari(data, false); - return flatten([o, gen.header, gen.image || '', gen.body, c]).join(''); + var info = { + data: data, + classes: data.editing ? ['editing'] : [], + style: '' + }; + if (data.flavor) + info.classes.push(data.flavor); + if (data.num == MILLION) { + info.classes.push('gravitas'); + if (data.image) + info.style = this.gravitas_style(data.image, true); + } + this.trigger('openArticle', info); + var cls = info.classes.length && info.classes.join(' '), + o = [safe('\t
')], + c = safe('
\n'), + gen = this.monogatari(data, false); + return flatten([o, gen.header, gen.image || '', gen.body, c]).join(''); }; OS.monomono = function (data, cls) { - if (data.flavor) - cls = cls ? cls+' '+data.flavor : data.flavor; - if (data.locked) - cls = cls ? cls+' locked' : 'locked'; - var style; - if (data.num == MILLION) { - cls = cls ? cls+' gravitas' : 'gravitas'; - if (data.image) - style = this.gravitas_style(data.image, true); - } - var o = [safe('
')], - c = safe('
\n'), - gen = this.monogatari(data, true); - return flatten([o, gen.image || '', gen.header, gen.body, '\n', c]); + if (data.flavor) + cls = cls ? cls+' '+data.flavor : data.flavor; + if (data.locked) + cls = cls ? cls+' locked' : 'locked'; + var style; + if (data.num == MILLION) { + cls = cls ? cls+' gravitas' : 'gravitas'; + if (data.image) + style = this.gravitas_style(data.image, true); + } + var o = [safe('
')], + c = safe('
\n'), + gen = this.monogatari(data, true); + return flatten([o, gen.image || '', gen.header, gen.body, '\n', c]); }; function pluralize(n, noun) { - return n + ' ' + noun + (n == 1 ? '' : 's'); + return n + ' ' + noun + (n == 1 ? '' : 's'); } exports.pluralize = pluralize; exports.abbrev_msg = function (omit, img_omit) { - return omit + (omit==1 ? ' reply' : ' replies') + (img_omit - ? ' and ' + pluralize(img_omit, 'image') - : '') + ' omitted.'; + return omit + (omit==1 ? ' reply' : ' replies') + (img_omit + ? ' and ' + pluralize(img_omit, 'image') + : '') + ' omitted.'; }; exports.parse_name = function (name) { - var tripcode = '', secure = ''; - var hash = name.indexOf('#'); + var tripcode = '', secure = ''; + var hash = name.indexOf('#'); + if (hash >= 0) { + tripcode = name.substr(hash+1); + name = name.substr(0, hash); + hash = tripcode.indexOf('#'); if (hash >= 0) { - tripcode = name.substr(hash+1); - name = name.substr(0, hash); - hash = tripcode.indexOf('#'); - if (hash >= 0) { - secure = escape_html(tripcode.substr(hash+1)); - tripcode = tripcode.substr(0, hash); - } - tripcode = escape_html(tripcode); + secure = escape_html(tripcode.substr(hash+1)); + tripcode = tripcode.substr(0, hash); } - name = name.trim().replace(config.EXCLUDE_REGEXP, ''); - return [name.substr(0, 100), tripcode.substr(0, 128), - secure.substr(0, 128)]; + tripcode = escape_html(tripcode); + } + name = name.trim().replace(config.EXCLUDE_REGEXP, ''); + return [name.substr(0, 100), tripcode.substr(0, 128), + secure.substr(0, 128)]; }; function random_id() { - return Math.floor(Math.random() * 1e16) + 1; + return Math.floor(Math.random() * 1e16) + 1; } diff --git a/server/amusement.js b/server/amusement.js index 14cd76c..b29d159 100644 --- a/server/amusement.js +++ b/server/amusement.js @@ -11,13 +11,13 @@ var working = false; function _cds() { - diskspace.check(config.MOUNTPOINT, function(e, result) { - if(result) - ds = Math.round((result.used / result.total) * 100); - else - ds = -1; - working=false; - }); + diskspace.check(config.MOUNTPOINT, function(e, result) { + if(result) + ds = Math.round((result.used / result.total) * 100); + else + ds = -1; + working=false; + }); } const loli = require("hashloli"); @@ -32,169 +32,181 @@ const maxLolis = 10; const maxLolisLong = 100; function getLoli() { - if(lolis[0]) - var ret = lolis.pop(); - - if(!ret || lolis.length= maxLolisLong) - reqd.pop(); - - }); - -// console.log("AAAA "+JSON.stringify(lolis)); - }); - return ret; + if(v && !reqd.includes(v)) { + lolis.push({file: v, preview: vv.preview_url}); + reqd.push(v); + } else if(reqd[0]) reqd.pop(); + + while(reqd.length >= maxLolisLong) + reqd.pop(); + + }); + + // console.log("AAAA "+JSON.stringify(lolis)); + }); + return ret; } getLoli(); //_cds(); exports.roll_dice = function (frag, post, extra) { - var ms = frag.split(common.dice_re); - var dice = []; - for (var i = 1; i < ms.length && dice.length < rollLimit; i += 2) { - if (ms[i] == '#loli') { - let cute = getLoli(); - if(cute) - dice.push([cute.file, cute.preview]); - else - dice.push(["/404", "/s/error.jpg"]); - } - else if(ms[i] == '#?') - { - if(!post.body) dice.push([-1]); - else { - var options=[]; - var sbody = post.body.split("\n"); - for(var j=sbody.length-2;j>=0;j--) - { - var cur = sbody[j].trim(); - if(cur.length<1 || /#\?$/.test(cur)) continue; - if(/\?$/.test(cur)) options.push(cur.slice(0,-1)); - else break; - } - var f = options.length; - if(options.length<1) dice.push([0]); - else dice.push([options[Math.floor(Math.random() * f)]]); - - } - } - else if(ms[i] == '#du') + var ms = frag.split(common.dice_re); + var dice = []; + for (var i = 1; i < ms.length && dice.length < rollLimit; i += 2) { + if (ms[i] == '#loli') { + let cute = getLoli(); + if(cute) + dice.push([cute.file, cute.preview]); + else + dice.push(["/404", "/s/error.jpg"]); + } + else if(ms[i] == '#?') + { + if(!post.body) dice.push([-1]); + else { + var options=[]; + var sbody = post.body.split("\n"); + for(var j=sbody.length-2;j>=0;j--) { - working = true; - if( dice.length + (post.dice ? post.dice.length : 0) < rollLimit) - _cds(); - else working = false; - // while(working) ; //SPIN SPIN SPINNN~~~~ - - dice.push([ds]); - } - else if(ms[i] == '#pyu') { - if( dice.length + (post.dice ? post.dice.length : 0) < rollLimit) - pyu += 1; - dice.push([pyu]); - } - else if(ms[i] == '#pcount') { - dice.push([pyu]); - } - else { - var info = common.parse_dice(ms[i]); - if (!info) - continue; - var f = info.faces; - var rolls = [f]; - for (var j = 0; j < info.n; j++) - rolls.push(Math.floor(Math.random() * f) + 1); - if (info.bias) - rolls.push({bias: info.bias}) - dice.push(rolls); + var cur = sbody[j].trim(); + if(cur.length<1 || /#\?$/.test(cur)) continue; + if(/\?$/.test(cur)) options.push(cur.slice(0,-1)); + else break; } + var f = options.length; + if(options.length<1) dice.push([0]); + else dice.push([options[Math.floor(Math.random() * f)]]); + + } + } + else if(ms[i] == '#du') + { + working = true; + if( dice.length + (post.dice ? post.dice.length : 0) < rollLimit) + _cds(); + else working = false; + // while(working) ; //SPIN SPIN SPINNN~~~~ + + dice.push([ds]); } + else if (ms[i] == '#tea') + { + const hours = new Date().getUTCHours(); + if ( (hours >= 14 && hours< 16) || (hours >= 2 && hours <4)) + dice.push([true]); + else { + const fxdate = (h) => h<0?fxdate(24+h):h; + const morning_session = fxdate(14 - hours); + const evening_session = fxdate(2 - hours); + dice.push([Math.min(morning_session, evening_session)]); + } + } + else if(ms[i] == '#pyu') { + if( dice.length + (post.dice ? post.dice.length : 0) < rollLimit) + pyu += 1; + dice.push([pyu]); + } + else if(ms[i] == '#pcount') { + dice.push([pyu]); + } + else { + var info = common.parse_dice(ms[i]); + if (!info) + continue; + var f = info.faces; + var rolls = [f]; + for (var j = 0; j < info.n; j++) + rolls.push(Math.floor(Math.random() * f) + 1); + if (info.bias) + rolls.push({bias: info.bias}) + dice.push(rolls); + } + } + if (dice.length) { + // Would prefer an appending scheme for adding new rolls but + // there's no hash value append redis command... + // I don't want to spill into a separate redis list. + // Overwriting the whole log every time is quadratic though. + // Enforcing a roll limit to deter that and for sanity + var exist = post.dice ? post.dice.length : 0; + if (dice.length + exist > rollLimit) + dice = dice.slice(0, Math.max(0, rollLimit - exist)); if (dice.length) { - // Would prefer an appending scheme for adding new rolls but - // there's no hash value append redis command... - // I don't want to spill into a separate redis list. - // Overwriting the whole log every time is quadratic though. - // Enforcing a roll limit to deter that and for sanity - var exist = post.dice ? post.dice.length : 0; - if (dice.length + exist > rollLimit) - dice = dice.slice(0, Math.max(0, rollLimit - exist)); - if (dice.length) { - extra.new_dice = dice; - dice = post.dice ? post.dice.concat(dice) : dice; - post.dice = dice; - } + extra.new_dice = dice; + dice = post.dice ? post.dice.concat(dice) : dice; + post.dice = dice; } + } }; function inline_dice(post, dice) { - if (dice && dice.length) { - dice = JSON.stringify(dice); - post.dice = dice.substring(1, dice.length - 1); - } + if (dice && dice.length) { + dice = JSON.stringify(dice); + post.dice = dice.substring(1, dice.length - 1); + } } hooks.hook('attachToPost', function (attached, cb) { - var new_dice = attached.extra.new_dice; - if (new_dice) { - attached.attach.dice = new_dice; - inline_dice(attached.writeKeys, attached.post.dice); - } - cb(null); + var new_dice = attached.extra.new_dice; + if (new_dice) { + attached.attach.dice = new_dice; + inline_dice(attached.writeKeys, attached.post.dice); + } + cb(null); }); hooks.hook_sync('inlinePost', function (info) { - inline_dice(info.dest, info.src.dice); + inline_dice(info.dest, info.src.dice); }); hooks.hook_sync('extractPost', function (post) { - if (!post.dice) - return; - try { - post.dice = JSON.parse('[' + post.dice + ']'); - } - catch (e) { - delete post.dice; - } + if (!post.dice) + return; + try { + post.dice = JSON.parse('[' + post.dice + ']'); + } + catch (e) { + delete post.dice; + } }); // This is looking rather boilerplatey hooks.hook('clientSynced', function (info, cb) { - var op = info.op, client = info.client; - if (op) { - client.db.get_fun(op, function (err, js) { - if (err) - return cb(err); - if (js) - client.send([op, common.EXECUTE_JS, js]); - cb(null); - }); - } - else - cb(null); + var op = info.op, client = info.client; + if (op) { + client.db.get_fun(op, function (err, js) { + if (err) + return cb(err); + if (js) + client.send([op, common.EXECUTE_JS, js]); + cb(null); + }); + } + else + cb(null); }); hooks.hook('clientSynced', function (info, cb) { - var client = info.client; - client.db.get_banner(function (err, banner) { - if (err) - return cb(err); - if (!banner) - return cb(null); - var msg = banner.message; - if (msg) - client.send([banner.op, common.UPDATE_BANNER, msg]); - cb(null); - }); + var client = info.client; + client.db.get_banner(function (err, banner) { + if (err) + return cb(err); + if (!banner) + return cb(null); + var msg = banner.message; + if (msg) + client.send([banner.op, common.UPDATE_BANNER, msg]); + cb(null); + }); });