/*
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/
// THIS IS AN AUTOMATICALLY COMBINED FILE. PLEASE EDIT THE source/ FILES!

const PONYMAIL_REVISION = '86af91a';


/******************************************
 Fetched from source/aavariables.js
******************************************/

 /* jshint -W097 */
'use strict';

const PONYMAIL_VERSION = "1.0.1"; // Current version of Pony Mail Foal

let G_apiURL = ''; // external API URL. Usually left blank.

// Stuff regarding what we're doing right now
let G_current_json = {};
let G_current_state = {};
let G_current_list = '';
let G_current_domain = '';
let G_current_year = 0;
let G_current_month = 0;
let G_current_open_email = null;
let G_select_primed = false;
let G_ponymail_preferences = {};
let G_ponymail_search_list = 'this';

let G_current_listmode = 'threaded';
let G_current_listmode_compact = false;
const PONYMAIL_MAX_NESTING = 10; // max nesting level before unthreading to save space

// thread state
let G_current_email_idx;
let G_chatty_layout = true;

// emails (composer, key-commands, render-email)
let G_full_emails = {};

// listview-*.js, key-commands
let G_current_index_pos = 0;
let G_current_per_page = 0;

// sidebar calendar
const MONTHS_SHORTENED = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const CALENDAR_YEARS_SHOWN = 4; // TODO: should this be configurable?
let G_show_stats_sidebar = true; // Whether to show author stats or not

// datepicker
const DAYS_SHORTENED = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']

// render_email_chatty
const PONYMAIL_DATE_FORMAT = {
    weekday: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric'
};
const PONYMAIL_TIME_FORMAT = { timeStyle: 'long'}; // ensure TZ is shown

let G_collated_json = {};

if (pm_config.apiURL) {
    G_apiURL = pm_config.apiURL;
    console.log("Setting API URL to " + G_apiURL);
}

// check local storage for settings
console.log("Checking localStorage availability");
let G_can_store = false;
if (window.localStorage && window.localStorage.setItem) {
    try {
        window.localStorage.setItem("ponymail_test", "foo");
        G_can_store = true;
        console.log("localStorage available!");
    } catch (e) {
        console.log("no localStorage available!");
    }
}


/******************************************
 Fetched from source/base-http-extensions.js
******************************************/

// URL calls currently 'in escrow'. This controls the spinny wheel animation
let async_escrow = {}
const ASYNC_MAXWAIT = 250; // ms to wait before displaying spinner
let async_status = 'clear';
let async_cache = {}

// Escrow spinner check
async function escrow_check() {
    let now = new Date();
    let show_spinner = false;
    for (let k in async_escrow) {
        if ((now - async_escrow[k]) > ASYNC_MAXWAIT) {
            show_spinner = true;
            break;
        }
    }
    // Fetch or create the spinner
    let spinner = document.getElementById('spinner');
    if (!spinner) {
        spinner = new HTML('div', {
            id: 'spinner',
            class: 'spinner'
        });
        let spinwheel = new HTML('div', {
            id: 'spinwheel',
            class: 'spinwheel'
        });
        spinner.inject(spinwheel);
        spinner.inject(new HTML('h2', {}, "Loading, please wait.."));
        document.body.appendChild(spinner);
    }
    // Show or don't show spinner?
    if (show_spinner) {
        spinner.style.display = 'block';
        if (async_status === 'clear') {
            console.log("Waiting for JSON resource, deploying spinner");
            async_status = 'waiting';
        }
    } else {
        spinner.style.display = 'none';
        if (async_status === 'waiting') {
            console.log("All URLs out of escrow, dropping spinner");
            async_status = 'clear';
        }
    }
}

async function async_snap(error) {
    let msg = await error.text();
    msg = msg.replace(/<.*?>/g, ""); // strip HTML tags
    if (error.status === 404) {
        msg += "\n\nYou may need to be logged in with additional permissions in order to view this resource.";
        if (pm_config.perm_error_postface) {
            msg += pm_config.perm_error_postface;
        }
    }
    modal("An error occured", "An error code %u occured while trying to fetch %s:\n%s".format(error.status, error.url, msg), "error");
}


// Asynchronous GET call
async function GET(url, callback, state) {
    console.log("Fetching JSON resource at %s".format(url));
    let pkey = "GET-%s-%s".format(callback, url);
    let res;
    let res_json;
    state = state || {};
    state.url = url;
    if (state && state.cached === true && async_cache[url]) {
        console.log("Fetching %s from cache".format(url));
        res_json = async_cache[url];
    } else {
        try {
            console.log("putting %s in escrow...".format(url));
            async_escrow[pkey] = new Date(); // Log start of request in escrow dict
            const rv = await fetch(url, {
                credentials: 'same-origin'
            }); // Wait for resource...

            // Since this is an async request, the request may have been canceled
            // by the time we get a response. Only do callback if not.
            if (async_escrow[pkey] !== undefined) {
                res = rv;
            }
        } catch (e) {
            delete async_escrow[pkey]; // move out of escrow if failed
            console.log("The URL %s could not be fetched: %s".format(url, e));
            modal("An error occured", "An error occured while trying to fetch %s:\n%s".format(url, e), "error");
        }
    }
    if (res !== undefined || res_json !== undefined) {
        // We expect a 2xx return code (usually 200 or 201), snap otherwise
        if ((res_json) || (res.status >= 200 && res.status < 300)) {
            console.log("Successfully fetched %s".format(url))
            let js;
            if (res_json) {
                js = res_json;
            } else {
                js = await res.json();
                delete async_escrow[pkey]; // move out of escrow when fetched
                async_cache[url] = js;
            }
            if (callback) {
                callback(state, js);
            } else {
                console.log("No callback function was registered for %s, ignoring result.".format(url));
            }
        } else {
            console.log("URL %s returned HTTP code %u, snapping!".format(url, res.status));
            delete async_escrow[pkey]; // move out of escrow when fetched
            async_snap(res);
        }
    }
}


/******************************************
 Fetched from source/base-js-extensions.js
******************************************/

/**
 * String formatting prototype
 * A'la printf
 */

String.prototype.format = function() {
    let args = arguments;
    let n = 0;
    let t = this;
    let rtn = this.replace(/(?!%)?%([-+]*)([0-9.]*)([a-zA-Z])/g, function(m, pm, len, fmt) {
        len = parseInt(len || '1');
        // We need the correct number of args, balk otherwise, using ourselves to format the error!
        if (args.length <= n) {
            let err = "Error interpolating string '%s': Expected at least %u argments, only got %u!".format(t, n + 1, args.length);
            console.log(err);
            throw err;
        }
        let varg = args[n];
        n++;
        switch (fmt) {
            case 's':
                if (typeof(varg) == 'function') {
                    varg = '(function)';
                }
                return varg;
                // For now, let u, d and i do the same thing
            case 'd':
            case 'i':
            case 'u':
                varg = parseInt(varg).pad(len); // truncate to Integer, pad if needed
                return varg;
        }
    });
    return rtn;
};


/**
 * Number prettification prototype:
 * Converts 1234567 into 1,234,567 etc
 */

Number.prototype.pretty = function(fix) {
    if (fix) {
        return String(this.toFixed(fix)).replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
    }
    return String(this.toFixed(0)).replace(/(\d)(?=(\d{3})+$)/g, '$1,');
};


/**
 * Number padding
 * usage: 123.pad(6) -> 000123
 */

Number.prototype.pad = function(n) {
    let str = String(this);

    /* Do we need to pad? if so, do it using String.repeat */
    if (str.length < n) {
        str = "0".repeat(n - str.length) + str;
    }
    return str;
};

/* Func for converting TZ offset from minutes to +/-HHMM */

Date.prototype.TZ_HHMM = function() {
    let off_mins = this.getTimezoneOffset();
    let off_hh =   Math.floor(Math.abs(off_mins/60));
    let off_mm =   Math.abs(off_mins%60);
    let sgn = off_mins > 0 ? '-' : '+';
    return sgn + off_hh.pad(2) + ':' + off_mm.pad(2);
};



/* Func for converting a date to YYYY-MM-DD HH:MM TZ */

Date.prototype.ISOBare = function() {
    let M, O, d, h, m, y;
    if (prefs.UTC === true) {
        y = this.getUTCFullYear();
        m = (this.getUTCMonth() + 1).pad(2);
        d = this.getUTCDate().pad(2);
        h = this.getUTCHours().pad(2);
        M = this.getUTCMinutes().pad(2);
        O = 'UTC';
    } else {
        y = this.getFullYear();
        m = (this.getMonth() + 1).pad(2);
        d = this.getDate().pad(2);
        h = this.getHours().pad(2);
        M = this.getMinutes().pad(2);
        O = this.TZ_HHMM();
    }
    return y + "-" + m + "-" + d + " " + h + ":" + M + " " + O;
};


/* isArray: function to detect if an object is an array */

function isArray(value) {
    return value && typeof value === 'object' && value instanceof Array && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
}


/* isHash: function to detect if an object is a hash */

function isHash(value) {
    return value && typeof value === 'object' && !isArray(value);
}


/* Remove an array element by value */

Array.prototype.remove = function(val) {
    let i, item, j, len;
    for (i = j = 0, len = this.length; j < len; i = ++j) {
        item = this[i];
        if (item === val) {
            this.splice(i, 1);
            return this;
        }
    }
    return this;
};


/* Check if array has value */
Array.prototype.has = function(val) {
    for (let item of this) {
        if (item === val) {
            return true;
        }
    }
    return false;
};

function isEmpty(obj) {
    return (
        obj &&
        Object.keys(obj).length === 0 &&
        Object.getPrototypeOf(obj) === Object.prototype
    );
}


/******************************************
 Fetched from source/body-fixups.js
******************************************/

const PONYMAIL_URL_RE = new RegExp("(" + "(?:(?:[a-z]+)://)" + "(?:\\S+(?::\\S*)?@)?" + "(?:" + "([01][0-9][0-9]|2[0-4][0-9]|25[0-5])" + "|" + "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" + "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" + "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" + "\\.?" + ")" + "(?::\\d{2,5})?" + "\\/?" + "(?:[/?#]?([^,<>()\\[\\] \\t\\r\\n]|(<[^:\\s]*?>|\\([^:\\s]*?\\)|\\[[^:\\s]*?\\]))*)?" + ")\\.?" + "\\b", "mi");

// Regex for things to potentially put inside quote objects:
// - quotes
// - forwarded emails
// - inline quoting
// - top posting with original email following
const PONYMAIL_QUOTE_RE = new RegExp("(" +
    // Typical encapsulation of context by ticketing systems and/or bug trackers
    "(---\\r?\\n([^\\r\\n]*?\\r?\\n)*?---$)|" +
    "(" +
    "(?:\\r?\\n|^)" + // start of line or after a colon
    // Classic method; a signal line and the quote with '>' starting each line quoted
    "(" +
    "(" + // Initial line signalling a quote
    "((\\d+-\\d+-\\d+)\\s+.+<\\S+@\\S+>:[ \t\r\n]+)|" + // "01-02-1982 Foo Bar <foo@bar.baz>:" OR
    "(on\\s+(.+|.+\\n.+)\\s+wrote:[\r?\n]+)|" + // "On $somedate, $someone wrote:", OR...
    "(le\\s+(.+|.+\\n.+)\\s+écrit:[\r?\n]+)|" + // French version of the above, OR...
    "(.?am .+? schrieb\\s+.+:[\r?\n]+)|" + // German version of the above, OR...
    "(envoy[ée] de mon .+|sent from my .+|von meinem .+ gesendet)[ \t\r\n]+" + // "sent from my iphone/ipad/android phone/whatever", usually means the next part is a quote.
    ")" + // End initial signal line
    "(^$)*" + // Accept blank newlines following it...
    "(((^(?!>)[\\s\\S]+$)*)|(^\\s*>[\\s\\S]+$)*)" + // Either text that follows immediately after with no '>' first, OR text with '>' first, but NOT both...
    ")|" +
    "(" +
    // Lines after the signal line; comes in one shape, generally speaking...
    "(^\\s*>+[ \\t]*[^\r\n]*\r*\n+)+" + // Lines beginning with one or more '>' after the initial signal line
    ")" +
    ")+|" + //OR...
    "(" +
    "^(-{5,10}) .+? \\1[\r\n]+" + // ----- Forwarded Message -----
    "(^\\w+:\\s+.+[\r\n]+){3,10}[\r\n]+" + // Between three and ten header fields (we ask for at least 3, so as to not quote PGP blocks)
    "[\\S\\s]+" + // Whatever comes next...
    ")+" +
    ")", "mi");

// Somewhat simplified method for catching email footers/trailers that we don't need
const PONYMAIL_TRAILER_RE = new RegExp("^--[\r\n]+.*", "mi"); //(--\r?\n([^\r\n]*?\r?\n){1,6}$)|[\r\n.]+^((--+ \r?\n|--+\r?\n|__+\r?\n|--+\\s*[^\r\n]+\\s*--+\r?\n)(.*\r?\n)+)+$", "m");

// This is a regex for capturing code diff blocks in an email
const PONYMAIL_DIFF_RE = new RegExp(
    "(" +
    "^-{3} .+?[\r\n]+" + // Starts with a "--- /foo/bar/baz"
    "^\\+{3} .+?[\r\n]+" + // Then a "+++ /foo/bar/baz"
    "(" + // Then one or more of...
    "^@@@? .+[\r\n]+" + // positioning
    "(^ .*[\r\n]*$){0,3}" + // diff header
    "(^[-+ ].*[\r\n]*)+" + // actual diff
    "(^ .*[\r\n]*$){0,3}" + // diff trailer
    ")+" +
    ")", "mi");

// Function for turning URLs into <a> tags
function fixup_urls(splicer) {

    if (typeof splicer == 'object') {
        return splicer;
        //splicer = splicer.innerText;
    }
    /* Array holding text and links */
    let i, m, t, textbits, url, urls;
    textbits = [];

    /* Find the first link, if any */
    i = splicer.search(PONYMAIL_URL_RE);
    urls = 0;

    /* While we have more links, ... */
    while (i !== -1) {
        urls++;

        /* Only parse the first 250 URLs... srsly */
        if (urls > 250) {
            break;
        }

        /* Text preceding the link? add it to textbits frst */
        if (i > 0) {
            t = splicer.substr(0, i);
            textbits.push(t);
            splicer = splicer.substr(i);
        }

        /* Find the URL and cut it out as a link */
        m = splicer.match(PONYMAIL_URL_RE);
        if (m) {
            url = m[1];
            i = url.length;
            t = splicer.substr(0, i);
            textbits.push(new HTML('a', {
                href: url
            }, url));
            splicer = splicer.substr(i);
        }

        /* Find the next link */
        i = splicer.search(PONYMAIL_URL_RE);
    }

    /* push the remaining text into textbits */
    textbits.push(splicer);
    return textbits;
}


// Simple check to (attempt to) assess whether a trailer should
// remain or get cut out.
function legit_trailer(a) {
    let lines = a.split(/\s*\r?\n/);
    let first_line = lines.shift();
    while (first_line.length == 0 && lines.length) first_line = lines.shift(); // get first meaningful line
    if (!lines.length || first_line == '--') return ''; // likely a simple trailer
    let last_line = lines.pop();
    while (last_line.length == 0 && lines.length) last_line = lines.pop(); // get last meaningful line

    // Check if first and last line are similar, which is usually indictive of a ticket system
    if (last_line == first_line) {
        return a;
    }
    // Otherwise, check if first line has two or more dashes, and it occurs again later (also tix)
    if (first_line.match(/^---+/) && lines.has(first_line)) {
        return "|||" + a + "|||";
    }

    // Lastly, if there is "sufficient" length to the dashes, allow (JIRA etc)
    if (first_line.match(/^-{6,72}$/)) return a;
    return '';
}

// Function for cutting away trailers
function cut_trailer(splicer) {
    if (!G_chatty_layout) return splicer; // only invoke in social rendering mode
    if (typeof splicer == 'object') {
        splicer.innerText = splicer.innerText.replace(PONYMAIL_TRAILER_RE, legit_trailer, 3);
    } else {
        splicer = splicer.replace(PONYMAIL_TRAILER_RE, legit_trailer);

    }
    return splicer;
}

function color_diff_lines(diff) {
    let lines = diff.split(/[\r\n]+/);
    let ret = [];
    for (let z = 0; z < lines.length; z++) {
        let line = lines[z];
        let color = 'grey';
        if (line[0] == '@') color = 'blue';
        if (line[0] == '-') color = 'red';
        if (line[0] == '+') color = 'green';
        if (line[0] == ' ') color = 'black';
        let el = new HTML('span', {
            style: {
                color: color
            }
        }, line);
        ret.push(el);
        ret.push(new HTML('br'));
    }
    return ret;
}

// Function for coloring diffs
function fixup_diffs(splicer) {
    if (!G_chatty_layout) return splicer; // only invoke in social rendering mode
    if (typeof splicer == 'object') {
        splicer = splicer.innerText;
    }
    /* Array holding text and links */
    let i, m, t, diff, diffs;
    let textbits = [];

    /* Find the first link, if any */
    i = splicer.search(PONYMAIL_DIFF_RE);
    diffs = 0;

    /* While we have more links, ... */
    while (i !== -1) {
        diffs++;

        /* Only parse the first 20 diffs... srsly */
        if (diffs > 25) {
            break;
        }
        console.log(i);
        /* Text preceding the diff? add it to textbits frst */
        if (i > 0) {
            t = splicer.substr(0, i);
            textbits.push(t);
            splicer = splicer.substr(i);
        }

        /* Find the URL and cut it out as a link */
        m = splicer.match(PONYMAIL_DIFF_RE);
        if (m) {
            diff = m[1];
            i = diff.length;
            t = splicer.substr(0, i);
            textbits.push(new HTML('pre', {
                class: 'diff'
            }, color_diff_lines(diff)));
            splicer = splicer.substr(i);
        }

        /* Find the next link */
        i = splicer.search(PONYMAIL_DIFF_RE);
    }

    /* push the remaining text into textbits */
    textbits.push(splicer);
    return textbits;
}

