<commit_before>(function ($) {
    $.fn.alphanumeric = function (p) {
        var input = $(this),
            //add new letter (ñ, for spanish keyboard) (Felipe Pincheira A.)
            az = 'abcdefghijklmnñopqrstuvwxyz',
            options = $.extend({
                //add new characters (¡°¬´¨) (Felipe Pincheira A.)
                ichars: '!@#$%^&*()+=[]\\\';,/{}|":<>?~`.- _¡°¬´¨',
                nchars: '',
                allow: ''
            }, p),
            s = options.allow.split(''),
            i = 0,
            ch,
            regex;

        for (i; i < s.length; i++) {
            if (options.ichars.indexOf(s[i]) != -1) {
                s[i] = '\\' + s[i];
            }
        }

        if (options.nocaps) {
            options.nchars += az.toUpperCase();
        }

        if (options.allcaps) {
            options.nchars += az;
        }

        options.allow = s.join('|');

        regex = new RegExp(options.allow, 'gi');
        ch = (options.ichars + options.nchars).replace(regex, '');

        input
            .keypress(function (e) {

                var key = String.fromCharCode(!e.charCode ? e.which : e.charCode);

                if (ch.indexOf(key) != -1 && !e.ctrlKey) {
                    e.preventDefault();
                }

            })
            .blur(function () {

                var value = input.val(),
                    j = 0;

                for (j; j < value.length; j++) {
                    if (ch.indexOf(value[j]) != -1) {
                        input.val('');
                        return false;
                    }
                }
                return false;
            });

        return input;

    };

    $.fn.numeric = function (p) {
        //add new letter (ñ, for spanish keyboard) (Felipe Pincheira A.)
        var az = 'abcdefghijklmnñopqrstuvwxyz',
            aZ = az.toUpperCase();

        return this.each(function () {
            $(this).alphanumeric($.extend({ nchars: az + aZ }, p));
        });
    };

    $.fn.alpha = function (p) {
        var nm = '1234567890';
        return this.each(function () {
            $(this).alphanumeric($.extend({ nchars: nm }, p));
        });
    };
})(jQuery);
<commit_msg>Add new characters<commit_after>(function ($) {
    $.fn.alphanumeric = function (p) {
        var input = $(this),
            //add new letter (ñ, for spanish keyboard) (Felipe Pincheira A.)
            // + french letter
            az = 'aàáâãäåæbcçdeèéêëfghiìíîïjklmnñoðòóôõöpqrstuùúûüvwxyýÿz',
            options = $.extend({
                //add new characters (¡°¬´¨) (Felipe Pincheira A.)
                ichars: '!@#$%^&*()+=[]\\\';,/{}|":<>?~`.- _¡°¬´¨²€ƒ^‰¥£¢¦§¨ø',
                nchars: '',
                allow: ''
            }, p),
            s = options.allow.split(''),
            i = 0,
            ch,
            regex;

        for (i; i < s.length; i++) {
            if (options.ichars.indexOf(s[i]) != -1) {
                s[i] = '\\' + s[i];
            }
        }

        if (options.nocaps) {
            options.nchars += az.toUpperCase();
        }

        if (options.allcaps) {
            options.nchars += az;
        }

        options.allow = s.join('|');

        regex = new RegExp(options.allow, 'gi');
        ch = (options.ichars + options.nchars).replace(regex, '');

        input
            .keypress(function (e) {

                var key = String.fromCharCode(!e.charCode ? e.which : e.charCode);

                if (ch.indexOf(key) != -1 && !e.ctrlKey) {
                    e.preventDefault();
                }

            })
            .blur(function () {

                var value = input.val(),
                    j = 0;

                for (j; j < value.length; j++) {
                    if (ch.indexOf(value[j]) != -1) {
                        input.val('');
                        return false;
                    }
                }
                return false;
            });

        return input;

    };

    $.fn.numeric = function (p) {
        //add new letter (ñ, for spanish keyboard) (Felipe Pincheira A.)
        var az = 'aàáâãäåæbcçdeèéêëfghiìíîïjklmnñoðòóôõöpqrstuùúûüvwxyýÿz',
            aZ = az.toUpperCase();

        return this.each(function () {
            $(this).alphanumeric($.extend({ nchars: az + aZ }, p));
        });
    };

    $.fn.alpha = function (p) {
        var nm = '1234567890';
        return this.each(function () {
            $(this).alphanumeric($.extend({ nchars: nm }, p));
        });
    };
})(jQuery);
<|endoftext|>


<commit_before>// ==UserScript==
// @name         花瓣网下载
// @namespace    https://www.saintic.com/
// @version      0.1
// @description  花瓣网(huaban.com)用户画板图片批量下载到本地
// @author       staugur
// @match        http*://huaban.com/boards/*
// @require      https://static.saintic.com/cdn/js/FileSaver.min.js
// @grant        GM_setClipboard
// @license      MIT
// @date         2018-05-25
// @modified     none
// @github       https://github.com/staugur/grab_huaban_board
// @supportURL   https://github.com/staugur/grab_huaban_board/issues
// ==/UserScript==

(function() {
    'use strict';
    /*
        公共接口
    */
    //字符串是否包含子串
    function isContains(str, substr) {
        //str是否包含substr
        return str.indexOf(substr) >= 0;
    }
    //下载保存图片
    function saveImage(imgUrl, imgName) {
        //imgUrl: 图片地址; imgName: 保存的文件名
        try {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', imgUrl, true);
            xhr.responseType = 'blob';
            xhr.onload = () => {
                if (xhr.status === 200) {
                    //将图片文件用浏览器中下载
                    saveAs(xhr.response, imgName);
                }
            };
            xhr.send();
        } catch (e) {
            console.log(e);
        }
    }
    //加载css文件
    function addCSS(href) {
        var link = document.createElement('link');
        link.type = 'text/css';
        link.rel = 'stylesheet';
        link.href = href;
        document.getElementsByTagName("head")[0].appendChild(link);
    }
    //加载js文件
    function addJS(src, cb) {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = src;
        document.getElementsByTagName('head')[0].appendChild(script);
        script.onload = typeof cb === "function" ? cb : function() {};
    }
    //由于@require方式引入jquery时layer使用异常，故引用cdn中jquery v1.10.1；加载完成后引用又拍云中layer v3.1.1
    addJS("https://cdn.bootcss.com/jquery/1.10.1/jquery.min.js", function() {
        addJS("https://static.saintic.com/cdn/layer/3.1.1/layer.js");
    });
    const board_id = window.location.pathname.split('/')[1] === "boards" ? window.location.pathname.split('/')[2] : "";
    const protocol = window.location.protocol;
    /*
        下载图片
    */
    //交互确定下载方式
    function interactive(pins) {
        var msg = [
            '当前画板共抓取' + pins.length + '张图片！提示: 只有登录后才可以抓取几乎所有图片哦。
',
            '请选择以下三种下载方式：
',
            '1. 文本：
    即所有图片地址按行显示，提供复制，粘贴至迅雷、QQ旋风等下载工具批量下载即可，推荐使用此方法。
',
            '2. 本地：
    即所有图片直接保存到硬盘中，由于是批量下载，所以浏览器设置中请关闭"下载前询问每个文件的保存位置"，并且允许浏览器下载多个文件的授权申请，以保证可以自动批量保存，否则每次保存时会弹出询问，对您造成困扰。
',
            '3. 远程：
    即所有图片将由第三方服务器下载并压缩，提供压缩文件链接，直接下载此链接解压即可。
',
            '

寻求帮助？请点击我！
'
        ].join('');
        layer.confirm(msg, {
            title: "选择画板图片下载方式",
            closeBtn: false,
            shadeClose: false,
            shade: 0,
            btn: ['文本', '本地', '远程'],
            btnAlign: 'c',
            btn3: function(index, layero) {
                downloadPicRemotely(pins);
            }
        }, function(index, layero) {
            downloadPicText(pins);
        }, function(index) {
            downloadPicLocally(pins);
        });
    }
    //本地下载
    function downloadPicLocally(pins) {
        for (var i = 0, len = pins.length; i < len; i++) {
            saveImage(pins[i].imgUrl, pins[i].imgName);
        }
    }
    //远端下载
    function downloadPicRemotely(pins) {
        $.ajax({
            url: "https://www.saintic.com/CrawlHuaban/",
            type: "POST",
            data: {
                board_id: board_id,
                pins: JSON.stringify(pins)
            },
            success: function(res) {
                if (res.success === true) {
                    var msg = "下载任务已经提交！
根据画板图片数量，所需时间不等，请稍等数分钟后访问下载链接：
" + res.downloadUrl + "
它将于" + res.expireTime + "过期，资源会被删除，请在那之前下载。";
                    layer.alert(msg, {
                        icon: 1,
                        title: "温馨提示",
                        btn: '我已知晓并复制下载链接',
                        btnAlign: 'c'
                    }, function(index) {
                        layer.close(index);
                        GM_setClipboard(res.downloadUrl);
                        layer.msg("复制成功", {
                            icon: 1
                        });
                    });
                } else {
                    layer.msg("第三方服务异常: " + res.msg);
                }
            }
        });
    }
    //文本方式下载，比如迅雷、QQ旋风
    function downloadPicText(pins) {
        var tip = '请点击复制按钮，粘贴到迅雷等下载！
',
            str = '';
        for (var i = 0, len = pins.length; i < len; i++) {
            str += pins[i].imgUrl + "\n";
        }
        layer.alert(tip + str, {
            title: "文本方式下载",
            btn: '复制',
            btnAlign: 'c',
            icon: 1,
            yes: function(index, layero) {
                layer.close(index);
                GM_setClipboard(str);
                layer.msg("复制成功", {
                    icon: 1
                });
            }
        });
    }
    //定位
    var d = document.getElementById('page').getElementsByClassName('action-buttons')[0];
    //插入下载画板按钮
    if (isContains(d.innerText, "下载此画板") === false) {
        d.insertAdjacentHTML('afterbegin', ' 下载此画板');
    }
    //监听点击下载事件
    document.getElementById("downloadBoard").onclick = function() {
        if (board_id) {
            var retry = 100,
                limit = 100,
                board_url = protocol + '//huaban.com/boards/' + board_id;
            //get first pin data
            $.ajax({
                url: board_url,
                type: "GET",
                async: false,
                success: function(res) {
                    try {
                        //console.log(res);
                        if (res.hasOwnProperty("board") === true) {
                            var board_data = res.board,
                                pin_number = board_data.pin_count,
                                board_pins = board_data.pins;
                            //console.log("Current board <" + board_id + "> pins number is " + pin_number + ", first pins number is " + board_pins.length);
                            if (board_pins.length < pin_number) {
                                var last_pin = board_pins[board_pins.length - 1].pin_id;
                                while (1 <= retry) {
                                    //get ajax pin data
                                    var board_next_url = protocol + "//huaban.com/boards/" + board_id + "/?max=" + last_pin + "&limit=" + limit + "&wfl=1";
                                    $.ajax({
                                        url: board_next_url,
                                        type: "GET",
                                        async: false,
                                        success: function(res) {
                                            //console.log(res);
                                            var board_next_data = res.board;
                                            board_pins = board_pins.concat(board_next_data.pins);
                                            console.log("ajax load board with pin_id " + last_pin + ", get pins number is " + board_next_data.pins.length + ", merged");
                                            if (board_next_data.pins.length === 0) {
                                                retry = 0;
                                                return false;
                                            }
                                            last_pin = board_next_data.pins[board_next_data.pins.length - 1].pin_id;
                                        }
                                    });
                                    retry -= 1;
                                }
                            }
                            //console.log("共抓取" + board_pins.length + "个pin");
                            var pins = [];
                            for (var i = 0, len = board_pins.length; i < len; i++) {
                                var pin = board_pins[i];
                                pins.push({
                                    imgUrl: "http://img.hb.aicdn.com/" + pin.file.key + "_fw658",
                                    imgName: pin.pin_id + "." + pin.file.type.split("/")[1]
                                });
                            }
                            //交互确定下载方式
                            interactive(pins);
                        }
                    } catch (e) {
                        console.log(e);
                    }
                }
            });
        }
    };
})();<commit_msg>update grab_huaban_board.js<commit_after>// ==UserScript==
// @name         花瓣网下载
// @namespace    https://www.saintic.com/
// @version      0.1
// @description  花瓣网(huaban.com)用户画板图片批量下载到本地
// @author       staugur
// @match        http*://huaban.com/boards/*
// @require      https://cdn.bootcss.com/FileSaver.js/2014-11-29/FileSaver.min.js
// @grant        GM_setClipboard
// @license      MIT
// @date         2018-05-25
// @modified     none
// @github       https://github.com/staugur/grab_huaban_board
// @supportURL   https://github.com/staugur/grab_huaban_board/issues
// ==/UserScript==

