<commit_before>/**
 * Patterns calendar - Calendar with different views for patterns.
 *
 * Copyright 2013-2014 Marko Durkovic
 * Copyright 2014 Florian Friesdorf
 * Copyright 2014 Syslab.com GmbH
 */
define([
    "jquery",
    "pat-logger",
    "pat-parser",
    "pat-store",
    "pat-utils",
    "pat-registry",
    "pat-calendar-moment-timezone-data",
    "jquery.fullcalendar.dnd",
    "jquery.fullcalendar"
], function($, logger, Parser, store, utils, registry) {
    "use strict";
    var log = logger.getLogger("calendar"),
        parser = new Parser("calendar");

    parser.add_argument("height", "auto");
    parser.add_argument("start-date");
    parser.add_argument("time-format", "h(:mm)t");
    parser.add_argument("title-month", "MMMM YYYY");
    parser.add_argument("title-week", "MMM D YYYY");
    parser.add_argument("title-day", "dddd, MMM d, YYYY");
    parser.add_argument("column-month", "ddd");
    parser.add_argument("column-week", "ddd M/d");
    parser.add_argument("column-day", "dddd M/d");
    parser.add_argument("first-day", "0");
    parser.add_argument("first-hour", "6");
    parser.add_argument("calendar-controls", "");
    parser.add_argument("category-controls", "");
    parser.add_argument("default-view", "month",
                        ["month", "basicWeek", "basicDay",
                         "agendaWeek", "agendaDay"]);
    parser.add_argument("store", "none", ["none", "session", "local"]);
    parser.add_argument("ignore-url", false);

    var _ = {
        name: "calendar",
        trigger: ".pat-calendar",

        _parseSearchString: function() {
            var context = {};
            window.location.search.substr(1).split("&").forEach(function(str) {
                if (str) {
                    var keyValue = str.split("="),
                        key = keyValue[0],
                        value = decodeURIComponent(keyValue[1]);
                    if (value && (value.match(/^\[.*\]$/) ||
                                  value.match(/^\{.*\}$/))) {
                        context[key] = JSON.parse(value);
                    } else {
                        context[key] = value;
                    }
                }
            });
            return context;
        },

        init: function($el, opts) {
            opts = opts || {};
            var cfg = store.updateOptions($el[0], parser.parse($el)),
                storage = cfg.store === "none" ? null : store[cfg.store](_.name + $el[0].id);

            cfg.defaultDate = storage.get("date") || cfg.defaultDate;
            cfg.defaultView = storage.get("view") || cfg.defaultView;
            cfg.tooltip = $el.data('patCalendarTooltip');

            if (!opts.ignoreUrl) {
                var search = _._parseSearchString();
                if (search["default-date"]) {
                    cfg.defaultDate = search["default-date"];
                }
                if (search["default-view"]) {
                    cfg.defaultView = search["default-view"];
                }
            }

            var calOpts = {
                    axisFormat: cfg.timeFormat,
                    columnFormat: cfg.column,
                    defaultDate: cfg.defaultDate,
                    defaultView: cfg.defaultView,
                    droppable: true,
                    editable: true,
                    firstHour: cfg.first.hour,
                    header: false,
                    timeFormat: cfg.timeFormat,
                    titleFormat: cfg.title,
                    viewRender: _.highlightButtons,

                    // Callback functions
                    // ------------------
                    eventDrop: function(event) {
                        $.getJSON(
                            event.url,
                            { 'start': event.start.toISOString(),
                              'end': event.end.toISOString(),
                              'pat-calendar-event-drop': true
                            }
                        );
                    },
                    events: function(start, end, timezone, callback) {
                        var events = _.parseEvents($el, timezone);
                        callback(events);
                    },
                    dayClick: function () {
                        /* Allows for a tooltip (via pat-tooltip) to be shown
                         * when a user clicks on a day.
                         *
                         * The configuration is the same as pat-tooltip but
                         * appears under "data-pat-calendar-tooltip".
                         */
                        if (!cfg.tooltip) {
                            return;
                        }
                        var $el = $(this);
                        if (!$el.hasClass('pat-tooltip')) {
                            /* Retrieve the injection URL from the tooltip
                             * config data and add the day's date to its query
                             * string.
                             * Then take this data and use it to create and
                             * configure a tooltip trigger element, which is
                             * then triggered.
                             */
                            var match = cfg.tooltip.match(/url:[ ](.*?)(;|$)/),
                                data = cfg.tooltip.replace(match[0], ''),
                                url = utils.addURLQueryParameter(match[1], 'date', $(this).data('date'));
                            registry.scan($el.addClass('pat-tooltip').attr({'data-pat-tooltip': data}).attr({'href': url}));
                            $el.trigger('click.tooltip');
                        }
                    }
                };

            $el.__cfg = cfg;
            $el.__storage = storage;

            if (cfg.height !== "auto") {
                calOpts.height = cfg.height;
            }

            var dayNames = [ "su", "mo", "tu", "we", "th", "fr", "sa" ];
            if (dayNames.indexOf(cfg.first.day) >= 0) {
                calOpts.firstDay = dayNames.indexOf(cfg.first.day);
            }

            var refetch = function() {
                $el.fullCalendar("refetchEvents");
            };
            var refetch_deb = utils.debounce(refetch, 400);

            $el.on("keyup.pat-calendar", ".filter .search-text",
                   refetch_deb);
            $el.on("click.pat-calendar", ".filter .search-text[type=search]",
                   refetch_deb);
            $el.on("change.pat-calendar", ".filter select[name=state]",
                   refetch);
            $el.on("change.pat-calendar", ".filter .check-list",
                   refetch);

            $el.categories = $el.find(".cal-events .cal-event")
                .map(function() {
                    return this.className.split(" ").filter(function(cls) {
                        return (/^cal-cat/).test(cls);
                    });
                });

            var $categoryRoot = cfg.categoryControls ?
                    $(cfg.categoryControls) : $el;

            $el.$catControls = $categoryRoot.find("input[type=checkbox]");
            $el.$catControls.on("change.pat-calendar", refetch);

            var $controlRoot = cfg.calendarControls ?
                    $(cfg.calendarControls) : $el;
            $el.$controlRoot = $controlRoot;
            calOpts.timezone = $controlRoot.find("select.timezone").val();

            $el.fullCalendar(calOpts);
            // move to end of $el
            $el.find(".fc-content").appendTo($el);

            if (cfg.height === "auto") {
                $el.fullCalendar("option", "height",
                    $el.find(".fc-content").height());

                $(window).on("resize.pat-calendar", function() {
                    $el.fullCalendar("option", "height",
                        $el.find(".fc-content").height());
                });
                $(document).on("pat-update.pat-calendar", function() {
                    $el.fullCalendar("option", "height",
                        $el.find(".fc-content").height());
                });
            }

            // update title
            var $title = $el.find(".cal-title");
            $title.text($el.fullCalendar("getView").title);

            var classMap = {
                month: ".view-month",
                agendaWeek: ".view-week",
                agendaDay: ".view-day"
            };

            $controlRoot.find(classMap[calOpts.defaultView]).addClass("active");

            $controlRoot.on("click.pat-calendar", ".jump-next", function() {
                $el.fullCalendar("next");
                _._viewChanged($el);
            });
            $controlRoot.on("click.pat-calendar", ".jump-prev", function() {
                $el.fullCalendar("prev");
                _._viewChanged($el);
            });
            $controlRoot.on("click.pat-calendar", ".jump-today", function() {
                $el.fullCalendar("today");
                _._viewChanged($el);
            });
            $controlRoot.on("click.pat-calendar", ".view-month", function() {
                $el.fullCalendar("changeView", "month");
                _._viewChanged($el);
            });
            $controlRoot.on("click.pat-calendar", ".view-week", function() {
                $el.fullCalendar("changeView", "agendaWeek");
                _._viewChanged($el);
            });
            $controlRoot.on("click.pat-calendar", ".view-day", function() {
                $el.fullCalendar("changeView", "agendaDay");
                _._viewChanged($el);
            });
            $controlRoot.on("change.pat-calendar", "select.timezone", function(ev) {
                _.destroy($el);
                _.init($el, {ignoreUrl: true});
            });

            $el.find(".cal-events").css("display", "none");
        },

        destroy: function($el) {
            $el.off(".pat-calendar");
            $el.$catControls.off(".pat-calendar");
            $el.$controlRoot.off(".pat-calendar");
            $(window).off(".pat-calendar");
            $(document).off(".pat-calendar");
            $(".cal-events .cal-event").off(".pat-calendar");
            $el.fullCalendar("destroy");
        },

        _viewChanged: function($el) {
            // update title
            var $title = $el.find(".cal-title");
            $title.html($el.fullCalendar("getView").title);

            // adjust height
            if ($el.__cfg.height === "auto") {
                $el.fullCalendar("option", "height",
                                 $el.find(".fc-content").height());
            }

            // store current date and view
            var date = $el.fullCalendar("getDate").format(),
                view = $el.fullCalendar("getView").name;

            $el.__storage.set("date", date);
            $el.__storage.set("view", view);
        },

        highlightButtons: function(view, element) {
            var $el = element.parents(".pat-calendar").first(),
                $body = element.parents("body").first(),
                $today = $el.find(".jump-today");
            $today.removeClass("active");
            if (view.name === "agendaDay") {
                var calDate = $el.fullCalendar("getDate"),
                    today = $.fullCalendar.moment();
                if (calDate.date() === today.date() &&
                    calDate.month() === today.month() &&
                    calDate.year() === today.year()) {
                    $today.addClass("active");
                }
            }

            var classMap = {
                month: ".view-month",
                agendaWeek: ".view-week",
                agendaDay: ".view-day"
            };
            $body.find(".view-month").removeClass("active");
            $body.find(".view-week").removeClass("active");
            $body.find(".view-day").removeClass("active");
            $body.find(classMap[view.name]).addClass("active");
        },

        parseEvents: function($el, timezone) {
            var $events = $el.find(".cal-events"),
                $filter = $el.find(".filter"),
                searchText,
                regex;

            // parse filters
            if ($filter && $filter.length > 0) {
                searchText = $(".search-text", $filter).val();
                regex = new RegExp(searchText, "i");
            }

            var shownCats = $el.categories.filter(function() {
                var cat = this;
                return $el.$catControls.filter(function() {
                    return this.checked &&
                        $(this)
                            .parents()
                            .andSelf()
                            .hasClass(cat);
                }).length;
            });

            var events = $events.find(".cal-event").filter(function() {
                var $event = $(this);

                if (searchText && !regex.test($event.find(".title").text())) {
                    log.debug("remove due to search-text="+searchText, $event);
                    return false;
                }

                return shownCats.filter(function() {
                    return $event.hasClass(this);
                }).length;
            }).map(function(idx, event) {
                var attr, i;

                // classNames: all event classes without "event" + anchor classes
                var classNames = $(event).attr("class").split(/\s+/)
                    .filter(function(cls) { return (cls !== "cal-event"); })
                    .concat($("a", event).attr("class").split(/\s+/));

                // attrs: all "data-" attrs from anchor
                var allattrs = $("a", event)[0].attributes,
                    attrs = {};
                for (attr, i=0; i<allattrs.length; i++){
                    attr = allattrs.item(i);
                    if (attr.nodeName.slice(0,5) === "data-") {
                        attrs[attr.nodeName] = attr.nodeValue;
                    }
                }

                var location = ($(".location", event).html() || "").trim();
                var startstr = $(".start", event).attr("datetime"),
                    endstr = $(".end", event).attr("datetime"),
                    start = $.fullCalendar.moment.parseZone(startstr),
                    end = $.fullCalendar.moment.parseZone(endstr);

                if (timezone) {
                    start = start.tz(timezone);
                    end = end.tz(timezone);
                }
                var ev = {
                    title: $(".title", event).text().trim() +
                        (location ? (" (" + location + ")") : ""),
                    start: start.format(),
                    end: end.format(),
                    allDay: $(event).hasClass("all-day"),
                    url: $("a", event).attr("href"),
                    className: classNames,
                    attrs: attrs,
                    editable: true // FIXME: $(event).hasClass("editable")
                };
                if (!ev.title) {
                    log.error("No event title for:", event);
                }
                if (!ev.start) {
                    log.error("No event start for:", event);
                }
                if (!ev.url) {
                    log.error("No event url for:", event);
                }
                return ev;
            }).toArray();
            return events;
        }
    };
    registry.register(_);
});
// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<commit_msg>No functionality changes. Just refactored to make init smaller<commit_after>/**
 * Patterns calendar - Calendar with different views for patterns.
 *
 * Copyright 2013-2014 Marko Durkovic
 * Copyright 2014 Florian Friesdorf
 * Copyright 2014 Syslab.com GmbH
 */