// Function for turning quotes into quote segments
function fixup_quotes(splicer) {
    if (splicer[splicer.length - 1] !== "\n") splicer += "\n"; //tweak to make quotes match the last line if no newline on it.
    let hideQuotes, i, m, qdiv, quote, quotes, t, textbits;
    hideQuotes = true;
    if (prefs.compactQuotes === false && !G_chatty_layout) {
        hideQuotes = false;
    }
    if (!hideQuotes) return splicer; // We'll bail here for now. Dunno why not.

    /* Array holding text and quotes */
    textbits = [];

    /* Find the first quote, if any */
    i = splicer.search(PONYMAIL_QUOTE_RE);
    quotes = 0;

    /* While we have more quotes, ... */
    while (i !== -1) {
        quotes++;

        /* Only parse the first 50 quotes... srsly */
        if (quotes > 50) {
            break;
        }

        /* Text preceding the quote? add it to textbits first */
        if (i > 0) {
            t = splicer.substr(0, i);
            let diffed = fixup_diffs(cut_trailer(t));
            if (isArray(diffed)) {
                for (let z = 0; z < diffed.length; z++) textbits.push(fixup_urls(diffed[z]));
            } else textbits.push(fixup_urls(diffed));
            splicer = splicer.substr(i);
        }

        /* Find the quote and cut it out as a div */
        m = splicer.match(PONYMAIL_QUOTE_RE);
        if (m) {
            quote = m[0];
            i = quote.length;
            t = splicer.substr(0, i);
            quote = quote.replace(/\n>[>\s]*$/g, "\n");
            qdiv = new HTML('div', {
                "class": "email_quote_parent"
            }, [
                new HTML('button', {
                    title: "Toggle quote",
                    onclick: "toggle_quote(this)"
                }, new HTML('span', {
                    class: 'glyphicon glyphicon-comment'
                }, " ")), new HTML('br'), new HTML('blockquote', {
                    "class": "email_quote",
                    style: {
                        display: hideQuotes ? 'none' : 'block'
                    }
                }, fixup_urls(quote))
            ]);
            textbits.push(qdiv);
            splicer = splicer.substr(i);
        }

        /* Find the next quotes */
        i = splicer.search(PONYMAIL_QUOTE_RE);
    }

    /* push the remaining text into textbits */
    let diffed = fixup_diffs(cut_trailer(splicer));
    if (isArray(diffed)) {
        for (let z = 0; z < diffed.length; z++) diffed[z] = fixup_urls(diffed[z]);
    } else diffed = fixup_urls(diffed);
    textbits.push(new HTML('span', {}, diffed));

    return textbits;
}

function toggle_quote(el) {
    let quote = el.parentNode.childNodes[2];
    if (quote.style.display != 'block') {
        quote.style.display = 'block';
    } else {
        quote.style.display = 'none';
    }
}


/******************************************
 Fetched from source/composer.js
******************************************/

let mua_headers = {}; // communication between compose_email and compose_send

function compose_send() {
    let content = [];
    for (let k in mua_headers) {
        content.push(k + "=" + encodeURIComponent(mua_headers[k]));
    }
    // Push the subject, (b)cc and email body into the form data
    content.push("subject=" + encodeURIComponent(document.getElementById('composer_subject').value));
    content.push("cc=" + encodeURIComponent(document.getElementById('composer_cc').value));
    content.push("bcc=" + encodeURIComponent(document.getElementById('composer_bcc').value));
    content.push("body=" + encodeURIComponent(document.getElementById('composer_body').value));
    if (G_ponymail_preferences.login && G_ponymail_preferences.login.alternates && document.getElementById('composer_alt')) {
        content.push("alt=" + encodeURIComponent(document.getElementById('composer_alt').options[document.getElementById('composer_alt').selectedIndex].value));
    }

    let request = new XMLHttpRequest();
    request.open("POST", "%sapi/compose.lua".format(G_apiURL));
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    request.send(content.join("&")); // send email as a POST string

    request.onreadystatechange = function(state) {
        if (request.readyState == 4) {
            document.getElementById('composer_modal').style.display = 'none';
            let response = JSON.parse(request.responseText)
            if (response.error) {
                modal("Message dispatch failed!", response.error, "error");
            } else {
                modal("Message dispatched!", "Your email has been sent. Depending on moderation rules, it may take a while before it shows up in the archives.", "help");
            }
        }
    }

}

function compose_email(replyto, list) {
    let email = null;
    let mua_trigger = null;
    let loggedIn = (G_ponymail_preferences.login && G_ponymail_preferences.login.credentials) ? true : false;
    if (replyto) email = G_full_emails[replyto || ''];
    let listname = list;
    mua_headers = {};
    if (email) {
        listname = email.list_raw.replace(/[<>]/g, '').replace('.', '@', 1);
        mua_trigger = mua_link(email);
        if (email['message-id'] && email['message-id'].length > 0) mua_headers['in-reply-to'] = email['message-id'];
        if (email['message-id'] && email['message-id'].length > 0) mua_headers.references = email['message-id'];
        mua_headers.eid = email.mid;
    } else {
        mua_trigger = mua_link(null, listname);
    }
    mua_headers.to = listname;

    // Not logged in? MUA it is, then!
    if (!loggedIn) {
        if (email) {
            let a = new HTML('a', {
                href: mua_trigger
            }, "Reply via your own email client");
            let p = new HTML('p', {}, [
                "In order to reply to emails using the web interface, you need to be ",
                new HTML('a', {
                    href: '/oauth.html'
                }, "logged in first"),
                ". You can however still reply to this email using your own email client: ",
                a
            ]);
            composer("Reply to thread:", p);
            return;
        } else {
            modal("Please log in", "You need to be logged in before you can start a new thread.", "warning");
            return
        }
    }

    // Replying to an email and logged in?
    let eml_subject = "";
    let eml_body = "";
    let eml_title = `Start a new thread on ${listname}:`;
    if (email) {
        eml_subject = email.subject;
        if (!eml_subject.match(/^Re:\s+/i)) {  // Add "Re: " if needed only.
            eml_subject = "Re: " + eml_subject;
        }
        eml_body = composer_re(email);
        eml_title = `Reply to email on ${listname}:`;
    }
    let form = [];
    form.push(new HTML('b', {}, "Sending as:"));
    let s = new HTML('select', {
        id: 'composer_alt'
    });
    s.inject(new HTML('option', {}, G_ponymail_preferences.login.credentials.email));
    if (G_ponymail_preferences.login && G_ponymail_preferences.login.alternates) {
        for (let alternate of G_ponymail_preferences.login.alternates) {
            s.inject(new HTML('option', {}, alternate));
        }
    }
    form.push(new HTML('br'));
    form.push(s);
    form.push(new HTML('br'));
    form.push(new HTML('b', {}, "Subject:"));
    form.push(new HTML('br'));
    form.push(new HTML('input', {
        style: {
            width: '90%'
        },
        id: 'composer_subject',
        type: 'text',
        value: eml_subject
    }));
    form.push(new HTML('br'));
    form.push(new HTML('b', {}, "Cc:"));
    form.push(new HTML('br'));
    form.push(new HTML('input', {
        style: {
            width: '90%'
        },
        id: 'composer_cc',
        type: 'text',
    }));
    form.push(new HTML('br'));
    form.push(new HTML('b', {}, "Bcc:"));
    form.push(new HTML('br'));
    form.push(new HTML('input', {
        style: {
            width: '90%'
        },
        id: 'composer_bcc',
        type: 'text',
    }));
    form.push(new HTML('br'));
    form.push(new HTML('b', {}, "Reply:"));
    form.push(new HTML('br'));
    let body = new HTML('textarea', {
        style: {
            width: '90%',
            minHeight: '400px'
        },
        id: 'composer_body'
    }, eml_body);
    form.push(body);

    let btn = new HTML('button', {
        onclick: 'compose_send();'
    }, "Send reply");
    form.push(btn);
    form.push("   ");
    form.push(new HTML('a', {
        href: mua_trigger,
        style: {
            marginLeft: '10px'
        }
    }, "Or compose via your own email client"));

    composer(eml_title, form);
    if (email) document.getElementById('composer_body').focus();

}



// Generic modal function
function composer(title, contents) {
    let composer_modal = document.getElementById('composer_modal');
    if (composer_modal == undefined) {
        composer_modal = new HTML('div', {
            id: 'composer_modal'
        }, [
            new HTML('div', {
                id: 'composer_modal_content'
            }, [
                new HTML('span', {
                    id: 'composer_modal_close',
                    onclick: 'document.getElementById("composer_modal").style.display = "none";'
                }, 'X'),
                new HTML('h2', {
                    id: 'composer_modal_title'
                }, title),
                new HTML('div', {
                    id: 'composer_modal_contents'
                }, contents)
            ])
        ]);
        document.body.appendChild(composer_modal);

    } else {
        document.getElementById('composer_modal_title').innerText = title;
        document.getElementById('composer_modal_contents').innerHTML = '';
        document.getElementById('composer_modal_contents').inject(contents || '');
    }
    composer_modal.style.display = 'block';
}

// Constructor for email body in replies...
function composer_re(email) {
    let lines = email.body.split(/\r?\n/);
    for (let i = 0; i < lines.length; i++) {
        lines[i] = '> ' + lines[i];
    }
    let re = `\n\nOn ${email.date} ${email.from.replace(/\s*<.+?>/, '')} wrote:\n`;
    re += lines.join("\n");
    return re;
}

// MUA mailto: link generator
function mua_link(email, xlist) {
    if (!email && xlist) {
        return `mailto:${xlist}?subject=Subject+goes+here`;
    }
    let eml_raw_short = composer_re(email);
    let subject = "RE: " + email.subject || '';
    let N = 16000; // Anything above 16K can cause namespace issues with links.
    if (eml_raw_short.length > N) {
        eml_raw_short = eml_raw_short.substring(0, N) + "\n[message truncated...]";
    }
    let listname = email.list_raw.replace(/[<>]/g, '').replace('.', '@', 1);
    let xlink = 'mailto:' + listname + "?subject=" + encodeURIComponent(subject) + "&amp;In-Reply-To=" + encodeURIComponent(email['message-id']) + "&body=" + encodeURIComponent(eml_raw_short);
    return xlink;
}


/******************************************
 Fetched from source/construct-thread.js
******************************************/

function expand_email_threaded(idx, flat) {
    let placeholder = document.getElementById('email_%u'.format(idx));
    if (placeholder) {
        // Check if email is already visible - if so, hide it!
        if (placeholder.style.display == 'block') {
            console.log("Collapsing thread at index %u".format(idx));
            placeholder.style.display = 'none';
            G_current_email_idx = undefined;
            return false;
        }
        G_current_email_idx = idx;
        console.log("Expanding thread at index %u".format(idx));
        placeholder.style.display = 'block';

        // Check if we've already filled out the structure here
        if (placeholder.getAttribute('data-filled') == 'yes') {
            console.log("Already constructed this thread, bailing!");
        } else {
            // Construct the base scaffolding for all emails
            let eml = flat ? G_current_json.emails[idx] : G_current_json.thread_struct[idx];
            if (eml) {
                G_current_open_email = eml.tid || eml.mid;
            }
            let thread = construct_thread(eml);
            placeholder.inject(thread);
            placeholder.setAttribute("data-filled", 'yes');
        }
    }
    return false;
}

function construct_thread(thread, cid, nestlevel, included) {
    // First call on a thread/email, this is indef.
    // Use this to plop a scroll call when loaded
    // to prevent weird cache-scrolling
    let doScroll = false;
    if (cid === undefined) {
        doScroll = true;
    }
    included = included || [];
    cid = (cid || 0) + 1;
    nestlevel = (nestlevel || 0) + 1;
    let mw = calc_email_width();
    let max_nesting = PONYMAIL_MAX_NESTING;
    if (mw < 700) {
        max_nesting = Math.floor(mw / 250);
    }
    cid %= 5;
    let color = ['286090', 'ccab0a', 'c04331', '169e4e', '6d4ca5'][cid];
    let email;
    if (nestlevel < max_nesting) {
        email = new HTML('div', {
            class: 'email_wrapper',
            id: 'email_%s'.format(thread.tid || thread.id)
        });
        if (G_chatty_layout) {
            email.style.border = "none !important";
        } else {
            email.style.borderLeft = '3px solid #%s'.format(color);
        }
    } else {
        email = new HTML('div', {
            class: 'email_wrapper_nonest',
            id: 'email_%s'.format(thread.tid || thread.id)
        });
    }
    let wrapper = new HTML('div', {
        class: 'email_inner_wrapper',
        id: 'email_contents_%s'.format(thread.tid || thread.id)
    });
    email.inject(wrapper);
    if (isArray(thread.children)) {
        thread.children.sort((a, b) => a.epoch - b.epoch);
        for (let child of thread.children) {
            let reply = construct_thread(child, cid, nestlevel, included);
            cid++;
            if (reply) {
                email.inject(reply);
            }
        }
    }
    let tid = thread.tid || thread.id;
    if (!included.includes(tid)) {
        included.push(tid);
        console.log("Loading email %s".format(tid));
        GET("%sapi/email.lua?id=%s".format(G_apiURL, encodeURIComponent(tid)), render_email, {
            cached: true,
            scroll: doScroll,
            id: tid,
            div: wrapper
        });
    }
    return email;
}

// Singular thread construction via permalinks
function construct_single_thread(state, json) {
    G_current_json = json;
    if (json) {
        // Old schema has json.error filled on error, simplified schema has json.message filled and json.okay set to false
        let error_message = json.okay === false ? json.message : json.error;
        if (error_message) {
            modal("An error occured", "Sorry, we hit a snag while trying to load the email(s): \n\n%s".format(error_message), "error");
            return;
        }
    }
    let div = document.getElementById('emails');
    div.innerHTML = "";

    // Fix URLs if they point to an deprecated permalink
    if (json.thread) {
        let url_to_push = location.href.replace(/[^/]+$/, "") + json.thread.id;
        if (location.href != url_to_push) {
            console.log("URL differs from default permalink, pushing correct ID to history.");
            window.history.pushState({}, json.thread.subject, url_to_push)
        }
    }

    // Not top level thread?
    let looked_for_parent = location.query == 'find_parent=true';
    if (!looked_for_parent && json.thread['in-reply-to'] && json.thread['in-reply-to'].length > 0) {
        let isign = new HTML('span', {class: 'glyphicon glyphicon-eye-close'}, " ");
        let btitle = new HTML("b", {}, "This may not be the start of the conversation...");
        let a = new HTML("a", {href: "javascript:void(location.href += '?find_parent=true');"}, "Find parent email");
        let notice = new HTML("div", {class: "infobox"}, [
            isign,
            btitle,
            new HTML("br"),
            "This email appears to be a reply to another email, as it contains an in-reply-to reference.",
            new HTML("br"),
            "If you wish to attempt finding the root thread, click here: ",
            a
        ]);
        div.inject(notice);
        notice.inject(a);
    }

    if (G_chatty_layout) {
        let listname = json.thread.list_raw.replace(/[<>]/g, '').replace('.', '@', 1);
        div.setAttribute("class", "email_placeholder_chatty");
        div.inject(new HTML('h4', {
            class: 'chatty_title'
        }, json.emails[0].subject));
        div.inject(new HTML('a', {
            href: 'list.html?%s'.format(listname),
            class: 'chatty_title'
        }, 'Posted to %s'.format(listname)));
    } else {
        div.setAttribute("class", "email_placeholder");
    }
    document.title = json.emails[0].subject + "-" + prefs.title
    div.style.display = "block";
    let thread = json.thread;
    let email = construct_thread(thread);
    div.inject(email);
}


/******************************************
 Fetched from source/datepicker.js
******************************************/

const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
let datepicker_spawner = null
let calendarpicker_spawner = null
const DATE_UNITS = {
    w: 'week',
    d: 'day',
    M: 'month',
    y: 'year'
}

function fixupPicker(obj) {
    obj.addEventListener("focus", function(event) {
        $('html').on('hide.bs.dropdown', function(e) {
            return false;
        });
    });
    obj.addEventListener("blur", function(event) {
        $('html').unbind('hide.bs.dropdown')
    });
}
// makeSelect: Creates a <select> object with options
function makeSelect(options, id, selval) {
    let sel = document.createElement('select')
    sel.addEventListener("focus", function(event) {
        $('html').on('hide.bs.dropdown', function(e) {
            return false;
        });
    });
    sel.addEventListener("blur", function(event) {
        $('html').unbind('hide.bs.dropdown')
    });
    sel.setAttribute("name", id)
    sel.setAttribute("id", id)
    // For each options element, create it in the DOM
    for (let key in options) {
        let opt = document.createElement('option')
        // Hash or array?
        if (typeof key == "string") {
            opt.setAttribute("value", key)
            // Option is selected by default?
            if (key == selval) {
                opt.setAttribute("selected", "selected")
            }
        } else {
            // Option is selected by default?
            if (options[key] == selval) {
                opt.setAttribute("selected", "selected")
            }
        }
        opt.text = options[key]
        sel.appendChild(opt)
    }
    return sel
}

// splitDiv: Makes a split div with 2 elements,
// and puts div2 into the right column,
// and 'name' as text in the left one.
function splitDiv(id, name, div2) {
    let div = document.createElement('div')
    let subdiv = document.createElement('div')
    let radio = document.createElement('input')
    radio.setAttribute("type", "radio")
    radio.setAttribute("name", "datepicker_radio")
    radio.setAttribute("value", name)
    radio.setAttribute("id", "datepicker_radio_" + id)
    radio.setAttribute("onclick", "calcTimespan('" + id + "')")
    let label = document.createElement('label')
    label.innerHTML = "&nbsp; " + name + ": "
    label.setAttribute("for", "datepicker_radio_" + id)


    subdiv.appendChild(radio)
    subdiv.appendChild(label)


    subdiv.style.float = "left"
    div2.style.float = "left"

    subdiv.style.width = "120px"
    subdiv.style.height = "48px"
    div2.style.height = "48px"
    div2.style.width = "250px"

    div.appendChild(subdiv)
    div.appendChild(div2)
    return div
}

