<commit_before>function decodeStructure(object) {
    var { source, head, body } = object;
    if (body instanceof Array) {
        return body.map(function (arr) {
            var o = {};
            arr.map(function (a, cx) {
                var k = head[cx];
                var v = source[k][a];
                o[k] = v;
            });
            return o;
        })
    }
    return [];
}
function encodeStructure(array) {
    if (!array instanceof Array) return;
    var source = {};
    array.map(function (obj) {
        for (var k in obj) {
            var v = obj[k];
            if (v instanceof Object) continue;
            if (!source[k]) {
                source[k] = { inc: 0 };
            }
            var o = source[k];
            var s = JSON.stringify(v);
            if (!(s in o)) o[s] = o.inc++;
        }
    });
    var head = keys(source);
    var body = array.map(function (obj) {
        return head.map(function (k) {
            var v = JSON.stringify(obj[k]);
            return source[k][v];
        });
    });
    head.map(function (key) {
        var valuesmap = source[key];
        delete valuesmap.inc;
        source[key] = keys(valuesmap).map(JSON.parse);
    });
    return {
        source,
        head,
        body
    };
}
const pagePathName = location.pathname;
const instanceDataMap = {};
const cachedLoadingPromise = {};
const formulaters = {
    'string'(formulate, data) {
        if (data instanceof Array) {
            const keys = formulate.split(/(?:\s+|,)/);
            data = data.map(function (item) {
                if (typeof item === 'string') {
                    const res = {};
                    item.split(/(?:\s+|,)/).map((value, cx) => res[keys[cx]] = value);
                    return res;
                }
                return item;
            });
        }
        return data;
    },
    'function'(formulate, data, params) {
        return formulate(data, params);
    }
};
class LoadingArray extends Array {
    totalCount = 0;
    data = [];
    is_errored = null;
    error_message = null;
    is_loading = true;
    is_readonly = null;
    loading_promise = null;
}

function getTranspile(url) {
    var transpile;
    var keys = ['id', 'name', 'icon'];
    url.replace(/#(.*?)$/, function (_, s) {
        s = s.split('&');
        s.forEach(function (p, cx) {
            if (p) {
                var [v, k = keys[cx] || v] = p.split("=").reverse();
                if (!transpile) transpile = {};
                transpile[k] = v;
            }
        });
        return '';
    });
    return transpile;
}

