<commit_before>/**
 * Copyright 2013 Google, Inc.
 * Copyright 2015 Vivliostyle Inc.
 * @fileoverview Vivliostyle page viewer base on adapt.sampleapp
 */
goog.provide('adapt.vivliostyle');

goog.require('adapt.base');
goog.require('adapt.viewer');

/** @type {number} */ adapt.vivliostyle.fontSize = 16;
/** @type {boolean} */ adapt.vivliostyle.touchActive = false;
/** @type {number} */ adapt.vivliostyle.touchX = 0;
/** @type {number} */ adapt.vivliostyle.touchY = 0;
/** @type {boolean} */ adapt.vivliostyle.zoomActive = false;
/** @type {number} */ adapt.vivliostyle.pinchDist = 0;

/**
 * @param {adapt.base.JSON} cmd
 */
adapt.vivliostyle.sendCommand = function(cmd) {
	window["adapt_command"](cmd);
};

/**
 * @param {KeyboardEvent} evt
 * @return {void}
 */
adapt.vivliostyle.keydown = function(evt) {
    switch (evt.keyCode) {
    case 35:  // end
    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "last"});
    	break;
    case 36:  // home
    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "first"});
    	break;
    case 39:  // right arrow
    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "next"});
        break;
    case 37:  // left arrow
    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "previous"});
        break;
    case 48:  // zero
    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
    	break;
    	/*
    case 78:  // N - night toggle
    	self.pref.nightMode = !self.pref.nightMode;
    	self.viewport = null;
    	self.resize().thenFinish(frame);
    	break;
    case 86:  // V - vertical toggle
    	self.pref.horizontal = !self.pref.horizontal;
    	self.viewport = null;
    	self.resize().thenFinish(frame);
    	break;
    	*/
    case 84: // 'T' - show TOC
    	adapt.vivliostyle.sendCommand({"a": "toc", "v": "toggle", "autohide": true});
    	break;
    case 187:  // plus
    	adapt.vivliostyle.fontSize *= 1.2;
    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
    	break;
    case 189:  // minus
    	adapt.vivliostyle.fontSize /= 1.2;
    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
    	break;
    }
};

/**
 * @param {TouchEvent} evt
 * @return {void}
 */
adapt.vivliostyle.touch = function(evt) {
	if (evt.type == "touchmove") {
		evt.preventDefault();
	}
	if (evt.touches.length == 1) {
		var x = evt.touches[0].pageX;
		var y = evt.touches[0].pageY;
		if (evt.type == "touchstart") {
			adapt.vivliostyle.touchActive = true;
			adapt.vivliostyle.touchX = x;
			adapt.vivliostyle.touchY = y;
		} else if (adapt.vivliostyle.touchActive) {
			var dx = x - adapt.vivliostyle.touchX;
			var dy = y - adapt.vivliostyle.touchY;
			if (evt.type == "touchend") {
				adapt.vivliostyle.touchActive = false;
			}
			if (Math.abs(dy) < 0.5 * Math.abs(dx) && Math.abs(dx) > 15) {
				adapt.vivliostyle.touchActive = false;
				if (dx > 0) {
			    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "previous"});
				} else {
			    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "next"});
				}
			}
		}
	} else if (evt.touches.length == 2) {
		var px = evt.touches[0].pageX - evt.touches[1].pageX;
		var py = evt.touches[0].pageY - evt.touches[1].pageY;
		var pinchDist = Math.sqrt(px*px + py*py);
		if (evt.type == "touchstart") {
			adapt.vivliostyle.zoomActive = true;
			adapt.vivliostyle.zoomDist = pinchDist;
		} else if (adapt.vivliostyle.zoomActive) {
			if (evt.type == "touchend") {
				adapt.vivliostyle.zoomActive = false;
			}
			var scale = pinchDist / adapt.vivliostyle.zoomDist;
			if (scale > 1.5) {
		    	adapt.vivliostyle.fontSize *= 1.2;
		    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
			} else if (scale < 1/1.5) {
		    	adapt.vivliostyle.fontSize *= 1.2;
		    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
			}
		}
	}
};

adapt.vivliostyle.callback = function(msg) {
	switch (msg["t"]) {
	case "error" :
		adapt.base.log("Error: " + msg["content"]);
		break;
	case "nav" :
		var cfi = msg["cfi"];
		if (cfi) {
			location.replace(adapt.base.setURLParam(location.href,
				"f", adapt.base.lightURLEncode(cfi || "")));
		}
		break;
	case "hyperlink" :
		if (msg["internal"]) {
	    	adapt.vivliostyle.sendCommand({"a": "moveTo", "url": msg["href"]});
		}
	}
};

/**
 * @param {?string} width
 * @param {?string} height
 * @param {?string} size
 * @param {?string} orientation
 * @param {!Object.<string, *>} config
 * @return {void}
 */
function setViewportSize(width, height, size, orientation, config) {
    var pageSpec;
    if (!width || !height) {
        switch (size) {
            case "A5":
                width = "148mm";
                height = "210mm";
                break;
            case "A4":
                width = "210mm";
                height = "297mm";
                break;
            case "A3":
                width = "297mm";
                height = "420mm";
                break;
            case "B5":
                width = "176mm";
                height = "250mm";
                break;
            case "B4":
                width = "250mm";
                height = "353mm";
                break;
            case "letter":
                width = "8.5in";
                height = "11in";
                break;
            case "legal":
                width = "8.5in";
                height = "14in";
                break;
            case "ledger":
                width = "11in";
                height = "17in";
                break;
        }
        if (width && height) {
            pageSpec = size;
            if (orientation === "landscape") {
                pageSpec = pageSpec ? pageSpec + " landscape" : null;
                // swap
                var tmp = width;
                width = height;
                height = tmp;
            }
        }
    } else {
        pageSpec = width + " " + height;
    }

    if (width && height) {
        config.viewport = {"width": width, "height": height};
        var s = document.createElement("style");
        s.textContent = "@page { size: " + pageSpec + "; margin: 0; }";
        document.head.appendChild(s);
    }
}

/**
 * @return {void}
 */
adapt.vivliostyle.main = function(arg) {
    var fragment = (arg && arg.fragment) || adapt.base.getURLParam("f");
    var epubURL = (arg && arg.epubURL) || adapt.base.getURLParam("b");
    var xmlURL = (arg && arg.xmlURL) || adapt.base.getURLParam("x");
    var width = (arg && arg.defaultPageWidth) || adapt.base.getURLParam("w");
    var height = (arg && arg.defaultPageHeight) || adapt.base.getURLParam("h");
    var size = (arg && arg.defaultPageSize) || adapt.base.getURLParam("size");
    var orientation = (arg && arg.orientation) || adapt.base.getURLParam("orientation");
    var uaRoot = (arg && arg.uaRoot) || null;
    var doc = (arg && arg.document) || null;
	var viewer = new adapt.viewer.Viewer(window, "main", adapt.vivliostyle.callback);

    var config = {
        "autoresize": true,
        "fragment": fragment,
        // render all pages on load and resize
        "renderAllPages": true,
        "userAgentRootURL": uaRoot,
        "document": doc
    };
    setViewportSize(width, height, size, orientation, config);
    config["a"] = epubURL ? "loadEPUB" : "loadXML";
    config["url"] = epubURL || xmlURL;

    viewer.initEmbed(config);

    window.addEventListener("keydown", /** @type {Function} */ (adapt.vivliostyle.keydown), false);
    window.addEventListener("touchstart", /** @type {Function} */ (adapt.vivliostyle.touch), false);
    window.addEventListener("touchmove", /** @type {Function} */ (adapt.vivliostyle.touch), false);
    window.addEventListener("touchend", /** @type {Function} */ (adapt.vivliostyle.touch), false);
};
<commit_msg>Export entry point on compilation<commit_after>/**
 * Copyright 2013 Google, Inc.
 * Copyright 2015 Vivliostyle Inc.
 * @fileoverview Vivliostyle page viewer base on adapt.sampleapp
 */
goog.provide('adapt.vivliostyle');

goog.require('adapt.base');
goog.require('adapt.viewer');

/** @type {number} */ adapt.vivliostyle.fontSize = 16;
/** @type {boolean} */ adapt.vivliostyle.touchActive = false;
/** @type {number} */ adapt.vivliostyle.touchX = 0;
/** @type {number} */ adapt.vivliostyle.touchY = 0;
/** @type {boolean} */ adapt.vivliostyle.zoomActive = false;
/** @type {number} */ adapt.vivliostyle.pinchDist = 0;

/**
 * @param {adapt.base.JSON} cmd
 */
adapt.vivliostyle.sendCommand = function(cmd) {
	window["adapt_command"](cmd);
};

/**
 * @param {KeyboardEvent} evt
 * @return {void}
 */
adapt.vivliostyle.keydown = function(evt) {
    switch (evt.keyCode) {
    case 35:  // end
    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "last"});
    	break;
    case 36:  // home
    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "first"});
    	break;
    case 39:  // right arrow
    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "next"});
        break;
    case 37:  // left arrow
    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "previous"});
        break;
    case 48:  // zero
    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
    	break;
    	/*
    case 78:  // N - night toggle
    	self.pref.nightMode = !self.pref.nightMode;
    	self.viewport = null;
    	self.resize().thenFinish(frame);
    	break;
    case 86:  // V - vertical toggle
    	self.pref.horizontal = !self.pref.horizontal;
    	self.viewport = null;
    	self.resize().thenFinish(frame);
    	break;
    	*/
    case 84: // 'T' - show TOC
    	adapt.vivliostyle.sendCommand({"a": "toc", "v": "toggle", "autohide": true});
    	break;
    case 187:  // plus
    	adapt.vivliostyle.fontSize *= 1.2;
    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
    	break;
    case 189:  // minus
    	adapt.vivliostyle.fontSize /= 1.2;
    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
    	break;
    }
};