// calcTimespan: Calculates the value and representational text
// for the datepicker choice and puts it in the datepicker's
// spawning input/select element.
function calcTimespan(what) {
    let wat = ""
    let tval = ""

    // Less than N units ago?
    if (what == 'lt') {
        // Get unit and how many units
        let N = document.getElementById('datepicker_lti').value
        let unit = document.getElementById('datepicker_lts').value
        let unitt = DATE_UNITS[unit]
        if (parseInt(N) != 1) {
            unitt += "s"
        }

        // If this makes sense, construct a humanly readable and a computer version
        // of the timespan
        if (N.length > 0) {
            wat = "Less than " + N + " " + unitt + " ago"
            tval = "lte=" + N + unit
        }
    }

    // More than N units ago?
    if (what == 'mt') {
        // As above, get unit and no of units.
        let N = document.getElementById('datepicker_mti').value
        let unit = document.getElementById('datepicker_mts').value
        let unitt = DATE_UNITS[unit]
        if (parseInt(N) != 1) {
            unitt += "s"
        }

        // construct timespan val + description
        if (N.length > 0) {
            wat = "More than " + N + " " + unitt + " ago"
            tval = "gte=" + N + unit
        }
    }

    // Date range?
    if (what == 'cd') {
        // Get From and To values
        let f = document.getElementById('datepicker_cfrom').value
        let t = document.getElementById('datepicker_cto').value
        // construct timespan val + description if both from and to are valid
        if (f.length > 0 && t.length > 0) {
            wat = "From " + f + " to " + t
            tval = "dfr=" + f + "|dto=" + t
        }
    }

    // If we calc'ed a value and spawner exists, update its key/val
    if (datepicker_spawner && what && wat.length > 0) {
        document.getElementById('datepicker_radio_' + what).checked = true
        if (datepicker_spawner.options) {
            datepicker_spawner.options[0].value = tval
            datepicker_spawner.options[0].text = wat
        } else if (datepicker_spawner.value) {
            datepicker_spawner.value = wat
            datepicker_spawner.setAttribute("data", tval)
        }

    }
}

// datePicker: spawns a date picker with letious
// timespan options right next to the parent caller.
function datePicker(parent, seedPeriod) {
    datepicker_spawner = parent
    let div = document.getElementById('datepicker_popup')

    // If the datepicker object doesn't exist, spawn it
    if (!div) {
        div = document.createElement('div')
        div.setAttribute("id", "datepicker_popup")
        div.setAttribute("class", "datepicker")
    }

    // Reset the contents of the datepicker object
    div.innerHTML = ""
    div.style.display = "block"

    // Position the datepicker next to whatever called it
    let bb = parent.getBoundingClientRect()
    div.style.top = (bb.bottom + 8) + "px"
    div.style.left = (bb.left + 32) + "px"


    // -- Less than N $units ago
    let ltdiv = document.createElement('div')
    let lti = document.createElement('input')
    lti.setAttribute("id", "datepicker_lti")
    lti.style.width = "48px"
    lti.setAttribute("onkeyup", "calcTimespan('lt')")
    lti.setAttribute("onblur", "calcTimespan('lt')")
    ltdiv.appendChild(lti)

    let lts = makeSelect({
        'd': "Day(s)",
        'w': 'Week(s)',
        'M': "Month(s)",
        'y': "Year(s)"
    }, 'datepicker_lts', 'm')
    lts.setAttribute("onchange", "calcTimespan('lt')")
    ltdiv.appendChild(lts)
    ltdiv.appendChild(document.createTextNode(' ago'))

    div.appendChild(splitDiv('lt', 'Less than', ltdiv))


    // -- More than N $units ago
    let mtdiv = document.createElement('div')

    let mti = document.createElement('input')
    mti.style.width = "48px"
    mti.setAttribute("id", "datepicker_mti")
    mti.setAttribute("onkeyup", "calcTimespan('mt')")
    mti.setAttribute("onblur", "calcTimespan('mt')")
    mtdiv.appendChild(mti)


    let mts = makeSelect({
        'd': "Day(s)",
        'w': 'Week(s)',
        'M': "Month(s)",
        'y': "Year(s)"
    }, 'datepicker_mts', 'm')
    mtdiv.appendChild(mts)
    mts.setAttribute("onchange", "calcTimespan('mt')")
    mtdiv.appendChild(document.createTextNode(' ago'))
    div.appendChild(splitDiv('mt', 'More than', mtdiv))



    // -- Calendar timespan
    // This is just two text fields, the calendarPicker sub-plugin populates them
    let cdiv = document.createElement('div')

    let cfrom = document.createElement('input')
    cfrom.style.width = "90px"
    cfrom.setAttribute("id", "datepicker_cfrom")
    cfrom.setAttribute("onfocus", "showCalendarPicker(this)")
    cfrom.setAttribute("onchange", "calcTimespan('cd')")
    cdiv.appendChild(document.createTextNode('From: '))
    cdiv.appendChild(cfrom)

    let cto = document.createElement('input')
    cto.style.width = "90px"
    cto.setAttribute("id", "datepicker_cto")
    cto.setAttribute("onfocus", "showCalendarPicker(this)")
    cto.setAttribute("onchange", "calcTimespan('cd')")
    cdiv.appendChild(document.createTextNode('To: '))
    cdiv.appendChild(cto)

    div.appendChild(splitDiv('cd', 'Date range', cdiv))



    // -- Magic button that sends the timespan back to the caller
    let okay = document.createElement('input')
    okay.setAttribute("type", "button")
    okay.setAttribute("value", "Okay")
    okay.setAttribute("onclick", "setDatepickerDate()")
    div.appendChild(okay)
    parent.parentNode.appendChild(div)
    document.body.setAttribute("onclick", "")
    window.setTimeout(function() {
        document.body.setAttribute("onclick", "blurDatePicker(event)")
    }, 200)
    lti.focus()

    // This is for recalcing the set options if spawned from a
    // select/input box with an existing value derived from an
    // earlier call to datePicker
    let ptype = ""
    let pvalue = parent.hasAttribute("data") ? parent.getAttribute("data") : parent.value
    if (pvalue.search(/=|-/) != -1) {

        // Less than N units ago?
        if (pvalue.match(/lte/)) {
            let m = pvalue.match(/lte=(\d+)([dMyw])/)
            ptype = 'lt'
            if (m) {
                document.getElementById('datepicker_lti').value = m[1]
                let sel = document.getElementById('datepicker_lts')
                for (let i in sel.options) {
                    if (parseInt(i) >= 0) {
                        if (sel.options[i].value == m[2]) {
                            sel.options[i].selected = "selected"
                        } else {
                            sel.options[i].selected = null
                        }
                    }
                }
            }

        }

        // More than N units ago?
        if (pvalue.match(/gte/)) {
            ptype = 'mt'
            let m = pvalue.match(/gte=(\d+)([dMyw])/)
            if (m) {
                document.getElementById('datepicker_mti').value = m[1]
                let sel = document.getElementById('datepicker_mts')
                // Go through the unit values, select the one we use
                for (let i in sel.options) {
                    if (parseInt(i) >= 0) {
                        if (sel.options[i].value == m[2]) {
                            sel.options[i].selected = "selected"
                        } else {
                            sel.options[i].selected = null
                        }
                    }
                }
            }
        }

        // Date range?
        if (pvalue.match(/dfr/)) {
            ptype = 'cd'
            // Make sure we have both a dfr and a dto here, catch them
            let mf = pvalue.match(/dfr=(\d+-\d+-\d+)/)
            let mt = pvalue.match(/dto=(\d+-\d+-\d+)/)
            if (mf && mt) {
                // easy peasy, just set two text fields!
                document.getElementById('datepicker_cfrom').value = mf[1]
                document.getElementById('datepicker_cto').value = mt[1]
            }
        }
        // Month??
        if (pvalue.match(/(\d{4})-(\d+)/)) {
            ptype = 'cd'
            // Make sure we have both a dfr and a dto here, catch them
            let m = pvalue.match(/(\d{4})-(\d+)/)
            if (m.length == 3) {
                // easy peasy, just set two text fields!
                let dfrom = new Date(parseInt(m[1]), parseInt(m[2]) - 1, 1, 0, 0, 0)
                let dto = new Date(parseInt(m[1]), parseInt(m[2]), 0, 23, 59, 59)
                document.getElementById('datepicker_cfrom').value = m[0] + "-" + dfrom.getDate()
                document.getElementById('datepicker_cto').value = m[0] + "-" + dto.getDate()
            }
        }
        calcTimespan(ptype)
    }
}


function datePickerValue(seedPeriod) {
    // This is for recalcing the set options if spawned from a
    // select/input box with an existing value derived from an
    // earlier call to datePicker
    let rv = seedPeriod
    if (seedPeriod && seedPeriod.search && seedPeriod.search(/=|-/) != -1) {

        // Less than N units ago?
        if (seedPeriod.match(/lte/)) {
            let m = seedPeriod.match(/lte=(\d+)([dMyw])/)
            let unitt = DATE_UNITS[m[2]]
            if (parseInt(m[1]) != 1) {
                unitt += "s"
            }
            rv = "Less than " + m[1] + " " + unitt + " ago"
        }

        // More than N units ago?
        if (seedPeriod.match(/gte/)) {
            let m = seedPeriod.match(/gte=(\d+)([dMyw])/)
            let unitt = DATE_UNITS[m[2]]
            if (parseInt(m[1]) != 1) {
                unitt += "s"
            }
            rv = "More than " + m[1] + " " + unitt + " ago"
        }

        // Date range?
        if (seedPeriod.match(/dfr/)) {
            let mf = seedPeriod.match(/dfr=(\d+-\d+-\d+)/)
            let mt = seedPeriod.match(/dto=(\d+-\d+-\d+)/)
            if (mf && mt) {
                rv = "From " + mf[1] + " to " + mt[1]
            }
        }

        // Month??
        if (seedPeriod.match(/^(\d+)-(\d+)$/)) {
            let mr = seedPeriod.match(/(\d+)-(\d+)/)
            if (mr) {
                let dfrom = new Date(parseInt(mr[1]), parseInt(mr[2]) - 1, 1, 0, 0, 0)
                rv = MONTHS[dfrom.getMonth()] + ', ' + mr[1]
            }
        }

    }
    return rv
}

function datePickerDouble(seedPeriod) {
    // This basically takes a date-arg and doubles it backwards
    // so >=3M becomes =>6M etc. Also returns the cutoff for
    // the original date and the span in days of the original
    let dbl = seedPeriod
    let tspan = 1
    let dfrom = new Date()
    let dto = new Date()

    // datepicker range?
    if (seedPeriod && seedPeriod.search && seedPeriod.search(/=/) != -1) {

        // Less than N units ago?
        if (seedPeriod.match(/lte/)) {
            let m = seedPeriod.match(/lte=(\d+)([dMyw])/)
            dbl = "lte=" + (parseInt(m[1]) * 2) + m[2]

            // N months ago
            if (m[2] == "M") {
                dfrom.setMonth(dfrom.getMonth() - parseInt(m[1]), dfrom.getDate())
            }

            // N days ago
            if (m[2] == "d") {
                dfrom.setDate(dfrom.getDate() - parseInt(m[1]))
            }

            // N years ago
            if (m[2] == "y") {
                dfrom.setYear(dfrom.getFullYear() - parseInt(m[1]))
            }

            // N weeks ago
            if (m[2] == "w") {
                dfrom.setDate(dfrom.getDate() - (parseInt(m[1]) * 7))
            }

            // Calc total duration in days for this time span
            tspan = parseInt((dto.getTime() - dfrom.getTime() + 5000) / (1000 * 86400))
        }

        // More than N units ago?
        if (seedPeriod.match(/gte/)) {
            let m = seedPeriod.match(/gte=(\d+)([dMyw])/)
            dbl = "gte=" + (parseInt(m[1]) * 2) + m[2]
            // Can't really figure out a timespan for this, so...null!
            // This also sort of invalidates use on the trend page, but meh..
            tspan = null
            dfrom = null

            // Months
            if (m[2] == "M") {
                dto.setMonth(dto.getMonth() - parseInt(m[1]), dto.getDate())
            }

            // Days
            if (m[2] == "d") {
                dto.setDate(dto.getDate() - parseInt(m[1]))
            }

            // Years
            if (m[2] == "y") {
                dto.setYear(dto.getFullYear() - parseInt(m[1]))
            }

            // Weeks
            if (m[2] == "w") {
                dto.setDate(dto.getDate() - (parseInt(m[1]) * 7))
            }
        }

        // Date range?
        if (seedPeriod.match(/dfr/)) {
            // Find from and to
            let mf = seedPeriod.match(/dfr=(\d+)-(\d+)-(\d+)/)
            let mt = seedPeriod.match(/dto=(\d+)-(\d+)-(\d+)/)
            if (mf && mt) {
                // Starts at 00:00:00 on from date
                dfrom = new Date(parseInt(mf[1]), parseInt(mf[2]) - 1, parseInt(mf[3]), 0, 0, 0)

                // Ends at 23:59:59 on to date
                dto = new Date(parseInt(mt[1]), parseInt(mt[2]) - 1, parseInt(mt[3]), 23, 59, 59)

                // Get duration in days, add 5 seconds to we can floor the value and get an integer
                tspan = parseInt((dto.getTime() - dfrom.getTime() + 5000) / (1000 * 86400))

                // double the distance
                let dpast = new Date(dfrom)
                dpast.setDate(dpast.getDate() - tspan)
                dbl = seedPeriod.replace(/dfr=[^|]+/, "dfr=" + (dpast.getFullYear()) + '-' + (dpast.getMonth() + 1) + '-' + dpast.getDate())
            } else {
                tspan = 0
            }
        }
    }

    // just N days?
    else if (parseInt(seedPeriod).toString() == seedPeriod.toString()) {
        tspan = parseInt(seedPeriod)
        dfrom.setDate(dfrom.getDate() - tspan)
        dbl = "lte=" + (tspan * 2) + "d"
    }

    // Specific month?
    else if (seedPeriod.match(/^(\d+)-(\d+)$/)) {
        // just a made up thing...(month range)
        let mr = seedPeriod.match(/(\d+)-(\d+)/)
        if (mr) {
            // Same as before, start at 00:00:00
            dfrom = new Date(parseInt(mr[1]), parseInt(mr[2]) - 1, 1, 0, 0, 0)
            // end at 23:59:59
            dto = new Date(parseInt(mr[1]), parseInt(mr[2]), 0, 23, 59, 59)

            // B-A, add 5 seconds so we can floor the no. of days into an integer neatly
            tspan = parseInt((dto.getTime() - dfrom.getTime() + 5000) / (1000 * 86400))

            // Double timespan
            let dpast = new Date(dfrom)
            dpast.setDate(dpast.getDate() - tspan)
            dbl = "dfr=" + (dpast.getFullYear()) + '-' + (dpast.getMonth() + 1) + '-' + dpast.getDate() + "|dto=" + (dto.getFullYear()) + '-' + (dto.getMonth() + 1) + '-' + dto.getDate()
        } else {
            tspan = 0
        }
    }

    return [dbl, dfrom, dto, tspan]
}

// set date in caller and hide datepicker again.
function setDatepickerDate() {
    calcTimespan()
    blurDatePicker()
}

// findParent: traverse DOM and see if we can find a parent to 'el'
// called 'name'. This is used for figuring out whether 'el' has
// lost focus or not.
function findParent(el, name) {
    if (el.getAttribute && el.getAttribute("id") == name) {
        return true
    }
    if (el.parentNode && el.parentNode.getAttribute) {
        if (el.parentNode.getAttribute("id") != name) {
            return findParent(el.parentNode, name)
        } else {
            return true
        }
    } else {
        return false;
    }
}

// function for hiding the date picker
function blurDatePicker(evt) {
    let es = evt ? (evt.target || evt.srcElement) : null;
    if ((!es || !es.parentNode || (!findParent(es, "datepicker_popup") && !findParent(es, "calendarpicker_popup"))) && !(es ? es : "null").toString().match(/javascript:void/)) {
        document.getElementById('datepicker_popup').style.display = "none"
        $('html').trigger('hide.bs.dropdown')
    }
}