(function() {
    'use strict';
    /*
        公共接口
    */
    //字符串是否包含子串
    function isContains(str, substr) {
        //str是否包含substr
        return str.indexOf(substr) >= 0;
    }
    //下载保存图片
    function saveImage(imgUrl, imgName) {
        //imgUrl: 图片地址; imgName: 保存的文件名
        try {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', imgUrl, true);
            xhr.responseType = 'blob';
            xhr.onload = () => {
                if (xhr.status === 200) {
                    //将图片文件用浏览器中下载
                    saveAs(xhr.response, imgName);
                }
            };
            xhr.send();
        } catch (e) {
            console.log(e);
        }
    }
    //加载css文件
    function addCSS(href) {
        var link = document.createElement('link');
        link.type = 'text/css';
        link.rel = 'stylesheet';
        link.href = href;
        document.getElementsByTagName("head")[0].appendChild(link);
    }
    //加载js文件
    function addJS(src, cb) {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = src;
        document.getElementsByTagName('head')[0].appendChild(script);
        script.onload = typeof cb === "function" ? cb : function() {};
    }
    //由于@require方式引入jquery时layer使用异常，故引用cdn中jquery v1.10.1；加载完成后引用又拍云中layer v3.1.1
    addJS("https://cdn.bootcss.com/jquery/1.10.1/jquery.min.js", function() {
        addJS("https://static.saintic.com/cdn/layer/3.1.1/layer.js");
    });
    var board_id = window.location.pathname.split('/')[1] === "boards" ? window.location.pathname.split('/')[2] : "";
    var protocol = window.location.protocol;
    /*
        下载图片
    */
    //交互确定下载方式
    function interactive(pins) {
        var msg = [
            '当前画板共抓取' + pins.length + '张图片！提示: 只有登录后才可以抓取几乎所有图片哦。
',
            '请选择以下三种下载方式：
',
            '1. 文本：
    即所有图片地址按行显示，提供复制，粘贴至迅雷、QQ旋风等下载工具批量下载即可，推荐使用此方法。
',
            '2. 本地：
    即所有图片直接保存到硬盘中，由于是批量下载，所以浏览器设置中请关闭"下载前询问每个文件的保存位置"，并且允许浏览器下载多个文件的授权申请，以保证可以自动批量保存，否则每次保存时会弹出询问，对您造成困扰。
',
            '3. 远程：
    即所有图片将由第三方服务器下载并压缩，提供压缩文件链接，直接下载此链接解压即可。
',
            '

寻求帮助？请点击我！
'
        ].join('');
        layer.confirm(msg, {
            title: "选择画板图片下载方式",
            closeBtn: false,
            shadeClose: false,
            shade: 0,
            btn: ['文本', '本地', '远程'],
            btnAlign: 'c',
            btn3: function(index, layero) {
                downloadPicRemotely(pins);
            }
        }, function(index, layero) {
            downloadPicText(pins);
        }, function(index) {
            downloadPicLocally(pins);
        });
    }
    //本地下载
    function downloadPicLocally(pins) {
        for (var i = 0, len = pins.length; i < len; i++) {
            saveImage(pins[i].imgUrl, pins[i].imgName);
        }
    }
    //远端下载
    function downloadPicRemotely(pins) {
        $.ajax({
            url: "https://www.saintic.com/CrawlHuaban/",
            type: "POST",
            data: {
                board_id: board_id,
                pins: JSON.stringify(pins)
            },
            success: function(res) {
                if (res.success === true) {
                    var msg = "下载任务已经提交！
根据画板图片数量，所需时间不等，请稍等数分钟后访问下载链接：
" + res.downloadUrl + "
它将于" + res.expireTime + "过期，资源会被删除，请在那之前下载。";
                    layer.alert(msg, {
                        icon: 1,
                        title: "温馨提示",
                        btn: '我已知晓并复制下载链接',
                        btnAlign: 'c'
                    }, function(index) {
                        layer.close(index);
                        GM_setClipboard(res.downloadUrl);
                        layer.msg("复制成功", {
                            icon: 1
                        });
                    });
                } else {
                    layer.msg("第三方服务异常: " + res.msg);
                }
            }
        });
    }
    //文本方式下载，比如迅雷、QQ旋风
    function downloadPicText(pins) {
        var tip = '请点击复制按钮，粘贴到迅雷等下载！
',
            str = '';
        for (var i = 0, len = pins.length; i < len; i++) {
            str += pins[i].imgUrl + "\n";
        }
        layer.alert(tip + str, {
            title: "文本方式下载",
            btn: '复制',
            btnAlign: 'c',
            icon: 1,
            yes: function(index, layero) {
                layer.close(index);
                GM_setClipboard(str);
                layer.msg("复制成功", {
                    icon: 1
                });
            }
        });
    }
    //定位
    var d = document.getElementById('page').getElementsByClassName('action-buttons')[0];
    //插入下载画板按钮
    if (isContains(d.innerText, "下载此画板") === false) {
        d.insertAdjacentHTML('afterbegin', ' 下载此画板');
    }
    //监听点击下载事件
    document.getElementById("downloadBoard").onclick = function() {
        if (board_id) {
            var retry = 100,
                limit = 100,
                board_url = protocol + '//huaban.com/boards/' + board_id;
            //get first pin data
            $.ajax({
                url: board_url,
                type: "GET",
                async: false,
                success: function(res) {
                    try {
                        //console.log(res);
                        if (res.hasOwnProperty("board") === true) {
                            var board_data = res.board,
                                pin_number = board_data.pin_count,
                                board_pins = board_data.pins;
                            //console.log("Current board <" + board_id + "> pins number is " + pin_number + ", first pins number is " + board_pins.length);
                            if (board_pins.length < pin_number) {
                                var last_pin = board_pins[board_pins.length - 1].pin_id;
                                while (1 <= retry) {
                                    //get ajax pin data
                                    var board_next_url = protocol + "//huaban.com/boards/" + board_id + "/?max=" + last_pin + "&limit=" + limit + "&wfl=1";
                                    $.ajax({
                                        url: board_next_url,
                                        type: "GET",
                                        async: false,
                                        success: function(res) {
                                            //console.log(res);
                                            var board_next_data = res.board;
                                            board_pins = board_pins.concat(board_next_data.pins);
                                            console.log("ajax load board with pin_id " + last_pin + ", get pins number is " + board_next_data.pins.length + ", merged");
                                            if (board_next_data.pins.length === 0) {
                                                retry = 0;
                                                return false;
                                            }
                                            last_pin = board_next_data.pins[board_next_data.pins.length - 1].pin_id;
                                        }
                                    });
                                    retry -= 1;
                                }
                            }
                            //console.log("共抓取" + board_pins.length + "个pin");
                            var pins = [];
                            for (var i = 0, len = board_pins.length; i < len; i++) {
                                var pin = board_pins[i];
                                pins.push({
                                    imgUrl: "http://img.hb.aicdn.com/" + pin.file.key + "_fw658",
                                    imgName: pin.pin_id + "." + pin.file.type.split("/")[1]
                                });
                            }
                            //交互确定下载方式
                            interactive(pins);
                        }
                    } catch (e) {
                        console.log(e);
                    }
                }
            });
        }
    };
})();<|endoftext|>


<commit_before><commit_msg>js: core/datetime: add daysInMonth() function<commit_after><|endoftext|>


<commit_before>//
// Eyes.js - a customizable value inspector for Node.js
//
//   usage:
//
//       var inspect = require('eyes').inspector({style: 'magenta'});
//
//       inspect(something); // inspect with the settings passed to `inspector`
//
//     or
//
//       var eyes = require('eyes');
//
//       eyes.inspect(something); // inspect with the default settings
//
var eyes = {
    defaults: {
        styles: {                // Styles applied to stdout
            all:   'cyan',       // Overall style applied to everything
            label: 'underline',  // Inspection labels, like 'array' in `array: [1, 2, 3]`
            other: 'inverted',   // Objects which don't a literal representation, such as functions
            key:   'bold',       // The keys in object literals, like 'a' in `{a: 1}`
            special: '',         // null, undefined...
            bool: ''             // true & false
        },
        writer: process.stdio.write
    },

    // Return a curried inspect() function, with the `options` argument filled in.
    inspector: function (options) {
        var that = this;
        return function (obj, label, opts) {
            return that.inspect(obj, label,
                process.mixin(true, {}, options || {}, opts || {}));
        };
    },

    // Calls print() to output the inspected object
    inspect: function (obj, label, options) {
        options = process.mixin(true, {}, this.defaults, options || {})
        return this.print(this.stringify(obj, options.styles) + "\n", label, options);
    },

    // Output using the 'writer', and an optional label
    print: function (str, label, options) {
        return options.writer((label ? this.stylize(label, options.styles.label, options.styles) + ': ' : '') +
                                       this.stylize(str,   options.styles.all, options.styles));
    },

    // Convert any object to a string, ready for output.
    // When an 'array' or an 'object' are encountered, they are
    // passed to specialized functions, which can then recursively call
    // stringify().
    stringify: function (obj, styles) {
        var that = this, stylize = function (str, style) {
            return that.stylize(str, style, styles)
        };

        switch (typeOf(obj)) {
            case "string":
                if (obj.length === 1) { return "'" + obj + "'" }
                else { return '"' + obj + '"' }
            case "number"   : return obj + '';
            case "regexp"   : return obj + '';
            case "function" : return stylize("Function",  styles.other);
            case "null"     : return stylize("null",      styles.special);
            case "undefined": return stylize("undefined", styles.special);
            case "boolean"  : return stylize(obj + '',    styles.bool);
            case "array"    : return this.stringifyArray(obj,  styles);
            case "object"   : return this.stringifyObject(obj, styles);
        }
    },

    // Convert an array to a string, such as [1, 2, 3].
    // This function calls stringify() for each of the elements
    // in the array.
    stringifyArray: function (ary, styles) {
        var out = [];

        for (var i = 0; i < ary.length; i++) {
            out.push(this.stringify(ary[i], styles));
        }
        return '[' + out.join(', ') + ']';
    },

    // Convert an object to a string, such as {a: 1}.
    // This function calls stringify() for each of its values,
    // and does not output functions or prototype values.
    stringifyObject: function (obj, styles) {
        var out = [];

        for (var k in obj) {
            if (obj.hasOwnProperty(k) && !(obj[k] instanceof Function)) {
                out.push(this.stylize(k, styles.key, styles) + ': ' + this.stringify(obj[k], styles));
            }
        }
        return "{" + out.join(', ') + "}";
    },

    // Apply a style to a string, eventually,
    // I'd like this to support passing multiple
    // styles.
    stylize: function (str, style, styles) {
        var codes = {
            'bold'      : [1,  22],
            'underline' : [4,  24],
            'inverse'   : [7,  27],
            'cyan'      : [36, 39],
            'magenta'   : [35, 39],
            'yellow'    : [33, 39],
            'green'     : [32, 39],
            'red'       : [31, 39]
        };

        if (style) {
            return '\033[' + styles[style][0] + 'm' + str +
                   '\033[' + styles[style][1] + 'm';
        } else { return str }
    }
};