define([
    "jquery",
    "pat-logger",
    "pat-parser",
    "pat-store",
    "pat-utils",
    "pat-registry",
    "pat-calendar-moment-timezone-data",
    "jquery.fullcalendar.dnd",
    "jquery.fullcalendar"
], function($, logger, Parser, store, utils, registry) {
    "use strict";
    var log = logger.getLogger("calendar"),
        parser = new Parser("calendar");

    parser.add_argument("height", "auto");
    parser.add_argument("start-date");
    parser.add_argument("time-format", "h(:mm)t");
    parser.add_argument("title-month", "MMMM YYYY");
    parser.add_argument("title-week", "MMM D YYYY");
    parser.add_argument("title-day", "dddd, MMM d, YYYY");
    parser.add_argument("column-month", "ddd");
    parser.add_argument("column-week", "ddd M/d");
    parser.add_argument("column-day", "dddd M/d");
    parser.add_argument("first-day", "0");
    parser.add_argument("first-hour", "6");
    parser.add_argument("calendar-controls", "");
    parser.add_argument("category-controls", "");
    parser.add_argument("default-view", "month",
                        ["month", "basicWeek", "basicDay",
                         "agendaWeek", "agendaDay"]);
    parser.add_argument("store", "none", ["none", "session", "local"]);
    parser.add_argument("ignore-url", false);

    var calendar = {
        name: "calendar",
        trigger: ".pat-calendar",

        _parseSearchString: function() {
            var context = {};
            window.location.search.substr(1).split("&").forEach(function(str) {
                if (str) {
                    var keyValue = str.split("="),
                        key = keyValue[0],
                        value = decodeURIComponent(keyValue[1]);
                    if (value && (value.match(/^\[.*\]$/) ||
                                  value.match(/^\{.*\}$/))) {
                        context[key] = JSON.parse(value);
                    } else {
                        context[key] = value;
                    }
                }
            });
            return context;
        },

        init: function($el, opts) {
            opts = opts || {};
            var cfg = store.updateOptions($el[0], parser.parse($el)),
                storage = cfg.store === "none" ? null : store[cfg.store](calendar.name + $el[0].id);
            calendar.cfg = cfg;
            calendar.storage = storage;
            cfg.defaultDate = storage.get("date") || cfg.defaultDate;
            cfg.defaultView = storage.get("view") || cfg.defaultView;
            cfg.tooltip = $el.data('patCalendarTooltip');

            if (!opts.ignoreUrl) {
                var search = calendar._parseSearchString();
                if (search["default-date"]) {
                    cfg.defaultDate = search["default-date"];
                }
                if (search["default-view"]) {
                    cfg.defaultView = search["default-view"];
                }
            }

            var calOpts = {
                    axisFormat: cfg.timeFormat,
                    columnFormat: cfg.column,
                    defaultDate: cfg.defaultDate,
                    defaultView: cfg.defaultView,
                    droppable: true,
                    editable: true,
                    firstHour: cfg.first.hour,
                    header: false,
                    timeFormat: cfg.timeFormat,
                    titleFormat: cfg.title,
                    viewRender: calendar.highlightButtons,
                    height: cfg.height !== "auto" ? cfg.height : undefined,

                    // Callback functions
                    // ------------------
                    eventDrop: function(event) {
                        $.getJSON(
                            event.url,
                            { 'start': event.start.toISOString(),
                              'end': event.end.toISOString(),
                              'pat-calendar-event-drop': true
                            }
                        );
                    },
                    events: function(start, end, timezone, callback) {
                        var events = calendar.parseEvents($el, timezone);
                        callback(events);
                    },
                    dayClick: function () {
                        /* Allows for a tooltip (via pat-tooltip) to be shown
                         * when a user clicks on a day.
                         *
                         * The configuration is the same as pat-tooltip but
                         * appears under "data-pat-calendar-tooltip".
                         */
                        if (!cfg.tooltip) {
                            return;
                        }
                        var $el = $(this);
                        if (!$el.hasClass('pat-tooltip')) {
                            /* Retrieve the injection URL from the tooltip
                             * config data and add the day's date to its query
                             * string.
                             * Then take this data and use it to create and
                             * configure a tooltip trigger element, which is
                             * then triggered.
                             */
                            var match = cfg.tooltip.match(/url:[ ](.*?)(;|$)/),
                                data = cfg.tooltip.replace(match[0], ''),
                                url = utils.addURLQueryParameter(match[1], 'date', $(this).data('date'));
                            registry.scan($el.addClass('pat-tooltip').attr({'data-pat-tooltip': data}).attr({'href': url}));
                            $el.trigger('click.tooltip');
                        }
                    }
                };

            var dayNames = [ "su", "mo", "tu", "we", "th", "fr", "sa" ];
            if (dayNames.indexOf(cfg.first.day) >= 0) {
                calOpts.firstDay = dayNames.indexOf(cfg.first.day);
            }

            $el.categories = $el.find(".cal-events .cal-event")
                .map(function() {
                    return this.className.split(" ").filter(function(cls) {
                        return (/^cal-cat/).test(cls);
                    });
                });

            calendar._registerEventRefetchers($el);
            calendar._registerCategoryControls($el);

            var $controlRoot = cfg.calendarControls ?
                    $(cfg.calendarControls) : $el;
            $el.$controlRoot = $controlRoot;
            calOpts.timezone = $controlRoot.find("select.timezone").val();

            $el.fullCalendar(calOpts);
            // move to end of $el
            $el.find(".fc-content").appendTo($el);

            if (cfg.height === "auto") {
                $el.fullCalendar("option", "height",
                    $el.find(".fc-content").height());

                $(window).on("resize.pat-calendar", function() {
                    $el.fullCalendar("option", "height",
                        $el.find(".fc-content").height());
                });
                $(document).on("pat-update.pat-calendar", function() {
                    $el.fullCalendar("option", "height",
                        $el.find(".fc-content").height());
                });
            }

            // update title
            var $title = $el.find(".cal-title");
            $title.text($el.fullCalendar("getView").title);

            var classMap = {
                month: ".view-month",
                agendaWeek: ".view-week",
                agendaDay: ".view-day"
            };
            $el.$controlRoot.find(classMap[calOpts.defaultView]).addClass("active");

            calendar._registerCalendarControls($el);
            $el.find(".cal-events").css("display", "none");
        },

        _refetchEvents: function($el) {
            $el.fullCalendar("refetchEvents");
        },

        _registerEventRefetchers: function($el) {
            /* Register handlers for those IO events that necessitate a refetching
             * of the calendar's event objects.
             */
            $el.on("keyup.pat-calendar", ".filter .search-text",
                   utils.debounce(calendar._refetchEvents.bind(calendar, $el), 400));
            $el.on("click.pat-calendar", ".filter .search-text[type=search]",
                   utils.debounce(calendar._refetchEvents.bind(calendar, $el), 400));
            $el.on("change.pat-calendar", ".filter select[name=state]",
                   calendar._refetchEvents.bind(calendar, $el));
            $el.on("change.pat-calendar", ".filter .check-list",
                   calendar._refetchEvents.bind(calendar, $el));
        },

        _registerCategoryControls: function($el) {
            /* The "category controls" are checkboxes that cause different
             * types of events to be shown or hidden.
             *
             * Configured via the "category-controls" parser argument.
             *
             * Events will be refetched.
             */
            var $categoryRoot = calendar.cfg.categoryControls ?
                    $(calendar.cfg.categoryControls) : $el;
            $el.$catControls = $categoryRoot.find("input[type=checkbox]");
            $el.$catControls.on("change.pat-calendar", calendar._refetchEvents.bind(calendar, $el));
        },

        _registerCalendarControls: function($el) {
            /* Register handlers for the calendar control elements.
             *
             * Configured via the "calendar-controls" parser argument.
             */
            $el.$controlRoot.on("click.pat-calendar", ".jump-next", function() {
                $el.fullCalendar("next");
                calendar._viewChanged($el);
            });
            $el.$controlRoot.on("click.pat-calendar", ".jump-prev", function() {
                $el.fullCalendar("prev");
                calendar._viewChanged($el);
            });
            $el.$controlRoot.on("click.pat-calendar", ".jump-today", function() {
                $el.fullCalendar("today");
                calendar._viewChanged($el);
            });
            $el.$controlRoot.on("click.pat-calendar", ".view-month", function() {
                $el.fullCalendar("changeView", "month");
                calendar._viewChanged($el);
            });
            $el.$controlRoot.on("click.pat-calendar", ".view-week", function() {
                $el.fullCalendar("changeView", "agendaWeek");
                calendar._viewChanged($el);
            });
            $el.$controlRoot.on("click.pat-calendar", ".view-day", function() {
                $el.fullCalendar("changeView", "agendaDay");
                calendar._viewChanged($el);
            });
            $el.$controlRoot.on("change.pat-calendar", "select.timezone", function(ev) {
                calendar.destroy($el);
                calendar.init($el, {ignoreUrl: true});
            });
        },

        destroy: function($el) {
            $el.off(".pat-calendar");
            $el.$catControls.off(".pat-calendar");
            $el.$controlRoot.off(".pat-calendar");
            $(window).off(".pat-calendar");
            $(document).off(".pat-calendar");
            $(".cal-events .cal-event").off(".pat-calendar");
            $el.fullCalendar("destroy");
        },

        _viewChanged: function($el) {
            // update title
            var $title = $el.find(".cal-title");
            $title.html($el.fullCalendar("getView").title);
            // adjust height
            if (calendar.cfg.height === "auto") {
                $el.fullCalendar("option", "height",
                                 $el.find(".fc-content").height());
            }
            // store current date and view
            var date = $el.fullCalendar("getDate").format(),
                view = $el.fullCalendar("getView").name;
            calendar.storage.set("date", date);
            calendar.storage.set("view", view);
        },

        highlightButtons: function(view, element) {
            var $el = element.parents(".pat-calendar").first(),
                $body = element.parents("body").first(),
                $today = $el.find(".jump-today");
            $today.removeClass("active");
            if (view.name === "agendaDay") {
                var calDate = $el.fullCalendar("getDate"),
                    today = $.fullCalendar.moment();
                if (calDate.date() === today.date() &&
                    calDate.month() === today.month() &&
                    calDate.year() === today.year()) {
                    $today.addClass("active");
                }
            }

            var classMap = {
                month: ".view-month",
                agendaWeek: ".view-week",
                agendaDay: ".view-day"
            };
            $body.find(".view-month").removeClass("active");
            $body.find(".view-week").removeClass("active");
            $body.find(".view-day").removeClass("active");
            $body.find(classMap[view.name]).addClass("active");
        },

        parseEvents: function($el, timezone) {
            var $events = $el.find(".cal-events"),
                $filter = $el.find(".filter"),
                searchText,
                regex;

            // parse filters
            if ($filter && $filter.length > 0) {
                searchText = $(".search-text", $filter).val();
                regex = new RegExp(searchText, "i");
            }

            var shownCats = $el.categories.filter(function() {
                var cat = this;
                return $el.$catControls.filter(function() {
                    return this.checked &&
                        $(this)
                            .parents()
                            .andSelf()
                            .hasClass(cat);
                }).length;
            });

            var events = $events.find(".cal-event").filter(function() {
                var $event = $(this);

                if (searchText && !regex.test($event.find(".title").text())) {
                    log.debug("remove due to search-text="+searchText, $event);
                    return false;
                }

                return shownCats.filter(function() {
                    return $event.hasClass(this);
                }).length;
            }).map(function(idx, event) {
                var attr, i;

                // classNames: all event classes without "event" + anchor classes
                var classNames = $(event).attr("class").split(/\s+/)
                    .filter(function(cls) { return (cls !== "cal-event"); })
                    .concat($("a", event).attr("class").split(/\s+/));

                // attrs: all "data-" attrs from anchor
                var allattrs = $("a", event)[0].attributes,
                    attrs = {};
                for (attr, i=0; i<allattrs.length; i++){
                    attr = allattrs.item(i);
                    if (attr.nodeName.slice(0,5) === "data-") {
                        attrs[attr.nodeName] = attr.nodeValue;
                    }
                }

                var location = ($(".location", event).html() || "").trim();
                var startstr = $(".start", event).attr("datetime"),
                    endstr = $(".end", event).attr("datetime"),
                    start = $.fullCalendar.moment.parseZone(startstr),
                    end = $.fullCalendar.moment.parseZone(endstr);

                if (timezone) {
                    start = start.tz(timezone);
                    end = end.tz(timezone);
                }
                var ev = {
                    title: $(".title", event).text().trim() +
                        (location ? (" (" + location + ")") : ""),
                    start: start.format(),
                    end: end.format(),
                    allDay: $(event).hasClass("all-day"),
                    url: $("a", event).attr("href"),
                    className: classNames,
                    attrs: attrs,
                    editable: true // FIXME: $(event).hasClass("editable")
                };
                if (!ev.title) {
                    log.error("No event title for:", event);
                }
                if (!ev.start) {
                    log.error("No event start for:", event);
                }
                if (!ev.url) {
                    log.error("No event url for:", event);
                }
                return ev;
            }).toArray();
            return events;
        }
    };
    registry.register(calendar);
});
// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<|endoftext|>


