<commit_before>// Node.js / browser support
var isNodeJS = false;
if (typeof exports === 'undefined') {
    exports = {};
}

if (typeof module !== 'undefined') {
    isNodeJS = true;
}

var path;

if (isNodeJS) {
    pathHelper = require('path');
}

// Common namespace for browsers
var common = {};

// --- CHALLENGE ACTIVE SETTING ---
// Set to true to enable challenge active mode
// so that the routes are requestable.
// This is a function so we can return a boolean
// based on the current date being within a set date range, for example.
var challengeActive = exports.challengeActive = common.challengeActive = function() {
    return true;
}

var formAbsoluteURI = exports.formAbsoluteURI = common.formAbsoluteURI = function(path, options) {
    if (isNodeJS) {
        var url = require('url');

        if (!options) {
            options = require('../../enums.json').options;
        }

        if (path) {
            options.pathname = path;
        }

        return url.format(options);
    }
}

var tagize = exports.tagize = common.tagize = function(string) {
    return splitIntoTags(string).map(normalizeTag);
};

var campaign = exports.campaign = common.campaign = function() {
    var campaigns = {
        trial: 'VerilyTrial',
        main: 'VerilyLive'
    }
    return campaigns.main;
}

var campaigner = exports.campaigner = common.campaigner = function(medium, text, link) {
    if (medium === 'twitter') {
        return {
            hashtags: campaign()
        };
    } else if (medium === 'email') {
        return {
            subject: text + ' #' + campaign(),
            body: text + ' – ' +  link + ' %0D%0A%0D%0AAnswer this with Verily, a crowdsourced verification platform.'
        };
    }
};

var splitIntoTags = exports.splitIntoTags = common.splitIntoTags = function(string) {
    return string.split(',').filter(function(tag) {
        // Do not include just whitespace elements.
        if (tag && !(/^\s+$/.test(tag))) {
            return tag;
        }

    });
};

