<commit_before>(function(window, $, app, CssEvents) {
    function UI() {
        var $draggables;
        var $selected = $([]);
        var offset = {top: 0, left: 0};

        this.showBtn = function(group, button) {
            var $group = $('#' + group);

            $group.find('.btn').removeClass('--show').addClass('--hide');

            if ($group.hasClass('--loading')) {
                $group.find('[data-name="' + button + '"]').removeClass('--hide');
            } else {
                $group.find('[data-name="' + button + '"]').removeClass('--hide').addClass('--show').on(CssEvents.transitionEvent(), function() {
                    $(this).off(CssEvents.transitionEvent()).removeClass('--show');
                });
            }
        };

        this.btnGroupLoading = function(group) {
            $('#' + group).addClass('--loading');
        };

        this.btnGroupLoaded = function(group) {
            $('#' + group).removeClass('--loading');
        };

        var select = function(el) {
            $selected = $selected.add(el);
            $(el).addClass('ui-selected');
        };

        this.makeSelectable = function() {
            var $content = app.Page.getContent();
            var $selectables = $content.find('.draggable, .editable, .resizable');

            $content.selectable({
                filter: '.draggable, .editable, .resizable',
                selected: function(e, ui) {
                    select(ui.selected);
                },
                unselected: function(e, ui) {
                    $selected = $selected.not(ui.unselected);
                }
            });

            $selectables.data('click', function(e) {
                var $this = $(this);

                if (e.metaKey) {
                    if ($this.hasClass('ui-selected')) {
                        $this.removeClass('ui-selected');
                    } else {
                        $this.addClass('ui-selecting');
                    }
                } else {
                    $content.find('.ui-selected').removeClass('ui-selected');
                    $selected = $([]);
                    $this.addClass('ui-selecting');
                }

                $content.selectable('instance')._mouseStop(null);
            });

            $selectables.click($selectables.data('click'));
        };

        this.removeSelectable = function() {
            var $content = app.Page.getContent();
            var $selectables = $content.find('.draggable, .editable, .resizable');

            $content.selectable('destroy');
            $selectables.unbind('click', $selectables.data('click'));
        };

        this.makeDraggable = function() {
            $draggables = app.Page.getContent().find('.draggable');

            $draggables.draggable({
                cursor: "move",
                start: function(e, ui) {
                    var $this = $(this);

                    if ($this.hasClass('ui-selected')) {
                        $selected = $selected.filter('.draggable').each(function() {
                            var $this = $(this);

                            $this.data('offset', $this.position());
                        });

                        window.$selected = $selected;
                    } else {
                        $selected = $([]);
                        $this.data('offset', $this.position());
                        app.Page.getContent().find('.ui-selected').removeClass('ui-selected');
                    }

                    select($this);
                },
                drag: function(e, ui) {
                    var $this = $(this);
                    var drag = {
                        top: ui.position.top - $this.data('offset').top,
                        left: ui.position.left - $this.data('offset').left,
                    };

                    $selected.not($this).filter('.draggable').each(function() {
                        var $this = $(this);

                        $this.addClass('ui-draggable-dragging').css({top: $this.data('offset').top + drag.top, left: $this.data('offset').left + drag.left});
                    });
                },
                stop: function(e, ui) {
                    $selected.each(function() {
                        var $this = $(this);
                        var top = parseInt($this.css('top'));
                        var left = parseInt($this.css('left'));

                        if ($this.is('[class*=push-down]')) {
                            var push_down = Math.round(top / 16);

                            $this.removeClass(function(index, css) {
                                return (css.match(/\bpush-down\S+/g) || []).join(' ');
                            });

                            $this.addClass('push-down-' + push_down);
                        } else {
                            var bottom = 624 - top - $this.outerHeight();
                            var pull_up = Math.round(bottom / 16);

                            $this.removeClass(function(index, css) {
                                return (css.match(/\bpull-up\S+/g) || []).join(' ');
                            });

                            $this.addClass('pull-up-' + pull_up);
                        }

                        if($this.is('[class*=push-right]')){
                            var push_right = Math.round(left / 19);

                            $this.removeClass(function(index, css) {
                                return (css.match(/\bpush-right\S+/g) || []).join(' ');
                            });

                            $this.addClass('push-right-' + push_right);
                        } else {
                            var right = 950 - left - $this.outerWidth();
                            var pull_left = Math.round(right / 19);

                            $this.removeClass(function(index, css) {
                                return (css.match (/\bpull-left-\S+/g) || []).join(' ');
                            });

                            $this.addClass('pull-left-' + pull_left);
                        }
                    }).removeClass('ui-draggable-dragging');
                },
                grid: [19, 16]
            });
        };

        this.removeDraggable = function() {
            $draggables.draggable('destroy');
        };
    }

    app.modules.UI = UI;
})(window, jQuery, MagTool, CssEvents);
<commit_msg>Allow shiftKey as well<commit_after>(function(window, $, app, CssEvents) {
    function UI() {
        var $draggables;
        var $selected = $([]);
        var offset = {top: 0, left: 0};

        this.showBtn = function(group, button) {
            var $group = $('#' + group);

            $group.find('.btn').removeClass('--show').addClass('--hide');

            if ($group.hasClass('--loading')) {
                $group.find('[data-name="' + button + '"]').removeClass('--hide');
            } else {
                $group.find('[data-name="' + button + '"]').removeClass('--hide').addClass('--show').on(CssEvents.transitionEvent(), function() {
                    $(this).off(CssEvents.transitionEvent()).removeClass('--show');
                });
            }
        };

        this.btnGroupLoading = function(group) {
            $('#' + group).addClass('--loading');
        };

        this.btnGroupLoaded = function(group) {
            $('#' + group).removeClass('--loading');
        };

        var select = function(el) {
            $selected = $selected.add(el);
            $(el).addClass('ui-selected');
        };

        this.makeSelectable = function() {
            var $content = app.Page.getContent();
            var $selectables = $content.find('.draggable, .editable, .resizable');

            $content.selectable({
                filter: '.draggable, .editable, .resizable',
                selected: function(e, ui) {
                    select(ui.selected);
                },
                unselected: function(e, ui) {
                    $selected = $selected.not(ui.unselected);
                }
            });

            $selectables.data('click', function(e) {
                var $this = $(this);

                if (e.metaKey|| e.shiftKey) {
                    if ($this.hasClass('ui-selected')) {
                        $this.removeClass('ui-selected');
                    } else {
                        $this.addClass('ui-selecting');
                    }
                } else {
                    $content.find('.ui-selected').removeClass('ui-selected');
                    $selected = $([]);
                    $this.addClass('ui-selecting');
                }

                $content.selectable('instance')._mouseStop(null);
            });

            $selectables.click($selectables.data('click'));
        };

        this.removeSelectable = function() {
            var $content = app.Page.getContent();
            var $selectables = $content.find('.draggable, .editable, .resizable');

            $content.selectable('destroy');
            $selectables.unbind('click', $selectables.data('click'));
        };

        this.makeDraggable = function() {
            $draggables = app.Page.getContent().find('.draggable');

            $draggables.draggable({
                cursor: "move",
                start: function(e, ui) {
                    var $this = $(this);

                    if ($this.hasClass('ui-selected')) {
                        $selected = $selected.filter('.draggable').each(function() {
                            var $this = $(this);

                            $this.data('offset', $this.position());
                        });

                        window.$selected = $selected;
                    } else {
                        $selected = $([]);
                        $this.data('offset', $this.position());
                        app.Page.getContent().find('.ui-selected').removeClass('ui-selected');
                    }

                    select($this);
                },
                drag: function(e, ui) {
                    var $this = $(this);
                    var drag = {
                        top: ui.position.top - $this.data('offset').top,
                        left: ui.position.left - $this.data('offset').left,
                    };

                    $selected.not($this).filter('.draggable').each(function() {
                        var $this = $(this);

                        $this.addClass('ui-draggable-dragging').css({top: $this.data('offset').top + drag.top, left: $this.data('offset').left + drag.left});
                    });
                },
                stop: function(e, ui) {
                    $selected.each(function() {
                        var $this = $(this);
                        var top = parseInt($this.css('top'));
                        var left = parseInt($this.css('left'));

                        if ($this.is('[class*=push-down]')) {
                            var push_down = Math.round(top / 16);

                            $this.removeClass(function(index, css) {
                                return (css.match(/\bpush-down\S+/g) || []).join(' ');
                            });

                            $this.addClass('push-down-' + push_down);
                        } else {
                            var bottom = 624 - top - $this.outerHeight();
                            var pull_up = Math.round(bottom / 16);

                            $this.removeClass(function(index, css) {
                                return (css.match(/\bpull-up\S+/g) || []).join(' ');
                            });

                            $this.addClass('pull-up-' + pull_up);
                        }

                        if($this.is('[class*=push-right]')){
                            var push_right = Math.round(left / 19);

                            $this.removeClass(function(index, css) {
                                return (css.match(/\bpush-right\S+/g) || []).join(' ');
                            });

                            $this.addClass('push-right-' + push_right);
                        } else {
                            var right = 950 - left - $this.outerWidth();
                            var pull_left = Math.round(right / 19);

                            $this.removeClass(function(index, css) {
                                return (css.match (/\bpull-left-\S+/g) || []).join(' ');
                            });

                            $this.addClass('pull-left-' + pull_left);
                        }
                    }).removeClass('ui-draggable-dragging');
                },
                grid: [19, 16]
            });
        };

        this.removeDraggable = function() {
            $draggables.draggable('destroy');
        };
    }

    app.modules.UI = UI;
})(window, jQuery, MagTool, CssEvents);
<|endoftext|>


<commit_before>var validator = require('validator');
var errors = require('./errors');
var urlParse = require('url');

function notAllowed(msg, req, res, next) {
    var result = {status: 'failure', message: msg};
    res.send(result);
}

function ping(msg, req, res, next) {
    var result = {status: 'ping', message: msg};
    res.send(result);
}

function preflight(msg, req, res, next) {
    res.send(204);
}

/**
 * Utility method for ensuring the payload is JSON
 *
 * @param req
 * @returns {*}
 */
function getBodyAsJSON(req) {

    if (!req) {
        return;
    }

    var rawData = req.body;

    if (!rawData) {
        return;
    }

    var type = typeof rawData;

    var data = rawData;
    if ("string" === typeof rawData) {
        data = JSON.parse(rawData);
    }
    return data;
}

/**
 * Function to extract the strategy from a permissions or access_token request
 * @param req
 */
function getStrategy(req) {
    var rawStrategy;

    if (req.query && req.query.strategy) {
        rawStrategy = req.query.strategy;
    }

    if (!rawStrategy) {
        var jsonBody = getBodyAsJSON(req);
        if (jsonBody && jsonBody.strategy) {
            rawStrategy = jsonBody.strategy;
        }
    }
    if (rawStrategy) {
        var sanitizedStrategy = validator.toString(rawStrategy);
        return sanitizedStrategy;
    }
}

/**
 * Utility method for extracting the access_token from either
 * a query parameter, body parameter, or header.
 *
 * @param req
 * @returns access_token if available via one of these strategies
 */