<commit_before>/***/
// [noleak-emitter-js] NoleakEmitter.js
(function(has_win, has_mod) {

  if(typeof Emitter == 'undefined')
    throw new Error('NoleakEmitter requires "Emitter" on global-scope');

  var processor = typeof setImmediate == 'undefined' ? function(fn) {
    setTimeout(fn, r)
  }: setImmediate;

  has_mod && (module.exports = NoleakEmitter);
  has_win && (window.NoleakEmitter = NoleakEmitter);

  function NoleakEmitter() {
    var emitter = this;

    Emitter.call(emitter);
    emitter.on('error', careLeak).on('end', careLeak);

    function careLeak() {
      processor(function() {
        if(emitter == null)
          return;

        // Like Node
        if(typeof emitter.removeAllListeners == 'function')
          emitter.removeAllListeners();

        // jQuery Oriented API
        if(typeof emitter.off == 'function')
          emitter.off();

        emitter = null;
      });
    }

  }
  for( var i in Emitter.prototype)
    NoleakEmitter.prototype[i] = Emitter.prototype[i];

})(typeof window != 'undefined', typeof module != 'undefined');
<commit_msg>bugfix<commit_after>/***/
// [noleak-emitter-js] NoleakEmitter.js
(function(has_win, has_mod) {

  if(typeof Emitter == 'undefined')
    throw new Error('NoleakEmitter requires "Emitter" on global-scope');

  var processor = typeof setImmediate == 'undefined' ? function(fn) {
    setTimeout(fn, 4)
  }: setImmediate;

  has_mod && (module.exports = NoleakEmitter);
  has_win && (window.NoleakEmitter = NoleakEmitter);

  function NoleakEmitter() {
    var emitter = this;

    Emitter.call(emitter);
    emitter.on('error', careLeak).on('end', careLeak);

    function careLeak() {
      processor(function() {
        if(emitter == null)
          return;

        // Like Node
        if(typeof emitter.removeAllListeners == 'function')
          emitter.removeAllListeners();

        // jQuery Oriented API
        if(typeof emitter.off == 'function')
          emitter.off();

        emitter = null;
      });
    }

  }
  for( var i in Emitter.prototype)
    NoleakEmitter.prototype[i] = Emitter.prototype[i];

})(typeof window != 'undefined', typeof module != 'undefined');
<|endoftext|>


<commit_before>var fs = require('fs');

describe('The assets copied from the src/static directory...', function() {

    it('Should include a favicon file', function(done) {
        fs.stat('build/favicon.ico', function(err, stats) {
            if (err) throw err;
            done();
        });
    });

    it('Should include a robots.txt file', function(done) {
        fs.stat('build/robots.txt', function(err, stats) {
            if (err) throw err;
            done();
        });
    });

});<commit_msg>Adding image check to static tests<commit_after>var assert = require('assert'),
    fs     = require('fs');

describe('The assets copied from the src/static directory...', function() {

    it('Should include a favicon file', function(done) {
        fs.stat('build/favicon.ico', function(err, stats) {
            if (err) throw err;
            done();
        });
    });

    it('Should include ALL images in /img', function(done) {
        fs.readdir('build/img', function(err, built) {
            if (err) throw err;
            fs.readdir('src/static/img', function(err, source) {
                if (err) throw err;
                assert.deepEqual(built, source);
                done();
            });
        });
    });

});<|endoftext|>


<commit_before>
var connect = require('../');

var fixtures = __dirname + '/fixtures';

var app = connect();
app.use(connect.static(fixtures));

app.use(function(req, res){
  res.statusCode = 404;
  res.end('sorry!');
});