// CommonJS module support
process.mixin(exports, eyes);

// A better `typeof`
function typeOf(value) {
    var s = typeof value;

    if (s === 'object' || s === 'function') {
        if (value) {
            if (value instanceof Array) { s = 'array' }
            else if (value instanceof RegExp) { s = 'regexp' }
        } else { s = 'null' }
    }
    return s;
}

<commit_msg>end color sections with the styles.all color, instead of no color<commit_after>//
// Eyes.js - a customizable value inspector for Node.js
//
//   usage:
//
//       var inspect = require('eyes').inspector({style: 'magenta'});
//
//       inspect(something); // inspect with the settings passed to `inspector`
//
//     or
//
//       var eyes = require('eyes');
//
//       eyes.inspect(something); // inspect with the default settings
//
var eyes = {
    defaults: {
        styles: {                // Styles applied to stdout
            all:   'cyan',       // Overall style applied to everything
            label: 'underline',  // Inspection labels, like 'array' in `array: [1, 2, 3]`
            other: 'inverted',   // Objects which don't a literal representation, such as functions
            key:   'bold',       // The keys in object literals, like 'a' in `{a: 1}`
            special: '',         // null, undefined...
            bool: ''             // true & false
        },
        writer: process.stdio.write
    },

    // Return a curried inspect() function, with the `options` argument filled in.
    inspector: function (options) {
        var that = this;
        return function (obj, label, opts) {
            return that.inspect(obj, label,
                process.mixin(true, {}, options || {}, opts || {}));
        };
    },

    // Calls print() to output the inspected object
    inspect: function (obj, label, options) {
        options = process.mixin(true, {}, this.defaults, options || {})
        return this.print(this.stringify(obj, options.styles) + "\n", label, options);
    },

    // Output using the 'writer', and an optional label
    print: function (str, label, options) {
        return options.writer((label ? this.stylize(label, options.styles.label, options.styles) + ': ' : '') +
                                       this.stylize(str,   options.styles.all, options.styles));
    },

    // Convert any object to a string, ready for output.
    // When an 'array' or an 'object' are encountered, they are
    // passed to specialized functions, which can then recursively call
    // stringify().
    stringify: function (obj, styles) {
        var that = this, stylize = function (str, style) {
            return that.stylize(str, style, styles)
        };

        switch (typeOf(obj)) {
            case "string":
                if (obj.length === 1) { return "'" + obj + "'" }
                else { return '"' + obj + '"' }
            case "number"   : return obj + '';
            case "regexp"   : return obj + '';
            case "function" : return stylize("Function",  styles.other);
            case "null"     : return stylize("null",      styles.special);
            case "undefined": return stylize("undefined", styles.special);
            case "boolean"  : return stylize(obj + '',    styles.bool);
            case "array"    : return this.stringifyArray(obj,  styles);
            case "object"   : return this.stringifyObject(obj, styles);
        }
    },

    // Convert an array to a string, such as [1, 2, 3].
    // This function calls stringify() for each of the elements
    // in the array.
    stringifyArray: function (ary, styles) {
        var out = [];

        for (var i = 0; i < ary.length; i++) {
            out.push(this.stringify(ary[i], styles));
        }
        return '[' + out.join(', ') + ']';
    },

    // Convert an object to a string, such as {a: 1}.
    // This function calls stringify() for each of its values,
    // and does not output functions or prototype values.
    stringifyObject: function (obj, styles) {
        var out = [];

        for (var k in obj) {
            if (obj.hasOwnProperty(k) && !(obj[k] instanceof Function)) {
                out.push(this.stylize(k, styles.key, styles) + ': ' + this.stringify(obj[k], styles));
            }
        }
        return "{" + out.join(', ') + "}";
    },

    // Apply a style to a string, eventually,
    // I'd like this to support passing multiple
    // styles.
    stylize: function (str, style, styles) {
        var codes = {
            'bold'      : [1,  22],
            'underline' : [4,  24],
            'inverse'   : [7,  27],
            'cyan'      : [36, 39],
            'magenta'   : [35, 39],
            'yellow'    : [33, 39],
            'green'     : [32, 39],
            'red'       : [31, 39]
        }, endCode;

        if (style && codes[style]) {
            endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0]
                                                             : codes[style][1];
            return '\033[' + codes[style][0] + 'm' + str +
                   '\033[' + endCode + 'm';
        } else { return str }
    }
};

// CommonJS module support
process.mixin(exports, eyes);

// A better `typeof`
function typeOf(value) {
    var s = typeof value;

    if (s === 'object' || s === 'function') {
        if (value) {
            if (value instanceof Array) { s = 'array' }
            else if (value instanceof RegExp) { s = 'regexp' }
        } else { s = 'null' }
    }
    return s;
}

<|endoftext|>


<commit_before>#!/usr/bin/node

var _ = require('underscore');
var cluster = require('cluster');
var path = require('path');
var os = require('os');
var config_path = null;
var working_path = null;
var log_file_path = null;
var logger = null;

// Flag that is consulted for whether we will attempt to spawn
// replacement workers if any should die. This will be set to
// true when we shutdown via the 'exit' handler.
var letWorkersDie = false;

// Flags to indicate whether a non-standard config file location or
// non-standard working directories were specified.
var custom_config = false;
var custom_working = false;
var custom_log_file = false;
var osdf_utils = require('osdf_utils');

configure();

function engine_start() {
    // Get the configuration.
    require('config');
    var config = Config.get_instance(config_path);

    if (cluster.isMaster) {
        start_master(config);
    } else {
        var forked_worker = require("./worker");
        forked_worker.start_worker(config, working_path);
    }
}

function configure() {
    var commander = require('commander');

    commander.option('-c, --config <path>', 'Specify a configuration file. Default is <OSDF_HOME>/conf/config.ini.')
             .option('-w, --working <path>', 'Specify a path to the working directory where namespaces data is stored.')
             .option('-l, --log <path>', 'Specify the path to the log file.')
             .parse(process.argv);

    config_path = commander.config;
    working_path = commander.working;
    log_file_path = commander.log;

    if (config_path === null || typeof config_path === 'undefined') {
        config_path = osdf_utils.get_config();
    } else {
        osdf_utils.set_config(config_path);
        custom_config = true;
    }

    if (log_file_path === null || typeof log_file_path === 'undefined') {
        //log_file_path = path.join(osdf_utils.get_osdf_root(), '/logs/osdf.log');
    } else {
        // Set the path to hte log file and...
        osdf_utils.set_log_file(log_file_path);
        custom_log_file = true;
    }

    // ...get the logger object
    logger = osdf_utils.get_logger();

    if (working_path === null || typeof working_path === 'undefined') {
        // Nothing specified, get the default
        working_path = osdf_utils.get_working_dir();
        engine_start();
    } else {
        custom_working = true;
        osdf_utils.set_working_dir(working_path, function() {
            engine_start();
        });
    }
}

function start_master(config) {
    console.log("OSDF_ROOT: " + osdf_utils.get_osdf_root());

    var cpu_count = os.cpus().length;
    var workers_ready = 0;
    var worker_idx;

    console.log("Running on " + cpu_count + " CPUs.");

    var workers_array = [];

    var ready_data = {};

    // Fork a worker for each CPU
    for (worker_idx = 0; worker_idx < cpu_count; worker_idx++) {
        var worker = cluster.fork();

        workers_array.push(worker);

        worker.on('message', function(msg) {
            if (msg.hasOwnProperty('cmd') && msg['cmd'] === 'user_count') {
                ready_data['user_count'] = msg['users'];
            }

            if (msg.hasOwnProperty('cmd') && msg['cmd'] === 'schema_change') {
                // Send messages to all the workers so that they can adjust their
                // lists of active schemas.
                var type = msg['type'];
                logger.info("Master got a schema change event of type: " + type + ". Relay this to the workers.");

                _.each(workers_array, function (clustered_worker) {
                    clustered_worker.send(msg);
                });
            }

            if (msg.hasOwnProperty('cmd') && msg['cmd'] === 'abort') {
                var reason = msg['reason'];
                console.error("Aborting execution. Reason: " + reason);
                letWorkersDie = true;
                process.exit(1);
            }

            if (msg.hasOwnProperty('cmd') && msg['cmd'] === 'init_completed') {
                workers_ready++;

                if (workers_ready === cpu_count) {
                    // Show some details about the server after it's up and running.
                    var bind_address = config.value("global", "bind_address");
                    var port = config.value("global", "port");
                    ready_data['address'] = bind_address;
                    ready_data['port'] = port;
                    show_ready(ready_data);
                }
            }
        });
    }

    cluster.on('death', function(worker) {
        if (! letWorkersDie) {
            console.error('Worker ' + worker.pid + ' died. Starting a replacement...');
            cluster.fork();
        }
    });

    process.on('SIGTERM', function() {
        console.error("Caught SIGTERM. Killing workers.");

        // Modify the flag so that the 'death' handler does not attempt
        // to replace the workers we are about to kill off.
        letWorkersDie = true;

        kill_workers(workers_array);
    });

    process.on('exit', function() {
        console.error("Exiting. Killing workers.");

        // Modify the flag so that the 'death' handler does not attempt
        // to replace the workers we are about to kill off.
        letWorkersDie = true;

        kill_workers(workers_array);
    });
}

function kill_workers(workers) {
    // Iterate through the workers, and kill each of them.
    _.each(workers, function(worker) {
        console.error('Killing worker ' + worker.pid);
        worker.kill();
    });
}

// Display server details when we have started up.
function show_ready(ready_data) {
    var user_count = ready_data['user_count'];
    var address = ready_data['address'];
    var port = ready_data['port'];

    if (custom_config) {
        console.log("Configured settings file: " + config_path);
    }

    if (custom_working) {
        console.log("Configured working area: " + working_path);
    }

    if (custom_log_file) {
        console.log("Configured log file: " + log_file_path);
    }

    console.log("Total number of registered OSDF users: " + user_count);
    console.log("=================================");
    console.log("Welcome to");
    console.log(new Buffer("ICBfX19fICBfX19fX19fICBfX19fCiAvIF9fIFwvIF9fLyBfIFw" +
                           "vIF9fLwovIC9fLyAvXCBcLyAvLyAvIF8vClxfX19fL19fXy9fX19fL18vCgo=",
                           'base64').toString('utf8'));
    console.log("Open Science Data Framework\n");

    console.log('Listening on server:port : ' + address + ":" + port);
}
<commit_msg>Renamed some methods and terms to match the latest node api for cluster work.<commit_after>#!/usr/bin/node

var _ = require('underscore');
var cluster = require('cluster');
var path = require('path');
var os = require('os');
var config_path = null;
var working_path = null;
var log_file_path = null;
var logger = null;

// Flag that is consulted for whether we will attempt to spawn
// replacement workers if any should die. This will be set to
// true when we shutdown via the 'exit' handler.
var letWorkersDie = false;

// Flags to indicate whether a non-standard config file location or
// non-standard working directories were specified.
var custom_config = false;
var custom_working = false;
var custom_log_file = false;
var osdf_utils = require('osdf_utils');

configure();