function getAccessToken(req) {

    var rawToken;

    if (req.query && req.query.access_token) {
        rawToken = req.query.access_token;
    }

    if (!rawToken && req.params && req.params.access_token) {
        rawToken = req.params.access_token;
    }

    if (!rawToken) {
        var jsonBody = getBodyAsJSON(req);
        if (jsonBody && jsonBody.access_token) {
            rawToken = jsonBody.access_token;
        }
    }

    if (!rawToken && req.headers && req.headers.authorization) {

        var authPieces = req.headers.authorization.split(' ');

        if (authPieces.length === 2) {
            var type = authPieces[0];
            var token = authPieces[1];

            if (type === 'Bearer' && token) {
                rawToken = token;
            }
        }
    }

    if (rawToken) {
        var sanitizedToken = validator.toString(rawToken);
        if (validator.isUUID(sanitizedToken, 4)) {
            return sanitizedToken;
        }
    }

}

/**
 * Utility method for extracting the permissions from either
 * a query parameter or the body.
 *
 * @param req
 * @returns permissions if available via one of these strategies
 */
function getPermissions(req) {

    var rawPermissions;

    if (req.query && req.query.permissions) {
        rawPermissions = req.query.permissions;
    }

    if (!rawPermissions && req.params && req.params.permissions) {
        rawPermissions = req.params.permissions;
    }

    if (!rawPermissions) {
        var jsonBody = getBodyAsJSON(req);
        if (jsonBody && jsonBody.permissions) {
            rawPermissions = jsonBody.permissions;
        }
    }

    if (!rawPermissions) {
        return null;
    }

    return sanitizePermissions(rawPermissions);
}

var permissionRegEx = /^[A-Za-z0-9\.]*$/;

/**
 * Utility method for extracting the logical permission op from either
 * a query parameter or the body. Values can be AND, OR,
 *
 * @param req
 * @returns permissions if available via one of these strategies
 */
function getPermissionOp(req) {

    var rawPermissionOp;
    if (req.query && req.query.op) {
        rawPermissionOp = req.query.op;
    }
    if (!rawPermissionOp && req.params && req.params.op) {
        rawPermissionOp = req.params.op;
    }
    if (!rawPermissionOp) {
        var jsonBody = getBodyAsJSON(req);
        if (jsonBody && jsonBody.op) {
            rawPermissionOp = jsonBody.op;
        }
    }
    if (!rawPermissionOp) {
        return 'and';
    }
    return sanitizePermissions(rawPermissionOp);
}

var permissionRegEx = /^[A-Za-z0-9\.]*$/;
var permissionOpRegEx = /^[and|or]$/;
var MAX_OP_LENGTH = 3;

/**
 * Go through a string of permissions and validate each string and
 * convert the string to an array
 * @param rawPermissions The raw permission string
 */
function sanitizePermissions(rawPermissions){
    var permissionsArray = rawPermissions;
    if(!Array.isArray(rawPermissions)){
        var sanitizedPermissions = validator.toString(rawPermissions);
        permissionsArray = sanitizedPermissions.split(' ');
    }
    for (var i = 0; i < permissionsArray.length; i++) {
        var perm = permissionsArray[i];
        if (!permissionRegEx.test(perm)) {
            return null;
        }
    }
    return permissionsArray;
}

/**
 * Sanitize the permission op string, returning the
 * logical operation for permission combinations
 */
function sanitizePermissionOp(op){

    if (!op || op.length > MAX_OP_LENGTH || typeof(op) != 'String') {
        return 'and';
    }
    if (!permissionOpRegEx.test(op.toLowerCase())) {
        return 'and';
    }
    return op;
}

/**
 * Fetch the origins field from either a query parameter
 * or the body. This is NOT the origin header field.
 * @param req
 * @returns origin field if available from one of these strategies
 */
function getOrigin(req, callback) {

    var logger = require('./loggers').getLogger();
    var rawOrigin;
    // Choose x-forwarded-host over the origin header if available.
    if (req.headers['x-forwarded-host']) {
        rawOrigin = req.headers['x-forwarded-host'];
        if (rawOrigin) {
            logger.info('X1/3) Origin vaue from forwarded host: ' + rawOrigin);
        }
    }
    if (!rawOrigin && req.headers['origin']) {
        rawOrigin = req.headers['origin'];
        if (rawOrigin) {
             logger.info('X2/3) Origin Value from origin header: ' + rawOrigin);
        }
    }
    if (!rawOrigin && req.headers['referer']) {
        rawOrigin = req.headers['referer'];
        if (rawOrigin) {
             logger.info('X3/3) Origin Value from referer header: ' + rawOrigin);
        }
    }
    var sanitizedOrigin;
    if (rawOrigin) {
        if (typeof(rawOrigin) !=='string') {
            logger.info('Type of origin value is not string: ' + typeof(rawOrigin));
            return callback(new errors.BadRequestError('invalidOriginFormat'), null);
        }
        sanitizedOrigin = validator.toString(rawOrigin);
        var spos = sanitizedOrigin.indexOf('://');
        if (spos != -1) {
            sanitizedOrigin = sanitizedOrigin.substring(spos+3);
        }
        var testRegEx = /^[A-Za-z0-9\.\-\$_]*$/;
        if (!testRegEx.test(sanitizedOrigin)) {
            logger.info('Origin regex is failing on: ' + sanitizedOrigin);
            return callback(new errors.BadRequestError('invalidOriginFormat'), null);
        }
    }
    callback(null, sanitizedOrigin);
}

function getLocale(req) {
    return 'en';
};

/**
 * Handle splitting up an origin URL into protocol and domain. This is a bit of a pain since the
 * format of what we're accepting doesn't necessarily have all the pieces
 * @param url
 */
function splitURL(url) {
    var package = {};
    var tempUrl;
    if ( url && ( (url.indexOf ('http:') == -1) && (url.indexOf('https') == -1) )) {
        tempUrl = 'http://' + url;
    } else {
        tempUrl = url;
    }
    var uri = urlParse.parse(tempUrl);
    package.protocol = uri.protocol;

    if (url.indexOf('*') != -1) {
        // Worry about formatting later
        package.hostname = url;
    } else {
        package.hostname = uri.hostname;
    }
    return package;
}

/**
 * Get the host value from the request. This prefers the forwarded host header (if provided)
 * over the local host
 * @param req
 */
var getHost = function(req) {

    var host = req.headers.host;
    if (req.headers['x-forwarded-host']) {
        host = req.headers['x-forwarded-host'];
    }
    return host;
};

module.exports.getBodyAsJSON = getBodyAsJSON;
module.exports.getStrategy = getStrategy;
module.exports.getAccessToken = getAccessToken;
module.exports.getPermissions = getPermissions;
module.exports.getPermissionOp = getPermissionOp;
module.exports.santizePermissions = sanitizePermissions;
module.exports.getOrigin = getOrigin;
module.exports.notAllowed = notAllowed;
module.exports.preflight = preflight;
module.exports.ping = ping;
module.exports.getLocale = getLocale;
module.exports.getHost = getHost;
module.exports.splitURL = splitURL;<commit_msg>NTFY-88 Try to parse the origin using the splitUrl function<commit_after>var validator = require('validator');
var errors = require('./errors');
var urlParse = require('url');

function notAllowed(msg, req, res, next) {
    var result = {status: 'failure', message: msg};
    res.send(result);
}

function ping(msg, req, res, next) {
    var result = {status: 'ping', message: msg};
    res.send(result);
}

function preflight(msg, req, res, next) {
    res.send(204);
}

/**
 * Utility method for ensuring the payload is JSON
 *
 * @param req
 * @returns {*}
 */
function getBodyAsJSON(req) {

    if (!req) {
        return;
    }

    var rawData = req.body;

    if (!rawData) {
        return;
    }

    var type = typeof rawData;

    var data = rawData;
    if ("string" === typeof rawData) {
        data = JSON.parse(rawData);
    }
    return data;
}

/**
 * Function to extract the strategy from a permissions or access_token request
 * @param req
 */
function getStrategy(req) {
    var rawStrategy;

    if (req.query && req.query.strategy) {
        rawStrategy = req.query.strategy;
    }

    if (!rawStrategy) {
        var jsonBody = getBodyAsJSON(req);
        if (jsonBody && jsonBody.strategy) {
            rawStrategy = jsonBody.strategy;
        }
    }
    if (rawStrategy) {
        var sanitizedStrategy = validator.toString(rawStrategy);
        return sanitizedStrategy;
    }
}

/**
 * Utility method for extracting the access_token from either
 * a query parameter, body parameter, or header.
 *
 * @param req
 * @returns access_token if available via one of these strategies
 */
function getAccessToken(req) {

    var rawToken;

    if (req.query && req.query.access_token) {
        rawToken = req.query.access_token;
    }

    if (!rawToken && req.params && req.params.access_token) {
        rawToken = req.params.access_token;
    }

    if (!rawToken) {
        var jsonBody = getBodyAsJSON(req);
        if (jsonBody && jsonBody.access_token) {
            rawToken = jsonBody.access_token;
        }
    }

    if (!rawToken && req.headers && req.headers.authorization) {

        var authPieces = req.headers.authorization.split(' ');

        if (authPieces.length === 2) {
            var type = authPieces[0];
            var token = authPieces[1];

            if (type === 'Bearer' && token) {
                rawToken = token;
            }
        }
    }

    if (rawToken) {
        var sanitizedToken = validator.toString(rawToken);
        if (validator.isUUID(sanitizedToken, 4)) {
            return sanitizedToken;
        }
    }

}

/**
 * Utility method for extracting the permissions from either
 * a query parameter or the body.
 *
 * @param req
 * @returns permissions if available via one of these strategies
 */
function getPermissions(req) {

    var rawPermissions;

    if (req.query && req.query.permissions) {
        rawPermissions = req.query.permissions;
    }

    if (!rawPermissions && req.params && req.params.permissions) {
        rawPermissions = req.params.permissions;
    }

    if (!rawPermissions) {
        var jsonBody = getBodyAsJSON(req);
        if (jsonBody && jsonBody.permissions) {
            rawPermissions = jsonBody.permissions;
        }
    }

    if (!rawPermissions) {
        return null;
    }

    return sanitizePermissions(rawPermissions);
}

var permissionRegEx = /^[A-Za-z0-9\.]*$/;

/**
 * Utility method for extracting the logical permission op from either
 * a query parameter or the body. Values can be AND, OR,
 */
function getPermissionOp(req) {

    var rawPermissionOp;
    if (req.query && req.query.op) {
        rawPermissionOp = req.query.op;
    }
    if (!rawPermissionOp && req.params && req.params.op) {
        rawPermissionOp = req.params.op;
    }
    if (!rawPermissionOp) {
        var jsonBody = getBodyAsJSON(req);
        if (jsonBody && jsonBody.op) {
            rawPermissionOp = jsonBody.op;
        }
    }
    if (!rawPermissionOp) {
        return 'and';
    }
    return sanitizePermissions(rawPermissionOp);
}

var permissionRegEx = /^[A-Za-z0-9\.]*$/;
var permissionOpRegEx = /^[and|or]$/;
var MAX_OP_LENGTH = 3;

/**
 * Go through a string of permissions and validate each string and
 * convert the string to an array
 * @param rawPermissions The raw permission string
 */