describe('connect.static()', function(){
  it('should serve static files', function(done){
    app.request()
    .get('/todo.txt')
    .expect('- groceries', done);
  })

  it('should support nesting', function(done){
    app.request()
    .get('/users/tobi.txt')
    .expect('ferret', done);
  })

  it('should set Content-Type', function(done){
    app.request()
    .get('/todo.txt')
    .expect('Content-Type', 'text/plain; charset=UTF-8', done);
  })

  it('should default max-age=0', function(done){
    app.request()
    .get('/todo.txt')
    .expect('Cache-Control', 'public, max-age=0', done);
  })

  it('should support urlencoded pathnames', function(done){
    app.request()
    .get('/foo%20bar')
    .expect('baz', done);
  })

  it('should not choke on auth-looking URL', function(done){
    app.request()
    .get('//todo@txt')
    .expect(404, done);
  })

  it('should redirect directories with query string', function (done) {
    app.request()
    .get('/users?name=john')
    .expect('Location', '/users/?name=john', done);
  })

  it('should redirect directories', function(done){
    app.request()
    .get('/users')
    .expect(303, done);
  })

  it('should not redirect incorrectly', function (done) {
    app.request()
    .get('/')
    .expect(404, done);
  });

  it('should support index.html', function(done){
    app.request()
    .get('/users/')
    .end(function(res){
      res.body.should.equal('
tobi, loki, jane
');
      res.headers.should.have.property('content-type', 'text/html; charset=UTF-8');
      done();
    })
  })

  it('should support ../', function(done){
    app.request()
    .get('/users/../todo.txt')
    .expect('- groceries', done);
  })

  it('should support HEAD', function(done){
    app.request()
    .head('/todo.txt')
    .expect('', done);
  })

  it('should support conditional requests', function(done){
    app.request()
    .get('/todo.txt')
    .end(function(res){
      app.request()
      .get('/todo.txt')
      .set('If-None-Match', res.headers.etag)
      .expect(304, done);
    });
  })

  describe('hidden files', function(){
    it('should be ignored by default', function(done){
      app.request()
      .get('/.hidden')
      .expect(404, done);
    })

    it('should be served when hidden: true is given', function(done){
      var app = connect();

      app.use(connect.static(fixtures, { hidden: true }));

      app.request()
      .get('/.hidden')
      .expect('I am hidden', done);
    })
  })

  describe('maxAge', function(){
    it('should be 0 by default', function(done){
      app.request()
      .get('/todo.txt')
      .end(function(res){
        res.should.have.header('cache-control', 'public, max-age=0');
        done();
      });
    })

    it('should be reasonable when infinite', function(done){
      var app = connect();

      app.use(connect.static(fixtures, { maxAge: Infinity }));

      app.request()
      .get('/todo.txt')
      .end(function(res){
        res.should.have.header('cache-control', 'public, max-age=' + 60*60*24*365);
        done();
      });
    })
  })

  describe('when traversing passed root', function(){
    it('should respond with 403 Forbidden', function(done){
      app.request()
      .get('/users/../../todo.txt')
      .expect(403, done);
    })

    it('should catch urlencoded ../', function(done){
      app.request()
      .get('/users/%2e%2e/%2e%2e/todo.txt')
      .expect(403, done);
    })
  })

  describe('on ENOENT', function(){
    it('should next()', function(done){
      app.request()
      .get('/does-not-exist')
      .end(function(res){
        res.should.have.status(404);
        res.body.should.equal('sorry!');
        done();
      });
    })
  })

  describe('Range', function(){
    it('should support byte ranges', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=0-4')
      .expect('12345', done);
    })

    it('should be inclusive', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=0-0')
      .expect('1', done);
    })

    it('should set Content-Range', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=2-5')
      .expect('Content-Range', 'bytes 2-5/9', done);
    })

    it('should support -n', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=-3')
      .expect('789', done);
    })

    it('should support n-', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=3-')
      .expect('456789', done);
    })

    it('should respond with 206 "Partial Content"', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=0-4')
      .expect(206, done);
    })

    it('should set Content-Length to the # of octets transferred', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=2-3')
      .end(function(res){
        res.body.should.equal('34');
        res.headers['content-length'].should.equal('2');
        done();
      });
    })

    describe('when last-byte-pos of the range is greater than current length', function(){
      it('is taken to be equal to one less than the current length', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'bytes=2-50')
        .expect('Content-Range', 'bytes 2-8/9', done)
      })

      it('should adapt the Content-Length accordingly', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'bytes=2-50')
        .end(function(res){
          res.headers['content-length'].should.equal('7');
          done();
        });
      })
    })

    describe('when the first- byte-pos of the range is greater than the current length', function(){
      it('should respond with 416', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'bytes=9-50')
        .expect(416, done);
      })

      it('should include a Content-Range field with a byte-range- resp-spec of "*" and an instance-length specifying the current length', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'bytes=9-50')
        .expect('Content-Range', 'bytes */9', done)
      })
    })

    describe('when syntactically invalid', function(){
      it('should respond with 200 and the entire contents', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'asdf')
        .expect('123456789', done);
      })
    })
  })

  describe('when a trailing backslash is given', function(){
    if (connect.utils.brokenPause) {
      // https://github.com/senchalabs/connect/issues/452
      it('should 500 in node < 0.10 because fs.stat is broken', function(done){
        app.request()
        .get('/todo.txt\\')
        .expect(500, done);
      })
    } else {
      it('should 404 as expected in node >= 0.10', function(done){
        app.request()
        .get('/todo.txt\\')
        .expect(404, done);
      })
    }
  })

  describe('with a malformed URL', function(){
    it('should respond with 400', function(done){
      app.request()
      .get('/%')
      .expect(400, done)
    });
  })

  describe('on ENAMETOOLONG', function(){
    it('should next()', function(done){
      var path = Array(100).join('foobar');

      app.request()
      .get('/' + path)
      .expect(404, done);
    })
  })

  describe('on ENOTDIR', function(){
    it('should next()', function(done) {
      app.request()
      .get('/todo.txt/a.php')
      .expect(404, done);
    })
  })

  describe('when mounted', function(){
    it('should redirect when index at mount point', function (done) {
      var app = connect();

      app.use('/users', connect.static('test/fixtures/users'));

      app.request()
      .get('/users')
      .end(function (res) {
        res.should.have.status(303);
        res.headers.location.should.equal('/users/');
        done();
      });
    });

    it('should redirect relative to the originalUrl', function(done){
      var app = connect();

      app.use('/static', connect.static('test/fixtures'));

      app.request()
      .get('/static/users')
      .end(function(res){
        res.headers.location.should.equal('/static/users/');
        res.should.have.status(303);
        done();
      });
    })
  })

  describe('when responding non-2xx or 304', function(){
    it('should respond as-is', function(done){
      var app = connect();
      var n = 0;

      app.use(function(req, res, next){
        switch (n++) {
          case 0: return next();
          case 1: res.statusCode = 500; return next();
        }
      });

      app.use(connect.static(fixtures));

      app.request()
      .get('/todo.txt')
      .end(function(res){
        app.request()
        .get('/todo.txt')
        .set('If-None-Match', res.headers.etag)
        .end(function(res){
          res.should.have.status(500);
          res.body.should.equal('- groceries');
          done();
        })
      })
    })
  })
})
<commit_msg>tests: remove test that doesn't work on windows<commit_after>
var connect = require('../');

var fixtures = __dirname + '/fixtures';

var app = connect();
app.use(connect.static(fixtures));

app.use(function(req, res){
  res.statusCode = 404;
  res.end('sorry!');
});

describe('connect.static()', function(){
  it('should serve static files', function(done){
    app.request()
    .get('/todo.txt')
    .expect('- groceries', done);
  })

  it('should support nesting', function(done){
    app.request()
    .get('/users/tobi.txt')
    .expect('ferret', done);
  })

  it('should set Content-Type', function(done){
    app.request()
    .get('/todo.txt')
    .expect('Content-Type', 'text/plain; charset=UTF-8', done);
  })

  it('should default max-age=0', function(done){
    app.request()
    .get('/todo.txt')
    .expect('Cache-Control', 'public, max-age=0', done);
  })

  it('should support urlencoded pathnames', function(done){
    app.request()
    .get('/foo%20bar')
    .expect('baz', done);
  })

  it('should not choke on auth-looking URL', function(done){
    app.request()
    .get('//todo@txt')
    .expect(404, done);
  })

  it('should redirect directories with query string', function (done) {
    app.request()
    .get('/users?name=john')
    .expect('Location', '/users/?name=john', done);
  })

  it('should redirect directories', function(done){
    app.request()
    .get('/users')
    .expect(303, done);
  })

  it('should not redirect incorrectly', function (done) {
    app.request()
    .get('/')
    .expect(404, done);
  });

  it('should support index.html', function(done){
    app.request()
    .get('/users/')
    .end(function(res){
      res.body.should.equal('
tobi, loki, jane
');
      res.headers.should.have.property('content-type', 'text/html; charset=UTF-8');
      done();
    })
  })

  it('should support ../', function(done){
    app.request()
    .get('/users/../todo.txt')
    .expect('- groceries', done);
  })

  it('should support HEAD', function(done){
    app.request()
    .head('/todo.txt')
    .expect('', done);
  })

  it('should support conditional requests', function(done){
    app.request()
    .get('/todo.txt')
    .end(function(res){
      app.request()
      .get('/todo.txt')
      .set('If-None-Match', res.headers.etag)
      .expect(304, done);
    });
  })

  describe('hidden files', function(){
    it('should be ignored by default', function(done){
      app.request()
      .get('/.hidden')
      .expect(404, done);
    })

    it('should be served when hidden: true is given', function(done){
      var app = connect();

      app.use(connect.static(fixtures, { hidden: true }));

      app.request()
      .get('/.hidden')
      .expect('I am hidden', done);
    })
  })

  describe('maxAge', function(){
    it('should be 0 by default', function(done){
      app.request()
      .get('/todo.txt')
      .end(function(res){
        res.should.have.header('cache-control', 'public, max-age=0');
        done();
      });
    })

    it('should be reasonable when infinite', function(done){
      var app = connect();

      app.use(connect.static(fixtures, { maxAge: Infinity }));

      app.request()
      .get('/todo.txt')
      .end(function(res){
        res.should.have.header('cache-control', 'public, max-age=' + 60*60*24*365);
        done();
      });
    })
  })

  describe('when traversing passed root', function(){
    it('should respond with 403 Forbidden', function(done){
      app.request()
      .get('/users/../../todo.txt')
      .expect(403, done);
    })

    it('should catch urlencoded ../', function(done){
      app.request()
      .get('/users/%2e%2e/%2e%2e/todo.txt')
      .expect(403, done);
    })
  })

  describe('on ENOENT', function(){
    it('should next()', function(done){
      app.request()
      .get('/does-not-exist')
      .end(function(res){
        res.should.have.status(404);
        res.body.should.equal('sorry!');
        done();
      });
    })
  })

  describe('Range', function(){
    it('should support byte ranges', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=0-4')
      .expect('12345', done);
    })

    it('should be inclusive', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=0-0')
      .expect('1', done);
    })

    it('should set Content-Range', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=2-5')
      .expect('Content-Range', 'bytes 2-5/9', done);
    })

    it('should support -n', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=-3')
      .expect('789', done);
    })

    it('should support n-', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=3-')
      .expect('456789', done);
    })

    it('should respond with 206 "Partial Content"', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=0-4')
      .expect(206, done);
    })

    it('should set Content-Length to the # of octets transferred', function(done){
      app.request()
      .get('/nums')
      .set('Range', 'bytes=2-3')
      .end(function(res){
        res.body.should.equal('34');
        res.headers['content-length'].should.equal('2');
        done();
      });
    })

    describe('when last-byte-pos of the range is greater than current length', function(){
      it('is taken to be equal to one less than the current length', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'bytes=2-50')
        .expect('Content-Range', 'bytes 2-8/9', done)
      })

      it('should adapt the Content-Length accordingly', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'bytes=2-50')
        .end(function(res){
          res.headers['content-length'].should.equal('7');
          done();
        });
      })
    })

    describe('when the first- byte-pos of the range is greater than the current length', function(){
      it('should respond with 416', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'bytes=9-50')
        .expect(416, done);
      })

      it('should include a Content-Range field with a byte-range- resp-spec of "*" and an instance-length specifying the current length', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'bytes=9-50')
        .expect('Content-Range', 'bytes */9', done)
      })
    })

    describe('when syntactically invalid', function(){
      it('should respond with 200 and the entire contents', function(done){
        app.request()
        .get('/nums')
        .set('Range', 'asdf')
        .expect('123456789', done);
      })
    })
  })

  describe('with a malformed URL', function(){
    it('should respond with 400', function(done){
      app.request()
      .get('/%')
      .expect(400, done)
    });
  })

  describe('on ENAMETOOLONG', function(){
    it('should next()', function(done){
      var path = Array(100).join('foobar');

      app.request()
      .get('/' + path)
      .expect(404, done);
    })
  })

  describe('on ENOTDIR', function(){
    it('should next()', function(done) {
      app.request()
      .get('/todo.txt/a.php')
      .expect(404, done);
    })
  })

  describe('when mounted', function(){
    it('should redirect when index at mount point', function (done) {
      var app = connect();

      app.use('/users', connect.static('test/fixtures/users'));

      app.request()
      .get('/users')
      .end(function (res) {
        res.should.have.status(303);
        res.headers.location.should.equal('/users/');
        done();
      });
    });

    it('should redirect relative to the originalUrl', function(done){
      var app = connect();

      app.use('/static', connect.static('test/fixtures'));

      app.request()
      .get('/static/users')
      .end(function(res){
        res.headers.location.should.equal('/static/users/');
        res.should.have.status(303);
        done();
      });
    })
  })

  describe('when responding non-2xx or 304', function(){
    it('should respond as-is', function(done){
      var app = connect();
      var n = 0;

      app.use(function(req, res, next){
        switch (n++) {
          case 0: return next();
          case 1: res.statusCode = 500; return next();
        }
      });

      app.use(connect.static(fixtures));

      app.request()
      .get('/todo.txt')
      .end(function(res){
        app.request()
        .get('/todo.txt')
        .set('If-None-Match', res.headers.etag)
        .end(function(res){
          res.should.have.status(500);
          res.body.should.equal('- groceries');
          done();
        })
      })
    })
  })
})
<|endoftext|>