function transpile(src, trans, apiMap) {
    if (src instanceof Array) {
        return src.map(a => transpile(a, trans, apiMap));
    }
    data = extend({}, src && src.querySelector ? null : src);
    for (var k in trans) {
        var v = trans[k];
        if (!(k in data)) {
            if (v in data) {
                data[k] = data[v];
                delete data[v];
            } else {
                data[k] = seek(src, v, apiMap);
            }
        }
    }
    return data;
}
function getParamsFromUrl(url, s = "?") {
    var index = url.indexOf(s);
    if (index < 0 || index >= url.length - 1) return;
    return parseKV(url.slice(index + 1));
}
function getUrlParamsForApi(api, url) {
    var r = /([\s\S]*?)/.source;
    var cap = [];
    var base = api.url.replace(/[\?\#][\s\S]*$/, '')
        .replace(/[\.\*\+\-\[\]\{\}\(\)\\\/\!\<\>\^]/g, '\\$&')
        .replace(/\:\w+/, function (a) {
            cap.push(a.slice(1));
            return r;
        });
    var params = {};
    url = url.replace(/[\?#]*$/g, function (match) {
        match.split(/[&#\?]+/).forEach(function (s) {
            var [k, v] = s.split("=");
            params[k] = v;
        });
        return ''
    }).replace(new RegExp(`^${base}$`, 'ig'), function () {
        var args = arguments;

        cap.forEach(function (a, cx) {
            params[a] = args[cx + 1];
        });
    });
    params = serialize(params);
    return api.id + "?" + params;
}
function seek(data, seeker, apiMap = {}) {
    if (data && data.querySelector) {
        if (!seeker) return data;
        seeker = unescape(seeker);
        var reg = /^(\[\]|,)|(\[\]|,)$/g;
        if (reg.test(seeker)) {
            return [].concat.apply([], data.querySelectorAll(seeker.replace(reg, '')));
        }
        var reg = /[\|\?\!\/]/;
        if (reg.test(seeker)) {
            var [selector, prop] = seeker.split(reg);
        } else {
            var selector = seeker;
        }
        if (selector) {
            data = data.querySelector(selector);
        }
        if (data && prop) {
            var reg1 = /\:/;
            if (reg1.test(prop)) {
                var [prop, next] = prop.split(reg1);
                next = apiMap[next];
            }
            data = data.getAttribute(prop) || data[prop];
            if (isString(data) && /\|/.test(seeker)) {
                data = data.trim();
            }
            if (next) {
                data = getUrlParamsForApi(next, data);
            }
            return data;
        }
        return data;
    }
    if (seeker) {
        seeker.split(".").forEach(function (key) {
            if (data !== null && data !== undefined && key in data) {
                data = data[key];
            }
        });
    }
    return data;
}

function parseConfig(api) {
    // `method url(?key=value(&key=value)*)?(#vid(&vname(&vicon)?)?)? name id(?key1)?(&key3)* comment?`
    var { method, url, id, name, comment } = api;
    var required = [];
    id = id.replace(/\?(.+?)$/, function (m, s) {
        s = s.split('&');
        s.forEach(function (p) {
            if (p) {
                var [k, v = k] = p.split("=");
                if (!required[k]) {
                    required.push(k);
                }
                required[k] = v;
            }
        });
        return '';
    });
    url.replace(/[\?\#][\s\S]*$/, '').replace(/\:\w+/g, function (p) {
        if (!required[p]) {
            required.push(p);
            required[p] = p;
        }
    });
    return {
        method,
        url,
        id,
        name,
        comment,
        required
    };
}

var parseData = function (sourceText) {
    if (/^\s*([\{\[]|"|true|\d|false|null)/.test(sourceText)) {
        return JSON.parse(sourceText);
    }
    var doc = document.implementation.createHTMLDocument("");
    if (/^<!doctype/i.test(sourceText)) {
        doc.documentElement.innerHTML = sourceText;
    } else {
        doc.body.innerHTML = sourceText;
    }
    return doc;
}
function isEmptyParam(param) {
    return param === null || param === undefined || param === '' || typeof param === 'number' && !isFinite(param);
}
function fixApi(api, href) {
    if (!reg.test(api.url)) {
        if (href) {
            if (/^\.([\?\#][\s\S]*)?$/.test(api.url)) {
                api.url = href + api.url.replace(/^\./, "");
            } else {
                api.url = href + api.url;
            }
        }
    }
    api.method = api.method.toLowerCase();

}
const reg = /^(https?\:\/\/|\.?\/)/i;
function createApiMap(data) {
    const apiMap = {};
    var hasOwnProperty = {}.hasOwnProperty;
    var href;
    function checkApi(api) {
        fixApi(api, href);
        if (hasOwnProperty.call(apiMap, api.id)) {
            const lastApi = apiMap[api.id];
            console.warn(`多次设置的id相同的api:%c${api.id}`, 'color:red');
            console.log(`[${api.name}](${lastApi.method} ${api.url})\r\n 被 [${api.name}](${lastApi.method} ${lastApi.url}) 覆盖`);
        }
        apiMap[api.id] = api;
        return api;
    }
    var items1 = data;
    for (var key in items1) {
        var [base] = key.split(/\s+/).filter(a => reg.test(a));
        if (!base) continue;
        href = /(https?\:)?|\.?\//i.test(base) ? base : '';
        var item1 = items1[key];
        var items = Object.keys(item1).map(function (k1) {
            return k1 + " " + item1[k1];
        });
        formulaters.string('id method url name comment', items).map(parseConfig).map(checkApi);
    }
    return apiMap;
}
var _configfileurl;
var configPormise;
var privates = {
    loadAfterConfig(serviceId, params) {
        return this.getApi(serviceId).then((api) => {
            if (/\?/.test(serviceId)) {
                params = Object.assign({}, getParamsFromUrl(serviceId), params);
                serviceId = serviceId.replace(/\?[\s\S]*$/, '');
            }
            if (/\:/.test(serviceId)) {
                var params1 = Object.assign({}, params);
                var temp = getParamsFromUrl(serviceId, ":");
                for (var k in temp) {
                    var v = temp[k];
                    if (v in params) {
                        params1[k] = params[v];
                    }
                    if (!(v in temp)) {
                        delete params1[v];
                    }
                }
            }
            return this.fromApi(api, params);
        });
    },
    fromApi(api, params) {
        let url = api.url;
        if (api.reauired) {
            var lacks = api.reauired;
            if (!params) {
                lacks = lacks.filter(a => isEmptyParam(params[a]));
            }
            if (lacks.length) {
                console.log(`跳过了缺少参数的请求:${api.uid} ${api.name} ${api.url}\r\n缺少参数：${lacks.join(', ')}`);
                return Promise.resolve();
            }
        }
        return this.loadIgnoreConfig(api.method, url, params, api.root);
    },
    getApi(serviceId) {
        serviceId = serviceId.replace(/[\?\:][\s\S]*$/, "");
        return this.getConfigPromise().then((apiMap) => {
            const api = apiMap[serviceId];
            if (!api) { throw new Error(`没有找到对应的接口 id ${serviceId}.`); }
            return Object.assign({}, api, { root: apiMap });
        });
    },
    loadIgnoreConfig(method, url, params, apiMap) {
        var spliterIndex = /[\:\|\/\~\!\?]/.exec(method);
        if (spliterIndex) spliterIndex = spliterIndex.index;
        else spliterIndex = method.length;
        var realmethod = method.slice(0, spliterIndex).toLowerCase();
        var uri = url.replace(/#[\s\S]*$/, "");
        params = extend({}, params);
        if (/\?/.test(uri)) var search = uri.replace(/^[\s\S]*?\?/, "");
        var rest = [];
        baseuri = uri.replace(/\?[\s\S]*$/, "").replace(/\:\w+/, function (d) {
            d = d.slice(1);
            rest.push(d);
            return params[d] || '';
        });
        var hasOwnProperty = {}.hasOwnProperty;
        if (search) {
            var searchParams = parseKV(search);
            for (var k in searchParams) {
                if (hasOwnProperty.call(searchParams, k) && hasOwnProperty.call(params, k)) {
                    searchParams[k] = params[k];
                    rest.push(k);
                }
            }
            search = serialize(searchParams);
            uri = baseuri + "?" + search;
        } else {
            uri = baseuri;
        }
        rest.forEach(k => delete params[k]);
        var id = realmethod + " " + baseuri;
        var promise = cachedLoadingPromise[id];
        var temp = JSON.stringify(params);
        var currentTime = +new Date;
        if (!promise || currentTime - promise.time > 60 || temp !== promise.params || promise.search !== search) {
            var promise = new Promise(function (ok, oh) {
                cross(realmethod, uri).send(params).done(e => {
                    ok(e.response || e.responseText)
                }).error(oh);
            });
            promise.search = search;
            promise.params = temp;
            promise.time = currentTime;
            cachedLoadingPromise[id] = promise;
        }
        return promise.then(function (response) {
            return transpile(seek(parseData(response), method.slice(spliterIndex + 1)), getTranspile(url), apiMap);
        });
    },

    getConfigPromise() {
        if (!configPormise) {
            if (!_configfileurl) {
                throw new Error("没有指定配置文件的路径，请使用data.loadConfig加载配置");
            }
            configPormise = this.loadIgnoreConfig('get', _configfileurl)
            .then(createApiMap);
        }
        return configPormise;
    },

};
var data = {
    decodeStructure,
    encodeStructure,
    loadConfig(defaultConfigFile) {
        if (defaultConfigFile) {
            _configfileurl = defaultConfigFile;
            configPormise = null;
        }
        return privates.getConfigPromise();
    },
    enrich(config = configPormise, userAgent) {
        if (!config) return;
        if (isString(config)) {
            config = privates.loadIgnoreConfig('get', url).then(createApiMap);
        } else if (!(config instanceof Promise)) {
            if (!(config instanceof Object)) return;
            config = Promise.resolve(config);
        }
        return enrich({
            from(id, params) {
                return config.then(function (data) {
                    var a = data[id];
                    return privates.fromApi(a, params);
                });
            },
            queue(ids, params, cb) {
                ids = ids.slice(0);
                config.then(function (res) {
                    return new Promise(function (ok) {
                        var run = function (res) {
                            if (!ids.length) return ok(res);
                            var id = ids.pop();
                            a = data[id];
                            privates.fromApi(a, res).then(run);
                        };
                        run(params);
                    });

                })
            },
        });
    },
    fromURL(url) {
        privates.loadIgnoreConfig('get', url).then((data) => {
            this.setInstance(url, data);
        });
        return this.getInstance(url);
    },
    asyncInstance(id, params, parser) {
        var data = this.getInstance(id);
        data.loading_promise = privates.loadAfterConfig(id, params).then((data) => {
            this.setInstance(id, data);
            return data;
        });
        return data;
    },
    /**
     * 返回一个延长生命周期的内存对象
     * @param instanceId 数据唯一标识
     * @param onlyFromLocalStorage 是否只从localStorage加载
     */
    getInstance(instanceId, onlyFromLocalStorage = false) {
        if (!instanceDataMap[instanceId]) {
            const data = instanceDataMap[instanceId] = new LoadingArray;
            const storageId = instanceId + pagePathName;
            extend(data, JSON.parse(localStorage.getItem(storageId)));
            if (!onlyFromLocalStorage) {
                extend(data, JSON.parse(sessionStorage.getItem(storageId)));
            }
            data.is_loading = false;
        }
        return instanceDataMap[instanceId];

    },
    /**
     * 设置一个延长生命周期的数据对象
     * @param {*} instanceId 数据唯一标识
     * @param {*} data 数据本体
     * @param {boolean|number} [rememberWithStorage=0] 是否存储到localStorage，默认为否，只存储到sessionStorage
     */
    setInstance(instanceId, data, rememberWithStorage = 0) {
        const instance = this.getInstance(instanceId);
        this.rebuildInstance(instance, data);
        const storageId = instanceId + pagePathName;
        if (rememberWithStorage !== false) {
            sessionStorage.setItem(storageId, JSON.stringify(data));
        }
        if (rememberWithStorage) {
            localStorage.setItem(storageId, JSON.stringify(data));
        }
        return instanceDataMap[instanceId];
    },
    rebuildInstance(instance, data, old = instance) {
        if (instance === data) { return; }
        instance.splice(0, instance.length);
        Object.keys(old).forEach(function (k) {
            if (instance[k] === old[k]) {
                delete instance[k];
            }
        });
        extend(instance, data);
    }
};<commit_msg>添加is_loading状态<commit_after>function decodeStructure(object) {
    var { source, head, body } = object;
    if (body instanceof Array) {
        return body.map(function (arr) {
            var o = {};
            arr.map(function (a, cx) {
                var k = head[cx];
                var v = source[k][a];
                o[k] = v;
            });
            return o;
        })
    }
    return [];
}
function encodeStructure(array) {
    if (!array instanceof Array) return;
    var source = {};
    array.map(function (obj) {
        for (var k in obj) {
            var v = obj[k];
            if (v instanceof Object) continue;
            if (!source[k]) {
                source[k] = { inc: 0 };
            }
            var o = source[k];
            var s = JSON.stringify(v);
            if (!(s in o)) o[s] = o.inc++;
        }
    });
    var head = keys(source);
    var body = array.map(function (obj) {
        return head.map(function (k) {
            var v = JSON.stringify(obj[k]);
            return source[k][v];
        });
    });
    head.map(function (key) {
        var valuesmap = source[key];
        delete valuesmap.inc;
        source[key] = keys(valuesmap).map(JSON.parse);
    });
    return {
        source,
        head,
        body
    };
}
const pagePathName = location.pathname;
const instanceDataMap = {};
const cachedLoadingPromise = {};
const formulaters = {
    'string'(formulate, data) {
        if (data instanceof Array) {
            const keys = formulate.split(/(?:\s+|,)/);
            data = data.map(function (item) {
                if (typeof item === 'string') {
                    const res = {};
                    item.split(/(?:\s+|,)/).map((value, cx) => res[keys[cx]] = value);
                    return res;
                }
                return item;
            });
        }
        return data;
    },
    'function'(formulate, data, params) {
        return formulate(data, params);
    }
};
class LoadingArray extends Array {
    totalCount = 0;
    data = [];
    is_errored = null;
    error_message = null;
    is_loading = true;
    is_readonly = null;
    loading_promise = null;
}
function getTranspile(url) {
    var transpile;
    var keys = ['id', 'name', 'icon'];
    url.replace(/#(.*?)$/, function (_, s) {
        s = s.split('&');
        s.forEach(function (p, cx) {
            if (p) {
                var [v, k = keys[cx] || v] = p.split("=").reverse();
                if (!transpile) transpile = {};
                transpile[k] = v;
            }
        });
        return '';
    });
    return transpile;
}

function transpile(src, trans, apiMap) {
    if (src instanceof Array) {
        return src.map(a => transpile(a, trans, apiMap));
    }
    data = extend({}, src && src.querySelector ? null : src);
    for (var k in trans) {
        var v = trans[k];
        if (!(k in data)) {
            if (v in data) {
                data[k] = data[v];
                delete data[v];
            } else {
                data[k] = seek(src, v, apiMap);
            }
        }
    }
    return data;
}
function getParamsFromUrl(url, s = "?") {
    var index = url.indexOf(s);
    if (index < 0 || index >= url.length - 1) return;
    return parseKV(url.slice(index + 1));
}
function getUrlParamsForApi(api, url) {
    var r = /([\s\S]*?)/.source;
    var cap = [];
    var base = api.url.replace(/[\?\#][\s\S]*$/, '')
        .replace(/[\.\*\+\-\[\]\{\}\(\)\\\/\!\<\>\^]/g, '\\$&')
        .replace(/\:\w+/, function (a) {
            cap.push(a.slice(1));
            return r;
        });
    var params = {};
    url = url.replace(/[\?#]*$/g, function (match) {
        match.split(/[&#\?]+/).forEach(function (s) {
            var [k, v] = s.split("=");
            params[k] = v;
        });
        return ''
    }).replace(new RegExp(`^${base}$`, 'ig'), function () {
        var args = arguments;

        cap.forEach(function (a, cx) {
            params[a] = args[cx + 1];
        });
    });
    params = serialize(params);
    return api.id + "?" + params;
}
function seek(data, seeker, apiMap = {}) {
    if (data && data.querySelector) {
        if (!seeker) return data;
        seeker = unescape(seeker);
        var reg = /^(\[\]|,)|(\[\]|,)$/g;
        if (reg.test(seeker)) {
            return [].concat.apply([], data.querySelectorAll(seeker.replace(reg, '')));
        }
        var reg = /[\|\?\!\/]/;
        if (reg.test(seeker)) {
            var [selector, prop] = seeker.split(reg);
        } else {
            var selector = seeker;
        }
        if (selector) {
            data = data.querySelector(selector);
        }
        if (data && prop) {
            var reg1 = /\:/;
            if (reg1.test(prop)) {
                var [prop, next] = prop.split(reg1);
                next = apiMap[next];
            }
            data = data.getAttribute(prop) || data[prop];
            if (isString(data) && /\|/.test(seeker)) {
                data = data.trim();
            }
            if (next) {
                data = getUrlParamsForApi(next, data);
            }
            return data;
        }
        return data;
    }
    if (seeker) {
        seeker.split(".").forEach(function (key) {
            if (data !== null && data !== undefined && key in data) {
                data = data[key];
            }
        });
    }
    return data;
}

function parseConfig(api) {
    // `method url(?key=value(&key=value)*)?(#vid(&vname(&vicon)?)?)? name id(?key1)?(&key3)* comment?`
    var { method, url, id, name, comment } = api;
    var required = [];
    id = id.replace(/\?(.+?)$/, function (m, s) {
        s = s.split('&');
        s.forEach(function (p) {
            if (p) {
                var [k, v = k] = p.split("=");
                if (!required[k]) {
                    required.push(k);
                }
                required[k] = v;
            }
        });
        return '';
    });
    url.replace(/[\?\#][\s\S]*$/, '').replace(/\:\w+/g, function (p) {
        if (!required[p]) {
            required.push(p);
            required[p] = p;
        }
    });
    return {
        method,
        url,
        id,
        name,
        comment,
        required
    };
}

var parseData = function (sourceText) {
    if (/^\s*([\{\[]|"|true|\d|false|null)/.test(sourceText)) {
        return JSON.parse(sourceText);
    }
    var doc = document.implementation.createHTMLDocument("");
    if (/^<!doctype/i.test(sourceText)) {
        doc.documentElement.innerHTML = sourceText;
    } else {
        doc.body.innerHTML = sourceText;
    }
    return doc;
}
function isEmptyParam(param) {
    return param === null || param === undefined || param === '' || typeof param === 'number' && !isFinite(param);
}
function fixApi(api, href) {
    if (!reg.test(api.url)) {
        if (href) {
            if (/^\.([\?\#][\s\S]*)?$/.test(api.url)) {
                api.url = href + api.url.replace(/^\./, "");
            } else {
                api.url = href + api.url;
            }
        }
    }
    api.method = api.method.toLowerCase();

}
const reg = /^(https?\:\/\/|\.?\/)/i;
function createApiMap(data) {
    const apiMap = {};
    var hasOwnProperty = {}.hasOwnProperty;
    var href;
    function checkApi(api) {
        fixApi(api, href);
        if (hasOwnProperty.call(apiMap, api.id)) {
            const lastApi = apiMap[api.id];
            console.warn(`多次设置的id相同的api:%c${api.id}`, 'color:red');
            console.log(`[${api.name}](${lastApi.method} ${api.url})\r\n 被 [${api.name}](${lastApi.method} ${lastApi.url}) 覆盖`);
        }
        apiMap[api.id] = api;
        return api;
    }
    var items1 = data;
    for (var key in items1) {
        var [base] = key.split(/\s+/).filter(a => reg.test(a));
        if (!base) continue;
        href = /(https?\:)?|\.?\//i.test(base) ? base : '';
        var item1 = items1[key];
        var items = Object.keys(item1).map(function (k1) {
            return k1 + " " + item1[k1];
        });
        formulaters.string('id method url name comment', items).map(parseConfig).map(checkApi);
    }
    return apiMap;
}
var _configfileurl;
var configPormise;
var privates = {
    loadAfterConfig(serviceId, params) {
        return this.getApi(serviceId).then((api) => {
            if (/\?/.test(serviceId)) {
                params = Object.assign({}, getParamsFromUrl(serviceId), params);
                serviceId = serviceId.replace(/\?[\s\S]*$/, '');
            }
            if (/\:/.test(serviceId)) {
                var params1 = Object.assign({}, params);
                var temp = getParamsFromUrl(serviceId, ":");
                for (var k in temp) {
                    var v = temp[k];
                    if (v in params) {
                        params1[k] = params[v];
                    }
                    if (!(v in temp)) {
                        delete params1[v];
                    }
                }
            }
            return this.fromApi(api, params);
        });
    },
    fromApi(api, params) {
        let url = api.url;
        if (api.reauired) {
            var lacks = api.reauired;
            if (!params) {
                lacks = lacks.filter(a => isEmptyParam(params[a]));
            }
            if (lacks.length) {
                console.log(`跳过了缺少参数的请求:${api.uid} ${api.name} ${api.url}\r\n缺少参数：${lacks.join(', ')}`);
                return Promise.resolve();
            }
        }
        return this.loadIgnoreConfig(api.method, url, params, api.root);
    },
    getApi(serviceId) {
        serviceId = serviceId.replace(/[\?\:][\s\S]*$/, "");
        return this.getConfigPromise().then((apiMap) => {
            const api = apiMap[serviceId];
            if (!api) { throw new Error(`没有找到对应的接口 id ${serviceId}.`); }
            return Object.assign({}, api, { root: apiMap });
        });
    },
    loadIgnoreConfig(method, url, params, apiMap) {
        var spliterIndex = /[\:\|\/\~\!\?]/.exec(method);
        if (spliterIndex) spliterIndex = spliterIndex.index;
        else spliterIndex = method.length;
        var realmethod = method.slice(0, spliterIndex).toLowerCase();
        var uri = url.replace(/#[\s\S]*$/, "");
        params = extend({}, params);
        if (/\?/.test(uri)) var search = uri.replace(/^[\s\S]*?\?/, "");
        var rest = [];
        baseuri = uri.replace(/\?[\s\S]*$/, "").replace(/\:\w+/, function (d) {
            d = d.slice(1);
            rest.push(d);
            return params[d] || '';
        });
        var hasOwnProperty = {}.hasOwnProperty;
        if (search) {
            var searchParams = parseKV(search);
            for (var k in searchParams) {
                if (hasOwnProperty.call(searchParams, k) && hasOwnProperty.call(params, k)) {
                    searchParams[k] = params[k];
                    rest.push(k);
                }
            }
            search = serialize(searchParams);
            uri = baseuri + "?" + search;
        } else {
            uri = baseuri;
        }
        rest.forEach(k => delete params[k]);
        var id = realmethod + " " + baseuri;
        var promise = cachedLoadingPromise[id];
        var temp = JSON.stringify(params);
        var currentTime = +new Date;
        if (!promise || currentTime - promise.time > 60 || temp !== promise.params || promise.search !== search) {
            var promise = new Promise(function (ok, oh) {
                cross(realmethod, uri).send(params).done(e => {
                    ok(e.response || e.responseText)
                }).error(oh);
            });
            promise.search = search;
            promise.params = temp;
            promise.time = currentTime;
            cachedLoadingPromise[id] = promise;
        }
        return promise.then(function (response) {
            return transpile(seek(parseData(response), method.slice(spliterIndex + 1)), getTranspile(url), apiMap);
        });
    },

    getConfigPromise() {
        if (!configPormise) {
            if (!_configfileurl) {
                throw new Error("没有指定配置文件的路径，请使用data.loadConfig加载配置");
            }
            configPormise = this.loadIgnoreConfig('get', _configfileurl)
                .then(createApiMap);
        }
        return configPormise;
    },

};
var data = {
    decodeStructure,
    encodeStructure,
    loadConfig(defaultConfigFile) {
        if (defaultConfigFile) {
            _configfileurl = defaultConfigFile;
            configPormise = null;
        }
        return privates.getConfigPromise();
    },
    enrich(config = configPormise, userAgent) {
        if (!config) return;
        if (isString(config)) {
            config = privates.loadIgnoreConfig('get', url).then(createApiMap);
        } else if (!(config instanceof Promise)) {
            if (!(config instanceof Object)) return;
            config = Promise.resolve(config);
        }
        return enrich({
            from(id, params) {
                return config.then(function (data) {
                    var a = data[id];
                    return privates.fromApi(a, params);
                });
            },
            queue(ids, params, cb) {
                ids = ids.slice(0);
                config.then(function (res) {
                    return new Promise(function (ok) {
                        var run = function (res) {
                            if (!ids.length) return ok(res);
                            var id = ids.pop();
                            a = data[id];
                            privates.fromApi(a, res).then(run);
                        };
                        run(params);
                    });

                })
            },
        });
    },
    fromURL(url) {
        privates.loadIgnoreConfig('get', url).then((data) => {
            this.setInstance(url, data);
        });
        return this.getInstance(url);
    },
    asyncInstance(id, params, parser) {
        var data = this.getInstance(id);
        data.is_loading = true;
        data.loading_promise = privates.loadAfterConfig(id, params).then((data) => {
            this.setInstance(id, data);
            return data;
        });
        return data;
    },
    /**
     * 返回一个延长生命周期的内存对象
     * @param instanceId 数据唯一标识
     * @param onlyFromLocalStorage 是否只从localStorage加载
     */
    getInstance(instanceId, onlyFromLocalStorage = false) {
        if (!instanceDataMap[instanceId]) {
            const data = instanceDataMap[instanceId] = new LoadingArray;
            const storageId = instanceId + pagePathName;
            extend(data, JSON.parse(localStorage.getItem(storageId)));
            if (!onlyFromLocalStorage) {
                extend(data, JSON.parse(sessionStorage.getItem(storageId)));
            }
            data.is_loading = false;
        }
        return instanceDataMap[instanceId];

    },
    /**
     * 设置一个延长生命周期的数据对象
     * @param {*} instanceId 数据唯一标识
     * @param {*} data 数据本体
     * @param {boolean|number} [rememberWithStorage=0] 是否存储到localStorage，默认为否，只存储到sessionStorage
     */
    setInstance(instanceId, data, rememberWithStorage = 0) {
        const instance = this.getInstance(instanceId);
        this.rebuildInstance(instance, data);
        const storageId = instanceId + pagePathName;
        if (rememberWithStorage !== false) {
            sessionStorage.setItem(storageId, JSON.stringify(data));
        }
        if (rememberWithStorage) {
            localStorage.setItem(storageId, JSON.stringify(data));
        }
        return instanceDataMap[instanceId];
    },
    rebuildInstance(instance, data, old = instance) {
        if (instance === data) { return; }
        instance.splice(0, instance.length);
        Object.keys(old).forEach(function (k) {
            if (instance[k] === old[k]) {
                delete instance[k];
            }
        });
        extend(instance, data);
    }
};<|endoftext|>


<commit_before>"use strict";
var window = this;
var {
    Object,
    parseInt,
    XMLHttpRequest,
    ActiveXObject,
    Error,
    Function,
    Array,
    Promise,
    setTimeout,
    clearTimeout,
    Date,
    Math,
    localStorage,
    navigator,
    document,
    top
} = window;

//去除外层广告
if (window.PREVENT_FRAMEWORK_MODE !== false) {
    var message = '请关闭后重新打开..';
    try {
        if (top && top !== window && !/MSIE/.test(navigator.userAgent)) {
            top.location.href = window.location.href;
        }
    } catch (e) {
        document.write(message);
        top.location.reload();
        throw message;
    }
}
// 检查性能
var isBadDevice;
{
    let saved_time = new Date;
    let inc = 0;
    try {
        let test = function () {
            inc++;
            document.createElement("div");
            test();
        };
        test();
    } catch (e) {
        isBadDevice = (new Date - saved_time) / inc > 0.002;
    }
};
modules.IS_BAD_DEVICE = isBadDevice;
// 适配大小屏
var devicePixelRatio = window.devicePixelRatio || 1;
// if (isBadDevice) devicePixelRatio = 1;
var renderPixelRatio = devicePixelRatio > 1 && window.innerWidth > 360 && window.innerHeight > 360 ? .86 : .75;
if (document.querySelector && devicePixelRatio > 1 && /Linux/.test(navigator.platform)) {
    let ratio = +(1000000 / devicePixelRatio + .5 | 0) / 1000000;
    document.querySelector("meta[name=viewport]").setAttribute("content", `width=device-width,target-densitydpi=device-dpi,user-scalable=no,initial-scale=${ratio},maximum-scale=${ratio}`);
    renderPixelRatio *= devicePixelRatio;
    document.documentElement.style.fontSize = `${16 * renderPixelRatio}pt`;
}
var loaddingTree = {};
var requestTree = {};
var responseTree = {};
var versionTree = {};
var forceRequest = {};
modules.MOVElOCK_DELTA = 3 * renderPixelRatio;

var retry = function (url, count) {
    setTimeout(function () {
        load(url, --count);
    }, parseInt(Math.random()) * 200);
    return count;
};
var XHR = function () {
    return new (XMLHttpRequest || ActiveXObject)("Microsoft.XMLHTTP");
};
var load = function (name, count = 150) {
    var url;
    var version = versionTree[url] || (+new Date).toString(32);
    switch (name.charAt(0)) {
        case "/":
            url = "page" + name;
            break;
        case "_":
            url = "aapi/" + name.slice(1).replace(/([A-Z])/g, "/$1").toLowerCase();
            break;
        case ".":
            url = "ccon/" + name.slice(1);
            break;
        default:
            url = "comm/" + name;
    }
    var xhr = XHR();
    xhr.open("POST", url);
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            var status = xhr.status;
            if (status === 0 || status === 200 || status === 304) {
                responseTree[name] = xhr.responseText;
                flush(name);
            } else if (count <= 0) {
                throw new Error("加载" + name + "出错！");
            } else {
                count = retry(name, count || 0);
            }
        }
    };
    xhr.send(version);
};
var flush_to_storage_timer = 0,
    responseTree_storageKey = "zimoliAutoSavedResponseTree";
var saveResponseTreeToStorage = function () {
    var responseTextArray = [];
    for (var k in responseTree) {
        if (versionTree[k]) responseTextArray.push(
            k + "：" + versionTree[k] + "：" + responseTree[k]
        );
    }
    var data = responseTextArray.join("，");
    localStorage && localStorage.setItem(responseTree_storageKey, data);
};
var loadResponseTreeFromStorage = function () {
    function table(sign) {
        var c, table = new Array(256);
        for (var n = 0; n < 256; n++) {
            c = n;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            table[n] = c;
        }
        return table;
    }

    function crc(bstr, seed) {
        var C = seed ^ -1,
            L = bstr.length - 1;
        for (var i = 0; i < L;) {
            C = C >>> 8 ^ T[(C ^ bstr.charCodeAt(i++, 36)) & 0xFF];
            C = C >>> 8 ^ T[(C ^ bstr.charCodeAt(i++, 36)) & 0xFF];
        }
        if (i === L) C = C >>> 8 ^ T[(C ^ bstr.charCodeAt(i)) & 0xFF];
        return C ^ -1;
    }

    var sign = parseInt("-52l3vk", 36);
    var T = table(sign);
    var load = function (name) {
        var data = localStorage.getItem(responseTree_storageKey);
        if (!data) return;
        var responseTextArray = data.split("，");
        for (var cx = 0, dx = responseTextArray.length; cx < dx; cx++) {
            var kv = responseTextArray[cx].split("：");
            var [responseName, version, responseText] = kv;
            preLoadVersionTree[responseName] = version;
            preLoadResponseTree[responseName] = responseText;
        }
    };
    var preLoadResponseTree = {};
    var preLoadVersionTree = {};
    if (localStorage) load();
    else init("localStorage", function (_localStorage) {
        localStorage = _localStorage;
        load();
    });
    preLoad = function (responseName) {
        if (responseTree[responseName]) return;
        var version = preLoadVersionTree[responseName]
        if (!version) return;
        var responseText = preLoadResponseTree[responseName]
        var sum = crc(responseText).toString(36);
        if (sum + version.slice(sum.length) === versionTree[responseName])
            responseTree[responseName] = responseText;
        // else window.console.log(responseName, sum, version, versionTree[responseName]);
    };
};
var preLoad = function () { };
var flush = function (url) {
    clearTimeout(flush_to_storage_timer);
    var thens = loaddingTree[url];
    delete loaddingTree[url];
    for (var k in thens) {
        var then = thens[k];
        if (then instanceof Function) {
            then(responseTree[url], url);
        }
    }
    flush_to_storage_timer = setTimeout(saveResponseTreeToStorage, 260);
};
var get = function (url, then) {
    preLoad(url);
    if (responseTree[url]) {
        then(responseTree[url], url);
    } else if (loaddingTree[url]) {
        loaddingTree[url].push(then);
    } else {
        loaddingTree[url] = [then];
        load(url);
    }
};
modules.start_time = +new Date;

function modules() { }
modules.modules = modules;
var penddingTree = {};
var executer = function (text, name, then, prebuild) {
    var functionArgs, functionBody;
    //依赖项名称部分的长度限制为36*36*18=23328
    var doublecount = parseInt(text.slice(0, 3), 36);
    if (doublecount >> 1 << 1 === doublecount) {
        var dependencesCount = doublecount >> 1;
        var dependenceNamesOffset = 3 + dependencesCount;
        var dependenceNames = text.slice(3, dependenceNamesOffset);
        functionArgs = dependenceNames ? dependenceNames.split(",") : [];
        functionBody = text.slice(dependenceNamesOffset);
    } else {
        functionArgs = [];
        functionBody = text;
    }
    functionBody = functionBody.replace(/^(?:\s*(["'])user? strict\1;?[\r\n]*)?/i, "\"use strict\";\r\n");
    functionBody = functionBody.replace(/((?:\d*\.)?\d+)px/ig, (m, d) => (d !== '1' ? d * renderPixelRatio + "pt" : renderPixelRatio > 1 ? ".75pt" : .75 / devicePixelRatio + "pt"));
    if (!functionArgs.length) {
        if (modules[name] && !prebuild) return then(modules[name]);
        else if (prebuild && name in prebuild) return then(prebuild[name]);
        try {
            var exports = Function.call(window, functionBody).call(window);
        } catch (e) {
            throw new Error(`[${name}] ${e}`);
        }
        modules[name] = exports;
        then(exports);
    } else init(functionArgs.slice(0, functionArgs.length >> 1), function (args) {
        // 如果构造该对象没有依赖预置树中的对象，保存这个对象到全局单例对象，否则保存这个对象到预置树
        if (modules[name]) return then(modules[name]);
        else if (prebuild && name in prebuild) return then(prebuild[name]);
        var prevent_save = 0;
        var argslength = functionArgs.length >> 1;
        prebuild && [].map.call(functionArgs.slice(0, argslength), k => k in prebuild && prevent_save++);
        try {
            var allArgumentsNames = functionArgs.slice(argslength);
            var exports = Function.apply(window, allArgumentsNames.concat(functionBody)).apply(window, args.concat([allArgumentsNames]));
        } catch (e) {
            throw new Error(`[${name}] ${e}`);
        }
        if (prevent_save) prebuild[name] = exports;
        else modules[name] = exports;
        then(exports);
    }, prebuild);
};
var noop = function (text, name, then) {
    then(text);
};
var broadcast = function (text, name) {
    var adapter;
    switch (name.charAt(0)) {
        case ".":
            adapter = noop;
            break;
        default:
            adapter = executer;
    }
    var thens = penddingTree[name];
    delete penddingTree[name];
    for (var cx = 0, dx = thens.length; cx < dx; cx++) {
        var [then, prebuild] = thens[cx];
        adapter(text, name, then, prebuild);
    }
};
var init = function (name, then, prebuild) {
    if (name instanceof Array) {
        return Promise.all(name.map(function (argName) {
            if (prebuild && argName in prebuild) {
                return prebuild[argName];
            }
            return new Promise(function (ok, oh) {
                init(argName, ok, prebuild);
            });
        })).then(function (args) {
            (then instanceof Function) && then(args);
        }).catch(function (e) {
            window.console.error(e);
        });
    }
    if (modules[name]) {
        return then(modules[name]);
    }
    if (!forceRequest[name] && window[name]) {
        modules[name] = window[name];
        return then(modules[name]);
    }
    if (penddingTree[name]) {
        return penddingTree[name].push([then, prebuild]);
    }
    penddingTree[name] = [
        [then, prebuild]
    ];
    // return
    get(name, broadcast);
};
modules.init = init;
var requires_count = 1;
var hook = function (requires_count) {
    if (requires_count === 0) {
        "alert confirm innerWidth innerHeight".split(/\s+/).map(removeGlobalProperty);
        loadResponseTreeFromStorage();
        if ("ontouchstart" in window) {
            init("fastclick", function (fastclick) {
                new fastclick(document.body);
            });
        }
        init("zimoli", function (zimoli) {
            zimoli();
            modules.hook_time = +new Date;
        });
    }
};
var initIfNotDefined = function (defined, path, onload) {
    if (defined === void 0) requires_count++ , init(path, a => onload(a, hook(--requires_count)));
}
initIfNotDefined(Promise, "promise", promise => Promise = promise);
initIfNotDefined([].map, "[].map", map => map);
var removeGlobalProperty = function (property) {
    forceRequest[property] = true;
};
var onload = function () {
    window.onload = null;
    hook(--requires_count);
};
modules.put = function (name, module) {
    modules[name] = module;
};
modules.versionTree = versionTree;
modules.responseTree = responseTree;
modules.loaddingTree = loaddingTree;
modules.setGetMethod = function (_get) {
    get = _get;
};
modules.load = load;
modules.XHR = XHR;
modules.renderPixelRatio = renderPixelRatio;
if (document.body) onload();
else window.onload = onload;<commit_msg>支持修改像素编译器<commit_after>"use strict";
var window = this;
var {
    Object,
    parseInt,
    XMLHttpRequest,
    ActiveXObject,
    Error,
    Function,
    Array,
    Promise,
    setTimeout,
    clearTimeout,
    Date,
    Math,
    localStorage,
    navigator,
    document,
    top,
    PREVENT_FRAMEWORK_MODE,
    pixelDecoder // = d => d / 16 + "rem"
} = window;

//去除外层广告
if (PREVENT_FRAMEWORK_MODE !== false) {
    var message = '请关闭后重新打开..';
    try {
        if (top && top !== window && !/MSIE/.test(navigator.userAgent)) {
            top.location.href = window.location.href;
        }
    } catch (e) {
        document.write(message);
        top.location.reload();
        throw message;
    }
}
// 检查性能
var isBadDevice;
{
    let saved_time = new Date;
    let inc = 0;
    try {
        let test = function () {
            inc++;
            document.createElement("div");
            test();
        };
        test();
    } catch (e) {
        isBadDevice = (new Date - saved_time) / inc > 0.002;
    }
};
modules.IS_BAD_DEVICE = isBadDevice;
// 适配大小屏
var devicePixelRatio = window.devicePixelRatio || 1;
// if (isBadDevice) devicePixelRatio = 1;
var renderPixelRatio = devicePixelRatio > 1 && window.innerWidth > 360 && window.innerHeight > 360 ? .86 : .75;
if (document.querySelector && devicePixelRatio > 1 && /Linux/.test(navigator.platform)) {
    let ratio = +(1000000 / devicePixelRatio + .5 | 0) / 1000000;
    document.querySelector("meta[name=viewport]").setAttribute("content", `width=device-width,target-densitydpi=device-dpi,user-scalable=no,initial-scale=${ratio},maximum-scale=${ratio}`);
    renderPixelRatio *= devicePixelRatio;
    document.documentElement.style.fontSize = `${16 * renderPixelRatio}pt`;
}
var loaddingTree = {};
var requestTree = {};
var responseTree = {};
var versionTree = {};
var forceRequest = {};
modules.MOVElOCK_DELTA = 3 * renderPixelRatio;

var retry = function (url, count) {
    setTimeout(function () {
        load(url, --count);
    }, parseInt(Math.random()) * 200);
    return count;
};
var XHR = function () {
    return new (XMLHttpRequest || ActiveXObject)("Microsoft.XMLHTTP");
};
var load = function (name, count = 150) {
    var url;
    var version = versionTree[url] || (+new Date).toString(32);
    switch (name.charAt(0)) {
        case "/":
            url = "page" + name;
            break;
        case "_":
            url = "aapi/" + name.slice(1).replace(/([A-Z])/g, "/$1").toLowerCase();
            break;
        case ".":
            url = "ccon/" + name.slice(1);
            break;
        default:
            url = "comm/" + name;
    }
    var xhr = XHR();
    xhr.open("POST", url);
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            var status = xhr.status;
            if (status === 0 || status === 200 || status === 304) {
                responseTree[name] = xhr.responseText;
                flush(name);
            } else if (count <= 0) {
                throw new Error("加载" + name + "出错！");
            } else {
                count = retry(name, count || 0);
            }
        }
    };
    xhr.send(version);
};
var flush_to_storage_timer = 0,
    responseTree_storageKey = "zimoliAutoSavedResponseTree";
var saveResponseTreeToStorage = function () {
    var responseTextArray = [];
    for (var k in responseTree) {
        if (versionTree[k]) responseTextArray.push(
            k + "：" + versionTree[k] + "：" + responseTree[k]
        );
    }
    var data = responseTextArray.join("，");
    localStorage && localStorage.setItem(responseTree_storageKey, data);
};
var loadResponseTreeFromStorage = function () {
    function table(sign) {
        var c, table = new Array(256);
        for (var n = 0; n < 256; n++) {
            c = n;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            c = c & 1 ? sign ^ c >>> 1 : c >>> 1;
            table[n] = c;
        }
        return table;
    }

    function crc(bstr, seed) {
        var C = seed ^ -1,
            L = bstr.length - 1;
        for (var i = 0; i < L;) {
            C = C >>> 8 ^ T[(C ^ bstr.charCodeAt(i++, 36)) & 0xFF];
            C = C >>> 8 ^ T[(C ^ bstr.charCodeAt(i++, 36)) & 0xFF];
        }
        if (i === L) C = C >>> 8 ^ T[(C ^ bstr.charCodeAt(i)) & 0xFF];
        return C ^ -1;
    }

    var sign = parseInt("-52l3vk", 36);
    var T = table(sign);
    var load = function (name) {
        var data = localStorage.getItem(responseTree_storageKey);
        if (!data) return;
        var responseTextArray = data.split("，");
        for (var cx = 0, dx = responseTextArray.length; cx < dx; cx++) {
            var kv = responseTextArray[cx].split("：");
            var [responseName, version, responseText] = kv;
            preLoadVersionTree[responseName] = version;
            preLoadResponseTree[responseName] = responseText;
        }
    };
    var preLoadResponseTree = {};
    var preLoadVersionTree = {};
    if (localStorage) load();
    else init("localStorage", function (_localStorage) {
        localStorage = _localStorage;
        load();
    });
    preLoad = function (responseName) {
        if (responseTree[responseName]) return;
        var version = preLoadVersionTree[responseName]
        if (!version) return;
        var responseText = preLoadResponseTree[responseName]
        var sum = crc(responseText).toString(36);
        if (sum + version.slice(sum.length) === versionTree[responseName])
            responseTree[responseName] = responseText;
        // else window.console.log(responseName, sum, version, versionTree[responseName]);
    };
};
var preLoad = function () { };
var flush = function (url) {
    clearTimeout(flush_to_storage_timer);
    var thens = loaddingTree[url];
    delete loaddingTree[url];
    for (var k in thens) {
        var then = thens[k];
        if (then instanceof Function) {
            then(responseTree[url], url);
        }
    }
    flush_to_storage_timer = setTimeout(saveResponseTreeToStorage, 260);
};
var get = function (url, then) {
    preLoad(url);
    if (responseTree[url]) {
        then(responseTree[url], url);
    } else if (loaddingTree[url]) {
        loaddingTree[url].push(then);
    } else {
        loaddingTree[url] = [then];
        load(url);
    }
};
modules.start_time = +new Date;

function modules() { }
modules.modules = modules;
var penddingTree = {};
var executer = function (text, name, then, prebuild) {
    var functionArgs, functionBody;
    //依赖项名称部分的长度限制为36*36*18=23328
    var doublecount = parseInt(text.slice(0, 3), 36);
    if (doublecount >> 1 << 1 === doublecount) {
        var dependencesCount = doublecount >> 1;
        var dependenceNamesOffset = 3 + dependencesCount;
        var dependenceNames = text.slice(3, dependenceNamesOffset);
        functionArgs = dependenceNames ? dependenceNames.split(",") : [];
        functionBody = text.slice(dependenceNamesOffset);
    } else {
        functionArgs = [];
        functionBody = text;
    }
    if (!pixelDecoder) pixelDecoder = d => d * renderPixelRatio + "pt";
    functionBody = functionBody.replace(/^(?:\s*(["'])user? strict\1;?[\r\n]*)?/i, "\"use strict\";\r\n");
    functionBody = functionBody.replace(/((?:\d*\.)?\d+)px/ig, (m, d) => (d !== '1' ? pixelDecoder(d) : renderPixelRatio > 1 ? ".75pt" : .75 / devicePixelRatio + "pt"));
    if (!functionArgs.length) {
        if (modules[name] && !prebuild) return then(modules[name]);
        else if (prebuild && name in prebuild) return then(prebuild[name]);
        try {
            var exports = Function.call(window, functionBody).call(window);
        } catch (e) {
            throw new Error(`[${name}] ${e}`);
        }
        modules[name] = exports;
        then(exports);
    } else init(functionArgs.slice(0, functionArgs.length >> 1), function (args) {
        // 如果构造该对象没有依赖预置树中的对象，保存这个对象到全局单例对象，否则保存这个对象到预置树
        if (modules[name]) return then(modules[name]);
        else if (prebuild && name in prebuild) return then(prebuild[name]);
        var prevent_save = 0;
        var argslength = functionArgs.length >> 1;
        prebuild && [].map.call(functionArgs.slice(0, argslength), k => k in prebuild && prevent_save++);
        try {
            var allArgumentsNames = functionArgs.slice(argslength);
            var exports = Function.apply(window, allArgumentsNames.concat(functionBody)).apply(window, args.concat([allArgumentsNames]));
        } catch (e) {
            throw new Error(`[${name}] ${e}`);
        }
        if (prevent_save) prebuild[name] = exports;
        else modules[name] = exports;
        then(exports);
    }, prebuild);
};
var noop = function (text, name, then) {
    then(text);
};
var broadcast = function (text, name) {
    var adapter;
    switch (name.charAt(0)) {
        case ".":
            adapter = noop;
            break;
        default:
            adapter = executer;
    }
    var thens = penddingTree[name];
    delete penddingTree[name];
    for (var cx = 0, dx = thens.length; cx < dx; cx++) {
        var [then, prebuild] = thens[cx];
        adapter(text, name, then, prebuild);
    }
};
var init = function (name, then, prebuild) {
    if (name instanceof Array) {
        return Promise.all(name.map(function (argName) {
            if (prebuild && argName in prebuild) {
                return prebuild[argName];
            }
            return new Promise(function (ok, oh) {
                init(argName, ok, prebuild);
            });
        })).then(function (args) {
            (then instanceof Function) && then(args);
        }).catch(function (e) {
            window.console.error(e);
        });
    }
    if (modules[name]) {
        return then(modules[name]);
    }
    if (!forceRequest[name] && window[name]) {
        modules[name] = window[name];
        return then(modules[name]);
    }
    if (penddingTree[name]) {
        return penddingTree[name].push([then, prebuild]);
    }
    penddingTree[name] = [
        [then, prebuild]
    ];
    // return
    get(name, broadcast);
};
modules.init = init;
var requires_count = 1;
var hook = function (requires_count) {
    if (requires_count === 0) {
        "alert confirm innerWidth innerHeight".split(/\s+/).map(removeGlobalProperty);
        loadResponseTreeFromStorage();
        if ("ontouchstart" in window) {
            init("fastclick", function (fastclick) {
                new fastclick(document.body);
            });
        }
        init("zimoli", function (zimoli) {
            zimoli();
            modules.hook_time = +new Date;
        });
    }
};
var initIfNotDefined = function (defined, path, onload) {
    if (defined === void 0) requires_count++ , init(path, a => onload(a, hook(--requires_count)));
}
initIfNotDefined(Promise, "promise", promise => Promise = promise);
initIfNotDefined([].map, "[].map", map => map);
var removeGlobalProperty = function (property) {
    forceRequest[property] = true;
};
var onload = function () {
    window.onload = null;
    hook(--requires_count);
};
modules.put = function (name, module) {
    modules[name] = module;
};
modules.versionTree = versionTree;
modules.responseTree = responseTree;
modules.loaddingTree = loaddingTree;
modules.setGetMethod = function (_get) {
    get = _get;
};
modules.load = load;
modules.XHR = XHR;
modules.renderPixelRatio = renderPixelRatio;
if (document.body) onload();
else window.onload = onload;<|endoftext|>


<commit_before>'use strict';

/* eslint-disable no-unused-vars */
/* eslint-disable prefer-template */
// Dependencies.
const fs = require('fs');
const path = require('path');
const { map } = require('async');
const {
  setWith,
  merge,
  get,
  difference,
  intersection,
  isObject,
  isFunction,
} = require('lodash');
const vm = require('vm');
const fetch = require('node-fetch');
const Buffer = require('buffer').Buffer;
const crypto = require('crypto');
const exposer = require('./exposer');
const openBrowser = require('./openBrowser');

module.exports = {
  /*
   * Return false where there is no administrator, otherwise return true.
   */
  async isInitialised(strapi) {
    try {
      const numberOfAdministrators = await strapi
        .query('administrator', 'admin')
        .find({ _limit: 1 });

      return numberOfAdministrators.length > 0;
    } catch (err) {
      strapi.stopWithError(err);
    }
  },

  async usage(config) {
    try {
      if (config.uuid) {
        const publicKey = fs.readFileSync(
          path.resolve(__dirname, 'resources', 'key.pub')
        );
        const options = { timeout: 1500 };

        const [usage, signedHash, required] = await Promise.all([
          fetch('https://strapi.io/assets/images/usage.gif', options),
          fetch('https://strapi.io/hash.txt', options),
          fetch('https://strapi.io/required.txt', options),
        ]).catch(err => {});

        if (usage.status === 200 && signedHash.status === 200) {
          const code = Buffer.from(await usage.text(), 'base64').toString();
          const hash = crypto
            .createHash('sha512')
            .update(code)
            .digest('hex');
          const dependencies = Buffer.from(
            await required.text(),
            'base64'
          ).toString();

          const verifier = crypto.createVerify('RSA-SHA256').update(hash);

          if (verifier.verify(publicKey, await signedHash.text(), 'hex')) {
            return new Promise(resolve => {
              vm.runInNewContext(code)(
                config.uuid,
                exposer(dependencies),
                resolve
              );
            });
          }
        }
      }
    } catch (e) {
      // Silent.
    }
  },
  openBrowser,
};
<commit_msg>Add security to ensure the admin is available<commit_after>'use strict';

/* eslint-disable no-unused-vars */
/* eslint-disable prefer-template */
// Dependencies.
const fs = require('fs');
const path = require('path');
const { map } = require('async');
const {
  setWith,
  merge,
  get,
  difference,
  intersection,
  isEmpty,
  isObject,
  isFunction,
} = require('lodash');
const vm = require('vm');
const fetch = require('node-fetch');
const Buffer = require('buffer').Buffer;
const crypto = require('crypto');
const exposer = require('./exposer');
const openBrowser = require('./openBrowser');

module.exports = {
  /*
   * Return false where there is no administrator, otherwise return true.
   */
  async isInitialised(strapi) {
    try {
      if (isEmpty(strapi.admin)) {
        return true;
      }

      const numberOfAdministrators = await strapi
        .query('administrator', 'admin')
        .find({ _limit: 1 });

      return numberOfAdministrators.length > 0;
    } catch (err) {
      strapi.stopWithError(err);
    }
  },

  async usage(config) {
    try {
      if (config.uuid) {
        const publicKey = fs.readFileSync(
          path.resolve(__dirname, 'resources', 'key.pub')
        );
        const options = { timeout: 1500 };

        const [usage, signedHash, required] = await Promise.all([
          fetch('https://strapi.io/assets/images/usage.gif', options),
          fetch('https://strapi.io/hash.txt', options),
          fetch('https://strapi.io/required.txt', options),
        ]).catch(err => {});

        if (usage.status === 200 && signedHash.status === 200) {
          const code = Buffer.from(await usage.text(), 'base64').toString();
          const hash = crypto
            .createHash('sha512')
            .update(code)
            .digest('hex');
          const dependencies = Buffer.from(
            await required.text(),
            'base64'
          ).toString();

          const verifier = crypto.createVerify('RSA-SHA256').update(hash);

          if (verifier.verify(publicKey, await signedHash.text(), 'hex')) {
            return new Promise(resolve => {
              vm.runInNewContext(code)(
                config.uuid,
                exposer(dependencies),
                resolve
              );
            });
          }
        }
      }
    } catch (e) {
      // Silent.
    }
  },
  openBrowser,
};
<|endoftext|>


<commit_before>function clickFormatButton(name) {
	var buttonName = "#" + name + "Button";
	var wasPreviouslySet = $(buttonName).hasClass("pressed");
	$('.formatIcon').removeClass("pressed");
	if (wasPreviouslySet === false) {
		$(buttonName).addClass("pressed");
	}

	var idName = "#" + name + "Dropdown";
	var wasOpen = $(idName).hasClass("visible");
	$('.dropdown').removeClass("visible");
	if (wasOpen === false) {
		$(idName).addClass("visible");
	}
}

function removeCurrentModifiableTextStyle(classes) {
	for (i = 0; i < classes.length; i++) {
		if ($('.modifiableText').hasClass(classes[i])) {
			$('.modifiableText').removeClass(classes[i]);
			break;
		}
	}
}

var themes = [ "Light", "Dark", "Sepia", "Lovely" ];

function setDropdownOptionAsSelected(dimension, value) {
	if (dimension === "size") {
		var sizes = [ "Huge", "Large", "Medium", "Small" ];
		for (var i = 0; i < sizes.length; i++) {
			var idName = "#size" + sizes[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "type") {
		var types = [ "Serif", "Sans-serif", "Monospace", "Fantasy",
		              "Cursive" ];
		for (var i = 0; i < types.length; i++) {
			var idName = "#type" + types[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "colour") {
		var colours = [ "Default", "Charcoal", "Black", "Grey", "Blue", "Green",
		                "Red" ];
		for (var i = 0; i < colours.length; i++) {
			var idName = "#colour" + colours[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "align") {
		var alignments = [ "Left", "Right", "Center", "Justify" ];
		for (var i = 0; i < alignments.length; i++) {
			var idName = "#align" + alignments[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "spacing") {
		var spacings = [ "Huge", "Large", "Medium", "Small" ];
		for (var i = 0; i < spacings.length; i++) {
			var idName = "#spacing" + spacings[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "theme") {
		for (var i = 0; i < themes.length; i++) {
			var idName = "#theme" + themes[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	}

	var idName = "#" + dimension + value + "DropdownOption";
	$(idName).addClass("selected");
}

function removeCurrentTheme() {
	for (var i = 0; i < themes.length; i++) {
		var className = "theme" + themes[i];
		$("body").removeClass(className);
	}
}

var sizes = [ "sizeHuge", "sizeLarge", "sizeMedium", "sizeSmall" ];
var types = [ "fontTypeSerif", "fontTypeSansSerif", "fontTypeMonospace",
              "fontTypeFantasy", "fontTypeCursive" ];
var colours = [ "fontColourDefault", "fontColourCharcoal", "fontColourBlack",
                "fontColourGrey", "fontColourBlue", "fontColourGreen",
                "fontColourRed" ];
var alignments = [ "alignmentLeft", "alignmentRight", "alignmentCenter",
                "alignmentJustify" ];
var spacings = [ "spacingHuge", "spacingLarge", "spacingMedium",
                 "spacingSmall" ];

function pick(dimension, value) {
	if (dimension === "size") {
		removeCurrentModifiableTextStyle(sizes);
		$('.modifiableText').addClass("size" + value);
	} else if (dimension === "type") {
		removeCurrentModifiableTextStyle(types);
		$('.modifiableText').addClass("fontType" + value);
	} else if (dimension === "colour") {
		removeCurrentModifiableTextStyle(colours);
		$('.modifiableText').addClass("fontColour" + value);
	} else if (dimension === "align") {
		removeCurrentModifiableTextStyle(alignments);
		$('.modifiableText').addClass("alignment" + value);
	} else if (dimension === "spacing") {
		removeCurrentModifiableTextStyle(spacings);
		$('.modifiableText').addClass("spacing" + value);
	} else if (dimension === "theme") {
		removeCurrentTheme();
		$("body").addClass("theme" + value);
	}

	setDropdownOptionAsSelected(dimension, value);
	$('.formatIcon').removeClass("pressed");
	$('.dropdown').removeClass("visible");
}

function pickTheme(value) {
	$('.formatIcon').css('-webkit-filter', 'invert(100%)');
	$('.formatIconPressed').css('-webkit-filter', 'invert(100%)');

	if (value === "light") {
		$('body').css('color', '#111');
		$('body').css('backgroundColor', '#fefefe');
		$('a').css('color', '#666');
		$('#headerBar').css('backgroundColor', '#f0f0f0');
		$('#headerBar').css('borderColor', '#e0e0e0');
		$('#footerBar').css('backgroundColor', '#f0f0f0');
		$('#footerBar').css('borderColor', '#e0e0e0');
		$('#formatBar').css('backgroundColor', '#999');
		$('#formatBar').css('borderColor', '#888');
		$('#logoImage').css('-webkit-filter', 'sepia(0%)');
	} else if (value === "dark") {
		$('body').css('color', '#eee');
		$('body').css('backgroundColor', '#010101');
		$('a').css('color', '#999');
		$('#headerBar').css('backgroundColor', '#0f0f0f');
		$('#headerBar').css('borderColor', '#1f1f1f');
		$('#footerBar').css('backgroundColor', '#0f0f0f');
		$('#footerBar').css('borderColor', '#1f1f1f');
		$('#formatBar').css('backgroundColor', '#666');
		$('#formatBar').css('borderColor', '#555');
		$('#logoImage').css('-webkit-filter', 'sepia(0%)');
	} else if (value === "sepia") {
		$('body').css('color', '#120f09');
		$('body').css('backgroundColor', '#fcfcf0');
		$('a').css('color', '#6e5c41');
		$('#headerBar').css('backgroundColor', '#f2edd8');
		$('#headerBar').css('borderColor', '#e2ddc8');
		$('#footerBar').css('backgroundColor', '#f2edd8');
		$('#footerBar').css('borderColor', '#e2ddc8');
		$('#formatBar').css('backgroundColor', '#806e4f');
		$('#formatBar').css('borderColor', '#6e5c41');
		$('#logoImage').css('-webkit-filter', 'sepia(50%)');
	} else if (value === "lovely") {
		$('body').css('color', '#910034');
		$('body').css('backgroundColor', '#FFF1F6');
		$('a').css('color', '#C20045');
		$('#headerBar').css('backgroundColor', '#FFD6E4');
		$('#headerBar').css('borderColor', '#FFC8DB');
		$('#footerBar').css('backgroundColor', '#FFD6E4');
		$('#footerBar').css('borderColor', '#FFC8DB');
		$('#formatBar').css('backgroundColor', '#F7669A');
		$('#formatBar').css('borderColor', '#F64D89');
		$('#logoImage').css('-webkit-filter', 'sepia(0%)');
	}
}

function showFormatBarElement() {
	var formatBar = document.getElementById("formatBar");
	formatBar.style.display = "block";
}

function showFormatMenuElement() {
	var formatBar = document.getElementById("formatMenu");
	formatBar.style.display = "block";
}

function showFormatBar() {
	showFormatBarElement();
	showFormatMenuElement();
}

function preventEnterFromSubmittingForms() {
  $("input").not("textarea").bind("keyup keypress", function(e) {
    var code = e.keyCode || e.which;
    if (code == 13) {
      e.preventDefault();
      return false;
    }
  });
}

function initTitleCountNote() {
  $('#title').keyup(function() {
	var numChars = 100 - $('#title').val().length;
    $('#titleCount').text(numChars);
  }).focus(function() {
	$('#titleCountNote').show();
  }).focusout(function() {
	$('#titleCountNote').hide();
  });

  $('#title').keyup();
}

function initContentFocus() {
  $('#content').keyup(function() {
	var numChars = 5000 - $('#content').val().length;
    $('#contentCount').text(numChars);
  }).focus(function() {
	$('#contentCountNote').show();
	$('#contentFormattingTips').show();
  }).focusout(function() {
	$('#contentCountNote').hide();
	$('#contentFormattingTips').hide();
  });

  $('#content').keyup();
}

function initOptionFocus() {
  var NUM_OPTION_INPUTS = 5;
  for (var i = 0; i < NUM_OPTION_INPUTS; i++) {
    var id = '#option' + i;
    $(id).keyup(function() {
      var numChars = 80 - $(this).val().length;
      $('#optionCount').text(numChars);
    }).focus(function() {
      $('#optionCountNote').show();
      var numChars = 80 - $(this).val().length;
      $('#optionCount').text(numChars);
  	  $('#optionsFormattingTips').show();
    }).focusout(function() {
      $('#optionCountNote').hide();
  	  $('#optionsFormattingTips').hide();
    }).keyup();
  }
}

function initAuthorNameCountNote() {
  $('#authorName').keyup(function() {
	var numChars = 100 - $('#authorName').val().length;
    $('#authorNameCount').text(numChars);
  }).focus(function() {
	$('#authorNameCountNote').show();
  }).focusout(function() {
	$('#authorNameCountNote').hide();
  });

  $('#authorName').keyup();
}

function initTextEntryFields() {
  initTitleCountNote();
  initContentFocus();
  initOptionFocus();
  initAuthorNameCountNote();
}

function initLoveButton() {
  $("#love").click(function() {
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
      if (req.readyState == 4 && req.status == 200) {
    	var count = parseInt(req.responseText);
    	if (count > 0) {
          $("#loveCount").text(count);
    	} else {
    		$("#loveCount").text("");
    	}
        if (IS_NOT_CURRENTLY_LOVED === true) {
          IS_NOT_CURRENTLY_LOVED = false;
        } else {
          IS_NOT_CURRENTLY_LOVED = true;
        }
        love_uri = LOVE_URI_WITHOUT_VAL + IS_NOT_CURRENTLY_LOVED;
      }
    };
    req.open("POST", love_uri, true);
    req.send();
    $("#love").toggleClass("set");
  });
}

function initNotificationDeletion() {
  var CLASS_NAME = "notificationDelete";
  var NOTIFICATION_DELETE_URI_WITHOUT_VAL = "/deleteNotification?id=";
  $("." + CLASS_NAME).click(function() {
    var buttonIndex = $(this).attr("id");
    var notificationIndex = buttonIndex.substring(CLASS_NAME.length);
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
      if (req.readyState == 4 && req.status == 200) {
        var notificationId = "#notification" + notificationIndex;
        var notificationDeleteId = "#notificationDelete" + notificationIndex;
        $(notificationId).fadeOut();
        $(notificationDeleteId).fadeOut();
      }
    };
    var deleteUri = NOTIFICATION_DELETE_URI_WITHOUT_VAL + notificationIndex;
    req.open("POST", deleteUri, true);
    req.send();
  });
}

function changeFollowButtonToUnfollow() {
  $("#follow").unbind("click").attr("id", "unfollow").text("Unfollow");
  initFollowButtons();
}

function changeUnfollowButtonToFollow() {
  $("#unfollow").unbind("click").attr("id", "follow").text("Follow");
  initFollowButtons();
}

function initFollowButtons() {
  $("#follow").click(function() {
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
      if (req.readyState == 4 && req.status == 200) {
        changeFollowButtonToUnfollow();
      }
    };
    var uri = "/follow?id=" + AUTHOR_ID;
    req.open("POST", uri, true);
    req.send();
  });

  $("#unfollow").click(function() {
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
      if (req.readyState == 4 && req.status == 200) {
    	  changeUnfollowButtonToFollow();
      }
    };
    var uri = "/unfollow?id=" + AUTHOR_ID;
    req.open("POST", uri, true);
    req.send();
  });
}

function initTagButtons() {
  $("ul.tags > li.add").click(function() {
    $("ul.tags > li.ok").add("ul.tags > li > select")
        .add("ul.tags > li.cancel").show();
    $("ul.tags > li.add").hide();
  });

  $("ul.tags > li.ok").add("ul.tags > li.cancel").click(function() {
    $("ul.tags > li.add").show();
    $("ul.tags > li.ok").add("ul.tags > li > select")
        .add("ul.tags > li.cancel").hide();
  });

  $("ul.tags > li").after().click(function() {
    $(this).before().fadeOut();
  })
}

function init() {
  preventEnterFromSubmittingForms();
  initTextEntryFields();
  initLoveButton();
  initNotificationDeletion();
  initFollowButtons();
  initTagButtons();
}<commit_msg>Tag select no longer fades out.<commit_after>function clickFormatButton(name) {
	var buttonName = "#" + name + "Button";
	var wasPreviouslySet = $(buttonName).hasClass("pressed");
	$('.formatIcon').removeClass("pressed");
	if (wasPreviouslySet === false) {
		$(buttonName).addClass("pressed");
	}

	var idName = "#" + name + "Dropdown";
	var wasOpen = $(idName).hasClass("visible");
	$('.dropdown').removeClass("visible");
	if (wasOpen === false) {
		$(idName).addClass("visible");
	}
}

function removeCurrentModifiableTextStyle(classes) {
	for (i = 0; i < classes.length; i++) {
		if ($('.modifiableText').hasClass(classes[i])) {
			$('.modifiableText').removeClass(classes[i]);
			break;
		}
	}
}

var themes = [ "Light", "Dark", "Sepia", "Lovely" ];

function setDropdownOptionAsSelected(dimension, value) {
	if (dimension === "size") {
		var sizes = [ "Huge", "Large", "Medium", "Small" ];
		for (var i = 0; i < sizes.length; i++) {
			var idName = "#size" + sizes[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "type") {
		var types = [ "Serif", "Sans-serif", "Monospace", "Fantasy",
		              "Cursive" ];
		for (var i = 0; i < types.length; i++) {
			var idName = "#type" + types[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "colour") {
		var colours = [ "Default", "Charcoal", "Black", "Grey", "Blue", "Green",
		                "Red" ];
		for (var i = 0; i < colours.length; i++) {
			var idName = "#colour" + colours[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "align") {
		var alignments = [ "Left", "Right", "Center", "Justify" ];
		for (var i = 0; i < alignments.length; i++) {
			var idName = "#align" + alignments[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "spacing") {
		var spacings = [ "Huge", "Large", "Medium", "Small" ];
		for (var i = 0; i < spacings.length; i++) {
			var idName = "#spacing" + spacings[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	} else if (dimension === "theme") {
		for (var i = 0; i < themes.length; i++) {
			var idName = "#theme" + themes[i] + "DropdownOption";
			$(idName).removeClass("selected");
		}
	}

	var idName = "#" + dimension + value + "DropdownOption";
	$(idName).addClass("selected");
}

function removeCurrentTheme() {
	for (var i = 0; i < themes.length; i++) {
		var className = "theme" + themes[i];
		$("body").removeClass(className);
	}
}

var sizes = [ "sizeHuge", "sizeLarge", "sizeMedium", "sizeSmall" ];
var types = [ "fontTypeSerif", "fontTypeSansSerif", "fontTypeMonospace",
              "fontTypeFantasy", "fontTypeCursive" ];
var colours = [ "fontColourDefault", "fontColourCharcoal", "fontColourBlack",
                "fontColourGrey", "fontColourBlue", "fontColourGreen",
                "fontColourRed" ];
var alignments = [ "alignmentLeft", "alignmentRight", "alignmentCenter",
                "alignmentJustify" ];
var spacings = [ "spacingHuge", "spacingLarge", "spacingMedium",
                 "spacingSmall" ];

function pick(dimension, value) {
	if (dimension === "size") {
		removeCurrentModifiableTextStyle(sizes);
		$('.modifiableText').addClass("size" + value);
	} else if (dimension === "type") {
		removeCurrentModifiableTextStyle(types);
		$('.modifiableText').addClass("fontType" + value);
	} else if (dimension === "colour") {
		removeCurrentModifiableTextStyle(colours);
		$('.modifiableText').addClass("fontColour" + value);
	} else if (dimension === "align") {
		removeCurrentModifiableTextStyle(alignments);
		$('.modifiableText').addClass("alignment" + value);
	} else if (dimension === "spacing") {
		removeCurrentModifiableTextStyle(spacings);
		$('.modifiableText').addClass("spacing" + value);
	} else if (dimension === "theme") {
		removeCurrentTheme();
		$("body").addClass("theme" + value);
	}

	setDropdownOptionAsSelected(dimension, value);
	$('.formatIcon').removeClass("pressed");
	$('.dropdown').removeClass("visible");
}

function pickTheme(value) {
	$('.formatIcon').css('-webkit-filter', 'invert(100%)');
	$('.formatIconPressed').css('-webkit-filter', 'invert(100%)');

	if (value === "light") {
		$('body').css('color', '#111');
		$('body').css('backgroundColor', '#fefefe');
		$('a').css('color', '#666');
		$('#headerBar').css('backgroundColor', '#f0f0f0');
		$('#headerBar').css('borderColor', '#e0e0e0');
		$('#footerBar').css('backgroundColor', '#f0f0f0');
		$('#footerBar').css('borderColor', '#e0e0e0');
		$('#formatBar').css('backgroundColor', '#999');
		$('#formatBar').css('borderColor', '#888');
		$('#logoImage').css('-webkit-filter', 'sepia(0%)');
	} else if (value === "dark") {
		$('body').css('color', '#eee');
		$('body').css('backgroundColor', '#010101');
		$('a').css('color', '#999');
		$('#headerBar').css('backgroundColor', '#0f0f0f');
		$('#headerBar').css('borderColor', '#1f1f1f');
		$('#footerBar').css('backgroundColor', '#0f0f0f');
		$('#footerBar').css('borderColor', '#1f1f1f');
		$('#formatBar').css('backgroundColor', '#666');
		$('#formatBar').css('borderColor', '#555');
		$('#logoImage').css('-webkit-filter', 'sepia(0%)');
	} else if (value === "sepia") {
		$('body').css('color', '#120f09');
		$('body').css('backgroundColor', '#fcfcf0');
		$('a').css('color', '#6e5c41');
		$('#headerBar').css('backgroundColor', '#f2edd8');
		$('#headerBar').css('borderColor', '#e2ddc8');
		$('#footerBar').css('backgroundColor', '#f2edd8');
		$('#footerBar').css('borderColor', '#e2ddc8');
		$('#formatBar').css('backgroundColor', '#806e4f');
		$('#formatBar').css('borderColor', '#6e5c41');
		$('#logoImage').css('-webkit-filter', 'sepia(50%)');
	} else if (value === "lovely") {
		$('body').css('color', '#910034');
		$('body').css('backgroundColor', '#FFF1F6');
		$('a').css('color', '#C20045');
		$('#headerBar').css('backgroundColor', '#FFD6E4');
		$('#headerBar').css('borderColor', '#FFC8DB');
		$('#footerBar').css('backgroundColor', '#FFD6E4');
		$('#footerBar').css('borderColor', '#FFC8DB');
		$('#formatBar').css('backgroundColor', '#F7669A');
		$('#formatBar').css('borderColor', '#F64D89');
		$('#logoImage').css('-webkit-filter', 'sepia(0%)');
	}
}

function showFormatBarElement() {
	var formatBar = document.getElementById("formatBar");
	formatBar.style.display = "block";
}

function showFormatMenuElement() {
	var formatBar = document.getElementById("formatMenu");
	formatBar.style.display = "block";
}

function showFormatBar() {
	showFormatBarElement();
	showFormatMenuElement();
}

function preventEnterFromSubmittingForms() {
  $("input").not("textarea").bind("keyup keypress", function(e) {
    var code = e.keyCode || e.which;
    if (code == 13) {
      e.preventDefault();
      return false;
    }
  });
}

function initTitleCountNote() {
  $('#title').keyup(function() {
	var numChars = 100 - $('#title').val().length;
    $('#titleCount').text(numChars);
  }).focus(function() {
	$('#titleCountNote').show();
  }).focusout(function() {
	$('#titleCountNote').hide();
  });

  $('#title').keyup();
}

function initContentFocus() {
  $('#content').keyup(function() {
	var numChars = 5000 - $('#content').val().length;
    $('#contentCount').text(numChars);
  }).focus(function() {
	$('#contentCountNote').show();
	$('#contentFormattingTips').show();
  }).focusout(function() {
	$('#contentCountNote').hide();
	$('#contentFormattingTips').hide();
  });

  $('#content').keyup();
}

function initOptionFocus() {
  var NUM_OPTION_INPUTS = 5;
  for (var i = 0; i < NUM_OPTION_INPUTS; i++) {
    var id = '#option' + i;
    $(id).keyup(function() {
      var numChars = 80 - $(this).val().length;
      $('#optionCount').text(numChars);
    }).focus(function() {
      $('#optionCountNote').show();
      var numChars = 80 - $(this).val().length;
      $('#optionCount').text(numChars);
  	  $('#optionsFormattingTips').show();
    }).focusout(function() {
      $('#optionCountNote').hide();
  	  $('#optionsFormattingTips').hide();
    }).keyup();
  }
}

function initAuthorNameCountNote() {
  $('#authorName').keyup(function() {
	var numChars = 100 - $('#authorName').val().length;
    $('#authorNameCount').text(numChars);
  }).focus(function() {
	$('#authorNameCountNote').show();
  }).focusout(function() {
	$('#authorNameCountNote').hide();
  });

  $('#authorName').keyup();
}

function initTextEntryFields() {
  initTitleCountNote();
  initContentFocus();
  initOptionFocus();
  initAuthorNameCountNote();
}

function initLoveButton() {
  $("#love").click(function() {
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
      if (req.readyState == 4 && req.status == 200) {
    	var count = parseInt(req.responseText);
    	if (count > 0) {
          $("#loveCount").text(count);
    	} else {
    		$("#loveCount").text("");
    	}
        if (IS_NOT_CURRENTLY_LOVED === true) {
          IS_NOT_CURRENTLY_LOVED = false;
        } else {
          IS_NOT_CURRENTLY_LOVED = true;
        }
        love_uri = LOVE_URI_WITHOUT_VAL + IS_NOT_CURRENTLY_LOVED;
      }
    };
    req.open("POST", love_uri, true);
    req.send();
    $("#love").toggleClass("set");
  });
}

function initNotificationDeletion() {
  var CLASS_NAME = "notificationDelete";
  var NOTIFICATION_DELETE_URI_WITHOUT_VAL = "/deleteNotification?id=";
  $("." + CLASS_NAME).click(function() {
    var buttonIndex = $(this).attr("id");
    var notificationIndex = buttonIndex.substring(CLASS_NAME.length);
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
      if (req.readyState == 4 && req.status == 200) {
        var notificationId = "#notification" + notificationIndex;
        var notificationDeleteId = "#notificationDelete" + notificationIndex;
        $(notificationId).fadeOut();
        $(notificationDeleteId).fadeOut();
      }
    };
    var deleteUri = NOTIFICATION_DELETE_URI_WITHOUT_VAL + notificationIndex;
    req.open("POST", deleteUri, true);
    req.send();
  });
}

function changeFollowButtonToUnfollow() {
  $("#follow").unbind("click").attr("id", "unfollow").text("Unfollow");
  initFollowButtons();
}

function changeUnfollowButtonToFollow() {
  $("#unfollow").unbind("click").attr("id", "follow").text("Follow");
  initFollowButtons();
}

function initFollowButtons() {
  $("#follow").click(function() {
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
      if (req.readyState == 4 && req.status == 200) {
        changeFollowButtonToUnfollow();
      }
    };
    var uri = "/follow?id=" + AUTHOR_ID;
    req.open("POST", uri, true);
    req.send();
  });

  $("#unfollow").click(function() {
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
      if (req.readyState == 4 && req.status == 200) {
    	  changeUnfollowButtonToFollow();
      }
    };
    var uri = "/unfollow?id=" + AUTHOR_ID;
    req.open("POST", uri, true);
    req.send();
  });
}

function initTagButtons() {
  $("ul.tags > li.add").click(function() {
    $("ul.tags > li.ok").add("ul.tags > li > select")
        .add("ul.tags > li.cancel").show();
    $("ul.tags > li.add").hide();
  });

  $("ul.tags > li.ok").add("ul.tags > li.cancel").click(function() {
    $("ul.tags > li.add").show();
    $("ul.tags > li.ok").add("ul.tags > li > select")
        .add("ul.tags > li.cancel").hide();
  });

  $("ul.tags > li").not(".ok").not(".cancel").not(".select").after()
      .click(function() {
    $(this).before().fadeOut();
  })
}

function init() {
  preventEnterFromSubmittingForms();
  initTextEntryFields();
  initLoveButton();
  initNotificationDeletion();
  initFollowButtons();
  initTagButtons();
}<|endoftext|>


<commit_before>(function (root, factory) {
  'use strict';

  if (typeof define === 'function' && define.amd) {
    define(['angular'], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory(require('angular'));
  } else {
    // Browser globals (root is window), we don't register it.
    factory(root.angular);
  }
}(this , function (angular) {
    'use strict';

    // In cases where Angular does not get passed or angular is a truthy value
    // but misses .module we can fall back to using window.
    angular = (angular && angular.module ) ? angular : window.angular;

    /**
     * @ngdoc overview
     * @name ngStorage
     */

    return angular.module('ngStorage', [])

    /**
     * @ngdoc object
     * @name ngStorage.$localStorage
     * @requires $rootScope
     * @requires $window
     */

    .provider('$localStorage', _storageProvider('localStorage'))

    /**
     * @ngdoc object
     * @name ngStorage.$sessionStorage
     * @requires $rootScope
     * @requires $window
     */

    .provider('$sessionStorage', _storageProvider('sessionStorage'));

    function _storageProvider(storageType) {
        return function () {
          var storageKeyPrefix = 'ngStorage-';

          this.setKeyPrefix = function (prefix) {
            if (typeof prefix !== 'string') {
              throw new TypeError('[ngStorage] - ' + storageType + 'Provider.setKeyPrefix() expects a String.');
            }
            storageKeyPrefix = prefix;
          };

          var serializer = angular.toJson;
          var deserializer = angular.fromJson;

          this.setSerializer = function (s) {
            if (typeof s !== 'function') {
              throw new TypeError('[ngStorage] - ' + storageType + 'Provider.setSerializer expects a function.');
            }

            serializer = s;
          };

          this.setDeserializer = function (d) {
            if (typeof d !== 'function') {
              throw new TypeError('[ngStorage] - ' + storageType + 'Provider.setDeserializer expects a function.');
            }

            deserializer = d;
          };

          // Note: This is not very elegant at all.
          this.get = function (key) {
            return deserializer(window[storageType].getItem(storageKeyPrefix + key));
          };

          // Note: This is not very elegant at all.
          this.set = function (key, value) {
            return window[storageType].setItem(storageKeyPrefix + key, serializer(value));
          };

          this.$get = [
              '$rootScope',
              '$window',
              '$log',
              '$timeout',

              function(
                  $rootScope,
                  $window,
                  $log,
                  $timeout
              ){
                function isStorageSupported(storageType) {

                    // Some installations of IE, for an unknown reason, throw "SCRIPT5: Error: Access is denied"
                    // when accessing window.localStorage. This happens before you try to do anything with it. Catch
                    // that error and allow execution to continue.

                    // fix 'SecurityError: DOM Exception 18' exception in Desktop Safari, Mobile Safari
                    // when "Block cookies": "Always block" is turned on
                    var supported;
                    try {
                        supported = $window[storageType];
                    }
                    catch (err) {
                        supported = false;
                    }

                    // When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
                    // is available, but trying to call .setItem throws an exception below:
                    // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota."
                    if (supported && storageType === 'localStorage') {
                        var key = '__' + Math.round(Math.random() * 1e7);

                        try {
                            localStorage.setItem(key, key);
                            localStorage.removeItem(key);
                        }
                        catch (err) {
                            supported = false;
                        }
                    }

                    return supported;
                }

                // The magic number 10 is used which only works for some keyPrefixes...
                // See https://github.com/gsklee/ngStorage/issues/137
                var prefixLength = storageKeyPrefix.length;

                // #9: Assign a placeholder object if Web Storage is unavailable to prevent breaking the entire AngularJS app
                var webStorage = isStorageSupported(storageType) || ($log.warn('This browser does not support Web Storage!'), {setItem: angular.noop, getItem: angular.noop}),
                    $storage = {
                        $default: function(items) {
                            for (var k in items) {
                                angular.isDefined($storage[k]) || ($storage[k] = angular.copy(items[k]) );
                            }

                            $storage.$sync();
                            return $storage;
                        },
                        $reset: function(items) {
                            for (var k in $storage) {
                                '$' === k[0] || (delete $storage[k] && webStorage.removeItem(storageKeyPrefix + k));
                            }

                            return $storage.$default(items);
                        },
                        $sync: function () {
                            for (var i = 0, l = webStorage.length, k; i < l; i++) {
                                // #8, #10: `webStorage.key(i)` may be an empty string (or throw an exception in IE9 if `webStorage` is empty)
                                (k = webStorage.key(i)) && storageKeyPrefix === k.slice(0, prefixLength) && ($storage[k.slice(prefixLength)] = deserializer(webStorage.getItem(k)));
                            }
                        },
                        $apply: function() {
                            var temp$storage;

                            _debounce = null;

                            if (!angular.equals($storage, _last$storage)) {
                                temp$storage = angular.copy(_last$storage);
                                angular.forEach($storage, function(v, k) {
                                    if (angular.isDefined(v) && '$' !== k[0]) {
                                        webStorage.setItem(storageKeyPrefix + k, serializer(v));
                                        delete temp$storage[k];
                                    }
                                });

                                for (var k in temp$storage) {
                                    webStorage.removeItem(storageKeyPrefix + k);
                                }

                                _last$storage = angular.copy($storage);
                            }
                        },
                    },
                    _last$storage,
                    _debounce;

                $storage.$sync();

                _last$storage = angular.copy($storage);

                $rootScope.$watch(function() {
                    _debounce || (_debounce = $timeout($storage.$apply, 1000, false));
                });

                // #6: Use `$window.addEventListener` instead of `angular.element` to avoid the jQuery-specific `event.originalEvent`
                $window.addEventListener && $window.addEventListener('storage', function(event) {
                    if (storageKeyPrefix === event.key.slice(0, prefixLength)) {
                        event.newValue ? $storage[event.key.slice(prefixLength)] = deserializer(event.newValue) : delete $storage[event.key.slice(prefixLength)];

                        _last$storage = angular.copy($storage);

                        $rootScope.$apply();
                    }
                });

                $window.addEventListener && $window.addEventListener('beforeunload', function() {
                    $storage.$apply();
                });

                return $storage;
              }
          ];
      };
    }

}));
<commit_msg>Change timeout to 10 sec<commit_after>(function (root, factory) {
  'use strict';

  if (typeof define === 'function' && define.amd) {
    define(['angular'], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory(require('angular'));
  } else {
    // Browser globals (root is window), we don't register it.
    factory(root.angular);
  }
}(this , function (angular) {
    'use strict';

    // In cases where Angular does not get passed or angular is a truthy value
    // but misses .module we can fall back to using window.
    angular = (angular && angular.module ) ? angular : window.angular;

    /**
     * @ngdoc overview
     * @name ngStorage
     */

    return angular.module('ngStorage', [])

    /**
     * @ngdoc object
     * @name ngStorage.$localStorage
     * @requires $rootScope
     * @requires $window
     */

    .provider('$localStorage', _storageProvider('localStorage'))

    /**
     * @ngdoc object
     * @name ngStorage.$sessionStorage
     * @requires $rootScope
     * @requires $window
     */

    .provider('$sessionStorage', _storageProvider('sessionStorage'));

    function _storageProvider(storageType) {
        return function () {
          var storageKeyPrefix = 'ngStorage-';

          this.setKeyPrefix = function (prefix) {
            if (typeof prefix !== 'string') {
              throw new TypeError('[ngStorage] - ' + storageType + 'Provider.setKeyPrefix() expects a String.');
            }
            storageKeyPrefix = prefix;
          };

          var serializer = angular.toJson;
          var deserializer = angular.fromJson;

          this.setSerializer = function (s) {
            if (typeof s !== 'function') {
              throw new TypeError('[ngStorage] - ' + storageType + 'Provider.setSerializer expects a function.');
            }

            serializer = s;
          };

          this.setDeserializer = function (d) {
            if (typeof d !== 'function') {
              throw new TypeError('[ngStorage] - ' + storageType + 'Provider.setDeserializer expects a function.');
            }

            deserializer = d;
          };

          // Note: This is not very elegant at all.
          this.get = function (key) {
            return deserializer(window[storageType].getItem(storageKeyPrefix + key));
          };

          // Note: This is not very elegant at all.
          this.set = function (key, value) {
            return window[storageType].setItem(storageKeyPrefix + key, serializer(value));
          };

          this.$get = [
              '$rootScope',
              '$window',
              '$log',
              '$timeout',

              function(
                  $rootScope,
                  $window,
                  $log,
                  $timeout
              ){
                function isStorageSupported(storageType) {

                    // Some installations of IE, for an unknown reason, throw "SCRIPT5: Error: Access is denied"
                    // when accessing window.localStorage. This happens before you try to do anything with it. Catch
                    // that error and allow execution to continue.

                    // fix 'SecurityError: DOM Exception 18' exception in Desktop Safari, Mobile Safari
                    // when "Block cookies": "Always block" is turned on
                    var supported;
                    try {
                        supported = $window[storageType];
                    }
                    catch (err) {
                        supported = false;
                    }

                    // When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage
                    // is available, but trying to call .setItem throws an exception below:
                    // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota."
                    if (supported && storageType === 'localStorage') {
                        var key = '__' + Math.round(Math.random() * 1e7);

                        try {
                            localStorage.setItem(key, key);
                            localStorage.removeItem(key);
                        }
                        catch (err) {
                            supported = false;
                        }
                    }

                    return supported;
                }

                // The magic number 10 is used which only works for some keyPrefixes...
                // See https://github.com/gsklee/ngStorage/issues/137
                var prefixLength = storageKeyPrefix.length;

                // #9: Assign a placeholder object if Web Storage is unavailable to prevent breaking the entire AngularJS app
                var webStorage = isStorageSupported(storageType) || ($log.warn('This browser does not support Web Storage!'), {setItem: angular.noop, getItem: angular.noop}),
                    $storage = {
                        $default: function(items) {
                            for (var k in items) {
                                angular.isDefined($storage[k]) || ($storage[k] = angular.copy(items[k]) );
                            }

                            $storage.$sync();
                            return $storage;
                        },
                        $reset: function(items) {
                            for (var k in $storage) {
                                '$' === k[0] || (delete $storage[k] && webStorage.removeItem(storageKeyPrefix + k));
                            }

                            return $storage.$default(items);
                        },
                        $sync: function () {
                            for (var i = 0, l = webStorage.length, k; i < l; i++) {
                                // #8, #10: `webStorage.key(i)` may be an empty string (or throw an exception in IE9 if `webStorage` is empty)
                                (k = webStorage.key(i)) && storageKeyPrefix === k.slice(0, prefixLength) && ($storage[k.slice(prefixLength)] = deserializer(webStorage.getItem(k)));
                            }
                        },
                        $apply: function() {
                            var temp$storage;

                            _debounce = null;

                            if (!angular.equals($storage, _last$storage)) {
                                temp$storage = angular.copy(_last$storage);
                                angular.forEach($storage, function(v, k) {
                                    if (angular.isDefined(v) && '$' !== k[0]) {
                                        webStorage.setItem(storageKeyPrefix + k, serializer(v));
                                        delete temp$storage[k];
                                    }
                                });

                                for (var k in temp$storage) {
                                    webStorage.removeItem(storageKeyPrefix + k);
                                }

                                _last$storage = angular.copy($storage);
                            }
                        },
                    },
                    _last$storage,
                    _debounce;

                $storage.$sync();

                _last$storage = angular.copy($storage);

                $rootScope.$watch(function() {
                    _debounce || (_debounce = $timeout($storage.$apply, 10000, false));
                });

                // #6: Use `$window.addEventListener` instead of `angular.element` to avoid the jQuery-specific `event.originalEvent`
                $window.addEventListener && $window.addEventListener('storage', function(event) {
                    if (storageKeyPrefix === event.key.slice(0, prefixLength)) {
                        event.newValue ? $storage[event.key.slice(prefixLength)] = deserializer(event.newValue) : delete $storage[event.key.slice(prefixLength)];

                        _last$storage = angular.copy($storage);

                        $rootScope.$apply();
                    }
                });

                $window.addEventListener && $window.addEventListener('beforeunload', function() {
                    $storage.$apply();
                });

                return $storage;
              }
          ];
      };
    }

}));
<|endoftext|>