function sanitizePermissions(rawPermissions){
    var permissionsArray = rawPermissions;
    if(!Array.isArray(rawPermissions)){
        var sanitizedPermissions = validator.toString(rawPermissions);
        permissionsArray = sanitizedPermissions.split(' ');
    }
    for (var i = 0; i < permissionsArray.length; i++) {
        var perm = permissionsArray[i];
        if (!permissionRegEx.test(perm)) {
            return null;
        }
    }
    return permissionsArray;
}

/**
 * Sanitize the permission op string, returning the
 * logical operation for permission combinations
 */
function sanitizePermissionOp(op){

    if (!op || op.length > MAX_OP_LENGTH || typeof(op) != 'String') {
        return 'and';
    }
    if (!permissionOpRegEx.test(op.toLowerCase())) {
        return 'and';
    }
    return op;
}

/**
 * Fetch the origins field from either a query parameter
 * or the body. This is NOT the origin header field.
 * Takes a callback of type function(err, value)
 */
function getOrigin(req) {

    var logger = require('./loggers').getLogger();
    var rawOrigin;
    logger.info('XX/X getOrigin header dump' );
    logger.info(req.headers);
    // Choose x-forwarded-host over the origin header if available.
    if (req.headers['x-forwarded-host']) {
        rawOrigin = req.headers['x-forwarded-host'];
        if (rawOrigin) {
            logger.info('X1/3) Origin value from forwarded host: ' + rawOrigin);
        }
    }
    if (!rawOrigin && req.headers['origin']) {
        rawOrigin = req.headers['origin'];
        if (rawOrigin) {
             logger.info('X2/3) Origin Value from origin header: ' + rawOrigin);
        }
    }
    if (!rawOrigin && req.headers['referer']) {
        rawOrigin = req.headers['referer'];
        if (rawOrigin) {
             logger.info('X3/3) Origin Value from referer header: ' + rawOrigin);
        }
    }
    var sanitizedOrigin;
    if (rawOrigin) {
        if (typeof(rawOrigin) !=='string') {
            logger.error('Type of origin value is not string: ' + typeof(rawOrigin));
            throw new errors.BadRequestError('invalidOriginFormat');
        }
        sanitizedOrigin = validator.toString(rawOrigin);
        var package = splitURL(sanitizedOrigin);

        // Strip off a leading protocol if present
        //var spos = sanitizedOrigin.indexOf('://');
        //if (spos != -1) {
        //    sanitizedOrigin = sanitizedOrigin.substring(spos+3);
        //}
       // Strip off the port number if present
        //spos = sanitizedOrigin.indexOf(':');
        //if (spos != -1) {
        //    sanitizedOrigin = sanitizedOrigin.substring(0, spos);
        //}
        sanitizedOrigin = package.hostname;
        var testRegEx = /^[A-Za-z0-9\.\-\$_]*$/;
        if (!testRegEx.test(sanitizedOrigin)) {
            logger.error('Origin regex is failing on: ' + sanitizedOrigin);
            throw new errors.BadRequestError('invalidOriginFormat');
        }
    }
    return sanitizedOrigin;
}

function getLocale(req) {
    return 'en';
}

/**
 * Handle splitting up an origin URL into protocol and domain. This is a bit of a pain since the
 * format of what we're accepting doesn't necessarily have all the pieces
 * @param url
 */
function splitURL(url) {
    var package = {};
    var tempUrl;
    if ( url && ( (url.indexOf ('http:') == -1) && (url.indexOf('https') == -1) )) {
        tempUrl = 'http://' + url;
    } else {
        tempUrl = url;
    }
    var uri = urlParse.parse(tempUrl);
    package.protocol = uri.protocol;

    if (url.indexOf('*') != -1) {
        // Worry about formatting later
        package.hostname = url;
    } else {
        package.hostname = uri.hostname;
    }
    return package;
}

/**
 * Get the host value from the request. This prefers the forwarded host header (if provided)
 * over the local host
 * @param req
 */
var getHost = function(req) {

    var host = req.headers.host;
    if (req.headers['x-forwarded-host']) {
        host = req.headers['x-forwarded-host'];
    }
    return host;
};

module.exports.getBodyAsJSON = getBodyAsJSON;
module.exports.getStrategy = getStrategy;
module.exports.getAccessToken = getAccessToken;
module.exports.getPermissions = getPermissions;
module.exports.getPermissionOp = getPermissionOp;
module.exports.santizePermissions = sanitizePermissions;
module.exports.getOrigin = getOrigin;
module.exports.notAllowed = notAllowed;
module.exports.preflight = preflight;
module.exports.ping = ping;
module.exports.getLocale = getLocale;
module.exports.getHost = getHost;
module.exports.splitURL = splitURL;<|endoftext|>