/**
 * @param {TouchEvent} evt
 * @return {void}
 */
adapt.vivliostyle.touch = function(evt) {
	if (evt.type == "touchmove") {
		evt.preventDefault();
	}
	if (evt.touches.length == 1) {
		var x = evt.touches[0].pageX;
		var y = evt.touches[0].pageY;
		if (evt.type == "touchstart") {
			adapt.vivliostyle.touchActive = true;
			adapt.vivliostyle.touchX = x;
			adapt.vivliostyle.touchY = y;
		} else if (adapt.vivliostyle.touchActive) {
			var dx = x - adapt.vivliostyle.touchX;
			var dy = y - adapt.vivliostyle.touchY;
			if (evt.type == "touchend") {
				adapt.vivliostyle.touchActive = false;
			}
			if (Math.abs(dy) < 0.5 * Math.abs(dx) && Math.abs(dx) > 15) {
				adapt.vivliostyle.touchActive = false;
				if (dx > 0) {
			    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "previous"});
				} else {
			    	adapt.vivliostyle.sendCommand({"a": "moveTo", "where": "next"});
				}
			}
		}
	} else if (evt.touches.length == 2) {
		var px = evt.touches[0].pageX - evt.touches[1].pageX;
		var py = evt.touches[0].pageY - evt.touches[1].pageY;
		var pinchDist = Math.sqrt(px*px + py*py);
		if (evt.type == "touchstart") {
			adapt.vivliostyle.zoomActive = true;
			adapt.vivliostyle.zoomDist = pinchDist;
		} else if (adapt.vivliostyle.zoomActive) {
			if (evt.type == "touchend") {
				adapt.vivliostyle.zoomActive = false;
			}
			var scale = pinchDist / adapt.vivliostyle.zoomDist;
			if (scale > 1.5) {
		    	adapt.vivliostyle.fontSize *= 1.2;
		    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
			} else if (scale < 1/1.5) {
		    	adapt.vivliostyle.fontSize *= 1.2;
		    	adapt.vivliostyle.sendCommand({"a": "configure", "fontSize": Math.round(adapt.vivliostyle.fontSize)});
			}
		}
	}
};

adapt.vivliostyle.callback = function(msg) {
	switch (msg["t"]) {
	case "error" :
		adapt.base.log("Error: " + msg["content"]);
		break;
	case "nav" :
		var cfi = msg["cfi"];
		if (cfi) {
			location.replace(adapt.base.setURLParam(location.href,
				"f", adapt.base.lightURLEncode(cfi || "")));
		}
		break;
	case "hyperlink" :
		if (msg["internal"]) {
	    	adapt.vivliostyle.sendCommand({"a": "moveTo", "url": msg["href"]});
		}
	}
};

/**
 * @param {?string} width
 * @param {?string} height
 * @param {?string} size
 * @param {?string} orientation
 * @param {!Object.<string, *>} config
 * @return {void}
 */
function setViewportSize(width, height, size, orientation, config) {
    var pageSpec;
    if (!width || !height) {
        switch (size) {
            case "A5":
                width = "148mm";
                height = "210mm";
                break;
            case "A4":
                width = "210mm";
                height = "297mm";
                break;
            case "A3":
                width = "297mm";
                height = "420mm";
                break;
            case "B5":
                width = "176mm";
                height = "250mm";
                break;
            case "B4":
                width = "250mm";
                height = "353mm";
                break;
            case "letter":
                width = "8.5in";
                height = "11in";
                break;
            case "legal":
                width = "8.5in";
                height = "14in";
                break;
            case "ledger":
                width = "11in";
                height = "17in";
                break;
        }
        if (width && height) {
            pageSpec = size;
            if (orientation === "landscape") {
                pageSpec = pageSpec ? pageSpec + " landscape" : null;
                // swap
                var tmp = width;
                width = height;
                height = tmp;
            }
        }
    } else {
        pageSpec = width + " " + height;
    }

    if (width && height) {
        config.viewport = {"width": width, "height": height};
        var s = document.createElement("style");
        s.textContent = "@page { size: " + pageSpec + "; margin: 0; }";
        document.head.appendChild(s);
    }
}

/**
 * @return {void}
 */
adapt.vivliostyle.main = function(arg) {
    var fragment = (arg && arg.fragment) || adapt.base.getURLParam("f");
    var epubURL = (arg && arg.epubURL) || adapt.base.getURLParam("b");
    var xmlURL = (arg && arg.xmlURL) || adapt.base.getURLParam("x");
    var width = (arg && arg.defaultPageWidth) || adapt.base.getURLParam("w");
    var height = (arg && arg.defaultPageHeight) || adapt.base.getURLParam("h");
    var size = (arg && arg.defaultPageSize) || adapt.base.getURLParam("size");
    var orientation = (arg && arg.orientation) || adapt.base.getURLParam("orientation");
    var uaRoot = (arg && arg.uaRoot) || null;
    var doc = (arg && arg.document) || null;
	var viewer = new adapt.viewer.Viewer(window, "main", adapt.vivliostyle.callback);

    var config = {
        "autoresize": true,
        "fragment": fragment,
        // render all pages on load and resize
        "renderAllPages": true,
        "userAgentRootURL": uaRoot,
        "document": doc
    };
    setViewportSize(width, height, size, orientation, config);
    config["a"] = epubURL ? "loadEPUB" : "loadXML";
    config["url"] = epubURL || xmlURL;

    viewer.initEmbed(config);

    window.addEventListener("keydown", /** @type {Function} */ (adapt.vivliostyle.keydown), false);
    window.addEventListener("touchstart", /** @type {Function} */ (adapt.vivliostyle.touch), false);
    window.addEventListener("touchmove", /** @type {Function} */ (adapt.vivliostyle.touch), false);
    window.addEventListener("touchend", /** @type {Function} */ (adapt.vivliostyle.touch), false);
};

goog.exportSymbol("adapt.vivliostyle.main", adapt.vivliostyle.main);
<|endoftext|>


<commit_before>/**
 * This file is part of the Spryker Demoshop.
 * For full license information, please view the LICENSE file that was distributed with this source code.
 */

'use strict';

// add your custom common js here
// and/or change the existing one

var $ = require('jquery');
var run = require('../lib/run');

function setJsEnabledMode() {
    $('html')
        .removeClass('no-js')
        .addClass('js');
}

$(function(){
    setJsEnabledMode();

    run([
        require('./components/aside'),
        require('./components/toggle'),
        require('./components/viewer'),
        require('./components/suggestions')
    ]);
});
<commit_msg>remove custom toggler<commit_after>/**
 * This file is part of the Spryker Demoshop.
 * For full license information, please view the LICENSE file that was distributed with this source code.
 */

'use strict';

// add your custom common js here
// and/or change the existing one

var run = require('../lib/run');

function setJsEnabledMode() {
    $('html')
        .removeClass('no-js')
        .addClass('js');
}

$(function(){
    setJsEnabledMode();

    run([
        require('./components/aside'),
        require('./components/viewer'),
        require('./components/suggestions')
    ]);
});
<|endoftext|>