<commit_before>// This is technically not a unit test, but an integration test.
// Since it requires connecting to a raw socket to parse data I'm
// not sure how to test the functionality without actually connecting.
// On the plus side, it's more valid of a test.

var chai = require("chai");
var expect = chai.expect;
var assert = chai.assert;

var getStreamStation = require("../lib/icystream.js").getStreamStation;
var fs = require('fs');
var main = require("../index.js");
var testStream = "http://ice1.somafm.com/groovesalad-128.mp3";

describe("handle stream data", function() {

  it("Should parse a generic stream", function(done) {

    getStreamStation(testStream, function(error, station) {
      expect(station).to.exist;
      expect(station).to.have.property('title');
      expect(station).to.have.property('fetchsource');
      expect(station).to.have.property('headers');

      expect(station.headers).to.have.property('icy-name');
      expect(station.headers).to.have.property('icy-br');
      expect(station.headers).to.have.property('content-type');

      expect(station.fetchsource).to.equal(main.StreamSource.STREAM);
      done();
    });
  });
});

describe("Handle stream redirect", function() {
  var redirectStream = "https://samcloud.spacial.com/api/listen?sid=73045&rid=155986&f=mp3,any&br=128000,any&m=sc";
  it("Should redirect and return valid data", function(done) {
    getStreamStation(redirectStream, function(error, station) {
      expect(station).to.exist;
      expect(station).to.have.property('title');
      done();
    });
  });
});
<commit_msg>Fix test<commit_after>// This is technically not a unit test, but an integration test.
// Since it requires connecting to a raw socket to parse data I'm
// not sure how to test the functionality without actually connecting.
// On the plus side, it's more valid of a test.

var chai = require("chai");
var expect = chai.expect;
var assert = chai.assert;

var getStreamStation = require("../lib/icystream.js").getStreamStation;
var fs = require('fs');
var main = require("../index.js");
var testStream = "http://sc6.easywebcommunications.com:8007/1?cb=930346.mp3";

describe("handle stream data", function () {

  it("Should parse a generic stream", function (done) {

    getStreamStation(testStream, function (error, station) {
      expect(station).to.exist;
      expect(station).to.have.property('title');
      expect(station).to.have.property('fetchsource');
      expect(station).to.have.property('headers');

      expect(station.headers).to.have.property('icy-name');
      expect(station.headers).to.have.property('icy-br');
      expect(station.headers).to.have.property('content-type');

      expect(station.fetchsource).to.equal(main.StreamSource.STREAM);
      done();
    });
  });
});

describe("Handle stream redirect", function () {
  var redirectStream = "http://listen.radionomy.com:80/WitchHouseRadiodotcom";
  it("Should redirect and return valid data", function (done) {
    getStreamStation(redirectStream, function (error, station) {
      expect(station).to.exist;
      expect(station).to.have.property('title');
      done();
    });
  });
});
<|endoftext|>


<commit_before>/* global describe, it, xit */
/* jslint node: true, esnext: true */

"use strict";

const chai = require('chai'),
  assert = chai.assert,
  expect = chai.expect,
  should = chai.should();
chai.use(require("chai-as-promised"));

const path = require('path'),
  fs = require('fs');

const testStep = require('kronos-test-step'),
  BaseStep = require('kronos-step');

const manager = testStep.managerMock;

require('../system').registerWithManager(manager);

describe('system', function () {
  const sys = manager.steps['kronos-system'].createInstance(manager, undefined, {
    name: "myStep",
    type: "kronos-system",
    command: "cat",
    args: [path.join(__dirname, 'system.js')]
  });

  const stdinEndpoint = BaseStep.createEndpoint('stdin-test', {
    "out": true,
    "active": true
  });

  stdinEndpoint.connect(sys.endpoints.stdin);

  const stdoutEndpoint = BaseStep.createEndpoint('stdout-test', {
    "in": true,
    "passive": true
  });

  let stdoutRequest;

  stdoutEndpoint.connect(sys.endpoints.stdout);

  stdoutEndpoint.receive(function* () {
    stdoutRequest = yield;
    //stdoutRequest.stream.pipe(process.stdout);
  });

  const stderrEndpoint = BaseStep.createEndpoint('stderr-test', {
    "in": true,
    "passive": true
  });

  stderrEndpoint.connect(sys.endpoints.stderr);

  let stderrRequest;

  stderrEndpoint.receive(function* () {
    stderrRequest = yield;
  });

  /*
      const commandEndpoint = BaseStep.createEndpoint('test', {
        "out": true,
        "active": true
      });

      commandEndpoint.connect(sys.endpoints.command);
    */

  describe('static', function () {
    testStep.checkStepStatic(manager, sys);
  });

  describe('live-cycle', function () {
    let wasRunning = false;
    testStep.checkStepLivecycle(manager, sys, function (step, state, livecycle, done) {
      if (state === 'running' && !wasRunning) {
        //console.log(`${state}: ${livecycle.statesHistory}`);

        const stream = fs.createReadStream(path.join(__dirname, 'system.js'), {
          encoding: 'utf8'
        });

        stdinEndpoint.send({
          stream: stream
        });

        /*
                        testCommandEndpoint.send({
                          data: [{
                            type: "stop",
                            flow: "sample"
                          }]
                        });
                */
        wasRunning = true;
      }

      if (state === 'stopped' && wasRunning) {
        assert.equal(stdoutRequest.info.command, 'cat');
      }

      done();
    });
  });
});
<commit_msg>test: prepare for multiple child processes test<commit_after>/* global describe, it, xit */
/* jslint node: true, esnext: true */

"use strict";

const chai = require('chai'),
  assert = chai.assert,
  expect = chai.expect,
  should = chai.should();
chai.use(require("chai-as-promised"));

const path = require('path'),
  fs = require('fs');

const testStep = require('kronos-test-step'),
  BaseStep = require('kronos-step');

const manager = testStep.managerMock;

require('../system').registerWithManager(manager);

describe('system', function () {
  const sys = manager.steps['kronos-system'].createInstance(manager, undefined, {
    name: "myStep",
    type: "kronos-system",
    command: "cat",
    args: ['-u' /*, path.join(__dirname, 'system.js')*/ ]
  });

  const stdinEndpoint = BaseStep.createEndpoint('stdin-test', {
    "out": true,
    "active": true
  });

  stdinEndpoint.connect(sys.endpoints.stdin);

  const stdoutEndpoint = BaseStep.createEndpoint('stdout-test', {
    "in": true,
    "passive": true
  });

  let stdoutRequest;

  stdoutEndpoint.connect(sys.endpoints.stdout);

  stdoutEndpoint.receive(function* () {
    stdoutRequest = yield;
    console.log("**** Request: ");
    //stdoutRequest.stream.pipe(process.stdout);
  });

  const stderrEndpoint = BaseStep.createEndpoint('stderr-test', {
    "in": true,
    "passive": true
  });

  stderrEndpoint.connect(sys.endpoints.stderr);

  let stderrRequest;

  stderrEndpoint.receive(function* () {
    stderrRequest = yield;
  });

  /*
      const commandEndpoint = BaseStep.createEndpoint('test', {
        "out": true,
        "active": true
      });

      commandEndpoint.connect(sys.endpoints.command);
    */

  describe('static', function () {
    testStep.checkStepStatic(manager, sys);
  });

  describe('live-cycle', function () {
    let wasRunning = false;
    testStep.checkStepLivecycle(manager, sys, function (step, state, livecycle, done) {
      if (state === 'running' && !wasRunning) {
        //console.log(`${state}: ${livecycle.statesHistory}`);

        for (let i = 0; i < 2; i++) {
          const stream = fs.createReadStream(path.join(__dirname, 'system.js'), {
            encoding: 'utf8'
          });

          stdinEndpoint.send({
            stream: stream
          });
        }

        /*
                        testCommandEndpoint.send({
                          data: [{
                            type: "stop",
                            flow: "sample"
                          }]
                        });
                */
        wasRunning = true;
      }

      if (state === 'stopped' && wasRunning) {
        assert.equal(stdoutRequest.info.command, 'cat');
      }

      done();
    });
  });
});
<|endoftext|>


<commit_before>var path          = require('path');
var fs            = require('fs');
var os            = require('os');
var system        = require('../code/system');

describe('system-level features', function() {
    it('should create a temporary directory with .init()', function() {
        var tmp = path.resolve(os.tmpdir(), 'avisynth.js-' + process.pid);
        system.cleanUp();
        if (fs.existsSync(tmp)) throw new Error('"' + tmp + '" should not exist!');
        system.init();
        if (!fs.existsSync(tmp)) throw new Error('"' + tmp + '" should exist!');
    });

    it('should remove a temporary directory with .cleanUp()', function() {
        var tmp = path.resolve(os.tmpdir(), 'avisynth.js-' + process.pid);
        system.init();
        if (!fs.existsSync(tmp)) throw new Error('"' + tmp + '" should exist!');
        system.cleanUp();
        if (fs.existsSync(tmp)) throw new Error('"' + tmp + '" should not exist!');
    });
});
<commit_msg>Extra case for cleanUp.<commit_after>var path          = require('path');
var fs            = require('fs');
var os            = require('os');
var system        = require('../code/system');

describe('system-level features', function() {
    it('should create a temporary directory with .init()', function() {
        var tmp = path.resolve(os.tmpdir(), 'avisynth.js-' + process.pid);
        system.cleanUp();
        if (fs.existsSync(tmp)) throw new Error('"' + tmp + '" should not exist!');
        system.init();
        if (!fs.existsSync(tmp)) throw new Error('"' + tmp + '" should exist!');
    });

    it('should remove a temporary directory with .cleanUp()', function() {
        var tmp = path.resolve(os.tmpdir(), 'avisynth.js-' + process.pid);
        system.init();
        if (!fs.existsSync(tmp)) throw new Error('"' + tmp + '" should exist!');
        system.cleanUp();
        system.cleanUp(); // Should not crash or something.
        if (fs.existsSync(tmp)) throw new Error('"' + tmp + '" should not exist!');
    });
});
<|endoftext|>


<commit_before>
module("");
test("hoge", function() {
	strictEqual("hoge", "hoge");
});
<commit_msg>検証用のテストケースを作成したのでコミット。<commit_after>/**
 * TODO
 *
 */
var ModulePattern2 = (function() {

	/**
	 * コンストラクタ関数。
	 *
	 * @param  {string} name
	 * @param  {integer} age
	 */
	var constructor = function(name, age) {
		this.name = name;
		this.age = age;
	};

	constructor.prototype = {
		/**
		 * TODO
		 *
		 * @return {string}
		 */
		toString: function() {
			return this.name + ":" + this.age;
		},
	};

	return constructor;

})();

module("インスタンスの生成確認");
test("コンストラクタで指定した値が取得できること", function() {
	var sut = new ModulePattern2("hoge", 30);
	strictEqual(sut.toString(), "hoge:30");

});