<commit_before>var app = {

    jiveURL : opensocial.getEnvironment()['jiveUrl'],

	init : function() {
		//** LOAD CURRENT VIEW ***
		var currentView = gadgets.views.getCurrentView().getName();

		/*** LOAD CONTEXT ***/
		osapi.jive.core.container.getLaunchContext(handleContext);

	}, // end init

	handleContext : function(ctx) {
		var appObj = this;
		$("#output").html('
'+ctx.jive.context.body+'
');
	} // end handleContext
};

gadgets.util.registerOnLoadHandler(gadgets.util.makeClosure(app, app.init));<commit_msg>Updated main.js<commit_after>var app = {

    jiveURL : opensocial.getEnvironment()['jiveUrl'],

    currentView : null,

	init : function() {
		//** LOAD CURRENT VIEW ***
		this.currentView = gadgets.views.getCurrentView().getName();

		/*** LOAD CONTEXT ***/
		osapi.jive.core.container.getLaunchContext(this.handleContext);

	}, // end init

	handleContext : function(ctx) {
		var appObj = this;
		$("#output").html('
'+JSON.stringify(ctx, null, '\t')+'
');
		gadgets.window.adjustHeight();
	} // end handleContext
};

gadgets.util.registerOnLoadHandler(gadgets.util.makeClosure(app, app.init));<|endoftext|>


<commit_before>const fs = require('fs'),
  https = require('https'),
  twitter = require('twitter'),
  config = require('../config/config.js'),
  client = new twitter(config.twitterKeys),
  Reddit = config.reddit

const getContent = function (url, callback) {
  const req = https.get(url, function (res) {
    const result = {}
    result['statusCode'] = res.statusCode
    let rawData = ''

    res.on('data', function (chunk) {
      rawData += chunk
    })

    res.on('end', function () {
      result['rawData'] = rawData
      callback(null, JSON.parse(result['rawData']).data.children, postTweet)
    })
  })

  req.on('error', function (err) {
    callback(err)
  })
}

const downloadImages = function (err, data, callback) {
  if (err !== null) console.error(err)
  else {
    data.map(function (current) {
      let post = current.data,
        imageUrl = post.url,
        filename = post.id,
        title = post.title

      let fileWrite = fs.createWriteStream(`images/${filename}.jpg`)
      https.get(imageUrl, function (res) {
        res.pipe(fileWrite)

        res.on('end', function () {
          callback(null, filename, title)
        })
        res.on('error', function (err) {
          callback(err)
        })
      })
      console.log(`downloaded: ${title}`)
    })
  }
}

const postTweet = function (err, filename, title) {
  if (err !== null) console.error(err)
  else {
    const file = fs.readFileSync(`images/${filename}.jpg`)
    client.post('media/upload', {
      media: file
    }, function (error, media, response) {
      if (!error) {
        let status = {
          status: `${title}`,
          media_ids: media.media_id_string
        }

        client.post('statuses/update', status, function (error, tweet, response) {
          if (!error) {
            console.log(`tweet: https://twitter.com/${tweet.screen_name}/status/${tweet.id_str}`)
          }
        })
      }
    })
  }
}

const imageUrl = `https://www.reddit.com/r/${Reddit.subreddit}/top/.json?sort=top&t=day&limit=${Reddit.limit}`
getContent(imageUrl, downloadImages)
<commit_msg>implemented checking of existing files before downloading them<commit_after>const fs = require('fs'),
  https = require('https'),
  twitter = require('twitter'),
  config = require('../config/config.js'),
  client = new twitter(config.twitterKeys)

const getContent = function (url, callback) {
  const req = https.get(url, function (res) {
    const result = {}
    result['statusCode'] = res.statusCode
    let rawData = ''

    res.on('data', function (chunk) {
      rawData += chunk
    })

    res.on('end', function () {
      result['rawData'] = rawData
      callback(null, JSON.parse(result['rawData']).data.children, postTweet)
    })
  })

  req.on('error', function (err) {
    callback(err)
  })
}

const downloadImages = function (err, data, callback) {
  if (err !== null) console.error(err)
  else {
    data.map(function (current) {
      let post = current.data,
        subreddit = post.subreddit,
        imageUrl = post.url,
        filename = post.id,
        title = post.title,
        subFolder = `./images/${subreddit}`

      if (!fs.existsSync(subFolder)) fs.mkdirSync(subFolder)

      let fileExists = fs.existsSync(`images/${subreddit}/${filename}.jpg`)

      if (fileExists) {
        console.log(`file exists: ${title}`)
        return
      }

      let fileWrite = fs.createWriteStream(`images/${subreddit}/${filename}.jpg`)
      https.get(imageUrl, function (res) {
        res.pipe(fileWrite)

        res.on('end', function () {
          callback(null, filename, title, subreddit)
        })
        res.on('error', function (err) {
          callback(err)
        })
      })
      console.log(`downloaded: ${printTitle(title)}`)
    })
  }
}

const postTweet = function (err, filename, title, subreddit) {
  if (err !== null) console.error(err)
  else {
    const file = fs.readFileSync(`images/${subreddit}/${filename}.jpg`)
    client.post('media/upload', {
      media: file
    }, function (error, media, response) {
      if (!error) {
        let status = {
          status: `${title}`,
          media_ids: media.media_id_string
        }

        client.post('statuses/update', status, function (error, tweet, response) {
          if (!error)
            console.log(`tweet: https://twitter.com/${tweet.screen_name}/status/${tweet.id_str}`)
        })
      }
    })
  }
}

const printTitle = function (title) {
  return (title.length < 10) ? title : (title.slice(0, 20) + '...')
}

module.exports = {
  getContent: getContent,
  downloadImages: downloadImages,
  postTweet: postTweet,
  printTitle: printTitle
}

// export = { getContent, downloadImages, postTweet, printTitle}
<|endoftext|>


<commit_before>
if( typeof(BiwaScheme)!='object' ) BiwaScheme={}; with(BiwaScheme) {
  define_libfunc("html-escape", 1, 1, function(ar){
    assert_string(ar[0]);
    return ar[0].escapeHTML();
  });
  BiwaScheme.inspect_objs = function(objs){
    return objs.map(function(obj){
      if(obj.inspect)
        return obj.inspect();
      else
        return Object.inspect($H(obj));
    }).join(" ");
  };
  define_libfunc("inspect", 1, null, function(ar){
    return BiwaScheme.inspect_objs(ar);
  });
  define_libfunc("inspect!", 1, null, function(ar){
    return puts(BiwaScheme.inspect_objs(ar));
  });

  //
  // json
  //
  // json->sexp
  // Array -> list
  // Object -> alist
  // (number, boolean, string,
  //
  BiwaScheme.json2sexp = function(json){
    switch(true){
    case Object.isNumber(json) ||
         Object.isString(json) ||
         json === true || json === false:
      return json;
    case Object.isArray(json):
      return json.map(function(item){
               return json2sexp(item);
             }).to_list();
    case typeof(json) == "object":
      var ls = nil;
      for(key in json){
        ls = new Pair(new Pair(key, json2sexp(json[key])),
               ls);
      }
      return ls;
    default:
      throw new Error("json->sexp: detected invalid value for json: "+Object.inspect(json));
    }
    throw new Bug("must not happen");
  }
  define_libfunc("json->sexp", 1, 1, function(ar){
    return json2sexp(ar[0]);
  })

  //
  //from Gauche
  //

  define_libfunc("string-concat", 1, 1, function(ar){
    assert_pair(ar[0]);
    return ar[0].to_array().join("");
  })
  define_libfunc("string-split", 2, 2, function(ar){
    assert_string(ar[0]);
    assert_string(ar[1]);
    return ar[0].split(ar[1]).to_list();
  })
  define_libfunc("string-join", 1, 2, function(ar){
    assert_pair(ar[0]);
    var delim = ""
    if(ar[1]){
      assert_string(ar[1]);
      delim = ar[1];
    }
    return ar[0].to_array().join(delim);
  })

  define_libfunc("intersperse", 2, 2, function(ar){
    var item = ar[0], ls = ar[1];
    assert_pair(ls);

    var ret = [];
    ls.to_array().reverse().each(function(x){
      ret.push(x);
      ret.push(item);
    });
    ret.pop();
    return ret.to_list();
  });

  define_libfunc("map-with-index", 2, null, function(ar){
    var proc = ar.shift(), lists = ar;
    lists.each(function(ls){ assert_pair(ls) });

    var results = [], i = 0;
    return Call.multi_foreach(lists, {
      call: function(xs){
        var args = xs.map(function(x){ return x.car });
        args.unshift(i);
        i++;
        return new Call(proc, args);
      },
      result: function(res){ results.push(res); },
      finish: function(){ return results.to_list(); }
    });
  });

  //(define-macro (foo x) body ...)
  //(define-macro foo lambda)

  var rearrange_args = function (expected, given) {
    var args = [];
    var dotpos = (new Compiler).find_dot_pos(expected);
    if (dotpos == -1)
      args = given;
    else {
      for (var i = 0; i < dotpos; i++)
	args[i] = given[i];
      args[i] = given.slice(i).to_list();
    }
    return args;
  }
  define_syntax("define-macro", function(x){
    var head = x.cdr.car;
    var expected_args;
    if(head instanceof Pair){
      var name = head.car;
      expected_args = head.cdr;
      var body = x.cdr.cdr;
      var lambda = new Pair(Sym("lambda"),
                     new Pair(expected_args,
                       body))
    }
    else{
      var name = head;
      var lambda = x.cdr.cdr.car;
      expected_args = lambda.cdr.car;
    }

    //[close, n_frees, do_body, next]
    var opc = Compiler.compile(lambda);
    if(opc[1] != 0)
      throw new Bug("you cannot use free variables in macro expander (or define-macro must be on toplevel)")
    var cls = [opc[2]];

    TopEnv[name.name] = new Syntax(name.name, function(sexp){
      var given_args = sexp.to_array();

      given_args.shift();

      var intp = new Interpreter();
      var args = rearrange_args(expected_args, given_args);
      var result = intp.invoke_closure(cls, args);
      return result;
    });

    return BiwaScheme.undef;
  })

  var macroexpand_1 = function(x){
    if(x instanceof Pair){
      if(x.car instanceof Symbol && TopEnv[x.car.name] instanceof Syntax){
        var transformer = TopEnv[x.car.name];
        x = transformer.transform(x);
      }
      else
        throw new Error("macroexpand-1: `" + to_write_ss(x) + "' is not a macro");
    }
    return x;
  }
  define_syntax("%macroexpand", function(x){
    var expanded = (new Interpreter).expand(x.cdr.car);
    return [Sym("quote"), expanded].to_list();
  });
  define_syntax("%macroexpand-1", function(x){
    var expanded = macroexpand_1(x.cdr.car);
    return [Sym("quote"), expanded].to_list();
  });

  define_libfunc("macroexpand", 1, 1, function(ar){
    return (new Interpreter).expand(ar[0]);
  });
  define_libfunc("macroexpand-1", 1, 1, function(ar){
    return macroexpand_1(ar[0]);
  });

  define_libfunc("print", 1, null, function(ar){
    ar.map(function(item){
      puts(to_display(item), true);
    })
    puts(""); //newline
    return BiwaScheme.undef;
  })
  define_syntax("let1", function(x){
    //(let1 vari expr body ...)
    //=> ((lambda (var) body ...) expr)
    var vari = x.cdr.car;
    var expr = x.cdr.cdr.car;
    var body = x.cdr.cdr.cdr;

    return new Pair(new Pair(Sym("lambda"),
                      new Pair(new Pair(vari, nil),
                        body)),
             new Pair(expr, nil));
  })

  define_libfunc("write-to-string", 1, 1, function(ar){
    return to_write(ar[0]);
  });
  define_libfunc("read-from-string", 1, 1, function(ar){
    assert_string(ar[0]);
    return Interpreter.read(ar[0]);
  });

  //
  // Regular Expression
  //
  var assert_regexp = function(obj, fname){
    if(!(obj instanceof RegExp))
      throw new Error(fname + ": regexp required, but got " + to_write(obj));
  }

  //Function: string->regexp string &keyword case-fold
  define_libfunc("string->regexp", 1, 1, function(ar){
    assert_string(ar[0], "string->regexp");
    return new RegExp(ar[0]); //todo: case-fold
  })
  //Function: regexp? obj
  define_libfunc("regexp?", 1, 1, function(ar){
    return (ar[0] instanceof RegExp);
  })
  //Function: regexp->string regexp
  define_libfunc("regexp->string", 1, 1, function(ar){
    assert_regexp(ar[0], "regexp->string");
    return ar[0].toString().slice(1, -1); //cut '/'
  })

  define_libfunc("regexp-exec", 2, 2, function(ar){
    var rexp = ar[0];
    if(Object.isString(ar[0])){
      rexp = new RegExp(ar[0]);
    }
    assert_regexp(rexp, "regexp-exec");
    assert_string(ar[1], "regexp-exec");
    var ret = rexp.exec(ar[1])
    return (ret === null) ? false : ret.to_list();
  })

//  //Function: rxmatch regexp string
//  define_libfunc("rxmatch", 1, 1, function(ar){
//    assert_regexp(ar[0], "rxmatch");
//    assert_string(ar[1], "rxmatch");
//    return ar[0].match(ar[1]);
//  });
  //Function: rxmatch-start match &optional (i 0)
  //Function: rxmatch-end match &optional (i 0)
  //Function: rxmatch-substring match &optional (i 0)
  //Function: rxmatch-num-matches match
  //Function: rxmatch-after match &optional (i 0)
  //Function: rxmatch-before match &optional (i 0)
  //Generic application: regmatch &optional index
  //Generic application: regmatch 'before &optional index
  //Generic application: regmatch 'after &optional index
  //Function: regexp-replace regexp string substitution
  //Function: regexp-replace-all regexp string substitution
  //Function: regexp-replace* string rx1 sub1 rx2 sub2 ...
  //Function: regexp-replace-all* string rx1 sub1 rx2 sub2 ...
  //Function: regexp-quote string
  //Macro: rxmatch-let match-expr (var ...) form ...
  //Macro: rxmatch-if match-expr (var ...) then-form else-form
  //Macro: rxmatch-cond clause ...
  //Macro: rxmatch-case string-expr clause ...

}

<commit_msg>refactor: Added some comments<commit_after>
if( typeof(BiwaScheme)!='object' ) BiwaScheme={}; with(BiwaScheme) {
  define_libfunc("html-escape", 1, 1, function(ar){
    assert_string(ar[0]);
    return ar[0].escapeHTML();
  });
  BiwaScheme.inspect_objs = function(objs){
    return objs.map(function(obj){
      if(obj.inspect)
        return obj.inspect();
      else
        return Object.inspect($H(obj));
    }).join(" ");
  };
  define_libfunc("inspect", 1, null, function(ar){
    return BiwaScheme.inspect_objs(ar);
  });
  define_libfunc("inspect!", 1, null, function(ar){
    return puts(BiwaScheme.inspect_objs(ar));
  });

  //
  // json
  //
  // json->sexp
  // Array -> list
  // Object -> alist
  // (number, boolean, string,
  //
  BiwaScheme.json2sexp = function(json){
    switch(true){
    case Object.isNumber(json) ||
         Object.isString(json) ||
         json === true || json === false:
      return json;
    case Object.isArray(json):
      return json.map(function(item){
               return json2sexp(item);
             }).to_list();
    case typeof(json) == "object":
      var ls = nil;
      for(key in json){
        ls = new Pair(new Pair(key, json2sexp(json[key])),
               ls);
      }
      return ls;
    default:
      throw new Error("json->sexp: detected invalid value for json: "+Object.inspect(json));
    }
    throw new Bug("must not happen");
  }
  define_libfunc("json->sexp", 1, 1, function(ar){
    return json2sexp(ar[0]);
  })

  //
  //from Gauche
  //

  // string
  define_libfunc("string-concat", 1, 1, function(ar){
    assert_pair(ar[0]);
    return ar[0].to_array().join("");
  })
  define_libfunc("string-split", 2, 2, function(ar){
    assert_string(ar[0]);
    assert_string(ar[1]);
    return ar[0].split(ar[1]).to_list();
  })
  define_libfunc("string-join", 1, 2, function(ar){
    assert_pair(ar[0]);
    var delim = ""
    if(ar[1]){
      assert_string(ar[1]);
      delim = ar[1];
    }
    return ar[0].to_array().join(delim);
  })

  // lists

  define_libfunc("intersperse", 2, 2, function(ar){
    var item = ar[0], ls = ar[1];
    assert_pair(ls);

    var ret = [];
    ls.to_array().reverse().each(function(x){
      ret.push(x);
      ret.push(item);
    });
    ret.pop();
    return ret.to_list();
  });

  define_libfunc("map-with-index", 2, null, function(ar){
    var proc = ar.shift(), lists = ar;
    lists.each(function(ls){ assert_pair(ls) });

    var results = [], i = 0;
    return Call.multi_foreach(lists, {
      call: function(xs){
        var args = xs.map(function(x){ return x.car });
        args.unshift(i);
        i++;
        return new Call(proc, args);
      },
      result: function(res){ results.push(res); },
      finish: function(){ return results.to_list(); }
    });
  });

  // macros

  //(define-macro (foo x) body ...)
  //(define-macro foo lambda)

  var rearrange_args = function (expected, given) {
    var args = [];
    var dotpos = (new Compiler).find_dot_pos(expected);
    if (dotpos == -1)
      args = given;
    else {
      for (var i = 0; i < dotpos; i++)
	args[i] = given[i];
      args[i] = given.slice(i).to_list();
    }
    return args;
  }
  define_syntax("define-macro", function(x){
    var head = x.cdr.car;
    var expected_args;
    if(head instanceof Pair){
      var name = head.car;
      expected_args = head.cdr;
      var body = x.cdr.cdr;
      var lambda = new Pair(Sym("lambda"),
                     new Pair(expected_args,
                       body))
    }
    else{
      var name = head;
      var lambda = x.cdr.cdr.car;
      expected_args = lambda.cdr.car;
    }

    //[close, n_frees, do_body, next]
    var opc = Compiler.compile(lambda);
    if(opc[1] != 0)
      throw new Bug("you cannot use free variables in macro expander (or define-macro must be on toplevel)")
    var cls = [opc[2]];

    TopEnv[name.name] = new Syntax(name.name, function(sexp){
      var given_args = sexp.to_array();

      given_args.shift();

      var intp = new Interpreter();
      var args = rearrange_args(expected_args, given_args);
      var result = intp.invoke_closure(cls, args);
      return result;
    });

    return BiwaScheme.undef;
  })

  var macroexpand_1 = function(x){
    if(x instanceof Pair){
      if(x.car instanceof Symbol && TopEnv[x.car.name] instanceof Syntax){
        var transformer = TopEnv[x.car.name];
        x = transformer.transform(x);
      }
      else
        throw new Error("macroexpand-1: `" + to_write_ss(x) + "' is not a macro");
    }
    return x;
  }
  define_syntax("%macroexpand", function(x){
    var expanded = (new Interpreter).expand(x.cdr.car);
    return [Sym("quote"), expanded].to_list();
  });
  define_syntax("%macroexpand-1", function(x){
    var expanded = macroexpand_1(x.cdr.car);
    return [Sym("quote"), expanded].to_list();
  });

  define_libfunc("macroexpand", 1, 1, function(ar){
    return (new Interpreter).expand(ar[0]);
  });
  define_libfunc("macroexpand-1", 1, 1, function(ar){
    return macroexpand_1(ar[0]);
  });

  // i/o

  define_libfunc("print", 1, null, function(ar){
    ar.map(function(item){
      puts(to_display(item), true);
    })
    puts(""); //newline
    return BiwaScheme.undef;
  })
  define_libfunc("write-to-string", 1, 1, function(ar){
    return to_write(ar[0]);
  });
  define_libfunc("read-from-string", 1, 1, function(ar){
    assert_string(ar[0]);
    return Interpreter.read(ar[0]);
  });

  // syntax

  define_syntax("let1", function(x){
    //(let1 vari expr body ...)
    //=> ((lambda (var) body ...) expr)
    var vari = x.cdr.car;
    var expr = x.cdr.cdr.car;
    var body = x.cdr.cdr.cdr;

    return new Pair(new Pair(Sym("lambda"),
                      new Pair(new Pair(vari, nil),
                        body)),
             new Pair(expr, nil));
  })

  //
  // Regular Expression
  //
  var assert_regexp = function(obj, fname){
    if(!(obj instanceof RegExp))
      throw new Error(fname + ": regexp required, but got " + to_write(obj));
  }

  //Function: string->regexp string &keyword case-fold
  define_libfunc("string->regexp", 1, 1, function(ar){
    assert_string(ar[0], "string->regexp");
    return new RegExp(ar[0]); //todo: case-fold
  })
  //Function: regexp? obj
  define_libfunc("regexp?", 1, 1, function(ar){
    return (ar[0] instanceof RegExp);
  })
  //Function: regexp->string regexp
  define_libfunc("regexp->string", 1, 1, function(ar){
    assert_regexp(ar[0], "regexp->string");
    return ar[0].toString().slice(1, -1); //cut '/'
  })

  define_libfunc("regexp-exec", 2, 2, function(ar){
    var rexp = ar[0];
    if(Object.isString(ar[0])){
      rexp = new RegExp(ar[0]);
    }
    assert_regexp(rexp, "regexp-exec");
    assert_string(ar[1], "regexp-exec");
    var ret = rexp.exec(ar[1])
    return (ret === null) ? false : ret.to_list();
  })

//  //Function: rxmatch regexp string
//  define_libfunc("rxmatch", 1, 1, function(ar){
//    assert_regexp(ar[0], "rxmatch");
//    assert_string(ar[1], "rxmatch");
//    return ar[0].match(ar[1]);
//  });
  //Function: rxmatch-start match &optional (i 0)
  //Function: rxmatch-end match &optional (i 0)
  //Function: rxmatch-substring match &optional (i 0)
  //Function: rxmatch-num-matches match
  //Function: rxmatch-after match &optional (i 0)
  //Function: rxmatch-before match &optional (i 0)
  //Generic application: regmatch &optional index
  //Generic application: regmatch 'before &optional index
  //Generic application: regmatch 'after &optional index
  //Function: regexp-replace regexp string substitution
  //Function: regexp-replace-all regexp string substitution
  //Function: regexp-replace* string rx1 sub1 rx2 sub2 ...
  //Function: regexp-replace-all* string rx1 sub1 rx2 sub2 ...
  //Function: regexp-quote string
  //Macro: rxmatch-let match-expr (var ...) form ...
  //Macro: rxmatch-if match-expr (var ...) then-form else-form
  //Macro: rxmatch-cond clause ...
  //Macro: rxmatch-case string-expr clause ...

}

<|endoftext|>


<commit_before>'use strict';

var nullFormCtrl = {
  $addControl: noop,
  $removeControl: noop,
  $setValidity: noop,
  $setDirty: noop,
  $setPristine: noop
};

/**
 * @ngdoc object
 * @name ng.directive:form.FormController
 *
 * @property {boolean} $pristine True if user has not interacted with the form yet.
 * @property {boolean} $dirty True if user has already interacted with the form.
 * @property {boolean} $valid True if all of the containing forms and controls are valid.
 * @property {boolean} $invalid True if at least one containing control or form is invalid.
 *
 * @property {Object} $error Is an object hash, containing references to all invalid controls or
 *  forms, where:
 *
 *  - keys are validation tokens (error names) — such as `required`, `url` or `email`),
 *  - values are arrays of controls or forms that are invalid with given error.
 *
 * @description
 * `FormController` keeps track of all its controls and nested forms as well as state of them,
 * such as being valid/invalid or dirty/pristine.
 *
 * Each {@link ng.directive:form form} directive creates an instance
 * of `FormController`.
 *
 */
//asks for $scope to fool the BC controller module
FormController.$inject = ['$element', '$attrs', '$scope'];
function FormController(element, attrs) {
  var form = this,
      parentForm = element.parent().controller('form') || nullFormCtrl,
      invalidCount = 0, // used to easily determine if we are valid
      errors = form.$error = {},
      controls = [];

  // init state
  form.$name = attrs.name;
  form.$dirty = false;
  form.$pristine = true;
  form.$valid = true;
  form.$invalid = false;

  parentForm.$addControl(form);

  // Setup initial state of the control
  element.addClass(PRISTINE_CLASS);
  toggleValidCss(true);

  // convenience method for easy toggling of classes
  function toggleValidCss(isValid, validationErrorKey) {
    validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';
    element.
      removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey).
      addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
  }

  form.$addControl = function(control) {
    controls.push(control);

    if (control.$name && !form.hasOwnProperty(control.$name)) {
      form[control.$name] = control;
    }
  };

  form.$removeControl = function(control) {
    if (control.$name && form[control.$name] === control) {
      delete form[control.$name];
    }
    forEach(errors, function(queue, validationToken) {
      form.$setValidity(validationToken, true, control);
    });

    arrayRemove(controls, control);
  };

  form.$setValidity = function(validationToken, isValid, control) {
    var queue = errors[validationToken];

    if (isValid) {
      if (queue) {
        arrayRemove(queue, control);
        if (!queue.length) {
          invalidCount--;
          if (!invalidCount) {
            toggleValidCss(isValid);
            form.$valid = true;
            form.$invalid = false;
          }
          errors[validationToken] = false;
          toggleValidCss(true, validationToken);
          parentForm.$setValidity(validationToken, true, form);
        }
      }

    } else {
      if (!invalidCount) {
        toggleValidCss(isValid);
      }
      if (queue) {
        if (includes(queue, control)) return;
      } else {
        errors[validationToken] = queue = [];
        invalidCount++;
        toggleValidCss(false, validationToken);
        parentForm.$setValidity(validationToken, false, form);
      }
      queue.push(control);

      form.$valid = false;
      form.$invalid = true;
    }
  };

  form.$setDirty = function() {
    element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS);
    form.$dirty = true;
    form.$pristine = false;
    parentForm.$setDirty();
  };

  /**
   * @ngdoc function
   * @name ng.directive:form.FormController#$setPristine
   * @methodOf ng.directive:form.FormController
   *
   * @description
   * Sets the form to its pristine state.
   *
   * This method can be called to remove the 'ng-dirty' class and set the form to its pristine
   * state (ng-pristine class). This method will also propagate to all the controls contained
   * in this form.
   *
   * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
   * saving or resetting it.
   */
  form.$setPristine = function () {
    element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
    form.$dirty = false;
    form.$pristine = true;
    forEach(controls, function(control) {
      control.$setPristine();
    });
  };
}

