var is_iphone = navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i); var is_ipad = navigator.userAgent.match(/iPad/i); var is_android = navigator.userAgent.match(/Android/i); var is_mobile = is_iphone || is_ipad || is_android; var is_desktop = !is_mobile; document.body.classList.add(is_desktop ? "desktop" : "mobile"); function choice(a) { return a[randint(a.length)]; } function csrf() { return $("[name=_csrf]").attr("value"); } function bold_terms(s, terms) { s = sanitizeHTML(s); terms.forEach((term) => { s = s.replace(new RegExp(term, "ig"), "" + term + ""); }); return s; } function querystring(opt) { return ( "?" + Object.keys(opt) .map((key) => { return encodeURIComponent(key) + "=" + encodeURIComponent(opt[key]); }) .join("&") ); } function commatize(n, radix) { radix = radix || 1000; var nums = [], i, counter = 0, r = Math.floor; if (radix !== -1 && n > radix) { n /= radix; nums.unshift(r((n * 10) % 10)); nums.unshift("."); } do { i = r(n % 10); n = r(n / 10); counter += 1; if (n && !(counter % 3)) { i = " " + r(i); } nums.unshift(i); } while (n); return nums.join(""); } function privacy_dot(p) { if (!p) return "·"; else return ".:"; } var short_months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "); function verbose_date(date, no_pad_hours) { var date = new Date(date * 1000); var d = date.getDate(); var m = date.getMinutes(); var h = date.getHours(); var meridian; if (h == 0) { h = 12; meridian = " am"; } else if (h == 12) { meridian = " pm"; } else if (h > 12) { h -= 12; meridian = " pm"; } else { meridian = " am"; } if (d < 10) d = "0" + d; if (m < 10) m = "0" + m; if (!no_pad_hours && h < 10) h = "0" + h; // non-breaking hyphen: ‑ var date = d + " " + short_months[date.getMonth()] + " " + date.getFullYear(); var time = h + ":" + m + meridian; return [date, time]; } function carbon_date(date, no_bold) { var span = +new Date() / 1000 - date; if (!no_bold && span < 86400) { // modified today color = "new"; } else if (span < 604800) { // modifed this week color = "recent"; } else if (span < 1209600) { // modifed 2 weeks ago color = "med"; } else if (span < 3024000) { // modifed 5 weeks ago color = "old"; } else if (span < 12315200) { // modifed 6 months ago color = "older"; } else { color = "quiet"; } return color; } function hush_views(n, bias, no_bold) { var txt = commatize(n, 1000); bias = bias || 1; n = n || 0; if (n < 30) { return ["quiet", n + " v."]; } if (n < 200) { return ["quiet", txt + " v."]; } else if (n < 500) { return ["old", txt + " v."]; } else if (n < 1000) { return ["med", txt + " v."]; } else if (n < 5000) { return ["recent", txt + " kv."]; } else if (no_bold || n < 10000) { return ["recent", txt + " kv."]; } else { return ["new", txt + " kv."]; } } function hush_threads(n, bias, no_bold) { var txt = commatize(n, -1); bias = bias || 1; n = n || 0; if (n < 10) { return ["quiet", n + " t."]; } else if (n < 25) { return ["old", txt + " t."]; } else if (n < 50) { return ["med", txt + " t."]; } else if (no_bold || n < 100) { return ["recent", txt + " t."]; } else { return ["new", txt + " t."]; } } function hush_size(n, bias, no_bold) { var txt = commatize(Math.floor(n / 1024), 1000); bias = 1 || bias; n = n || 0; if (n < 1024) { return ["quiet", n + " b."]; } if (n < 1000 * 1000) { return ["quiet", txt + " kb."]; } if (n < 20000000 / bias) { return ["quiet", txt + " mb."]; } if (n < 50000000 / bias) { return ["old", txt + " mb."]; } if (n < 80000000 / bias) { return ["med", txt + " mb."]; } if (no_bold || n < 170000000 / bias) { return ["recent", txt + " mb."]; } if (n >= 10000 * 1000 * 1000) { console.log(n); txt = commatize(Math.floor(n / (1024 * 1024 * 1024))); return ["new", txt + " gb."]; } return ["new", txt + " mb."]; } function hush_null(n, unit, no_bold) { n = commatize(n, -1); var s = unit ? n + " " + unit + "." : n; if (n < 3) { return ["quiet", s]; } else if (n < 6) { return ["older", s]; } else if (n < 10) { return ["old", s]; } else if (n < 16) { return ["med", s]; } else if (no_bold || n < 21) { return ["recent", s]; } else { return ["new", s]; } } function courtesy_s(n, s) { return n == 1 ? "" : s || "s"; } var revision_letters = "z a b c d f g h j k l m n p q r s t v w x y".split(" "); function get_revision(thread) { if (!thread.revision) return ""; var rev = thread.revision; var n = 0; var digits = ""; do { n = rev % 21; rev = Math.floor(rev / 21); digits = revision_letters[n] + digits; } while (rev !== 0); return digits; } function get_age(t, long) { var age = Math.abs(Date.now() / 1000 - t); var r = Math.floor; var m; if (age < 5) { return "now"; } if (age < 60) { return r(age) + (long ? " seconds" : "s"); } age /= 60; if (age < 60) { return r(age) + (long ? " minutes" : "m"); } m = r(age % 60); age /= 60; if (m > 0 && age < 2) { return r(age) + (long ? " hours " + m + " minutes" : "h" + m + "m"); } if (age < 24) { return r(age) + (long ? " hours" : "h"); } age /= 24; if (age < 7) { return r(age) + (long ? " days" : "d"); } age /= 7; if (age < 12) { return r(age) + (long ? " weeks" : "w"); } age /= 4; if (age < 12) { return r(age) + (long ? " months" : "m"); } age /= 12; return r(age) + (long ? " years" : "y"); } const age_scale = [ [0, 1.0], [60 * 10, 1.0], [60 * 60, 0.95], [60 * 60 * 8, 0.9], [60 * 60 * 24, 0.85], [60 * 60 * 24 * 7, 0.65], [60 * 60 * 24 * 7 * 4, 0.55], [60 * 60 * 24 * 7 * 4 * 12, 0.5], ]; function get_age_opacity(t) { var age = Math.abs(Date.now() / 1000 - t); return get_scale_opacity(age, age_scale); } const size_scale = [ [0, 0.0], [1, 0.7], [5, 0.8], [10, 0.9], [15, 0.95], [20, 0.99], ]; function get_size_opacity(n) { return get_scale_opacity(n, size_scale); } function get_scale_opacity(value, scale) { for (let i = 1; i < scale.length; i++) { const [max_value, max_lerp] = scale[i]; if (value < max_value) { const [min_value, min_lerp] = scale[i - 1]; return lerp(norm(value, min_value, max_value), min_lerp, max_lerp); } } return scale[scale.length - 1][1]; } function tidy_urls(s, short_urls) { var ret = s .split("\n") .map(function (line) { if (line.indexOf("<") !== -1) { return line; } return line.replace(/https?:\/\/[^ ]+/g, function (url) { if (is_image(url)) { return ( '' ); } else if (short_urls) { return ( '[' + get_domain(url) + "]" ); } else { return ( '' + url + "" ); } }); }) .join("\n") .replace(/\r/g, "") .replace(/\n/g, "") .replace(/<\/code>\n/g, ""); return ret; } function get_domain(url) { return url .replace(/https?:\/\//, "") .replace(/\/.*/, "") .replace(/www\./, ""); } function is_image(url) { return !!url.match(/\.(gif|jpe?g|png)(\?.*)?$/i); } function make_link(file) { if (file.storage) { return ( "//s3.amazonaws.com/" + file.storage + sdk.opt.s3.path + "/data/" + file.thread + "/" + encodeURIComponent(file.filename) ); } if (file.filename.indexOf("http") !== 0) { return "/data/" + file.thread + "/" + encodeURIComponent(file.filename); } return file.filename; } function profile_image(username) { return "//s3.amazonaws.com/i.asdf.us/bucky/profile/" + username + ".jpg"; } function make_thumb(file) { if (file.storage) { return ( "//s3.amazonaws.com/" + file.storage + sdk.opt.s3.path + "/data/" + file.thread + "/" + encodeURIComponent(file.filename) ); } if (file.filename.indexOf("http") !== 0) { return "/data/" + file.thread + "/" + file.filename; } return "/data/" + file.thread + "/" + file.filename; // var partz = file.filename.toLowerCase().split("/") // return partz.splice(partz.length-2, 0, ".thumb").join("/") } var metadataTemplate = $(".metadata_template").html(); function metadata(thread) { var datetime = verbose_date(thread.createdate, true); var age = get_age(thread.lastmodified, true); var t = metadataTemplate .replace(/{{username}}/g, thread.username) .replace(/{{date}}/g, datetime[0]) .replace(/{{time}}/g, datetime[1]) .replace(/{{active}}/g, age + " ago") .replace(/{{views}}/g, thread.viewed + " view" + courtesy_s(thread.viewed)); return t; }