<commit_before>class Checkout {
    constructor() {

        this.params = this.getParams('vendor/nails/driver-invoice-stripe/assets/js/checkout.min.js');

        //  Prepare the form
        //  Replace the input with a

        let id = '#stripe-elements-' + this.params.hash;
        let $original = $(id);

        this.$form = $('#js-invoice-main-form');
        this.$input = $('<input>').attr('type', 'hidden').attr('name', $original.attr('name'));
        this.$elements = $('
').attr('id', id.replace(/^#/, '')).addClass('input')
        this.$error = $('
').addClass('form__error');

        this
            .$group = $('
')
            .append(this.$input)
            .append(this.$elements)
            .append(this.$error);

        $original
            .replaceWith(this.$group);

        //  Build Stripe element
        this.stripe = Stripe(this.params.key);
        this.elements = this.stripe.elements();

        // Create an instance of the card Element.
        this.card = this.elements.create('card');

        //  Bind to the DOM
        this.card.mount(id);

        //  Show user errors
        this
            .card
            .addEventListener('change', (e) => {
                if (e.error) {
                    this.showError(e.error.message);
                } else {
                    this.hideError();
                }
            });

        //  Bind to form submission
        this
            .$form
            .on('submit', (e) => {

                //  @todo (Pablo - 2019-07-22) - Disable the form (prevent double submission)

                if (this.$input.val().length === 0) {

                    e.preventDefault();

                    this
                        .stripe
                        .createToken(this.card)
                        .then((result) => {
                            if (result.error) {
                                this.showError(result.error.message);
                            } else {
                                this.hideError()
                                this.$input.val(result.token.id);
                                this.$form.submit();
                            }
                        });
                }
            })
    }

    // --------------------------------------------------------------------------

    showError(error) {
        this.$error.html(error);
        this.$elements.addClass('has-error');
    }

    // --------------------------------------------------------------------------

    hideError() {
        this.$error.html('');
        this.$elements.removeClass('has-error');
    }

    // --------------------------------------------------------------------------

    /**
     * Returns the parameters passed to the script
     * @param {String} script_name The name of the script
     * @returns {{}}
     */
    getParams(script_name) {

        // Find all script tags
        var scripts = document.getElementsByTagName("script");

        // Look through them trying to find ourselves
        for (let i = 0; i < scripts.length; i++) {
            if (scripts[i].src.indexOf("/" + script_name) > -1) {
                // Get an array of key=value strings of params
                let pa = scripts[i].src.split("?").pop().split("&");

                // Split each key=value into array, the construct js object
                let p = {};
                for (let j = 0; j < pa.length; j++) {
                    let kv = pa[j].split("=");
                    p[kv[0]] = kv[1];
                }
                return p;
            }
        }

        // No scripts match
        return {};
    }
}

export default Checkout;
<commit_msg>Disabling form during checkout<commit_after>class Checkout {
    constructor() {

        this.params = this.getParams('vendor/nails/driver-invoice-stripe/assets/js/checkout.min.js');

        //  Prepare the form
        //  Replace the input with a

        let id = '#stripe-elements-' + this.params.hash;
        let $original = $(id);

        this.$form = $('#js-invoice-main-form');
        this.$input = $('<input>').attr('type', 'hidden').attr('name', $original.attr('name'));
        this.$elements = $('
').attr('id', id.replace(/^#/, '')).addClass('input')
        this.$error = $('
').addClass('form__error');

        this
            .$group = $('
')
            .append(this.$input)
            .append(this.$elements)
            .append(this.$error);

        $original
            .replaceWith(this.$group);

        //  Build Stripe element
        this.stripe = Stripe(this.params.key);
        this.elements = this.stripe.elements();

        // Create an instance of the card Element.
        this.card = this.elements.create('card');

        //  Bind to the DOM
        this.card.mount(id);

        //  Show user errors
        this
            .card
            .addEventListener('change', (e) => {
                if (e.error) {
                    this.showError(e.error.message);
                } else {
                    this.hideError();
                }
            });

        //  Bind to form submission
        this
            .$form
            .on('submit', (e) => {

                if (this.$input.val().length === 0) {

                    e.preventDefault();
                    $('#js-invoice-pay-now')
                        .addClass('btn--working')
                        .prop('disabled', true);

                    this
                        .stripe
                        .createToken(this.card)
                        .then((result) => {

                            if (result.error) {

                                this.showError(result.error.message);
                                $('#js-invoice-pay-now')
                                    .removeClass('btn--working')
                                    .prop('disabled', false);

                            } else {

                                this.hideError()
                                this.$input.val(result.token.id);
                                this.$form.submit();
                            }
                        });
                }
            })
    }

    // --------------------------------------------------------------------------

    showError(error) {
        this.$error.html(error);
        this.$elements.addClass('has-error');
    }

    // --------------------------------------------------------------------------

    hideError() {
        this.$error.html('');
        this.$elements.removeClass('has-error');
    }

    // --------------------------------------------------------------------------

    /**
     * Returns the parameters passed to the script
     * @param {String} script_name The name of the script
     * @returns {{}}
     */
    getParams(script_name) {

        // Find all script tags
        var scripts = document.getElementsByTagName("script");

        // Look through them trying to find ourselves
        for (let i = 0; i < scripts.length; i++) {
            if (scripts[i].src.indexOf("/" + script_name) > -1) {
                // Get an array of key=value strings of params
                let pa = scripts[i].src.split("?").pop().split("&");

                // Split each key=value into array, the construct js object
                let p = {};
                for (let j = 0; j < pa.length; j++) {
                    let kv = pa[j].split("=");
                    p[kv[0]] = kv[1];
                }
                return p;
            }
        }

        // No scripts match
        return {};
    }
}

export default Checkout;
<|endoftext|>


<commit_before>/*! jQuery Validation Plugin - v1.14.0 - 6/30/2015
 * http://jqueryvalidation.org/
 * Copyright (c) 2015 Jörn Zaefferer; Licensed MIT */
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return c.settings.submitHandler?(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e?e:!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,d=d.concat(c.errorList)}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){return!!a.trim(""+a(b).val())},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||-1!==a.inArray(c.keyCode,d)||(b.name in this.submitted||b===this.lastElement)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c=this.clean(b),d=this.validationTargetFor(c),e=!0;return this.lastElement=d,void 0===d?delete this.invalid[c.name]:(this.prepareElement(d),this.currentElements=a(d),e=this.check(d)!==!1,e?delete this.invalid[d.name]:this.invalid[d.name]=!0),a(b).attr("aria-invalid",!e),this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),e},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors();var b,c=this.elements().removeData("previousValue").removeAttr("aria-invalid");if(this.settings.unhighlight)for(b=0;c[b];b++)this.settings.unhighlight.call(this,c[b],this.settings.errorClass,"");else c.removeClass(this.settings.errorClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d=a(b),e=b.type;return"radio"===e||"checkbox"===e?this.findByName(b.name).filter(":checked").val():"number"===e&&"undefined"!=typeof b.validity?b.validity.badInput?!1:d.val():(c=d.val(),"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j instanceof TypeError&&(j.message+=".  Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a];return void 0},defaultMessage:function(b,c){return this.findDefined(this.customMessage(b.name,c),this.customDataMessage(b,c),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c],"Warning: No message defined for "+b.name+"")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b,method:c.method}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g=this.errorsFor(b),h=this.idOrName(b),i=a(b).attr("aria-describedby");g.length?(g.removeClass(this.settings.validClass).addClass(this.settings.errorClass),g.html(c)):(g=a("<"+this.settings.errorElement+">").attr("id",h+"-error").addClass(this.settings.errorClass).html(c||""),d=g,this.settings.wrapper&&(d=g.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),g.is("label")?g.attr("for",h):0===g.parents("label[for='"+h+"']").length&&(f=g.attr("id").replace(/(:|\.|\[|\]|\$)/g,"\\$1"),i?i.match(new RegExp("\\b"+f+"\\b"))||(i+=" "+f):i=f,a(b).attr("aria-describedby",i),e=this.groups[b.name],e&&a.each(this.groups,function(b,c){c===e&&a("[name='"+b+"']",this.currentForm).attr("aria-describedby",g.attr("id"))}))),!c&&this.settings.success&&(g.text(""),"string"==typeof this.settings.success?g.addClass(this.settings.success):this.settings.success(g,b)),this.toShow=this.toShow.add(g)},errorsFor:function(b){var c=this.idOrName(b),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+d.replace(/\s+/g,", #")),this.errors().filter(e)},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+b+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.off(".validate-equalTo").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e,f,g=this.previousValue(c);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),g.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=g.message,d="string"==typeof d&&{url:d}||d,g.old===b?g.valid:(g.old=b,e=this,this.startRequest(c),f={},f[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:f,context:e.currentForm,success:function(d){var f,h,i,j=d===!0||"true"===d;e.settings.messages[c.name].remote=g.originalMessage,j?(i=e.formSubmitted,e.prepareElement(c),e.formSubmitted=i,e.successList.push(c),delete e.invalid[c.name],e.showErrors()):(f={},h=d||e.defaultMessage(c,"remote"),f[c.name]=g.message=a.isFunction(h)?h(b):h,e.invalid[c.name]=!0,e.showErrors(f)),g.valid=j,e.stopRequest(c,j)}},d)),"pending")}}});var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)})});<commit_msg>mundaçande pasta 09:24 - 02/10/15<commit_after><|endoftext|>


<commit_before>/**
 *
 * Mixes together the AnimationClips scheduled by AnimationActions and applies them to the root and subtree
 *
 *
 * @author Ben Houston / http://clara.io/
 * @author David Sarno / http://lighthaus.us/
 */

THREE.AnimationMixer = function( root ) {

	this.root = root;
	this.time = 0;
	this.timeScale = 1.0;
	this.actions = [];
	this.propertyBindings = [];

};