module("プロパティのスコープ確認");
test("プロパティは public スコープなので外部から参照できることを確認する", function() {
	var sut = new ModulePattern2("hoge", 30);
	strictEqual(sut.name, "hoge", "プロパティ name を参照できること");
	strictEqual(sut.age, 30, "プロパティ age を参照できること");

});

test("プロパティは public スコープなので外部から値を変更できることを確認する", function() {
	var sut = new ModulePattern2("hoge", 30);
	sut.name = "fuga";
	sut.age = 40;
	strictEqual(sut.toString(), "fuga:40", "コンストラクタで指定した値が変更されていること");

});

module("プロパティの非共有");
test("プロパティの値がインスタンス間で共有されないことを確認する", function() {
	var hoge30 = new ModulePattern2("hoge", 30);
	strictEqual(hoge30.toString(), "hoge:30", "コンストラクタで指定した値が取得できること");

	var fuga40 = new ModulePattern2("fuga", 40);
	strictEqual(fuga40.toString(), "fuga:40", "コンストラクタで指定した値が取得できること");

	fuga40.age = 41;
	strictEqual(hoge30.toString(), "hoge:30", "fuga の age を変更しても hoge には反映されない");

});
<|endoftext|>


<commit_before>var _ = require('underscore')
  , fs = require('fs')
  , path = require('path')
  , child = require('child_process')
  , crypto = require('crypto')
  , expect = require('expect.js')
  , SVGCleaner = require('../')
  ;

function rasterizeWithPhantom(srcFilename, targetFilename, cb) {
	var ps = child.spawn('phantomjs', ['./test/rasterize.js', 'file://' + path.resolve(srcFilename), targetFilename]);
	ps.stdout.on('data', function(data) {
      console.log("phantom stdout: " + data);
    });
    ps.stderr.on('data', function(data) {
      console.warn("phantom stderr: " + data);
    });
    ps.on('exit', function() {
    	cb();
    });
}

function getMD5Sum(filename, cb) {
	var md5sum = crypto.createHash('md5');
	var s = fs.ReadStream(filename);
	s.on('data', function(d) {
  		md5sum.update(d);
	});
	s.on('end', function() {
  		var d = md5sum.digest('hex');
  		cb(d);
	});
}

function cleanRasterCompareSvgFile(svgBeforeCleanFilename, done) {

	var svgAfterCleanFilename = svgBeforeCleanFilename + '.cleaned.svg';
	var rasterBeforeCleanFilename = svgBeforeCleanFilename + '.rastered.png';
	var rasterAfterCleanFilename = svgAfterCleanFilename +  '.rastered.png';

	SVGCleaner.cleanFile(svgBeforeCleanFilename, svgAfterCleanFilename);

	function cleanup() {
		return;
		fs.unlinkSync(svgAfterCleanFilename);
		fs.unlinkSync(rasterBeforeCleanFilename);
		fs.unlinkSync(rasterAfterCleanFilename);
	}

	var whenBothRastered = _.after(2, function() {

	  	// read both files and compare them
	  	getMD5Sum(rasterBeforeCleanFilename, function(hashBeforeClean) {
	  		getMD5Sum(rasterAfterCleanFilename, function(hashAfterClean) {
	  			cleanup();
	  			if(hashBeforeClean == hashAfterClean) {
	  				done();
	  			} else {
	  				done(new Error(
	  					svgBeforeCleanFilename + ":\n"
	  					+ "Cleaned and rastered version does not equel original and rastered version \n"
	  					 + rasterBeforeCleanFilename + ' != ' + rasterAfterCleanFilename));
	  			}
	  		});
	  	});
	  });

	  rasterizeWithPhantom(svgBeforeCleanFilename, rasterBeforeCleanFilename, whenBothRastered);
	  rasterizeWithPhantom(svgAfterCleanFilename, rasterAfterCleanFilename, whenBothRastered);

}
 describe('SVGCleaner Visual Results', function() {

	it('should be the same before and after clean', function(done) {

		var files = [
			'acid'
			, 'adobe'
			, 'cascading-default-attribute-removal'
			//, 'cdata'
			, 'color-formats'
			, 'comments'
			, 'fill-none'
		];
		var allDone = _.after(files.length, function() {
			done();
		});
		var i = 0;
		function nextFile() {
			cleanRasterCompareSvgFile('./test/files/' + files[i] + '.svg', function(err) {
				if(err) throw err;
				allDone();
				i++;
				if(i < files.length) {
					nextFile();
				}
			});
		}
		nextFile();
	});
});<commit_msg>made visual test play nice with mocha. each file is its own test now. meta!<commit_after>var _ = require('underscore')
  , fs = require('fs')
  , path = require('path')
  , child = require('child_process')
  , crypto = require('crypto')
  , expect = require('expect.js')
  , SVGCleaner = require('../')
  ;

function rasterizeWithPhantom(srcFilename, targetFilename, cb) {
	var ps = child.spawn('phantomjs', ['./test/rasterize.js', 'file://' + path.resolve(srcFilename), targetFilename]);
	ps.stdout.on('data', function(data) {
      console.log("phantom stdout: " + data);
    });
    ps.stderr.on('data', function(data) {
      console.warn("phantom stderr: " + data);
    });
    ps.on('exit', function() {
    	cb();
    });
}

function getMD5Sum(filename, cb) {
	var md5sum = crypto.createHash('md5');
	var s = fs.ReadStream(filename);
	s.on('data', function(d) {
  		md5sum.update(d);
	});
	s.on('end', function() {
  		var d = md5sum.digest('hex');
  		cb(d);
	});
}

function cleanRasterCompareSvgFile(svgBeforeCleanFilename, done) {

	var svgAfterCleanFilename = svgBeforeCleanFilename + '.cleaned.svg';
	var rasterBeforeCleanFilename = svgBeforeCleanFilename + '.rastered.png';
	var rasterAfterCleanFilename = svgAfterCleanFilename +  '.rastered.png';

	SVGCleaner.cleanFile(svgBeforeCleanFilename, svgAfterCleanFilename);

	function cleanup() {
		fs.unlinkSync(svgAfterCleanFilename);
		fs.unlinkSync(rasterBeforeCleanFilename);
		fs.unlinkSync(rasterAfterCleanFilename);
	}

	var whenBothRastered = _.after(2, function() {

	  	// read both files and compare them
	  	getMD5Sum(rasterBeforeCleanFilename, function(hashBeforeClean) {
	  		getMD5Sum(rasterAfterCleanFilename, function(hashAfterClean) {
	  			cleanup();
	  			if(hashBeforeClean == hashAfterClean) {
	  				done();
	  			} else {
	  				done(new Error(
	  					svgBeforeCleanFilename + ":\n"
	  					+ "Cleaned and rastered version does not equel original and rastered version \n"
	  					 + rasterBeforeCleanFilename + ' != ' + rasterAfterCleanFilename));
	  			}
	  		});
	  	});
	  });

	  rasterizeWithPhantom(svgBeforeCleanFilename, rasterBeforeCleanFilename, whenBothRastered);
	  rasterizeWithPhantom(svgAfterCleanFilename, rasterAfterCleanFilename, whenBothRastered);

}
 describe('SVGCleaner Visual Results', function() {

  var files = [
    'acid'
    , 'adobe'
    , 'cascading-default-attribute-removal'
    , 'cdata'
    , 'color-formats'
    , 'comments'
    , 'fill-none'
  ];

  for(var i = 0; i < files.length; i++) {
    var filename = files[i];

    (function(filename, context) {
      it.apply(context, [
        'should be the same before and after clean for ' + filename,
        function(done) {
          cleanRasterCompareSvgFile('./test/files/' + filename + '.svg', function(err) {
            if(err) throw err;
            done();
          });
        }
      ]);
    })(filename, this);
  }

});<|endoftext|>


<commit_before>let assert = require('assert')
let {eq, neq, oeq, oneq, random} = require('./helpers')
let {identity} = require('../src/utils')
let retake = require('../src'), empty = retake.empty

describe('Zipper', function() {
    describe('boundaries', function() {
        let r, z, arr
        before(function() {
            arr = [1,2,3,4,5,6,7,8,9]
            r = retake.from(arr), z = r.toZipper()
        })
        it('should preserve integrity of source list on traversal', function() {
            let f = z.focus, sz = z.size(), z2sz = z.unzip().unzip().zip().size()
            eq(sz, 0)
            eq(z2sz, 1)
            eq(z.focus, f)
        })
        it('should preserve integrity of source list on updates', function() {
            let z2 = z.unzip(3).unzip(2).zip(3).unzip(2), value = random()*10000
            let z3 = z2.update(value)
            eq(z3.focus, value)
            neq([...z3.list], arr)
            oeq([...z.list], arr)
        })
        it('should preserve laziness of source list', function() {
            let i = 1, gen = function*() { while(true) yield ++i; }
            let r = retake.fromValue(i, gen), z = r.toZipper().unzip()
            eq(z.focus, i-1)
            let z2 = z.unzip(3)
            eq(z2.focus, i-1)
        })
    })
});<commit_msg>zipper update and remove operations tested<commit_after>let assert = require('assert')
let {eq, neq, oeq, oneq, random} = require('./helpers')
let {identity} = require('../src/utils')
let retake = require('../src'), empty = retake.empty

describe('Zipper', function() {
    describe('no side effects', function() {
        let r, z, arr
        before(function() {
            arr = [1,2,3,4,5,6,7,8,9]
            r = retake.from(arr), z = r.toZipper()
        })
        it('should preserve integrity of source list on traversal', function() {
            let f = z.focus, sz = z.size(), z2sz = z.unzip().unzip().zip().size()
            eq(sz, 0)
            eq(z2sz, 1)
            eq(z.focus, f)
        })
        it('should preserve integrity of source list on updates', function() {
            let z2 = z.unzip(3).unzip(2).zip(3).unzip(2), value = random()*10000
            let z3 = z2.update(value)
            eq(z3.focus, value)
            oneq([...z3.list], arr)
            oeq([...z.list], arr)
        })
        it('should preserve laziness of source list', function() {
            let i = 1, gen = function*() { while(true) yield ++i; }
            let r = retake.fromValue(i, gen), z = r.toZipper().unzip()
            eq(z.focus, i-1)
            let z2 = z.unzip(3)
            eq(z2.focus, i-1)
        })
    })
    describe('operations', function() {
        let r, z, arr
        before(function() {
            arr = [1,2,3,4,5,6,7,8,9]
            r = retake.from(arr), z = r.toZipper()
        })
        it('should unzip (down)', function() {
            let z1 = z.unzip().unzip(), z3 = z1.unzip(3).unzip(3)
            eq(z1.focus, 2)
            eq(z3.focus, 8)
            oeq([...z3], [6,7,8])
        })
        it('should zip (up)', function() {
            let z1 = z.unzip().unzip(), z3 = z1.unzip(3).unzip(3)
            let z4 = z1.zip(), z5 = z3.zip(3)
            eq(z1.focus, 2)
            eq(z3.focus, 8)
            eq(z4.focus, 1)
            eq(z5.focus, 5)
            oeq([...z5], [3,4,5])
        })
        it('should update focus', function() {
            let z2 = z.unzip(), value = random()*10000
            eq(z2.focus, arr[0])
            let z3 = z2.update(value)
            eq(z3.focus, value)
            oeq([...z3.list].slice(2), arr.slice(2))
        })
        it('should update more than one matching elements in focus list', function() {
            let z2 = z.unzip(4)
            let pred = v => v % 2 == 0, i = 0, newValues = v => ++i && v*1000
            let z3 = z2.updateWhen(pred, newValues)
            eq(i, 2)
            eq(z3.focus, newValues(z2.focus))
            oeq([...z3.list].slice(4), arr.slice(4))
            eq(z2.focus, 4)
        })
        it('should remove focus', function() {
            let z2 = z.unzip()
            eq(z2.focus, arr[0])
            let z3 = z2.remove()
            eq(z3.focus, undefined)
            oeq([...z3.list], arr.slice(1))
        })
        it('should remove more than one matching elements in focus list', function() {
            let z2 = z.unzip(4), pred = v => v % 2 == 0
            let z3 = z2.removeWhen(pred)
            eq(z2.focus, 4)
            eq(z2.size(), 4)
            eq(z3.size(), 2)
            eq(z3.focus, 3)
            oeq([...z3.list].slice(2), arr.slice(4))
        })
    })
});<|endoftext|>