/**
 * @ngdoc directive
 * @name ng.directive:ngForm
 * @restrict EAC
 *
 * @description
 * Nestable alias of {@link ng.directive:form `form`} directive. HTML
 * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a
 * sub-group of controls needs to be determined.
 *
 * @param {string=} name|ngForm Name of the form. If specified, the form controller will be published into
 *                       related scope, under this name.
 *
 */

 /**
 * @ngdoc directive
 * @name ng.directive:form
 * @restrict E
 *
 * @description
 * Directive that instantiates
 * {@link ng.directive:form.FormController FormController}.
 *
 * If `name` attribute is specified, the form controller is published onto the current scope under
 * this name.
 *
 * # Alias: {@link ng.directive:ngForm `ngForm`}
 *
 * In angular forms can be nested. This means that the outer form is valid when all of the child
 * forms are valid as well. However browsers do not allow nesting of `<form>` elements, for this
 * reason angular provides {@link ng.directive:ngForm `ngForm`} alias
 * which behaves identical to `<form>` but allows form nesting.
 *
 *
 * # CSS classes
 *  - `ng-valid` Is set if the form is valid.
 *  - `ng-invalid` Is set if the form is invalid.
 *  - `ng-pristine` Is set if the form is pristine.
 *  - `ng-dirty` Is set if the form is dirty.
 *
 *
 * # Submitting a form and preventing default action
 *
 * Since the role of forms in client-side Angular applications is different than in classical
 * roundtrip apps, it is desirable for the browser not to translate the form submission into a full
 * page reload that sends the data to the server. Instead some javascript logic should be triggered
 * to handle the form submission in application specific way.
 *
 * For this reason, Angular prevents the default action (form submission to the server) unless the
 * `<form>` element has an `action` attribute specified.
 *
 * You can use one of the following two ways to specify what javascript method should be called when
 * a form is submitted:
 *
 * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element
 * - {@link ng.directive:ngClick ngClick} directive on the first
  *  button or input field of type submit (input[type=submit])
 *
 * To prevent double execution of the handler, use only one of ngSubmit or ngClick directives. This
 * is because of the following form submission rules coming from the html spec:
 *
 * - If a form has only one input field then hitting enter in this field triggers form submit
 * (`ngSubmit`)
 * - if a form has has 2+ input fields and no buttons or input[type=submit] then hitting enter
 * doesn't trigger submit
 * - if a form has one or more input fields and one or more buttons or input[type=submit] then
 * hitting enter in any of the input fields will trigger the click handler on the *first* button or
 * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`)
 *
 * @param {string=} name Name of the form. If specified, the form controller will be published into
 *                       related scope, under this name.
 *
 * @example
    <doc:example>
      <doc:source>

       <form name="myForm" ng-controller="Ctrl">
         userType: <input name="input" ng-model="userType" required>
         Required!

         <tt>userType = {{userType}}</tt>

         <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt>

         <tt>myForm.input.$error = {{myForm.input.$error}}</tt>

         <tt>myForm.$valid = {{myForm.$valid}}</tt>

         <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt>

        </form>
      </doc:source>
      <doc:scenario>
        it('should initialize to model', function() {
         expect(binding('userType')).toEqual('guest');
         expect(binding('myForm.input.$valid')).toEqual('true');
        });

        it('should be invalid if empty', function() {
         input('userType').enter('');
         expect(binding('userType')).toEqual('');
         expect(binding('myForm.input.$valid')).toEqual('false');
        });
      </doc:scenario>
    </doc:example>
 */