THREE.AnimationMixer.prototype = {

	constructor: THREE.AnimationMixer,

	addAction: function( action ) {

		// TODO: check for duplicate action names?  Or provide each action with a UUID?

		this.actions.push( action );
		action.mixer = this;

		var tracks = action.clip.tracks;

		var root = action.localRoot || this.root;

		for( var i = 0; i < tracks.length; i ++ ) {

			var track = tracks[ i ];

			var j = this.getPropertyBindingIndex( root, track.name )

			var propertyBinding;

			if( j < 0 ) {

				propertyBinding = new THREE.PropertyBinding( root, track.name );
				this.propertyBindings.push( propertyBinding );

			}
			else {
				propertyBinding = this.propertyBindings[ j ];
			}

			// track usages of shared property bindings, because if we leave too many around, the mixer can get slow
			propertyBinding.referenceCount += 1;

		}

		this.updatePropertyBindingIndices();

	},

	getPropertyBindingIndex: function( rootNode, trackName ) {

		for( var k = 0; k < this.propertyBindings.length; k ++ ) {
			if( this.propertyBindings[k].trackName === trackName &&
				this.propertyBindings[k].rootNode === rootNode ) {
				return k;
			}
		}

		return -1;

	},

	updatePropertyBindingIndices: function() {

		for( var i = 0; i < this.actions.length; i++ ) {

			var action = this.actions[i];

			var root = action.localRoot || this.root;

			var propertyBindingIndices = [];

			for( var j = 0; j < action.clip.tracks.length; j ++ ) {

				var trackName = action.clip.tracks[j].name;
				propertyBindingIndices.push( this.getPropertyBindingIndex( root, trackName ) );

			}

			action.propertyBindingIndices = propertyBindingIndices;
		}

	},

	removeAllActions: function() {

		for( var i = 0; i < this.actions.length; i ++ ) {

			this.actions[i].mixer = null;

		}

		// unbind all property bindings
		for( var i = 0; i < this.propertyBindings.length; i ++ ) {

			this.propertyBindings[i].unbind();

		}

		this.actions = [];
		this.propertyBindings = [];

		return this;

	},

	removeAction: function( action ) {

		var index = this.actions.indexOf( action );

		if ( index !== - 1 ) {

			this.actions.splice( index, 1 );
			action.mixer = null;

		}

		// remove unused property bindings because if we leave them around the mixer can get slow
		var root = action.localRoot || this.root;
		var tracks = action.clip.tracks;

		for( var i = 0; i < tracks.length; i ++ ) {

			var track = tracks[ i ];
			var propertyBindingIndex = this.getPropertyBindingIndex( root, track.name );
			var propertyBinding = this.propertyBindings[ propertyBindingIndex ];

			propertyBinding.referenceCount -= 1;

			if( propertyBinding.referenceCount <= 0 ) {

				propertyBinding.unbind();

				this.propertyBindings.splice( this.propertyBindings.indexOf( propertyBinding ), 1 );

			}
		}

		this.updatePropertyBindingIndices();

		return this;

	},

	// can be optimized if needed
	findActionByName: function( name ) {

		for( var i = 0; i < this.actions.length; i ++ ) {

			if( this.actions[i].name === name ) return this.actions[i];

		}

		return null;

	},

	play: function( action, optionalFadeInDuration ) {

		action.startTime = this.time;
		this.addAction( action );

		return this;

	},

	fadeOut: function( action, duration ) {

		var keys = [];

		keys.push( { time: this.time, value: 1 } );
		keys.push( { time: this.time + duration, value: 0 } );

		action.weight = new THREE.NumberKeyframeTrack( "weight", keys );

		return this;

	},

	fadeIn: function( action, duration ) {

		var keys = [];

		keys.push( { time: this.time, value: 0 } );
		keys.push( { time: this.time + duration, value: 1 } );

		action.weight = new THREE.NumberKeyframeTrack( "weight", keys );

		return this;

	},

	warp: function( action, startTimeScale, endTimeScale, duration ) {

		var keys = [];

		keys.push( { time: this.time, value: startTimeScale } );
		keys.push( { time: this.time + duration, value: endTimeScale } );

		action.timeScale = new THREE.NumberKeyframeTrack( "timeScale", keys );

		return this;

	},

	crossFade: function( fadeOutAction, fadeInAction, duration, warp ) {

		this.fadeOut( fadeOutAction, duration );
		this.fadeIn( fadeInAction, duration );

		if( warp ) {

			var startEndRatio = fadeOutAction.clip.duration / fadeInAction.clip.duration;
			var endStartRatio = 1.0 / startEndRatio;

			this.warp( fadeOutAction, 1.0, startEndRatio, duration );
			this.warp( fadeInAction, endStartRatio, 1.0, duration );

		}

		return this;

	},

	update: function( deltaTime ) {

		var mixerDeltaTime = deltaTime * this.timeScale;
		this.time += mixerDeltaTime;

		for( var i = 0; i < this.actions.length; i ++ ) {

			var action = this.actions[i];

			var weight = action.getWeightAt( this.time );

			var actionTimeScale = action.getTimeScaleAt( this.time );
			var actionDeltaTime = mixerDeltaTime * actionTimeScale;

			var actionResults = action.update( actionDeltaTime );

			if( action.weight <= 0 || ! action.enabled ) continue;

			for( var j = 0; j < actionResults.length; j ++ ) {

				var name = action.clip.tracks[j].name;

				this.propertyBindings[ action.propertyBindingIndices[ j ] ].accumulate( actionResults[j], weight );

			}

		}

		// apply to nodes
		for ( var i = 0; i < this.propertyBindings.length; i ++ ) {

			this.propertyBindings[ i ].apply();

		}

		return this;

	}

};

THREE.EventDispatcher.prototype.apply( THREE.AnimationMixer.prototype );
<commit_msg>fix bug, not calling AnimationAction.init.<commit_after>/**
 *
 * Mixes together the AnimationClips scheduled by AnimationActions and applies them to the root and subtree
 *
 *
 * @author Ben Houston / http://clara.io/
 * @author David Sarno / http://lighthaus.us/
 */

THREE.AnimationMixer = function( root ) {

	this.root = root;
	this.time = 0;
	this.timeScale = 1.0;
	this.actions = [];
	this.propertyBindings = [];

};

THREE.AnimationMixer.prototype = {

	constructor: THREE.AnimationMixer,

	addAction: function( action ) {

		// TODO: check for duplicate action names?  Or provide each action with a UUID?

		this.actions.push( action );
		action.init( this.time );
		action.mixer = this;

		var tracks = action.clip.tracks;

		var root = action.localRoot || this.root;

		for( var i = 0; i < tracks.length; i ++ ) {

			var track = tracks[ i ];

			var j = this.getPropertyBindingIndex( root, track.name )

			var propertyBinding;

			if( j < 0 ) {

				propertyBinding = new THREE.PropertyBinding( root, track.name );
				this.propertyBindings.push( propertyBinding );

			}
			else {
				propertyBinding = this.propertyBindings[ j ];
			}

			// track usages of shared property bindings, because if we leave too many around, the mixer can get slow
			propertyBinding.referenceCount += 1;

		}

		this.updatePropertyBindingIndices();

	},

	getPropertyBindingIndex: function( rootNode, trackName ) {

		for( var k = 0; k < this.propertyBindings.length; k ++ ) {
			if( this.propertyBindings[k].trackName === trackName &&
				this.propertyBindings[k].rootNode === rootNode ) {
				return k;
			}
		}

		return -1;

	},

	updatePropertyBindingIndices: function() {

		for( var i = 0; i < this.actions.length; i++ ) {

			var action = this.actions[i];

			var root = action.localRoot || this.root;

			var propertyBindingIndices = [];

			for( var j = 0; j < action.clip.tracks.length; j ++ ) {

				var trackName = action.clip.tracks[j].name;
				propertyBindingIndices.push( this.getPropertyBindingIndex( root, trackName ) );

			}

			action.propertyBindingIndices = propertyBindingIndices;
		}

	},

	removeAllActions: function() {

		for( var i = 0; i < this.actions.length; i ++ ) {

			this.actions[i].mixer = null;

		}

		// unbind all property bindings
		for( var i = 0; i < this.propertyBindings.length; i ++ ) {

			this.propertyBindings[i].unbind();

		}

		this.actions = [];
		this.propertyBindings = [];

		return this;

	},

	removeAction: function( action ) {

		var index = this.actions.indexOf( action );

		if ( index !== - 1 ) {

			this.actions.splice( index, 1 );
			action.mixer = null;

		}

		// remove unused property bindings because if we leave them around the mixer can get slow
		var root = action.localRoot || this.root;
		var tracks = action.clip.tracks;

		for( var i = 0; i < tracks.length; i ++ ) {

			var track = tracks[ i ];
			var propertyBindingIndex = this.getPropertyBindingIndex( root, track.name );
			var propertyBinding = this.propertyBindings[ propertyBindingIndex ];

			propertyBinding.referenceCount -= 1;

			if( propertyBinding.referenceCount <= 0 ) {

				propertyBinding.unbind();

				this.propertyBindings.splice( this.propertyBindings.indexOf( propertyBinding ), 1 );

			}
		}

		this.updatePropertyBindingIndices();

		return this;

	},

	// can be optimized if needed
	findActionByName: function( name ) {

		for( var i = 0; i < this.actions.length; i ++ ) {

			if( this.actions[i].name === name ) return this.actions[i];

		}

		return null;

	},

	play: function( action, optionalFadeInDuration ) {

		action.startTime = this.time;
		this.addAction( action );

		return this;

	},

	fadeOut: function( action, duration ) {

		var keys = [];

		keys.push( { time: this.time, value: 1 } );
		keys.push( { time: this.time + duration, value: 0 } );

		action.weight = new THREE.NumberKeyframeTrack( "weight", keys );

		return this;

	},

	fadeIn: function( action, duration ) {

		var keys = [];

		keys.push( { time: this.time, value: 0 } );
		keys.push( { time: this.time + duration, value: 1 } );

		action.weight = new THREE.NumberKeyframeTrack( "weight", keys );

		return this;

	},

	warp: function( action, startTimeScale, endTimeScale, duration ) {

		var keys = [];

		keys.push( { time: this.time, value: startTimeScale } );
		keys.push( { time: this.time + duration, value: endTimeScale } );

		action.timeScale = new THREE.NumberKeyframeTrack( "timeScale", keys );

		return this;

	},

	crossFade: function( fadeOutAction, fadeInAction, duration, warp ) {

		this.fadeOut( fadeOutAction, duration );
		this.fadeIn( fadeInAction, duration );

		if( warp ) {

			var startEndRatio = fadeOutAction.clip.duration / fadeInAction.clip.duration;
			var endStartRatio = 1.0 / startEndRatio;

			this.warp( fadeOutAction, 1.0, startEndRatio, duration );
			this.warp( fadeInAction, endStartRatio, 1.0, duration );

		}

		return this;

	},

	update: function( deltaTime ) {

		var mixerDeltaTime = deltaTime * this.timeScale;
		this.time += mixerDeltaTime;

		for( var i = 0; i < this.actions.length; i ++ ) {

			var action = this.actions[i];

			var weight = action.getWeightAt( this.time );

			var actionTimeScale = action.getTimeScaleAt( this.time );
			var actionDeltaTime = mixerDeltaTime * actionTimeScale;

			var actionResults = action.update( actionDeltaTime );

			if( action.weight <= 0 || ! action.enabled ) continue;

			for( var j = 0; j < actionResults.length; j ++ ) {

				var name = action.clip.tracks[j].name;

				this.propertyBindings[ action.propertyBindingIndices[ j ] ].accumulate( actionResults[j], weight );

			}

		}

		// apply to nodes
		for ( var i = 0; i < this.propertyBindings.length; i ++ ) {

			this.propertyBindings[ i ].apply();

		}

		return this;

	}

};