<commit_before>const BaseActionCreator = require('./base-action-creator');

export default class MoleGameActionCreator extends BaseActionCreator {
  // Action types
  static ANIMATION_FINISH = "animation-finish";

  /**
   * Sends an action telling the mole game to finish off any
   * animation being played and restore the sculpture to a responsive
   * state
   */
  sendFinishAnimation() {
    this._dispatch(MoleGameActionCreator.ANIMATION_FINISH);
  }
}
<commit_msg>Removed now unused mole game action creator<commit_after><|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import FontAwesome from 'react-fontawesome';
import TimeAgo from 'react-timeago';
import { Link } from 'react-router';
import config from 'config';
import MediaStatus from './MediaStatus';
import MediaTags from './MediaTags';
import QuoteMediaCard from './QuoteMediaCard';
import SocialMediaCard from './SocialMediaCard';
import MediaActions from './MediaActions';
import util from './MediaUtil';
import Tags from '../source/Tags';
import DefaultButton from '../inputs/DefaultButton';

class MediaDetail extends Component {
  constructor(props) {
    super(props)

    this.state = {
      isEditing: false
    }
  }

  handleEdit() {
    this.setState({isEditing: true});
  }

  handleSave() {
    // TODO: mutation
    this.setState({isEditing: false});
  }

  handleCancel() {
    this.setState({isEditing: false});
  }

  statusToClass(baseClass, status) {
    return status.length ?
      [baseClass, `${baseClass}--${status.toLowerCase().replace(/[ _]/g, '-')}`].join(' ') :
      baseClass;
  }

  render() {
    const media = this.props.media;
    const data = JSON.parse(media.jsondata);
    const createdAt = util.createdAt(media);
    const annotationsCount = util.notesCount(media, data);

    const byUser = (media.user && media.user.source && media.user.source.dbid && media.user.name !== 'Pender') ?
      (by <Link to={`/source/${media.user.source.dbid}`}>{media.user.name}</Link>) : '';

    const embedCard = (media, data) => {
      if (data && data.quote && data.quote.length) {
        return <QuoteMediaCard quoteText={data.quote} attributionName={null} attributionUrl={null}/>;
      }
      if (media.url) {
        return <SocialMediaCard media={media} data={data} />
      }
      return null; // TODO: fallback
    }(media, data);

    return (

<MediaStatus media={media} />

          {this.state.isEditing ? (

              {/*<DefaultButton onClick={this.handleCancel.bind(this)} className='media-detail__cancel-edits' size='xsmall'>Cancel</DefaultButton>*/}
              <DefaultButton onClick={this.handleSave.bind(this)} className='media-detail__save-edits' size='xsmall' style='primary'>Done</DefaultButton>

            ) :
            <MediaActions media={media} handleEdit={this.handleEdit.bind(this)} />
          }

          {embedCard}

          Added {byUser} {createdAt ?
            <Link to={window.location.href}><TimeAgo date={createdAt} live={false} /></Link>
            : null
          } {annotationsCount}

        <MediaTags media={media} tags={media.tags.edges} isEditing={this.state.isEditing} />

    );
  }
}

export default MediaDetail;
<commit_msg>Revert to PenderCard on MediaDetail<commit_after>import React, { Component, PropTypes } from 'react';
import FontAwesome from 'react-fontawesome';
import TimeAgo from 'react-timeago';
import { Link } from 'react-router';
import config from 'config';
import MediaStatus from './MediaStatus';
import MediaTags from './MediaTags';
import QuoteMediaCard from './QuoteMediaCard';
import SocialMediaCard from './SocialMediaCard';
import MediaActions from './MediaActions';
import util from './MediaUtil';
import Tags from '../source/Tags';
import DefaultButton from '../inputs/DefaultButton';
import PenderCard from '../PenderCard';

class MediaDetail extends Component {
  constructor(props) {
    super(props)

    this.state = {
      isEditing: false
    }
  }

  handleEdit() {
    this.setState({isEditing: true});
  }

  handleSave() {
    // TODO: mutation
    this.setState({isEditing: false});
  }

  handleCancel() {
    this.setState({isEditing: false});
  }

  statusToClass(baseClass, status) {
    return status.length ?
      [baseClass, `${baseClass}--${status.toLowerCase().replace(/[ _]/g, '-')}`].join(' ') :
      baseClass;
  }

  render() {
    const media = this.props.media;
    const data = JSON.parse(media.jsondata);
    const createdAt = util.createdAt(media);
    const annotationsCount = util.notesCount(media, data);

    const byUser = (media.user && media.user.source && media.user.source.dbid && media.user.name !== 'Pender') ?
      (by <Link to={`/source/${media.user.source.dbid}`}>{media.user.name}</Link>) : '';

    const embedCard = (media, data) => {
      // if Media page:
      return <PenderCard url={media.url} penderUrl={config.penderUrl} />

      // TODO: if Project page:
      // if (data && data.quote && data.quote.length) {
      //   return <QuoteMediaCard quoteText={data.quote} attributionName={null} attributionUrl={null}/>;
      // }
      // if (media.url) {
      //   return <SocialMediaCard media={media} data={data} />
      // }
      // return null; // TODO: fallback
    }(media, data);

    return (

<MediaStatus media={media} />

          {this.state.isEditing ? (

              {/*<DefaultButton onClick={this.handleCancel.bind(this)} className='media-detail__cancel-edits' size='xsmall'>Cancel</DefaultButton>*/}
              <DefaultButton onClick={this.handleSave.bind(this)} className='media-detail__save-edits' size='xsmall' style='primary'>Done</DefaultButton>

            ) :
            <MediaActions media={media} handleEdit={this.handleEdit.bind(this)} />
          }

          {embedCard}

          Added {byUser} {createdAt ?
            <Link to={window.location.href}><TimeAgo date={createdAt} live={false} /></Link>
            : null
          } {annotationsCount}

        <MediaTags media={media} tags={media.tags.edges} isEditing={this.state.isEditing} />

    );
  }
}

export default MediaDetail;
<|endoftext|>


<commit_before>/*@cc_on@if(@_jscript_version<9)
(function (window, document) {

var documentElement = document.documentElement,
	documentFragment = document.createDocumentFragment(),
	html5_stylesheet = {},
	html5_elements = 'abbr|article|aside|audio|canvas|command|datalist|details|figure|figcaption|footer|header|hgroup|keygen|mark|meter|nav|output|progress|section|source|summary|time|video',
	html5_elements_array = html5_elements.split('|'),
	elementsCache = [],
	a = -1,
	firstChild = 'firstChild',
	createElement = 'createElement';

function append_stylesheet (media, cssText) {
	if (html5_stylesheet[media]) {
		html5_stylesheet[media].styleSheet.cssText += cssText;
	}
	else {
		var head = documentElement[firstChild],
			style = document[createElement]('style');

		style.media = media;
		head.insertBefore(style, head[firstChild]);
		html5_stylesheet[media] = style;
		append_stylesheet(media, cssText);
	}
}

function parse_style_sheet_list (styleSheetList, media) {
	var cssRuleList,
		selectorText,
		selectorTextMatch = new RegExp('\\b(' + html5_elements + ')\\b(?!.*[;}])', 'gi'),
		selectorTextReplace = function (m) {
			return '.iepp_' + m;
		},
		a = -1,
		media_stylesheet;

	while (++a < styleSheetList.length) {
		media = styleSheetList[a].media || media;

		parse_style_sheet_list(styleSheetList[a].imports, media);

		append_stylesheet(media, styleSheetList[a].cssText.replace(selectorTextMatch, selectorTextReplace));
	}
}

function on_before_print () {
	var head = documentElement[firstChild],
		element,
		elements = document.getElementsByTagName('*'),
		elementCache,
		elementName,
		elementMatch = new RegExp('^' + html5_elements + '$', 'i'),
		elementReplace,
		elementReplaced,
		a = -1;

	while (++a < elements.length) {
		if ((element = elements[a]) && (elementName = element.nodeName.match(elementMatch))) {
			elementReplace = new RegExp('^\\s*<' + elementName + '(.*)\\/' + elementName + '>\\s*$', 'i');

			documentFragment.innerHTML = element.outerHTML.replace(/\r|\n/g, ' ').replace(elementReplace, (element.currentStyle.display == 'block') ? '<div$1/div>' : '<span$1/span>');

			elementReplaced = documentFragment.childNodes[0];
			elementReplaced.className += ' iepp_' + elementName;

			elementCache = elementsCache[elementsCache.length] = [element, elementReplaced];

			element.parentNode.replaceChild(elementCache[1], elementCache[0]);
		}
	}

	parse_style_sheet_list(document.styleSheets, 'all');
}

function on_after_print () {
	var a = -1,
		b;

	while (++a < elementsCache.length) {
		elementsCache[a][1].parentNode.replaceChild(elementsCache[a][0], elementsCache[a][1]);
	}

	for (b in html5_stylesheet) {
		documentElement[firstChild].removeChild(html5_stylesheet[b]);
	}

	html5_stylesheet = {};
	elementsCache = [];
}

while (++a < html5_elements_array.length) {
	document[createElement](html5_elements_array[a]);
	documentFragment[createElement](html5_elements_array[a]);
}

documentFragment = documentFragment.appendChild(document[createElement]('div'));

window.attachEvent('onbeforeprint', on_before_print);
window.attachEvent('onafterprint', on_after_print);

}(A.config.win, A.config.doc));
@end@*/<commit_msg>Source Formatting<commit_after>/*@cc_on@if(@_jscript_version<9)
(function (window, document) {

var documentElement = document.documentElement,
	documentFragment = document.createDocumentFragment(),
	html5Stylesheet = {},
	html5Elements = AUI.HTML5_ELEMENTS.join('|'),
	elementsCache = [],
	a = -1,
	firstChild = 'firstChild',
	createElement = 'createElement';

function appendStylesheet (media, cssText) {
	if (html5Stylesheet[media]) {
		html5Stylesheet[media].styleSheet.cssText += cssText;
	}
	else {
		var head = documentElement[firstChild],
			style = document[createElement]('style');

		style.media = media;
		head.insertBefore(style, head[firstChild]);
		html5Stylesheet[media] = style;
		appendStylesheet(media, cssText);
	}
}

function parseStyleSheetList (styleSheetList, media) {
	var cssRuleList,
		selectorText,
		selectorTextMatch = new RegExp('\\b(' + html5Elements + ')\\b(?!.*[;}])', 'gi'),
		selectorTextReplace = function (m) {
			return '.iepp_' + m;
		},
		a = -1;

	while (++a < styleSheetList.length) {
		media = styleSheetList[a].media || media;

		parseStyleSheetList(styleSheetList[a].imports, media);

		appendStylesheet(media, styleSheetList[a].cssText.replace(selectorTextMatch, selectorTextReplace));
	}
}

function onBeforePrint () {
	var head = documentElement[firstChild],
		element,
		elements = document.getElementsByTagName('*'),
		elementCache,
		elementName,
		elementMatch = new RegExp('^' + html5Elements + '$', 'i'),
		elementReplace,
		elementReplaced,
		a = -1;

	while (++a < elements.length) {
		if ((element = elements[a]) && (elementName = element.nodeName.match(elementMatch))) {
			elementReplace = new RegExp('^\\s*<' + elementName + '(.*)\\/' + elementName + '>\\s*$', 'i');

			documentFragment.innerHTML = element.outerHTML.replace(/\r|\n/g, ' ').replace(elementReplace, (element.currentStyle.display == 'block') ? '<div$1/div>' : '<span$1/span>');

			elementReplaced = documentFragment.childNodes[0];
			elementReplaced.className += ' iepp_' + elementName;

			elementCache = elementsCache[elementsCache.length] = [element, elementReplaced];

			element.parentNode.replaceChild(elementCache[1], elementCache[0]);
		}
	}

	parseStyleSheetList(document.styleSheets, 'all');
}

function onAfterPrint () {
	var a = -1,
		b;

	while (++a < elementsCache.length) {
		elementsCache[a][1].parentNode.replaceChild(elementsCache[a][0], elementsCache[a][1]);
	}

	for (b in html5Stylesheet) {
		documentElement[firstChild].removeChild(html5Stylesheet[b]);
	}

	html5Stylesheet = {};
	elementsCache = [];
}

while (++a < HTML5_ELEMENTS.length) {
	document[createElement](HTML5_ELEMENTS[a]);
	documentFragment[createElement](HTML5_ELEMENTS[a]);
}

documentFragment = documentFragment.appendChild(document[createElement]('div'));

window.attachEvent('onbeforeprint', onBeforePrint);
window.attachEvent('onafterprint', onAfterPrint);

}(A.config.win, A.config.doc));
@end@*/<|endoftext|>