// draws the actual calendar inside a calendarPicker object
function drawCalendarPicker(obj, date) {


    obj.focus()

    // Default to NOW for calendar.
    let now = new Date()

    // if called with an existing date (YYYY-MM-DD),
    // convert it to a JS date object and use that for
    // rendering the calendar
    if (date) {
        let ar = date.split(/-/)
        now = new Date(ar[0], parseInt(ar[1]) - 1, ar[2])
    }
    let mat = now

    // Go to first day of the month
    mat.setDate(1)

    obj.innerHTML = "<h3>" + MONTHS[mat.getMonth()] + ", " + mat.getFullYear() + ":</h3>"
    let tm = mat.getMonth()

    // -- Nav buttons --

    // back-a-year button
    let a = document.createElement('a')
    fixupPicker(a)
    a.setAttribute("onclick", "drawCalendarPicker(this.parentNode, '" + (mat.getFullYear() - 1) + '-' + (mat.getMonth() + 1) + '-' + mat.getDate() + "');")
    a.setAttribute("href", "javascript:void(0);")
    a.setAttribute("class", "glyphicon glyphicon-fast-backward");
    obj.appendChild(a)

    // back-a-month button
    a = document.createElement('a')
    fixupPicker(a)
    a.setAttribute("onclick", "drawCalendarPicker(this.parentNode, '" + mat.getFullYear() + '-' + (mat.getMonth()) + '-' + mat.getDate() + "');")
    a.setAttribute("href", "javascript:void(0);")
    a.setAttribute("class", "glyphicon glyphicon-step-backward");
    obj.appendChild(a)

    // forward-a-month button
    a = document.createElement('a')
    fixupPicker(a)
    a.setAttribute("onclick", "drawCalendarPicker(this.parentNode, '" + mat.getFullYear() + '-' + (mat.getMonth() + 2) + '-' + mat.getDate() + "');")
    a.setAttribute("href", "javascript:void(0);")
    a.setAttribute("class", "glyphicon glyphicon-step-forward");
    obj.appendChild(a)

    // forward-a-year button
    a = document.createElement('a')
    fixupPicker(a)
    a.setAttribute("onclick", "drawCalendarPicker(this.parentNode, '" + (mat.getFullYear() + 1) + '-' + (mat.getMonth() + 1) + '-' + mat.getDate() + "');")
    a.setAttribute("href", "javascript:void(0);")
    a.setAttribute("class", "glyphicon glyphicon-fast-forward");
    obj.appendChild(a)
    obj.appendChild(document.createElement('br'))


    // Table containing the dates of the selected month
    let table = document.createElement('table')

    table.setAttribute("border", "1")
    table.style.margin = "0 auto"

    // Add header day names
    let tr = document.createElement('tr');
    for (let m = 0; m < 7; m++) {
        let td = document.createElement('th')
        td.innerHTML = DAYS_SHORTENED[m]
        tr.appendChild(td)
    }
    table.appendChild(tr)

    // Until we hit the first day in a month, add blank days
    tr = document.createElement('tr');
    let weekday = mat.getDay()
    if (weekday == 0) {
        weekday = 7
    }
    weekday--;
    for (let i = 0; i < weekday; i++) {
        let td = document.createElement('td')
        tr.appendChild(td)
    }

    // While still in this month, add day then increment date by 1 day.
    while (mat.getMonth() == tm) {
        weekday = mat.getDay()
        if (weekday == 0) {
            weekday = 7
        }
        weekday--;
        if (weekday == 0) {
            table.appendChild(tr)
            tr = document.createElement('tr');
        }
        let td = document.createElement('td')
        // onclick for setting the calendarPicker's parent to this val.
        td.setAttribute("onclick", "setCalendarDate('" + mat.getFullYear() + '-' + (mat.getMonth() + 1) + '-' + mat.getDate() + "');")
        td.innerHTML = mat.getDate()
        mat.setDate(mat.getDate() + 1)
        tr.appendChild(td)
    }

    table.appendChild(tr)
    obj.appendChild(table)
}

// callback for datePicker; sets the cd value to what date was picked
function setCalendarDate(what) {
    $('html').on('hide.bs.dropdown', function(e) {
        return false;
    });
    setTimeout(function() {
        $('html').unbind('hide.bs.dropdown');
    }, 250);


    calendarpicker_spawner.value = what
    let div = document.getElementById('calendarpicker_popup')
    div.parentNode.focus()
    div.style.display = "none"
    calcTimespan('cd')
}

// caller for when someone clicks on a calendarPicker enabled field
function showCalendarPicker(parent, seedDate) {
    calendarpicker_spawner = parent

    // If supplied with a YYYY-MM-DD date, use this to seed the calendar
    if (!seedDate) {
        let m = parent.value.match(/(\d+-\d+(-\d+)?)/)
        if (m) {
            seedDate = m[1]
        }
    }

    // Show or create the calendar object
    let div = document.getElementById('calendarpicker_popup')
    if (!div) {
        div = document.createElement('div')
        div.setAttribute("id", "calendarpicker_popup")
        div.setAttribute("class", "calendarpicker")
        document.getElementById('datepicker_popup').appendChild(div)
        div.innerHTML = "Calendar goes here..."
    }
    div.style.display = "block"
    let bb = parent.getBoundingClientRect()

    // Align with the calling object, slightly below
    div.style.top = (bb.bottom + 8) + "px"
    div.style.left = (bb.right - 32) + "px"

    drawCalendarPicker(div, seedDate)
}


/******************************************
 Fetched from source/init.js
******************************************/

console.log("/******* Apache Pony Mail (Foal v/%s) Initializing ********/".format(PONYMAIL_VERSION))

// Adjust titles:
document.title = prefs.title;
for (let title of document.getElementsByClassName("title")) {
    title.innerText = prefs.title;
}

console.log("Initializing escrow checks");
window.setInterval(escrow_check, 250);

console.log("Initializing key command logger");
window.addEventListener('keyup', keyCommands);

window.addEventListener('load', function() {
    let powered_by = "Powered by Apache Pony Mail (Foal v/%s ~%s)".format(PONYMAIL_VERSION, PONYMAIL_REVISION);
    let pb = document.getElementById("powered_by");
    if (pb) {
        pb.innerHTML = powered_by
    }
    document.body.appendChild(new HTML('footer', {
        class: 'footer hidden-xs'
    }, [
        new HTML('div', {
            class: 'container'
        }, [
            new HTML('p', {
                class: 'muted'
            }, powered_by)
        ])
    ]));
});
console.log("initializing pop state checker");
window.onpopstate = function(event) {
    console.log("Popping state");
    return parseURL({
        cached: true
    });
};


/******************************************
 Fetched from source/key-commands.js
******************************************/

// Generic modal function
function modal(title, msg, type, isHTML) {
    let modalId = document.getElementById('modal');
    let text = document.getElementById('modal_text');
    if (modalId == undefined) {
        text = new HTML('p', {
            id: 'modal_text'
        }, "");
        modalId = new HTML('div', {
            id: 'modal'
        }, [
            new HTML('div', {
                id: 'modal_content'
            }, [
                new HTML('span', {
                    id: 'modal_close',
                    onclick: 'document.getElementById("modal").style.display = "none";'
                }, 'X'),
                new HTML('h2', {
                    id: 'modal_title'
                }, title),
                new HTML('div', {}, text)
            ])
        ]);
        document.body.appendChild(modalId);

    }
    if (type) {
        modalId.setAttribute("class", "modal_" + type);
    } else {
        modalId.setAttribute("class", undefined);
    }
    modalId.style.display = 'block';
    document.getElementById('modal_title').innerText = title;
    // If we trust HTML, use it. Otherwise only show as textNode.
    if (isHTML) {
        text.innerHTML = msg;
    } else {
        msg = msg.replace(/<.*?>/g, ""); // strip HTML tags
        text.innerText = msg;
    }
}

// Helper for determining if an email is open or not...
function anyOpen() {
    let open = (G_current_email_idx !== undefined) ? true : false;
    console.log("Emails open? " + open);
    return open;
}

// Helper function for hiding windows and open tabs
// Hide previous action on first escape, hide everything on second escape
function hideWindows(force_all) {

    // First, check if we want to hide a modal
    let modalId = document.getElementById('modal');
    if (modalId && modalId.style.display == 'block') {
        modalId.style.display = 'none';
        if (force_all !== true) return;
    }

    // RThen, check if we want to hide a composer modal
    let cmodal = document.getElementById('composer_modal');
    if (cmodal && cmodal.style.display == 'block') {
        cmodal.style.display = 'none';
        if (force_all !== true) return;
    }

    // Check Advanced Search
    let as = document.getElementById('advanced_search');
    if (as && as.style.display == 'block') {
        as.style.display = 'none';
        if (force_all !== true) return;
    }

    // Check for individually opened email
    if (G_current_email_idx !== undefined) {
        console.log("Hiding placeholder at index %u".format(G_current_email_idx));
        let placeholder = document.getElementById('email_%u'.format(G_current_email_idx));
        if (placeholder) {
            placeholder.style.display = 'none';
        }
        G_current_email_idx = undefined; // undef this even if we can't find the email
        if (force_all !== true) return;
    }

    // if viewing a single thread, disregard the collapses below - the won't make sense!
    if (location.href.match(/thread(?:\.html)?/)) return;

    // Finally, check for other opened emails, close 'em all
    let placeholders = document.getElementsByClassName('email_placeholder');
    for (let placeholder of placeholders) {
        if (placeholder.style.display == 'block') {
            console.log("Hiding placeholder %s".format(placeholder.getAttribute('id')));
            placeholder.style.display = 'none';
            // Reset scroll cache
            try {
                window.scrollTo(0, 0);
            } catch (e) {}
        }
    }

    placeholders = document.getElementsByClassName('email_placeholder_chatty');
    for (let placeholder of placeholders) {
        if (placeholder.style.display == 'block') {
            console.log("Hiding placeholder %s".format(placeholder.getAttribute('id')));
            placeholder.style.display = 'none';
            // Reset scroll cache
            try {
                window.scrollTo(0, 0);
            } catch (e) {}
        }
    }

}

// Show keyboard commands
function showHelp() {
    modal("Keyboard shortcuts:", "<pre><kbd>H</kbd>: Show this help window.\n<kbd>C</kbd>: Compose a new email to this list.\n<kbd>R</kbd>: Reply to the currently active thread.\n<kbd>S</kbd>: Go to the search bar.\n<kbd>Escape</kbd>: Hide modals or collapse threads.\n<kbd>RightArrow</kbd>: Go to next bunch of emails in list view.\n<kbd>LeftArrow</kbd>: Go to previous bunch of emails in list view.</pre>", "help", true);
}

// Function for capturing and evaluating key strokes
// If it matches a known shortcut, execute that then..
function keyCommands(e) {
    if (!e.ctrlKey) {
        // Get calling element and its type
        let target = e.target || e.srcElement;
        let type = target.tagName;
        // We won't jump out of an input field!
        if (['INPUT', 'TEXTAREA', 'SELECT'].has(type)) {
            return;
        }
        switch (e.key) {
            case 's':
                document.getElementById('q').focus();
                return;
            case 'h':
                showHelp();
                return;
            case 'c':
                compose_email(null, `${G_current_list}@${G_current_domain}`);
                return;
            case 'r':
                console.log(G_current_open_email);
                if (G_current_open_email && G_full_emails[G_current_open_email]) {
                    compose_email(G_current_open_email);
                }
                return;
            case 'Escape':
                hideWindows();
                return;
            case 'ArrowRight': // quick-next
                if (G_current_json) { // IF list view...
                    let blobs = G_current_json.emails;
                    if (G_current_listmode == 'threaded') blobs = G_current_json.thread_struct;
                    let no_emails = blobs.length;
                    if (G_current_email_idx == undefined && G_current_json && (G_current_index_pos + G_current_per_page) < no_emails) {
                        listview_header({
                            pos: G_current_index_pos + G_current_per_page
                        }, G_current_json);
                    }
                }
                return;
            case 'ArrowLeft': // quick previous
                if (G_current_json) { // IF list view...
                    if (G_current_email_idx == undefined && G_current_json && (G_current_index_pos - G_current_per_page) >= 0) {
                        listview_header({
                            pos: G_current_index_pos - G_current_per_page
                        }, G_current_json);
                    }
                }
                return;
        }

    }
}

// swipe left/right for next/previous page on mobile
function ponymail_swipe(event) {
    // Only accept "big" swipes
    let len = Math.abs(event.detail.swipestart.coords[0] - event.detail.swipestop.coords[0]);
    let direction = event.detail.swipestart.coords[0] > event.detail.swipestop.coords[0] ? 'left' : 'right';
    console.log("swipe %s of %u pixels detected".format(direction, len));
    if (len < 20) return false;
    if (direction == 'right') {
        if (G_current_json) { // IF list view...
            if (G_current_email_idx == undefined && G_current_json && (G_current_index_pos - G_current_per_page) >= 0) {
                listview_header({
                    pos: G_current_index_pos - G_current_per_page
                }, G_current_json);
            }
        }
    } else if (direction == 'left') {
        if (G_current_json) { // IF list view...
            let blobs = G_current_json.emails;
            if (G_current_listmode == 'threaded') blobs = G_current_json.thread_struct;
            let no_emails = blobs.length;
            if (G_current_email_idx == undefined && G_current_json && (G_current_index_pos + G_current_per_page) < no_emails) {
                listview_header({
                    pos: G_current_index_pos + G_current_per_page
                }, G_current_json);
            }
        }
    }
    return false;
}


/******************************************
 Fetched from source/list-index.js
******************************************/

let list_json = {}

function list_index(state, json) {
    if (json) {
        list_json = json;
    }
    let letter = 'a';
    let lists = document.getElementById('list_picker_ul');
    if (state && state.letter) {
        letter = state.letter;
        for (let xtab of lists.childNodes) {
            if (xtab.innerText == state.letter) {
                xtab.setAttribute("class", 'active');
            } else if (xtab.setAttribute) {
                xtab.setAttribute("class", "");
            }
        }
    } else {
        let letters = 'abcdefghijklmnopqrstuvwxyz#';
        for (let char of letters) {
            let xletter = char.toUpperCase();
            let li = new HTML('li', {
                onclick: 'list_index({letter: "%s"});'.format(xletter),
                class: (xletter == 'A') ? 'active' : null
            }, xletter);
            lists.inject(li);
        }
    }

    let list_ul = document.getElementById('list_index_wide_lists');
    list_ul.textContent = "";
    let domains = Object.keys(list_json.lists);
    domains.sort();
    for (let domain_name of domains) {
        if (is_letter(domain_name, letter)) {
            console.log(domain_name);
            let li = new HTML('li', {});
            let a = new HTML('a', {
                href: 'list.html?%s'.format(domain_name)
            }, domain_name);
            li.inject(a);
            list_ul.inject(li);
        }
    }
}


function is_letter(domain, letter) {
    if (letter == '#' && domain.match(/^([^a-zA-Z]+)/)) return true
    else return domain.toLowerCase().startsWith(letter.toLowerCase());
}

function list_index_onepage(state, json) {
    let obj = document.getElementById('list_index_child');
    obj.style.padding = '8px';
    let domains = Object.keys(json.lists);
    domains.sort();
    let letter = '';
    for (let domain of domains) {
        let l = domain[0];
        if (l != letter) {
            letter = l;
            let lhtml = new HTML('h2', {}, l.toUpperCase());
            obj.inject(lhtml);
        }
        let a = new HTML('a', {
            href: 'list.html?%s'.format(domain)
        }, domain);
        obj.inject(['- ', a]);
        obj.inject(new HTML('br'));
    }
    if (domains.length > pm_config.LOTS_OF_LISTS) {
        list_index(state, json);
    } else {
        let wide_obj = document.getElementById('list_index_child_wide');
        let new_obj = obj.cloneNode(true);
        new_obj.setAttribute("id", "list_index_child_wide");
        wide_obj.replaceWith(new_obj);
        console.log(new_obj);
    }
}

// onload function for index.html
function prime_list_index() {
    GET('%sapi/preferences.lua'.format(G_apiURL), list_index_onepage, {});
}

/******************************************
 Fetched from source/listview-flat.js
******************************************/

let compact_email_height = 24;  // a normal email element is 24 pixels high
let preview_email_height = 40;

let narrow_width = 600;  // <= 600 pixels and we're in narrow view

function calc_per_page() {
    // Figure out how many emails per page
    let body = document.body;
    let html = document.documentElement;
    let height = Math.max(body.scrollHeight,
        html.clientHeight, html.scrollHeight);
    let width = Math.max(body.scrollWidth,
        html.clientWidth, html.scrollWidth);
    let email_h = G_current_listmode_compact ? compact_email_height : preview_email_height;
    if (width < narrow_width) {
        console.log("Using narrow view, reducing emails per page...");
        email_h = G_current_listmode_compact ? compact_email_height * 1.5 : preview_email_height * 2;
    }
    height -= document.getElementById("emails").getBoundingClientRect().y + 16; // top area height plus footer
    email_h += 2;
    let per_page = Math.max(5, Math.floor(height / email_h));
    per_page -= per_page % 5;
    console.log("Viewport is %ux%u. We can show %u emails per page".format(width, height, per_page));
    return per_page;
}

function listview_flat(json, start) {
    let list = document.getElementById('emails');
    list.innerHTML = "";

    let s = start || 0;
    let n;
    if (json.emails && json.emails.length) {
        for (n = s; n < (s + G_current_per_page); n++) {
            let z = json.emails.length - n - 1; // reverse order by default
            if (json.emails[z]) {
                let item = listview_flat_element(json.emails[z], z);
                list.inject(item);

                // Hidden placeholder for expanding email(s)
                let placeholder = new HTML('div', {
                    class: G_chatty_layout ? 'email_placeholder_chatty' : 'email_placeholder',
                    id: 'email_%u'.format(z)
                });
                list.inject(placeholder);
            }
        }
    } else {
        list.inject(txt("No emails found..."));
    }
}