THREE.EventDispatcher.prototype.apply( THREE.AnimationMixer.prototype );
<|endoftext|>


<commit_before>'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var QuestionSchema = new Schema({
	poll : { type: Schema.ObjectId, ref: 'Poll', required: true },
	title : { type: String, trim: true, required: true },
	type : { type: String, trim: true, default: '' },
	choices	: [{ type: Schema.ObjectId, ref: 'Choice' }]
});

// middleware for cascade delete
QuestionSchema.pre('remove', function(next) {
    var Poll = mongoose.model('Poll');
    Poll.findByIdAndUpdate(this.poll, { $pull: { questions: this._id } });

    var Choice = mongoose.model('Choice');
    Choice.find({ question: this._id }, function(err, choices) {
        if (err) { console.log(err); return; }
        choices.forEach(function (choice) { choice.remove(); });
    });

    next();
});

// middleware for cascade updating on create
QuestionChoiceSchema.pre('save', function(next) {
    this.wasNew = this.isNew;
    next();
});
QuestionSchema.post('save', function() {
    var Poll = mongoose.model('Poll');
    if (this.wasNew) { Poll.findByIdAndUpdate(this.poll, { $push: { questions: this._id } }); }
});

module.exports = mongoose.model('Question', QuestionSchema);<commit_msg>Fix typo mistake on question model middleware<commit_after>'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var QuestionSchema = new Schema({
	poll : { type: Schema.ObjectId, ref: 'Poll', required: true },
	title : { type: String, trim: true, required: true },
	type : { type: String, trim: true, default: '' },
	choices	: [{ type: Schema.ObjectId, ref: 'Choice' }]
});

// middleware for cascade delete
QuestionSchema.pre('remove', function(next) {
    var Poll = mongoose.model('Poll');
    Poll.findByIdAndUpdate(this.poll, { $pull: { questions: this._id } });

    var Choice = mongoose.model('Choice');
    Choice.find({ question: this._id }, function(err, choices) {
        if (err) { console.log(err); return; }
        choices.forEach(function (choice) { choice.remove(); });
    });

    next();
});

// middleware for cascade updating on create
QuestionSchema.pre('save', function(next) {
    this.wasNew = this.isNew;
    next();
});
QuestionSchema.post('save', function() {
    var Poll = mongoose.model('Poll');
    if (this.wasNew) { Poll.findByIdAndUpdate(this.poll, { $push: { questions: this._id } }); }
});

module.exports = mongoose.model('Question', QuestionSchema);<|endoftext|>


<commit_before>function ComponentCkeditor( id ) {
	var self = new ComponentTextfield(id);

	self.setDefaultState('text-value');
	self.setState('text-value', '');

	self.editor = CKEDITOR.instances[id];
	self.editorIsReady = false;
	self.editorToolbar = 'OneRow';
	self.haveUnsetData = false;
	self.hideWhenReady = false;

	self.config = {
		skin: 'kama',
		enterMode: CKEDITOR.ENTER_DIV,
		shiftEnterMode: CKEDITOR.ENTER_DIV,
		forcePasteAsPlainText: false,
		allowedContent: true,
		disableNativeSpellChecker: false,
		browserContextMenuOnCtrl: true,
		colorButton_enableMore: false,
		resize_dir: 'both',
		/*resize_enabled: true,*/
		fontSize_sizes:
			'8/8pt;' +
			'9/9pt;' +
			'10/10pt;' +
			'11/11pt;' +
			'12/12pt;' +
			'14/14pt;' +
			'16/16pt;' +
			'18/18pt;' +
			'20/20pt;' +
			'22/22pt;' +
			'24/24pt;' +
			'26/26pt;' +
			'28/28pt;' +
			'36/36pt;' +
			'48/48pt',
		font_names:
			'Arial/Arial, Helvetica, sans-serif;' +
			'Arial black;' +
			'Calibri/Calibri, sans-serif;' +
			'Comic Sans MS/Comic Sans MS, cursive;' +
			'Courier New/Courier New, Courier, monospace;' +
			'Georgia/Georgia, serif;' +
			'Lucida Console/Lucida Console, monospace;' +
			'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
			'Tahoma/Tahoma, Geneva, sans-serif;' +
			'Times New Roman/Times New Roman, Times, serif;' +
			'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
			'Verdana/Verdana, Geneva, sans-serif',
		toolbar_Empty: [],
		toolbar_SingleRow: [
			[ 'SpellCheckerLanguage' ],
			[ 'SpellChecker' ]
		],
		toolbar_OneRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ], [ 'PasteFromWord' ],
			[ 'Font' ], [ 'FontSize' ],
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], [ 'Resize' ]
		],
		toolbar_TwoRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ], [ 'PasteFromWord' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ],
			[ 'Font' ], [ 'FontSize' ],'/',
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], ['Resize']
		],
		toolbar: 'OneRow',
		plugins:
			'basicstyles,' +
			'blockquote,' +
			'clipboard,' +
			'colorbutton,' +
			'contextmenu,' +
			'enterkey,' +
			'font,' +
			'horizontalrule,' +
			'htmlwriter,' +
			'indent,' +
			'justify,' +
			'link,' +
			'list,' +
			'magicline,' +
			'pastetext,' +
			/* 'removeformat,' + */
			'showborders,' +
			'tab,' +
			/*'table,' + */
			/*'tabletools,' + */
			'toolbar,' +
			'undo,' +
			'wysiwygarea,' +
			'cention_spellcheck,' +
			'cention_image,' +
			'pastefromword,' +
			'resize,' +
			'youtube',
		contentsCss: [
			WFServerURI + 'Resources/CSS/jquery.spellchecker.css',
			WFServerURI + 'Resources/Javascript/ckeditor/contents.css',
			WFServerURI + 'Support/Components/Ckeditor/Ckeditor.css',
		],
		spellCheckLanguages: []
	};

	self.setLanguage = function( language ) {
		self.config.language = language;
	}

	self.setFontSize = function( size ){
		if( size ){
			self.config.fontSize_defaultLabel = '' + size;
			CKEDITOR.addCss('.cke_editable { font-size: '+ size +'; }');
		}
	};

	self.setFontFamily = function( family ){
		if( family ){
			self.config.font_defaultLabel = '' + family;
			CKEDITOR.addCss('.cke_editable { font-family: '+ family +'; }');
		}
	}

	self.setLanguages = function( list ) {
	    self.config.spellCheckLanguages = list;
	};
	self.setImages = function( list ) {
		if( self.editor ) {
			self.editor.___fileArchiveImages = list;
		}
	};
	self.setShowResize = function( resize ) {
		if( resize == true ) {
			self.config.resize_enabled = true;
		} else {
			self.config.resize_enabled = false;
		}
	};
	self.setItemHeight = function( height ){
		self.config.height = height;
	};
	self.showBasicToolbar = function() { };
	self.showAdvancedToolbar = function() { };
	self.setTwoRowToolbar = function( value ) {
		if( value ) {
			self.editorToolbar = 'TwoRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setShowToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'Empty';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setSimpleToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'SingleRow';
			self.config.toolbar = self.editorToolbar;
		}
	};

	self.bind = function() {
		self.attachFocusAction();
		self.attachBlurAction();
	};

	self.attachFocusAction = function() {
		if( self.editor ) {
			self.editor.on('focus', function() {
				self.action('focus');
			});
		}
	};
	self.attachBlurAction = function() {
		if( self.editor ) {
			self.editor.on('blur', function() {
				self.action('blur');
			});
		}
	};

	self.setReadOnly = function( value ) {};
	self.setEnabled = function( value ) {};

	self.focus = function() {
		if( self.editor ) {
			self.editor.focus();
			return true;
		}
		return false;
	};
	self.blur = function() {
		return false;
	};
	self.show = function() {
		var node = $('cke_' + self.identifier());
		if( node ) {
			node.show();
		}
	};
	self.hide = function() {
		if( self.editorIsReady ) {
			var node = $('cke_' + self.identifier());
			if( node ) {
				node.hide();
			}
		} else {
			self.hideWhenReady = true;
		}
	};

	self.empty = function() {
		if( self.editor ) {
			if( self.editor.getData() )
				return false;
		}
		return true;
	};

	var previousGetState = self.getState;
	self.getState = function( state ) {
		if( state == 'text-value' ) {
			return self.editor.getData();
		}
		return previousGetState(state);
	};

	var previousSetState = self.setState;
	self.setState = function( state, value ) {
		if( state == 'text-value' ) {
			var dataSet = false;
			self._states['text-value'] = value;
			if( self.editor ) {
				if( self.editorIsReady ) {
					self.editor.setData(value);
					self.editor.updateElement();
					dataSet = true;
				}
			}
			if( !dataSet ) {
				self.haveUnsetData = true;
			}
		} else {
			previousSetState(state, value);
		}
	};

	self.updateVisual = function() {};
	self.updateFormValue = function() {
		if( self.editor ) {
			self.editor.updateElement();
		}
	};

	var previousActivate = self.activate;
	self.activate = function() {
		self.editor = CKEDITOR.replace(self.identifier(), self.config);

		// Tobias 2015-03-17: The bind() function is called by SetComponent() however at the time
		//                    This happens the editor isn't created which means no event handlers
		//                    can be attached to it. The bind() function is therefore called one
		//                    more time here.
		self.bind();

		self.editor.on('contentDom', function() {
			self.editorIsReady = true;
			if( self.haveUnsetData ) {
				self.editor.setData(self._states['text-value']);
				self.editor.updateElement();
				self.haveUnsetData = false;
			}
			if( self.hideWhenReady ) {
				$('cke_' + self.identifier()).hide();
				self.hideWhenReady = false;
			}
		});

		self.editor.on('contentDomUnload', function() {
			self.editorIsReady = false;
		});
		previousActivate();
	};

	return self;
}