<commit_before>/**
 * Created by Nightpaws on 23/02/2016.
 */
var express = require('express'),
    bodyParser = require('body-parser'),
    responseFactory = require('./../response/response');

var users = function(){

    var userRouter = express.Router();

    userRouter.route('/auth')
        .post(function(req, res){

            var data = req.body;

            var Auth = require('./../modules/auth/UserAuth');
            var promise = Auth.validateUser(data.username, data.passphrase);

            var response = responseFactory();

            promise
                .then(function(data){
                    response.setSuccessful(true);
                    response.setMessage('User logged in');
                    response.setResult(data);

                    res.json(response.getResponse());
                })
                .fail(function(data){

                    response.setSuccessful(false);
                    var message = (data.error) ? 'Error resolving password': (data.wrongPass) ? 'Error: wrong username or password' : '';

                    response.setMessage(message);
                    res.json(response.getResponse());
                });

        });

    userRouter.route('/register')
        .post(function(req, res){

            var data = req.body;

            var auth = require('../modules/auth/UserAuth');
            var tokenPromise = auth.registerUser(data.username, data.email, data.passphrase);

            var response = responseFactory();

            tokenPromise
                .then(function(data){

                    response.setSuccessful(true);
                    response.setMessage('User logged in');
                    response.setResult({token: data});

                    res.json(response.getResponse());

                })
                .fail(function(data){
                    response.setSuccessful(false);
                    response.setMessage(data);

                    res.json(response.getResponse());
                });
        });

    return userRouter;
};

module.exports = users;<commit_msg>Casing issue I am disabling my caps lock and shift keys...<commit_after>/**
 * Created by Nightpaws on 23/02/2016.
 */
var express = require('express'),
    bodyParser = require('body-parser'),
    responseFactory = require('./../response/response');

var users = function(){

    var userRouter = express.Router();

    userRouter.route('/auth')
        .post(function(req, res){

            var data = req.body;

            var Auth = require('./../modules/auth/userauth');
            var promise = Auth.validateUser(data.username, data.password);

            var response = responseFactory();

            promise
                .then(function(data){
                    response.setSuccessful(true);
                    response.setMessage('User logged in');
                    response.setResult(data);

                    res.json(response.getResponse());
                })
                .fail(function(data){

                    response.setSuccessful(false);
                    var message = (data.error) ? 'Error resolving password': (data.wrongPass) ? 'Error: wrong username or password' : '';

                    response.setMessage(message);
                    res.json(response.getResponse());
                });

        });

    userRouter.route('/register')
        .post(function(req, res){

            var data = req.body;

            var auth = require('../modules/auth/UserAuth');
            var tokenPromise = auth.registerUser(data.username, data.email, data.password);

            var response = responseFactory();

            tokenPromise
                .then(function(data){

                    response.setSuccessful(true);
                    response.setMessage('User logged in');
                    response.setResult({token: data});

                    res.json(response.getResponse());

                })
                .fail(function(data){
                    response.setSuccessful(false);
                    response.setMessage(data);

                    res.json(response.getResponse());
                });
        });

    return userRouter;
};

module.exports = users;<|endoftext|>


<commit_before>/*
* BrainBrowser: Web-based Neurological Visualization Tools
* (https://brainbrowser.cbrain.mcgill.ca)
*
* Copyright (C) 2011
* The Royal Institution for the Advancement of Learning
* McGill University
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
* @author: Tarek Sherif
*/

(function() {
  "use strict";

  self.addEventListener("message", function(e) {
    self.postMessage(parseData(JSON.parse(e.data.data)));
  });

  function parseData(data) {
    var result = { shapes: [] };
    result.vertices = flatten(data.vertices);

    if (data.colors) {
      result.colors = flatten(data.colors);

      if (result.vertices.length === result.colors.length) {
        result.colors = insertColorAlpha(result.colors);
      }

    }
    if (data.normals) {
      result.normals = flatten(data.normals);
    }

    if (data.shapes === undefined) {
      data.shapes = [];
    }

    if (data.indices) {
      data.shapes.push({ indices: data.indices });
    }

    data.shapes.forEach(function(shape) {
      var indices = flatten(shape.indices);
      if (shape.one_indexed) {
        adjustIndices(indices);
      }
      result.shapes.push({ indices: indices });
    });

    return result;
  }

  function flatten(array, index) {
    if (!Array.isArray(array)) {
      return [array];
    }

    index = index || 0;

    if (index === array.length) {
      return [];
    }

    var result = [];
    var i, count;

    for (i = 0, count = array.length; i < count; i++) {
      result.push.apply(result, flatten(array[i]));
    }

    return result;
  }

  function insertColorAlpha(data_colors) {
    var colors;
    var i, ri, count;

    colors = new Float32Array(data_colors.length * 4 / 3);
    i = ri = 0;
    count = data_colors.length;

    while (i < count) {
      colors[ri++] = data_colors[i++];
      colors[ri++] = data_colors[i++];
      colors[ri++] = data_colors[i++];
      colors[ri++] = 1.0;
    }

    return colors;
  }

  function adjustIndices(indices) {
    var i, count;

    for (i = 0, count = indices.length; i < count; i++) {
      indices[i] = indices[i] - 1;
    }
  }

})();

<commit_msg>Pull shape names from JSON data.<commit_after>/*
* BrainBrowser: Web-based Neurological Visualization Tools
* (https://brainbrowser.cbrain.mcgill.ca)
*
* Copyright (C) 2011
* The Royal Institution for the Advancement of Learning
* McGill University
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
* @author: Tarek Sherif
*/

(function() {
  "use strict";

  self.addEventListener("message", function(e) {
    self.postMessage(parseData(JSON.parse(e.data.data)));
  });

  function parseData(data) {
    var result = { name: data.name, shapes: [] };
    result.vertices = flatten(data.vertices);

    if (data.colors) {
      result.colors = flatten(data.colors);

      if (result.vertices.length === result.colors.length) {
        result.colors = insertColorAlpha(result.colors);
      }

    }
    if (data.normals) {
      result.normals = flatten(data.normals);
    }

    if (data.shapes === undefined) {
      data.shapes = [];
    }

    if (data.indices) {
      data.shapes.push({ indices: data.indices });
    }

    data.shapes.forEach(function(shape) {
      var indices = flatten(shape.indices);
      if (shape.one_indexed) {
        adjustIndices(indices);
      }
      result.shapes.push({ name: shape.name, indices: indices });
    });

    return result;
  }

  function flatten(array, index) {
    if (!Array.isArray(array)) {
      return [array];
    }

    index = index || 0;

    if (index === array.length) {
      return [];
    }

    var result = [];
    var i, count;

    for (i = 0, count = array.length; i < count; i++) {
      result.push.apply(result, flatten(array[i]));
    }

    return result;
  }

  function insertColorAlpha(data_colors) {
    var colors;
    var i, ri, count;

    colors = new Float32Array(data_colors.length * 4 / 3);
    i = ri = 0;
    count = data_colors.length;

    while (i < count) {
      colors[ri++] = data_colors[i++];
      colors[ri++] = data_colors[i++];
      colors[ri++] = data_colors[i++];
      colors[ri++] = 1.0;
    }

    return colors;
  }

  function adjustIndices(indices) {
    var i, count;

    for (i = 0, count = indices.length; i < count; i++) {
      indices[i] = indices[i] - 1;
    }
  }

})();

<|endoftext|>


<commit_before>const Sequelize = require('sequelize');
const db = require('../db.js');

let Post = db.define('Post', {
  title: {
    type: Sequelize.STRING,
    unique: true
  },
  content: {
    type: Sequelize.TEXT,
    allowNull: false
  }
});

module.exports = Post;
<commit_msg>(cleanup) Removed file type extension from require statement to db.js<commit_after>const Sequelize = require('sequelize');
const db = require('../db');

let Post = db.define('Post', {
  title: {
    type: Sequelize.STRING,
    unique: true
  },
  content: {
    type: Sequelize.TEXT,
    allowNull: false
  }
});

module.exports = Post;
<|endoftext|>