function listview_flat_element(eml, idx) {

    let link_wrapper = new HTML('a', {
        href: 'thread/%s'.format(eml.id),
        onclick: 'return(expand_email_threaded(%u, true));'.format(idx)
    });

    let element = new HTML('div', {
        class: G_current_listmode_compact ? "listview_email_compact" : "listview_email_flat"
    }, " ");

    // Add gravatar
    let gravatar = new HTML('img', {
        class: "gravatar",
        src: GRAVATAR_URL.format(eml.gravatar)
    });
    element.inject(gravatar);


    // Add author
    let authorName = eml.from.replace(/\s*<.+>/, "").replace(/"/g, '');
    let authorEmail = eml.from.match(/\s*<(.+@.+)>\s*/);
    if (authorName.length == 0) authorName = authorEmail ? authorEmail[1] : "(No author?)";
    let author = new HTML('span', {
        class: "listview_email_author"
    }, authorName);
    element.inject(author);

    // reasons to show the list name
    let showList = G_current_domain == 'inbox' || G_current_list == '*' || G_current_domain == '*';

    // If space and needed, inject ML name
    if (!G_current_listmode_compact && showList) {
        author.style.lineHeight = '16px';
        author.inject(new HTML('br'));
        author.inject(new HTML('span', {
            class: "label label-primary",
            style: "font-style: italic; font-size: 1rem;"
        }, eml.list_raw.replace(/[<>]/g, '').replace('.', '@', 1)));
    }

    // Combined space for subject + body teaser
    let as = new HTML('div', {
        class: 'listview_email_as'
    });

    let suba = new HTML('a', {}, eml.subject === '' ? '(No subject)' : eml.subject);
    if (G_current_listmode_compact && showList) {
        let kbd = new HTML('kbd', {
            class: 'listview_kbd'
        }, eml.list_raw.replace(/[<>]/g, '').replace('.', '@', 1))
        suba = [kbd, suba];
    }
    let subject = new HTML('div', {
        class: 'listview_email_subject email_unread'
    }, suba);
    as.inject(subject);
    if (!G_current_listmode_compact) { // No body in compact mode
        let body = new HTML('div', {
            class: 'listview_email_body'
        }, eml.body);
        as.inject(body);
    }

    element.inject(as);

    // Labels
    let labels = new HTML('div', {
        class: 'listview_email_labels'
    });

    let date = new Date(eml.epoch * 1000.0);
    let now = new Date();

    let dl = new HTML('span', {
        class: 'label label-default'
    }, date.ISOBare());
    if (now - date < 86400000) {
        dl.setAttribute("class", "label label-primary");
    }
    labels.inject(dl);

    element.inject(labels);
    link_wrapper.inject(element);

    return link_wrapper;
}

/******************************************
 Fetched from source/listview-header.js
******************************************/

let prev_listview_json = {};
let prev_listview_state = {};

function listview_header(state, json) {
    if (isEmpty(json)) { // Bad search request?
        modal("Bad search request", "Your request could not be parsed.", "warning");
        return;
    }
    let list_title = json.list;
    prev_listview_json = json;
    prev_listview_state = state;
    if (G_current_list == 'virtual' && G_current_domain == 'inbox') {
        list_title = "Virtual inbox, past 30 days";
    }
    let blobs = json.emails ? json.emails : [];
    if (G_current_listmode == 'threaded' || G_current_listmode == 'treeview') blobs = json.thread_struct;

    if (G_current_year && G_current_month) {
        list_title += ", %s %u".format(MONTHS[G_current_month - 1], G_current_year);
    } else {
        list_title += ", past month";
    }

    if (json.searchParams && (
            json.searchParams.q &&
            json.searchParams.q.length ||
            (json.searchParams.d || "").match(/=/))
    ){
        list_title = "Custom search";
    }
    document.title = list_title + " - " + prefs.title;
    document.getElementById('listview_title').innerText = list_title + ":";
    let download = new HTML('button', {
        title: 'Download as mbox archive',
        download: 'true'
    }, new HTML('span', {
        class: 'glyphicon glyphicon-save'
    }, " "));
    document.getElementById('listview_title').inject(download);
    download.addEventListener('click', () => {
        let sep = '?';
        let dl_url = G_apiURL + 'api/mbox.lua';
        for (let key in json.searchParams || {}) {
            dl_url += sep + key + "=" + encodeURIComponent(json.searchParams[key]);
            sep = '&';
        }
        location.href = dl_url;
    });

    let chevrons = document.getElementById('listview_chevrons');
    G_current_per_page = calc_per_page();
    G_current_index_pos = state.pos || 0;
    let first = 1;
    if (state && state.pos) {
        first = 1 + state.pos;
    }
    if (!blobs || blobs.length == 0) {
        chevrons.innerHTML = "No topics to show";
        blobs = [];
    } else {
        chevrons.innerHTML = "Showing <b>%u through %u</b> of <b>%u</b> topics&nbsp;".format(first, Math.min(first + G_current_per_page - 1, blobs.length), blobs.length || 0);
    }

    let pprev = Math.max(0, first - G_current_per_page - 1);
    let cback = new HTML('button', {
        onclick: 'listview_header({pos: %u}, G_current_json);'.format(pprev),
        disabled: (first == 1) ? 'true' : null
    }, new HTML('span', {
        class: 'glyphicon glyphicon-chevron-left'
    }, " "));
    chevrons.inject(cback);

    let pnext = first + G_current_per_page - 1;
    let cforward = new HTML('button', {
        onclick: 'listview_header({pos: %u}, G_current_json);'.format(pnext),
        disabled: (first + G_current_per_page - 1 >= blobs.length) ? 'true' : null
    }, new HTML('span', {
        class: 'glyphicon glyphicon-chevron-right'
    }, " "));
    chevrons.inject(cforward);

    let crefresh = new HTML('button', {
        onclick: 'parseURL({noprefs: true});',
        title: 'Refresh results',
        style: {
            marginLeft: '8px'
        }
    }, new HTML('span', {
        class: 'glyphicon glyphicon-refresh'
    }, " "));
    chevrons.inject(crefresh);
    console.log(G_current_listmode)
    if (state && state.pos != undefined) {
        if (G_current_listmode == 'threaded') {
            listview_threaded(json, state.pos);
        } else if (G_current_listmode == 'flat') {
            listview_flat(json, state.pos);
        } else {
            listview_treeview(json, state.pos);
        }
    }

}

function listview_list_lists(state, json) {
    let lists = document.getElementById('list_picker_ul');
    let searching = (state && state.search === true) ? true : false;
    if (state && state.to) {
        let tab;
        let tabs = lists.childNodes;
        for (let xtab of tabs) {
            if ((state.to == 'search' && xtab.getAttribute('id') == 'tab_search') || (xtab.innerText == state.to || xtab.getAttribute('data-list') == state.to)) {
                tab = xtab;
                tab.setAttribute("class", state.to == 'search' ? 'search' : 'active');
            } else if (xtab.getAttribute("class") != 'list_all_narrow' && xtab.getAttribute("class") != 'others') {
                xtab.setAttribute("class", "");
            }

        }
        return;
    }
    if (!json) {
        json = G_ponymail_preferences;
    }
    if (lists) {
        lists.innerHTML = "";

        if (isHash(json.lists) && json.lists[G_current_domain]) {
            let lists_sorted = [];
            for (let list in json.lists[G_current_domain]) {
                lists_sorted.push([list, json.lists[G_current_domain][list]]);
            }
            lists_sorted.sort((a, b) => b[1] - a[1]);
            let alists = [];
            for (let list of lists_sorted) alists.push(list[0]);
            if (G_current_list != '*' && G_current_domain != '*') {
                alists.remove(G_current_list);
                alists.unshift(G_current_list);
            }
            let maxlists = (searching && 3 || 4);
            if (alists.length == maxlists + 1) maxlists++; // skip drop-down if only one additional list (#54)
            for (let i = 0; i < alists.length; i++) {
                if (i >= maxlists) break;
                let listname = alists[i];
                let listnametxt = listname;
                if (pm_config.long_tabs) {
                    listnametxt = '%s@%s'.format(listname, G_current_domain);
                }
                let li = new HTML('li', {
                    onclick: 'switch_list(this, "tab");',
                    class: (listname == G_current_list && !searching) ? 'active' : null
                }, listnametxt);
                li.setAttribute("data-list", '%s@%s'.format(listname, G_current_domain));
                lists.inject(li);
            }

            if (alists.length > maxlists) {
                let other_lists_sorted = [];
                for (let i = maxlists; i < alists.length; i++) {
                    other_lists_sorted.push(alists[i]);
                }
                other_lists_sorted.sort();
                let li = new HTML('li', {
                    class: 'others'
                });
                let otherlists = new HTML('select', {
                    class: 'listview_others',
                    onchange: 'switch_list(this.value);'
                });
                otherlists.inject(new HTML('option', {
                    disabled: 'disabled',
                    selected: 'selected'
                }, 'Other lists (%u):'.format(other_lists_sorted.length)));
                li.inject(otherlists);
                for (let listname of other_lists_sorted) {
                    let opt = new HTML('option', {
                        value: "%s@%s".format(listname, G_current_domain)
                    }, listname);
                    otherlists.inject(opt);
                }
                lists.inject(li);
            }
            // All lists, for narrow UI
            let all_lists_narrow = [];
            for (let alist of alists) {
                all_lists_narrow.push(alist);
            }
            all_lists_narrow.sort();
            let li = new HTML('li', {
                class: 'list_all_narrow'
            });
            let otherlists = new HTML('select', {
                class: 'listview_others',
                onchange: 'switch_list(this.value);'
            });
            otherlists.inject(new HTML('option', {
                disabled: 'disabled',
                selected: 'selected'
            }, "%s@%s".format(G_current_list, G_current_domain)));
            li.inject(otherlists);
            for (let listname of all_lists_narrow) {
                let opt = new HTML('option', {
                    value: "%s@%s".format(listname, G_current_domain)
                }, listname);
                otherlists.inject(opt);
            }
            lists.inject(li);
        }
    }
    if (searching) {
        let li = new HTML('li', {
            onclick: 'switch_list(this, "tab");',
            id: 'tab_search',
            class: 'search'
        }, "Search: %s".format(state.query));
        li.setAttribute("data-url", state.url);
        li.setAttribute("data-href", location.href);
        li.setAttribute("data-list", '%s@%s'.format(state.list, state.domain));
        lists.inject(li);
    }

    // Populate the project selector
    if (isHash(json.lists)) {
        let no_projects = 0;
        let select = document.getElementById('project_select');
        if (!select || G_select_primed) return;
        let opts = {}
        let doms = [];
        for (let domain in json.lists) {
            let option = new HTML('option', {
                value: domain
            }, domain);
            opts[domain] = option;
            doms.push(domain);
            no_projects++;
        }
        if (no_projects > 1 || G_current_domain == '*') {
            select.innerHTML = "";
            let title = new HTML('option', {
                disabled: 'disabled',
                selected: 'true',
                value: ''
            }, "Available projects (%u):".format(no_projects));
            select.inject(title);
            doms.sort();
            for (let dom of doms) {
                select.inject(opts[dom]);
            }
            select.style.display = "inline-block";
            G_select_primed = true; // mark it primed so we don't generate it again later
        }
    }
}


function switch_project(domain) {
    // TODO: improve this
    if (G_ponymail_preferences && G_ponymail_preferences.lists[domain]) {
        // Switch to the most populous, but not commits/cvs
        let lists_sorted = [];
        for (let list in G_ponymail_preferences.lists[domain]) {
            lists_sorted.push([list, G_ponymail_preferences.lists[domain][list]]);
        }
        lists_sorted.sort((a, b) => b[1] - a[1]);
        let lists = [];
        for (let list of lists_sorted) lists.push(list[0]);
        let listname = lists[0];
        let n = 1;
        if (lists.length > n) {
            while (pm_config.boring_lists.has(listname) && lists.length > n) {
                listname = lists[n];
                n++;
            }
            if (lists.has(pm_config.favorite_list)) {
                listname = pm_config.favorite_list;
            }
        }
        switch_list('%s@%s'.format(listname, domain));
    } else {
        switch_list('%s@%s'.format(pm_config.favorite_list, domain));
    }
}

function switch_list(list, from) {
    let listid = list;
    if (typeof list == 'object') {
        listid = list.getAttribute("data-list") || list.innerText;
        let dataURL = list.getAttribute('data-url');
        if (dataURL) {
            let bits = listid.split("@");
            G_current_list = bits[0];
            G_current_domain = bits[1];
            GET(dataURL, renderListView, {
                search: true,
                cached: true
            });
            let newhref = list.getAttribute('data-href');
            if (location.href !== newhref) {
                window.history.pushState({}, null, newhref);
            }
            listview_list_lists({
                to: 'search'
            });
            return;
        }
    }
    let bits = listid.split("@");
    G_current_list = bits[0];
    G_current_domain = bits[1];
    G_current_year = 0;
    G_current_month = 0;

    let newhref = "list.html?%s".format(listid);
    if (location.href !== newhref) {
        window.history.pushState({}, null, newhref);
    }

    console.log("Switching list to %s...".format(listid));
    listview_list_lists({
        to: from ? listid : undefined
    });
    post_prime({
        cached: true,
        from: from
    });
}

window.addEventListener('orientationchange', function() {
    window.setTimeout(function() {
        if (anyOpen() == false && location.href.match(/\/list(\.html)?/) && location.search.length) {
            listview_header(prev_listview_state, prev_listview_json);
        }
    }, 100);
}, false);


/******************************************
 Fetched from source/listview-threaded.js
******************************************/

function calc_email_width() {
    // Get email width; used for calculating reply nesting offsets
    let body = document.body;
    let html = document.documentElement;
    return Math.max(body.scrollWidth, body.offsetWidth,
        html.clientWidth, html.scrollWidth, html.offsetWidth);
}

function listview_threaded(json, start) {
    let list = document.getElementById('emails');
    list.innerHTML = "";

    let s = start || 0;
    if (json.thread_struct && json.thread_struct.length) {
        for (let n = s; n < (s + G_current_per_page); n++) {
            let z = json.thread_struct.length - n - 1; // reverse order by default
            if (json.thread_struct[z]) {
                let item = listview_threaded_element(json.thread_struct[z], z);
                list.inject(item);
                // Hidden placeholder for expanding email(s)
                let placeholder = new HTML('div', {
                    class: G_chatty_layout ? 'email_placeholder_chatty' : 'email_placeholder',
                    id: 'email_%u'.format(z)
                });
                list.inject(placeholder);
            }
        }
    } else {
        list.inject(txt("No emails found..."));
    }
}

function find_email(id) {
    if (!G_current_json.emails) return null;
    for (let email of G_current_json.emails) {
        if (email.id == id) return email;
    }
    return null;
}

function count_replies(thread) {
    let reps = 0;
    if (isArray(thread.children)) {
        for (let child of thread.children) {
            if (child.tid == thread.tid) reps--;
            reps++;
            reps += count_replies(child);
        }
    }
    return reps;
}

function count_people(thread, hash) {
    let ppl = hash || {};
    let eml = find_email(thread.tid);
    if (eml) ppl[eml.from] = true;
    if (isArray(thread.children)) {
        for (let child of thread.children) {
            count_people(child, ppl);
        }
    }
    let n = 0;
    for (let _ in ppl) n++;
    return n;
}


function last_email(thread) {
    let newest = thread.epoch;
    if (isArray(thread.children)) {
        for (let child of thread.children) {
            newest = Math.max(newest, last_email(child));
        }
    }
    return newest;
}



function listview_threaded_element(thread, idx) {
    let eml = find_email(thread.tid);
    if (!eml) {
        return;
    }

    let link_wrapper = new HTML('a', {
        href: 'thread/%s'.format(eml.id),
        onclick: 'return(expand_email_threaded(%u));'.format(idx)
    });

    let element = new HTML('div', {
        class: G_current_listmode_compact ? "listview_email_compact" : "listview_email_flat"
    }, " ");
    let date = new Date(eml.epoch * 1000.0);
    let now = new Date();

    // Add gravatar
    let gravatar = new HTML('img', {
        class: "gravatar",
        src: GRAVATAR_URL.format(eml.gravatar)
    });
    element.inject(gravatar);


    // Add author
    let authorName = eml.from.replace(/\s*<.+>/, "").replace(/"/g, '');
    let authorEmail = eml.from.match(/\s*<(.+@.+)>\s*/);
    if (authorName.length == 0) authorName = authorEmail ? authorEmail[1] : "(No author?)";
    let author = new HTML('span', {
        class: "listview_email_author"
    }, authorName);
    element.inject(author);

    // reasons to show the list name
    let showList = G_current_domain == 'inbox' || G_current_list == '*' || G_current_domain == '*';

    // If space and needed, inject ML name
    if (!G_current_listmode_compact && showList) {
        author.style.lineHeight = '16px';
        author.inject(new HTML('br'));
        author.inject(new HTML('span', {
            class: "label label-primary",
            style: "font-style: italic; font-size: 1rem;"
        }, eml.list_raw.replace(/[<>]/g, '').replace('.', '@', 1)));
    }



    // Combined space for subject + body teaser
    let as = new HTML('div', {
        class: 'listview_email_as'
    });

    let suba = new HTML('a', {}, eml.subject === '' ? '(No subject)' : eml.subject);
    if (G_current_listmode_compact && showList) {
        let kbd = new HTML('kbd', {
            class: 'listview_kbd'
        }, eml.list_raw.replace(/[<>]/g, '').replace('.', '@', 1))
        suba = [kbd, suba];
    }
    let subject = new HTML('div', {
        class: 'listview_email_subject email_unread'
    }, suba);
    as.inject(subject);

    if (!G_current_listmode_compact) { // No body teaser in compact mode
        let body = new HTML('div', {
            class: 'listview_email_body'
        }, eml.body);
        as.inject(body);
    }

    element.inject(as);

    // Labels
    let labels = new HTML('div', {
        class: 'listview_email_labels'
    });


    // Participants
    let ppl = count_people(thread);
    let ptitle = (ppl == 1) ? "one participant" : "%u participants".format(ppl);
    let people = new HTML('span', {
        class: 'label label-default',
        title: ptitle
    }, [
        new HTML('span', {
            class: 'glyphicon glyphicon-user'
        }, ' '),
        " %u".format(ppl)
    ]);
    labels.inject(people);

    // Replies
    let reps = count_replies(thread);
    let rtitle = (reps == 1) ? "one reply" : "%u replies".format(reps);
    let repl = new HTML('span', {
        class: 'label label-default',
        title: rtitle
    }, [
        new HTML('span', {
            class: 'glyphicon glyphicon-envelope'
        }, ' '),
        " %u".format(reps)
    ]);
    labels.inject(repl);

    // Date
    date = new Date(last_email(thread) * 1000.0);
    let dl = new HTML('span', {
        class: 'label label-default'
    }, date.ISOBare());
    if (now - date < 86400000) {
        dl.setAttribute("class", "label label-primary");
    }
    labels.inject(dl);

    element.inject(labels);
    link_wrapper.inject(element);

    return link_wrapper;
}


/******************************************
 Fetched from source/listview-treeview.js
******************************************/

function email_idx(email) {
    // Locates the index position of an email in our current json storage
    for (const [idx, eml] of G_current_json.emails.entries()) {
        if (eml.id === email.id) {
            return idx
        }
    }
    return 0
}

function listview_treeview(json, start) {
    let list = document.getElementById('emails');
    list.innerHTML = "";
    let s = start || 0;
    let email_ordered = [];
    for (let thread of json.thread_struct) {
        let eml = find_email(thread.tid);
        if (eml) email_ordered.push(eml);
        for (let child of thread.children) {
            let eml = find_email(child.tid);
            if (eml) email_ordered.push(eml);
        }
    }
    if (email_ordered.length) {
        for (let n = s; n < (s + G_current_per_page); n++) {
            let z = email_ordered.length - n - 1; // reverse order by default
            if (email_ordered[z]) {
                let item = listview_flat_element(email_ordered[z], email_idx(email_ordered[z]));
                list.inject(item);

                // Hidden placeholder for expanding email(s)
                let placeholder = new HTML('div', {
                    class: G_chatty_layout ? 'email_placeholder_chatty' : 'email_placeholder',
                    id: 'email_%u'.format(z)
                });
                list.inject(placeholder);
            }
        }
    } else {
        list.inject(txt("No emails found..."));
    }
}


/******************************************
 Fetched from source/mgmt.js
******************************************/

let admin_current_email = null;
let admin_email_meta = {};
let audit_page = 0;
let audit_size = 30;
let mgmt_prefs = {}

async function POST(url, formdata, state) {
    const resp = await fetch(url, {
        credentials: "same-origin",
        mode: "same-origin",
        method: "post",
        headers: {
            "Content-Type": "application/json"
        },
        body: formdata
    });
    return resp
}

// Removes an attachment from the archives
async function admin_del_attachment(hash) {
    if (!confirm("Are you sure you wish remove this attachment from the archives?")) {
        return
    }
    // rewrite attachments for email
    let new_attach = [];
    for (let el of admin_email_meta.attachments) {
        if (el.hash != hash) {
            new_attach.push(el);
        }
    }
    admin_email_meta.attachments = new_attach;
    let formdata = JSON.stringify({
        action: "delatt",
        document: hash
    });
    // remove attachment
    let rv = await POST('%sapi/mgmt.json'.format(G_apiURL), formdata, {});
    let response = await rv.text();

    // Edit email in place
    admin_save_email(true);

    if (rv.status == 200) {
        modal("Attachment removed", "Server responded with: " + response, "help");
    } else {
        modal("Something went wrong!", "Server responded with: " + response, "error");
    }
}

// Hides an email from the archives
async function admin_hide_email() {
    if (!confirm("Are you sure you wish to hide this email from the archives?")) {
        return
    }
    let formdata = JSON.stringify({
        action: "hide",
        document: admin_current_email
    });
    let rv = await POST('%sapi/mgmt.json'.format(G_apiURL), formdata, {});
    let response = await rv.text();
    if (rv.status == 200) {
        modal("Email hidden", "Server responded with: " + response, "help");
    } else {
        modal("Something went wrong!", "Server responded with: " + response, "error");
    }
}

async function admin_unhide_email() {
    if (!confirm("Are you sure you wish to unhide this email?")) {
        return
    }
    let formdata = JSON.stringify({
        action: "unhide",
        document: admin_current_email
    });
    let rv = await POST('%sapi/mgmt.json'.format(G_apiURL), formdata, {});
    let response = await rv.text();
    if (rv.status == 200) {
        modal("Email unhidden", "Server responded with: " + response, "help");
    } else {
        modal("Something went wrong!", "Server responded with: " + response, "error");
    }
}


// Fully deletes an email from the archives
async function admin_delete_email() {
    if (!confirm("Are you sure you wish to remove this email from the archives?")) {
        return
    }
    let formdata = JSON.stringify({
        action: "delete",
        document: admin_current_email
    });
    let rv = await POST('%sapi/mgmt.json'.format(G_apiURL), formdata, {});
    let response = await rv.text();
    if (rv.status == 200) {
        modal("Email removed", "Server responded with: " + response, "help");
    } else {
        modal("Something went wrong!", "Server responded with: " + response, "error");
    }
}

// Saves an email with edits
async function admin_save_email(edit_attachment = false) {
    let from = document.getElementById('email_from').value;
    let subject = document.getElementById('email_subject').value;
    let listname = document.getElementById('email_listname').value;
    let is_private = document.getElementById('email_private').value;
    let body = document.getElementById('email_body').value;
    let attach = null;
    if (edit_attachment) {
        attach = admin_email_meta.attachments;
    }
    let formdata = JSON.stringify({
        action: "edit",
        document: admin_current_email,
        from: from,
        subject: subject,
        list: listname,
        private: is_private,
        body: body,
        attachments: attach
    })
    let rv = await POST('%sapi/mgmt.json'.format(G_apiURL), formdata, {});
    let response = await rv.text();
    if (edit_attachment && rv.status == 200) return
    if (rv.status == 200) {
        modal("Email changed", "Server responded with: " + response, "help");
    } else {
        modal("Something went wrong!", "Server responded with: " + response, "error");
    }
}

function admin_email_preview(stats, json) {
    admin_current_email = json.mid;
    admin_email_meta = json;
    let cp = document.getElementById("panel");
    let div = new HTML('div', {
        style: {
            margin: '5px'
        }
    });
    cp.inject(div);

    div.inject(new HTML('h1', {}, "Editing email " + json.mid + ":"));

    // Author
    let author_field = new HTML('div', {
        class: 'email_kv_edit'
    });
    let author_key = new HTML('div', {
        class: 'email_key'
    }, "From: ");
    let author_value = new HTML('input', {
        id: 'email_from',
        style: {
            width: "480px"
        },
        value: json.from
    });
    author_field.inject([author_key, author_value]);
    div.inject(author_field);

    // Subject
    let subject_field = new HTML('div', {
        class: 'email_kv_edit'
    });
    let subject_key = new HTML('div', {
        class: 'email_key'
    }, "Subject: ");
    let subject_value = new HTML('input', {
        id: 'email_subject',
        style: {
            width: "480px"
        },
        value: json.subject
    });
    subject_field.inject([subject_key, subject_value]);
    div.inject(subject_field);

    // Date
    let date_field = new HTML('div', {
        class: 'email_kv_edit'
    });
    let date_key = new HTML('div', {
        class: 'email_key'
    }, "Date: ");
    let date_value = new HTML('div', {
        class: 'email_value'
    }, new Date(json.epoch * 1000.0).ISOBare());
    date_field.inject([date_key, date_value]);
    div.inject(date_field);

    // List
    let listname = json.list_raw.replace(".", "@", 1).replace(/[<>]/g, "");
    let list_field = new HTML('div', {
        class: 'email_kv_edit'
    });
    let list_key = new HTML('div', {
        class: 'email_key'
    }, "List: ");
    let list_value = new HTML('input', {
        id: 'email_listname',
        style: {
            width: "480px"
        },
        value: listname
    });
    list_field.inject([list_key, list_value]);
    div.inject(list_field);

    // Private email?
    let priv_field = new HTML('div', {
        class: 'email_kv_edit'
    });
    let priv_key = new HTML('div', {
        class: 'email_key'
    }, "Visibility: ");
    let priv_value = new HTML('select', {
        id: 'email_private'
    });
    priv_value.inject(new HTML('option', {
        value: 'no',
        style: {
            color: 'green'
        },
        selected: json.private ? null : "selected"
    }, "Public"));
    priv_value.inject(new HTML('option', {
        value: 'yes',
        style: {
            color: 'red'
        },
        selected: json.private ? "selected" : null
    }, "Private"));
    priv_field.inject([priv_key, priv_value]);
    div.inject(priv_field);

    // Attachments?
    if (json.attachments && json.attachments.length > 0) {
        let attach_field = new HTML('div', {
            class: 'email_kv'
        });
        let attach_key = new HTML('div', {
            class: 'email_key'
        }, "Attachment(s): ");
        let alinks = [];
        for (let attachment of json.attachments) {
            let link = `${G_apiURL}api/email.lua?attachment=true&id=${encodeURIComponent(json.mid)}&file=${encodeURIComponent(attachment.hash)}`;
            let a = new HTML('a', {
                href: link,
                target: '_blank'
            }, attachment.filename);
            alinks.push(a);
            let fs = ` ${attachment.size} bytes`;
            if (attachment.size >= 1024) fs = ` ${Math.floor(attachment.size/1024)} KB`;
            if (attachment.size >= 1024 * 1024) fs = ` ${Math.floor(attachment.size/(1024*10.24))/100} MB`;
            alinks.push(fs);
            let adel = new HTML('a', {
                onclick: `admin_del_attachment('${attachment.hash}');`,
                href: "javascript:void(0);"
            }, "Delete attachment");
            alinks.push(adel);
            alinks.push(new HTML('br'));
        }
        let attach_value = new HTML('div', {
            class: 'email_value'
        }, alinks);
        attach_field.inject([attach_key, attach_value]);
        div.inject(attach_field);
    }

    let text = new HTML('textarea', {
        id: 'email_body',
        style: {
            width: "100%",
            height: "480px"
        }
    }, json.body);
    div.inject(text);

    let btn_edit = new HTML('button', {
        onclick: "admin_save_email();"
    }, "Save changes to archive");
    let btn_del = new HTML('button', {
        onclick: "admin_delete_email();",
        style: {
            marginLeft: "36px",
            color: 'red'
        }
    }, "Delete email from archives");

    let btn_hide = new HTML('button', {
        onclick: "admin_hide_email();",
        style: {
            marginLeft: "36px",
            color: 'purple'
        }
    }, "Hide email from archives");
    if (admin_email_meta.deleted) {
        btn_hide = new HTML('button', {
            onclick: "admin_unhide_email();",
            style: {
                marginLeft: "36px",
                color: 'purple'
            }
        }, "Unhide email from archives");
    }

    div.inject(new HTML('br'));
    div.inject(btn_edit);
    div.inject(btn_hide);
    div.inject(btn_del);
    div.inject(new HTML('br'));
    div.inject(new HTML('small', {}, "Modifying emails will remove the option to view their sources via the web interface, as the source may contain traces that reveal the edit."))
    div.inject(new HTML('br'));
    if (!mgmt_prefs.login.credentials.fully_delete) {
        div.inject(new HTML('small', {}, "Emails that are deleted may still be recovered by the base system administrator. For complete expungement, please contact the system administrator."))
    } else {
        div.inject(new HTML('small', {style:{color: 'red'}}, "As full delete enforcement is enabled on this server, emails are removed forever from the archive when deleted, and cannot be recovered."))
    }
}

function admin_audit_view(state, json) {
    let headers = ['Date', 'Author', 'Remote', 'Action', 'Target', 'Log'];
    let cp = document.getElementById("panel");
    let div = document.getElementById('auditlog_entries');
    if (!div) {
        div = new HTML('div', {
            id: "auditlog",
            style: {
                margin: '5px'
            }
        });
        cp.inject(div);
        div.inject(new HTML('h1', {}, "Audit log:"));
    }
    let table = document.getElementById('auditlog_entries');
    if (json.entries && json.entries.length > 0 || table) {
        if (!table) {
            table = new HTML('table', {
                border: "1",
                id: "auditlog_entries",
                class: "auditlog_entries"
            });
            let trh = new HTML('tr');
            for (let header of headers) {
                let th = new HTML('th', {}, header + ":");
                trh.inject(th);
            }
            table.inject(trh)
            div.inject(table);
            let btn = new HTML('button', {
                onclick: "admin_audit_next();"
            }, "Load more entries");
            div.inject(btn);
        }
        for (let entry of json.entries) {
            let tr = new HTML('tr', {
                class: "auditlog_entry"
            });
            for (let header of headers) {
                let key = header.toLowerCase();
                let value = entry[key];
                if (key == 'target') {
                    value = new HTML('a', {
                        href: "/admin/" + value
                    }, value);
                }
                if (key == 'action') {
                    let action_colors = {
                        edit: 'blue',
                        delete: 'red',
                        default: 'black'
                    };
                    value = new HTML('spam', {
                        style: {
                            color: action_colors[value] ? action_colors[value] : action_colors['default']
                        }
                    }, value);
                }
                let th = new HTML('td', {}, value);
                tr.inject(th);
            }
            table.inject(tr);
        }
    } else {
        div.inject("Audit log is empty");
    }
}

function admin_audit_next() {
    audit_page++;
    GET('%sapi/mgmt.json?action=log&page=%u&size=%u'.format(G_apiURL, audit_page, audit_size), admin_audit_view, null);
}

// Onload function for admin.html
function admin_init() {
    init_preferences(); // blank call to load defaults like social rendering
    GET('%sapi/preferences.lua'.format(G_apiURL), (state, json) => {
        mgmt_prefs = json
        init_preferences(state, json);
    }, null);
    let mid = decodeURIComponent(location.href.split('/').pop());
    // Specific email/list handling?
    if (mid.length > 0) {
        // List handling?
        if (mid.match(/^<.+>$/)) {

        }
        // Email handling?
        else {
            GET('%sapi/email.json?id=%s'.format(G_apiURL, encodeURIComponent(mid)), admin_email_preview, null);
        }
    } else { // View audit log
        GET('%sapi/mgmt.json?action=log&page=%s&size=%u'.format(G_apiURL, audit_page, audit_size), admin_audit_view, null);
    }
}


/******************************************
 Fetched from source/preferences.js
******************************************/

// logout: log out a user
// call the logout URL, then refresh this page - much simple!
function logout() {
    GET("%sapi/preferences.lua?logout=true".format(G_apiURL), () => location.href = document.location);
}

function init_preferences(state, json) {
    G_ponymail_preferences = json || {};
    // First, load session local settings, if possible
    if (G_can_store) {
        let local_preferences = window.localStorage.getItem('G_ponymail_preferences');
        if (local_preferences) {
            let ljson = JSON.parse(local_preferences);
            if (ljson.G_chatty_layout !== undefined) {
                G_chatty_layout = ljson.G_chatty_layout;
            }
            if (ljson.G_current_listmode !== undefined) {
                G_current_listmode = ljson.G_current_listmode;
            }
            if (ljson.G_current_listmode_compact !== undefined) {
                G_current_listmode_compact = ljson.G_current_listmode_compact;
            }
            if (ljson.G_show_stats_sidebar !== undefined) {
                G_show_stats_sidebar = ljson.G_show_stats_sidebar;
            }
        }
    }

    // Set chatty/plain email rendering mode:
    let cl = document.getElementById('chatty_link'); //  legacy button
    if (cl) {
        cl.setAttribute("class", G_chatty_layout ? "enabled" : "disabled");
    }
    let cle = document.getElementById('email_mode_chatty');
    if (cle) {
        cle.checked = G_chatty_layout;
    }
    let cld = document.getElementById('email_mode_plain');
    if (cld) {
        cld.checked = !G_chatty_layout;
    }
    let cla = document.getElementById('G_show_stats_sidebar');
    if (cla) {
        cla.checked = G_show_stats_sidebar;
    }

    // Set list display mode:
    let dmt = document.getElementById('display_mode_threaded');
    if (dmt) {
        dmt.checked = (G_current_listmode == 'threaded');
    }
    let dmf = document.getElementById('display_mode_flat');
    if (dmf) {
        dmf.checked = (G_current_listmode == 'flat');
    }
    let dmtr = document.getElementById('display_mode_treeview');
    if (dmtr) {
        dmtr.checked = (G_current_listmode == 'treeview');
    }

    // Compact list view
    let dmc = document.getElementById('display_mode_compact');
    if (dmc) {
        dmc.checked = G_current_listmode_compact;
    }



    if (G_ponymail_preferences.login && G_ponymail_preferences.login.credentials) {
        let prefsmenu = document.getElementById('login_dropdown') || document.getElementById('prefs_dropdown');
        let uimg = document.getElementById('uimg');
        uimg.setAttribute("src", "images/user.png");
        uimg.setAttribute("title", "Logged in as %s".format(G_ponymail_preferences.login.credentials.fullname));

        // Generate user menu
        prefsmenu.innerHTML = "";


        let logout = new HTML('a', {
            href: "javascript:void(logout());"
        }, "Log out");
        let li = new HTML('li', {}, logout)
        prefsmenu.inject(li);

    } else {
        let prefsmenu = document.getElementById('login_dropdown') || document.getElementById('prefs_dropdown');
        if (prefsmenu) {
            prefsmenu.innerHTML = "";
            let login = new HTML('a', {
                href: "javascript:location.href='oauth.html';"
            }, "Log In");
            let li = new HTML('li', {}, login)
            prefsmenu.inject(li);
        }
    }

    if (json) {
        listview_list_lists(state, json);
        if (state && state.prime) {
            // If lists is accessible, show it
            if (json.lists[G_current_domain] && (G_current_list == '*' || json.lists[G_current_domain][G_current_list] != undefined)) {
                post_prime(state);
            } else if  (G_current_domain == '*') { // assume a match
                post_prime(state);
            } else { // otherwise, bork
                if (G_current_list.length > 0 && (!json.lists[G_current_domain] || Object.keys(json.lists[G_current_domain]).length > 0)) {
                    let eml = document.getElementById('emails');
                    eml.innerText = "We couldn't find this list. It may not exist or require you to be logged in with specific credentials.";
                    eml.inject(new HTML('br'));
                    eml.inject(new HTML('a', {
                        href: 'oauth.html',
                        onclick: 'location.href="oauth.html";'
                    }, "Click here to log in via OAuth"));
                } else {
                    switch_project(G_current_domain);
                }
            }
        }
    }
}

function save_preferences() {
    if (G_can_store) {
        let ljson = {
            G_chatty_layout: G_chatty_layout,
            G_current_listmode: G_current_listmode,
            G_current_listmode_compact: G_current_listmode_compact,
            G_show_stats_sidebar: G_show_stats_sidebar
        };
        let lstring = JSON.stringify(ljson);
        window.localStorage.setItem('G_ponymail_preferences', lstring);
        console.log("Saved local preferences");
    }
}


function set_theme(theme, compact_mode) {
    G_current_listmode = theme;
    if (compact_mode !== undefined) {
        G_current_listmode_compact = compact_mode;
    }
    renderListView(G_current_state, G_current_json);
    save_preferences();
}

function set_skin(skin) {
    if (typeof(enable_chatty) === "boolean") {
        G_chatty_layout = enable_chatty;
    } else {
        G_chatty_layout = !G_chatty_layout;
    }
    let cl = document.getElementById('chatty_link');
    if (cl) {
        cl.setAttribute("class", G_chatty_layout ? "enabled" : "disabled");
    }
    hideWindows(true);
    renderListView(G_current_state, G_current_json);
    save_preferences();
}

// set_skin, but for permalinks
function set_skin_permalink(enable_chatty) {
    if (typeof(enable_chatty) === "boolean") {
        G_chatty_layout = enable_chatty;
    } else {
        G_chatty_layout = !G_chatty_layout;
    }
    let cl = document.getElementById('chatty_link');
    if (cl) {
        cl.setAttribute("class", G_chatty_layout ? "enabled" : "disabled");
    }
    hideWindows(true);
    save_preferences();
    parse_permalink();
}

function set_show_stats(display) {
    G_show_stats_sidebar = display;
    if (display === false) {
        document.getElementById('sidebar_stats').style.display = "none";
        document.getElementById('sidebar_wordcloud').style.display = "none";
    } else {
        document.getElementById('sidebar_stats').style.display = "block";
        document.getElementById('sidebar_wordcloud').style.display = "block";
    }
    save_preferences();
    renderCalendar();
}

/******************************************
 Fetched from source/primer.js
******************************************/

/* List View Rendering main func */
function renderListView(state, json) {
    if (json) {
        G_current_json = json;
    }
    G_current_state = state;
    async_escrow['rendering'] = new Date();
    if (!state || state.update_calendar !== false) {
        renderCalendar({
            FY: json.firstYear,
            FM: json.firstMonth,
            LY: json.lastYear,
            LM: json.lastMonth,
            activity: json.active_months
        });
    }
    // sort threads by date
    if (isArray(json.thread_struct)) {
        G_current_json.thread_struct.sort((a, b) => last_email(a) - last_email(b));
    }
    listview_header(state, json);
    if (G_current_listmode == 'threaded') {
        listview_threaded(json, 0);
    } else if (G_current_listmode == 'treeview') {
        listview_treeview(json, 0);
    } else {
        listview_flat(json, 0);
    }

    sidebar_stats(json); // This comes last, takes the longest with WC enabled.
    delete async_escrow['rendering'];

    if (state && state.to) {
        listview_list_lists(state);
    }
}

/* Primer function for List View
 * Fetches the following:
 * - user preferences (api/preferences.lua)
 * When done, we create the scaffolding and list view
 */
function primeListView(state) {
    console.log("Priming user interface for List View..");
    state = state || {};
    state.prime = true;
    GET('%sapi/preferences.lua'.format(G_apiURL), init_preferences, state);
}

// callback from when prefs have loaded
function post_prime(state) {
    let sURL = '%sapi/stats.lua?list=%s&domain=%s'.format(G_apiURL, encodeURIComponent(G_current_list), encodeURIComponent(G_current_domain));
    if (G_current_year && G_current_month) {
        sURL += "&d=%u-%u".format(G_current_year, G_current_month);
    }
    if (!(state && state.search)) {
        if (state && state.array) {
            G_collated_json = {};
            for (let entry of state.array) {
                let list = entry.split('@');
                sURL = '%sapi/stats.lua?list=%s&domain=%s'.format(G_apiURL, encodeURIComponent(list[0]), encodeURIComponent(list[1]));
                GET(sURL, render_virtual_inbox, state);
            }
        } else {
            GET(sURL, renderListView, state);
        }
    } else {
        search(state.query, state.date);
    }
}

// onload function for list.html
function parseURL(state) {
    console.log("Running ParseURL");
    console.log(state);
    let bits = window.location.search.substring(1).split(":", 3);
    let list = bits[0];
    let month = bits[1];
    let query = bits[2];
    state = state || {};
    G_current_month = 0;
    G_current_year = 0;

    // If "month" (year-month) is specified,
    // we should set the current vars
    if (month) {
        try {
            let dbits = month.split("-");
            G_current_year = dbits[0];
            G_current_month = dbits[1];
        } catch (e) {}
    }
    // Is this a valid list?
    if (list !== '') {
        // multi-list??
        if (list.match(/,/)) {
            state.array = list.split(',');
            G_current_domain = 'inbox';
            G_current_list = 'virtual';
        } else {
            let lbits = list.split("@");
            if (lbits.length > 1) {
                G_current_list = lbits[0];
                G_current_domain = lbits[1];
            } else {
                G_current_domain = lbits;
                G_current_list = '';
            }
        }
    }
    // Are we initiating a search?
    if (query || (month && !month.match(/^\d\d\d\d-\d+$/))) { // single-month isn't a search, but any other date marker is
        state.search = true;
        state.query = decodeURIComponent(query||"");
        state.date = month;
    }
    // If hitting the refresh button, don't refresh preferences, just do the search.
    if (state.noprefs) {
        post_prime(state);
    } else {
        primeListView(state);
    }
}



// Parse a permalink and fetch the thread
// URL is expected to be of the form /thread[.html]/<msgid>?<list.id>|find_parent=true
// onload function for thread.html
function parse_permalink() {
    // message id is the bit after the last /
    // TODO: could look for thread[.html]/ instead
    let mid = decodeURIComponent(location.pathname.split('/').pop());
    // List-ID specified?
    // query needs decodeURIComponent with '+' conversion
    const query = decodeURIComponent(location.search.substring(1).replace(/\+/g, ' '));
    let list_id = null;
    let find_parent = false;
    if (query.length) {
        if (query.match(/^<.+>$/)) {
            list_id = query;
        }
        find_parent = query == 'find_parent=true';
    }

    mid = unshortenID(mid);  // In case of old school shortened links
    init_preferences(); // blank call to load defaults like social rendering
    GET('%sapi/preferences.lua'.format(G_apiURL), init_preferences, null);
    // Fetch the thread data and pass to build_single_thread
    if (list_id) {
        GET('%sapi/thread.lua?id=%s&listid=%s'.format(G_apiURL, encodeURIComponent(mid), encodeURIComponent(list_id)), construct_single_thread, {
            cached: true
        });
    }
    else {
        let encoded_mid = encodeURIComponent(mid);
        if (find_parent) {
            GET('%sapi/thread.lua?id=%s&find_parent=true'.format(G_apiURL, encoded_mid), construct_single_thread, {
                cached: true
            });
        } else {
            GET('%sapi/thread.lua?id=%s'.format(G_apiURL, encoded_mid), construct_single_thread, {
                cached: true
            });
        }
    }
}


// Virtual inbox ŕendering
function render_virtual_inbox(state, json) {
    if (json) {
        G_collated_json.emails = G_collated_json.emails || [];
        G_collated_json.thread_struct = G_collated_json.thread_struct || [];
        for (let email of json.emails) {
            G_collated_json.emails.push(email);
        }
        for (let thread_struct of json.thread_struct) {
            G_collated_json.thread_struct.push(thread_struct);
        }
    }

    for (let _ in async_escrow) {
        return;
    }

    if (true) {
        console.log("Rendering multi-list")
        G_current_json = G_collated_json;
        G_current_json.participants = [];

        async_escrow['rendering'] = new Date();
        if (!state || state.update_calendar !== false) {
            renderCalendar({
                FY: json.firstYear,
                FM: json.firstMonth,
                LY: json.lastYear,
                LM: json.lastMonth,
                activity: json.active_months
            });
        }
        // sort threads by date
        if (isArray(json.thread_struct)) {
            G_current_json.thread_struct.sort((a, b) => last_email(a) - last_email(b));
        }
        listview_header(state, G_current_json);
        if (G_current_listmode == 'threaded') {
            listview_threaded(G_current_json, 0);
        } else if (G_current_listmode == 'treeview') {
            listview_treeview(G_current_json, 0);
        } else {
            listview_flat(G_current_json, 0);
        }

        sidebar_stats(G_current_json); // This comes last, takes the longest with WC enabled.
        delete async_escrow['rendering'];
    }
}


// hex <- base 36 conversion, reverses short links
function unshortenID(mid) {
    // all short links begin with 'Z'. If not, it's not a short link
    // so let's just pass it through unaltered if so.
    // Some old shortlinks begin with 'B', so let's be backwards compatible for now.
    // Shortlinks are also 15 chars (including prefix)
    // They should also consist of base 36 chars or '-'
    if ((mid[0] == 'Z' || mid[0] == 'B') && mid.length == 15){
        // remove padding
        let id1 = parseInt(mid.substr(1, 7).replace(/-/g, ""), 36)
        let id2 = parseInt(mid.substr(8, 7).replace(/-/g, ""), 36)
        id1 = id1.toString(16)
        id2 = id2.toString(16)

        // add 0-padding
        while (id1.length < 9) id1 = '0' + id1
        while (id2.length < 9) id2 = '0' + id2
        return id1+id2
    }
    return mid
}


/******************************************
 Fetched from source/render-email.js
******************************************/

// Function for parsing email addresses from a to or cc line
function get_rcpts(addresses) {
    let list_of_emails = []
    if (!addresses) return [] // cc or to may be null
    for (let a of addresses.split(/,\s*/)) {
        let m = a.match(/<(.+)>/);
        if (m) {
            a = m[1];
        }
        if (a && a.length > 5) { // more than a@b.c
            list_of_emails.push(a);
            console.log(a);
        }
    }
    return list_of_emails;
}

async function render_email(state, json) {
    let div = state.div;
    G_full_emails[json.mid] = json; // Save for composer if replying later...
    if (state.scroll) {
        let rect = div.getBoundingClientRect();
        try {
            window.setTimeout(function() {
                window.scrollTo(0, rect.top - 48);
            }, 200);
            console.log("Scrolled to %u".format(rect.top - 48));
        } catch (e) {}
    }
    if (G_chatty_layout) {
        return render_email_chatty(state, json);
    }

    // Author
    let author_field = new HTML('div', {
        class: 'email_kv'
    });
    let author_key = new HTML('div', {
        class: 'email_key'
    }, "From: ");
    let author_value = new HTML('div', {
        class: 'email_value'
    }, json.from);
    author_field.inject([author_key, author_value]);
    div.inject(author_field);

    // Subject
    let subject_field = new HTML('div', {
        class: 'email_kv'
    });
    let subject_key = new HTML('div', {
        class: 'email_key'
    }, "Subject: ");
    let subject_value = new HTML('div', {
        class: 'email_value'
    }, json.subject == '' ? '(No subject)' : json.subject);
    subject_field.inject([subject_key, subject_value]);
    div.inject(subject_field);

    // Date
    let date_field = new HTML('div', {
        class: 'email_kv'
    });
    let date_key = new HTML('div', {
        class: 'email_key'
    }, "Date: ");
    let date_value = new HTML('div', {
        class: 'email_value'
    }, new Date(json.epoch * 1000.0).ISOBare());
    date_field.inject([date_key, date_value]);
    div.inject(date_field);


    // List
    let listname = json.list_raw.replace(".", "@", 1).replace(/[<>]/g, "");
    let list_field = new HTML('div', {
        class: 'email_kv'
    });
    let list_key = new HTML('div', {
        class: 'email_key'
    }, "List: ");
    let list_value = new HTML('div', {
            class: 'email_value'
        },
        new HTML('a', {
            href: 'list?%s'.format(listname)
        }, listname)
    );
    list_field.inject([list_key, list_value]);
    div.inject(list_field);

    // To + CC if need be
    let rcpts = get_rcpts(json.to);
    rcpts.push(...get_rcpts(json.cc));
    rcpts.remove(listname);
    if (rcpts.length) {
        let rcpt_field = new HTML('div', {
            class: 'email_kv'
        });
        let rcpt_key = new HTML('div', {
            class: 'email_key'
        }, "To/Cc: ");
        let rcpt_value = new HTML('div', {
                class: 'email_value'
            },
            new HTML('span', {}, rcpts.join(", "))
    );
        rcpt_field.inject([rcpt_key, rcpt_value]);
        div.inject(rcpt_field);
    }

    // Private email??
    if (json.private === true) {
        let priv_field = new HTML('div', {
            class: 'email_kv'
        });
        let priv_key = new HTML('div', {
            class: 'email_key'
        }, "Private: ");
        let priv_value = new HTML('div', {
            class: 'email_value_emphasis'
        }, "YES");
        priv_field.inject([priv_key, priv_value]);
        div.inject(priv_field);
    }

    // Attachments?
    if (json.attachments && json.attachments.length > 0) {
        let attach_field = new HTML('div', {
            class: 'email_kv'
        });
        let attach_key = new HTML('div', {
            class: 'email_key'
        }, "Attachment(s): ");
        let alinks = [];
        for (let attachment of json.attachments) {
            let link = `${G_apiURL}api/email.lua?attachment=true&id=${json.mid}&file=${attachment.hash}`;
            let a = new HTML('a', {
                href: link,
                target: '_blank'
            }, attachment.filename);
            alinks.push(a);
            let fs = ` ${attachment.size} bytes`;
            if (attachment.size >= 1024) fs = ` ${Math.floor(attachment.size/1024)} KB`;
            if (attachment.size >= 1024 * 1024) fs = ` ${Math.floor(attachment.size/(1024*10.24))/100} MB`;
            alinks.push(fs);
            alinks.push(new HTML('br'));
        }
        let attach_value = new HTML('div', {
            class: 'email_value'
        }, alinks);
        attach_field.inject([attach_key, attach_value]);
        div.inject(attach_field);
    }

    let text = new HTML('pre', {}, fixup_quotes(json.body));
    div.inject(text);

    // Private text?
    if (json.private === true) {
        text.style.backgroundImage = "url(images/private.png)";
    }


    let toolbar = new HTML('div', {
        class: 'toolbar'
    });

    // reply to email button
    let replybutton = new HTML('button', {
        title: "Reply to this email",
        onclick: `compose_email('${json.mid}');`,
        class: 'btn toolbar_btn toolbar_button_reply'
    }, new HTML('span', {
        class: 'glyphicon glyphicon-pencil'
    }, ' '));
    toolbar.inject(replybutton);

    // permalink button
    let linkbutton = new HTML('a', {
        href: 'thread/%s'.format(json.mid),
        target: '_blank',
        title: "Permanent link to this email",
        class: 'btn toolbar_btn toolbar_button_link'
    }, new HTML('span', {
        class: 'glyphicon glyphicon-link'
    }, ' '));
    toolbar.inject(linkbutton);

    // Source-view button
    let sourcebutton = new HTML('a', {
        href: '%sapi/source.lua?id=%s'.format(G_apiURL, encodeURIComponent(json.mid)),
        target: '_blank',
        title: "View raw source",
        class: 'btn toolbar_btn toolbar_button_source'
    }, new HTML('span', {
        class: 'glyphicon glyphicon-file'
    }, ' '));
    toolbar.inject(sourcebutton);

    // Admin button?
    if (G_ponymail_preferences.login && G_ponymail_preferences.login.credentials && G_ponymail_preferences.login.credentials.admin) {
        let adminbutton = new HTML('a', {
            href: 'admin/%s'.format(json.mid),
            target: '_blank',
            title: "Modify email",
            class: 'btn toolbar_btn toolbar_button_admin'
        }, new HTML('span', {
            class: 'glyphicon glyphicon-cog'
        }, ' '));
        toolbar.inject(adminbutton);
    }

    text.inject(toolbar);
}



async function render_email_chatty(state, json) {
    let div = state.div;
    div.parentNode.style.border = 'none';

    // Author
    let when = new Date(json.epoch * 1000.0);
    let ldate = when.toISOString();
    try {
        ldate = "%s %s".format(when.toLocaleDateString(undefined, PONYMAIL_DATE_FORMAT), when.toLocaleTimeString(undefined, PONYMAIL_TIME_FORMAT));
    } catch (e) {

    }

    let author_field = new HTML('div', {
        class: 'chatty_author'
    });
    let gravatar = new HTML('img', {
        class: "chatty_gravatar",
        src: GRAVATAR_URL.format(json.gravatar)
    });
    let author_name = json.from.replace(/\s*<.+>/, "").replace(/"/g, '');
    let author_email = json.from.match(/\s*<(.+@.+)>\s*/);
    if (author_name.length == 0) author_name = author_email ? author_email[1] : "(No author?)";
    let author_nametag = new HTML('div', {
        class: 'chatty_author_name'
    }, [
        new HTML('b', {}, author_name),
        " - %s".format(ldate)
    ]);
    author_field.inject([gravatar, author_nametag]);
    div.inject(author_field);
    let chatty_body = fixup_quotes(json.body);
    if (json.mid == G_current_open_email) {
        let header = new HTML('h4', {
            class: 'chatty_title_inline'
        }, json.subject);
        chatty_body.unshift(header);
    }
    let text = new HTML('pre', {
        class: 'chatty_body'
    }, chatty_body);
    div.inject(text);

    // Private text?
    if (json.private === true) {
        text.style.backgroundImage = "url(images/private.png)";
    }

    // Attachments?
    if (json.attachments && json.attachments.length > 0) {
        let attach_field = new HTML('div', {
            class: 'email_kv'
        });
        let attach_key = new HTML('div', {
            class: 'email_key'
        }, "Attachment(s):");
        let alinks = [];
        for (let attachment of json.attachments) {
            let link = `${G_apiURL}api/email.lua?attachment=true&id=${json.mid}&file=${attachment.hash}`;
            let a = new HTML('a', {
                href: link,
                target: '_blank'
            }, attachment.filename);
            alinks.push(a);
            let fs = ` ${attachment.size} bytes`;
            if (attachment.size >= 1024) fs = ` ${Math.floor(attachment.size/1024)} KB`;
            if (attachment.size >= 1024 * 1024) fs = ` ${Math.floor(attachment.size/(1024*10.24))/100} MB`;
            alinks.push(fs);
            alinks.push(new HTML('br'));
        }
        let attach_value = new HTML('div', {
            class: 'email_value'
        }, alinks);
        attach_field.inject([attach_key, attach_value]);
        text.inject(attach_field);
    }

    let toolbar = new HTML('div', {
        class: 'toolbar_chatty'
    });

    // reply to email button
    let replybutton = new HTML('button', {
        title: "Reply to this email",
        onclick: `compose_email('${json.mid}');`,
        class: 'btn toolbar_btn toolbar_button_reply'
    }, new HTML('span', {
        class: 'glyphicon glyphicon-pencil'
    }, ' '));
    toolbar.inject(replybutton);

    // permalink button
    let linkbutton = new HTML('a', {
        href: 'thread/%s'.format(json.mid),
        title: "Permanent link to this email",
        target: '_blank',
        class: 'btn toolbar_btn toolbar_button_link'
    }, new HTML('span', {
        class: 'glyphicon glyphicon-link'
    }, ' '));
    toolbar.inject(linkbutton);

    // Source-view button
    let sourcebutton = new HTML('a', {
        href: '%sapi/source.lua?id=%s'.format(G_apiURL, encodeURIComponent(json.mid)),
        target: '_blank',
        title: "View raw source",
        class: 'btn toolbar_btn toolbar_button_source'
    }, new HTML('span', {
        class: 'glyphicon glyphicon-file'
    }, ' '));
    toolbar.inject(sourcebutton);

    // Admin button?
    if (G_ponymail_preferences.login && G_ponymail_preferences.login.credentials && G_ponymail_preferences.login.credentials.admin) {
        let adminbutton = new HTML('a', {
            href: 'admin/%s'.format(encodeURIComponent(json.mid)),
            target: '_blank',
            title: "Modify email",
            class: 'btn toolbar_btn toolbar_button_admin'
        }, new HTML('span', {
            class: 'glyphicon glyphicon-cog'
        }, ' '));
        toolbar.inject(adminbutton);
    }

    text.inject(toolbar);
}


/******************************************
 Fetched from source/scaffolding-html.js
******************************************/

/**
 * HTML: DOM creator class
 * args:
 * - type: HTML element type (div, table, p etc) to produce
 * - params: hash of element params to add (class, style etc)
 * - children: optional child or children objects to insert into the new element
 * Example:
 * div = new HTML('div', {
 *    class: "footer",
 *    style: {
 *        fontWeight: "bold"
 *    }
#}, "Some text inside a div")
 */

const txt = (msg) => document.createTextNode(msg);

const HTML = (function() {
    function HTML(type, params, children) {

        /* create the raw element, or clone if passed an existing element */
        if (typeof type === 'object') {
            this.element = type.cloneNode();
        } else {
            this.element = document.createElement(type);
        }

        /* If params have been passed, set them */
        if (isHash(params)) {
            for (let key in params) {
                let val = params[key];

                /* Standard string value? */
                if (typeof val === "string" || typeof val === 'number') {
                    this.element.setAttribute(key, val);
                } else if (isArray(val)) {

                    /* Are we passing a list of data to set? concatenate then */
                    this.element.setAttribute(key, val.join(" "));
                } else if (isHash(val)) {

                    /* Are we trying to set multiple sub elements, like a style? */
                    for (let subkey in val) {
                        let subval = val[subkey];
                        if (!this.element[key]) {
                            throw "No such attribute, " + key + "!";
                        }
                        this.element[key][subkey] = subval;
                    }
                }
            }
        }

        /* If any children have been passed, add them to the element */
        if (children) {

            /* If string, convert to textNode using txt() */
            if (typeof children === "string") {
                this.element.inject(txt(children));
            } else {

                /* If children is an array of elems, iterate and add */
                if (isArray(children)) {
                    let child, j, len;
                    for (j = 0, len = children.length; j < len; j++) {
                        child = children[j];

                        /* String? Convert via txt() then */
                        if (typeof child === "string") {
                            this.element.inject(txt(child));
                        } else {

                            /* Plain element, add normally */
                            this.element.inject(child);
                        }
                    }
                } else {

                    /* Just a single element, add it */
                    this.element.inject(children);
                }
            }
        }
        return this.element;
    }

    return HTML;

})();

/**
 * prototype injector for HTML elements:
 * Example: mydiv.inject(otherdiv)
 */

HTMLElement.prototype.inject = function(child) {
    let item, j, len;
    if (isArray(child)) {
        for (j = 0, len = child.length; j < len; j++) {
            item = child[j];
            if (typeof item === 'string') {
                item = txt(item);
            }
            this.appendChild(item);
        }
    } else {
        if (typeof child === 'string') {
            child = txt(child);
        }
        this.appendChild(child);
    }
    return child;
};



/**
 * prototype for emptying an html element
 */

HTMLElement.prototype.empty = function() {
    let ndiv;
    ndiv = this.cloneNode();
    this.parentNode.replaceChild(ndiv, this);
    return ndiv;
};

function toggleView(id) {
    let obj = document.getElementById(id);
    if (obj) {
        obj.style.display = (obj.style.display == 'block') ? 'none' : 'block';
    }
}

/******************************************
 Fetched from source/search.js
******************************************/

function search(query, date) {
    let list = G_current_list;
    let global = false;
    let domain = G_current_domain;
    if (G_ponymail_search_list == 'global') {
        list = '*';
        domain = '*';
        global = true;
    }
    if (G_ponymail_search_list == 'domain') {
        list = '*';
        global = true;
    }

    let listid = '%s@%s'.format(list, domain);
    G_current_list = list;
    G_current_domain = domain;
    let newhref = "list?%s:%s:%s".format(listid, date, query);

    let header_from = document.getElementById('header_from');
    let header_subject = document.getElementById('header_subject');
    let header_to = document.getElementById('header_to');
    let header_body = document.getElementById('header_body');
    let sURL = '%sapi/stats.lua?d=%s&list=%s&domain=%s&q=%s'.format(
        G_apiURL, encodeURIComponent(date), encodeURIComponent(list), encodeURIComponent(domain), encodeURIComponent(query)
        );
    if (header_from.value.length > 0) {
        sURL += "&header_from=%s".format(encodeURIComponent(header_from.value));
        newhref += "&header_from=%s".format(header_from.value);
        header_from.value = "";
    }
    if (header_subject.value.length > 0) {
        sURL += "&header_subject=%s".format(encodeURIComponent(header_subject.value));
        newhref += "&header_subject=%s".format(header_subject.value);
        header_subject.value = "";
    }
    if (header_to.value.length > 0) {
        sURL += "&header_to=%s".format(encodeURIComponent(header_to.value));
        newhref += "&header_to=%s".format(header_to.value);
        header_to.value = "";
    }
    if (header_body.value.length > 0) {
        sURL += "&header_body=%s".format(encodeURIComponent(header_body.value));
        newhref += "&header_body=%s".format(header_body.value);
        header_body.value = "";
    }
    GET(sURL, renderListView, {
        search: true,
        global: global
    });
    if (location.href !== newhref) {
        window.history.pushState({}, null, newhref);
    }

    listview_list_lists({
        url: sURL,
        search: true,
        query: query,
        list: list,
        domain: domain
    });
    hideWindows(true);
    document.getElementById('q').value = query;
    return false;
}

// set the list(s) to search, update links
function search_set_list(what) {
    G_ponymail_search_list = what;
    let links = document.getElementsByClassName('searchlistoption');
    let whatxt = "this list"
    for (let el of links) {
        if (el.getAttribute("id").match(what)) {
            el.setAttribute("class", "searchlistoption checked");
            whatxt = el.innerText.toLowerCase();
        } else {
            el.setAttribute("class", "searchlistoption");
        }
    }
    document.getElementById('q').setAttribute("placeholder", "Search %s...".format(whatxt));
}

/******************************************
 Fetched from source/sidebar-calendar.js
******************************************/

let calendar_index = 0;
let current_calendar_size = CALENDAR_YEARS_SHOWN;
let calendar_state = {}


function calendar_max_height() {
    let body = document.body;
    let html = document.documentElement;
    let height = Math.max(body.scrollHeight,
        html.clientHeight, html.scrollHeight);
    let width = Math.max(body.scrollWidth,
        html.clientWidth, html.scrollWidth);
    let year_height = 48; // Height of one calendar year
    height -= document.getElementById("emails").getBoundingClientRect().y + 16; // top area height plus footer
    let number_of_years = Math.max(5, Math.floor(height / year_height));
    return number_of_years;
}

function renderCalendar(state) {
    calendar_state = state ? state : calendar_state;
    calendar_index = 0;
    current_calendar_size = G_show_stats_sidebar ? CALENDAR_YEARS_SHOWN : calendar_max_height();
    // Only render if calendar div is present
    let cal = document.getElementById('sidebar_calendar');
    if (!cal) {
        return;
    }

    let now = new Date();
    let CY = now.getFullYear();
    let CM = now.getMonth() + 1;
    let SY = Math.min(calendar_state.LY, CY); // last year in calendar, considering current date

    // If Last Year is into the future, set Last Month to this one.
    if (calendar_state.LY > CY) {
        calendar_state.LM = CM;
    }

    let cdiv = new HTML('div', {
        class: 'sidebar_calendar'
    })
    let N = 0;

    // Chevron for moving to later years
    let chevron = new HTML('div', {
        class: 'sidebar_calendar_chevron'
    });
    chevron.inject(new HTML('span', {
        onclick: 'calendar_scroll(this, -1);',
        style: {
            display: 'none'
        },
        id: 'sidebar_calendar_up',
        class: 'glyphicon glyphicon-collapse-up',
        title: "Show later years"
    }, " "));
    cdiv.inject(chevron);

    // Create divs for each year, assign all visible
    for (let Y = SY; Y >= calendar_state.FY; Y--) {
        let ydiv = new HTML('div', {
            class: 'sidebar_calendar_year',
            id: 'sidebar_calendar_' + N++
        });
        ydiv.inject(txt(Y));
        ydiv.inject(new HTML('br'));
        for (let i = 0; i < MONTHS_SHORTENED.length; i++) {
            let mon = MONTHS_SHORTENED[i];
            let mdiv = new HTML('div', {
                onclick: 'calendar_click(%u, %u);'.format(Y, i + 1),
                class: 'sidebar_calendar_month'
            }, mon);

            // Mark out-of-bounds segments
            let ym = '%04u-%02u'.format(Y, i+1);
            let c_active = true;
            if (calendar_state.activity && !calendar_state.activity[ym]) {
                c_active = false;
            }
            if ((Y == SY && i >= calendar_state.LM) || (Y == CY && i > CM)) {
                c_active = false;
            }
            if (Y == calendar_state.FY && ((i + 1) < calendar_state.FM)) {
                c_active = false;
            }
            if (!c_active) {
                mdiv.setAttribute("class", "sidebar_calendar_month_nothing");
                mdiv.setAttribute("onclick", "javascript:void(0);");
            } else if (calendar_state.activity && calendar_state.activity[ym]) {
                let count = calendar_state.activity[ym];
                if (count >= 1000) {
                    count = Math.round(count/100.0); // nearest century
                    count = Math.floor(count/10) + "k" + (count % 10); // thousands and remainder
                } else {
                    count = count.toString();
                }
                mdiv.inject(new HTML('span', {title: `${calendar_state.activity[ym].pretty()} emails this month`, class: 'calendar_count'}, count));
            }
            ydiv.inject(mdiv);
        }
        cdiv.inject(ydiv);
    }

    cal.innerHTML = "<p style='text-align: center;'>Archives (%u - %u):</p>".format(calendar_state.FY, SY);
    cal.inject(cdiv);


    chevron = new HTML('div', {
        class: 'sidebar_calendar_chevron'
    });
    chevron.inject(new HTML('span', {
        onclick: 'calendar_scroll(this, 1);',
        style: {
            display: 'none'
        },
        id: 'sidebar_calendar_down',
        class: 'glyphicon glyphicon-collapse-down',
        title: "Show earlier years"
    }, " "));
    cdiv.inject(chevron);

    // If we have > N years, hide the rest
    if (N > current_calendar_size) {
        for (let i = current_calendar_size; i < N; i++) {
            let obj = document.getElementById('sidebar_calendar_' + i);
            if (obj) {
                obj.style.display = "none";
            }
        }
        document.getElementById('sidebar_calendar_down').style.display = 'block';
    }
}

function calendar_scroll(me, direction) {
    let x = direction * current_calendar_size;
    let years = document.getElementsByClassName('sidebar_calendar_year');
    calendar_index = Math.max(Math.min(years.length - x, calendar_index + x), 0);
    if (calendar_index > 0) {
        document.getElementById('sidebar_calendar_up').style.display = 'block';
    } else {
        document.getElementById('sidebar_calendar_up').style.display = 'none';
    }
    if (calendar_index < (years.length - x)) {
        document.getElementById('sidebar_calendar_down').style.display = 'block';
    } else {
        document.getElementById('sidebar_calendar_down').style.display = 'none';
    }


    for (let i = 0; i < years.length; i++) {
        let year = years[i];
        if (typeof(year) == 'object') {
            if (i >= calendar_index && i < (calendar_index + Math.abs(x))) {
                year.style.display = "block";
            } else {
                year.style.display = "none";
            }
        }
    }

}


function calendar_click(year, month) {
    G_current_year = year;
    G_current_month = month;
    let searching = false;
    let q = "";
    let calendar_current_list = G_current_list;
    let calendar_current_domain = G_current_domain;
    if (G_current_json && G_current_json.searchParams) {
        q = G_current_json.searchParams.q || "";
        calendar_current_list = G_current_json.searchParams.list;
        calendar_current_domain = G_current_json.searchParams.domain;
        // Weave in header parameters
        for (let key of Object.keys((G_current_json.searchParams || {}))) {
            if (key.match(/^header_/)) {
                let value = G_current_json.searchParams[key];
                q += `&${key}=${value}`;
            }
        }
    }
    let newhref = "list?%s@%s:%u-%u".format(calendar_current_list, calendar_current_domain, year, month);
    if (q && q.length > 0) newhref += ":" + q;

    if (location.href !== newhref) {
        window.history.pushState({}, null, newhref);
    }
    GET('%sapi/stats.lua?list=%s&domain=%s&d=%u-%u&q=%s'.format(
            G_apiURL, encodeURIComponent(calendar_current_list),
            encodeURIComponent(calendar_current_domain),
            encodeURIComponent(year), encodeURIComponent(month),
            encodeURIComponent(q)
        ),
        renderListView, {
        to: (q && q.length > 0) ? 'search' : '%s@%s'.format(calendar_current_list, calendar_current_domain),
        update_calendar: false,
        search: (q && q.length > 0)
    });
}


/******************************************
 Fetched from source/sidebar-stats.js
******************************************/

async function sidebar_stats(json) {
    let obj = document.getElementById('sidebar_stats');
    if (!obj) {
        return;
    }

    obj.innerHTML = ""; // clear stats bar

    // Subscribe button
    if (prefs && prefs.subscribeLinks) {
        let sb = document.getElementById('sidebar_subscribe');
        if (sb) sb.textContent = "";
        if (sb && json.list && !json.list.match(/\*/)) {
            sb.textContent = "";
            let sublink = json.list.replace("@", "-subscribe@");
            let subbutton = new HTML("a", {href: `mailto:${sublink}`, id: "subscribe_button"}, "Subscribe to list");
            sb.inject(subbutton);
        }
    }

    let wc = document.getElementById('sidebar_wordcloud');
    if (!json.emails || isHash(json.emails) || json.emails.length == 0) {
        obj.innerText = "No emails found...";
        if (wc) {
            wc.innerHTML = "";
        }
        return;
    }

    // Top 10 participants
    obj.inject("Found %u emails by %u authors, divided into %u topics.".format(json.emails.length, json.numparts, json.no_threads));
    obj.inject(new HTML('h5', {}, "Most active authors: "));
    for (let i = 0; i < json.participants.length; i++) {
        if (i >= 5) {
            break;
        }
        let par = json.participants[i];
        if (par.name.length > 24) {
            par.name = par.name.substr(0, 23) + "...";
        }
        if (par.name.length == 0) {
            par.name = par.email;
        }
        let pdiv = new HTML('div', {
            class: "sidebar_stats_participant"
        });
        let pimg = new HTML('img', {
            class: "gravatar_sm",
            src: GRAVATAR_URL.format(par.gravatar)
        })
        pdiv.inject(pimg);
        pdiv.inject(new HTML('b', {}, par.name + ": "));
        pdiv.inject(new HTML('br'));
        pdiv.inject("%u emails sent".format(par.count));
        obj.inject(pdiv);
    }

    // Word cloud, if applicable
    if (wc && json.cloud) {
        wc.innerHTML = "";
        wc.inject(new HTML('h5', {}, "Popular topics:"));
        // word cloud is delayed by 50ms to let the rest render first
        // this is a chrome-specific slowdown we're addressing.
        window.setTimeout(function() {
            wordCloud(json.cloud, 220, 100, wc);
        }, 50);
    }
    if (G_show_stats_sidebar === false) {
        obj.style.display = "none";
        wc.style.display = "none";
    }
}


/******************************************
 Fetched from source/swipe.js
******************************************/

const SWIPE_THRESHOLD = 50; // Need at least this long a swipe before we register it

class SwipeDetector {
    constructor(target = document, threshold = SWIPE_THRESHOLD) {
        this.xDown = null;
        this.yDown = null;
        this.xUp = null;
        this.yUp = null;
        this.threshold = threshold;
        this.target = target;

        console.log("Attaching swipe detector to element ", target);
        target.addEventListener("touchstart", this.touchStart, false);
        target.addEventListener("touchend", this.touchEnd, false);
    }

    setCallback(direction, callback_function ) {
        document.addEventListener(`swipe${direction}`, callback_function);
    }

    touchStart(evt) {
        let firstTouch = (evt.touches || evt.originalEvent.touches)[0];
        this.xDown = firstTouch.clientX;
        this.yDown = firstTouch.clientY;
    }

    touchEnd(evt) {
        if (!this.xDown || !this.yDown) return
        this.xUp = evt.changedTouches[0].clientX;
        this.yUp = evt.changedTouches[0].clientY;

        let xDiff = Math.abs(this.xDown - this.xUp);
        let yDiff = Math.abs(this.yDown - this.yUp);
        let coords = {
            detail: {
                swipestart: {
                    coords: [this.xDown, this.yDown]
                },
                swipestop: {
                    coords: [this.xUp, this.yUp]
                }
            }
        };
        // If the swipe was too short, abort
        if (Math.sqrt(xDiff ** 2 + yDiff ** 2) < this.threshold) return

        // Which direction??
        if (xDiff > yDiff) {
            if (xDiff > 0) {
                document.dispatchEvent(new CustomEvent("swipeleft", coords));
            } else {
                document.dispatchEvent(new CustomEvent("swiperight", coords));
            }
        } else {
            if (yDiff > 0) {
                document.dispatchEvent(new CustomEvent("swipeup", coords));
            } else {
                document.dispatchEvent(new CustomEvent("swipedown", coords));
            }
        }
        this.xDown = null;
        this.yDown = null;
    }

}