CKEDITOR.addCss('body { margin-left: 5px; margin-right: 5px; margin-top: 3px; margin-bottom: 3px; }');
CKEDITOR.addCss('p { margin-top: 0; }');
<commit_msg>FS#4533: Do not ask answer available question when Ckeditor is empty<commit_after>function ComponentCkeditor( id ) {
	var self = new ComponentTextfield(id);

	self.setDefaultState('text-value');
	self.setState('text-value', '');

	self.editor = CKEDITOR.instances[id];
	self.editorIsReady = false;
	self.editorToolbar = 'OneRow';
	self.haveUnsetData = false;
	self.hideWhenReady = false;

	self.config = {
		skin: 'kama',
		enterMode: CKEDITOR.ENTER_DIV,
		shiftEnterMode: CKEDITOR.ENTER_DIV,
		forcePasteAsPlainText: false,
		allowedContent: true,
		disableNativeSpellChecker: false,
		browserContextMenuOnCtrl: true,
		colorButton_enableMore: false,
		resize_dir: 'both',
		/*resize_enabled: true,*/
		fontSize_sizes:
			'8/8pt;' +
			'9/9pt;' +
			'10/10pt;' +
			'11/11pt;' +
			'12/12pt;' +
			'14/14pt;' +
			'16/16pt;' +
			'18/18pt;' +
			'20/20pt;' +
			'22/22pt;' +
			'24/24pt;' +
			'26/26pt;' +
			'28/28pt;' +
			'36/36pt;' +
			'48/48pt',
		font_names:
			'Arial/Arial, Helvetica, sans-serif;' +
			'Arial black;' +
			'Calibri/Calibri, sans-serif;' +
			'Comic Sans MS/Comic Sans MS, cursive;' +
			'Courier New/Courier New, Courier, monospace;' +
			'Georgia/Georgia, serif;' +
			'Lucida Console/Lucida Console, monospace;' +
			'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
			'Tahoma/Tahoma, Geneva, sans-serif;' +
			'Times New Roman/Times New Roman, Times, serif;' +
			'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
			'Verdana/Verdana, Geneva, sans-serif',
		toolbar_Empty: [],
		toolbar_SingleRow: [
			[ 'SpellCheckerLanguage' ],
			[ 'SpellChecker' ]
		],
		toolbar_OneRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ], [ 'PasteFromWord' ],
			[ 'Font' ], [ 'FontSize' ],
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], [ 'Resize' ]
		],
		toolbar_TwoRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ], [ 'PasteFromWord' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ],
			[ 'Font' ], [ 'FontSize' ],'/',
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], ['Resize']
		],
		toolbar: 'OneRow',
		plugins:
			'basicstyles,' +
			'blockquote,' +
			'clipboard,' +
			'colorbutton,' +
			'contextmenu,' +
			'enterkey,' +
			'font,' +
			'horizontalrule,' +
			'htmlwriter,' +
			'indent,' +
			'justify,' +
			'link,' +
			'list,' +
			'magicline,' +
			'pastetext,' +
			/* 'removeformat,' + */
			'showborders,' +
			'tab,' +
			/*'table,' + */
			/*'tabletools,' + */
			'toolbar,' +
			'undo,' +
			'wysiwygarea,' +
			'cention_spellcheck,' +
			'cention_image,' +
			'pastefromword,' +
			'resize,' +
			'youtube',
		contentsCss: [
			WFServerURI + 'Resources/CSS/jquery.spellchecker.css',
			WFServerURI + 'Resources/Javascript/ckeditor/contents.css',
			WFServerURI + 'Support/Components/Ckeditor/Ckeditor.css',
		],
		spellCheckLanguages: []
	};

	self.setLanguage = function( language ) {
		self.config.language = language;
	}

	self.setFontSize = function( size ){
		if( size ){
			self.config.fontSize_defaultLabel = '' + size;
			CKEDITOR.addCss('.cke_editable { font-size: '+ size +'; }');
		}
	};

	self.setFontFamily = function( family ){
		if( family ){
			self.config.font_defaultLabel = '' + family;
			CKEDITOR.addCss('.cke_editable { font-family: '+ family +'; }');
		}
	}

	self.setLanguages = function( list ) {
	    self.config.spellCheckLanguages = list;
	};
	self.setImages = function( list ) {
		if( self.editor ) {
			self.editor.___fileArchiveImages = list;
		}
	};
	self.setShowResize = function( resize ) {
		if( resize == true ) {
			self.config.resize_enabled = true;
		} else {
			self.config.resize_enabled = false;
		}
	};
	self.setItemHeight = function( height ){
		self.config.height = height;
	};
	self.showBasicToolbar = function() { };
	self.showAdvancedToolbar = function() { };
	self.setTwoRowToolbar = function( value ) {
		if( value ) {
			self.editorToolbar = 'TwoRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setShowToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'Empty';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setSimpleToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'SingleRow';
			self.config.toolbar = self.editorToolbar;
		}
	};

	self.bind = function() {
		self.attachFocusAction();
		self.attachBlurAction();
	};

	self.attachFocusAction = function() {
		if( self.editor ) {
			self.editor.on('focus', function() {
				self.action('focus');
			});
		}
	};
	self.attachBlurAction = function() {
		if( self.editor ) {
			self.editor.on('blur', function() {
				self.action('blur');
			});
		}
	};

	self.setReadOnly = function( value ) {};
	self.setEnabled = function( value ) {};

	self.focus = function() {
		if( self.editor ) {
			self.editor.focus();
			return true;
		}
		return false;
	};
	self.blur = function() {
		return false;
	};
	self.show = function() {
		var node = $('cke_' + self.identifier());
		if( node ) {
			node.show();
		}
	};
	self.hide = function() {
		if( self.editorIsReady ) {
			var node = $('cke_' + self.identifier());
			if( node ) {
				node.hide();
			}
		} else {
			self.hideWhenReady = true;
		}
	};

	self.empty = function() {
		if( self.editor ) {
			var html = self.editor.getData();
			var text = jQuery("<div/>").html(html).text();
			text = jQuery.trim(text);
			if( text )
				return false;
		}
		return true;
	};

	var previousGetState = self.getState;
	self.getState = function( state ) {
		if( state == 'text-value' ) {
			return self.editor.getData();
		}
		return previousGetState(state);
	};

	var previousSetState = self.setState;
	self.setState = function( state, value ) {
		if( state == 'text-value' ) {
			var dataSet = false;
			self._states['text-value'] = value;
			if( self.editor ) {
				if( self.editorIsReady ) {
					self.editor.setData(value);
					self.editor.updateElement();
					dataSet = true;
				}
			}
			if( !dataSet ) {
				self.haveUnsetData = true;
			}
		} else {
			previousSetState(state, value);
		}
	};

	self.updateVisual = function() {};
	self.updateFormValue = function() {
		if( self.editor ) {
			self.editor.updateElement();
		}
	};

	var previousActivate = self.activate;
	self.activate = function() {
		self.editor = CKEDITOR.replace(self.identifier(), self.config);

		// Tobias 2015-03-17: The bind() function is called by SetComponent() however at the time
		//                    This happens the editor isn't created which means no event handlers
		//                    can be attached to it. The bind() function is therefore called one
		//                    more time here.
		self.bind();

		self.editor.on('contentDom', function() {
			self.editorIsReady = true;
			if( self.haveUnsetData ) {
				self.editor.setData(self._states['text-value']);
				self.editor.updateElement();
				self.haveUnsetData = false;
			}
			if( self.hideWhenReady ) {
				$('cke_' + self.identifier()).hide();
				self.hideWhenReady = false;
			}
		});

		self.editor.on('contentDomUnload', function() {
			self.editorIsReady = false;
		});
		previousActivate();
	};

	return self;
}