var formDirectiveFactory = function(isNgForm) {
  return ['$timeout', function($timeout) {
    var formDirective = {
      name: 'form',
      restrict: 'E',
      controller: FormController,
      compile: function() {
        return {
          pre: function(scope, formElement, attr, controller) {
            if (!attr.action) {
              // we can't use jq events because if a form is destroyed during submission the default
              // action is not prevented. see #1238
              //
              // IE 9 is not affected because it doesn't fire a submit event and try to do a full
              // page reload if the form was destroyed by submission of the form via a click handler
              // on a button in the form. Looks like an IE9 specific bug.
              var preventDefaultListener = function(event) {
                event.preventDefault
                  ? event.preventDefault()
                  : event.returnValue = false; // IE
              };

              addEventListenerFn(formElement[0], 'submit', preventDefaultListener);

              // unregister the preventDefault listener so that we don't not leak memory but in a
              // way that will achieve the prevention of the default action.
              formElement.bind('$destroy', function() {
                $timeout(function() {
                  removeEventListenerFn(formElement[0], 'submit', preventDefaultListener);
                }, 0, false);
              });
            }

            var parentFormCtrl = formElement.parent().controller('form'),
                alias = attr.name || attr.ngForm;

            if (alias) {
              scope[alias] = controller;
            }
            if (parentFormCtrl) {
              formElement.bind('$destroy', function() {
                parentFormCtrl.$removeControl(controller);
                if (alias) {
                  scope[alias] = undefined;
                }
                extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
              });
            }
          }
        };
      }
    };

    return isNgForm ? extend(copy(formDirective), {restrict: 'EAC'}) : formDirective;
  }];
};

var formDirective = formDirectiveFactory();
var ngFormDirective = formDirectiveFactory(true);
<commit_msg>docs(FormController): add methods for FormController<commit_after>'use strict';

var nullFormCtrl = {
  $addControl: noop,
  $removeControl: noop,
  $setValidity: noop,
  $setDirty: noop,
  $setPristine: noop
};

/**
 * @ngdoc object
 * @name ng.directive:form.FormController
 *
 * @property {boolean} $pristine True if user has not interacted with the form yet.
 * @property {boolean} $dirty True if user has already interacted with the form.
 * @property {boolean} $valid True if all of the containing forms and controls are valid.
 * @property {boolean} $invalid True if at least one containing control or form is invalid.
 *
 * @property {Object} $error Is an object hash, containing references to all invalid controls or
 *  forms, where:
 *
 *  - keys are validation tokens (error names) — such as `required`, `url` or `email`),
 *  - values are arrays of controls or forms that are invalid with given error.
 *
 * @description
 * `FormController` keeps track of all its controls and nested forms as well as state of them,
 * such as being valid/invalid or dirty/pristine.
 *
 * Each {@link ng.directive:form form} directive creates an instance
 * of `FormController`.
 *
 */
//asks for $scope to fool the BC controller module
FormController.$inject = ['$element', '$attrs', '$scope'];
function FormController(element, attrs) {
  var form = this,
      parentForm = element.parent().controller('form') || nullFormCtrl,
      invalidCount = 0, // used to easily determine if we are valid
      errors = form.$error = {},
      controls = [];

  // init state
  form.$name = attrs.name;
  form.$dirty = false;
  form.$pristine = true;
  form.$valid = true;
  form.$invalid = false;

  parentForm.$addControl(form);

  // Setup initial state of the control
  element.addClass(PRISTINE_CLASS);
  toggleValidCss(true);

  // convenience method for easy toggling of classes
  function toggleValidCss(isValid, validationErrorKey) {
    validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';
    element.
      removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey).
      addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
  }

  /**
   * @ngdoc function
   * @name ng.directive:form.FormController#$addControl
   * @methodOf ng.directive:form.FormController
   *
   * @description
   * Register a control with the form.
   *
   * Input elements using ngModelController do this automatically when they are linked.
   */
  form.$addControl = function(control) {
    controls.push(control);

    if (control.$name && !form.hasOwnProperty(control.$name)) {
      form[control.$name] = control;
    }
  };

  /**
   * @ngdoc function
   * @name ng.directive:form.FormController#$removeControl
   * @methodOf ng.directive:form.FormController
   *
   * @description
   * Deregister a control from the form.
   *
   * Input elements using ngModelController do this automatically when they are destroyed.
   */
  form.$removeControl = function(control) {
    if (control.$name && form[control.$name] === control) {
      delete form[control.$name];
    }
    forEach(errors, function(queue, validationToken) {
      form.$setValidity(validationToken, true, control);
    });

    arrayRemove(controls, control);
  };

  /**
   * @ngdoc function
   * @name ng.directive:form.FormController#$setValidity
   * @methodOf ng.directive:form.FormController
   *
   * @description
   * Sets the validity of a form control.
   *
   * This method will also propagate to parent forms.
   */
  form.$setValidity = function(validationToken, isValid, control) {
    var queue = errors[validationToken];

    if (isValid) {
      if (queue) {
        arrayRemove(queue, control);
        if (!queue.length) {
          invalidCount--;
          if (!invalidCount) {
            toggleValidCss(isValid);
            form.$valid = true;
            form.$invalid = false;
          }
          errors[validationToken] = false;
          toggleValidCss(true, validationToken);
          parentForm.$setValidity(validationToken, true, form);
        }
      }

    } else {
      if (!invalidCount) {
        toggleValidCss(isValid);
      }
      if (queue) {
        if (includes(queue, control)) return;
      } else {
        errors[validationToken] = queue = [];
        invalidCount++;
        toggleValidCss(false, validationToken);
        parentForm.$setValidity(validationToken, false, form);
      }
      queue.push(control);

      form.$valid = false;
      form.$invalid = true;
    }
  };

  /**
   * @ngdoc function
   * @name ng.directive:form.FormController#$setDirty
   * @methodOf ng.directive:form.FormController
   *
   * @description
   * Sets the form to a dirty state.
   *
   * This method can be called to add the 'ng-dirty' class and set the form to a dirty
   * state (ng-dirty class). This method will also propagate to parent forms.
   */
  form.$setDirty = function() {
    element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS);
    form.$dirty = true;
    form.$pristine = false;
    parentForm.$setDirty();
  };

  /**
   * @ngdoc function
   * @name ng.directive:form.FormController#$setPristine
   * @methodOf ng.directive:form.FormController
   *
   * @description
   * Sets the form to its pristine state.
   *
   * This method can be called to remove the 'ng-dirty' class and set the form to its pristine
   * state (ng-pristine class). This method will also propagate to all the controls contained
   * in this form.
   *
   * Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
   * saving or resetting it.
   */
  form.$setPristine = function () {
    element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
    form.$dirty = false;
    form.$pristine = true;
    forEach(controls, function(control) {
      control.$setPristine();
    });
  };
}

/**
 * @ngdoc directive
 * @name ng.directive:ngForm
 * @restrict EAC
 *
 * @description
 * Nestable alias of {@link ng.directive:form `form`} directive. HTML
 * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a
 * sub-group of controls needs to be determined.
 *
 * @param {string=} name|ngForm Name of the form. If specified, the form controller will be published into
 *                       related scope, under this name.
 *
 */

 /**
 * @ngdoc directive
 * @name ng.directive:form
 * @restrict E
 *
 * @description
 * Directive that instantiates
 * {@link ng.directive:form.FormController FormController}.
 *
 * If `name` attribute is specified, the form controller is published onto the current scope under
 * this name.
 *
 * # Alias: {@link ng.directive:ngForm `ngForm`}
 *
 * In angular forms can be nested. This means that the outer form is valid when all of the child
 * forms are valid as well. However browsers do not allow nesting of `<form>` elements, for this
 * reason angular provides {@link ng.directive:ngForm `ngForm`} alias
 * which behaves identical to `<form>` but allows form nesting.
 *
 *
 * # CSS classes
 *  - `ng-valid` Is set if the form is valid.
 *  - `ng-invalid` Is set if the form is invalid.
 *  - `ng-pristine` Is set if the form is pristine.
 *  - `ng-dirty` Is set if the form is dirty.
 *
 *
 * # Submitting a form and preventing default action
 *
 * Since the role of forms in client-side Angular applications is different than in classical
 * roundtrip apps, it is desirable for the browser not to translate the form submission into a full
 * page reload that sends the data to the server. Instead some javascript logic should be triggered
 * to handle the form submission in application specific way.
 *
 * For this reason, Angular prevents the default action (form submission to the server) unless the
 * `<form>` element has an `action` attribute specified.
 *
 * You can use one of the following two ways to specify what javascript method should be called when
 * a form is submitted:
 *
 * - {@link ng.directive:ngSubmit ngSubmit} directive on the form element
 * - {@link ng.directive:ngClick ngClick} directive on the first
  *  button or input field of type submit (input[type=submit])
 *
 * To prevent double execution of the handler, use only one of ngSubmit or ngClick directives. This
 * is because of the following form submission rules coming from the html spec:
 *
 * - If a form has only one input field then hitting enter in this field triggers form submit
 * (`ngSubmit`)
 * - if a form has has 2+ input fields and no buttons or input[type=submit] then hitting enter
 * doesn't trigger submit
 * - if a form has one or more input fields and one or more buttons or input[type=submit] then
 * hitting enter in any of the input fields will trigger the click handler on the *first* button or
 * input[type=submit] (`ngClick`) *and* a submit handler on the enclosing form (`ngSubmit`)
 *
 * @param {string=} name Name of the form. If specified, the form controller will be published into
 *                       related scope, under this name.
 *
 * @example
    <doc:example>
      <doc:source>

       <form name="myForm" ng-controller="Ctrl">
         userType: <input name="input" ng-model="userType" required>
         Required!

         <tt>userType = {{userType}}</tt>

         <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt>

         <tt>myForm.input.$error = {{myForm.input.$error}}</tt>

         <tt>myForm.$valid = {{myForm.$valid}}</tt>

         <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt>

        </form>
      </doc:source>
      <doc:scenario>
        it('should initialize to model', function() {
         expect(binding('userType')).toEqual('guest');
         expect(binding('myForm.input.$valid')).toEqual('true');
        });

        it('should be invalid if empty', function() {
         input('userType').enter('');
         expect(binding('userType')).toEqual('');
         expect(binding('myForm.input.$valid')).toEqual('false');
        });
      </doc:scenario>
    </doc:example>
 */