function engine_start() {
    // Get the configuration.
    require('config');
    var config = Config.get_instance(config_path);

    if (cluster.isMaster) {
        start_master(config);
    } else {
        var forked_worker = require("./worker");
        forked_worker.start_worker(config, working_path);
    }
}

function configure() {
    var commander = require('commander');

    commander.option('-c, --config <path>',
                     'Specify a configuration file. Default is <OSDF_HOME>/conf/config.ini.')
             .option('-w, --working <path>',
                     'Specify a path to the working directory where namespaces data is stored.')
             .option('-l, --log <path>',
                     'Specify the path to the log file.')
             .parse(process.argv);

    config_path = commander.config;
    working_path = commander.working;
    log_file_path = commander.log;

    if (config_path === null || typeof config_path === 'undefined') {
        config_path = osdf_utils.get_config();
    } else {
        osdf_utils.set_config(config_path);
        custom_config = true;
    }

    if (log_file_path === null || typeof log_file_path === 'undefined') {
        //log_file_path = path.join(osdf_utils.get_osdf_root(), '/logs/osdf.log');
    } else {
        // Set the path to the log file and...
        osdf_utils.set_log_file(log_file_path);
        custom_log_file = true;
    }

    // ...get the logger object
    logger = osdf_utils.get_logger();

    if (working_path === null || typeof working_path === 'undefined') {
        // Nothing specified, get the default
        working_path = osdf_utils.get_working_dir();
        engine_start();
    } else {
        custom_working = true;
        osdf_utils.set_working_dir(working_path, function() {
            engine_start();
        });
    }
}

function start_master(config) {
    console.log("OSDF_ROOT: " + osdf_utils.get_osdf_root());

    var cpu_count = os.cpus().length;
    var workers_ready = 0;
    var worker_idx;

    console.log("Running on " + cpu_count + " CPUs.");

    var workers_array = [];

    var ready_data = {};

    // Fork a worker for each CPU
    for (worker_idx = 0; worker_idx < cpu_count; worker_idx++) {
        var worker = cluster.fork();

        workers_array.push(worker);

        worker.on('message', function(msg) {
            if (msg.hasOwnProperty('cmd') && msg['cmd'] === 'user_count') {
                ready_data['user_count'] = msg['users'];
            }

            if (msg.hasOwnProperty('cmd') && msg['cmd'] === 'schema_change') {
                // Send messages to all the workers so that they can adjust their
                // lists of active schemas.
                var type = msg['type'];
                logger.info("Master got a schema change event of type: " + type + ". " +
                            "Relay this to the workers.");

                _.each(workers_array, function (clustered_worker) {
                    clustered_worker.send(msg);
                });
            }

            if (msg.hasOwnProperty('cmd') && msg['cmd'] === 'abort') {
                var reason = msg['reason'];
                console.error("Aborting execution. Reason: " + reason);
                letWorkersDie = true;
                process.exit(1);
            }

            if (msg.hasOwnProperty('cmd') && msg['cmd'] === 'init_completed') {
                workers_ready++;

                if (workers_ready === cpu_count) {
                    // Show some details about the server after it's up and running.
                    var bind_address = config.value("global", "bind_address");
                    var port = config.value("global", "port");
                    ready_data['address'] = bind_address;
                    ready_data['port'] = port;
                    show_ready(ready_data);
                }
            }
        });
    }

    // This is for node.js .6.x, in wich the event is called 'death'.
    cluster.on('death', function(worker) {
        if (! letWorkersDie) {
            console.error('Worker ' + worker.pid + ' died. Starting a replacement...');
            cluster.fork();
        }
    });

    // For node 0.8.x, the 'death' event was renamed to 'exit' on the cluster object.
    // See here: https://github.com/joyent/node/wiki/API-changes-between-v0.6-and-v0.8
    cluster.on('exit', function(worker) {
        if (! letWorkersDie) {
            console.error('Worker ' + worker.pid + ' died. Starting a replacement...');
            cluster.fork();
        }
    });

    process.on('SIGTERM', function() {
        console.error("Caught SIGTERM. Destroying workers.");

        // Modify the flag so that the 'death' handler does not attempt
        // to replace the workers we are about to destroy off.
        letWorkersDie = true;

        destroy_workers(workers_array);
    });

    process.on('exit', function() {
        console.error("Exiting. Destroying workers.");

        // Modify the flag so that the 'death' handler does not attempt
        // to replace the workers we are about to destroy off.
        letWorkersDie = true;

        destroy_workers(workers_array);
    });
}

function destroy_workers(workers) {
    // Iterate through the workers, and destroy each of them.
    _.each(workers, function(worker) {
        console.error('Destroying worker ' + worker.pid);
        if (worker.kill) {
            // This is for node.js 0.6.x
            worker.kill();
        } else {
            worker.destroy();
        }
    });
}

// Display server details when we have started up.
function show_ready(ready_data) {
    var user_count = ready_data['user_count'];
    var address = ready_data['address'];
    var port = ready_data['port'];

    if (custom_config) {
        console.log("Configured settings file: " + config_path);
    }

    if (custom_working) {
        console.log("Configured working area: " + working_path);
    }

    if (custom_log_file) {
        console.log("Configured log file: " + log_file_path);
    }

    console.log("Total number of registered OSDF users: " + user_count);
    console.log("=================================");
    console.log("Welcome to");
    console.log(new Buffer("ICBfX19fICBfX19fX19fICBfX19fCiAvIF9fIFwvIF9fLyBfIFw" +
                           "vIF9fLwovIC9fLyAvXCBcLyAvLyAvIF8vClxfX19fL19fXy9fX19fL18vCgo=",
                           'base64').toString('utf8'));
    console.log("Open Science Data Framework\n");

    console.log('Listening on server:port : ' + address + ":" + port);
}
<|endoftext|>


<commit_before>var Crypto = {
util: {

	// Convert n to unsigned 32-bit integer
	u32: function (n) {
		return n >>> 0;
	},

	// Unsigned 32-bit addition
	add: function (m, n) {

		// Shortcut
		var u32 = this.u32;

		// If only two numbers given, add them
		if (arguments.length == 2)
			return u32(u32(m) + u32(n));

		// Else, add any number of arguments
		var result = arguments[0];
		for (var i = 1; i < arguments.length; i++)
			result = this.add(result, arguments[i]);
		return result;

	},

	// Unsigned 32-bit multiplication
	mult: function (m, n) {
		return this.add((n & 0xFFFF0000) * m,
				(n & 0x0000FFFF) * m);
	},

	// Unsigned 32-bit greater than (>) comparison
	gt: function (m, n) {
		return this.u32(m) > this.u32(n);
	},

	// Unsigned 32-bit less than (<) comparison
	lt: function (m, n) {
		return this.u32(m) < this.u32(n);
	},

	// Bit-wise rotate left
	rotl: function (n, b) {
		return (n << b) | (n >>> (32 - b));
	},

	// Bit-wise rotate right
	rotr: function (n, b) {
		return (n << (32 - b)) | (n >>> b);
	},

	// Swap big-endian to little-endian and vice versa
	endian: function (n) {

		// If number given, swap endian
		if (n.constructor == Number) {
			return this.rotl(n,  8) & 0x00FF00FF |
			       this.rotl(n, 24) & 0xFF00FF00;
		}

		// Else, assume array and swap all items
		for (var i = 0; i < n.length; i++)
			n[i] = this.endian(n[i]);
		return n;

	},

	// Convert a string to a byte array
	string_bytes: function (str) {
		var bytes = [];
		for (var i = 0; i < str.length; i++)
			bytes.push(str.charCodeAt(i));
		return bytes;
	},

	// Convert a byte array to a string
	bytes_string: function (bytes) {
		var str = [];
		for (var i = 0; i < bytes.length; i++)
			str.push(String.fromCharCode(bytes[i]));
		return str.join("");
	},

	// Convert a string to big-endian 32-bit words
	string_words: function (str) {
		var words = [];
		for (var c = 0, b = 0; c < str.length; c++, b += 8)
			words[b >>> 5] |= str.charCodeAt(c) << (24 - b % 32);
		return words;
	},

	// Convert big-endian 32-bit words to a string
	words_string: function (words) {
		var str = [];
		for (var b = 0; b < words.length * 32; b += 8)
			str.push(String.fromCharCode((words[b >>> 5] >>> (24 - b % 32)) & 0xFF));
		return str.join("");
	},

	// Convert a byte array to big-endian 32-bits words
	bytes_words: function (bytes) {
		var words = [];
		for (var i = 0, b = 0; i < bytes.length; i++, b += 8)
			words[b >>> 5] |= bytes[i] << (24 - b % 32);
		return words;
	},

	// Convert big-endian 32-bit words to a byte array
	words_bytes: function (words) {
		var bytes = [];
		for (var b = 0; b < words.length * 32; b += 8)
			bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
		return bytes;
	}

}
};
<commit_msg>Fixed whitespace characters.<commit_after>var Crypto = {
util: {

	// Convert n to unsigned 32-bit integer
	u32: function (n) {
		return n >>> 0;
	},

	// Unsigned 32-bit addition
	add: function (m, n) {

		// Shortcut
		var u32 = this.u32;

		// If only two numbers given, add them
		if (arguments.length == 2)
			return u32(u32(m) + u32(n));

		// Else, add any number of arguments
		var result = arguments[0];
		for (var i = 1; i < arguments.length; i++)
			result = this.add(result, arguments[i]);
		return result;

	},

	// Unsigned 32-bit multiplication
	mult: function (m, n) {
		return this.add((n & 0xFFFF0000) * m,
		                (n & 0x0000FFFF) * m);
	},

	// Unsigned 32-bit greater than (>) comparison
	gt: function (m, n) {
		return this.u32(m) > this.u32(n);
	},

	// Unsigned 32-bit less than (<) comparison
	lt: function (m, n) {
		return this.u32(m) < this.u32(n);
	},

	// Bit-wise rotate left
	rotl: function (n, b) {
		return (n << b) | (n >>> (32 - b));
	},

	// Bit-wise rotate right
	rotr: function (n, b) {
		return (n << (32 - b)) | (n >>> b);
	},

	// Swap big-endian to little-endian and vice versa
	endian: function (n) {

		// If number given, swap endian
		if (n.constructor == Number) {
			return this.rotl(n,  8) & 0x00FF00FF |
			       this.rotl(n, 24) & 0xFF00FF00;
		}

		// Else, assume array and swap all items
		for (var i = 0; i < n.length; i++)
			n[i] = this.endian(n[i]);
		return n;

	},

	// Convert a string to a byte array
	string_bytes: function (str) {
		var bytes = [];
		for (var i = 0; i < str.length; i++)
			bytes.push(str.charCodeAt(i));
		return bytes;
	},

	// Convert a byte array to a string
	bytes_string: function (bytes) {
		var str = [];
		for (var i = 0; i < bytes.length; i++)
			str.push(String.fromCharCode(bytes[i]));
		return str.join("");
	},

	// Convert a string to big-endian 32-bit words
	string_words: function (str) {
		var words = [];
		for (var c = 0, b = 0; c < str.length; c++, b += 8)
			words[b >>> 5] |= str.charCodeAt(c) << (24 - b % 32);
		return words;
	},

	// Convert big-endian 32-bit words to a string
	words_string: function (words) {
		var str = [];
		for (var b = 0; b < words.length * 32; b += 8)
			str.push(String.fromCharCode((words[b >>> 5] >>> (24 - b % 32)) & 0xFF));
		return str.join("");
	},

	// Convert a byte array to big-endian 32-bits words
	bytes_words: function (bytes) {
		var words = [];
		for (var i = 0, b = 0; i < bytes.length; i++, b += 8)
			words[b >>> 5] |= bytes[i] << (24 - b % 32);
		return words;
	},

	// Convert big-endian 32-bit words to a byte array
	words_bytes: function (words) {
		var bytes = [];
		for (var b = 0; b < words.length * 32; b += 8)
			bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
		return bytes;
	}

}
};
<|endoftext|>