CKEDITOR.addCss('body { margin-left: 5px; margin-right: 5px; margin-top: 3px; margin-bottom: 3px; }');
CKEDITOR.addCss('p { margin-top: 0; }');
<|endoftext|>


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

  angular
    .module('app.auth')
    .controller('AuthController', AuthController);

  AuthController.$inject = ['$firebaseAuth'];

  function AuthController($firebaseAuth) {
    var vm = this;
    var firebaseReference = new Firebase('https://waitandeat-v2-demo.firebaseio.com/');
    var firebaseAuthObject = $firebaseAuth(firebaseReference);

    vm.user = {
      email: '',
      password: ''
    };

    vm.register = register;
    vm.login = login;

    function register(user) {
      return firebaseAuthObject.$createUser(user)
        .then(function() {
          return vm.login(user);
        })
        .catch(function(error) {
          console.log(error);
        });
    }

    function login(user) {
      return firebaseAuthObject.$authWithPassword(user)
        .then(function(loggedInUser) {
          console.log(loggedInUser);
        })
        .catch(function(error) {
          console.log(error);
        });
    }
  }

})();<commit_msg>Added AuthController.logout.<commit_after>(function() {
  'use strict';

  angular
    .module('app.auth')
    .controller('AuthController', AuthController);

  AuthController.$inject = ['$firebaseAuth'];

  function AuthController($firebaseAuth) {
    var vm = this;
    var firebaseReference = new Firebase('https://waitandeat-v2-demo.firebaseio.com/');
    var firebaseAuthObject = $firebaseAuth(firebaseReference);

    vm.user = {
      email: '',
      password: ''
    };

    vm.register = register;
    vm.login = login;
    vm.logout = logout;

    function register(user) {
      return firebaseAuthObject.$createUser(user)
        .then(function() {
          return vm.login(user);
        })
        .catch(function(error) {
          console.log(error);
        });
    }

    function login(user) {
      return firebaseAuthObject.$authWithPassword(user)
        .then(function(loggedInUser) {
          console.log(loggedInUser);
        })
        .catch(function(error) {
          console.log(error);
        });
    }

    function logout() {
      firebaseAuthObject.$unauth();
    }
  }

})();<|endoftext|>


<commit_before>

/**
 * Constructor for an Othello board
 * @param {Array.<Array.<othello.Piece>>} board a 2D array
 *     representing the board.
 * @constructor
 * @const
 */
othello.Board = function(board) {
  /** @const */ this.board = board;
};

/**
 * Retrieve the piece at a given location.
 * @param {number} row the row.
 * @param {number} column the column.
 * @return {othello.Piece} the Piece at that location.
 */
othello.Board.prototype.pieceAt = function(row, column) {
  return this.board[row][column];
};

/**
 * Given a proposed location to place a piece, return true
 * if it is valid.
 * @param {othello.Piece} piece the piece being placed.
 * @param {number} x the x coordinate for the piece.
 * @param {number} y the y coordinate for the piece.
 * @return {Boolean} true if it is a legal move to place the piece there.
 */
othello.Board.prototype.placementIsValid = function(piece, x, y) {
  if (this.isOccupiedAt(x, y)) {
    return false;
  }
  // TODO Implement
};

/**
 * Walk in a given direction, and locate all the coordinates
 * whose pieces need to be flipped. This will be all the pieces
 * in a line that starts at the original location, and ends at
 * the first square found that contains another piece of the same color.
 * If the chain is broken by an empty square or the end of the board,
 * this means no pieces can be flipped. Presumably, we are analyzing
 * the effects of a move that places a piece in (initialX, initialY).
 * @param {othello.Piece} piece the piece being placed in the first point.
 * @param {number} initialX the initial x coordinate.
 * @param {number} initialY the initial y coordinate.
 * @param {number} deltaX the amount by which to change x in each step.
 * @param {number} deltaY the amount by which to change y in each step.
 * @return {Array.<((xCoordinate: number, yCoordinate: number}}>} an
 *     array containing a record with the coordinates of pieces to flip.
 *     If no pieces can be flipped, returns an empty array.
 */
othello.Board.prototype.findPiecesToFlip =
    function(piece, initialX, initialY, deltaX, deltaY) {
  var next = this.nextSquare(initialX, initialY, deltaX, deltaY);
  var contents = next.getOrElse(othello.EmptyPiece.instance);
  if (contents === othello.EmptyPiece.instance ||
      contents === piece) {
    // It's next to an empty square or a piece of the same color.
    return []
  }
  // Now keep walking down the chain
  var currentX = initialX + deltaX;
  var currentY = initialY + deltaY;
  // But don't forget to add the coordinates we just stepped over.
  /** @const */ var firstStepCoordinates = {
    xCoordinate: currentX,
    yCoordinate: currentY
  };
  /** @const */ var captured = [firstStepCoordinates];
  while (true) {
    next = this.nextSquare(currentX, currentY, deltaX, deltaY);
    contents = next.getOrElse(othello.EmptyPiece.instance);
    if (contents === othello.EmptyPiece.instance) {
      // the chain broke
      return [];
    }
    else if (contents === piece) {
      // end of a valid chain, return the chain
      return captured;
    } else {
      // add the location of the piece we're passing over to captured
      /** @const */ var currentCoordinates = {
        xCoordinate: currentX,
        yCoordinate: currentY
      };
      captured.push(currentCoordinates);
      currentX += deltaX;
      currentY += deltaY;
    }
  }
};

/**
 * Test if a square is occupied
 * @param {number} x the x coordinate.
 * @param {number} y the y coordinate.
 * @return {Boolean} true if the square is occupied.
 */
othello.Board.prototype.isOccupiedAt = function(x, y) {
  return this.board[x][y] !== othello.EmptyPiece.instance;
};

/**
 * Get the contents of a square via relative positioning
 * @param {number} row the initial row.
 * @param {number} column the initial column
 * @param {number} deltaX the amount by which to change the X coordinate.
 * @param {number} deltaY the amount by which to change the Y coordinate.
 * @return {Option} Some(Piece in the found square) or None if we go off
 *     the board.
 */
othello.Board.prototype.nextSquare = function(row, column, deltaX, deltaY) {
  /** @const */ var newRow = row + deltaX;
  /** @const */ var newColumn = column + deltaY;
  if (this.inBounds(newRow, newColumn)) {
    return new othello.utils.Some(this.board[newRow][newColumn]);
  } else{
    return othello.utils.None.instance;
  }
};

/**
 * Helper function to tell if a pair of coordinate is in bounds.
 * @return {Boolean} true if it is safe to index this Board with
 *     the given coordinates.
 */
othello.Board.prototype.inBounds = function(x, y) {
  return x >= 0 && x < this.board.length &&
         y >= 0 && y < this.board[0].length;
};

/**
 * @const
 * @type {number}
 */
othello.Board.size = 8;

/**
 * Constructor for an Othello board builder
 * @param {Array.<Array.<othello.Piece>>} board the board to start with.
 * @constructor
 * @const
 */
othello.Board.Builder = function(board) {
  this.board = board;
  this.row = 0;
  this.column = 0;
};

/**
 * Named constructor to create an empty board as a Builder
 * @return {othello.Board.Builder} the created Builder.
 * @const
 */
othello.Board.Builder.emptyBoard = function() {
  /** @const */ var board = [];
  for (var i = 0; i < othello.Board.size; i++) {
    board.push(othello.Board.Builder.createRow());
  }

  return new othello.Board.Builder(board);
};

/**
 * Named constructor to create a new Board from an old one.
 * @param {othello.Board} board the old board.
 * @return {othello.Board.Builder} a new Builder based off
 *     the old board.
 */
othello.Board.Builder.templatedBy = function(board) {
  /** @const */ var builder = othello.Board.Builder.emptyBoard();
  /** @const */ var oldArray = board.board;
  for (var i = 0; i < oldArray.length; i++) {
    for (var j = 0; j < oldArray[0].length; j++) {
      builder.at(i, j).place(oldArray[i][j]);
    }
  }
  return builder;
};

/**
 * Name constructor to create an initial game as a Builder
 * @return {othello.Board.Builder} the created Builder.
 * @const
 */
othello.Board.Builder.initialGame = function() {
  return othello.Board.Builder.emptyBoard().
      at(3, 3).placeLightMarker().
      at(3, 4).placeDarkMarker().
      at(4, 3).placeDarkMarker().
      at(4, 4).placeLightMarker();
};

/**
 * Position this.row and this.column
 * @param {number} row the value for the row.
 * @param {number} column the value for the column.
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.at = function(row, column) {
  this.row = row;
  this.column = column;
  return this;
};

/**
 * Add a light marker to the board
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.placeLightMarker = function() {
  this.place(othello.LightPiece.instance);
  return this;
};

/**
 * Add a dark marker to the board
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.placeDarkMarker = function() {
  this.place(othello.DarkPiece.instance);
  return this;
};

/**
 * Add a marker to the board
 * @param {othello.Piece} piece the piece to add.
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.place = function(piece) {
  this.board[this.row][this.column] = piece;
  return this;
};

/**
 * Flip a piece, at the place specified by row and column (set with at)
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.flip = function() {
  /** @const */ var piece = this.board[this.row][this.column];
  this.place(piece.flip());
  return this;
};

/**
 * Helper function to create a row.
 * @return {Array.<othello.Piece>} an unpopulated
 *    row in the board.
 * @const
 */
othello.Board.Builder.createRow = function() {
  /** @const */ var row = [];
  for (var i = 0; i < othello.Board.size; i++) {
    row.push(othello.EmptyPiece.instance);
  }
  return row;
};

/**
 * Finally, create an Othello Board
 * @return {othello.Board} the board created from this Builder.
 */