var formDirectiveFactory = function(isNgForm) {
  return ['$timeout', function($timeout) {
    var formDirective = {
      name: 'form',
      restrict: 'E',
      controller: FormController,
      compile: function() {
        return {
          pre: function(scope, formElement, attr, controller) {
            if (!attr.action) {
              // we can't use jq events because if a form is destroyed during submission the default
              // action is not prevented. see #1238
              //
              // IE 9 is not affected because it doesn't fire a submit event and try to do a full
              // page reload if the form was destroyed by submission of the form via a click handler
              // on a button in the form. Looks like an IE9 specific bug.
              var preventDefaultListener = function(event) {
                event.preventDefault
                  ? event.preventDefault()
                  : event.returnValue = false; // IE
              };

              addEventListenerFn(formElement[0], 'submit', preventDefaultListener);

              // unregister the preventDefault listener so that we don't not leak memory but in a
              // way that will achieve the prevention of the default action.
              formElement.bind('$destroy', function() {
                $timeout(function() {
                  removeEventListenerFn(formElement[0], 'submit', preventDefaultListener);
                }, 0, false);
              });
            }

            var parentFormCtrl = formElement.parent().controller('form'),
                alias = attr.name || attr.ngForm;

            if (alias) {
              scope[alias] = controller;
            }
            if (parentFormCtrl) {
              formElement.bind('$destroy', function() {
                parentFormCtrl.$removeControl(controller);
                if (alias) {
                  scope[alias] = undefined;
                }
                extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
              });
            }
          }
        };
      }
    };

    return isNgForm ? extend(copy(formDirective), {restrict: 'EAC'}) : formDirective;
  }];
};

var formDirective = formDirectiveFactory();
var ngFormDirective = formDirectiveFactory(true);
<|endoftext|>


<commit_before>/**
 * Strings <https://github.com/sellside/strings>
 *
 * Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward
 * Licensed under the MIT License (MIT).
 */

'use strict';

var _ = require('lodash');
var utils = module.exports = {};

utils._wrap = function (ctx) {
  return function () {
    return ctx;
  };
};

utils._ensureMiddleware = function (middleware) {
  if (_.isFunction(middleware) === false) {
    return utils._wrap(middleware);
  }
  return middleware;
};

utils._normalize = function (parsers) {
  var arr = [];
  if (Array.isArray(parsers)) {
    // [{key: value}, {key, value}] => [{pattern: key, replacement: value], {pattern:key, replacement: value}]
    var i;
    for (i = 0; i < parsers.length; i++) {
      arr = arr.concat(utils._normalizeObject(parsers[i]));
    }
  } else {
    // {key: value} => [{pattern: key, replacement: value}];
    arr = arr.concat(utils._normalizeObject(parsers));
  }
  return arr;
};

utils._normalizeObject = function (object) {
  if (object.hasOwnProperty('pattern') && object.hasOwnProperty('replacement')) {
    return [object];
  }

  var arr = [];
  _.forOwn(object, function (value, key) {
    arr.push({pattern: key, replacement: value});
  });

  return arr;
};

utils._extend = function (middleware) {
  return function (context) {
    return _.extend(context, utils._ensureMiddleware(middleware)());
  };
};

utils._remove = function (middleware) {
  return function (context) {
    return _.omit(context, utils._ensureMiddleware(middleware)());
  };
};

utils._bind = function (replacements, context) {
  context = context || {};
  return _.map(replacements, function (item) {
    if (_.isFunction(item.replacement)) {
      var fn = item.replacement;
      item.replacement = function () {
        return fn.apply(context, arguments);
      };
    }
    return item;
  });
};
<commit_msg>removing unused utility methods<commit_after>/**
 * Strings <https://github.com/sellside/strings>
 *
 * Copyright (c) 2014 Sellside, Jon Schlinkert and Brian Woodward
 * Licensed under the MIT License (MIT).
 */

'use strict';

var _ = require('lodash');
var utils = {};

utils._normalize = function (parsers) {
  var arr = [];
  if (Array.isArray(parsers)) {
    // [{key: value}, {key, value}] => [{pattern: key, replacement: value], {pattern:key, replacement: value}]
    var i;
    for (i = 0; i < parsers.length; i++) {
      arr = arr.concat(utils._normalizeObject(parsers[i]));
    }
  } else {
    // {key: value} => [{pattern: key, replacement: value}];
    arr = arr.concat(utils._normalizeObject(parsers));
  }
  return arr;
};

utils._normalizeObject = function (object) {
  if (object.hasOwnProperty('pattern') && object.hasOwnProperty('replacement')) {
    return [object];
  }

  var arr = [];
  _.forOwn(object, function (value, key) {
    arr.push({pattern: key, replacement: value});
  });

  return arr;
};

utils._bind = function (replacements, context) {
  context = context || {};
  return _.map(replacements, function (item) {
    if (_.isFunction(item.replacement)) {
      var fn = item.replacement;
      item.replacement = function () {
        return fn.apply(context, arguments);
      };
    }
    return item;
  });
};

module.exports = utils;
<|endoftext|>


<commit_before>var fs = require('fs-extra');
var path = require('path');
var Promise = require('bluebird');
var plist = require('plist');
var Glob = require('simple-glob');
var temp = require('temp');
var archiver = require('archiver');
var _ = require('lodash');
var minimatch = require('minimatch');

// Automatically track and cleanup files at exit
temp.track();

module.exports = {
    getPackageInfo: function(path) {
        return new Promise(function(resolve, reject) {
            fs.readFile(path, function (err, data) {
                if (err) return reject(err);
                var appPkg = JSON.parse(data);
                if (!appPkg.name || !appPkg.version) {
                    reject("Please make sure that your project's package.json includes a version and a name value");
                } else {
                    resolve(appPkg);
                }
            });
        });
    },
    getFileList: function(fileglob) {
        var self = this,
            jsonfile, destFiles = [],
            srcFiles = [],
            package_path,
            fileglob_ = _.map(fileglob, function(item) {
              return item.src || item;
            }),
            matches = Glob(fileglob_),
            dests = _.filter(fileglob, function(v,k) {
              return typeof v.src === 'string' && v.src.charAt(0) !== '!';
            });

        return new Promise(function(resolve, reject) {
            if(!matches.length) return reject('No files matching');

            matches.forEach(function(file) {
                var internalFileName = path.normalize(file);
                if (internalFileName.match('package.json')) {
                    jsonfile = self.closerPathDepth(internalFileName, jsonfile);
                    package_path = path.normalize(jsonfile.split('package.json')[0] || './');
                }

                if(!fs.lstatSync(internalFileName).isDirectory()) {
                    srcFiles.push(internalFileName);
                }
            });

            if (!jsonfile) {
                return reject('Could not find a package.json in your src folder');
            }

            srcFiles.forEach(function(file) {
                var dest_path = file.replace(package_path, '');

                dest = _.find(dests, function(d) {
                  return minimatch(file, d.src);
                });

                if (typeof dest !== 'undefined') {
                  var dest_src = dest.src.replace(/\/\*?\*+/g, '');
                  dest_path = dest.dest + file.replace(dest_src, '');
                }

                destFiles.push({
                    src: file,
                    dest: dest_path
                });
            });

            resolve({
                files: destFiles,
                json: jsonfile
            });
        });
    },
    closerPathDepth: function(path1, path2) {
        if (!path2) { return path1; }

        var d1 = this.pathDepth(path1),
            d2 = this.pathDepth(path2);

        return d1 < d2 ? path1 : path2;
    },
    pathDepth: function(absolutePath) {
        return absolutePath.split(path.sep).length;
    },
    copyFile: function (src, dest) {
        return new Promise(function(resolve, reject) {
            var stats = fs.lstatSync(src);
            fs.copy(src, dest, function (err) {
                if(err) return reject(err);
                fs.chmodSync(dest, stats.mode);
                resolve();
            });
        });
    },
    mergeFiles: function (app, zipfile, chmod) {
        // we need to pipe the app into the zipfile and chmod it
        return new Promise(function(resolve, reject) {
            var zipStream = fs.createReadStream(zipfile),
                writeStream = fs.createWriteStream(app, {flags:'a'});

            zipStream.on('error', reject);
            writeStream.on('error', reject);

            writeStream.on('finish', function () {
                if(chmod) {
                    fs.chmodSync(app, chmod);
                }
                resolve();
            });

            zipStream.pipe(writeStream);
        });
    },
    generateZipFile: function (files, _event) {
        var destStream = temp.createWriteStream(),
            archive = archiver('zip');

        return new Promise(function(resolve, reject) {

            // Resolve on close
            destStream.on('close', function () {
                resolve(destStream.path);
            });

            // Reject on Error
            archive.on('error', reject);

            // Add the files
            files.forEach(function (file) {
                archive.file(file.src, { name:file.dest });
            });

            // Some logs
            archive.on('entry', function (file) {
                _event.emit('log', 'Zipping ' + file.name);
            });

            // Pipe the stream
            archive.pipe(destStream);
            archive.finalize();

        });
    },
    editPlist: function (plistInput, plistOutput, options) {

        return new Promise(function(resolve, reject) {
            if(!options.appName || !options.appVersion) {
                return reject('You have to set the appName and appVersion in the Plist options');
            }

            // Handle the INfo.plist file
            var info = plist.parseFileSync(plistInput);
            info.CFBundleDisplayName = options.appName;
            info.CFBundleName = options.appName;
            info.CFBundleVersion = options.appVersion;
            info.CFBundleShortVersionString = 'Version ' + options.appVersion;
            if(options.copyright) {
              info.NSHumanReadableCopyright = options.copyright;
            }
            if(options.mac_bundle_id) {
                info.CFBundleIdentifier = options.mac_bundle_id;
            }
            if(options.mac_document_types) {
                info.CFBundleDocumentTypes = options.mac_document_types.map(function(type) {
                    return {
                        CFBundleTypeName: type.name,
                        CFBundleTypeExtensions: type.extenstions,
                        CFBundleTypeRole: type.role,
                        LSIsAppleDefaultForType: type.isDefault
                    };
                });
            } else {
                info.CFBundleDocumentTypes = [];
            }

            info.UTExportedTypeDeclarations = [];
            fs.writeFileSync(plistOutput, plist.build(info));
            resolve();
        });
    }
};
<commit_msg>[fixed] window path separator error.<commit_after>var fs = require('fs-extra');
var path = require('path');
var Promise = require('bluebird');
var plist = require('plist');
var Glob = require('simple-glob');
var temp = require('temp');
var archiver = require('archiver');
var _ = require('lodash');
var minimatch = require('minimatch');

