<commit_before>function Ui(ui_container) {
    this.container(ui_container);
    this.board(null);
    this.displayed_board(null);
    this.row(0);
    this.column(0);
    this.displayed_row(null);
}

accessor(Ui, "container");
accessor(Ui, "board");
accessor(Ui, "displayed_board");
accessor(Ui, "row");
accessor(Ui, "column");
accessor(Ui, "displayed_row");

Ui.prototype.cell_class= function() {
    return this.board().cell_color(this.row(), this.column()) + "-cell";
}

Ui.prototype.cell_contents= function() {
    if (this.board().is_ant_at(this.row(), this.column()))
	return "";
    return "";
};

Ui.prototype.start_row= function() {
    this.displayed_row($("

").appendTo(this.displayed_board()));
};

Ui.prototype.done= function() {
    return this.row() >= this.board().height();
};

Ui.prototype.next_cell= function() {
    this.column(this.column() + 1);
    if (this.column() >= this.board().width()) {
	this.column(0);
	this.row(this.row() + 1);
    }
};

Ui.prototype.add_cell= function() {
    if (this.column() === 0)
	this.start_row();

    $("" + this.cell_contents() + "	").appendTo(this.displayed_row());
    this.next_cell();
    return !this.done();
};

Ui.prototype.display= function(a_board) {
    this.board(a_board);
    this.displayed_board($("

").appendTo(this.container()));
    while (this.add_cell())
	;
};
<commit_msg>Specs pass<commit_after>function Ui(ui_container) {
    this.container(ui_container);
    this.board(null);
    this.displayed_board(null);
    this.row(0);
    this.column(0);
    this.displayed_row(null);
}

accessor(Ui, "container");
accessor(Ui, "board");
accessor(Ui, "displayed_board");
accessor(Ui, "row");
accessor(Ui, "column");
accessor(Ui, "displayed_row");

Ui.prototype.cell_class= function() {
    return this.board().cell_color(this.row(), this.column()) + "-cell";
}

Ui.prototype.cell_contents= function() {
    if (this.board().is_ant_at(this.row(), this.column()))
	return "";
    return "";
};

Ui.prototype.start_row= function() {
    this.displayed_row($("

").appendTo(this.displayed_board()));
};

Ui.prototype.done= function() {
    return this.row() >= this.board().height();
};

Ui.prototype.next_cell= function() {
    this.column(this.column() + 1);
    if (this.column() >= this.board().width()) {
	this.column(0);
	this.row(this.row() + 1);
    }
};

Ui.prototype.add_cell= function() {
    if (this.column() === 0)
	this.start_row();

    $("" + this.cell_contents() + "	").appendTo(this.displayed_row());
    this.next_cell();
    return !this.done();
};

Ui.prototype.display= function(a_board) {
    this.board(a_board);
    this.displayed_board($("

").appendTo(this.container()));
    while (this.add_cell())
	;
};
<|endoftext|>


<commit_before><commit_msg>changed the data structure. We are now enforcing that title, publisher, identifier, contributor as a list even if there is just a single value. We need this to align it to the api data structure.<commit_after><|endoftext|>


<commit_before>/**
 * Copyright 2015, Nominet.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/

var dns = require('native-dns');

module.exports = function (RED) {
    "use strict";

    function DnsQueryNode(config) {

        RED.nodes.createNode(this, config);
        var node = this;
        this.on("input", function (msg) {
            var question = dns.Question({
                name: msg.dnsQuery.name,
                type: msg.dnsQuery.type
            });

            var req = dns.Request({
                question: question,
                server: {address: "8.8.8.8", port: 53, type: "udp"},
                timeout: 1000
            });

            if (req) {
                req.on("timeout", function () {
                    console.log("Request timeout");
                    msg.dnsResponse.type = "Error";
                    msg.dnsResponse.value = "Request Timeout";
                    node.send(msg);
                });

                req.send();

            } else {
                msg.dnsResponse.type = "Error";
                msg.dnsResponse.value = "Malformed or missing dns query";
            }

            req.on('message', function (err, answer) {
                msg.dnsResponse = {};

                answer.answer.forEach(function (a) {
                    if (a.type == 1) {	// A
                        msg.dnsResponse.type = "A";
                        msg.dnsResponse.value = a.address;
                    }
                    else if (a.type == 16) {	// TXT
                        //TODO: Handle text record better
                        var str = "";

                        for (var i = 0; i < a.data.length; i++) {
                            str = str + a.data[i]
                        }

                        msg.dnsResponse.type = "TXT";
                        msg.dnsResponse.value = str;
                    }
                    else if (a.type == 33) {	// SRV
                        msg.dnsResponse.type = "SRV";
                        msg.dnsResponse.value = a.target;
                    }
                    else if (a.type == 256) {	// URI
                        msg.dnsResponse.type = "URI";
                        msg.dnsResponse.value = a.target;
                    } else {
                        msg.dnsResponse.type = "Error";
                        msg.dnsResponse.value = "Message not recognised";
                    }
                });
                node.send(msg);
            });

        });
    }

    RED.nodes.registerType("dns-query", DnsQueryNode);
}
<commit_msg>Better error reporting<commit_after>/**
 * Copyright 2015, Nominet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/

var dns = require('native-dns');

module.exports = function (RED) {
    "use strict";

    function DnsQueryNode(config) {

        RED.nodes.createNode(this, config);
        var node = this;
        this.on("input", function (msg) {
            var question = dns.Question({
                name: msg.dnsQuery.name,
                type: msg.dnsQuery.type
            });

            var req = dns.Request({
                question: question,
                server: {address: "8.8.8.8", port: 53, type: "udp"},
                timeout: 1000
            });

            if (req) {
                req.on("timeout", function () {
                    console.log("Request timeout");
                    msg.dnsResponse.type = "Error";
                    msg.dnsResponse.value = "Request Timeout";
                    node.send(msg);
                });

                req.send();

            } else {
                msg.dnsResponse.type = "Error";
                msg.dnsResponse.value = "Malformed or missing dns query";
            }

            req.on('message', function (err, answer) {
                msg.dnsResponse = {};

                answer.answer.forEach(function (a) {
                    if (a.type == 1) {	// A
                        msg.dnsResponse.type = "A";
                        msg.dnsResponse.value = a.address;
                    }
                    else if (a.type == 16) {	// TXT
                        //TODO: Handle text record better
                        var str = "";

                        for (var i = 0; i < a.data.length; i++) {
                            str = str + a.data[i]
                        }

                        msg.dnsResponse.type = "TXT";
                        msg.dnsResponse.value = str;
                    }
                    else if (a.type == 33) {	// SRV
                        msg.dnsResponse.type = "SRV";
                        msg.dnsResponse.value = a.target;
                    }
                    else if (a.type == 256) {	// URI
                        msg.dnsResponse.type = "URI";
                        msg.dnsResponse.value = a.target;
                    } else {
                        msg.dnsResponse.type = "Error";
                        msg.dnsResponse.value = "Message not recognised";
                    }
                });
                node.send(msg);
            });

        });
    }

    RED.nodes.registerType("dns-query", DnsQueryNode);
}
<|endoftext|>


<commit_before>if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
(function($){
    $.fn.extend({
        lbListRotator: function(options) {
            if (this.length) {
                return this.each(function() {
                    var obj = Object.create(lbListRotatorClass);
                    obj.init(this, options);
                    $.data(this, 'lbListRotator', lbListRotatorClass);
                });
            }
            return false;
        }
    });
})(jQuery);

/* Advanced List Rotator
 * Copyright (c) 2010 Lars Boldt (larsboldt.com)
 * E-mail: boldt.lars@gmail.com
 * Version: 1.2
 * Released: 27.06.2010
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
var lbListRotatorClass = {
    init: function(element, options) {
        // Store "this" for reference
        var c = this;
        // Settings
        c.settings = jQuery.extend({
                                    rotationInterval: 5000,
                                    effectTimer: 1000,
                                    effect: 'fade',
                                    effectOptions: {},
                                    itemControl: {},
                                    shuffle: false,
                                    randomStart: false,
                                    autoStart: true,
                                    disableRotationEngine: false,
                                    listRotatorHelper: false,
                                    activeItemClass: 'lbListRotatorItemActive',
                                    activeHelperItemClass: 'lbListRotatorHelperItemActive',
                                    helperInteraction: 'mouseover',
                                    startIndex: 0,
                                    nextItemElement: false,
                                    nextItemElementInteraction: 'click',
                                    previousItemElement: false,
                                    previousItemElementInteraction: 'click',
                                    randomEffect: false,
                                    randomEffects: new Array('blind', 'clip', 'explode', 'fade', 'fold')
                                   }, c.settings, options);
        // Effect options
        c.effectOptions = jQuery.extend({}, c.effectOptions, c.settings.effectOptions);

        // Effect control
        c.itemControl = jQuery.extend({}, c.itemControl, c.settings.itemControl);

        // Store element for reference, both normal and jQuery
        c.listRotator = element;
        c.$listRotator = jQuery(element);
        // Total items (li's in ul)
        c.totalItems = c.$listRotator.find('li').length;
        // Current item
        c.currentItem = (c.settings.startIndex >= 0 && c.settings.startIndex < c.totalItems) ? c.settings.startIndex : 0;
        // Shuffle array
        c.shuffledItems = new Array();
        // Add currentItem to shuffle list to avoid showing item twice the first round
        c.shuffledItems.push(c.currentItem);
        // Timer
        c.tId = null;
        // User interaction
        c.userInteraction = false;
        // Calculate next item index (we use this flag to skip calculating next item index when we move backwards)
        c.calculateNextItem = true;
        // Is animation running
        c.animationRunning = false;
        // Random start
        if (c.settings.randomStart) {
            c.currentItem = c.random(c.totalItems);
        }
        // previousItem prevents shuffle ending and starting on the same item
        c.previousItem = c.currentItem;

        // Display first content
        c.$listRotator.children().each(function(index) {
            if (index == c.currentItem) {
                if (c.settings.effect == 'slide') {
                    var pos = '-' + c.currentItem*c.effectOptions.slideBy;
                    c.$listRotator.css('left', pos);
                }
                jQuery(this).show();
                jQuery(this).addClass(c.settings.activeItemClass);
                c.setHelperClass(c, index, true);
            }
        });

        // Loop all helper elements within the ul and bind mouseover/mouseout functionality to them
        if (jQuery(c.settings.listRotatorHelper).length > 0) {
            jQuery(c.settings.listRotatorHelper).children().each(function() {
                jQuery(this).bind(c.settings.helperInteraction, function() {
                    // Set userInteraction true
                    c.userInteraction = true;
                    // Stop rotationEngine
                    c.stopRotationEngine(c);
                    // Hide active content
                    if (c.settings.effect != 'slide') {
                        c.$listRotator.children().hide();
                    }
                    // Remove active class from helper
                    c.$listRotator.children().removeClass(c.settings.activeItemClass);
                    jQuery(c.settings.listRotatorHelper).children().removeClass(c.settings.activeHelperItemClass);
                    // Find position of current item
                    c.currentItem = jQuery(this).index();
                    // Show current content
                    c.$listRotator.children().each(function (index) {
                        if (index == c.currentItem) {
                            // Stop animations on this element
                            jQuery(this).stop();

                            // Reset opacity incase animation was fade
                            jQuery(this).css('opacity', 1);
                            // Show element
                            jQuery(this).show();

                            if (c.settings.effect == 'slide') {
                                c.runEffect(c, jQuery(this), false);
                            }

                            // Add active class to helper
                            jQuery(this).addClass(c.settings.activeItemClass);
                            c.setHelperClass(c, index, true);
                            return false;
                        }
                        return true;
                    });
                });
                jQuery(this).bind('mouseout', function() {
                    // Start rotationEngine
                    c.startRotationEngine(c);
                });
            });
        }

        // Bind functionality to nextItemElement
        if (jQuery(c.settings.nextItemElement).length > 0) {
            jQuery(c.settings.nextItemElement).bind(c.settings.nextItemElementInteraction, function() {
                c.moveToNextItem(c);
            });
        }

        // Bind functionality to previousItemElement
        if (jQuery(c.settings.previousItemElement).length > 0) {
            jQuery(c.settings.previousItemElement).bind(c.settings.previousItemElementInteraction, function() {
                c.moveToPreviousItem(c);
            });
        }

        // Start rotationEngine if autoStart is true
        if (c.settings.autoStart) {
            c.startRotationEngine(c);
        }
    },

    // rotationEngine
    rotationEngine: function(c) {
        // Stop rotationEngine
        c.stopRotationEngine(c);

        // Reset userInteraction
        c.userInteraction = false;

        // Hide open content
        c.$listRotator.children().each(function(index) {
            if (index == c.currentItem) {
                // Should we calculate next item index?
                if (c.calculateNextItem) {
                    // Is shuffle set?
                    if (c.settings.shuffle) {
                        // Get a random item, but make sure every item is shown in each rotation
                        c.currentItem = c.shuffleRotationEngine(c, c.totalItems);
                    } else {
                        // Activate next item
                        c.currentItem++;
                        // Make sure currentItem resets at the end of the itemlist
                        c.currentItem = (c.currentItem >= c.totalItems) ? 0 : c.currentItem;
                    }
                } else {
                    // Calculate previous item index instead
                    // Going backwards is alittle more complicated because of shuffle
                    // Is shuffle enabled?
                    if (c.settings.shuffle) {
                        // Now we need to find the previous previous item based on the shuffleItems list
                        if (c.shuffledItems.length >= 1) {
                            for (var j=0; j < c.shuffledItems.length; j++) {
                                if (c.shuffledItems[j] == c.previousItem) {
                                    // Moving backwards in the shuffledItems list will only hold true until we reach zero.
                                    // At this point you will get a random item if you keep going backwards
                                    // However, this is complicated by the fact that shuffledItems is reset at the last item.
                                    // Moving backwards when you are at the last item in the current shuffle gives you a
                                    // random item
                                    do {
                                        j--;
                                        c.previousItem = (j < 0) ? c.shuffleRotationEngine(c, c.totalItems) : c.shuffledItems[j];
                                    } while (c.currentItem == c.previousItem);
                                    break;
                                }
                            }
                        } else {
                            // shuffledItems was reset.
                            c.previousItem = c.shuffleRotationEngine(c, c.totalItems);
                        }
                        // Set currentItem to the previous shuffled item
                        c.currentItem = c.previousItem;
                    } else {
                        // Move index back once
                        c.currentItem--;
                        // Once index goes below zero we simply move it to the last item in the list, creating an endless loop
                        c.currentItem = (c.currentItem < 0) ? (c.totalItems-1) : c.currentItem;
                    }
                }

                // Loop all li elements until you locate the new active item
                c.$listRotator.children().each(function (idx) {
                    // Is next item found?
                    if (idx == c.currentItem) {
                        // Show item
                        jQuery(this).show();
                        // Give it the active class
                        c.setHelperClass(c, idx, true);
                        // Remove active class from current active item
                        c.setHelperClass(c, index, false);

                        return false;
                    }
                    return true;
                });

                // Reset item index calculation
                c.calculateNextItem = true;

                // Run effect
                c.runEffect(c, jQuery(this), true);

                return false;
            }
            return true;
        });
    },

    continueRotation: function(c, e, h) {
        // Check if user interacted with helper during effect duration
        if (! c.userInteraction) {
            // Make sure the element is hidden when effect is done, not all effects end with hide
            if (h) {
                e.hide();
            }
            // Remove active class on previous active item
            e.removeClass(c.settings.activeItemClass);

            // Loop all li elements until you locate the new active item
            c.$listRotator.children().each(function (index) {
                // Is next item found?
                if (index == c.currentItem) {
                    // Give it the active class
                    jQuery(this).addClass(c.settings.activeItemClass);

                    return false;
                }
                return true;
            });

            // Start rotationEngine
            this.startRotationEngine(c);
        }
    },

    runEffect: function(c, e, runCallback) {
        // Set animationRunning flag to true
        c.animationRunning = true;
        // Make sure jQuery UI is installed before running UI effects, if fade effect or UI isn't installed, run the standard fadeOut effect
        if (c.getItemEffect(c) == 'slide') {
            var pos = '-' + c.currentItem*c.effectOptions.slideBy;
            c.$listRotator.animate({left: pos}, c.getItemEffectTimer(c), 'swing', function() {
                // Animation done, reset animationRunning flag
                c.animationRunning = false;
                // Run callback?
                if (runCallback) {
                    c.continueRotation(c, e, false);
                }
            });
        } else if (e.effect && c.getItemEffect(c) != 'fade') {
            e.effect(c.getItemEffect(c), c.getItemEffectOptions(c), c.getItemEffectTimer(c), function() {
                // Animation done, reset animationRunning flag
                c.animationRunning = false;
                // Run callback?
                if (runCallback) {
                    c.continueRotation(c, e, true);
                }
            });
        } else {
            e.fadeOut(c.getItemEffectTimer(c), function() {
                // Animation done, reset animationRunning flag
                c.animationRunning = false;
                // Run callback?
                if (runCallback) {
                    c.continueRotation(c, e, true);
                }
            });
        }
    },

    stopRotationEngine: function(c) {
        // Stop rotationEngine
        clearInterval(c.tId);
    },

    startRotationEngine: function(c) {
        // Stop rotationEngine
        c.stopRotationEngine(c);
        // Start rotationEngine as long as disableRotationEngine is false
        if (! c.settings.disableRotationEngine) {
            c.tId = setInterval(function() {c.rotationEngine(c)}, c.getItemRotationInterval(c));
        }
    },

    shuffleRotationEngine: function(c, max) {
        // Number holds the random generated number
        var number = c.random(max);
        // Loop until we get a random number that has not been used in this rotation or was the last number of the previous rotation
        while (c.in_array(number, c.shuffledItems) || number == c.previousItem) {
            // Generate a new number until we get the one we want
            number = c.random(max);
        }
        // Set generated number to previousItem
        c.previousItem = number;
        // Add generated number to shuffle list to avoid showing it twice or more each rotation
        c.shuffledItems.push(number);
        // Reset shuffle list if we've been through all the items
        if (c.shuffledItems.length == c.totalItems) {
            c.shuffledItems = new Array();
        }
        // Return generated number
        return number;
    },

    in_array: function(needle, haystack) {
        // Returns true if needle is in haystack
        for (n in haystack) {
            if (haystack[n] == needle) {
                return true;
            }
        }
        return false;
    },

    random: function(max) {
        // Return a number between 0 and "max"
        return Math.floor(Math.random()*max);
    },

    setHelperClass: function(c, n, status) {
        // Make sure helper object is set
        if (jQuery(c.settings.listRotatorHelper).length > 0) {
            // Loop childs of helper object
            jQuery(c.settings.listRotatorHelper).children().each(function(index) {
                // Find the correct child
                if (index == n) {
                    // Toggle class
                    if (status) {
                        jQuery(this).addClass(c.settings.activeHelperItemClass);
                    } else {
                        jQuery(this).removeClass(c.settings.activeHelperItemClass);
                    }
                    return false;
                }
                return true;
            });
        }
        return false;
    },

    moveToNextItem: function(c) {
        // Move can only be done when animation isn't running
        if (! c.animationRunning) {
            // Make sure we intercept any ongoing animations with the userInteraction flag
            c.userInteraction = true;
            // Call the next item, rotationEngine will automatically figure out which item is next
            c.rotationEngine(c);
        }
    },

    moveToPreviousItem: function(c) {
        // Move can only be done when animation isn't running
        if (! c.animationRunning) {
            // Make sure we intercept any ongoing animations with the userInteraction flag
            c.userInteraction = true;
            // Setting calculate next item to false will tell rotationEngine to calculate the previous item instead
            c.calculateNextItem = false;
            c.rotationEngine(c);
        }
    },

    getItemObj: function(c) {
        var actualItem = (c.currentItem > 0) ? c.currentItem-1 : c.totalItems-1;
        var obj = eval("c.itemControl.listIndex_"+actualItem);
        return (typeof(obj) == 'undefined') ? false : obj;
    },

    getItemEffect: function(c) {
        var obj = c.getItemObj(c);
        if (obj !== false) {
            return (typeof(obj.effect) == 'undefined') ? c.settings.effect : obj.effect;
        }
        return c.settings.effect;
    },

    getItemEffectTimer: function(c) {
        var obj = c.getItemObj(c);
        if (obj !== false) {
            return (typeof(obj.effectTimer) == 'undefined') ? c.settings.effectTimer : obj.effectTimer;
        }
        return c.settings.effectTimer;
    },

    getItemEffectOptions: function(c) {
        var obj = c.getItemObj(c);
        if (obj !== false) {
            return (typeof(obj.effectOptions) == 'undefined') ? c.effectOptions : jQuery.extend({}, c.effectOptions, obj.effectOptions);
        }
        return c.effectOptions;
    },

    getItemRotationInterval: function(c) {
        var obj = c.getItemObj(c);
        if (obj !== false) {
            return (typeof(obj.rotationInterval) == 'undefined') ? c.settings.rotationInterval : obj.rotationInterval;
        }
        return c.settings.rotationInterval;
    }
}
<commit_msg>Version number correction<commit_after>if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
(function($){
    $.fn.extend({
        lbListRotator: function(options) {
            if (this.length) {
                return this.each(function() {
                    var obj = Object.create(lbListRotatorClass);
                    obj.init(this, options);
                    $.data(this, 'lbListRotator', lbListRotatorClass);
                });
            }
            return false;
        }
    });
})(jQuery);

/* Advanced List Rotator
 * Copyright (c) 2010 Lars Boldt (larsboldt.com)
 * E-mail: boldt.lars@gmail.com
 * Version: 1.3
 * Released: -
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
var lbListRotatorClass = {
    init: function(element, options) {
        // Store "this" for reference
        var c = this;
        // Settings
        c.settings = jQuery.extend({
                                    rotationInterval: 5000,
                                    effectTimer: 1000,
                                    effect: 'fade',
                                    effectOptions: {},
                                    itemControl: {},
                                    shuffle: false,
                                    randomStart: false,
                                    autoStart: true,
                                    disableRotationEngine: false,
                                    listRotatorHelper: false,
                                    activeItemClass: 'lbListRotatorItemActive',
                                    activeHelperItemClass: 'lbListRotatorHelperItemActive',
                                    helperInteraction: 'mouseover',
                                    startIndex: 0,
                                    nextItemElement: false,
                                    nextItemElementInteraction: 'click',
                                    previousItemElement: false,
                                    previousItemElementInteraction: 'click',
                                    randomEffect: false,
                                    randomEffects: new Array('blind', 'clip', 'explode', 'fade', 'fold')
                                   }, c.settings, options);
        // Effect options
        c.effectOptions = jQuery.extend({}, c.effectOptions, c.settings.effectOptions);

        // Effect control
        c.itemControl = jQuery.extend({}, c.itemControl, c.settings.itemControl);

        // Store element for reference, both normal and jQuery
        c.listRotator = element;
        c.$listRotator = jQuery(element);
        // Total items (li's in ul)
        c.totalItems = c.$listRotator.find('li').length;
        // Current item
        c.currentItem = (c.settings.startIndex >= 0 && c.settings.startIndex < c.totalItems) ? c.settings.startIndex : 0;
        // Shuffle array
        c.shuffledItems = new Array();
        // Add currentItem to shuffle list to avoid showing item twice the first round
        c.shuffledItems.push(c.currentItem);
        // Timer
        c.tId = null;
        // User interaction
        c.userInteraction = false;
        // Calculate next item index (we use this flag to skip calculating next item index when we move backwards)
        c.calculateNextItem = true;
        // Is animation running
        c.animationRunning = false;
        // Random start
        if (c.settings.randomStart) {
            c.currentItem = c.random(c.totalItems);
        }
        // previousItem prevents shuffle ending and starting on the same item
        c.previousItem = c.currentItem;

        // Display first content
        c.$listRotator.children().each(function(index) {
            if (index == c.currentItem) {
                if (c.settings.effect == 'slide') {
                    var pos = '-' + c.currentItem*c.effectOptions.slideBy;
                    c.$listRotator.css('left', pos);
                }
                jQuery(this).show();
                jQuery(this).addClass(c.settings.activeItemClass);
                c.setHelperClass(c, index, true);
            }
        });

        // Loop all helper elements within the ul and bind mouseover/mouseout functionality to them
        if (jQuery(c.settings.listRotatorHelper).length > 0) {
            jQuery(c.settings.listRotatorHelper).children().each(function() {
                jQuery(this).bind(c.settings.helperInteraction, function() {
                    // Set userInteraction true
                    c.userInteraction = true;
                    // Stop rotationEngine
                    c.stopRotationEngine(c);
                    // Hide active content
                    if (c.settings.effect != 'slide') {
                        c.$listRotator.children().hide();
                    }
                    // Remove active class from helper
                    c.$listRotator.children().removeClass(c.settings.activeItemClass);
                    jQuery(c.settings.listRotatorHelper).children().removeClass(c.settings.activeHelperItemClass);
                    // Find position of current item
                    c.currentItem = jQuery(this).index();
                    // Show current content
                    c.$listRotator.children().each(function (index) {
                        if (index == c.currentItem) {
                            // Stop animations on this element
                            jQuery(this).stop();

                            // Reset opacity incase animation was fade
                            jQuery(this).css('opacity', 1);
                            // Show element
                            jQuery(this).show();

                            if (c.settings.effect == 'slide') {
                                c.runEffect(c, jQuery(this), false);
                            }

                            // Add active class to helper
                            jQuery(this).addClass(c.settings.activeItemClass);
                            c.setHelperClass(c, index, true);
                            return false;
                        }
                        return true;
                    });
                });
                jQuery(this).bind('mouseout', function() {
                    // Start rotationEngine
                    c.startRotationEngine(c);
                });
            });
        }

        // Bind functionality to nextItemElement
        if (jQuery(c.settings.nextItemElement).length > 0) {
            jQuery(c.settings.nextItemElement).bind(c.settings.nextItemElementInteraction, function() {
                c.moveToNextItem(c);
            });
        }

        // Bind functionality to previousItemElement
        if (jQuery(c.settings.previousItemElement).length > 0) {
            jQuery(c.settings.previousItemElement).bind(c.settings.previousItemElementInteraction, function() {
                c.moveToPreviousItem(c);
            });
        }

        // Start rotationEngine if autoStart is true
        if (c.settings.autoStart) {
            c.startRotationEngine(c);
        }
    },

    // rotationEngine
    rotationEngine: function(c) {
        // Stop rotationEngine
        c.stopRotationEngine(c);

        // Reset userInteraction
        c.userInteraction = false;

        // Hide open content
        c.$listRotator.children().each(function(index) {
            if (index == c.currentItem) {
                // Should we calculate next item index?
                if (c.calculateNextItem) {
                    // Is shuffle set?
                    if (c.settings.shuffle) {
                        // Get a random item, but make sure every item is shown in each rotation
                        c.currentItem = c.shuffleRotationEngine(c, c.totalItems);
                    } else {
                        // Activate next item
                        c.currentItem++;
                        // Make sure currentItem resets at the end of the itemlist
                        c.currentItem = (c.currentItem >= c.totalItems) ? 0 : c.currentItem;
                    }
                } else {
                    // Calculate previous item index instead
                    // Going backwards is alittle more complicated because of shuffle
                    // Is shuffle enabled?
                    if (c.settings.shuffle) {
                        // Now we need to find the previous previous item based on the shuffleItems list
                        if (c.shuffledItems.length >= 1) {
                            for (var j=0; j < c.shuffledItems.length; j++) {
                                if (c.shuffledItems[j] == c.previousItem) {
                                    // Moving backwards in the shuffledItems list will only hold true until we reach zero.
                                    // At this point you will get a random item if you keep going backwards
                                    // However, this is complicated by the fact that shuffledItems is reset at the last item.
                                    // Moving backwards when you are at the last item in the current shuffle gives you a
                                    // random item
                                    do {
                                        j--;
                                        c.previousItem = (j < 0) ? c.shuffleRotationEngine(c, c.totalItems) : c.shuffledItems[j];
                                    } while (c.currentItem == c.previousItem);
                                    break;
                                }
                            }
                        } else {
                            // shuffledItems was reset.
                            c.previousItem = c.shuffleRotationEngine(c, c.totalItems);
                        }
                        // Set currentItem to the previous shuffled item
                        c.currentItem = c.previousItem;
                    } else {
                        // Move index back once
                        c.currentItem--;
                        // Once index goes below zero we simply move it to the last item in the list, creating an endless loop
                        c.currentItem = (c.currentItem < 0) ? (c.totalItems-1) : c.currentItem;
                    }
                }

                // Loop all li elements until you locate the new active item
                c.$listRotator.children().each(function (idx) {
                    // Is next item found?
                    if (idx == c.currentItem) {
                        // Show item
                        jQuery(this).show();
                        // Give it the active class
                        c.setHelperClass(c, idx, true);
                        // Remove active class from current active item
                        c.setHelperClass(c, index, false);

                        return false;
                    }
                    return true;
                });

                // Reset item index calculation
                c.calculateNextItem = true;

                // Run effect
                c.runEffect(c, jQuery(this), true);

                return false;
            }
            return true;
        });
    },

    continueRotation: function(c, e, h) {
        // Check if user interacted with helper during effect duration
        if (! c.userInteraction) {
            // Make sure the element is hidden when effect is done, not all effects end with hide
            if (h) {
                e.hide();
            }
            // Remove active class on previous active item
            e.removeClass(c.settings.activeItemClass);

            // Loop all li elements until you locate the new active item
            c.$listRotator.children().each(function (index) {
                // Is next item found?
                if (index == c.currentItem) {
                    // Give it the active class
                    jQuery(this).addClass(c.settings.activeItemClass);

                    return false;
                }
                return true;
            });

            // Start rotationEngine
            this.startRotationEngine(c);
        }
    },

    runEffect: function(c, e, runCallback) {
        // Set animationRunning flag to true
        c.animationRunning = true;
        // Make sure jQuery UI is installed before running UI effects, if fade effect or UI isn't installed, run the standard fadeOut effect
        if (c.getItemEffect(c) == 'slide') {
            var pos = '-' + c.currentItem*c.effectOptions.slideBy;
            c.$listRotator.animate({left: pos}, c.getItemEffectTimer(c), 'swing', function() {
                // Animation done, reset animationRunning flag
                c.animationRunning = false;
                // Run callback?
                if (runCallback) {
                    c.continueRotation(c, e, false);
                }
            });
        } else if (e.effect && c.getItemEffect(c) != 'fade') {
            e.effect(c.getItemEffect(c), c.getItemEffectOptions(c), c.getItemEffectTimer(c), function() {
                // Animation done, reset animationRunning flag
                c.animationRunning = false;
                // Run callback?
                if (runCallback) {
                    c.continueRotation(c, e, true);
                }
            });
        } else {
            e.fadeOut(c.getItemEffectTimer(c), function() {
                // Animation done, reset animationRunning flag
                c.animationRunning = false;
                // Run callback?
                if (runCallback) {
                    c.continueRotation(c, e, true);
                }
            });
        }
    },

    stopRotationEngine: function(c) {
        // Stop rotationEngine
        clearInterval(c.tId);
    },

    startRotationEngine: function(c) {
        // Stop rotationEngine
        c.stopRotationEngine(c);
        // Start rotationEngine as long as disableRotationEngine is false
        if (! c.settings.disableRotationEngine) {
            c.tId = setInterval(function() {c.rotationEngine(c)}, c.getItemRotationInterval(c));
        }
    },

    shuffleRotationEngine: function(c, max) {
        // Number holds the random generated number
        var number = c.random(max);
        // Loop until we get a random number that has not been used in this rotation or was the last number of the previous rotation
        while (c.in_array(number, c.shuffledItems) || number == c.previousItem) {
            // Generate a new number until we get the one we want
            number = c.random(max);
        }
        // Set generated number to previousItem
        c.previousItem = number;
        // Add generated number to shuffle list to avoid showing it twice or more each rotation
        c.shuffledItems.push(number);
        // Reset shuffle list if we've been through all the items
        if (c.shuffledItems.length == c.totalItems) {
            c.shuffledItems = new Array();
        }
        // Return generated number
        return number;
    },

    in_array: function(needle, haystack) {
        // Returns true if needle is in haystack
        for (n in haystack) {
            if (haystack[n] == needle) {
                return true;
            }
        }
        return false;
    },

    random: function(max) {
        // Return a number between 0 and "max"
        return Math.floor(Math.random()*max);
    },

    setHelperClass: function(c, n, status) {
        // Make sure helper object is set
        if (jQuery(c.settings.listRotatorHelper).length > 0) {
            // Loop childs of helper object
            jQuery(c.settings.listRotatorHelper).children().each(function(index) {
                // Find the correct child
                if (index == n) {
                    // Toggle class
                    if (status) {
                        jQuery(this).addClass(c.settings.activeHelperItemClass);
                    } else {
                        jQuery(this).removeClass(c.settings.activeHelperItemClass);
                    }
                    return false;
                }
                return true;
            });
        }
        return false;
    },

    moveToNextItem: function(c) {
        // Move can only be done when animation isn't running
        if (! c.animationRunning) {
            // Make sure we intercept any ongoing animations with the userInteraction flag
            c.userInteraction = true;
            // Call the next item, rotationEngine will automatically figure out which item is next
            c.rotationEngine(c);
        }
    },

    moveToPreviousItem: function(c) {
        // Move can only be done when animation isn't running
        if (! c.animationRunning) {
            // Make sure we intercept any ongoing animations with the userInteraction flag
            c.userInteraction = true;
            // Setting calculate next item to false will tell rotationEngine to calculate the previous item instead
            c.calculateNextItem = false;
            c.rotationEngine(c);
        }
    },

    getItemObj: function(c) {
        var actualItem = (c.currentItem > 0) ? c.currentItem-1 : c.totalItems-1;
        var obj = eval("c.itemControl.listIndex_"+actualItem);
        return (typeof(obj) == 'undefined') ? false : obj;
    },

    getItemEffect: function(c) {
        var obj = c.getItemObj(c);
        if (obj !== false) {
            return (typeof(obj.effect) == 'undefined') ? c.settings.effect : obj.effect;
        }
        return c.settings.effect;
    },

    getItemEffectTimer: function(c) {
        var obj = c.getItemObj(c);
        if (obj !== false) {
            return (typeof(obj.effectTimer) == 'undefined') ? c.settings.effectTimer : obj.effectTimer;
        }
        return c.settings.effectTimer;
    },

    getItemEffectOptions: function(c) {
        var obj = c.getItemObj(c);
        if (obj !== false) {
            return (typeof(obj.effectOptions) == 'undefined') ? c.effectOptions : jQuery.extend({}, c.effectOptions, obj.effectOptions);
        }
        return c.effectOptions;
    },

    getItemRotationInterval: function(c) {
        var obj = c.getItemObj(c);
        if (obj !== false) {
            return (typeof(obj.rotationInterval) == 'undefined') ? c.settings.rotationInterval : obj.rotationInterval;
        }
        return c.settings.rotationInterval;
    }
}<|endoftext|>


<commit_before>const should = require('should');
const path = require('path');
const assert = require('assert');
const {parse} = require('../index');
const csvPath = path.join(__dirname, '/fixtures/');

const readCSV = ({filePath, mapping, defaultLabels}) => parse(filePath, mapping, defaultLabels);

describe('parse', function () {
    it('read csv: empty file', async function () {
        const result = await readCSV({
            filePath: csvPath + 'empty.csv'
        });

        should.exist(result);
        result.length.should.eql(0);
    });

    it('read csv: one column', async function () {
        const result = await readCSV({
            filePath: csvPath + 'single-column-with-header.csv'
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[1].email.should.eql('test@example.com');
    });

    it('read csv: two columns, 1 filter', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-with-header.csv'
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[1].email.should.eql('test@example.com');
    });

    it('read csv: two columns, 2 filters', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-obscure-header.csv',
            mapping: {
                'Email Address': 'email'
            }
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[0].id.should.eql('1');
        result[1].email.should.eql('test@example.com');
        result[1].id.should.eql('2');
    });

    it('read csv: two columns with mapping', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-mapping-header.csv',
            mapping: {
                correo_electronico: 'email',
                nombre: 'name'
            }
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[0].name.should.eql('joe');
        result[0].id.should.eql('1');

        result[1].email.should.eql('test@example.com');
        result[1].name.should.eql('test');
        result[1].id.should.eql('2');
    });

    it('read csv: two columns with partial mapping', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-mapping-header.csv',
            mapping: {
                correo_electronico: 'email'
            }
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[0].nombre.should.eql('joe');
        result[0].id.should.eql('1');

        result[1].email.should.eql('test@example.com');
        result[1].nombre.should.eql('test');
        result[1].id.should.eql('2');
    });

    it('read csv: two columns with empty mapping', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-mapping-header.csv',
            mapping: {}
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].correo_electronico.should.eql('jbloggs@example.com');
        result[0].nombre.should.eql('joe');
        result[0].id.should.eql('1');

        result[1].correo_electronico.should.eql('test@example.com');
        result[1].nombre.should.eql('test');
        result[1].id.should.eql('2');
    });

    it('read csv: transforms empty values to nulls', async function () {
        const result = await readCSV({
            filePath: csvPath + 'multiple-records-with-empty-values.csv'
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[0].name.should.eql('Bob');

        result[1].email.should.eql('test@example.com');
        should.equal(result[1].name, null);
    });

    it('read csv: transforms "subscribed_to_emails" column to "subscribed" property when the mapping is passed in', async function () {
        const mapping = {
            subscribed_to_emails: 'subscribed'
        };
        const result = await readCSV({
            filePath: csvPath + 'subscribed-to-emails-header.csv',
            mapping
        });

        assert.ok(result);
        assert.equal(result.length, 2);
        assert.equal(result[0].email, 'jbloggs@example.com');
        assert.ok(result[0].subscribed);

        assert.equal(result[1].email, 'test@example.com');
        assert.equal(result[1].subscribed, false);
    });

    it('read csv: DOES NOT transforms "subscribed_to_emails" column to "subscribed" property when the WITHOUT mapping', async function () {
        const result = await readCSV({
            filePath: csvPath + 'subscribed-to-emails-header.csv'
        });

        assert.ok(result);
        assert.equal(result.length, 2);
        assert.equal(result[0].email, 'jbloggs@example.com');
        assert.ok(result[0].subscribed_to_emails);

        assert.equal(result[1].email, 'test@example.com');
        assert.equal(result[1].subscribed_to_emails, false);
    });
});
<commit_msg>Cleaned up test case names<commit_after>const should = require('should');
const path = require('path');
const assert = require('assert');
const {parse} = require('../index');
const csvPath = path.join(__dirname, '/fixtures/');

const readCSV = ({filePath, mapping, defaultLabels}) => parse(filePath, mapping, defaultLabels);

describe('parse', function () {
    it('empty file', async function () {
        const result = await readCSV({
            filePath: csvPath + 'empty.csv'
        });

        should.exist(result);
        result.length.should.eql(0);
    });

    it('one column', async function () {
        const result = await readCSV({
            filePath: csvPath + 'single-column-with-header.csv'
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[1].email.should.eql('test@example.com');
    });

    it('two columns, 1 filter', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-with-header.csv'
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[1].email.should.eql('test@example.com');
    });

    it('two columns, 2 filters', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-obscure-header.csv',
            mapping: {
                'Email Address': 'email'
            }
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[0].id.should.eql('1');
        result[1].email.should.eql('test@example.com');
        result[1].id.should.eql('2');
    });

    it('two columns with mapping', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-mapping-header.csv',
            mapping: {
                correo_electronico: 'email',
                nombre: 'name'
            }
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[0].name.should.eql('joe');
        result[0].id.should.eql('1');

        result[1].email.should.eql('test@example.com');
        result[1].name.should.eql('test');
        result[1].id.should.eql('2');
    });

    it('two columns with partial mapping', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-mapping-header.csv',
            mapping: {
                correo_electronico: 'email'
            }
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[0].nombre.should.eql('joe');
        result[0].id.should.eql('1');

        result[1].email.should.eql('test@example.com');
        result[1].nombre.should.eql('test');
        result[1].id.should.eql('2');
    });

    it('two columns with empty mapping', async function () {
        const result = await readCSV({
            filePath: csvPath + 'two-columns-mapping-header.csv',
            mapping: {}
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].correo_electronico.should.eql('jbloggs@example.com');
        result[0].nombre.should.eql('joe');
        result[0].id.should.eql('1');

        result[1].correo_electronico.should.eql('test@example.com');
        result[1].nombre.should.eql('test');
        result[1].id.should.eql('2');
    });

    it('transforms empty values to nulls', async function () {
        const result = await readCSV({
            filePath: csvPath + 'multiple-records-with-empty-values.csv'
        });

        should.exist(result);
        result.length.should.eql(2);
        result[0].email.should.eql('jbloggs@example.com');
        result[0].name.should.eql('Bob');

        result[1].email.should.eql('test@example.com');
        should.equal(result[1].name, null);
    });

    it(' transforms "subscribed_to_emails" column to "subscribed" property when the mapping is passed in', async function () {
        const mapping = {
            subscribed_to_emails: 'subscribed'
        };
        const result = await readCSV({
            filePath: csvPath + 'subscribed-to-emails-header.csv',
            mapping
        });

        assert.ok(result);
        assert.equal(result.length, 2);
        assert.equal(result[0].email, 'jbloggs@example.com');
        assert.ok(result[0].subscribed);

        assert.equal(result[1].email, 'test@example.com');
        assert.equal(result[1].subscribed, false);
    });

    it('DOES NOT transforms "subscribed_to_emails" column to "subscribed" property when the WITHOUT mapping', async function () {
        const result = await readCSV({
            filePath: csvPath + 'subscribed-to-emails-header.csv'
        });

        assert.ok(result);
        assert.equal(result.length, 2);
        assert.equal(result[0].email, 'jbloggs@example.com');
        assert.ok(result[0].subscribed_to_emails);

        assert.equal(result[1].email, 'test@example.com');
        assert.equal(result[1].subscribed_to_emails, false);
    });
});
<|endoftext|>


<commit_before>// Copyright 2011 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * Describe the supplied set of arguments to a mock function as a list of lines
 * to be displayed.
 *
 * @param {!Arguments} args
 *
 * @param {!function(*):!string} stringify
 *     A function that turns arbitrary objects into a convenient human-readable
 *     form.
 *
 * @return {!Array.<string>}
 *
 * @private
 */
gjstest.internal.describeArgs_ = function(args, stringify) {
  if (args.length == 0) return ['    (No arguments.)'];

  var result = [];
  for (var i = 0; i < args.length; ++i) {
    result.push('    Arg ' + i + ': ' + stringify(args[i]));
  }

  return result;
};

/**
 * Find the next active action for an expectation and return its function,
 * returning the empty function if none is available. If a one-time action is
 * chosen, mark it as expired.
 *
 * @param {!gjstest.internal.CallExpectation} expectation
 * @return {!Function}
 *
 * @private
 */
gjstest.internal.consumeAction_ = function(expectation) {
  // Is there an unexpired one-time action?
  for (var i = 0; i < expectation.oneTimeActions.length; ++i) {
    var action = expectation.oneTimeActions[i];
    if (!action.expired) {
      action.expired = true;
      return action.actionFunction;
    }
  }

  // Is there a fallback action?
  if (!!expectation.fallbackAction) {
    return expectation.fallbackAction.actionFunction;
  }

  // Fall back to the empty function.
  return function() {};
};

/**
 * Describe the matchers composing a call expectation as a list of lines to be
 * displayed.
 *
 * @param {!gjstest.internal.CallExpectation} expectation
 * @return {!Array.<string>}
 */
gjstest.internal.describeExpectation = function(expectation) {
  var result = [];
  var matchers = expectation.argMatchers;

  for (var i = 0; i < matchers.length; ++i) {
    var description = matchers[i].description;
    result.push('    Arg ' + i + ': ' + description);
  }

  return result;
};

/**
 * Create a mock function that verifies against a list of expectation and takes
 * the appropriate action when called.
 *
 * @param {function(*):!string} stringify
 *     A function that turns arbitrary objects into a convenient human-readable
 *     form.
 *
 * @param {function(!Arguments, !gjstest.internal.CallExpectation):string?}
 *     checkArgs
 *     A function that knows how to check function call arguments against a call
 *     expectation, returning null if it matches and an error message otherwise.
 *
 * @param {function(string)} reportFailure
 *     A function that will be called with a descriptive error message in the
 *     event of failure.
 *
 * @param {string} opt_name
 *     A name for this mock function, used in unexpected call output.
 *
 * @return {!Function}
 */
gjstest.internal.createMockFunction =
    function(stringify, checkArgs, reportFailure, opt_name) {
  // Initialize a list of call expectations for this function.
  var callExpectations =
      /** @type !Array.<gjstest.internal.CallExpectation> */([]);

  // Create a function that checks its arguments against the expectations that
  // have been registered.
  var result = function() {
    // Build a failure message iteratively, assuming we won't match.
    var failureLines = ['Call matches no expectation.'];

    if (opt_name) {
      failureLines = ['Call to ' + opt_name + ' matches no expectation.'];
    }

    // Describe the arguments we were called with.
    failureLines = failureLines.concat(
        gjstest.internal.describeArgs_(arguments, stringify));

    // Check the arguments against each expectation. Iterate in reverse order to
    // match most recent expectations first.
    for (var i = callExpectations.length - 1; i >= 0; --i) {
      var expectation = callExpectations[i];

      // Does this expectation match?
      var expectationFailureMessage = checkArgs(arguments, expectation);
      if (expectationFailureMessage === null) {
        failureLines = [];
        ++expectation.numMatches;
        break;
      }

      // Describe the failure.
      var stackFrame = expectation.stackFrame;

      failureLines.push('');
      failureLines.push(
          'Tried expectation at ' +
              stackFrame.fileName + ':' + stackFrame.lineNumber +
              ', but ' + expectationFailureMessage + ':');

      failureLines = failureLines.concat(
          gjstest.internal.describeExpectation(expectation));
    }

    // If there was a failure, report it and return.
    if (failureLines.length > 0) {
      reportFailure(failureLines.join('\n'));
      return;
    }

    // Take the appropriate action.
    var actionFunc = gjstest.internal.consumeAction_(expectation);
    return actionFunc.apply(this, arguments);
  };

  // Add a reference to the list of expectations.
  result.__gjstest_expectations = callExpectations;

  return result;
};
<commit_msg>Fixed some casting problems.<commit_after>// Copyright 2011 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * Describe the supplied set of arguments to a mock function as a list of lines
 * to be displayed.
 *
 * @param {!Arguments} args
 *
 * @param {!function(*):!string} stringify
 *     A function that turns arbitrary objects into a convenient human-readable
 *     form.
 *
 * @return {!Array.<string>}
 *
 * @private
 */
gjstest.internal.describeArgs_ = function(args, stringify) {
  if (args.length == 0) return ['    (No arguments.)'];

  var result = [];
  for (var i = 0; i < args.length; ++i) {
    result.push('    Arg ' + i + ': ' + stringify(args[i]));
  }

  return result;
};

/**
 * Find the next active action for an expectation and return its function,
 * returning the empty function if none is available. If a one-time action is
 * chosen, mark it as expired.
 *
 * @param {!gjstest.internal.CallExpectation} expectation
 * @return {!Function}
 *
 * @private
 */
gjstest.internal.consumeAction_ = function(expectation) {
  // Is there an unexpired one-time action?
  for (var i = 0; i < expectation.oneTimeActions.length; ++i) {
    var action = expectation.oneTimeActions[i];
    if (!action.expired) {
      action.expired = true;
      return action.actionFunction;
    }
  }

  // Is there a fallback action?
  if (!!expectation.fallbackAction) {
    return expectation.fallbackAction.actionFunction;
  }

  // Fall back to the empty function.
  return function() {};
};

/**
 * Describe the matchers composing a call expectation as a list of lines to be
 * displayed.
 *
 * @param {!gjstest.internal.CallExpectation} expectation
 * @return {!Array.<string>}
 */
gjstest.internal.describeExpectation = function(expectation) {
  var result = [];
  var matchers = expectation.argMatchers;

  for (var i = 0; i < matchers.length; ++i) {
    var description = matchers[i].description;
    result.push('    Arg ' + i + ': ' + description);
  }

  return result;
};

/**
 * Create a mock function that verifies against a list of expectation and takes
 * the appropriate action when called.
 *
 * @param {function(*):!string} stringify
 *     A function that turns arbitrary objects into a convenient human-readable
 *     form.
 *
 * @param {function(!Arguments, !gjstest.internal.CallExpectation):string?}
 *     checkArgs
 *     A function that knows how to check function call arguments against a call
 *     expectation, returning null if it matches and an error message otherwise.
 *
 * @param {function(string)} reportFailure
 *     A function that will be called with a descriptive error message in the
 *     event of failure.
 *
 * @param {string} opt_name
 *     A name for this mock function, used in unexpected call output.
 *
 * @return {!Function}
 */
gjstest.internal.createMockFunction =
    function(stringify, checkArgs, reportFailure, opt_name) {
  // Initialize a list of call expectations for this function.
  var callExpectations =
      /** @type !Array.<gjstest.internal.CallExpectation> */([]);

  // Create a function that checks its arguments against the expectations that
  // have been registered.
  var result = function() {
    // Build a failure message iteratively, assuming we won't match.
    var failureLines = ['Call matches no expectation.'];

    if (opt_name) {
      failureLines = ['Call to ' + opt_name + ' matches no expectation.'];
    }

    // Describe the arguments we were called with.
    failureLines = failureLines.concat(
        gjstest.internal.describeArgs_(arguments, stringify));

    // Check the arguments against each expectation. Iterate in reverse order to
    // match most recent expectations first.
    for (var i = callExpectations.length - 1; i >= 0; --i) {
      var expectation = /** @type {!gjstest.internal.CallExpectation} */ (
          callExpectations[i]);

      // Does this expectation match?
      var expectationFailureMessage = checkArgs(arguments, expectation);
      if (expectationFailureMessage === null) {
        failureLines = [];
        ++expectation.numMatches;
        break;
      }

      // Describe the failure.
      var stackFrame = expectation.stackFrame;

      failureLines.push('');
      failureLines.push(
          'Tried expectation at ' +
              stackFrame.fileName + ':' + stackFrame.lineNumber +
              ', but ' + expectationFailureMessage + ':');

      failureLines = failureLines.concat(
          gjstest.internal.describeExpectation(expectation));
    }

    // If there was a failure, report it and return.
    if (failureLines.length > 0) {
      reportFailure(failureLines.join('\n'));
      return;
    }

    // Take the appropriate action.
    var actionFunc = gjstest.internal.consumeAction_(
        /** @type {!gjstest.internal.CallExpectation} */ (expectation));
    return actionFunc.apply(this, arguments);
  };

  // Add a reference to the list of expectations.
  result.__gjstest_expectations = callExpectations;

  return result;
};
<|endoftext|>


<commit_before>function toggleClass() {
    var theme = document.getElementById("theme-area");
    theme.classList.toggle("active");
}
function setTheme(btn) {
    var newTheme = "cld-video-player-skin-" + btn.value;
    var oldTheme = "cld-video-player-skin-";
    if(btn.value == "dark") {
        oldTheme += "light";
    }
    else {
        oldTheme += "dark";
    }
    var vplayers = document.getElementsByClassName("cld-video-player");
    for(var i = 0; i < vplayers.length; i++) {
        vplayers[i].classList.remove(oldTheme);
        vplayers[i].classList.add(newTheme);
    }
    toggleClass();
}

window.addEventListener('scroll',checkPosition,false);

function checkPosition()
{
    var themeArea = document.getElementById("theme-area");
    if(window.scrollY > 50)
    {
        themeArea.classList.add("scrolling");
    } else {
        themeArea.classList.remove("scrolling");
    }
}

function showContentBlocks() {
    var contentBlocks = document.getElementsByClassName("content-block");
    for(var i = 0; i < contentBlocks.length; i++) {
        contentBlocks[i].classList.remove("hidden");
    }
    showProgressBar(true,"transcript");
    showProgressBar(true,"autotag");
}

function initScreen() {
    getTranscriptFile = true;
    transcriptComplete = false;
    progress = 0;
    autoTagProgress = 0;
    transcriptProgress = 0;
}

function uploadVideo(){
	cloudinary.openUploadWidget({ cloud_name: 'demo', upload_preset: 'video_autotag_transcript_sd_lambda', sources: [ 'local', 'url'], multiple: false, max_file_size: 100000000, resource_type: 'video'},
      function(error, result) { processResponse(error, result); }, false);
}

function useVideo(vid) {
    console.log("useVideo",vid.title);
    initScreen();
    publicId = vid.title + "_autotag";
    transcript = publicId + ".transcript";
    updatePlayers(vid.title + "_sd");
    showContentBlocks();
    progress = 15;
    updateProgress();
    updateAutoPlayers();
}

function updateAutoPlayers() {
    autoTagPlayer.source(publicId);
    transcriptPlayer.source(publicId);
}

function processResponse(error, result) {
    console.log(error, result);
    initScreen();
    if(result && result[0].bytes > 0 && result[0].bytes <= 100000000)
    {
        publicId = result[0].public_id;
        transcript = publicId + ".transcript";
        updatePlayers(publicId);
	showContentBlocks();
        updateProgress();
	updateAutoPlayers();
    }
    else if(result && result[0].bytes > 100000000) {
	    showContentBlocks();
            showError("Uploaded file is too big. This demo file size limit is 100MB");
    }
    else
        showError(error);
}

function updatePlayers(pid) {
    for(var i = 0; i < players.length; i++)
        players[i].source(pid);
    var links = document.getElementsByClassName("manipulation")
    for(var j = 0; j < links.length; j++) {
            var ref = links[j].getAttribute("data-href");
            links[j].setAttribute("href",ref+pid+".mp4");
    }
}

function updateProgress() {
    progress++;
    console.log("updateProgress", progress);
    if (progress == 20)
        checkLambda();
    if(autoTagProgress < 100)
        updateAutoTagProgress()
    if(transcriptProgress < 100)
        updateTranscriptProgress()
    if (autoTagProgress < 100 || transcriptProgress < 100)
        setTimeout(updateProgress,1500);
    else
	console.log("updateProgress complete",autoTagProgress,transcriptProgress);
}

function getData() {
    if(getTranscriptFile && transcriptComplete)
        getTranscript();
    else if (autoTagProgress < 100 || transcriptProgress < 100) {
	console.log("getData autoT p",autoTagProgress,transcriptProgress);
        checkLambda();
    }
    else
        console.log("getData Done");
}

  function getTranscript() {
	console.log("getTranscript", transcript);
	var checkUrl = url + transcript;
    httpTranscript.open('GET', checkUrl);
	httpTranscript.send();
}

function checkLambda() {
    console.log("checkLambda", transcript);
    var checkUrl = "https://4k4smz181f.execute-api.us-east-1.amazonaws.com/Prod/" + publicId;
    httpLambda.open('GET', checkUrl);
	httpLambda.send();
}

var httpLambda = new XMLHttpRequest();
httpLambda.onreadystatechange = function() {
    if (this.readyState == 4) {
        if(this.status == 200) {
          var notify = JSON.parse(httpLambda.responseText);
          checkLambdaNotification(notify);
        }
        setTimeout(getData,4000);
    }
    else
          console.log("onreadystatechange", this.readyState, this.status);
}

var httpTranscript = new XMLHttpRequest();
httpTranscript.onreadystatechange = function() {
    if (this.readyState == 4) {
        if(this.status == 200) {
          var notify = JSON.parse(httpTranscript.responseText);
          checkTranscriptFile(notify);
        }
        setTimeout(getData,3000);
    }
    else
          console.log("onreadystatechange", this.readyState, this.status);
}

function checkLambdaNotification(notify) {
        checkTranscript(notify);
        checkTags(notify);
}

function checkTranscriptFile(notify) {
    if(transcriptComplete && getTranscriptFile && Array.isArray(notify)) {
        transcriptProgress = 99;
	getTranscriptFile = false;
	if(notify.length > 0)
	{
        	showJSON("transcript",notify);
		transcriptPlayer.source(publicId,{ transformation: {overlay: "subtitles:"+transcript}}).play();
	}
	else
		showJSON("transcript","This video clip has no detected words");
    }
}

function checkTranscript(notify) {
    if (notify.transcript.status == "pending") {
        console.log("transcript pending");
    }
    else if (notify.transcript.status == "complete") {
        transcriptComplete = true;
        console.log("transcript ready");
    }
    else
    {
        getTranscriptFile = false;
        transcriptComplete = true;
        transcriptProgress = 99;
        showJSON("transcript","There is no transcript for this video");
        console.log("no transcript");
    }
}

function checkTags(notify) {
    if (notify.tags.status == "pending")
        console.log("autotag pending");
    else if (notify.tags.status == "complete") {
        autoTagProgress = 99;
        showJSON("autotag",notify.tags.data);
    }
    else
        console.log("no autotag");
}

function showProgressBar(show,id) {
    var pre = document.getElementById("pre-"+id);
    var bar = document.getElementById(id+"-bar");
    if(show) {
        bar.setAttribute("style","");
        pre.setAttribute("style","display: none");
    }
    else {
        bar.setAttribute("style","display: none");
        pre.setAttribute("style","");
    }
}

function showError(error) {
    showJSON("autotag",error);
    showJSON("transcript",error);
}

function showJSON(id,notify) {
    var content = document.getElementById(id);
    showProgressBar(false,id);
    var data = JSON.stringify(notify);
    content.innerText = data;
    Prism.highlightElement(content);
}

function updateAutoTagProgress() {
    autoTagProgress++;
    var autoTaggingBar = document.getElementById("autoTaggingBar");
    autoTaggingBar.style.width = autoTagProgress + '%';
}

function updateTranscriptProgress() {
    transcriptProgress++;
    var transcriptBar = document.getElementById("transcriptBar");
    transcriptBar.style.width = transcriptProgress + '%';
}

var url = "https://res.cloudinary.com/demo/raw/upload/";
var publicId = "sample";
var transcript = "sample.transcript"
var getTranscriptFile = true;
var transcriptComplete = false;
var progress = 0;
var autoTagProgress = 0;
var transcriptProgress = 0;

var cld = cloudinary.Cloudinary.new({ cloud_name: 'demo' });

var players = cld.videoPlayers('.demo-manipulation', {videojs: { bigPlayButton: false, controlBar: false } });

var transcriptPlayer = cld.videoPlayer('demo-transcript-player');

var autoTagPlayer = cld.videoPlayer('demo-autotag-player');

transcriptPlayer.on('sourcechanged', function(event) {
        console.log("sourcechanged ",event);
      });

 autoTagPlayer.on('sourcechanged', function(event) {
        console.log("sourcechanged ",event);
      });

<commit_msg>Update transcode.js<commit_after>function toggleClass() {
    var theme = document.getElementById("theme-area");
    theme.classList.toggle("active");
}
function setTheme(btn) {
    var newTheme = "cld-video-player-skin-" + btn.value;
    var oldTheme = "cld-video-player-skin-";
    if(btn.value == "dark") {
        oldTheme += "light";
    }
    else {
        oldTheme += "dark";
    }
    var vplayers = document.getElementsByClassName("cld-video-player");
    for(var i = 0; i < vplayers.length; i++) {
        vplayers[i].classList.remove(oldTheme);
        vplayers[i].classList.add(newTheme);
    }
    toggleClass();
}

window.addEventListener('scroll',checkPosition,false);

function checkPosition()
{
    var themeArea = document.getElementById("theme-area");
    if(window.scrollY > 50)
    {
        themeArea.classList.add("scrolling");
    } else {
        themeArea.classList.remove("scrolling");
    }
}

function showContentBlocks() {
    var contentBlocks = document.getElementsByClassName("content-block");
    for(var i = 0; i < contentBlocks.length; i++) {
        contentBlocks[i].classList.remove("hidden");
    }
    showProgressBar(true,"transcript");
    showProgressBar(true,"autotag");
}

function initScreen() {
    getTranscriptFile = true;
    transcriptComplete = false;
    progress = 0;
    autoTagProgress = 0;
    transcriptProgress = 0;
}

function uploadVideo(){
	cloudinary.openUploadWidget({ cloud_name: 'demo', upload_preset: 'video_autotag_transcript_sd_lambda', sources: [ 'local', 'url'], multiple: false, max_file_size: 100000000, resource_type: 'video'},
      function(error, result) { processResponse(error, result); }, false);
}

function useVideo(vid) {
    console.log("useVideo",vid.title);
    initScreen();
    publicId = vid.title + "_autotag";
    transcript = publicId + ".transcript";
    updatePlayers(vid.title + "_sd");
    showContentBlocks();
    progress = 15;
    updateProgress();
    updateAutoPlayers();
}

function updateAutoPlayers() {
    autoTagPlayer.source(publicId);
    transcriptPlayer.source(publicId);
}

function processResponse(error, result) {
    console.log("processResponse",error, result);
    initScreen();
    if(result && result[0].bytes > 0 && result[0].bytes <= 100000000)
    {
        publicId = result[0].public_id;
        transcript = publicId + ".transcript";
        updatePlayers(publicId);
	showContentBlocks();
        updateProgress();
	updateAutoPlayers();
    }
    else if(result && result[0].bytes > 100000000) {
	    showContentBlocks();
            showError("Uploaded file is too big. This demo file size limit is 100MB");
    }
    else
        showError(error);
}

function updatePlayers(pid) {
    for(var i = 0; i < players.length; i++)
        players[i].source(pid);
    var links = document.getElementsByClassName("manipulation")
    for(var j = 0; j < links.length; j++) {
            var ref = links[j].getAttribute("data-href");
            links[j].setAttribute("href",ref+pid+".mp4");
    }
}

function updateProgress() {
    progress++;
    console.log("updateProgress", progress);
    if (progress == 20)
        checkLambda();
    if(autoTagProgress < 100)
        updateAutoTagProgress();
    if(transcriptProgress < 100)
        updateTranscriptProgress();
    if (autoTagProgress < 100 || transcriptProgress < 100) {
	console.log("calling updateProgress cycle",autoTagProgress,transcriptProgress);
        setTimeout(updateProgress,1500);
    }
    else
	console.log("updateProgress complete",autoTagProgress,transcriptProgress);
}

function getData() {
    if(getTranscriptFile && transcriptComplete)
        getTranscript();
    else if (autoTagProgress < 100 || transcriptProgress < 100) {
	console.log("getData autoT p",autoTagProgress,transcriptProgress);
        checkLambda();
    }
    else
        console.log("getData Done");
}

  function getTranscript() {
	console.log("getTranscript", transcript);
	var checkUrl = url + transcript;
    httpTranscript.open('GET', checkUrl);
	httpTranscript.send();
}

function checkLambda() {
    console.log("checkLambda", transcript);
    var checkUrl = "https://4k4smz181f.execute-api.us-east-1.amazonaws.com/Prod/" + publicId;
    httpLambda.open('GET', checkUrl);
	httpLambda.send();
}

var httpLambda = new XMLHttpRequest();
httpLambda.onreadystatechange = function() {
    if (this.readyState == 4) {
        if(this.status == 200) {
          var notify = JSON.parse(httpLambda.responseText);
          checkLambdaNotification(notify);
        }
        setTimeout(getData,4000);
    }
    else
          console.log("onreadystatechange", this.readyState, this.status);
}

var httpTranscript = new XMLHttpRequest();
httpTranscript.onreadystatechange = function() {
    if (this.readyState == 4) {
        if(this.status == 200) {
          var notify = JSON.parse(httpTranscript.responseText);
          checkTranscriptFile(notify);
        }
        setTimeout(getData,3000);
    }
    else
          console.log("onreadystatechange", this.readyState, this.status);
}

function checkLambdaNotification(notify) {
        checkTranscript(notify);
        checkTags(notify);
}

function checkTranscriptFile(notify) {
    if(transcriptComplete && getTranscriptFile && Array.isArray(notify)) {
        transcriptProgress = 99;
	getTranscriptFile = false;
	if(notify.length > 0)
	{
        	showJSON("transcript",notify);
		transcriptPlayer.source(publicId,{ transformation: {overlay: "subtitles:"+transcript}}).play();
	}
	else
		showJSON("transcript","This video clip has no detected words");
    }
}

function checkTranscript(notify) {
    if (notify.transcript.status == "pending") {
        console.log("transcript pending");
    }
    else if (notify.transcript.status == "complete") {
        transcriptComplete = true;
        console.log("transcript ready");
    }
    else
    {
        getTranscriptFile = false;
        transcriptComplete = true;
        transcriptProgress = 99;
        showJSON("transcript","There is no transcript for this video");
        console.log("no transcript");
    }
}

function checkTags(notify) {
    if (notify.tags.status == "pending")
        console.log("autotag pending");
    else if (notify.tags.status == "complete") {
        autoTagProgress = 99;
        showJSON("autotag",notify.tags.data);
    }
    else
        console.log("no autotag");
}

function showProgressBar(show,id) {
    var pre = document.getElementById("pre-"+id);
    var bar = document.getElementById(id+"-bar");
    if(show) {
        bar.setAttribute("style","");
        pre.setAttribute("style","display: none");
    }
    else {
        bar.setAttribute("style","display: none");
        pre.setAttribute("style","");
    }
}

function showError(error) {
    showJSON("autotag",error);
    showJSON("transcript",error);
}

function showJSON(id,notify) {
    var content = document.getElementById(id);
    showProgressBar(false,id);
    var data = JSON.stringify(notify);
    content.innerText = data;
    Prism.highlightElement(content);
}

function updateAutoTagProgress() {
    autoTagProgress++;
    var autoTaggingBar = document.getElementById("autoTaggingBar");
    autoTaggingBar.style.width = autoTagProgress + '%';
}

function updateTranscriptProgress() {
    transcriptProgress++;
    var transcriptBar = document.getElementById("transcriptBar");
    transcriptBar.style.width = transcriptProgress + '%';
}

var url = "https://res.cloudinary.com/demo/raw/upload/";
var publicId = "sample";
var transcript = "sample.transcript"
var getTranscriptFile = true;
var transcriptComplete = false;
var progress = 0;
var autoTagProgress = 0;
var transcriptProgress = 0;

var cld = cloudinary.Cloudinary.new({ cloud_name: 'demo' });

var players = cld.videoPlayers('.demo-manipulation', {videojs: { bigPlayButton: false, controlBar: false } });

var transcriptPlayer = cld.videoPlayer('demo-transcript-player');

var autoTagPlayer = cld.videoPlayer('demo-autotag-player');

transcriptPlayer.on('sourcechanged', function(event) {
        console.log("sourcechanged ",event);
      });

 autoTagPlayer.on('sourcechanged', function(event) {
        console.log("sourcechanged ",event);
      });

<|endoftext|>


<commit_before><commit_msg>remove alerts + fix indentation<commit_after><|endoftext|>


<commit_before><commit_msg>Build 0609<commit_after><|endoftext|>


<commit_before>function LineHead(tool_name, colour, thickness) {
	this.tool_name = tool_name;
	this.p_start = null;
	this.p_end = null;
	this.colour = colour;
	this.thickness = thickness;
	this.distance = 0;
}

LineHead.prototype.onMove = function(p) {
	if (this.p_start == null) {
		this.p_start = new Point(p.x, p.y);
	} else {
		this.p_end = new Point(p.x, p.y);
		drawClear(context_preview);
		drawSegment(this.p_start, this.p_end, context_preview, this.colour, this.thickness);
	}
}

LineHead.prototype.onRelease = function() {
	if (this.p_end != null) {
		var action_data = {
			points: [this.p_start, this.p_end],
			colour: this.colour,
			thickness: this.thickness,
			style: 'straight'
		}
		sendPaintEvent(this.tool_name, action_data);
		drawClear(context_preview);
	}
}<commit_msg>Maybe I fixed the line tool?<commit_after>function LineHead(tool_name, colour, thickness) {
	this.tool_name = tool_name;
	this.p_start = null;
	this.p_end = null;
	this.colour = colour;
	this.thickness = thickness;
	this.distance = 0;
}

LineHead.prototype.onMove = function(p) {
	if (this.p_start == null) {
		this.p_start = new Point(p.x, p.y);
	} else {
		this.p_end = new Point(p.x, p.y);
		drawClear(context_preview);
		drawSegment(this.p_start, this.p_end, context_preview, this.colour, this.thickness);
	}
}

LineHead.prototype.onRelease = function() {
	if (this.p_end != null) {
		var action_data = {
			points: [this.p_start, this.p_end],
			colour: this.colour,
			thickness: this.thickness,
			style: 'straight'
		}
		whiteboard.sendPaintEvent(this.tool_name, action_data);
		drawClear(context_preview);
	}
}<|endoftext|>


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

    function updateData() {
        $.getJSON('/events/' + (okular.device_uuid || 'testdevice'), function(data) {
            var now = new Date();

            $('#meeting div').html('
Room available
');
            $('#next').html('');
            $('#finish, #cancel').hide();

            var filled = false;
            $.each(data, function(index, evt) {
                var start = new Date(evt.start.dateTime),
                    end = new Date(evt.end.dateTime);
                var attendees = [evt.creator];
                if ('attendees' in evt) {
                    attendees = attendees.concat(evt.attendees);
                }
                attendees = $.map(attendees, function(a) {
                    return a.displayName || a.email;
                });
                if (start.getTime() < now.getTime() && now.getTime() < end.getTime() && !filled) {
                    $('#meeting div').html('
' + evt.summary + '

' + time(start) + '-' + time(end) + '

Atendees:

' + attendees.join(', ') + '
');
                    filled = true;
                    $('#finish, #cancel').show();
                } else {
                    $('#next').append('<button type="button" class="btn btn-success">' + time(start) + '-' + time(end) + '
' + evt.summary + '</button>');
                }
            });
        });
    }

    function time(date) {
        var hours = date.getHours(),
            minutes = date.getMinutes(),
            out = '';
        if (hours < 10)
            out += '0';
        out += hours + ':';
        if (minutes < 10)
            out += '0'

        return out + minutes;
    }

    $('#book').click(function(e) {
        $.get('/create_action/' + (okular.device_uuid || 'testdevice') + '/newevent', function(data) {
            console.log(data);
            $('#qr').show();
            //$('#qr').html('Scan this code

 or open
' + data + '
 in your browser.');
            $('#qr').html('Scan this code

');
            new QRCode("qrcode", {
                text: data,
                width: 300,
                height: 300
            });
            $('#qr').tmList();

            $('body').one('click', function() {
                $('#qr').hide();
                okular.add({
                    width: 600,
                    height: 600
                });
            });
        });
    });

    $('#cancel').click(function(e) {
        $.get('/create_action/' + (okular.device_uuid || 'testdevice') + '/cancelevent', function(data) {
            $('#qr').show();
            //$('#qr').html('Scan this code

 or open
' + data + '
 in your browser.');
            $('#qr').html('Scan this code

');
            new QRCode("qrcode", {
                text: data,
                width: 300,
                height: 300
            });
            $('#qr').tmList();

            $('body').one('click', function() {
                $('#qr').hide();
                okular.add({
                    width: 600,
                    height: 600
                });
            });
        });
    });

    $('#finish').click(function(e) {
        $.get('/create_action/' + (okular.device_uuid || 'testdevice') + '/finishevent', function(data) {
            $('#qr').show();
            //$('#qr').html('Scan this code

 or open
' + data + '
 in your browser.');
            $('#qr').html('Scan this code

');
            new QRCode("qrcode", {
                text: data,
                width: 300,
                height: 300
            });
            $('#qr').tmList();

            $('body').one('click', function() {
                $('#qr').hide();
                okular.add({
                    width: 600,
                    height: 600
                });
            });
        });
    });

    okular.init({
        width: 800,
        height: 600
    });

    updateData();
    setInterval(updateData, 60000);
});
<commit_msg>Removed the debug overlay that prevented use on desktop.<commit_after>$(document).ready(function() {

    function updateData() {
        $.getJSON('/events/' + (okular.device_uuid || 'testdevice'), function(data) {
            var now = new Date();

            $('#meeting div').html('
Room available
');
            $('#next').html('');
            $('#finish, #cancel').hide();

            var filled = false;
            $.each(data, function(index, evt) {
                var start = new Date(evt.start.dateTime),
                    end = new Date(evt.end.dateTime);
                var attendees = [evt.creator];
                if ('attendees' in evt) {
                    attendees = attendees.concat(evt.attendees);
                }
                attendees = $.map(attendees, function(a) {
                    return a.displayName || a.email;
                });
                if (start.getTime() < now.getTime() && now.getTime() < end.getTime() && !filled) {
                    $('#meeting div').html('
' + evt.summary + '

' + time(start) + '-' + time(end) + '

Atendees:

' + attendees.join(', ') + '
');
                    filled = true;
                    $('#finish, #cancel').show();
                } else {
                    $('#next').append('<button type="button" class="btn btn-success">' + time(start) + '-' + time(end) + '
' + evt.summary + '</button>');
                }
            });
        });
    }

    function time(date) {
        var hours = date.getHours(),
            minutes = date.getMinutes(),
            out = '';
        if (hours < 10)
            out += '0';
        out += hours + ':';
        if (minutes < 10)
            out += '0'

        return out + minutes;
    }

    $('#book').click(function(e) {
        $.get('/create_action/' + (okular.device_uuid || 'testdevice') + '/newevent', function(data) {
            console.log(data);
            $('#qr').show();
            //$('#qr').html('Scan this code

 or open
' + data + '
 in your browser.');
            $('#qr').html('Scan this code

');
            new QRCode("qrcode", {
                text: data,
                width: 300,
                height: 300
            });
            $('#qr').tmList();

            $('body').one('click', function() {
                $('#qr').hide();
                okular.add({
                    width: 600,
                    height: 600
                });
            });
        });
    });

    $('#cancel').click(function(e) {
        $.get('/create_action/' + (okular.device_uuid || 'testdevice') + '/cancelevent', function(data) {
            $('#qr').show();
            //$('#qr').html('Scan this code

 or open
' + data + '
 in your browser.');
            $('#qr').html('Scan this code

');
            new QRCode("qrcode", {
                text: data,
                width: 300,
                height: 300
            });
            $('#qr').tmList();

            $('body').one('click', function() {
                $('#qr').hide();
                okular.add({
                    width: 600,
                    height: 600
                });
            });
        });
    });

    $('#finish').click(function(e) {
        $.get('/create_action/' + (okular.device_uuid || 'testdevice') + '/finishevent', function(data) {
            $('#qr').show();
            //$('#qr').html('Scan this code

 or open
' + data + '
 in your browser.');
            $('#qr').html('Scan this code

');
            new QRCode("qrcode", {
                text: data,
                width: 300,
                height: 300
            });
            $('#qr').tmList();

            $('body').one('click', function() {
                $('#qr').hide();
                okular.add({
                    width: 600,
                    height: 600
                });
            });
        });
    });

    okular.init({
        width: 800,
        height: 600,
        debug: false
    });

    updateData();
    setInterval(updateData, 60000);
});
<|endoftext|>