othello.Board.Builder.prototype.build = function() {
  return new othello.Board(this.board);
};
<commit_msg>Added findAllPiecesToFLip<commit_after>

/**
 * Constructor for an Othello board
 * @param {Array.<Array.<othello.Piece>>} board a 2D array
 *     representing the board.
 * @constructor
 * @const
 */
othello.Board = function(board) {
  /** @const */ this.board = board;
};

/**
 * Retrieve the piece at a given location.
 * @param {number} row the row.
 * @param {number} column the column.
 * @return {othello.Piece} the Piece at that location.
 */
othello.Board.prototype.pieceAt = function(row, column) {
  return this.board[row][column];
};

/**
 * Given a proposed location to place a piece, return true
 * if it is valid.
 * @param {othello.Piece} piece the piece being placed.
 * @param {number} x the x coordinate for the piece.
 * @param {number} y the y coordinate for the piece.
 * @return {boolean} true if it is a legal move to place the piece there.
 */
othello.Board.prototype.placementIsValid = function(piece, x, y) {
  if (this.isOccupiedAt(x, y)) {
    return false;
  }
  /** @const */ var self = this;
  /** @const */ var flipped = this.findAllPiecesToFlip(piece, x, y)
  return flipped.length > 0;
};

/**
 * Given an initial location and a piece, returns the coordinates of
 * all the pieces that would be flipped if piece was placed in the initial
 * location.
 * @param {othello.Piece} piece the piece being placed.
 * @param {number} x the x coordinate.
 * @param {number} y the y coordinate.
 * @return {Array.<{xCoordinate: number, yCoordinate: number}>} an Array
 *    containing the coordinates of all the pieces that would be flipped.
 */
othello.Board.prototype.findAllPiecesToFlip = function(piece, x, y) {
  /** @const */ var self = this;
  return othello.utils.flatMap(othello.Board.deltas(), function(delta) {
    return self.findPiecesToFlip(piece, x, y, delta[0], delta[1]);
  });
};

/**
 * Return a list of lists containing the appropriate values for
 * deltaX and deltaY
 * @return {othello.underscore.header.RichArray} a list of deltas,
 *     wrapped in an _. The exact type is defined by underscore.js.
 *     RichArray is a type synonym to provide information to the compiler.
 */
othello.Board.deltas = function() {
  /** @const */ var allCombinations = othello.utils.flatMap(_.range(-1, 2),
  function(item) {
      return [[-1, item], [0, item], [1, item]];
  });
  return _(allCombinations).reject(function removeTheZeroPair(item) {
    return item[0] === 0 && item[1] === 0;
  });
  /*
  return _(_.zip(_.range(-1, 2), _.range(-1, 2))).chain().
      filter(function(item) {
    return item[0] !== 0 && item[1] !== 1;
  });
  */
};

/**
 * Walk in a given direction, and locate all the coordinates
 * whose pieces need to be flipped. This will be all the pieces
 * in a line that starts at the original location, and ends at
 * the first square found that contains another piece of the same color.
 * If the chain is broken by an empty square or the end of the board,
 * this means no pieces can be flipped. Presumably, we are analyzing
 * the effects of a move that places a piece in (initialX, initialY).
 * @param {othello.Piece} piece the piece being placed in the first point.
 * @param {number} initialX the initial x coordinate.
 * @param {number} initialY the initial y coordinate.
 * @param {number} deltaX the amount by which to change x in each step.
 * @param {number} deltaY the amount by which to change y in each step.
 * @return {Array.<{xCoordinate: number, yCoordinate: number}>} an
 *     array containing a record with the coordinates of pieces to flip.
 *     If no pieces can be flipped, returns an empty array.
 */
othello.Board.prototype.findPiecesToFlip =
    function(piece, initialX, initialY, deltaX, deltaY) {
  var next = this.nextSquare(initialX, initialY, deltaX, deltaY);
  var contents = next.getOrElse(othello.EmptyPiece.instance);
  if (contents === othello.EmptyPiece.instance ||
      contents === piece) {
    // It's next to an empty square or a piece of the same color.
    return []
  }
  // Now keep walking down the chain
  var currentX = initialX + deltaX;
  var currentY = initialY + deltaY;
  // But don't forget to add the coordinates we just stepped over.
  /** @const */ var firstStepCoordinates = {
    xCoordinate: currentX,
    yCoordinate: currentY
  };
  /** @const */ var captured = [firstStepCoordinates];
  while (true) {
    next = this.nextSquare(currentX, currentY, deltaX, deltaY);
    contents = next.getOrElse(othello.EmptyPiece.instance);
    if (contents === othello.EmptyPiece.instance) {
      // the chain broke
      return [];
    }
    else if (contents === piece) {
      // end of a valid chain, return the chain
      return captured;
    } else {
      // add the location of the piece we're passing over to captured
      /** @const */ var currentCoordinates = {
        xCoordinate: currentX,
        yCoordinate: currentY
      };
      captured.push(currentCoordinates);
      currentX += deltaX;
      currentY += deltaY;
    }
  }
};

/**
 * Test if a square is occupied
 * @param {number} x the x coordinate.
 * @param {number} y the y coordinate.
 * @return {boolean} true if the square is occupied.
 */
othello.Board.prototype.isOccupiedAt = function(x, y) {
  return this.board[x][y] !== othello.EmptyPiece.instance;
};

/**
 * Get the contents of a square via relative positioning
 * @param {number} row the initial row.
 * @param {number} column the initial column
 * @param {number} deltaX the amount by which to change the X coordinate.
 * @param {number} deltaY the amount by which to change the Y coordinate.
 * @return {othello.utils.Option} Some(Piece in the found square) or None if
 *     we go off the board.
 */
othello.Board.prototype.nextSquare = function(row, column, deltaX, deltaY) {
  /** @const */ var newRow = row + deltaX;
  /** @const */ var newColumn = column + deltaY;
  if (this.inBounds(newRow, newColumn)) {
    return new othello.utils.Some(this.board[newRow][newColumn]);
  } else{
    return othello.utils.None.instance;
  }
};

/**
 * Helper function to tell if a pair of coordinate is in bounds.
 * @return {boolean} true if it is safe to index this Board with
 *     the given coordinates.
 */
othello.Board.prototype.inBounds = function(x, y) {
  return x >= 0 && x < this.board.length &&
         y >= 0 && y < this.board[0].length;
};

/**
 * @const
 * @type {number}
 */
othello.Board.size = 8;

/**
 * Constructor for an Othello board builder
 * @param {Array.<Array.<othello.Piece>>} board the board to start with.
 * @constructor
 * @const
 */
othello.Board.Builder = function(board) {
  this.board = board;
  this.row = 0;
  this.column = 0;
};

/**
 * Named constructor to create an empty board as a Builder
 * @return {othello.Board.Builder} the created Builder.
 * @const
 */
othello.Board.Builder.emptyBoard = function() {
  /** @const */ var board = [];
  _.each(_.range(0, othello.Board.size), function(i) {
    board.push(othello.Board.Builder.createRow());
  });

  return new othello.Board.Builder(board);
};

/**
 * Named constructor to create a new Board from an old one.
 * @param {othello.Board} board the old board.
 * @return {othello.Board.Builder} a new Builder based off
 *     the old board.
 */
othello.Board.Builder.templatedBy = function(board) {
  /** @const */ var builder = othello.Board.Builder.emptyBoard();
  /** @const */ var oldArray = board.board;
  _.each(_.range(0, oldArray.length), function(i) {
    _.each(_.range(0, oldArray.length), function(j) {
      builder.at(i, j).place(oldArray[i][j]);
    });
  });
  return builder;
};

/**
 * Name constructor to create an initial game as a Builder
 * @return {othello.Board.Builder} the created Builder.
 * @const
 */
othello.Board.Builder.initialGame = function() {
  return othello.Board.Builder.emptyBoard().
      at(3, 3).placeLightMarker().
      at(3, 4).placeDarkMarker().
      at(4, 3).placeDarkMarker().
      at(4, 4).placeLightMarker();
};

/**
 * Position this.row and this.column
 * @param {number} row the value for the row.
 * @param {number} column the value for the column.
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.at = function(row, column) {
  this.row = row;
  this.column = column;
  return this;
};

/**
 * Add a light marker to the board
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.placeLightMarker = function() {
  this.place(othello.LightPiece.instance);
  return this;
};

/**
 * Add a dark marker to the board
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.placeDarkMarker = function() {
  this.place(othello.DarkPiece.instance);
  return this;
};

/**
 * Add a marker to the board
 * @param {othello.Piece} piece the piece to add.
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.place = function(piece) {
  this.board[this.row][this.column] = piece;
  return this;
};

/**
 * Flip a piece, at the place specified by row and column (set with at)
 * @return {othello.Board.Builder} this for chaining.
 * @const
 */
othello.Board.Builder.prototype.flip = function() {
  /** @const */ var piece = this.board[this.row][this.column];
  this.place(piece.flip());
  return this;
};

/**
 * Helper function to create a row.
 * @return {Array.<othello.Piece>} an unpopulated
 *    row in the board.
 * @const
 */
othello.Board.Builder.createRow = function() {
  return _.map(_.range(0, othello.Board.size), function(i) {
    return othello.EmptyPiece.instance;
  });
};

/**
 * Finally, create an Othello Board
 * @return {othello.Board} the board created from this Builder.
 */
othello.Board.Builder.prototype.build = function() {
  return new othello.Board(this.board);
};
<|endoftext|>