<commit_before>// Liveblog custom additions to Backbone.js
'use strict';

define([
    'backbone',
    'underscore'
], function(Backbone, _) {

    Backbone.defaultSync = Backbone.sync;

    Backbone.sync = function(method, model, options) {

        if (!options) { options = {}; }

        // Never delete models from the collection on merge
        options.remove = false;

        if (method === 'read') {
            // Request a date format that all browsers can parse
            options.headers = _.isObject(options.headers) ? options.headers : {};

            options.headers['X-Format-DateTime'] = 'yyyy-MM-ddTHH:mm:ss\'Z\'';
            // Add parameters provided in model.syncParams.headers
            // to the request header
            _.each(model.syncParams.headers, function(value, key) {
                options.headers[key] = value;
            });

            // Add parameters provided in model.syncParams.data
            // as parameters to the request url, unless the same
            // parameter has been provided as an option in fetch method.
            // (params in fetch method have precedence over params in
            // syncParams.data)
            _.each(model.syncParams.data, function(value, key) {
                options.data = options.data || {};
                if (!options.data[key]) {
                    options.data[key] = value;
                }
            });
        }
        return Backbone.defaultSync(method, model, options);
    };

    Backbone.defaultAjax = Backbone.ajax;

    Backbone.ajax = function(options) {

        if (typeof process !== 'undefined' &&
                process.versions &&
                !!process.versions.node) {
            return Backbone.nodeSync(options);
        }

        // send the old headers if liveblog.emulateOLDHEADERS
        if (liveblog.emulateOLDHEADERS) {
            options.dataType = 'json';
            options.headers = _.isObject(options.headers) ? options.headers : {};
            options.headers.Accept = 'text/json';
        }

        // send the headers as GET parametes if liveblog.emulateHEADERSPARAMS
        if (liveblog.emulateHEADERSASPARAMS) {
            options.data = _.extend(options.data, options.headers);
            delete options.headers;
        }
        return Backbone.defaultAjax(options);
    };

    Backbone.nodeSync = function(options) {

        var request = require.nodeRequire('request'),
           qs = require.nodeRequire('qs');

        // Parse response to json
        options.json = true;
        options.timeout = 1000;

        // Set the query string with the options.data params
        if (options.data) {
            options.url += ((options.url.indexOf('?') === -1) ? '?': '&') + qs.stringify(options.data);
            delete options.data;
        }

        if (GLOBAL && GLOBAL.liveblogLogger) {
            liveblogLogger.info('Request to url: %s', options.url);
        }
        // Use options.success and options.errors callbacks
        request.get(options, function(error, response, data) {
            if (!error && response.statusCode === 200) {
                if (options.success) {
                    return options.success(data);
                }
            } else if (options.error && _.has(response, 'request')) {
                liveblogLogger.error('Request to url: %s failed with code: %s and body: ', response.request.href, response.statusCode, response.body);
                return options.error(response);
            }
        });
    };

    return Backbone;
});
<commit_msg>LB-1901 Better logging<commit_after>// Liveblog custom additions to Backbone.js
'use strict';

define([
    'backbone',
    'underscore'
], function(Backbone, _) {

    Backbone.defaultSync = Backbone.sync;

    Backbone.sync = function(method, model, options) {

        if (!options) { options = {}; }

        // Never delete models from the collection on merge
        options.remove = false;

        if (method === 'read') {
            // Request a date format that all browsers can parse
            options.headers = _.isObject(options.headers) ? options.headers : {};

            options.headers['X-Format-DateTime'] = 'yyyy-MM-ddTHH:mm:ss\'Z\'';
            // Add parameters provided in model.syncParams.headers
            // to the request header
            _.each(model.syncParams.headers, function(value, key) {
                options.headers[key] = value;
            });

            // Add parameters provided in model.syncParams.data
            // as parameters to the request url, unless the same
            // parameter has been provided as an option in fetch method.
            // (params in fetch method have precedence over params in
            // syncParams.data)
            _.each(model.syncParams.data, function(value, key) {
                options.data = options.data || {};
                if (!options.data[key]) {
                    options.data[key] = value;
                }
            });
        }
        return Backbone.defaultSync(method, model, options);
    };

    Backbone.defaultAjax = Backbone.ajax;

    Backbone.ajax = function(options) {

        if (typeof process !== 'undefined' &&
                process.versions &&
                !!process.versions.node) {
            return Backbone.nodeSync(options);
        }

        // send the old headers if liveblog.emulateOLDHEADERS
        if (liveblog.emulateOLDHEADERS) {
            options.dataType = 'json';
            options.headers = _.isObject(options.headers) ? options.headers : {};
            options.headers.Accept = 'text/json';
        }

        // send the headers as GET parametes if liveblog.emulateHEADERSPARAMS
        if (liveblog.emulateHEADERSASPARAMS) {
            options.data = _.extend(options.data, options.headers);
            delete options.headers;
        }
        return Backbone.defaultAjax(options);
    };

    Backbone.nodeSync = function(options) {

        var request = require.nodeRequire('request'),
           qs = require.nodeRequire('qs');

        // Parse response to json
        options.json = true;
        options.timeout = 2000;

        // Set the query string with the options.data params
        if (options.data) {
            options.url += ((options.url.indexOf('?') === -1) ? '?': '&') + qs.stringify(options.data);
            delete options.data;
        }

        if (GLOBAL && GLOBAL.liveblogLogger) {
            liveblogLogger.info('Request to url: %s', options.url);
        }
        // Use options.success and options.errors callbacks
        request.get(options, function(error, response, data) {
            if (error) {
                liveblogLogger.error('Request to url: %s failed with code: %s and body: ',
                        _.has(response, 'request') ? response.request.href : options.url,
                        _.has(response, 'statusCode') ? response.statusCode : error,
                        _.has(response, 'body') ? response.body : response
                );
            }
            if (!error && response.statusCode === 200) {
                if (options.success) {
                    return options.success(data);
                }
            } else if (options.error) {
                return options.error(response);
            }
        });
    };

    return Backbone;
});
<|endoftext|>


<commit_before>;(function($){

	// registered modules to cytoweb, indexed by name
	var reg = {
		renderers: {},
		layouts: {}
	};

	// allow calls on a jQuery selector by proxing calls to $.cytoscapeweb
	// e.g. $("#foo").cytoscapeweb(options) => $.cytoscapeweb(options) on #foo
	$.fn.cytoscapeweb = function(opts){

		// proxy to create instance
		if( typeof opts == typeof {} ){
			return $(this).each(function(){
				var options = $.extend({}, opts, {
					selector: $(this)
				});

				$.cytoscapeweb(options);
			});
		}

		// proxy a function call
		else {
			var rets = [];

			$(this).each({
				var cy = $(this).data("cytoscapeweb");
				var fnName = opts;
				var args = Array.prototype.slice.call( arguments, 1 );

				if( cy != null && $.isFunction( cy[fnName] ) ){
					var ret = cy[fnName].apply(cy, args);
					rets.push(ret);
				}
			});

			return rets;
		}

	};

	// allow functional access to cytoweb
	// e.g. var cytoweb = $.cytoscapeweb({ selector: "#foo", ... });
	//      var nodes = cytoweb.nodes();
	$.cytoscapeweb = function(opts){

		// create instance
		if( typeof opts == typeof {} ){
			var defaults = {
				layout: "forcedirected",
				renderer: "svg",
				style: { // actual default style later specified by renderer
					global: {},
					nodes: {},
					edges: {}
				},
				bypass: {
					nodes: {},
					edges: {}
				}
			};

			var options = $.extend(true, {}, defaults, opts);

			// structs to hold internal cytoweb model
			var structs = {
				style: options.style,
				bypass: options.bypass,
				data: {
					nodes: {}, // id => data
					edges: {}  // id => data
				},
				nodes: {}, // id => node object
				edges: {}  // id => edge object
			};

			// return a deep copy of an object
			function copy(obj){
				if( $.isArray(obj) ){
					return $.extend(true, [], obj);
				} else {
					return $.extend(true, {}, obj);
				}
			}

			// getter/setter for node and edge fields
			function field(params){
				return function(){

					if( params.json ){
						var newVal = arguments[0];

						if( newVal === undefined ){
							return copy( structs[params.name][params.group][this.id] );
						} else {
							structs[params.name][params.group][this.id] = copy( newVal );
						}

					} else {
						var attr = arguments[0];
						var val = arguments[1];

						if( val === undefined ){
							var ret = structs[params.name][params.group][this.id][attr];

							return ( typeof ret == "object" ? copy(ret) : ret );
						} else {
							structs[params.name][params.group][this.id][attr] = ( typeof val == "object" ? copy(val) : val );
						}
					}

				};
			}

			function CyNode(params){
				this.id = params.data.id;
				this.data(params.data);
				this.bypass(params.bypass);
			}
			CyNode.prototype.bypass = field({ name: "bypass",  group: "nodes", json: true });
			CyNode.prototype.data = field({ name: "data",  group: "nodes" });

			function CyEdge(params){
				this.id = params.data.id;
			}
			CyEdge.prototype.bypass = field({ name: "bypass",  group: "edges", json: true });
			CyEdge.prototype.data = field({ name: "data",  group: "edges" });

			// for getting/setting top-level object properties
			function jsonGetterSetter(field, callback){
				return function(val){

					if( val === undefined ){
						return copy( structs[field] );
					} else {
						structs[field] = copy( val );
					}

					callback();
				};
			}

			var renderer = reg.renderers[options.renderer.toLowerCase()];

			// this is the cytoweb object
			var cy = {

				style: jsonGetterSetter("style", function(){
					// TODO notify renderer of style change
				}),

				bypass: jsonGetterSetter("bypass", function(){
					// TODO notify renderer of bypass change
				}),

				node: function(id){
					return nodes[id];
				},

				edge: function(id){
					return edges[id];
				},

				nodes: function(){
					var ret = [];
					$.each(nodes, function(id, node){
						ret.push(node);
					});
					return ret;
				},

				edges: function(){
					var ret = [];
					$.each(edges, function(id, edge){
						ret.push(edge);
					});
					return ret;
				}

			};

			renderer.draw({
				nodes: nodes,
				edges: edges,
				style: style,
				bypass: bypass
			});

			return cy;
		}

		// allow for registration of extensions
		else if( typeof opts == typeof "" ) {
			var registrant = arguments[0].toLowerCase(); // what to register (e.g. "renderer")
			var name = arguments[1].toLowerCase(); // name of the module (e.g. "svg")
			var module = arguments[2]; // the module object

			if( module == null ){
				// get the module by name; e.g. $.cytoscapeweb("renderer", "svg");
				return reg[registrant][name];
			} else {
				// set the module; e.g. $.cytoscapeweb("renderer", "svg", { ... });
				reg[registrant][name] = module;
			}
		}
	};

	// use short alias (cy) if not already defined
	if( $.fn.cy == null && $.cy == null ){
		$.fn.cy = $.fn.cytoscapeweb;
		$.cy = $.cytoscapeweb;
	}

})(jQuery);