// Automatically track and cleanup files at exit
temp.track();

module.exports = {
    getPackageInfo: function(path) {
        return new Promise(function(resolve, reject) {
            fs.readFile(path, function (err, data) {
                if (err) return reject(err);
                var appPkg = JSON.parse(data);
                if (!appPkg.name || !appPkg.version) {
                    reject("Please make sure that your project's package.json includes a version and a name value");
                } else {
                    resolve(appPkg);
                }
            });
        });
    },
    getFileList: function(fileglob) {
        var self = this,
            jsonfile, destFiles = [],
            srcFiles = [],
            package_path,
            fileglob_ = _.map(fileglob, function(item) {
              return item.src || item;
            }),
            matches = Glob(fileglob_),
            dests = _.filter(fileglob, function(v,k) {
              return typeof v.src === 'string' && v.src.charAt(0) !== '!';
            });

        return new Promise(function(resolve, reject) {
            if(!matches.length) return reject('No files matching');

            matches.forEach(function(file) {
                var internalFileName = path.normalize(file);
                if (internalFileName.match('package.json')) {
                    jsonfile = self.closerPathDepth(internalFileName, jsonfile);
                    package_path = path.normalize(jsonfile.split('package.json')[0] || './');
                }

                if(!fs.lstatSync(internalFileName).isDirectory()) {
                    srcFiles.push(internalFileName);
                }
            });

            if (!jsonfile) {
                return reject('Could not find a package.json in your src folder');
            }

            srcFiles.forEach(function(file) {
                var dest_path = file.replace(package_path, '');

                dest = _.find(dests, function(d) {
                  return minimatch(file, d.src);
                });

                if (typeof dest !== 'undefined') {
                  var dest_src = path.normalize(dest.src).replace(/[\/|\\]+\*?\*+/g, '');
                  dest_path = dest.dest + file.replace(dest_src, '');
                }

                destFiles.push({
                    src: file,
                    dest: dest_path
                });
            });

            resolve({
                files: destFiles,
                json: jsonfile
            });
        });
    },
    closerPathDepth: function(path1, path2) {
        if (!path2) { return path1; }

        var d1 = this.pathDepth(path1),
            d2 = this.pathDepth(path2);

        return d1 < d2 ? path1 : path2;
    },
    pathDepth: function(absolutePath) {
        return absolutePath.split(path.sep).length;
    },
    copyFile: function (src, dest) {
        return new Promise(function(resolve, reject) {
            var stats = fs.lstatSync(src);
            fs.copy(src, dest, function (err) {
                if(err) return reject(err);
                fs.chmodSync(dest, stats.mode);
                resolve();
            });
        });
    },
    mergeFiles: function (app, zipfile, chmod) {
        // we need to pipe the app into the zipfile and chmod it
        return new Promise(function(resolve, reject) {
            var zipStream = fs.createReadStream(zipfile),
                writeStream = fs.createWriteStream(app, {flags:'a'});

            zipStream.on('error', reject);
            writeStream.on('error', reject);

            writeStream.on('finish', function () {
                if(chmod) {
                    fs.chmodSync(app, chmod);
                }
                resolve();
            });

            zipStream.pipe(writeStream);
        });
    },
    generateZipFile: function (files, _event) {
        var destStream = temp.createWriteStream(),
            archive = archiver('zip');

        return new Promise(function(resolve, reject) {

            // Resolve on close
            destStream.on('close', function () {
                resolve(destStream.path);
            });

            // Reject on Error
            archive.on('error', reject);

            // Add the files
            files.forEach(function (file) {
                archive.file(file.src, { name:file.dest });
            });

            // Some logs
            archive.on('entry', function (file) {
                _event.emit('log', 'Zipping ' + file.name);
            });

            // Pipe the stream
            archive.pipe(destStream);
            archive.finalize();

        });
    },
    editPlist: function (plistInput, plistOutput, options) {

        return new Promise(function(resolve, reject) {
            if(!options.appName || !options.appVersion) {
                return reject('You have to set the appName and appVersion in the Plist options');
            }

            // Handle the INfo.plist file
            var info = plist.parseFileSync(plistInput);
            info.CFBundleDisplayName = options.appName;
            info.CFBundleName = options.appName;
            info.CFBundleVersion = options.appVersion;
            info.CFBundleShortVersionString = 'Version ' + options.appVersion;
            if(options.copyright) {
              info.NSHumanReadableCopyright = options.copyright;
            }
            if(options.mac_bundle_id) {
                info.CFBundleIdentifier = options.mac_bundle_id;
            }
            if(options.mac_document_types) {
                info.CFBundleDocumentTypes = options.mac_document_types.map(function(type) {
                    return {
                        CFBundleTypeName: type.name,
                        CFBundleTypeExtensions: type.extenstions,
                        CFBundleTypeRole: type.role,
                        LSIsAppleDefaultForType: type.isDefault
                    };
                });
            } else {
                info.CFBundleDocumentTypes = [];
            }

            info.UTExportedTypeDeclarations = [];
            fs.writeFileSync(plistOutput, plist.build(info));
            resolve();
        });
    }
};
<|endoftext|>


<commit_before>'use strict'

const Crypto = require('crypto')
const Moment = require('moment')
const Fs = require('fs')
const LazyPromise = require('./lazy')

module.exports.stats = function(path, cb) {
  Fs.stat(path, function(err, stats) {
    if (err === null) {
      cb(stats)
    } else if (err.code === 'ENOENT') {
      cb(undefined)
    } else {
      throw err
    }
  })
}

module.exports.throw = function(msg) {
  throw new Error(msg)
}

module.exports.removeBasedir = function(basedir, s) {
  if (basedir) {
    // FIXME
    return s.replace(new RegExp('^' + basedir + '/'), '')
  } else {
    return s
  }
}

module.exports.pathJoin = function(a,b) {
  // FIXME
  return a + '/' + b
}

// f81d4fae-7dec-11d0-a765-00a0c91e6bf6
module.exports.urn = function(s) {
  if (s) {
    const hash = Crypto.createHash('sha1')
    hash.update(s)
    const digest = hash.digest('hex')

    return 'urn:uuid:'
      + digest.slice(0,8) + '-'
      + digest.slice(8,12) + '-'
      + digest.slice(12,16) + '-'
      + digest.slice(16,20) + '-'
      + digest.slice(20,32)
  } else {
    return s
  }
}

module.exports.formatTimestamp = function(lmod) {
  return Moment(lmod).format('YYYY-MM-DDTHH:mm:ssZ')
  // var d = new Date(lmod)
  // var y = d.getFullYear()
  // var m = '0' + (d.getMonth() + 1)
  // var d = '0' + d.getDate()
  // return y + '-' + m.slice(-2) + '-' + d.slice(-2)
}

module.exports.max = function(values) {
  let m = undefined
  values.forEach(function(v){
    if (v !== undefined) {
      m = (m !== undefined) ? Math.max(m, v) : v
    }
  })
  return m
}

module.exports.lazyLoad = function(obj) {
  return new LazyPromise(function(resolve, reject) {
    resolve(obj)
  })
}

const merge = function() {
  const args = Array.prototype.slice.call(arguments)
  const r = {}
  args.forEach(function(arg){
    if (arg) {
      Object.keys(arg).forEach(function(key){
        r[key] = arg[key]
      })
    }
  })
  return r
}
module.exports.merge = merge

module.exports.spread = function(fn) {
  return function (values) {
    return fn.apply(null, values)
  }
}

module.exports.wrap = function(fn, before, after, target) {
  return function() {
    if(before) before.apply(target, arguments)
    const res = fn.apply(target, arguments)
    if(after) after.apply(target, arguments)
    return res
  }
}

let _objid = 1
module.exports.objectId = function(obj) {
  if (obj == null) {
    return null
  }
  if (obj._objid == null) {
    obj._objid = _objid++
  }
  return obj._objid
}

module.exports.renderContext = function(project, options, doc, other) {
  return merge(
    { site: project.options },
    options || {},
    doc.meta,
    { file: { path: doc.path, lmod: doc.lmod }},
    other || {}
  )
}
<commit_msg>provide json<commit_after>'use strict'

const Crypto = require('crypto')
const Moment = require('moment')
const Fs = require('fs')
const LazyPromise = require('./lazy')

module.exports.stats = function(path, cb) {
  Fs.stat(path, function(err, stats) {
    if (err === null) {
      cb(stats)
    } else if (err.code === 'ENOENT') {
      cb(undefined)
    } else {
      throw err
    }
  })
}

module.exports.throw = function(msg) {
  throw new Error(msg)
}

module.exports.removeBasedir = function(basedir, s) {
  if (basedir) {
    // FIXME
    return s.replace(new RegExp('^' + basedir + '/'), '')
  } else {
    return s
  }
}

module.exports.pathJoin = function(a,b) {
  // FIXME
  return a + '/' + b
}

// f81d4fae-7dec-11d0-a765-00a0c91e6bf6
module.exports.urn = function(s) {
  if (s) {
    const hash = Crypto.createHash('sha1')
    hash.update(s)
    const digest = hash.digest('hex')

    return 'urn:uuid:'
      + digest.slice(0,8) + '-'
      + digest.slice(8,12) + '-'
      + digest.slice(12,16) + '-'
      + digest.slice(16,20) + '-'
      + digest.slice(20,32)
  } else {
    return s
  }
}

module.exports.formatTimestamp = function(lmod) {
  return Moment(lmod).format('YYYY-MM-DDTHH:mm:ssZ')
  // var d = new Date(lmod)
  // var y = d.getFullYear()
  // var m = '0' + (d.getMonth() + 1)
  // var d = '0' + d.getDate()
  // return y + '-' + m.slice(-2) + '-' + d.slice(-2)
}

module.exports.max = function(values) {
  let m = undefined
  values.forEach(function(v){
    if (v !== undefined) {
      m = (m !== undefined) ? Math.max(m, v) : v
    }
  })
  return m
}

module.exports.lazyLoad = function(obj) {
  return new LazyPromise(function(resolve, reject) {
    resolve(obj)
  })
}

const merge = function() {
  const args = Array.prototype.slice.call(arguments)
  const r = {}
  args.forEach(function(arg){
    if (arg) {
      Object.keys(arg).forEach(function(key){
        r[key] = arg[key]
      })
    }
  })
  return r
}
module.exports.merge = merge

module.exports.spread = function(fn) {
  return function (values) {
    return fn.apply(null, values)
  }
}

module.exports.wrap = function(fn, before, after, target) {
  return function() {
    if(before) before.apply(target, arguments)
    const res = fn.apply(target, arguments)
    if(after) after.apply(target, arguments)
    return res
  }
}

let _objid = 1
module.exports.objectId = function(obj) {
  if (obj == null) {
    return null
  }
  if (obj._objid == null) {
    obj._objid = _objid++
  }
  return obj._objid
}

module.exports.renderContext = function(project, options, doc, other) {
  return merge(
    { site: project.options },
    options || {},
    doc.meta,
    (doc.json && { json: doc.json }) || {},
    { file: { path: doc.path, lmod: doc.lmod }},
    other || {}
  )
}
<|endoftext|>