// Make tags friendly for URIs.
// Replace multiple instances of whitespace with '-'.
// e.g. turn " " into "-".
var normalizeTag = exports.normalizeTag = common.normalizeTag = exports.normalizeString = common.normalizeString = function(tag) {
    // Just remove apostrophes, don't replace them with '-'.
    // If after the first replace there is just 1 '-' at start or end, remove it, or if there are 2 or more hyphens (-), trim to 1 '-'.
    return tag.trim().toLowerCase().replace(/'/g, '').replace(/[\s/\\#._!@$£€%^?<>{}\[\]&*+=:;"`~]+/g, '-').replace(/-{2,}/g, '-' ).replace(/(^-)?(-$)?/g, '');
};

// Pretty paths for canonical URLs
var prettyPath = exports.prettyPath = common.prettyPath = function(data) {
    var path = data.path;
    var prefix = data.prefix;
    var postPrefix = data.postPrefix;
    if (isNodeJS && pathHelper && data.hasOwnProperty('req')) {
        if (data.sameLevel || !postPrefix) {
            path = pathHelper.dirname(data.req.path);
        } else {
            path = data.req.path;
        }

        if (prefix) {
            path = prefix + '/' + path;
        }

        if (postPrefix) {
            path += '/' + postPrefix;
        }
    }

    return path + '/' + common.normalizeString(data.id + '-' + data.string);
};

var getYears = exports.getYears = common.getYears = function() {
    var now = new Date();
    var currentYear = now.getFullYear();
    var years = [];

    for (var i = currentYear; i > currentYear - 101; i--) {
        years.push(i);
    }
    return years;
};

var getAllFromRange = exports.getAllFromRange = common.getAllFromRange = function(start, end, format) {
    var returner = [];
    var pad = Number.MAX_VALUE;

    if (format === 'padding') {
        pad = 10;
    }

    // Zero padding.
    for (var i = start; i < pad && i <= end; i++) {
        var item = i.toString();
        if (format === 'padding') {
            returner.push('0' + item);
        } else {
            returner.push(item);
        }
    }

    if (format === 'padding') {
        // We have done padding, so start iterating at value of pad.
        for (var i = pad; i <= end; i++) {
            returner.push(i.toString());
        }
    }

    return returner;
};

// maxTitleLength defined in generic/title-chars-left.html
// @return boolean: true for valid
var validateVideoImage = exports.validateVideoImage = common.validateVideoImage = function(values, elemsParent, elemsIsArray, callback) {
    var error = null,
        i = 0;
    for(var key in values){
        if(values[key].length > 0){
            i++;
        }
    }
    if(i > 1){
        error = 'Please submit only 1 piece of evidence! (video or image)';
    }

    callback(error, values);
};
// maxTitleLength defined in generic/title-chars-left.html
// @return boolean: true for valid
var validateFormTitle = exports.validateFormTitle = common.validateFormTitle = function(value, elemsParent, elemsIsArray, callback) {
    var error = null;

    if (value.length === 0) {
        error = 'need one!';
    } else if (value.length > common.maxTitleLength) {
        error = 'too long!';
    }

    callback(error, value);
};
var validateURL = exports.validateURL = common.validateURL = function(value, callback) {

    var error = null;
    var reg_exp = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/;

    if (!reg_exp.test(value)) {
        error = 'provide a valid URL!';
    }

    callback(error, value);
};
var validateComment = exports.validateComment = common.validateComment = function(value, callback) {
    var error = null;

    if (value.length <= 3) {
        error = 'write some more!';
    }

    callback(error, value);
};

// --- CHALLENGE PUBLISHED SETTING ---
var challengePublished = exports.challengePublished = common.challengePublished = function() {
    return false;
}

// Used at client and server side.
var validateDateTimeOccurred = exports.validateDateTimeOccurred = common.validateDateTimeOccurred = function(value, elemsParent, elemsIsArray, callback) {
    var error = null;
    var date = null;

    // We are dealing with an array of values (dd, mm, yyyy, h, m, s)
    var day = value[0];
    var month = value[1];
    var year = value[2];
    var hour = value[3];
    var minute = value[4];
    // var second = value[5];

    // If they didn't select a date at all, that's fine -- the date is optional.
    if (day !== common.dayDefault() ||
        month !== common.monthDefault() ||
        year !== common.yearDefault() ||
        hour !== common.hourDefault() ||
        minute !== common.minuteDefault()) {
        // second !== common.secondDefault()) {
            // There is at least one field not set to its default (placeholder), so
            // try to construct a date object.

            day = parseInt(day);
            month = parseInt(month);
            year = parseInt(year);
            hour = parseInt(hour);
            minute = parseInt(minute);
            // second = parseInt(second);

            // Try to construct a date object out of these fields' values.
            // var date = new Date(year, month, day, hour, minute, second);
            date = new Date();
            date.setUTCFullYear(year);
            date.setUTCMonth(month - 1);
            date.setUTCDate(day);
            date.setUTCHours(hour);
            date.setUTCMinutes(minute);
            // date.setUTCSeconds(second);

            if (isNaN(date.getTime()) || date.getUTCDate() !== day || date.getUTCMonth() + 1 !== month || date.getUTCFullYear() !== year || date.getUTCHours() !== hour || date.getUTCMinutes() !== minute) {
             // date.getUTCSeconds() !== second) {
                // Invalid date.
                error = 'not valid!';
            }
        }

    callback(error, date);
};

// Normally 117 characters to allow t.co linking of the resource.
// Ref: https://blog.twitter.com/2012/upcoming-tco-changes
// For Verily challenge, hashtag is #VerilyLive which takes up 11 additional characters. To counter for whitespace, rounding to 100.
var maxTitleLength = exports.maxTitleLength = common.maxTitleLength = 100;

var dayDefault = exports.dayDefault = common.dayDefault = function() {
    return "Day";
};

var monthDefault = exports.monthDefault = common.monthDefault = function() {
    return "Month";
};

var yearDefault = exports.yearDefault = common.yearDefault = function() {
    return "Year";
};

var hourDefault = exports.hourDefault = common.hourDefault = function() {
    return "Hours";
};

var minuteDefault = exports.minuteDefault = common.minuteDefault = function() {
    return "Minutes";
};

var secondDefault = exports.secondDefault = common.secondDefault = function() {
    return "Seconds";
};

var properUser = exports.properUser = common.properUser = function(req) {
    return !(req.user.type === 'provisional' && process.env.BLOCK_PROVISIONAL_USERS == 1) && req.user.active;
}

var isUserContentShow = exports.isUserContentShow = common.isUserContentShow = function(user) {
    return !(user.type === 'provisional' && process.env.HIDE_PROVISIONAL_USERS_CONTENT == 1);
}

var isItemShow = exports.isItemShow = common.isItemShow = function(item){
    return !(item.hasOwnProperty('show') && !item.show);
}
<commit_msg>allow null date for bulk question upload<commit_after>// Node.js / browser support
var isNodeJS = false;
if (typeof exports === 'undefined') {
    exports = {};
}

if (typeof module !== 'undefined') {
    isNodeJS = true;
}

var path;

if (isNodeJS) {
    pathHelper = require('path');
}

// Common namespace for browsers
var common = {};

// --- CHALLENGE ACTIVE SETTING ---
// Set to true to enable challenge active mode
// so that the routes are requestable.
// This is a function so we can return a boolean
// based on the current date being within a set date range, for example.
var challengeActive = exports.challengeActive = common.challengeActive = function() {
    return true;
}

var formAbsoluteURI = exports.formAbsoluteURI = common.formAbsoluteURI = function(path, options) {
    if (isNodeJS) {
        var url = require('url');

        if (!options) {
            options = require('../../enums.json').options;
        }

        if (path) {
            options.pathname = path;
        }

        return url.format(options);
    }
}

var tagize = exports.tagize = common.tagize = function(string) {
    return splitIntoTags(string).map(normalizeTag);
};

var campaign = exports.campaign = common.campaign = function() {
    var campaigns = {
        trial: 'VerilyTrial',
        main: 'VerilyLive'
    }
    return campaigns.main;
}

var campaigner = exports.campaigner = common.campaigner = function(medium, text, link) {
    if (medium === 'twitter') {
        return {
            hashtags: campaign()
        };
    } else if (medium === 'email') {
        return {
            subject: text + ' #' + campaign(),
            body: text + ' – ' +  link + ' %0D%0A%0D%0AAnswer this with Verily, a crowdsourced verification platform.'
        };
    }
};

var splitIntoTags = exports.splitIntoTags = common.splitIntoTags = function(string) {
    return string.split(',').filter(function(tag) {
        // Do not include just whitespace elements.
        if (tag && !(/^\s+$/.test(tag))) {
            return tag;
        }

    });
};

// Make tags friendly for URIs.
// Replace multiple instances of whitespace with '-'.
// e.g. turn " " into "-".
var normalizeTag = exports.normalizeTag = common.normalizeTag = exports.normalizeString = common.normalizeString = function(tag) {
    // Just remove apostrophes, don't replace them with '-'.
    // If after the first replace there is just 1 '-' at start or end, remove it, or if there are 2 or more hyphens (-), trim to 1 '-'.
    return tag.trim().toLowerCase().replace(/'/g, '').replace(/[\s/\\#._!@$£€%^?<>{}\[\]&*+=:;"`~]+/g, '-').replace(/-{2,}/g, '-' ).replace(/(^-)?(-$)?/g, '');
};

// Pretty paths for canonical URLs
var prettyPath = exports.prettyPath = common.prettyPath = function(data) {
    var path = data.path;
    var prefix = data.prefix;
    var postPrefix = data.postPrefix;
    if (isNodeJS && pathHelper && data.hasOwnProperty('req')) {
        if (data.sameLevel || !postPrefix) {
            path = pathHelper.dirname(data.req.path);
        } else {
            path = data.req.path;
        }

        if (prefix) {
            path = prefix + '/' + path;
        }

        if (postPrefix) {
            path += '/' + postPrefix;
        }
    }

    return path + '/' + common.normalizeString(data.id + '-' + data.string);
};

var getYears = exports.getYears = common.getYears = function() {
    var now = new Date();
    var currentYear = now.getFullYear();
    var years = [];

    for (var i = currentYear; i > currentYear - 101; i--) {
        years.push(i);
    }
    return years;
};

var getAllFromRange = exports.getAllFromRange = common.getAllFromRange = function(start, end, format) {
    var returner = [];
    var pad = Number.MAX_VALUE;

    if (format === 'padding') {
        pad = 10;
    }

    // Zero padding.
    for (var i = start; i < pad && i <= end; i++) {
        var item = i.toString();
        if (format === 'padding') {
            returner.push('0' + item);
        } else {
            returner.push(item);
        }
    }

    if (format === 'padding') {
        // We have done padding, so start iterating at value of pad.
        for (var i = pad; i <= end; i++) {
            returner.push(i.toString());
        }
    }

    return returner;
};

// maxTitleLength defined in generic/title-chars-left.html
// @return boolean: true for valid
var validateVideoImage = exports.validateVideoImage = common.validateVideoImage = function(values, elemsParent, elemsIsArray, callback) {
    var error = null,
        i = 0;
    for(var key in values){
        if(values[key].length > 0){
            i++;
        }
    }
    if(i > 1){
        error = 'Please submit only 1 piece of evidence! (video or image)';
    }

    callback(error, values);
};
// maxTitleLength defined in generic/title-chars-left.html
// @return boolean: true for valid
var validateFormTitle = exports.validateFormTitle = common.validateFormTitle = function(value, elemsParent, elemsIsArray, callback) {
    var error = null;

    if (value.length === 0) {
        error = 'need one!';
    } else if (value.length > common.maxTitleLength) {
        error = 'too long!';
    }

    callback(error, value);
};
var validateURL = exports.validateURL = common.validateURL = function(value, callback) {

    var error = null;
    var reg_exp = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/;

    if (!reg_exp.test(value)) {
        error = 'provide a valid URL!';
    }

    callback(error, value);
};
var validateComment = exports.validateComment = common.validateComment = function(value, callback) {
    var error = null;

    if (value.length <= 3) {
        error = 'write some more!';
    }

    callback(error, value);
};

// --- CHALLENGE PUBLISHED SETTING ---
var challengePublished = exports.challengePublished = common.challengePublished = function() {
    return false;
}

// Used at client and server side.
var validateDateTimeOccurred = exports.validateDateTimeOccurred = common.validateDateTimeOccurred = function(value, elemsParent, elemsIsArray, callback) {
    var error = null;
    var date = null;

    if (value && Object.prototype.toString.call(value) === '[object Array]') {
        // We are dealing with an array of values (dd, mm, yyyy, h, m, s)
        var day = value[0];
        var month = value[1];
        var year = value[2];
        var hour = value[3];
        var minute = value[4];
        // var second = value[5];

        // If they didn't select a date at all, that's fine -- the date is optional.
        if (day !== common.dayDefault() ||
            month !== common.monthDefault() ||
            year !== common.yearDefault() ||
            hour !== common.hourDefault() ||
            minute !== common.minuteDefault()) {
            // second !== common.secondDefault()) {
                // There is at least one field not set to its default (placeholder), so
                // try to construct a date object.

                day = parseInt(day);
                month = parseInt(month);
                year = parseInt(year);
                hour = parseInt(hour);
                minute = parseInt(minute);
                // second = parseInt(second);

                // Try to construct a date object out of these fields' values.
                // var date = new Date(year, month, day, hour, minute, second);
                date = new Date();
                date.setUTCFullYear(year);
                date.setUTCMonth(month - 1);
                date.setUTCDate(day);
                date.setUTCHours(hour);
                date.setUTCMinutes(minute);
                // date.setUTCSeconds(second);

                if (isNaN(date.getTime()) || date.getUTCDate() !== day || date.getUTCMonth() + 1 !== month || date.getUTCFullYear() !== year || date.getUTCHours() !== hour || date.getUTCMinutes() !== minute) {
                 // date.getUTCSeconds() !== second) {
                    // Invalid date.
                    error = 'not valid!';
                }
            }
    }

    callback(error, date);
};

// Normally 117 characters to allow t.co linking of the resource.
// Ref: https://blog.twitter.com/2012/upcoming-tco-changes
// For Verily challenge, hashtag is #VerilyLive which takes up 11 additional characters. To counter for whitespace, rounding to 100.
var maxTitleLength = exports.maxTitleLength = common.maxTitleLength = 100;

var dayDefault = exports.dayDefault = common.dayDefault = function() {
    return "Day";
};

var monthDefault = exports.monthDefault = common.monthDefault = function() {
    return "Month";
};

var yearDefault = exports.yearDefault = common.yearDefault = function() {
    return "Year";
};

var hourDefault = exports.hourDefault = common.hourDefault = function() {
    return "Hours";
};

var minuteDefault = exports.minuteDefault = common.minuteDefault = function() {
    return "Minutes";
};

var secondDefault = exports.secondDefault = common.secondDefault = function() {
    return "Seconds";
};

var properUser = exports.properUser = common.properUser = function(req) {
    return !(req.user.type === 'provisional' && process.env.BLOCK_PROVISIONAL_USERS == 1) && req.user.active;
}

var isUserContentShow = exports.isUserContentShow = common.isUserContentShow = function(user) {
    return !(user.type === 'provisional' && process.env.HIDE_PROVISIONAL_USERS_CONTENT == 1);
}

var isItemShow = exports.isItemShow = common.isItemShow = function(item){
    return !(item.hasOwnProperty('show') && !item.show);
}
<|endoftext|>


<commit_before>var Filter = (function () {

function mit_edu_stream_name_match(message, operand) {
    // MIT users expect narrowing to "social" to also show messages to /^(un)*social(.d)*$/
    // (unsocial, ununsocial, social.d, etc)
    // TODO: hoist the regex compiling out of the closure
    var m = /^(?:un)*(.+?)(?:\.d)*$/i.exec(operand);
    var base_stream_name = operand;
    if (m !== null && m[1] !== undefined) {
        base_stream_name = m[1];
    }
    var related_regexp = new RegExp(/^(un)*/.source + util.escape_regexp(base_stream_name) + /(\.d)*$/.source, 'i');
    return related_regexp.test(message.stream);
}

function mit_edu_topic_name_match(message, operand) {
    // MIT users expect narrowing to topic "foo" to also show messages to /^foo(.d)*$/
    // (foo, foo.d, foo.d.d, etc)
    // TODO: hoist the regex compiling out of the closure
    var m = /^(.*?)(?:\.d)*$/i.exec(operand);
    var base_topic = m[1];
    var related_regexp;

    // Additionally, MIT users expect the empty instance and
    // instance "personal" to be the same.
    if (base_topic === ''
        || base_topic.toLowerCase() === 'personal'
        || base_topic.toLowerCase() === '(instance "")')
    {
        related_regexp = /^(|personal|\(instance ""\))(\.d)*$/i;
    } else {
        related_regexp = new RegExp(/^/.source + util.escape_regexp(base_topic) + /(\.d)*$/.source, 'i');
    }

    return related_regexp.test(message.subject);
}

function message_in_home(message) {
    if (message.type === "private") {
        return true;
    }

    return stream_data.in_home_view(message.stream);
}

function Filter(operators) {
    if (operators === undefined) {
        this._operators = [];
    } else {
        this._operators = this._canonicalize_operators(operators);
    }
}

var canonical_operators = {"from": "sender", "subject": "topic"};

Filter.canonicalize_operator = function (operator) {
    operator = operator.toLowerCase();
    if (canonical_operators.hasOwnProperty(operator)) {
        return canonical_operators[operator];
    } else {
        return operator;
    }
};

Filter.canonicalize_tuple = function (tuple) {
    var operator = tuple[0];
    var operand = tuple[1];

    operator = Filter.canonicalize_operator(operator);

    switch (operator) {
    case 'stream':
        operand = stream_data.get_name(operand);
        break;
    case 'topic':
        break;
    case 'sender':
    case 'pm-with':
        operand = operand.toString().toLowerCase();
        if (operand === 'me') {
            operand = page_params.email;
        }
        break;
    default:
        operand = operand.toString().toLowerCase();
    }

    // We may want to consider allowing mixed-case operators at some point
    return [operator, operand];
};

/* We use a variant of URI encoding which looks reasonably
   nice and still handles unambiguously cases such as
   spaces in operands.

   This is just for the search bar, not for saving the
   narrow in the URL fragment.  There we do use full
   URI encoding to avoid problematic characters. */
function encodeOperand(operand) {
    return operand.replace(/%/g,  '%25')
                  .replace(/\+/g, '%2B')
                  .replace(/ /g,  '+');
}

function decodeOperand(encoded, operator) {
    if (operator !== 'pm-with' && operator !== 'sender') {
        encoded = encoded.replace(/\+/g, ' ');
    }
    return util.robust_uri_decode(encoded);
}

// Parse a string into a list of operators (see below).
Filter.parse = function (str) {
    var operators   = [];
    var search_term = [];
    var matches = str.match(/"[^"]+"|\S+/g);
    if (matches === null) {
        return operators;
    }
    _.each(matches, function (token) {
        var parts, operator;
        parts = token.split(':');
        if (token[0] === '"' || parts.length === 1) {
            // Looks like a normal search term.
            search_term.push(token);
        } else {
            // Looks like an operator.
            // FIXME: Should we skip unknown operator names here?
            operator = parts.shift();
            operators.push([operator, decodeOperand(parts.join(':'), operator)]);
        }
    });
    // NB: Callers of 'parse' can assume that the 'search' operator is last.
    if (search_term.length > 0) {
        operators.push(['search', search_term.join(' ')]);
    }
    return operators;
};

/* Convert a list of operators to a string.
   Each operator is a key-value pair like

       ['subject', 'my amazing subject']

   These are not keys in a JavaScript object, because we
   might need to support multiple operators of the same type.
*/
Filter.unparse = function (operators) {
    var parts = _.map(operators, function (elem) {
        var operator = elem[0];
        if (operator === 'search') {
            // Search terms are the catch-all case.
            // All tokens that don't start with a known operator and
            // a colon are glued together to form a search term.
            return elem[1];
        } else {
            return elem[0] + ':' + encodeOperand(elem[1].toString());
        }
    });
    return parts.join(' ');
};

Filter.prototype = {
    predicate: function Filter_predicate() {
        if (this._predicate === undefined) {
            this._predicate = this._build_predicate();
        }
        return this._predicate;
    },

    operators: function Filter_operators() {
        return this._operators;
    },

    public_operators: function Filter_public_operators() {
        var safe_to_return = _.filter(this._operators, function (value) {
            // Currently just filter out the "in" keyword.
            return value[0] !== 'in';
        });
        if (safe_to_return.length !== 0) {
            return safe_to_return;
        }
    },

    operands: function Filter_get_operands(operator) {
        return _.chain(this._operators)
            .filter(function (elem) { return elem[0] === operator; })
            .map(function (elem) { return elem[1]; })
            .value();
    },

    has_operand: function Filter_has_operand(operator, operand) {
        return _.any(this._operators, function (elem) {
            return elem[0] === operator && elem[1] === operand;
        });
    },

    has_operator: function Filter_has_operator(operator) {
        return _.any(this._operators, function (elem) {
            return elem[0] === operator;
        });
    },

    is_search: function Filter_is_search() {
        return this.has_operator('search');
    },

    can_apply_locally: function Filter_can_apply_locally() {
        return ! this.is_search();
    },

    _canonicalize_operators: function Filter__canonicalize_operators(operators_mixed_case) {
        return _.map(operators_mixed_case, function (tuple) {
            return Filter.canonicalize_tuple(tuple);
        });
    },

    // Build a filter function from a list of operators.
    _build_predicate: function Filter__build_predicate() {
        var operators = this._operators;

        if (! this.can_apply_locally()) {
            return function () { return true; };
        }

        // FIXME: This is probably pretty slow.
        // We could turn it into something more like a compiler:
        // build JavaScript code in a string and then eval() it.

        return function (message) {
            var operand, i, index;
            for (i = 0; i < operators.length; i++) {
                // Inside this loop, the correct protocol for a test is to
                // * "return false" if the value does not match
                // * "break" if there is a match
                // If you "return true", you circumvent all future operators
                operand = operators[i][1];
                switch (operators[i][0]) {
                case 'is':
                    if (operand === 'private') {
                        if (message.type !== 'private') {
                            return false;
                        }
                    } else if (operand === 'starred') {
                        if (!message.starred) {
                            return false;
                        }
                    } else if (operand === 'mentioned') {
                        if (!message.mentioned) {
                            return false;
                        }
                    } else if (operand === 'alerted') {
                        if (!message.alerted) {
                            return false;
                        }
                    }

                    break;

                case 'in':
                    if (operand === 'home') {
                        return message_in_home(message);
                    }
                    else if (operand === 'all') {
                        break;
                    }
                    break;

                case 'near':
                    break;

                case 'id':
                    return message.id.toString() === operand;

                case 'stream':
                    if (message.type !== 'stream') {
                        return false;
                    }

                    operand = operand.toLowerCase();
                    if (page_params.domain === "mit.edu") {
                        if (!mit_edu_stream_name_match(message, operand)) {
                            return false;
                        }
                    } else if (message.stream.toLowerCase() !== operand) {
                        return false;
                    }
                    break;

                case 'topic':
                    if (message.type !== 'stream') {
                        return false;
                    }

                    operand = operand.toLowerCase();
                    if (page_params.domain === "mit.edu") {
                        if (!mit_edu_topic_name_match(message, operand)) {
                            return false;
                        }
                    } else if (message.subject.toLowerCase() !== operand) {
                        return false;
                    }
                    break;

                case 'sender':
                    if ((message.sender_email.toLowerCase() !== operand)) {
                        return false;
                    }
                    break;

                case 'pm-with':
                    if ((message.type !== 'private') ||
                        message.reply_to.toLowerCase() !== operand.split(',').sort().join(',')) {
                        return false;
                    }
                    break;
                }
            }

            // All filters passed.
            return true;
        };
    }
};

return Filter;

}());
if (typeof module !== 'undefined') {
    module.exports = Filter;
}
<commit_msg>Show @-mentioned messages even for muted streams<commit_after>var Filter = (function () {

function mit_edu_stream_name_match(message, operand) {
    // MIT users expect narrowing to "social" to also show messages to /^(un)*social(.d)*$/
    // (unsocial, ununsocial, social.d, etc)
    // TODO: hoist the regex compiling out of the closure
    var m = /^(?:un)*(.+?)(?:\.d)*$/i.exec(operand);
    var base_stream_name = operand;
    if (m !== null && m[1] !== undefined) {
        base_stream_name = m[1];
    }
    var related_regexp = new RegExp(/^(un)*/.source + util.escape_regexp(base_stream_name) + /(\.d)*$/.source, 'i');
    return related_regexp.test(message.stream);
}

function mit_edu_topic_name_match(message, operand) {
    // MIT users expect narrowing to topic "foo" to also show messages to /^foo(.d)*$/
    // (foo, foo.d, foo.d.d, etc)
    // TODO: hoist the regex compiling out of the closure
    var m = /^(.*?)(?:\.d)*$/i.exec(operand);
    var base_topic = m[1];
    var related_regexp;

    // Additionally, MIT users expect the empty instance and
    // instance "personal" to be the same.
    if (base_topic === ''
        || base_topic.toLowerCase() === 'personal'
        || base_topic.toLowerCase() === '(instance "")')
    {
        related_regexp = /^(|personal|\(instance ""\))(\.d)*$/i;
    } else {
        related_regexp = new RegExp(/^/.source + util.escape_regexp(base_topic) + /(\.d)*$/.source, 'i');
    }

    return related_regexp.test(message.subject);
}

function message_in_home(message) {
    if (message.type === "private" || message.mentioned) {
        return true;
    }

    return stream_data.in_home_view(message.stream);
}

function Filter(operators) {
    if (operators === undefined) {
        this._operators = [];
    } else {
        this._operators = this._canonicalize_operators(operators);
    }
}

var canonical_operators = {"from": "sender", "subject": "topic"};

Filter.canonicalize_operator = function (operator) {
    operator = operator.toLowerCase();
    if (canonical_operators.hasOwnProperty(operator)) {
        return canonical_operators[operator];
    } else {
        return operator;
    }
};

Filter.canonicalize_tuple = function (tuple) {
    var operator = tuple[0];
    var operand = tuple[1];

    operator = Filter.canonicalize_operator(operator);

    switch (operator) {
    case 'stream':
        operand = stream_data.get_name(operand);
        break;
    case 'topic':
        break;
    case 'sender':
    case 'pm-with':
        operand = operand.toString().toLowerCase();
        if (operand === 'me') {
            operand = page_params.email;
        }
        break;
    default:
        operand = operand.toString().toLowerCase();
    }

    // We may want to consider allowing mixed-case operators at some point
    return [operator, operand];
};

/* We use a variant of URI encoding which looks reasonably
   nice and still handles unambiguously cases such as
   spaces in operands.

   This is just for the search bar, not for saving the
   narrow in the URL fragment.  There we do use full
   URI encoding to avoid problematic characters. */
function encodeOperand(operand) {
    return operand.replace(/%/g,  '%25')
                  .replace(/\+/g, '%2B')
                  .replace(/ /g,  '+');
}

function decodeOperand(encoded, operator) {
    if (operator !== 'pm-with' && operator !== 'sender') {
        encoded = encoded.replace(/\+/g, ' ');
    }
    return util.robust_uri_decode(encoded);
}

// Parse a string into a list of operators (see below).
Filter.parse = function (str) {
    var operators   = [];
    var search_term = [];
    var matches = str.match(/"[^"]+"|\S+/g);
    if (matches === null) {
        return operators;
    }
    _.each(matches, function (token) {
        var parts, operator;
        parts = token.split(':');
        if (token[0] === '"' || parts.length === 1) {
            // Looks like a normal search term.
            search_term.push(token);
        } else {
            // Looks like an operator.
            // FIXME: Should we skip unknown operator names here?
            operator = parts.shift();
            operators.push([operator, decodeOperand(parts.join(':'), operator)]);
        }
    });
    // NB: Callers of 'parse' can assume that the 'search' operator is last.
    if (search_term.length > 0) {
        operators.push(['search', search_term.join(' ')]);
    }
    return operators;
};

/* Convert a list of operators to a string.
   Each operator is a key-value pair like

       ['subject', 'my amazing subject']

   These are not keys in a JavaScript object, because we
   might need to support multiple operators of the same type.
*/
Filter.unparse = function (operators) {
    var parts = _.map(operators, function (elem) {
        var operator = elem[0];
        if (operator === 'search') {
            // Search terms are the catch-all case.
            // All tokens that don't start with a known operator and
            // a colon are glued together to form a search term.
            return elem[1];
        } else {
            return elem[0] + ':' + encodeOperand(elem[1].toString());
        }
    });
    return parts.join(' ');
};

Filter.prototype = {
    predicate: function Filter_predicate() {
        if (this._predicate === undefined) {
            this._predicate = this._build_predicate();
        }
        return this._predicate;
    },

    operators: function Filter_operators() {
        return this._operators;
    },

    public_operators: function Filter_public_operators() {
        var safe_to_return = _.filter(this._operators, function (value) {
            // Currently just filter out the "in" keyword.
            return value[0] !== 'in';
        });
        if (safe_to_return.length !== 0) {
            return safe_to_return;
        }
    },

    operands: function Filter_get_operands(operator) {
        return _.chain(this._operators)
            .filter(function (elem) { return elem[0] === operator; })
            .map(function (elem) { return elem[1]; })
            .value();
    },

    has_operand: function Filter_has_operand(operator, operand) {
        return _.any(this._operators, function (elem) {
            return elem[0] === operator && elem[1] === operand;
        });
    },

    has_operator: function Filter_has_operator(operator) {
        return _.any(this._operators, function (elem) {
            return elem[0] === operator;
        });
    },

    is_search: function Filter_is_search() {
        return this.has_operator('search');
    },

    can_apply_locally: function Filter_can_apply_locally() {
        return ! this.is_search();
    },

    _canonicalize_operators: function Filter__canonicalize_operators(operators_mixed_case) {
        return _.map(operators_mixed_case, function (tuple) {
            return Filter.canonicalize_tuple(tuple);
        });
    },

    // Build a filter function from a list of operators.
    _build_predicate: function Filter__build_predicate() {
        var operators = this._operators;

        if (! this.can_apply_locally()) {
            return function () { return true; };
        }

        // FIXME: This is probably pretty slow.
        // We could turn it into something more like a compiler:
        // build JavaScript code in a string and then eval() it.

        return function (message) {
            var operand, i, index;
            for (i = 0; i < operators.length; i++) {
                // Inside this loop, the correct protocol for a test is to
                // * "return false" if the value does not match
                // * "break" if there is a match
                // If you "return true", you circumvent all future operators
                operand = operators[i][1];
                switch (operators[i][0]) {
                case 'is':
                    if (operand === 'private') {
                        if (message.type !== 'private') {
                            return false;
                        }
                    } else if (operand === 'starred') {
                        if (!message.starred) {
                            return false;
                        }
                    } else if (operand === 'mentioned') {
                        if (!message.mentioned) {
                            return false;
                        }
                    } else if (operand === 'alerted') {
                        if (!message.alerted) {
                            return false;
                        }
                    }

                    break;

                case 'in':
                    if (operand === 'home') {
                        return message_in_home(message);
                    }
                    else if (operand === 'all') {
                        break;
                    }
                    break;

                case 'near':
                    break;

                case 'id':
                    return message.id.toString() === operand;

                case 'stream':
                    if (message.type !== 'stream') {
                        return false;
                    }

                    operand = operand.toLowerCase();
                    if (page_params.domain === "mit.edu") {
                        if (!mit_edu_stream_name_match(message, operand)) {
                            return false;
                        }
                    } else if (message.stream.toLowerCase() !== operand) {
                        return false;
                    }
                    break;

                case 'topic':
                    if (message.type !== 'stream') {
                        return false;
                    }

                    operand = operand.toLowerCase();
                    if (page_params.domain === "mit.edu") {
                        if (!mit_edu_topic_name_match(message, operand)) {
                            return false;
                        }
                    } else if (message.subject.toLowerCase() !== operand) {
                        return false;
                    }
                    break;

                case 'sender':
                    if ((message.sender_email.toLowerCase() !== operand)) {
                        return false;
                    }
                    break;

                case 'pm-with':
                    if ((message.type !== 'private') ||
                        message.reply_to.toLowerCase() !== operand.split(',').sort().join(',')) {
                        return false;
                    }
                    break;
                }
            }

            // All filters passed.
            return true;
        };
    }
};

return Filter;

}());
if (typeof module !== 'undefined') {
    module.exports = Filter;
}
<|endoftext|>


<commit_before>(function() {
    'use strict';

    function Point(x, y) {
        this.x = x;
        this.y = y;
    }

    var simplex = new SimplexNoise();

    function setupCanvas(canvas, ctx) {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }

    function setupState(width, height) {
        var scale = window.devicePixelRatio > 1 ? 0.015 : 0.0075;
        var offset = Math.max(width, height) * scale;
        var segmentSize = offset / 2;
        return {
            w: width,
            h: height,
            segmentSize: segmentSize,
            lastPoint: new Point(0, 0),
        }
    }

    function draw(ctx, state, step) {
        var w = state.w;
        var h = state.h;
        var segmentSize = state.segmentSize;

        if (step * segmentSize > w + segmentSize) {
            return state;
        }

        var lastPoint = state.lastPoint;
        var px = lastPoint.x;
        var py = lastPoint.y;
        var offset = simplex.noise3d(px/100, py/100, step/100) * 5;
        var nx = step * segmentSize
        var ny = h/2 + offset;

        ctx.lineWidth = 1;
        ctx.beginPath();

        ctx.moveTo(px, py);
        ctx.lineTo(nx, ny);
        ctx.stroke();

        state.lastPoint = new Point(nx, ny);
        return state;
    }

    Muybridge.run({
        draw: draw,
        setup: setupState,
        setupCanvas: setupCanvas,
    });
})();
<commit_msg>contour: many lines<commit_after>(function() {
    'use strict';

    var simplex = new SimplexNoise();

    function setupCanvas(canvas, ctx) {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }

    function setupState(width, height) {
        var scale = window.devicePixelRatio > 1 ? 0.015 : 0.0075;
        var offset = Math.max(width, height) * scale;
        var segmentSize = offset / 2;
        var lineCount = height / segmentSize;

        var lastPoints = [];
        for (var i = 0; i < lineCount; i++) {
            lastPoints[i] = {x: 0, y: 0};
        }
        return {
            w: width,
            h: height,
            segmentSize: segmentSize,
            lastPoints: lastPoints,
        }
    }

    function draw(ctx, state, step) {
        var w = state.w;
        var h = state.h;
        var segmentSize = state.segmentSize;

        if (step * segmentSize > w + segmentSize) {
            return state;
        }

        ctx.lineWidth = 2;
        ctx.beginPath();

        var lastPoints = state.lastPoints;
        var nextPoints = [];
        for (var i = 0; i < lastPoints.length; i++) {
            var lastPoint = lastPoints[i];
            var px = lastPoint.x;
            var py = lastPoint.y;
            var offset = simplex.noise3d(px/100, py/100, step/100) * 5;
            var nx = step * segmentSize;
            var ny = i * segmentSize + offset;

            ctx.moveTo(px, py);
            ctx.lineTo(nx, ny);

            nextPoints.push({x: nx, y: ny});
        }
        ctx.stroke();

        state.lastPoints = nextPoints;
        return state;
    }

    Muybridge.run({
        draw: draw,
        setup: setupState,
        setupCanvas: setupCanvas,
    });
})();
<|endoftext|>


<commit_before>
var loop;
var level;

function parse(str) {

    var i = 0;

     loop = setInterval(function () {

        i++;

        console.log("ROUND " + i + " ------------------");

        check();
         var element = Player.checkNextField(Map.map);
        switch (element.name) {
            case 'r':
                Player.canMove = true;
                var audio = new Audio('assets/sounds/coin.mp3');
                audio.play();
                break;
            case 'e':
                console.log("yo");
                Player.canMove = false;
                element.attack();
                break;
            default:
                Player.canMove = true;
                break;
        }

        eval(str);

        Display.draw(Map.map);

        if(i>25){ clearInterval(loop);}

    }, 500);

}

function check() {
    if (Player.getX() === 10){

        clearInterval(loop);
        level++;
        $('#console-log-text').text('');
        console.log("Victory!");
        Player.health = 100;
        Map.map.splice(0,Map.map.length);
        loadMap(level);
    }
    if(Player.health <= 0){
        clearInterval(loop);
        $('#console-log-text').text('');
        console.log("Defeat!");
        Map.map.splice(0,Map.map.length);
        loadMap(level);
    }
}

function loadMap(level) {
    $.when(
        $.get("assets/levels/level" + level + ".txt")
    ).then(function (response) {
        Player.constructor();
        Display.setPlayer = Player;
        console.log("in loadmap");
        Map.parseLevel(response);
        Display.draw(Map.map);
    });
};

$(function () {
   level = 1;
   loadMap(level);
});

<commit_msg>Remove coin if user get it<commit_after>
var loop;
var level;

function parse(str) {

    var i = 0;

     loop = setInterval(function () {

        i++;

        console.log("ROUND " + i + " ------------------");

        check();
         var element = Player.checkNextField(Map.map);
        switch (element.name) {
            case 'r':
                Player.canMove = true;
                var audio = new Audio('assets/sounds/coin.mp3');
                audio.play();
                Map.map.splice(Map.map.indexOf(element), 1);
                break;
            case 'e':
                console.log("yo");
                Player.canMove = false;
                element.attack();
                break;
            default:
                Player.canMove = true;
                break;
        }

        eval(str);

        Display.draw(Map.map);

        if(i>25){ clearInterval(loop);}

    }, 500);

}

function check() {
    if (Player.getX() === 10){
        Map.map.forEach(function (element){
           if(element.name == 'r'){
               return false;
           }
        });
        clearInterval(loop);
        level++;
        $('#console-log-text').text('');
        console.log("Victory!");
        Player.health = 100;
        Map.map.splice(0,Map.map.length);
        loadMap(level);
    }
    if(Player.health <= 0){
        clearInterval(loop);
        $('#console-log-text').text('');
        console.log("Defeat!");
        Map.map.splice(0,Map.map.length);
        loadMap(level);
    }
}

function loadMap(level) {
    $.when(
        $.get("assets/levels/level" + level + ".txt")
    ).then(function (response) {
        Player.constructor();
        Display.setPlayer = Player;
        console.log("in loadmap");
        Map.parseLevel(response);
        Display.draw(Map.map);
    });
};

$(function () {
   level = 1;
   loadMap(level);
});

<|endoftext|>


<commit_before>const socket = io('https://noters.ir/socket.io');
var player, nobat, name , clicked = false;
$('form').submit(function () {
    name = $("#nameInp").val();
    var mode = $("#modeSel").val();
    socket.emit('game', {
        name: name,
        mode: mode
    });
    return false;
});

socket.on('waitG', () => {
    player = 1;
    $("#sendBtn").html("please wait for second player ...");
    $("#sendBtn").css('color', 'red');
    $("#sendBtn").prop('disabled', true);
});

socket.on('startG', (data) => {
    if (player) {
        player = data.p1;
    } else {
        player = data.p2;
    }
    $("#sendBtn").html("after 7 seconds, game willbe starting");
    $("#sendBtn").css('color', 'black');
    $("#sendBtn").prop('disabled', true);
    setTimeout(() => {
        $("#body").empty();
        $("#head").empty();
        $("head").append(`
            <meta charset="utf-8">
            <meta name="viewport" content="initial-scale=1.0">
            <title>game</title>
            <link href="http://fonts.googleapis.com/css?family=Raleway:300,400,400,100" rel="stylesheet" type="text/css">
            <link rel="stylesheet" href="css/standardize.css">
            <link rel="stylesheet" href="css/game-grid.css">
            <link rel="stylesheet" href="css/game.css">`);
        $("#body").append(`

                <button id="0" class="_button _button-1 js-btn-g-v"></button>
                <button id="1" class="_button _button-2 js-btn-g-v"></button>
                <button id="2" class="_button _button-3 js-btn-g-v"></button>
                <button id="3" class="_button _button-4 js-btn-g-v"></button>
                <button id="4" class="_button _button-5 js-btn-g-v"></button>
                <button id="5" class="_button _button-6 js-btn-g-v"></button>
                <button id="6" class="_button _button-7 js-btn-g-v"></button>
                <button id="7" class="_button _button-8 js-btn-g-v"></button>
                <button id="8" class="_button _button-9 js-btn-g-v"></button>

you are : ${player==0?'x':'o'}

${player==0?'you\'r':'his/m'} turn.

                <button class="_button _button-10" id="btnCancel">cancel</button>

`);
        $("#body").attr('class', 'container container-1 clearfix');
    }, 7 * 1000);
});

$("body").on('click', '#btns', function (e) {
    if (!clicked) {
        var number = parseInt($(e.target).attr('id'));
        if (isNaN(number)) return;
        socket.emit('btn', {
            name: name,
            i: parseInt(number / 3),
            j: number % 3
        });
        clicked = true;
    } else {}
});

$("body").on('click', '#btnCancel', () => {
    if (confirm('are you sure?')) {
        socket.emit('disconnecting', 'by user');
        window.open('', '_self').close();
        window.close();
        close();
        $("#body").empty();
        $("#head").empty();
        $("head").append(`<link rel="stylesheet" href="css/index.css">`);
        $("#body").append(`<p class="text">Good Bye</p>`);
    }
});

socket.on('btnR', (r) => {
    if (r.r == true) {
        $("#" + r.num).html(r.p == 0 ? 'x' : 'o');
        $("#turn").html((r.p == player ? 'his/m' : 'you\'r') + " turn.");
    } else {
        alert("its his/m turn or select disable button.");
    }
    clicked = false;
})

socket.on('win', (data) => {
    $("#body").empty();
    $("#head").empty();
    $("head").append(`<link rel="stylesheet" href="css/index.css">`);
    if (player == data.winner) {
        $("#body").append(`<p class="text">YOU WON</p><p class="text">you'r rating is ${data.rating}</p>`);
    } else {
        $("#body").append(`<p class="text">GAME OVER</p>`);
    }
})

socket.on('equ', (data) => {
    $("#body").empty();
    $("#head").empty();
    $("head").append(`<link rel="stylesheet" href="css/index.css">`);
    $("#body").append(`<p class="text">YOU EQUATED</p><p class="text">you'r rating is ${data.players[player]} </p>`);
})

socket.on('dis', () => {
    $("#body").empty();
    $("#head").empty();
    $("head").append(`<link rel="stylesheet" href="css/index.css">`);
    $("#body").append(`<p class="text">DISCONNECTION</br>YOU WON</br>(but not saved in rating.)</p>`);
})
<commit_msg>Update indexj.js<commit_after>const socket = io('https://noters.ir:430');
var player, nobat, name , clicked = false;
$('form').submit(function () {
    name = $("#nameInp").val();
    var mode = $("#modeSel").val();
    socket.emit('game', {
        name: name,
        mode: mode
    });
    return false;
});

socket.on('waitG', () => {
    player = 1;
    $("#sendBtn").html("please wait for second player ...");
    $("#sendBtn").css('color', 'red');
    $("#sendBtn").prop('disabled', true);
});

socket.on('startG', (data) => {
    if (player) {
        player = data.p1;
    } else {
        player = data.p2;
    }
    $("#sendBtn").html("after 7 seconds, game willbe starting");
    $("#sendBtn").css('color', 'black');
    $("#sendBtn").prop('disabled', true);
    setTimeout(() => {
        $("#body").empty();
        $("#head").empty();
        $("head").append(`
            <meta charset="utf-8">
            <meta name="viewport" content="initial-scale=1.0">
            <title>game</title>
            <link href="http://fonts.googleapis.com/css?family=Raleway:300,400,400,100" rel="stylesheet" type="text/css">
            <link rel="stylesheet" href="css/standardize.css">
            <link rel="stylesheet" href="css/game-grid.css">
            <link rel="stylesheet" href="css/game.css">`);
        $("#body").append(`

                <button id="0" class="_button _button-1 js-btn-g-v"></button>
                <button id="1" class="_button _button-2 js-btn-g-v"></button>
                <button id="2" class="_button _button-3 js-btn-g-v"></button>
                <button id="3" class="_button _button-4 js-btn-g-v"></button>
                <button id="4" class="_button _button-5 js-btn-g-v"></button>
                <button id="5" class="_button _button-6 js-btn-g-v"></button>
                <button id="6" class="_button _button-7 js-btn-g-v"></button>
                <button id="7" class="_button _button-8 js-btn-g-v"></button>
                <button id="8" class="_button _button-9 js-btn-g-v"></button>

you are : ${player==0?'x':'o'}

${player==0?'you\'r':'his/m'} turn.

                <button class="_button _button-10" id="btnCancel">cancel</button>

`);
        $("#body").attr('class', 'container container-1 clearfix');
    }, 7 * 1000);
});

$("body").on('click', '#btns', function (e) {
    if (!clicked) {
        var number = parseInt($(e.target).attr('id'));
        if (isNaN(number)) return;
        socket.emit('btn', {
            name: name,
            i: parseInt(number / 3),
            j: number % 3
        });
        clicked = true;
    } else {}
});

$("body").on('click', '#btnCancel', () => {
    if (confirm('are you sure?')) {
        socket.emit('disconnecting', 'by user');
        window.open('', '_self').close();
        window.close();
        close();
        $("#body").empty();
        $("#head").empty();
        $("head").append(`<link rel="stylesheet" href="css/index.css">`);
        $("#body").append(`<p class="text">Good Bye</p>`);
    }
});

socket.on('btnR', (r) => {
    if (r.r == true) {
        $("#" + r.num).html(r.p == 0 ? 'x' : 'o');
        $("#turn").html((r.p == player ? 'his/m' : 'you\'r') + " turn.");
    } else {
        alert("its his/m turn or select disable button.");
    }
    clicked = false;
})

socket.on('win', (data) => {
    $("#body").empty();
    $("#head").empty();
    $("head").append(`<link rel="stylesheet" href="css/index.css">`);
    if (player == data.winner) {
        $("#body").append(`<p class="text">YOU WON</p><p class="text">you'r rating is ${data.rating}</p>`);
    } else {
        $("#body").append(`<p class="text">GAME OVER</p>`);
    }
})

socket.on('equ', (data) => {
    $("#body").empty();
    $("#head").empty();
    $("head").append(`<link rel="stylesheet" href="css/index.css">`);
    $("#body").append(`<p class="text">YOU EQUATED</p><p class="text">you'r rating is ${data.players[player]} </p>`);
})

socket.on('dis', () => {
    $("#body").empty();
    $("#head").empty();
    $("head").append(`<link rel="stylesheet" href="css/index.css">`);
    $("#body").append(`<p class="text">DISCONNECTION</br>YOU WON</br>(but not saved in rating.)</p>`);
})
<|endoftext|>


<commit_before>
$(document).ready(function(){

    $('.js-menu').each(function(){

        var location = window.location.href;
        location = location.substr(7);
        location = location.substr(0, location.length -1);
        location = location.replace(window.location.host, '');

        var current = $(this).find('a').attr('href');
        if(current)
        	current = current.substr(0, current.length -1);

        if(current == location){
            $(this).addClass('current');
        }
    });

	// === Sidebar navigation === //

	$('.submenu > a').click(function(e)
	{
		e.preventDefault();
		var submenu = $(this).siblings('ul');
		var li = $(this).parents('li');
		var submenus = $('#sidebar li.submenu ul');
		var submenus_parents = $('#sidebar li.submenu');
		if(li.hasClass('open'))
		{
			if(($(window).width() > 768) || ($(window).width() < 479)) {
				submenu.slideUp();
			} else {
				submenu.fadeOut(250);
			}
			li.removeClass('open');
		} else
		{
			if(($(window).width() > 768) || ($(window).width() < 479)) {
				submenus.slideUp();
				submenu.slideDown();
			} else {
				submenus.fadeOut(250);
				submenu.fadeIn(250);
			}
			submenus_parents.removeClass('open');
			li.addClass('open');
		}
	});

	var ul = $('#sidebar > ul');

	$('#sidebar > a').click(function(e)
	{
		e.preventDefault();
		var sidebar = $('#sidebar');
		if(sidebar.hasClass('open'))
		{
			sidebar.removeClass('open');
			ul.slideUp(250);
		} else
		{
			sidebar.addClass('open');
			ul.slideDown(250);
		}
	});

	// === Resize window related === //
	$(window).resize(function()
	{
		if($(window).width() > 479)
		{
			ul.css({'display':'block'});
			$('#content-header .btn-group').css({width:'auto'});
		}
		if($(window).width() < 479)
		{
			ul.css({'display':'none'});
			fix_position();
		}
		if($(window).width() > 768)
		{
			$('#user-nav > ul').css({width:'auto',margin:'0'});
            $('#content-header .btn-group').css({width:'auto'});
		}
	});

	if($(window).width() < 468)
	{
		ul.css({'display':'none'});
		fix_position();
	}

	if($(window).width() > 479)
	{
	   $('#content-header .btn-group').css({width:'auto'});
		ul.css({'display':'block'});
	}

	// === Tooltips === //
	$('.tip').tooltip();
	$('.tip-left').tooltip({ placement: 'left' });
	$('.tip-right').tooltip({ placement: 'right' });
	$('.tip-top').tooltip({ placement: 'top' });
	$('.tip-bottom').tooltip({ placement: 'bottom' });

	// === Search input typeahead === //
	$('#search input[type=text]').typeahead({
		source: ['Dashboard','Form elements','Common Elements','Validation','Wizard','Buttons','Icons','Interface elements','Support','Calendar','Gallery','Reports','Charts','Graphs','Widgets'],
		items: 4
	});

	// === Fixes the position of buttons group in content header and top user navigation === //
	function fix_position()
	{
		var uwidth = $('#user-nav > ul').width();
		$('#user-nav > ul').css({width:uwidth,'margin-left':'-' + uwidth / 2 + 'px'});

        var cwidth = $('#content-header .btn-group').width();
        $('#content-header .btn-group').css({width:cwidth,'margin-left':'-' + uwidth / 2 + 'px'});
	}

	// === Style switcher === //
	$('#style-switcher i').click(function()
	{
		if($(this).hasClass('open'))
		{
			$(this).parent().animate({marginRight:'-=190'});
			$(this).removeClass('open');
		} else
		{
			$(this).parent().animate({marginRight:'+=190'});
			$(this).addClass('open');
		}
		$(this).toggleClass('icon-arrow-left');
		$(this).toggleClass('icon-arrow-right');
	});

	$('#style-switcher a').click(function()
	{
		var style = $(this).attr('href').replace('#','');
		$('.skin-color').attr('href','css/maruti.'+style+'.css');
		$(this).siblings('a').css({'border-color':'transparent'});
		$(this).css({'border-color':'#aaaaaa'});
	});

	$('.lightbox_trigger').click(function(e) {

		e.preventDefault();

		var image_href = $(this).attr("href");

		if ($('#lightbox').length > 0) {

			$('#imgbox').html('

');

			$('#lightbox').slideDown(500);
		}

		else {
			var lightbox =
			'
' +
				'
' +
					'

' +
				'
' +
			'
';

			$('body').append(lightbox);
			$('#lightbox').slideDown(500);
		}

	});

});

<commit_msg>wrong class<commit_after>
$(document).ready(function(){

    $('.js-menu').each(function(){

        var location = window.location.href;
        location = location.substr(7);
        location = location.substr(0, location.length -1);
        location = location.replace(window.location.host, '');

        var current = $(this).find('a').attr('href');
        if(current)
        	current = current.substr(0, current.length -1);

        if(current == location){
            $(this).addClass('active');
        }
    });

	// === Sidebar navigation === //

	$('.submenu > a').click(function(e)
	{
		e.preventDefault();
		var submenu = $(this).siblings('ul');
		var li = $(this).parents('li');
		var submenus = $('#sidebar li.submenu ul');
		var submenus_parents = $('#sidebar li.submenu');
		if(li.hasClass('open'))
		{
			if(($(window).width() > 768) || ($(window).width() < 479)) {
				submenu.slideUp();
			} else {
				submenu.fadeOut(250);
			}
			li.removeClass('open');
		} else
		{
			if(($(window).width() > 768) || ($(window).width() < 479)) {
				submenus.slideUp();
				submenu.slideDown();
			} else {
				submenus.fadeOut(250);
				submenu.fadeIn(250);
			}
			submenus_parents.removeClass('open');
			li.addClass('open');
		}
	});

	var ul = $('#sidebar > ul');

	$('#sidebar > a').click(function(e)
	{
		e.preventDefault();
		var sidebar = $('#sidebar');
		if(sidebar.hasClass('open'))
		{
			sidebar.removeClass('open');
			ul.slideUp(250);
		} else
		{
			sidebar.addClass('open');
			ul.slideDown(250);
		}
	});

	// === Resize window related === //
	$(window).resize(function()
	{
		if($(window).width() > 479)
		{
			ul.css({'display':'block'});
			$('#content-header .btn-group').css({width:'auto'});
		}
		if($(window).width() < 479)
		{
			ul.css({'display':'none'});
			fix_position();
		}
		if($(window).width() > 768)
		{
			$('#user-nav > ul').css({width:'auto',margin:'0'});
            $('#content-header .btn-group').css({width:'auto'});
		}
	});

	if($(window).width() < 468)
	{
		ul.css({'display':'none'});
		fix_position();
	}

	if($(window).width() > 479)
	{
	   $('#content-header .btn-group').css({width:'auto'});
		ul.css({'display':'block'});
	}

	// === Tooltips === //
	$('.tip').tooltip();
	$('.tip-left').tooltip({ placement: 'left' });
	$('.tip-right').tooltip({ placement: 'right' });
	$('.tip-top').tooltip({ placement: 'top' });
	$('.tip-bottom').tooltip({ placement: 'bottom' });

	// === Search input typeahead === //
	$('#search input[type=text]').typeahead({
		source: ['Dashboard','Form elements','Common Elements','Validation','Wizard','Buttons','Icons','Interface elements','Support','Calendar','Gallery','Reports','Charts','Graphs','Widgets'],
		items: 4
	});

	// === Fixes the position of buttons group in content header and top user navigation === //
	function fix_position()
	{
		var uwidth = $('#user-nav > ul').width();
		$('#user-nav > ul').css({width:uwidth,'margin-left':'-' + uwidth / 2 + 'px'});

        var cwidth = $('#content-header .btn-group').width();
        $('#content-header .btn-group').css({width:cwidth,'margin-left':'-' + uwidth / 2 + 'px'});
	}

	// === Style switcher === //
	$('#style-switcher i').click(function()
	{
		if($(this).hasClass('open'))
		{
			$(this).parent().animate({marginRight:'-=190'});
			$(this).removeClass('open');
		} else
		{
			$(this).parent().animate({marginRight:'+=190'});
			$(this).addClass('open');
		}
		$(this).toggleClass('icon-arrow-left');
		$(this).toggleClass('icon-arrow-right');
	});

	$('#style-switcher a').click(function()
	{
		var style = $(this).attr('href').replace('#','');
		$('.skin-color').attr('href','css/maruti.'+style+'.css');
		$(this).siblings('a').css({'border-color':'transparent'});
		$(this).css({'border-color':'#aaaaaa'});
	});

	$('.lightbox_trigger').click(function(e) {

		e.preventDefault();

		var image_href = $(this).attr("href");

		if ($('#lightbox').length > 0) {

			$('#imgbox').html('

');

			$('#lightbox').slideDown(500);
		}

		else {
			var lightbox =
			'
' +
				'
' +
					'

' +
				'
' +
			'
';

			$('body').append(lightbox);
			$('#lightbox').slideDown(500);
		}

	});

});

<|endoftext|>


<commit_before>/**
 * We will expose all methods and properties of CookieMaster
 * through the parent object, for easy extendability
 *
 * @type {Object}
 */
CM = {};

/**
 * Configuration settings for CookieMaster, the loaded version of
 * Cookie Clicker and user-specific settings.
 *
 * @type {Object}
 */
CM.config = {

	cmVersion: '0.1',
	cmIsLoaded: false,
	cmCSS: 'https://rawgithub.com/greenc/CookieMaster/master/styles.css',

	ccURL: 'http://orteil.dashnet.org/cookieclicker/',
	ccVersion: '',
	ccCompatibleVersions: ['1.0402', '1.0403'],

	ccBody: $('body'),
	ccWrapper: $('#wrapper'),
	ccGame: $('#game'),

	// User configurable settings
	settings: {
		cleanUI: {
			label: 'Clean UI',
			desc: 'Hide the top bar, and make other small graphical enhancements to the game interface',
			options: 'toggle',
			current: 'on'
		},
		numFormat: {
			label: 'Number Formatting',
			desc: 'Display numbers in US (123,456,789.0) or European (123.456.789,0) format',
			options: ['US', 'European'],
			current: 'US'
		},
		shortNums: {
			label: 'Short Numbers',
			desc: 'Shorten large numbers with suffixes',
			options: 'toggle',
			current: 'on'
		}
	},

};

/**
 * Initialization method. This is the first thing that gets called
 * when the script runs, and all methods that need to be invoked on
 * startup should be called from here in the order needed.
 */
CM.init = function() {

	var cmCSS = this.config.cmCSS,
		cssID = this.config.cmStyleID;

	//Perform a quick check to make sure CM can run correctly
	if(this.integrityCheck()) {

		this.loadUserSettings();
		this.attachStyleSheet(cmCSS, cssID);
		this.attachSettingsPanel();

		// Apply the current user settings after we've done everything else
		this.applyUserSettings();

		// All done :)
		this.config.cmIsLoaded = true;
		Game.Popup('CookieMaster v.' + this.config.cmVersion + ' loaded successfully!');

	} else {

		this.suicide();
		return false;

	}

};

/**
 * Checks that CookieMaster can run correctly and informs the
 * user if anything is wrong
 *
 * @return {boolean}
 */
CM.integrityCheck = function() {

	var ccVersion = Game.version.toString() || '',
		message = false,
		error = false,
		i;

	if(this.config.cmIsLoaded) {
		// Already loaded
		message = 'Error: CookieMaster is already running!';
		error = true;
	} else if(document.location.href.indexOf(this.config.ccURL) === -1) {
		// Wrong URL
		message = 'Error: This isn\'t the Cookie Clicker URL';
		error = true;
	} else if(!window.jQuery) {
		// jQuery isn't loaded
		message = 'Error: jQuery is not loaded';
		error = true;
	} else if(!Game) {
		// Game class doesn't exist
		message = 'Error: Cookie Clicker does not appear to be initialized';
		error = true;
	}

	// Warn against potential incompatibility
	if(this.compatibilityCheck(ccVersion) === -1) {
		message = 'Warning: This version of Cookie Clicker may not be fully supported!';
	}

	// Alert user to any issues
	if(message) {
		this.alertMessage(message);
	}

	if(error) {

		return false;

	} else {

		// Set some useful config options for later use
		this.config.ccVersion = ccVersion;
		this.config.ccGame = $('#game');

		return true;
	}

};

/**
 * Checks the loaded version of CC against a list of
 * known compatible versions
 *
 * @param  {string} version The version of CC we are running on
 *
 * @return {integer}         Return index of matched version
 */
CM.compatibilityCheck = function(version) {

	var compVersions = this.config.ccCompatibleVersions,
		ccVersion = version || '',
		i;

	for(i = 0; i < compVersions.length; i++) {
		if(compVersions[i].match(ccVersion)) {
			return i;
		}
	}

	return -1;

}

/**
 * Clean up the game interface a little.
 *
 * @param  {boolean} state Turn on or off
 */
CM.cleanUI = function(state) {

	var cssClass = 'cleanUI',
		$body = this.config.ccBody;

	if(state) {
		$body.addClass(cssClass);
	} else {
		$body.removeClass(cssClass);
	}

};

/**
 * Formats very large numbers with their appropriate suffix, also adds
 * thousands and decimal separators and performs correct rounding for
 * smaller numbers
 *
 * @param  {integer} num The number to be formatted
 * @param  {integer} floats Amount of decimal places required
 *
 * @return {string}     Formatted number (as string) with suffix
 */
CM.largeNumFormat = function(num, floats) {

	var useShortNums = this.config.settings.shortNums.current === 'on' ? true : false,
		decSep = this.config.settings.numFormat.current === 'US' ? '.' : ',',
		decimal = decSep === '.' ? '.' : ',',
		comma = decSep === '.' ? ',' : '.',
		floats = floats || 0,
		parts,
		ranges = [
			{divider: 1e33, suffix: 'Dc'},
			{divider: 1e30, suffix: 'No'},
			{divider: 1e27, suffix: 'Oc'},
			{divider: 1e24, suffix: 'Sp'},
			{divider: 1e21, suffix: 'Sx'},
			{divider: 1e18, suffix: 'Qi'},
			{divider: 1e15, suffix: 'Qa'},
			{divider: 1e12, suffix: 'T'},
			{divider: 1e9, suffix: 'B'},
			{divider: 1e6, suffix: 'M'}
		];

	if(useShortNums) {
		for(var i = 0; i < ranges.length; i++) {

			if(num >= ranges[i].divider) {
				num = (num / ranges[i].divider).toFixed(3) + ' ' + ranges[i].suffix;
				return num.replace('.', decimal);
			}

		}
	}

	// Apply rounding, if any
	num = Math.round(num * Math.pow(10, floats)) / Math.pow(10, floats);

	// Prettify and localize the remaining "smaller" numbers
	parts = num.toString().split('.');
	parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, comma);

	return parts.join(decimal);

};

/**
 * Build and attach the settings panel to the DOM
 */
CM.attachSettingsPanel = function() {

	var self = this,
		items = [],
		options = [],
		control = [],
		current = '',
		selected = '',
		settings = this.config.settings,
		$wrapper = this.config.ccWrapper,
		$cmSettingsPanel = $('
').attr('id', 'CMSettingsPanel'),
		$cmSettingsTitle = $('
').attr('id', 'CMSettingsTitle').text('Settings:'),
		$cmSettingsList = $('
').attr('id', 'CMSettingsList'),
		$cmSettingsSaveButon = $('<button />').attr({'id': 'CMSettingsSave', 'type': 'button'}).text('Save');

		// Build each setting item
		$.each(settings, function(key, value) {

			// Reset these for each loop
			options = [];
			control = [];
			current = this.current;

			if(typeof this.options === 'object') {

				// Build a select box if a setting has multiple options
				$.each(this.options, function() {
					selected = (current === this.toString()) ? ' selected="selected"' : '';
					options.push('<option value="' + this + '"' + selected + '>' + this + '</option>');
				});
				control = '<select>';
				control += options.join('');
				control += '</select>';

			} else if(this.options === 'toggle') {

				// Build a checkbox if it's a simple toggle
				selected = (current === 'on') ? ' checked="checked"' : '';
				control = '<input type="checkbox"' + selected + ' />'

			}

			// Build the list of items
			items.push('
' + this.label + control + '
');

		});

		// Glue it together
		$cmSettingsList.append(items.join(''));
		$cmSettingsPanel.append($cmSettingsTitle);
		$cmSettingsPanel.append($cmSettingsList);
		$cmSettingsPanel.append($cmSettingsSaveButon);

		// Attach to DOM
		$wrapper.append($cmSettingsPanel);

		/**
		 *	Set event listeners
		 */

		// cleanUI toggle
		$cmSettingsList.find('.setting-cleanUI input').change(function() {
			settings.cleanUI.current = $(this).prop('checked') ? true : false;
		});

		//  numFormat change
		$cmSettingsList.find('.setting-numFormat select').change(function() {
			settings.numFormat.current = $(this).find(":selected").val();
		});

		//  shortNums toggle
		$cmSettingsList.find('.setting-shortNums input').change(function() {
			settings.shortNums.current = $(this).prop('checked') ? true : false;
		});

		// Save button
		$cmSettingsSaveButon.click(function() {
			self.saveUserSettings();
			self.applyUserSettings();
		});

};

/**
 * Attach an external stylesheet to the DOM
 *
 * @param  {string} url The URL of the stylesheet to load
 * @param  {string} id  an ID to give the stylesheet
 */
CM.attachStyleSheet = function(url, id) {

	var $stylesheet = $('<link>'),
		id = id || '',
		url = url || '';

	$stylesheet.attr({
		'type': 'text/css',
		'rel': 'stylesheet',
		'href': url,
		'id': id
	});

	$('head').append($stylesheet);

};

/**
 * Apply the current user settings to the game
 */
CM.applyUserSettings = function() {

	var settings = settings.this.config.settings;

	settings.cleanUI.current === 'on' ? this.cleanUI(true) : this.cleanUI(false);
	Game.RebuildStore();

};

/**
 * Save all user settings to the settings cookie
 */
CM.saveUserSettings = function() {

	var settings = this.config.settings,
		settingsStates = {}
		serializedSettings = '',
		cookieDate = new Date();

	// Grab the current value of each user setting
	$.each(settings, function(key, value) {
		settingsStates[key] =  this.current;
	});

	// Serialize the settings for cookie use
	serializedSettings = $.param(settingsStates).replace(/=/g, ':').replace(/&/g, '|');

	// Create and set the settings cookie
	cookieDate.setFullYear(cookieDate.getFullYear() + 1);
	document.cookie = 'CMSettings=' + serializedSettings + ';expires=' + cookieDate.toGMTString( ) + ';';

	Game.Popup('CookieMaster settings saved successfully!');

};

/**
 * Attempt to load user settings from the settings cookie
 */
CM.loadUserSettings = function() {

	var settings = this.config.settings,
		cookie = document.cookie.replace(/(?:(?:^|.*;\s*)CMSettings\s*\=\s*([^;]*).*$)|^.*$/, "$1"),
		settingsPairs = [],
		keyVals = [],
		self = this;

	if(cookie) {

		// Split apart and update each setting's current value
		settingsPairs = cookie.split('|');
		$.each(settingsPairs, function(key, value) {

			keyVals = this.split(':');
			// If we can't find a setting, skip it
			if(settings.hasOwnProperty(keyVals[0])) {
				settings[keyVals[0]].current = keyVals[1];
			}

		});

	}

};

/**
 * Remove all traces of CookieMaster
 */
CM.suicide = function() {
	// TO DO: Implement this functionality
	alert('This kills the CookieMaster.');
};

/**
 * Alert user to messages (expand later)
 *
 * @param  {string} msg The message
 */
CM.alertMessage = function(msg) {
	alert(msg);
};

// Start it up!
CM.init();

/* ===========================================
	COOKIE CLICKER FUNCTION OVERRIDES
=========================================== */

/**
 * Hijacks the original Beautify method to use our own formatting function
 *
 * @param {integer} what   The number to beautify
 * @param {integer} floats Number of decimal places desired :/
 *
 * @return {string}    Nicely formatted number as a string
 */
function Beautify(what, floats) {

	var floats = floats || 0;

	return CM.largeNumFormat(what, floats);

}
/* ===========================================
	END COOKIE CLICKER FUNCTION OVERRIDES
=========================================== */
<commit_msg>Fixed the fix<commit_after>/**
 * We will expose all methods and properties of CookieMaster
 * through the parent object, for easy extendability
 *
 * @type {Object}
 */
CM = {};

/**
 * Configuration settings for CookieMaster, the loaded version of
 * Cookie Clicker and user-specific settings.
 *
 * @type {Object}
 */
CM.config = {

	cmVersion: '0.1',
	cmIsLoaded: false,
	cmCSS: 'https://rawgithub.com/greenc/CookieMaster/master/styles.css',

	ccURL: 'http://orteil.dashnet.org/cookieclicker/',
	ccVersion: '',
	ccCompatibleVersions: ['1.0402', '1.0403'],

	ccBody: $('body'),
	ccWrapper: $('#wrapper'),
	ccGame: $('#game'),

	// User configurable settings
	settings: {
		cleanUI: {
			label: 'Clean UI',
			desc: 'Hide the top bar, and make other small graphical enhancements to the game interface',
			options: 'toggle',
			current: 'on'
		},
		numFormat: {
			label: 'Number Formatting',
			desc: 'Display numbers in US (123,456,789.0) or European (123.456.789,0) format',
			options: ['US', 'European'],
			current: 'US'
		},
		shortNums: {
			label: 'Short Numbers',
			desc: 'Shorten large numbers with suffixes',
			options: 'toggle',
			current: 'on'
		}
	},

};

/**
 * Initialization method. This is the first thing that gets called
 * when the script runs, and all methods that need to be invoked on
 * startup should be called from here in the order needed.
 */
CM.init = function() {

	var cmCSS = this.config.cmCSS,
		cssID = this.config.cmStyleID;

	//Perform a quick check to make sure CM can run correctly
	if(this.integrityCheck()) {

		this.loadUserSettings();
		this.attachStyleSheet(cmCSS, cssID);
		this.attachSettingsPanel();

		// Apply the current user settings after we've done everything else
		this.applyUserSettings();

		// All done :)
		this.config.cmIsLoaded = true;
		Game.Popup('CookieMaster v.' + this.config.cmVersion + ' loaded successfully!');

	} else {

		this.suicide();
		return false;

	}

};

/**
 * Checks that CookieMaster can run correctly and informs the
 * user if anything is wrong
 *
 * @return {boolean}
 */
CM.integrityCheck = function() {

	var ccVersion = Game.version.toString() || '',
		message = false,
		error = false,
		i;

	if(this.config.cmIsLoaded) {
		// Already loaded
		message = 'Error: CookieMaster is already running!';
		error = true;
	} else if(document.location.href.indexOf(this.config.ccURL) === -1) {
		// Wrong URL
		message = 'Error: This isn\'t the Cookie Clicker URL';
		error = true;
	} else if(!window.jQuery) {
		// jQuery isn't loaded
		message = 'Error: jQuery is not loaded';
		error = true;
	} else if(!Game) {
		// Game class doesn't exist
		message = 'Error: Cookie Clicker does not appear to be initialized';
		error = true;
	}

	// Warn against potential incompatibility
	if(this.compatibilityCheck(ccVersion) === -1) {
		message = 'Warning: This version of Cookie Clicker may not be fully supported!';
	}

	// Alert user to any issues
	if(message) {
		this.alertMessage(message);
	}

	if(error) {

		return false;

	} else {

		// Set some useful config options for later use
		this.config.ccVersion = ccVersion;
		this.config.ccGame = $('#game');

		return true;
	}

};

/**
 * Checks the loaded version of CC against a list of
 * known compatible versions
 *
 * @param  {string} version The version of CC we are running on
 *
 * @return {integer}         Return index of matched version
 */
CM.compatibilityCheck = function(version) {

	var compVersions = this.config.ccCompatibleVersions,
		ccVersion = version || '',
		i;

	for(i = 0; i < compVersions.length; i++) {
		if(compVersions[i].match(ccVersion)) {
			return i;
		}
	}

	return -1;

}

/**
 * Clean up the game interface a little.
 *
 * @param  {boolean} state Turn on or off
 */
CM.cleanUI = function(state) {

	var cssClass = 'cleanUI',
		$body = this.config.ccBody;

	if(state) {
		$body.addClass(cssClass);
	} else {
		$body.removeClass(cssClass);
	}

};

/**
 * Formats very large numbers with their appropriate suffix, also adds
 * thousands and decimal separators and performs correct rounding for
 * smaller numbers
 *
 * @param  {integer} num The number to be formatted
 * @param  {integer} floats Amount of decimal places required
 *
 * @return {string}     Formatted number (as string) with suffix
 */
CM.largeNumFormat = function(num, floats) {

	var useShortNums = this.config.settings.shortNums.current === 'on' ? true : false,
		decSep = this.config.settings.numFormat.current === 'US' ? '.' : ',',
		decimal = decSep === '.' ? '.' : ',',
		comma = decSep === '.' ? ',' : '.',
		floats = floats || 0,
		parts,
		ranges = [
			{divider: 1e33, suffix: 'Dc'},
			{divider: 1e30, suffix: 'No'},
			{divider: 1e27, suffix: 'Oc'},
			{divider: 1e24, suffix: 'Sp'},
			{divider: 1e21, suffix: 'Sx'},
			{divider: 1e18, suffix: 'Qi'},
			{divider: 1e15, suffix: 'Qa'},
			{divider: 1e12, suffix: 'T'},
			{divider: 1e9, suffix: 'B'},
			{divider: 1e6, suffix: 'M'}
		];

	if(useShortNums) {
		for(var i = 0; i < ranges.length; i++) {

			if(num >= ranges[i].divider) {
				num = (num / ranges[i].divider).toFixed(3) + ' ' + ranges[i].suffix;
				return num.replace('.', decimal);
			}

		}
	}

	// Apply rounding, if any
	num = Math.round(num * Math.pow(10, floats)) / Math.pow(10, floats);

	// Prettify and localize the remaining "smaller" numbers
	parts = num.toString().split('.');
	parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, comma);

	return parts.join(decimal);

};

/**
 * Build and attach the settings panel to the DOM
 */
CM.attachSettingsPanel = function() {

	var self = this,
		items = [],
		options = [],
		control = [],
		current = '',
		selected = '',
		settings = this.config.settings,
		$wrapper = this.config.ccWrapper,
		$cmSettingsPanel = $('
').attr('id', 'CMSettingsPanel'),
		$cmSettingsTitle = $('
').attr('id', 'CMSettingsTitle').text('Settings:'),
		$cmSettingsList = $('
').attr('id', 'CMSettingsList'),
		$cmSettingsSaveButon = $('<button />').attr({'id': 'CMSettingsSave', 'type': 'button'}).text('Save');

		// Build each setting item
		$.each(settings, function(key, value) {

			// Reset these for each loop
			options = [];
			control = [];
			current = this.current;

			if(typeof this.options === 'object') {

				// Build a select box if a setting has multiple options
				$.each(this.options, function() {
					selected = (current === this.toString()) ? ' selected="selected"' : '';
					options.push('<option value="' + this + '"' + selected + '>' + this + '</option>');
				});
				control = '<select>';
				control += options.join('');
				control += '</select>';

			} else if(this.options === 'toggle') {

				// Build a checkbox if it's a simple toggle
				selected = (current === 'on') ? ' checked="checked"' : '';
				control = '<input type="checkbox"' + selected + ' />'

			}

			// Build the list of items
			items.push('
' + this.label + control + '
');

		});

		// Glue it together
		$cmSettingsList.append(items.join(''));
		$cmSettingsPanel.append($cmSettingsTitle);
		$cmSettingsPanel.append($cmSettingsList);
		$cmSettingsPanel.append($cmSettingsSaveButon);

		// Attach to DOM
		$wrapper.append($cmSettingsPanel);

		/**
		 *	Set event listeners
		 */

		// cleanUI toggle
		$cmSettingsList.find('.setting-cleanUI input').change(function() {
			settings.cleanUI.current = $(this).prop('checked') ? true : false;
		});

		//  numFormat change
		$cmSettingsList.find('.setting-numFormat select').change(function() {
			settings.numFormat.current = $(this).find(":selected").val();
		});

		//  shortNums toggle
		$cmSettingsList.find('.setting-shortNums input').change(function() {
			settings.shortNums.current = $(this).prop('checked') ? true : false;
		});

		// Save button
		$cmSettingsSaveButon.click(function() {
			self.saveUserSettings();
			self.applyUserSettings();
		});

};

/**
 * Attach an external stylesheet to the DOM
 *
 * @param  {string} url The URL of the stylesheet to load
 * @param  {string} id  an ID to give the stylesheet
 */
CM.attachStyleSheet = function(url, id) {

	var $stylesheet = $('<link>'),
		id = id || '',
		url = url || '';

	$stylesheet.attr({
		'type': 'text/css',
		'rel': 'stylesheet',
		'href': url,
		'id': id
	});

	$('head').append($stylesheet);

};

/**
 * Apply the current user settings to the game
 */
CM.applyUserSettings = function() {

	var settings = this.config.settings;

	settings.cleanUI.current === 'on' ? this.cleanUI(true) : this.cleanUI(false);
	Game.RebuildStore();

};

/**
 * Save all user settings to the settings cookie
 */
CM.saveUserSettings = function() {

	var settings = this.config.settings,
		settingsStates = {}
		serializedSettings = '',
		cookieDate = new Date();

	// Grab the current value of each user setting
	$.each(settings, function(key, value) {
		settingsStates[key] =  this.current;
	});

	// Serialize the settings for cookie use
	serializedSettings = $.param(settingsStates).replace(/=/g, ':').replace(/&/g, '|');

	// Create and set the settings cookie
	cookieDate.setFullYear(cookieDate.getFullYear() + 1);
	document.cookie = 'CMSettings=' + serializedSettings + ';expires=' + cookieDate.toGMTString( ) + ';';

	Game.Popup('CookieMaster settings saved successfully!');

};

/**
 * Attempt to load user settings from the settings cookie
 */
CM.loadUserSettings = function() {

	var settings = this.config.settings,
		cookie = document.cookie.replace(/(?:(?:^|.*;\s*)CMSettings\s*\=\s*([^;]*).*$)|^.*$/, "$1"),
		settingsPairs = [],
		keyVals = [],
		self = this;

	if(cookie) {

		// Split apart and update each setting's current value
		settingsPairs = cookie.split('|');
		$.each(settingsPairs, function(key, value) {

			keyVals = this.split(':');
			// If we can't find a setting, skip it
			if(settings.hasOwnProperty(keyVals[0])) {
				settings[keyVals[0]].current = keyVals[1];
			}

		});

	}

};

/**
 * Remove all traces of CookieMaster
 */
CM.suicide = function() {
	// TO DO: Implement this functionality
	alert('This kills the CookieMaster.');
};

/**
 * Alert user to messages (expand later)
 *
 * @param  {string} msg The message
 */
CM.alertMessage = function(msg) {
	alert(msg);
};

// Start it up!
CM.init();

/* ===========================================
	COOKIE CLICKER FUNCTION OVERRIDES
=========================================== */

/**
 * Hijacks the original Beautify method to use our own formatting function
 *
 * @param {integer} what   The number to beautify
 * @param {integer} floats Number of decimal places desired :/
 *
 * @return {string}    Nicely formatted number as a string
 */
function Beautify(what, floats) {

	var floats = floats || 0;

	return CM.largeNumFormat(what, floats);

}
/* ===========================================
	END COOKIE CLICKER FUNCTION OVERRIDES
=========================================== */
<|endoftext|>


<commit_before>
/*!--------------------------------*\
   3-Jekyll Theme
   @author Peiwen Lu (P233)
   https://github.com/P233/3-Jekyll
\*---------------------------------*/

// Detect window size, if less than 1280px add class 'mobile' to sidebar therefore it will be auto hide when trigger the pjax request in small screen devices.
if ($(window).width() <= 1280) {
  $('#sidebar').addClass('mobile')
}

// Variables
    tag1       = $('.techs'),
    tag2       = $('.engineer'),
    tag3       = $('.life');
var sidebar    = $('#sidebar'),
    container  = $('#post'),
    content    = $('#pjax'),
    button     = $('#icon-arrow');

// Tags switcher
var clickHandler = function(k) {
  return function() {
    $(this).addClass('active').siblings().removeClass('active');
    tag1.hide();
    window['tag'+k].delay(50).fadeIn(350);
  }
};
for (var i = 1; i <= 6; i++) {
  $('#js-label' + i).on('click', clickHandler(i));
}

// If sidebar has class 'mobile', hide it after clicking.
tag1.on('click', function() {
  $(this).addClass('active').siblings().removeClass('active');
  if (sidebar.hasClass('mobile')) {
    $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
  }
});

// Enable fullscreen.
$('#js-fullscreen').on('click', function() {
  if (button.hasClass('fullscreen')) {
    sidebar.removeClass('fullscreen');
    button.removeClass('fullscreen');
    content.delay(300).queue(function(){
      $(this).removeClass('fullscreen').dequeue();
    });
  } else {
    sidebar.addClass('fullscreen');
    button.addClass('fullscreen');
    content.delay(200).queue(function(){
      $(this).addClass('fullscreen').dequeue();
    });
  }
});

$('#mobile-avatar').on('click', function(){
  $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
});

// Pjax
$(document).pjax('#avatar, #mobile-avatar, .pl__all', '#pjax', { fragment: '#pjax', timeout: 10000 });
$(document).on({
  'pjax:click': function() {
    content.removeClass('fadeIn').addClass('fadeOut');
    NProgress.start();
  },
  'pjax:start': function() {
    content.css({'opacity':0});
  },
  'pjax:end': function() {
    NProgress.done();
    container.scrollTop(0);
    content.css({'opacity':1}).removeClass('fadeOut').addClass('fadeIn');
    afterPjax();
  }
});

// Codepen embed js
// http://codepen.io/assets/embed/ei.js
// Added on 17 Nov 2013
var CodePenEmbed={width:"100%",init:function(){this.showCodePenEmbeds(),this.listenToParentPostMessages()},showCodePenEmbeds:function(){var e=document.getElementsByClassName("codepen");for(var t=e.length-1;t>-1;t--){var n=this._getParamsFromAttributes(e[t]);n=this._convertOldDataAttributesToNewDataAttributes(n);var r=this._buildURL(n),i=this._buildIFrame(n,r);this._addIFrameToPage(e[t],i)}},_getParamsFromAttributes:function(e){var t={},n=e.attributes;for(var r=0,i=n.length;r<i;r++)name=n[r].name,name.indexOf("data-")===0&&(t[name.replace("data-","")]=n[r].value);return t},_convertOldDataAttributesToNewDataAttributes:function(e){return e.href&&(e["slug-hash"]=e.href),e.type&&(e["default-tab"]=e.type),e.safe&&(e["safe"]=="true"?e.animations="run":e.animations="stop-after-5"),e},_buildURL:function(e){var t=this._getHost(e),n=e.user?e.user:"anon",r="?"+this._getGetParams(e),i=[t,n,"embed",e["slug-hash"]+r].join("/");return i.replace(/\/\//g,"//")},_getHost:function(e){return e.host?e.host:document.location.protocol=="file:"?"http://codepen.io":"//codepen.io"},_getGetParams:function(e){var t="",n=0;for(var r in e)t!==""&&(t+="&"),t+=r+"="+encodeURIComponent(e[r]);return t},_buildIFrame:function(e,t){var n={id:"cp_embed_"+e["slug-hash"].replace("/","_"),src:t,scrolling:"no",frameborder:"0",height:this._getHeight(e),allowTransparency:"true","class":"cp_embed_iframe",style:"width: "+this.width+"; overflow: hidden;"},r="",r},_getHeight:function(e){return e.height?e["height"]=="auto"?300:e.height:300},_addIFrameToPage:function(e,t){if(e.parentNode){var n=document.createElement("div");n.innerHTML=t,e.parentNode.replaceChild(n,e)}else e.innerHTML=t},listenToParentPostMessages:function(){var eventMethod=window.addEventListener?"addEventListener":"attachEvent",eventListener=window[eventMethod],messageEvent=eventMethod=="attachEvent"?"onmessage":"message";eventListener(messageEvent,function(e){try{var dataObj=eval("("+e.data+")"),iframe=document.getElementById("cp_embed_"+dataObj.hash);iframe&&(iframe.height=dataObj.height)}catch(err){}},!1)}};

// Re-run scripts for post content after pjax
function afterPjax() {
  // Open links in new tab
  $('#post__content a').attr('target','_blank');

  // Embed codepen after pjax
  CodePenEmbed.init();

  // Generate post TOC for h1 h2 and h3
  var toc = $('#post__toc-ul');
  // Empty TOC and generate an entry for h1
  toc.empty().append('
' + $('#post__title').text() + '
');

  // Generate entries for h2 and h3
  $('#post__content').children('h2,h3').each(function() {
    // Generate random ID for each heading
    $(this).attr('id', function() {
      var ID = "",
          alphabet = "abcdefghijklmnopqrstuvwxyz";

      for(var i=0; i < 5; i++) {
        ID += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
      }
      return ID;
    });

    if ($(this).prop("tagName") == 'H2') {
      toc.append('
' + $(this).text() + '
');
    } else {
      toc.append('
' + $(this).text() + '
');
    }
  });

  // Smooth scrolling
  $('.js-anchor-link').on('click', function() {
    var target = $(this.hash);
    container.animate({scrollTop: target.offset().top + container.scrollTop() - 70}, 500, function() {
      target.addClass('flash').delay(700).queue(function() {
        $(this).removeClass('flash').dequeue();
      });
    });
  });

  // Lazy Loading Disqus
  // http://jsfiddle.net/dragoncrew/SHGwe/1/
  var ds_loaded = false,
      top = $('#disqus_thread').offset().top;
      identifier = $('#post__title').data('identifier');
  window.disqus_shortname = 'lipvun';
  window.disqus_identifier = identifier;

  function check() {
    if ( !ds_loaded && container.scrollTop() + container.height() > top ) {
      $.ajax({
        type: 'GET',
        url: 'http://' + disqus_shortname + '.disqus.com/embed.js',
        dataType: 'script',
        cache: true
      });
      ds_loaded = true;
    }
  }check();
  container.scroll(check);
}afterPjax();

<commit_msg>update<commit_after>
/*!--------------------------------*\
   3-Jekyll Theme
   @author Peiwen Lu (P233)
   https://github.com/P233/3-Jekyll
\*---------------------------------*/

// Detect window size, if less than 1280px add class 'mobile' to sidebar therefore it will be auto hide when trigger the pjax request in small screen devices.
if ($(window).width() <= 1280) {
  $('#sidebar').addClass('mobile')
}

// Variables
    tag1       = $('.techs'),
    tag2       = $('.engineer'),
    tag3       = $('.life');
var sidebar    = $('#sidebar'),
    container  = $('#post'),
    content    = $('#pjax'),
    button     = $('#icon-arrow');

var timer = setTimeout(function(){
  sidebar.addClass('fullscreen');
  button.addClass('fullscreen');
  content.delay(200).queue(function(){
    $(this).addClass('fullscreen').dequeue();
  });

}, 3000)

// Tags switcher
var clickHandler = function(k) {
  return function() {
    $(this).addClass('active').siblings().removeClass('active');
    tag1.hide();
    window['tag'+k].delay(50).fadeIn(350);
  }
};
for (var i = 1; i <= 6; i++) {
  $('#js-label' + i).on('click', clickHandler(i));
}

// If sidebar has class 'mobile', hide it after clicking.
tag1.on('click', function() {
  $(this).addClass('active').siblings().removeClass('active');
  if (sidebar.hasClass('mobile')) {
    $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
  }
});

// Enable fullscreen.
$('#js-fullscreen').on('click', function() {
  if (button.hasClass('fullscreen')) {
    sidebar.removeClass('fullscreen');
    button.removeClass('fullscreen');
    content.delay(300).queue(function(){
      $(this).removeClass('fullscreen').dequeue();
    });
  } else {
    sidebar.addClass('fullscreen');
    button.addClass('fullscreen');
    content.delay(200).queue(function(){
      $(this).addClass('fullscreen').dequeue();
    });
  }
});

$('#mobile-avatar').on('click', function(){
  $('#sidebar, #pjax, #icon-arrow').addClass('fullscreen');
});

// Pjax
$(document).pjax('#avatar, #mobile-avatar, .pl__all', '#pjax', { fragment: '#pjax', timeout: 10000 });
$(document).on({
  'pjax:click': function() {
    content.removeClass('fadeIn').addClass('fadeOut');
    NProgress.start();
  },
  'pjax:start': function() {
    content.css({'opacity':0});
  },
  'pjax:end': function() {
    NProgress.done();
    container.scrollTop(0);
    content.css({'opacity':1}).removeClass('fadeOut').addClass('fadeIn');
    afterPjax();
  }
});

// Codepen embed js
// http://codepen.io/assets/embed/ei.js
// Added on 17 Nov 2013
var CodePenEmbed={width:"100%",init:function(){this.showCodePenEmbeds(),this.listenToParentPostMessages()},showCodePenEmbeds:function(){var e=document.getElementsByClassName("codepen");for(var t=e.length-1;t>-1;t--){var n=this._getParamsFromAttributes(e[t]);n=this._convertOldDataAttributesToNewDataAttributes(n);var r=this._buildURL(n),i=this._buildIFrame(n,r);this._addIFrameToPage(e[t],i)}},_getParamsFromAttributes:function(e){var t={},n=e.attributes;for(var r=0,i=n.length;r<i;r++)name=n[r].name,name.indexOf("data-")===0&&(t[name.replace("data-","")]=n[r].value);return t},_convertOldDataAttributesToNewDataAttributes:function(e){return e.href&&(e["slug-hash"]=e.href),e.type&&(e["default-tab"]=e.type),e.safe&&(e["safe"]=="true"?e.animations="run":e.animations="stop-after-5"),e},_buildURL:function(e){var t=this._getHost(e),n=e.user?e.user:"anon",r="?"+this._getGetParams(e),i=[t,n,"embed",e["slug-hash"]+r].join("/");return i.replace(/\/\//g,"//")},_getHost:function(e){return e.host?e.host:document.location.protocol=="file:"?"http://codepen.io":"//codepen.io"},_getGetParams:function(e){var t="",n=0;for(var r in e)t!==""&&(t+="&"),t+=r+"="+encodeURIComponent(e[r]);return t},_buildIFrame:function(e,t){var n={id:"cp_embed_"+e["slug-hash"].replace("/","_"),src:t,scrolling:"no",frameborder:"0",height:this._getHeight(e),allowTransparency:"true","class":"cp_embed_iframe",style:"width: "+this.width+"; overflow: hidden;"},r="",r},_getHeight:function(e){return e.height?e["height"]=="auto"?300:e.height:300},_addIFrameToPage:function(e,t){if(e.parentNode){var n=document.createElement("div");n.innerHTML=t,e.parentNode.replaceChild(n,e)}else e.innerHTML=t},listenToParentPostMessages:function(){var eventMethod=window.addEventListener?"addEventListener":"attachEvent",eventListener=window[eventMethod],messageEvent=eventMethod=="attachEvent"?"onmessage":"message";eventListener(messageEvent,function(e){try{var dataObj=eval("("+e.data+")"),iframe=document.getElementById("cp_embed_"+dataObj.hash);iframe&&(iframe.height=dataObj.height)}catch(err){}},!1)}};

// Re-run scripts for post content after pjax
function afterPjax() {
  // Open links in new tab
  $('#post__content a').attr('target','_blank');

  // Embed codepen after pjax
  CodePenEmbed.init();

  // Generate post TOC for h1 h2 and h3
  var toc = $('#post__toc-ul');
  // Empty TOC and generate an entry for h1
  toc.empty().append('
' + $('#post__title').text() + '
');

  // Generate entries for h2 and h3
  $('#post__content').children('h2,h3').each(function() {
    // Generate random ID for each heading
    $(this).attr('id', function() {
      var ID = "",
          alphabet = "abcdefghijklmnopqrstuvwxyz";

      for(var i=0; i < 5; i++) {
        ID += alphabet.charAt(Math.floor(Math.random() * alphabet.length));
      }
      return ID;
    });

    if ($(this).prop("tagName") == 'H2') {
      toc.append('
' + $(this).text() + '
');
    } else {
      toc.append('
' + $(this).text() + '
');
    }
  });

  // Smooth scrolling
  $('.js-anchor-link').on('click', function() {
    var target = $(this.hash);
    container.animate({scrollTop: target.offset().top + container.scrollTop() - 70}, 500, function() {
      target.addClass('flash').delay(700).queue(function() {
        $(this).removeClass('flash').dequeue();
      });
    });
  });

  // Lazy Loading Disqus
  // http://jsfiddle.net/dragoncrew/SHGwe/1/
  var ds_loaded = false,
      top = $('#disqus_thread').offset().top;
      identifier = $('#post__title').data('identifier');
  window.disqus_shortname = 'lipvun';
  window.disqus_identifier = identifier;

  function check() {
    if ( !ds_loaded && container.scrollTop() + container.height() > top ) {
      $.ajax({
        type: 'GET',
        url: 'http://' + disqus_shortname + '.disqus.com/embed.js',
        dataType: 'script',
        cache: true
      });
      ds_loaded = true;
    }
  }check();
  container.scroll(check);
}afterPjax();

<|endoftext|>