<commit_msg>most functions added from old api<commit_after>;(function($){

	// registered modules to cytoweb, indexed by name
	var reg = {
		formats: {},
		renderers: {},
		layouts: {}
	};

	// allow calls on a jQuery selector by proxing calls to $.cytoscapeweb
	// e.g. $("#foo").cytoscapeweb(options) => $.cytoscapeweb(options) on #foo
	$.fn.cytoscapeweb = function(opts){

		// proxy to create instance
		if( typeof opts == typeof {} ){
			return $(this).each(function(){
				var options = $.extend({}, opts, {
					selector: $(this)
				});

				$.cytoscapeweb(options);
			});
		}

		// proxy a function call
		else {
			var rets = [];

			$(this).each({
				var cy = $(this).data("cytoscapeweb");
				var fnName = opts;
				var args = Array.prototype.slice.call( arguments, 1 );

				if( cy != null && $.isFunction( cy[fnName] ) ){
					var ret = cy[fnName].apply(cy, args);
					rets.push(ret);
				}
			});

			// if only one instance, don't need to return array
			if( rets.length == 1 ){
				rets = rets[0];
			}

			return rets;
		}

	};

	// allow functional access to cytoweb
	// e.g. var cytoweb = $.cytoscapeweb({ selector: "#foo", ... });
	//      var nodes = cytoweb.nodes();
	$.cytoscapeweb = function(opts){

		// create instance
		if( typeof opts == typeof {} ){
			var defaults = {
				layout: "forcedirected",
				renderer: "svg",
				style: { // actual default style later specified by renderer
					global: {},
					nodes: {},
					edges: {}
				},
				bypass: {
					nodes: {},
					edges: {}
				}
			};

			var options = $.extend(true, {}, defaults, opts);

			// structs to hold internal cytoweb model
			var structs = {
				style: options.style,
				bypass: options.bypass,
				nodes: {}, // id => node object
				edges: {}  // id => edge object
			};

			// return a deep copy of an object
			function copy(obj){
				if( $.isArray(obj) ){
					return $.extend(true, [], obj);
				} else {
					return $.extend(true, {}, obj);
				}
			}

			// reusable functions for use in defining api functions w/o typing very similar code
			// over and over agaim
			var functions = {

				element: {

					attrGetterSetter: function(params){
						return function(attr, val){
							var ret;

							if( val === undefined ){
								ret = this._private.[ params.name ][ attr ];
								ret =  ( typeof ret == "object" ? copy(ret) : ret );
							} else {
								this._private.[ params.name ][ attr ] = ( typeof val == "object" ? copy(val) : val );
								ret = this;
							}

							$.isFunction(params.callback) && params.callback();
							return ret;
						};
					},

					listenerAlias: function(params){
						return function(callback){
							return this.bind(params.name, callback);
						};
					}

				},

				api: {
					// for getting/setting top-level object properties
					jsonGetterSetter: function (params){
						return function(val){
							var ret;

							if( val === undefined ){
								ret = copy( structs[params.struct] );
							} else {
								structs[params.struct] = copy( val );
								ret = this;
							}

							$.isFunction(params.after) && params.after();
							return ret;
						};
					},

					// getting nodes/edges with a filter function to select which ones to include
					elementsCollection: function(params){
						return function(filterFn){
							var elements = [];
							$.each(structs[params.group], function(id, element){
								if( !$.isFunction(filterFn) || filterFn(element) ){
									elements.push(element);
								}
							});
							var collection = new CyCollection(elements);
							return collection;
						};
					},

					// add node/edge to cytoweb
					addElement: function(params){
						return function(opts){
							return new CyElement({
								group: params.group,
								data: opts.data.
								bypass: opts.bypass
							});
						}
					}
				}

			};

			var idFactory = {
				prefix: {
					nodes: "n",
					edges: "e"
				},
				id: {
					nodes: 0,
					edges: 0
				},
				generate: function(group, tryThisId){
					var id = tryThisId != null ? tryThisId : this.prefix[group] + this.id[group];

					while( structs[group][id] != null ){
						id = this.prefix[group] + ( ++this.id[group] );
					}

					return id;
				}
			};

			// represents a node or an edge
			function CyElement(params){
				var group = params.group;
				this.group = function(){
					return group;
				}

				this.active = function(){
					return true;
				};

				this._private.data = copy( data );
				this._private.data.id = idFactory.generate( group(), this._private.data.id );
				this.id = function(){
					 return this._private.data.id;
				};

				this._private.bypass = copy( params.bypass );
				this._private.listeners = {};
				this._private.position = copy( params.position );

				structs.bypass[ group() ][ id() ] = this._private.bypass;
				structs[ group() ][ id() ] = this;
			}

			// remove from cytoweb
			CyElement.prototype.remove = function(){
				structs.bypass[ group() ][ id() ] = undefined;
				structs[ group() ][ id() ] = undefined;

				this.active = function(){
					return false;
				};

				return this;
			}

			CyElement.prototype.bypass = function(newBypass){
				if( newBypass === undefined ){
					return copy( this._private.bypass );
				} else {
					this._private.bypass = copy( newBypass );

				}
			};

			CyElement.prototype.data = functions.element.attrGetterSetter({ name: "data", callback: function(){
				notifyRenderer({
					type: "data",
					elements: new CyCollection([ this ])
				});
			} });

			CyElement.prototype.position = functions.element.attrGetterSetter({ name: "position", callback: function(){
				notifyRenderer({
					type: "position",
					elements: new CyCollection([ this ])
				});
			} });

			CyElement.prototype.bind = function(event, callback){
				if( this._private.listeners[event] == null ){
					this._private.listeners[event] = [];
				}
				this._private.listeners[event].push(callback);

				return this;
			};

			CyElement.prototype.unbind = function(event, callback){
				var listeners = this._private.listeners[event];

				if( listeners != null ){
					$.each(listeners, function(i, listener){
						if( callback == null || callback == listener ){
							listeners[i] = undefined;
						}
					});
				}

				return this;
			};

			CyElement.prototype.trigger = function(event, data){
				var listeners = this._private.listeners[event];

				var eventData = data;
				if( listeners != null ){
					$.each(listeners, function(i, listener){
						if( $.isFunction(listener) ){
							listener(eventData);
						}
					});
				}

				return this;
			};

			CyElement.prototype.select = function(){
				this.selected = function(){
					return true;
				};

				notifyRenderer({
					type: "select",
					elements: new CyCollection([ this ])
				});
			};

			CyElement.prototype.unselect = function(){
				this.selected = function(){
					return false;
				};

				notifyRenderer({
					type: "unselect",
					elements: new CyCollection([ this ])
				});
			};

			CyElement.prototype.firstNeighbors = function(){
				// TODO
			};

			// aliases to listeners, e.g. node.click(fn) => node.bind("click", fn)
			// TODO add more
			CyElement.prototype.mousedown = functions.element.listenerAlias("mousedown");
			CyElement.prototype.mouseup = functions.element.listenerAlias("mouseup");
			CyElement.prototype.mousemove = functions.element.listenerAlias("mousemove");
			CyElement.prototype.click = functions.element.listenerAlias("click");
			CyElement.prototype.select = functions.element.listenerAlias("select");
			CyElement.prototype.unselect = functions.element.listenerAlias("unselect");

			// represents a set of nodes, edges, or both together
			function CyCollection(elements){
				$.each(elements, function(i, element){
					this[i] = element;
				});

				var length = elements.length;
				this.size = function(){
					return length;
				}
			}

			CyCollection.prototype.toArray = function(){
				var array = [];

				for(var i = 0; i < this.size(); i++){
					array.push( this.eq(i) );
				}

				return array;
			};

			CyCollection.prototype.eq = function(i){
				return this[i];
			};

			CyCollection.prototype.each = function(fn){
				for(var i = 0; i < this.size(); i++){
					fn( i, this.eq(i) );
				}
				return this;
			};

			CyCollection.prototype.add = function(toAdd){
				var elements = [];

				// add own
				this.each(function(i, element){
					elements.push(element);
				});

				// add toAdd
				if( $isFunction(toAdd.size) ){
					// we have a collection
					var collection = toAdd;
					collection.each(function(i, element){
						elements.push(element);
					});
				} else {
					// we have one element
					var element = toAdd;
					elements.push(element);
				}

				return new CyCollection(elements);
			};

			CyCollection.prototype.filter = function(filterFn){
				var elements = [];
				this.each(function(i, element){
					if( !$.isFunction(filterFn) || filterFn(element) ){
						elements.push(element);
					}
				});

				return new CyCollection(elements);
			};

			// functions in element can also be used on collections
			var rendererFunctions = [ "data", "select", "unselect", "position" ];
			$.each(CyElement.prototype, function(name, func){
				CyCollection.prototype[name] = function(){
					var rets = [];

					// disable renderer notifications during loop
					// just notify at the end of the loop with the whole collection
					var notifyRenderer = $.inArray(name, rendererFunctions) >= 0;
					if( notifyRenderer ){
						rendererNotificationsEnabled(false);
					}

					for(var i = 0; i < this.size(); i++){
						var element = this[i];
						var ret = func.apply(element, arguments);

						if( ret !== undefined ){
							rets.push(ret);
						}
					}

					// notify the renderer of the call on the whole collection
					// (more efficient than sending each in a row---may have flicker?)
					if( notifyRenderer ){
						rendererNotificationsEnabled(true);
						notifyRenderer({
							type: name,
							collection = this;
						});
					}

					if( rets.length == 0 ){
						rets = this; // if function doesn't return a value, return this for chaining
					}

					return rets;
				};
			});

			var renderer = reg.renderers[ options.renderer.toLowerCase() ];
			var rendererNotifications = true;

			function rendererNotificationsEnabled(enabled){
				rendererNotificationsEnabled = enabled;
			}

			function notifyRenderer(params){
				rendererNotifications && renderer.notify(params);
			}

			// this is the cytoweb object
			var cy = {

				style: functions.api.jsonGetterSetter({ struct: "style", after: function(){
					notifyRenderer({
						style: structs.style
					});
				} }),

				bypass: functions.api.jsonGetterSetter({ struct: "bypass", after: function(){
					notifyRenderer({
						bypass: structs.bypass
					});
				} }),

				addNode: functions.api.addElement({ group: "nodes" }),

				addEdge: functions.api.addElement({ group: "edges" }),

				node: function(id){
					return structs.nodes[id];
				},

				edge: function(id){
					return structs.edges[id];
				},

				nodes: functions.api.elementsCollection({ group: "nodes" }),

				edges: functions.api.elementsCollection({ group: "edges" }),

				layout: function(params){
					reg.layout[name].run($.extend({}, params, {
						nodes: cy.nodes(),
						edges: cy.edges()
					});
				},

				pan: function(options){
					renderer.pan(options);
				}

			};

			renderer.draw({
				nodes: nodes,
				edges: edges,
				style: style,
				bypass: bypass
			});

			return cy;
		}

		// allow for registration of extensions
		else if( typeof opts == typeof "" ) {
			var registrant = arguments[0].toLowerCase(); // what to register (e.g. "renderer")
			var name = arguments[1].toLowerCase(); // name of the module (e.g. "svg")
			var module = arguments[2]; // the module object

			if( module == null ){
				// get the module by name; e.g. $.cytoscapeweb("renderer", "svg");
				return reg[registrant][name];
			} else {
				// set the module; e.g. $.cytoscapeweb("renderer", "svg", { ... });
				reg[registrant][name] = module;
			}
		}
	};

	// use short alias (cy) if not already defined
	if( $.fn.cy == null && $.cy == null ){
		$.fn.cy = $.fn.cytoscapeweb;
		$.cy = $.cytoscapeweb;
	}

})(jQuery);

<|endoftext|>


<commit_before>var npm = require('npm');
var moment = require('moment');
var RSS = require('rss');

function Package(name, versions) {
	this.name = name; // The name of the package
	this.versions = versions; // Versions and their pubdate as returned by NPM
	this.expires = moment().add(Package.TTL); // When the versions information is considered stale
}

Package.TTL = moment.duration({hours: 1});

var packages = {};

function FeedItem(name, previous, current, pubdate) {
	this.name = name;
	this.previous = previous;
	this.current = current;
	this.pubdate = pubdate;
}

// Create a bunch of Feed items from the passed package
function packageToFeedItems(pkg) {

	var previous = null;

	return Object.keys(pkg.versions).map(function(version) {

		var item = new FeedItem(pkg.name, previous, version, pkg.versions[version]);

		previous = version;

		return item;
	});
}

// Create the feed XML from the FeedItems
function buildFeedXml(items, name, depNames, limit) {

	limit = limit || 32;

	items.sort(function(a, b) {
		if(a.pubdate < b.pubdate) {
			return 1;
		} else if(a.pubdate === b.pubdate) {
			return 0;
		} else {
			return -1;
		}
	});

	items = items.slice(0, limit);

	var rssFeed = new RSS({
		title: 'Recently updated dependencies for ' + name,
		description: 'Version updates for ' + depNames.join(', '),
		site_url: 'https://david-dm.org/'
	});

	for(var i = 0, len = items.length; i < len; ++i) {
		rssFeed.item({
			title: items[i].name + ' ' + items[i].previous + ' to ' + items[i].current,
			url: 'https://npmjs.org/package/' + items[i].name,
			date: items[i].pubdate
		});
	}

	return rssFeed.xml();
}

/**
 * Get a Package for a given package name guaranteed to be less old than Package.TTL
 *
 * Must be executed in `npm.load()` callback.
 *
 * @param pkgName
 * @param callback
 */
function getPackage(pkgName, callback) {

	var pkg = packages[pkgName];

	if(pkg && pkg.expires > new Date()) {
		callback(null, pkg);
		return;
	}

	npm.commands.view([pkgName, 'time'], true, function(err, data) {

		if(err) {
			callback(err);
			return;
		}

		pkg = packages[pkgName] = new Package(pkgName, data[Object.keys(data)[0]].time);

		callback(null, pkg);
	});
}

module.exports.get = function(manifest, options, callback) {

	// Allow callback to be passed as second parameter
	if(!callback) {
		callback = options;
		options = {};
	} else {
		options = options || {};
	}

	// Assume we're probably going to have to use NPM
	npm.load({}, function(err) {

		if(err) {
			callback(err);
			return;
		}

		var items = [];
		var deps = options.dev ? manifest.devDependencies : manifest.dependencies;
		var depNames = Object.keys(deps || {});
		var processedDeps = 0;

		if(!depNames.length) {
			callback(null, buildFeedXml([], manifest.name, depNames, options.limit));
			return;
		}

		depNames.forEach(function(depName) {

			getPackage(depName, function(err, pkg) {

				if(err) {
					callback(err);
					return;
				}

				items = items.concat(packageToFeedItems(pkg));

				processedDeps++;

				if(processedDeps == depNames.length) {
					callback(null, buildFeedXml(items, manifest.name, depNames, options.limit));
				}
			});
		});
	});
};<commit_msg>Adds requirement to feed item title<commit_after>var npm = require('npm');
var moment = require('moment');
var RSS = require('rss');

function Package(name, versions) {
	this.name = name; // The name of the package
	this.versions = versions; // Versions and their pubdate as returned by NPM
	this.expires = moment().add(Package.TTL); // When the versions information is considered stale
}

Package.TTL = moment.duration({hours: 1});

var packages = {};

function FeedItem(name, previous, current, pubdate) {
	this.name = name;
	this.previous = previous;
	this.current = current;
	this.pubdate = pubdate;
}

// Create a bunch of Feed items from the passed package
function packageToFeedItems(pkg) {

	var previous = null;

	return Object.keys(pkg.versions).map(function(version) {

		var item = new FeedItem(pkg.name, previous, version, pkg.versions[version]);

		previous = version;

		return item;
	});
}

// Create the feed XML from the FeedItems
function buildFeedXml(items, name, deps, limit) {

	limit = limit || 32;
	deps = deps || {};

	items.sort(function(a, b) {
		if(a.pubdate < b.pubdate) {
			return 1;
		} else if(a.pubdate === b.pubdate) {
			return 0;
		} else {
			return -1;
		}
	});

	items = items.slice(0, limit);

	var rssFeed = new RSS({
		title: 'Recently updated dependencies for ' + name,
		description: 'Version updates for ' + Object.keys(deps).join(', '),
		site_url: 'https://david-dm.org/'
	});

	for(var i = 0, len = items.length; i < len; ++i) {
		rssFeed.item({
			title: items[i].name + ' ' + items[i].previous + ' to ' + items[i].current + ' (' + deps[items[i].name] + ' required)',
			url: 'https://npmjs.org/package/' + items[i].name,
			date: items[i].pubdate
		});
	}

	return rssFeed.xml();
}

/**
 * Get a Package for a given package name guaranteed to be less old than Package.TTL
 *
 * Must be executed in `npm.load()` callback.
 *
 * @param pkgName
 * @param callback
 */
function getPackage(pkgName, callback) {

	var pkg = packages[pkgName];

	if(pkg && pkg.expires > new Date()) {
		callback(null, pkg);
		return;
	}

	npm.commands.view([pkgName, 'time'], true, function(err, data) {

		if(err) {
			callback(err);
			return;
		}

		pkg = packages[pkgName] = new Package(pkgName, data[Object.keys(data)[0]].time);

		callback(null, pkg);
	});
}

module.exports.get = function(manifest, options, callback) {

	// Allow callback to be passed as second parameter
	if(!callback) {
		callback = options;
		options = {};
	} else {
		options = options || {};
	}

	// Assume we're probably going to have to use NPM
	npm.load({}, function(err) {

		if(err) {
			callback(err);
			return;
		}

		var items = [];
		var deps = options.dev ? manifest.devDependencies : manifest.dependencies;
		var depNames = Object.keys(deps || {});
		var processedDeps = 0;

		if(!depNames.length) {
			callback(null, buildFeedXml([], manifest.name, deps, options.limit));
			return;
		}

		depNames.forEach(function(depName) {

			getPackage(depName, function(err, pkg) {

				if(err) {
					callback(err);
					return;
				}

				items = items.concat(packageToFeedItems(pkg));

				processedDeps++;

				if(processedDeps == depNames.length) {
					callback(null, buildFeedXml(items, manifest.name, deps, options.limit));
				}
			});
		});
	});
};<|endoftext|>


<commit_before>/**
 Jasmine Reporter that outputs test results to the browser console.
 Useful for running in a headless environment such as PhantomJs, ZombieJs etc.

 Usage:
 // From your html file that loads jasmine:
 jasmine.getEnv().addReporter(new jasmine.ConsoleReporter());
 jasmine.getEnv().execute();
*/
/*global jasmine */

(function(jasmine, console) {
  if (!jasmine) {
    throw "jasmine library isn't loaded!";
  }

  var ANSI = {
    color_map : {
      "green" : 32,
      "red"   : 31
    },
    colorize_text : function(text, color) {
      var color_code = this.color_map[color];
      return "\u001b[" + color_code + "m" + text + "\u001b[0m";
    }
  }, proto;

  function ConsoleReporter() {
    if (!console || !console.log) { throw "console isn't present!"; }
    this.status = this.statuses.stopped;
  }

  proto = ConsoleReporter.prototype;
  proto.statuses = {
    stopped : "stopped",
    running : "running",
    fail    : "fail",
    success : "success"
  };

  proto.reportRunnerStarting = function(runner) {
    this.status = this.statuses.running;
    this.start_time = (new Date()).getTime();
    this.executed_specs = 0;
    this.passed_specs = 0;
    this.log("Starting...");
  };

  proto.reportRunnerResults = function(runner) {
    var failed = this.executed_specs - this.passed_specs,
        spec_str = this.executed_specs + (this.executed_specs === 1 ? " spec, " : " specs, "),
        fail_str = failed + (failed === 1 ? " failure in " : " failures in "),
        color = (failed > 0)? "red" : "green",
        dur = (new Date()).getTime() - this.start_time;

    this.log("");
    this.log("Finished");
    this.log("-----------------");
    this.log(spec_str + fail_str + (dur/1000) + "s.", color);

    this.status = (failed > 0)? this.statuses.fail : this.statuses.success;

    /* Print something that signals that testing is over so that headless browsers
       like PhantomJs know when to terminate. */
    this.log("");
    this.log("ConsoleReporter finished");
  };

  proto.reportSpecStarting = function(spec) {
    this.executed_specs++;
  };

  proto.reportSpecResults = function(spec) {
    if (spec.results().passed()) {
      this.passed_specs++;
      return;
    }

    var items, i, trace,
        resultText = spec.suite.description + " : " + spec.description;
    this.log(resultText, "red");

    items = spec.results().getItems();
    for (i = 0; i < items.length; i++) {
      trace = items[i].trace.stack || items[i].trace;
      this.log(trace, "red");
    }
  };

  proto.reportSuiteResults = function(suite) {
    if (!suite.parentSuite) { return; }
    var results = suite.results(),
        failed = results.totalCount - results.passedCount,
        color = (failed > 0)? "red" : "green";
    this.log(suite.description + ": " + results.passedCount + " of " + results.totalCount + " passed.", color);
  };

  proto.log = function(str, color) {
    var text = (color != undefined)? ANSI.colorize_text(str, color) : str;
    console.log(text);
  };

  jasmine.ConsoleReporter = ConsoleReporter;
}(jasmine, console));

<commit_msg>console-runner: showing top-level suites instead<commit_after>/**
 Jasmine Reporter that outputs test results to the browser console.
 Useful for running in a headless environment such as PhantomJs, ZombieJs etc.

 Usage:
 // From your html file that loads jasmine:
 jasmine.getEnv().addReporter(new jasmine.ConsoleReporter());
 jasmine.getEnv().execute();
*/
/*global jasmine */

(function(jasmine, console) {
  if (!jasmine) {
    throw "jasmine library isn't loaded!";
  }

  var ANSI = {
    color_map : {
      "green" : 32,
      "red"   : 31
    },
    colorize_text : function(text, color) {
      var color_code = this.color_map[color];
      return "\u001b[" + color_code + "m" + text + "\u001b[0m";
    }
  }, proto;

  function ConsoleReporter() {
    if (!console || !console.log) { throw "console isn't present!"; }
    this.status = this.statuses.stopped;
  }

  proto = ConsoleReporter.prototype;
  proto.statuses = {
    stopped : "stopped",
    running : "running",
    fail    : "fail",
    success : "success"
  };

  proto.reportRunnerStarting = function(runner) {
    this.status = this.statuses.running;
    this.start_time = (new Date()).getTime();
    this.executed_specs = 0;
    this.passed_specs = 0;
    this.log("Starting...");
  };

  proto.reportRunnerResults = function(runner) {
    var failed = this.executed_specs - this.passed_specs,
        spec_str = this.executed_specs + (this.executed_specs === 1 ? " spec, " : " specs, "),
        fail_str = failed + (failed === 1 ? " failure in " : " failures in "),
        color = (failed > 0)? "red" : "green",
        dur = (new Date()).getTime() - this.start_time;

    this.log("");
    this.log("Finished");
    this.log("-----------------");
    this.log(spec_str + fail_str + (dur/1000) + "s.", color);

    this.status = (failed > 0)? this.statuses.fail : this.statuses.success;

    /* Print something that signals that testing is over so that headless browsers
       like PhantomJs know when to terminate. */
    this.log("");
    this.log("ConsoleReporter finished");
  };

  proto.reportSpecStarting = function(spec) {
    this.executed_specs++;
  };

  proto.reportSpecResults = function(spec) {
    if (spec.results().passed()) {
      this.passed_specs++;
      return;
    }

    var items, i, trace,
        resultText = spec.suite.description + " : " + spec.description;
    this.log(resultText, "red");

    items = spec.results().getItems();
    for (i = 0; i < items.length; i++) {
      trace = items[i].trace.stack || items[i].trace;
      this.log(trace, "red");
    }
  };

  proto.reportSuiteResults = function(suite) {
    if (suite.parentSuite) { return; }
    var results = suite.results(),
        failed = results.totalCount - results.passedCount,
        color = (failed > 0)? "red" : "green";
    this.log(suite.description + ": " + results.passedCount + " of " + results.totalCount + " passed.", color);
  };

  proto.log = function(str, color) {
    var text = (color != undefined)? ANSI.colorize_text(str, color) : str;
    console.log(text);
  };

  jasmine.ConsoleReporter = ConsoleReporter;
}(jasmine, console));

<|endoftext|>


<commit_before>if (typeof document.registerElement === 'function') {
  return;
}

var oldCreateElement = document.createElement.bind(document);
document.createElement = function (name, parent) {
  var element = oldCreateElement(name);
  parent && element.setAttribute('is', parent);
  return element;
}
<commit_msg>Fix failing tests due to bad compile.<commit_after>() => {
  if (typeof document.registerElement === 'function') {
    return;
  }

  var oldCreateElement = document.createElement.bind(document);
  document.createElement = function (name, parent) {
    var element = oldCreateElement(name);
    if (parent) {
      element.setAttribute('is', parent);
    }
    return element;
  };
}();
<|endoftext|>


<commit_before>/*jslint browser: true */
(function ($, window, document) {
	'use strict';

	var IcbiaControl, controlMap;

	IcbiaControl = function () {};

	IcbiaControl.prototype = {
		optionAttributePrefix: 'data-icbiacontrol-',
		initialize: function ($el, options) {
			this.$el = $el;
			this.options = $.extend(this.defaultOptions, this.getHtmlOptions(), options);
			this.$el
				.change($.proxy(this.changeHandler, this))
				.focus($.proxy(this.focusHandler, this))
				.blur($.proxy(this.blurHandler, this));
			this.wrap();
			this.updateHitArea();
			this.updateWidget();
		},

		blurHandler: function (event) {
			this.wrapper.removeClass('focus');
		},

		focusHandler: function (event) {
			this.wrapper.addClass('focus');
		},

		changeHandler: function (event) {
			this.updateWidget();
		},

		updateWidget: $.noop,

		updateHitArea: function () {
			this.$el
				.css({
					width: this.widget.width(),
					height: this.widget.height()
				});
		},

		getHtmlOptions: function () {
			var self = this,
			    opts = {};
			$.each(this.$el[0].attributes, function (i, attr) {
				if (attr.name.indexOf(self.optionAttributePrefix) !== -1) {
					opts[attr.name.substr(self.optionAttributePrefix.length)] = attr.value;
				}
			});
			return opts;
		},

		defaultOptions: {
		},

		createWidget: function () {
			var wt = this.options.widgetTemplate,
			    widget = typeof wt === 'function' ? wt() : $($(wt).html());

			return widget
				.removeAttr(this.optionAttributePrefix + 'widgetTemplate')
				.addClass('icbiacontrol-widget')
				.addClass('icbia' + this.controlName + '-widget');
		},

		wrap: function () {
			if (!this.wrapper) {
				var parent = this.$el.parent();
				this.widget = this.createWidget();
				this.wrapper = $('')
					.addClass('icbia' + this.controlName)
					.css({
						position: 'relative',
						display: 'inline-block'
					})
					.append(this.widget)
					.append(
						this.$el.css({
							position: 'absolute',
							border: '1px solid #fff',  // To force the dimensions to take effect.
							top: 0,
							left: 0,
							opacity: 0
						})
					)
					.appendTo(parent);
			}
		}
	};

	IcbiaControl.extend = function (attrs) {
		var SuperClass = this,
		    ctor = function () {};
		ctor.prototype = new SuperClass();
		ctor.prototype.constructor = ctor;
		$.extend(ctor.prototype, attrs);
		return ctor;
	};

	controlMap = {
		'select': IcbiaControl.extend({
			controlName: 'select',
			defaultOptions: $.extend(IcbiaControl.prototype.defaultOptions, {
				widgetTemplate: function () {
					return $(' ' +
							'                                                        ' +
							'                    ' +
							'                     ' +
							'                                                       ' +
							'                ' +
							'                                                       '
						);
				}
			}),
			updateWidget: function () {
				var label = this.$el.find('option:selected').html();
				this.widget.find('.icbiaselect-display').html(label || ' ');
				this.updateHitArea();
			}
		})
	};

	function createIcbiaControl($el, options) {
		var plugin;
		$.each(controlMap, function (selector, Cls) {
			if ($el.is(selector)) {
				plugin = new Cls();
				plugin.initialize($el, options);
				return false;
			}
		});

		if (!plugin) {
			$.error('There\'s no control for the ' + $el.prop('tagName') + ' element ' + $el);
		}

		return plugin;
	}

	$.extend($.fn, {
		icbiaControl: function (optionsOrMethod) {
			var returnValue = this,
			    args = arguments;
			this.each(function (i, el) {
				var $el = $(el),
				    plugin = $el.data('icbiaControl'),
				    method = typeof optionsOrMethod === 'string' ? optionsOrMethod : null,
				    options = method === null ? optionsOrMethod || {} : {};

				if (!plugin) {
					if (method) {
						$.error('You can\'t call the icbiaControl method "' + method
								+ '" without first initializing the plugin by calling '
								+ 'icbiaControl() on the jQuery object.');
					} else {
						plugin = createIcbiaControl($el, options);
						$el.data('icbiaControl', plugin);
					}
				} else if (method) {
					if (typeof plugin[method] !== 'function') {
						$.error('Method "' + method + '" does not exist on jQuery.icbiaControl');
					} else {
						// NOTE: If you call a method that returns a value, you will only get the result from the last item in the collection.
						returnValue = plugin[method].apply(plugin, Array.prototype.slice.call(args, 1));
					}
				}
			});
			return returnValue;
		}
	});
}(this.jQuery, window, document));
<commit_msg>Replace element in place<commit_after>/*jslint browser: true */
(function ($, window, document) {
	'use strict';

	var IcbiaControl, controlMap;

	IcbiaControl = function () {};

	IcbiaControl.prototype = {
		optionAttributePrefix: 'data-icbiacontrol-',
		initialize: function ($el, options) {
			this.$el = $el;
			this.options = $.extend(this.defaultOptions, this.getHtmlOptions(), options);
			this.$el
				.change($.proxy(this.changeHandler, this))
				.focus($.proxy(this.focusHandler, this))
				.blur($.proxy(this.blurHandler, this));
			this.wrap();
			this.updateHitArea();
			this.updateWidget();
		},

		blurHandler: function (event) {
			this.wrapper.removeClass('focus');
		},

		focusHandler: function (event) {
			this.wrapper.addClass('focus');
		},

		changeHandler: function (event) {
			this.updateWidget();
		},

		updateWidget: $.noop,

		updateHitArea: function () {
			this.$el
				.css({
					width: this.widget.width(),
					height: this.widget.height()
				});
		},

		getHtmlOptions: function () {
			var self = this,
			    opts = {};
			$.each(this.$el[0].attributes, function (i, attr) {
				if (attr.name.indexOf(self.optionAttributePrefix) !== -1) {
					opts[attr.name.substr(self.optionAttributePrefix.length)] = attr.value;
				}
			});
			return opts;
		},

		defaultOptions: {
		},

		createWidget: function () {
			var wt = this.options.widgetTemplate,
			    widget = typeof wt === 'function' ? wt() : $($(wt).html());

			return widget
				.removeAttr(this.optionAttributePrefix + 'widgetTemplate')
				.addClass('icbiacontrol-widget')
				.addClass('icbia' + this.controlName + '-widget');
		},

		wrap: function () {
			if (!this.wrapper) {
				this.widget = this.createWidget();
				this.wrapper = $('')
					.addClass('icbia' + this.controlName)
					.css({
						position: 'relative',
						display: 'inline-block'
					})
					.append(this.widget)
					.insertBefore(this.$el)
					.append(
						this.$el.css({
							position: 'absolute',
							border: '1px solid #fff',  // To force the dimensions to take effect.
							top: 0,
							left: 0,
							opacity: 0
						})
					);
			}
		}
	};

	IcbiaControl.extend = function (attrs) {
		var SuperClass = this,
		    ctor = function () {};
		ctor.prototype = new SuperClass();
		ctor.prototype.constructor = ctor;
		$.extend(ctor.prototype, attrs);
		return ctor;
	};

	controlMap = {
		'select': IcbiaControl.extend({
			controlName: 'select',
			defaultOptions: $.extend(IcbiaControl.prototype.defaultOptions, {
				widgetTemplate: function () {
					return $(' ' +
							'                                                        ' +
							'                    ' +
							'                     ' +
							'                                                       ' +
							'                ' +
							'                                                       '
						);
				}
			}),
			updateWidget: function () {
				var label = this.$el.find('option:selected').html();
				this.widget.find('.icbiaselect-display').html(label || ' ');
				this.updateHitArea();
			}
		})
	};

	function createIcbiaControl($el, options) {
		var plugin;
		$.each(controlMap, function (selector, Cls) {
			if ($el.is(selector)) {
				plugin = new Cls();
				plugin.initialize($el, options);
				return false;
			}
		});

		if (!plugin) {
			$.error('There\'s no control for the ' + $el.prop('tagName') + ' element ' + $el);
		}

		return plugin;
	}

	$.extend($.fn, {
		icbiaControl: function (optionsOrMethod) {
			var returnValue = this,
			    args = arguments;
			this.each(function (i, el) {
				var $el = $(el),
				    plugin = $el.data('icbiaControl'),
				    method = typeof optionsOrMethod === 'string' ? optionsOrMethod : null,
				    options = method === null ? optionsOrMethod || {} : {};

				if (!plugin) {
					if (method) {
						$.error('You can\'t call the icbiaControl method "' + method
								+ '" without first initializing the plugin by calling '
								+ 'icbiaControl() on the jQuery object.');
					} else {
						plugin = createIcbiaControl($el, options);
						$el.data('icbiaControl', plugin);
					}
				} else if (method) {
					if (typeof plugin[method] !== 'function') {
						$.error('Method "' + method + '" does not exist on jQuery.icbiaControl');
					} else {
						// NOTE: If you call a method that returns a value, you will only get the result from the last item in the collection.
						returnValue = plugin[method].apply(plugin, Array.prototype.slice.call(args, 1));
					}
				}
			});
			return returnValue;
		}
	});
}(this.jQuery, window, document));
<|endoftext|>


<commit_before>import { expect } from 'chai';
import Fibonacci from '../../src/math/Fibonacci';

describe('Fibonacci', () => {

  describe('Fibonacci.calculate()', () => {

    it('should return 8 given fib(6)', () => {
      const fib = new Fibonacci();
      const result = fib.calculate(6);
      expect(result).to.be.equal(8);
    });

  });

});
<commit_msg>adding another test<commit_after>import { expect } from 'chai';
import Fibonacci from '../../src/math/Fibonacci';

describe('Fibonacci', () => {

  describe('Fibonacci.calculate()', () => {

    it('should return 8 given fib(6)', () => {
      const fib = new Fibonacci();
      const result = fib.calculate(6);
      expect(result).to.be.equal(8);
    });

  });

  describe('Fibonacci.calculate2()', () => {

    it('should return 13 given fib(7)', () => {
      const fib = new Fibonacci();
      const result = fib.calculate(7);
      expect(result).to.be.equal(13);
    });

  });

});
<|endoftext|>