<commit_before>jQuery.fn.mousehold = function (f) {
    var timeout = 100;
    if (f && typeof f == 'function') {
        var intervalId = 0;
        var firstStep = false;
        var clearMousehold = undefined;
        return this.each(function () {
            $(this).mousedown(function () {
                firstStep = true;
                var ctr = 0;
                var t = this;
                intervalId = setInterval(function () {
                    ctr++;
                    f.call(t, ctr);
                    firstStep = false;
                }, timeout);
            });

            clearMousehold = function () {
                clearInterval(intervalId);
                if (firstStep) f.call(this, 1);
                firstStep = false;
            };

            $(this).mouseout(clearMousehold);
            $(this).mouseup(clearMousehold);
        });
    }
};

$(function () {
    $.extend($.fn.disableTextSelect = function () {
        return this.each(function () {
            if ($.browser.mozilla) {//Firefox
                $(this).css('MozUserSelect', 'none');
            } else if ($.browser.msie) {//IE
                $(this).bind('selectstart', function () { return false; });
            } else {//Opera, etc.
                $(this).mousedown(function () { return false; });
            }
        });
    });
});

!function ($) {

    var SpinEdit = function (element, options) {
        this.element = $(element);
        this.element.addClass("spinedit");
        this.element.addClass("noSelect");
        this.intervalId = undefined;

        var hasOptions = typeof options == 'object';

        this.minimum = $.fn.spinedit.defaults.minimum;
        if (hasOptions && typeof options.minimum == 'number') {
            this.setMinimum(options.minimum);
        }

        this.maximum = $.fn.spinedit.defaults.maximum;
        if (hasOptions && typeof options.maximum == 'number') {
            this.setMaximum(options.maximum);
        }

        this.value = $.fn.spinedit.defaults.value;
        if (hasOptions && typeof options.value == 'number') {
            this.setValue(options.value);
        }
        this.element.val(this.value);

        this.step = $.fn.spinedit.defaults.step;
        if (hasOptions && typeof options.step == 'number') {
            this.setStep(options.step);
        }

        var template = $(DRPGlobal.template);
        this.element.after(template);
        template.disableTextSelect();

        template.find('.icon-chevron-up').mousehold($.proxy(this.increase, this));
        template.find('.icon-chevron-down').mousehold($.proxy(this.decrease, this));
        this.element.on('keydown', $.proxy(this._keydown, this));
        this.element.on('blur', $.proxy(this._checkConstraints, this));
    };

    SpinEdit.prototype = {
        constructor: SpinEdit,

        setMinimum: function (value) {
            this.minimum = parseInt(value);
        },

        setMaximum: function (value) {
            this.maximum = parseInt(value);
        },

        setStep: function (value) {
            this.step = parseInt(value);
        },

        setValue: function (value) {
            value = parseInt(value);
            if (value < this.minimum)
                value = this.minimum;
            if (value > this.maximum)
                value = this.maximum;
            this.value = value;
            this.element.val(this.value);
        },

        increase: function () {
            if (this.value >= this.maximum)
                return;

            this.value += this.step;
            this.element.val(this.value);
            this._triggerValueChanged();
        },

        decrease: function () {
            if (this.value <= this.minimum)
                return;

            this.value -= this.step;
            this.element.val(this.value);
            this._triggerValueChanged();
        },

        _keydown: function (event) {
            // Allow: backspace, delete, tab, escape, enter, home, end, left, right, -
            if (event.keyCode == 109 || event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 ||
			   (event.keyCode >= 35 && event.keyCode <= 39)) {
                return;
            }
            else {
                // Ensure that it is a number and stop the keypress
                if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                    event.preventDefault();
                }
            }
        },

        _checkConstraints: function (e) {
            var target = $(e.target);
            var value = parseInt(target.val());
            if (this.value == value) {
                return;
            }

            if (value <= this.minimum)
                value = this.minimum;
            if (value >= this.maximum)
                value = this.maximum;

            this.value = value;
            this.element.val(this.value);
            this._triggerValueChanged();
        },

        _triggerValueChanged: function () {
            this.element.trigger({
                type: "valueChanged",
                value: this.value
            });
        }
    };

    $.fn.spinedit = function (option) {
        var args = Array.apply(null, arguments);
        args.shift();
        return this.each(function () {
            var $this = $(this),
				data = $this.data('spinedit'),
				options = typeof option == 'object' && option;

            if (!data) {
                $this.data('spinedit', new SpinEdit(this, $.extend({}, $.fn.spinedit().defaults, options)));
            }
            if (typeof option == 'string' && typeof data[option] == 'function') {
                data[option].apply(data, args);
            }
        });
    };

    $.fn.spinedit.defaults = {
        value: 0,
        minimum: 0,
        maximum: 100,
        step: 1
    };

    $.fn.spinedit.Constructor = SpinEdit;

    var DRPGlobal = {};

    DRPGlobal.template =
	'
' +
	'' +
	'' +
	'
';

}(window.jQuery);<commit_msg>Keydown event handler replaced with keyup. Keydown only handled numeric keypad<commit_after>jQuery.fn.mousehold = function (f) {
    var timeout = 100;
    if (f && typeof f == 'function') {
        var intervalId = 0;
        var firstStep = false;
        var clearMousehold = undefined;
        return this.each(function () {
            $(this).mousedown(function () {
                firstStep = true;
                var ctr = 0;
                var t = this;
                intervalId = setInterval(function () {
                    ctr++;
                    f.call(t, ctr);
                    firstStep = false;
                }, timeout);
            });

            clearMousehold = function () {
                clearInterval(intervalId);
                if (firstStep) f.call(this, 1);
                firstStep = false;
            };

            $(this).mouseout(clearMousehold);
            $(this).mouseup(clearMousehold);
        });
    }
};

$(function () {
    $.extend($.fn.disableTextSelect = function () {
        return this.each(function () {
            if ($.browser.mozilla) {//Firefox
                $(this).css('MozUserSelect', 'none');
            } else if ($.browser.msie) {//IE
                $(this).bind('selectstart', function () { return false; });
            } else {//Opera, etc.
                $(this).mousedown(function () { return false; });
            }
        });
    });
});

!function ($) {

    var SpinEdit = function (element, options) {
        this.element = $(element);
        this.element.addClass("spinedit");
        this.element.addClass("noSelect");
        this.intervalId = undefined;

        var hasOptions = typeof options == 'object';

        this.minimum = $.fn.spinedit.defaults.minimum;
        if (hasOptions && typeof options.minimum == 'number') {
            this.setMinimum(options.minimum);
        }

        this.maximum = $.fn.spinedit.defaults.maximum;
        if (hasOptions && typeof options.maximum == 'number') {
            this.setMaximum(options.maximum);
        }

        this.value = $.fn.spinedit.defaults.value;
        if (hasOptions && typeof options.value == 'number') {
            this.setValue(options.value);
        }
        this.element.val(this.value);

        this.step = $.fn.spinedit.defaults.step;
        if (hasOptions && typeof options.step == 'number') {
            this.setStep(options.step);
        }

        var template = $(DRPGlobal.template);
        this.element.after(template);
        template.disableTextSelect();

        template.find('.icon-chevron-up').mousehold($.proxy(this.increase, this));
        template.find('.icon-chevron-down').mousehold($.proxy(this.decrease, this));
        this.element.on('keypress', $.proxy(this._keypress, this));
        this.element.on('blur', $.proxy(this._checkConstraints, this));
    };

    SpinEdit.prototype = {
        constructor: SpinEdit,

        setMinimum: function (value) {
            this.minimum = parseInt(value);
        },

        setMaximum: function (value) {
            this.maximum = parseInt(value);
        },

        setStep: function (value) {
            this.step = parseInt(value);
        },

        setValue: function (value) {
            value = parseInt(value);
            if (value < this.minimum)
                value = this.minimum;
            if (value > this.maximum)
                value = this.maximum;
            this.value = value;
            this.element.val(this.value);
        },

        increase: function () {
            if (this.value >= this.maximum)
                return;

            this.value += this.step;
            this.element.val(this.value);
            this._triggerValueChanged();
        },

        decrease: function () {
            if (this.value <= this.minimum)
                return;

            this.value -= this.step;
            this.element.val(this.value);
            this._triggerValueChanged();
        },

        _keypress: function (event) {
            // Allow: -
            if (event.keyCode == 45) {
                return;
            }

            // Ensure that it is a number and stop the keypress
            var a = [];
            for (var i = 48; i < 58; i++)
                a.push(i);
            var k = event.keyCode;
            if (!(a.indexOf(k) >= 0))
                event.preventDefault();
        },

        _checkConstraints: function (e) {
            var target = $(e.target);
            var value = parseInt(target.val());
            if (this.value == value) {
                return;
            }

            if (value <= this.minimum)
                value = this.minimum;
            if (value >= this.maximum)
                value = this.maximum;

            this.value = value;
            this.element.val(this.value);
            this._triggerValueChanged();
        },

        _triggerValueChanged: function () {
            this.element.trigger({
                type: "valueChanged",
                value: this.value
            });
        }
    };

    $.fn.spinedit = function (option) {
        var args = Array.apply(null, arguments);
        args.shift();
        return this.each(function () {
            var $this = $(this),
				data = $this.data('spinedit'),
				options = typeof option == 'object' && option;

            if (!data) {
                $this.data('spinedit', new SpinEdit(this, $.extend({}, $.fn.spinedit().defaults, options)));
            }
            if (typeof option == 'string' && typeof data[option] == 'function') {
                data[option].apply(data, args);
            }
        });
    };

    $.fn.spinedit.defaults = {
        value: 0,
        minimum: 0,
        maximum: 100,
        step: 1
    };

    $.fn.spinedit.Constructor = SpinEdit;

    var DRPGlobal = {};

    DRPGlobal.template =
	'
' +
	'' +
	'' +
	'
';

}(window.jQuery);<|endoftext|>


<commit_before>// Copyright 2014-2018, University of Colorado Boulder

/**
 * Constants that are global to this sim.
 *
 * @author Andrea Lin
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const Bounds2 = require( 'DOT/Bounds2' );
  const GQColors = require( 'GRAPHING_QUADRATICS/common/GQColors' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const PhetFont = require( 'SCENERY_PHET/PhetFont' );
  const Range = require( 'DOT/Range' );

  // constants
  const PANEL_CORNER_RADIUS = 5; // corner radius for all panel-like containers

  const GQConstants = {

    SCREEN_VIEW_LAYOUT_BOUNDS: new Bounds2( 0, 0, 1100, 700 ),
    SCREEN_VIEW_X_MARGIN: 20,
    SCREEN_VIEW_Y_MARGIN: 16,

    // range of the graph's axes
    X_AXIS_RANGE: new Range( -10, 10 ),
    Y_AXIS_RANGE: new Range( -10, 10 ),

    // options applied to all AccordionBoxes
    ACCORDION_BOX_OPTIONS: {
      resize: false,
      fill: GQColors.CONTROL_PANEL_BACKGROUND,
      cornerRadius: PANEL_CORNER_RADIUS,
      titleYMargin: 10,
      buttonLength: 25,
      buttonXMargin: 10,
      buttonYMargin: 10,
      contentXMargin: 20,
      contentYMargin: 15
    },

    // options applied to all Panels
    PANEL_OPTIONS: {
      fill: GQColors.CONTROL_PANEL_BACKGROUND,
      cornerRadius: PANEL_CORNER_RADIUS,
      xMargin: 20,
      yMargin: 15
    },

    // options applied to all NumberPickers
    NUMBER_PICKER_OPTIONS: {
      font: new PhetFont( 26 ),
      xMargin: 5,
      touchAreaXDilation: 30
    },

    // vertical space between checkboxes
    CHECKBOXES_Y_SPACING: 15,

    // radii
    MANIPULATOR_RADIUS: 0.425,  // radius of manipulators, in model coordinates
    POINT_RADIUS: 0.25, // radius of non-interactive points, in model coordinates

    // font sizes
    TITLE_FONT_SIZE: 20,
    INTERACTIVE_EQUATION_FONT_SIZE: 26,
    SLIDER_TICK_LABEL_FONT_SIZE: 16,
    CHECKBOX_LABEL_FONT_SIZE: 20,
    CHECKBOX_EQUATION_FONT_SIZE: 22,
    GRAPH_EQUATION_FONT_SIZE: 18,

    // line widths
    INTERACTIVE_QUADRATIC_LINE_WIDTH: 4,
    SAVED_QUADRATIC_LINE_WIDTH: 3,
    QUADRATIC_TERMS_LINE_WIDTH: 2, // y = ax^2, y = bx, y = c
    AXIS_OF_SYMMETRY_LINE_WIDTH: 3,
    DIRECTRIX_LINE_WIDTH: 3,
    POINT_ON_PARABOLA_LINE_WIDTH: 3, // lines that connect point to focus and directrix

    // line dashes
    AXIS_OF_SYMMETRY_LINE_DASH: [ 5, 5 ],
    DIRECTRIX_LINE_DASH: [ 5, 5 ],
    POINT_ON_PARABOLA_LINE_DASH: [ 5, 5 ], // lines that connect point to focus and directrix

    // decimal places
    AXIS_OF_SYMMETRY_DECIMALS: 2,
    DIRECTRIX_DECIMALS: 2,
    FOCUS_DECIMALS: 2,
    POINT_ON_PARABOLA_DECIMALS: 2,
    POINT_TOOL_DECIMALS: 1,
    ROOTS_DECIMALS: 2,
    VERTEX_DECIMALS: 2,
    EXPLORE_DECIMALS_A: 2,
    EXPLORE_DECIMALS_B: 1,
    EXPLORE_DECIMALS_C: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_A: 3,
    FOCUS_AND_DIRECTRIX_DECIMALS_P: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_H: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_K: 1,

    // slider intervals
    EXPLORE_INTERVAL_A: 0.01,
    EXPLORE_INTERVAL_B: 0.1,
    EXPLORE_INTERVAL_C: 0.1,
    FOCUS_AND_DIRECTRIX_INTERVAL_P: 0.1,
    FOCUS_AND_DIRECTRIX_INTERVAL_H: 0.1,
    FOCUS_AND_DIRECTRIX_INTERVAL_K: 0.1,

    // enums
    EQUATION_FORMS: [ 'standard', 'vertex' ], // form of equations on curves
    PROBE_SIDES: [ 'right', 'left' ], // which side the point tool's probe is on

    // margins between equations and edges of graph
    // Caution! Changing these may cause an equation to go off the graph. Test thoroughly!
    EQUATION_X_MARGIN: 1.5, // distance between equation and left/right edges of graph, in model coordinate frame
    EQUATION_Y_MARGIN: 0.5, // distance between equation and top/bottom edges of graph, in model coordinate frame

    // space between equation and the curve that it labels, in view coordinate frame
    EQUATION_CURVE_SPACING: 5,

    // spacing around operators in interactive equations
    EQUATION_OPERATOR_SPACING: 8,

    // spacing within terms in interactive equations
    EQUATION_TERM_SPACING: 6
  };

  return graphingQuadratics.register( 'GQConstants', GQConstants );
} );
<commit_msg>demonstrate moving linear sliders in 0.5 increments, #73<commit_after>// Copyright 2014-2018, University of Colorado Boulder

/**
 * Constants that are global to this sim.
 *
 * @author Andrea Lin
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const Bounds2 = require( 'DOT/Bounds2' );
  const GQColors = require( 'GRAPHING_QUADRATICS/common/GQColors' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const PhetFont = require( 'SCENERY_PHET/PhetFont' );
  const Range = require( 'DOT/Range' );

  // constants
  const PANEL_CORNER_RADIUS = 5; // corner radius for all panel-like containers

  const GQConstants = {

    SCREEN_VIEW_LAYOUT_BOUNDS: new Bounds2( 0, 0, 1100, 700 ),
    SCREEN_VIEW_X_MARGIN: 20,
    SCREEN_VIEW_Y_MARGIN: 16,

    // range of the graph's axes
    X_AXIS_RANGE: new Range( -10, 10 ),
    Y_AXIS_RANGE: new Range( -10, 10 ),

    // options applied to all AccordionBoxes
    ACCORDION_BOX_OPTIONS: {
      resize: false,
      fill: GQColors.CONTROL_PANEL_BACKGROUND,
      cornerRadius: PANEL_CORNER_RADIUS,
      titleYMargin: 10,
      buttonLength: 25,
      buttonXMargin: 10,
      buttonYMargin: 10,
      contentXMargin: 20,
      contentYMargin: 15
    },

    // options applied to all Panels
    PANEL_OPTIONS: {
      fill: GQColors.CONTROL_PANEL_BACKGROUND,
      cornerRadius: PANEL_CORNER_RADIUS,
      xMargin: 20,
      yMargin: 15
    },

    // options applied to all NumberPickers
    NUMBER_PICKER_OPTIONS: {
      font: new PhetFont( 26 ),
      xMargin: 5,
      touchAreaXDilation: 30
    },

    // vertical space between checkboxes
    CHECKBOXES_Y_SPACING: 15,

    // radii
    MANIPULATOR_RADIUS: 0.425,  // radius of manipulators, in model coordinates
    POINT_RADIUS: 0.25, // radius of non-interactive points, in model coordinates

    // font sizes
    TITLE_FONT_SIZE: 20,
    INTERACTIVE_EQUATION_FONT_SIZE: 26,
    SLIDER_TICK_LABEL_FONT_SIZE: 16,
    CHECKBOX_LABEL_FONT_SIZE: 20,
    CHECKBOX_EQUATION_FONT_SIZE: 22,
    GRAPH_EQUATION_FONT_SIZE: 18,

    // line widths
    INTERACTIVE_QUADRATIC_LINE_WIDTH: 4,
    SAVED_QUADRATIC_LINE_WIDTH: 3,
    QUADRATIC_TERMS_LINE_WIDTH: 2, // y = ax^2, y = bx, y = c
    AXIS_OF_SYMMETRY_LINE_WIDTH: 3,
    DIRECTRIX_LINE_WIDTH: 3,
    POINT_ON_PARABOLA_LINE_WIDTH: 3, // lines that connect point to focus and directrix

    // line dashes
    AXIS_OF_SYMMETRY_LINE_DASH: [ 5, 5 ],
    DIRECTRIX_LINE_DASH: [ 5, 5 ],
    POINT_ON_PARABOLA_LINE_DASH: [ 5, 5 ], // lines that connect point to focus and directrix

    // decimal places
    AXIS_OF_SYMMETRY_DECIMALS: 2,
    DIRECTRIX_DECIMALS: 2,
    FOCUS_DECIMALS: 2,
    POINT_ON_PARABOLA_DECIMALS: 2,
    POINT_TOOL_DECIMALS: 1,
    ROOTS_DECIMALS: 2,
    VERTEX_DECIMALS: 2,
    EXPLORE_DECIMALS_A: 2,
    EXPLORE_DECIMALS_B: 1,
    EXPLORE_DECIMALS_C: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_A: 3,
    FOCUS_AND_DIRECTRIX_DECIMALS_P: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_H: 1,
    FOCUS_AND_DIRECTRIX_DECIMALS_K: 1,

    // slider intervals
    EXPLORE_INTERVAL_A: 0.01,
    EXPLORE_INTERVAL_B: 0.5,
    EXPLORE_INTERVAL_C: 0.5,
    FOCUS_AND_DIRECTRIX_INTERVAL_P: 0.5,
    FOCUS_AND_DIRECTRIX_INTERVAL_H: 0.5,
    FOCUS_AND_DIRECTRIX_INTERVAL_K: 0.5,

    // enums
    EQUATION_FORMS: [ 'standard', 'vertex' ], // form of equations on curves
    PROBE_SIDES: [ 'right', 'left' ], // which side the point tool's probe is on

    // margins between equations and edges of graph
    // Caution! Changing these may cause an equation to go off the graph. Test thoroughly!
    EQUATION_X_MARGIN: 1.5, // distance between equation and left/right edges of graph, in model coordinate frame
    EQUATION_Y_MARGIN: 0.5, // distance between equation and top/bottom edges of graph, in model coordinate frame

    // space between equation and the curve that it labels, in view coordinate frame
    EQUATION_CURVE_SPACING: 5,

    // spacing around operators in interactive equations
    EQUATION_OPERATOR_SPACING: 8,

    // spacing within terms in interactive equations
    EQUATION_TERM_SPACING: 6
  };

  return graphingQuadratics.register( 'GQConstants', GQConstants );
} );
<|endoftext|>


<commit_before>// Copyright (C) 2011 - Texas Instruments, Jason Kridner
//
//
var fs = require('fs');
var child_process = require('child_process');
var http = require('http');
var url = require('url');
var path = require('path');
var events = require('events');
bone = require('./bone').bone;

var myrequire = function(packageName, onfail) {
    var y = {};
    try {
        y = require(packageName);
        y.exists = true;
    } catch(ex) {
        y.exists = false;
        console.log("'" + packageName + "' not loaded");
        console.log("If desired, try installing it with:");
        console.log("  curl http://npmjs.org/install.sh | bash");
        console.log("  npm install " + packageName);
        onfail();
    }
    return(y);
};

var socket = myrequire('socket.io', function() {
    console.log("Dynamic web features not enabled");
});

var binary = myrequire('binary', function() { });
var inotify = myrequire('inotify', function() { });

var fibers = myrequire('fibers', function() {
    console.log("Delay operations loops will consume CPU cycles");
    console.log("Invoke using 'node-fibers' if node version < 0.5.2");
});

OUTPUT = exports.OUTPUT = "out";
INPUT = exports.INPUT = "in";
HIGH = exports.HIGH = 1;
LOW = exports.LOW = 0;
LSBFIRST = 1;  // used in: shiftOut(dataPin, clockPin, bitOrder, val)
MSBFIRST = 0;

var gpio = [];

pinMode = exports.pinMode = function(pin, mode)
{
    var n = pin.gpio;

    if(!gpio[n] || !gpio[n].path) {
        gpio[n] = {};

        // Ensure the pin is in GPIO mode
        if(pin.mux) {
            try {
                var muxfile = fs.openSync(
                    "/sys/kernel/debug/omap_mux/" + pin.mux, "w"
                );
                if(mode == OUTPUT)  fs.writeSync(muxfile, "7", null);
                    else fs.writeSync(muxfile, "27", null);
            } catch(ex3) {
                console.log("" + ex3);
                console.log("Unable to configure pinmux for: " + pin.name +
                    " (" + pin.mux + ")");
                console.log("Trying: mount -t debugfs none /sys/kernel/debug");
                //var state =
                //    fs.readFileSync("/sys/kernel/debug/omap_mux/" + pin.mux);
                //console.log("pinmux state: ");
                //console.log("" + state);

                // Configure the pinmux later once mount has run
                child_process.exec("mount -t debugfs none /sys/kernel/debug",
                    function(error, stderr, stdout) {
                        if(mode == OUTPUT) var muxfile = fs.writeFile("/sys/kernel/debug/omap_mux/" + pin.mux, "7");
                            else var muxfile = fs.writeFile("/sys/kernel/debug/omap_mux/" + pin.mux, "27");
                    }
                );
            }
        }

        // Export the GPIO controls
        try {
              var exists = path.existsSync("/sys/class/gpio/gpio" + n);
              if(exists) {
                      console.log("gpio: " + n + " already exported.");
                  } else {
                      try {
                          fs.writeFileSync("/sys/class/gpio/export", "" + n,null);
                      } catch(ex2) {
                          console.log(ex2);
                          console.log("Unable to export gpio: " + n);
                      }
                  }
            fs.writeFileSync("/sys/class/gpio/gpio" + n + "/direction",
                mode);
            gpio[n].path = "/sys/class/gpio/gpio" + n + "/value";
            return(true);
        } catch(ex) {
            // Perhaps we couldn't open it because it was allocated as an LED
            if(pin.led) {
                fs.writeFileSync(
                    "/sys/class/leds/beaglebone::" + pin.led + "/trigger",
                    "gpio");
                if(mode == OUTPUT) {
                    gpio[n].path =
                        "/sys/class/leds/beaglebone::" + pin.led +
                        "/brightness";
                } else {
                    gpio[n].path =
                        "/sys/class/leds/beaglebone::" + pin.led +
                        "/gpio";
                }
                return(true);
            }
        }
    }
};

digitalWrite = exports.digitalWrite = function(pin, value)
{
    fs.writeFileSync(gpio[pin.gpio].path, "" + value, null);
};

digitalRead = exports.digitalRead = function(pin)
{
    return fs.readFileSync(gpio[pin.gpio].path, null);
};

analogRead = exports.analogRead = function(pin)
{
    return fs.readFileSync("/sys/bus/platform/devices/tsc/ain" + (pin+1), null);
};

shiftOut = exports.shiftOut = function(dataPin, clockPin, bitOrder, val)
{
  var i;
  var bit;
  for (i = 0; i < 8; i++)
  {
    if (bitOrder == LSBFIRST)
    {
         bit = val & (1 << i);
    } else
    {
         bit = val & (1 << (7 - i));
    }

    digitalWrite(dataPin, bit);
    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);
  }
};

// Wait for some time
if(fibers.exists) {
    delay = exports.delay = function(milliseconds)
    {
        var fiber = Fiber.current;
        setTimeout(function() {
            fiber.run();
        }, milliseconds);
        yield();
    };
} else {
    delay = exports.delay = function(milliseconds)
    {
        var startTime = new Date().getTime();
        while(new Date().getTime() < startTime + milliseconds) {
        }
    };
}

// This is where everything is meant to happen
if(fibers.exists) {
    run = exports.run = function()
    {
        Fiber(function() {
            var fiber = Fiber.current;
            setup();
            if(typeof loop === "function") {
                while(true) {
                    loop();
                    setTimeout(function() {
                        fiber.run();
                    }, 0);
		            yield();
		        }
            }
        }).run();
    };
} else {
    run = exports.run = function()
    {
        setup();
        if(typeof loop === "function") {
            process.nextTick(function repeat() {
                loop();
                process.nextTick(repeat);
            });
        }
    };
}

// This is a helper function for web servers
var loadFile = function(uri, subdir, res, type) {
    var filename = path.join(subdir, uri);
    path.exists(
        filename,
        function(exists) {
            if(!exists) {
                res.writeHead(404, {"Content-Type": "text/plain"});
                res.write("Error 404: '" + uri + "' Not Found\n");
                res.end();
                return;
            }
            if(type == "binary") {
                fs.readFile(
                    filename,
                    "binary",
                    function(err, file) {
                        if(err) {
                            res.writeHead(500, {"Content-Type": "text/plain"});
                            res.write(err + "\n");
                            res.end();
                            return;
                        }
                        res.writeHead(200);
                        res.write(file, "binary");
                        res.end();
                    }
                );
            } else {
                fs.readFile(
                    filename,
                    encoding='utf8',
                    function(err, file) {
                        if(err) {
                            res.writeHead(500, {"Content-Type": "text/plain"});
                            res.write(err + "\n");
                            res.end();
                            return;
                        }
                        res.writeHead(200, {"Content-Type": type});
                        res.write("" + file);
                        res.end();
                    }
                );
            }
        }
    );
};

var addSocketListeners = function() {};
if(socket.exists) {
    addSocketListeners = function(server, onconnect) {
        var io = socket.listen(server);
        io.sockets.on('connection', function(socket) {
            console.log("New client connected");

            // on message
            socket.on('message', function(data) {
                console.log("Got message from client:", data);
            });

            // on disconnect
            socket.on('disconnect', function() {
                console.log("Client disconnected.");
            });

            // listen for requests and reads the debugfs entry async
            socket.on('listMux', function(pinname, fn) {
                console.log(pinname + ": " + bone[pinname].mux);
                path.exists("/sys/kernel/debug/omap_mux/" + bone[pinname].mux, function(exists) {
                    if(exists) {
                        fs.readFile("/sys/kernel/debug/omap_mux/" + bone[pinname].mux, 'utf8', function (err, data) {
                            fn(data, pinname);
                        });
                    } else {
                        // default mux
                        console.log(bone[pinname].mux + ": default mux");
                        fn("0", pinname);
                    }
                });
            });

            // call user-provided on-connect function
            if(typeof onconnect == 'function')
                onconnect(socket);

            // provide client basic platform information
            socket.emit('init', { 'platform': bone });
        });
    };
}

exports.Server = function(port, subdir, onconnect) {
    subdir = path.join(process.cwd(), subdir);
    var handler = function(req, res) {
        var uri = url.parse(req.url).pathname;
        if(uri == '/') {
            loadFile('index.html', subdir, res, "text/html");
        } else {
            if(uri.match(/\.js$/i)) {
                loadFile(uri, subdir, res, "application/javascript");
            } else if(uri.match(/\.css$/i)) {
                loadFile(uri, subdir, res, "text/css");
            } else if(uri.match(/\.htm(.)$/i)) {
                loadFile(uri, subdir, res, "text/html");
            } else if(uri.match(/\.(jpg|png|ico)$/i)) {
                loadFile(uri, subdir, res, "binary");
            } else {
                loadFile(uri, subdir, res, "text/plain");
            }
        }
    };
    this.server6 = http.createServer();
    this.server6.addListener('request', handler);
    addSocketListeners(this.server6, onconnect);
    this.server = http.createServer();
    this.server.addListener('request', handler);
    addSocketListeners(this.server, onconnect);
    this.begin = function() {
        this.server6.listen(port, '::0');
        this.server.listen(port);
    };
};
<commit_msg>Updates to bonescript to support tieing button pin to ground<commit_after>// Copyright (C) 2011 - Texas Instruments, Jason Kridner
// Note: Modified so that input pin mux is 37 instead of 27
// This allows the input pin to be tied to ground
//
var fs = require('fs');
var child_process = require('child_process');
var http = require('http');
var url = require('url');
var path = require('path');
var events = require('events');
bone = require('./bone').bone;

var myrequire = function(packageName, onfail) {
    var y = {};
    try {
        y = require(packageName);
        y.exists = true;
    } catch(ex) {
        y.exists = false;
        console.log("'" + packageName + "' not loaded");
        console.log("If desired, try installing it with:");
        console.log("  curl http://npmjs.org/install.sh | bash");
        console.log("  npm install " + packageName);
        onfail();
    }
    return(y);
};

var socket = myrequire('socket.io', function() {
    console.log("Dynamic web features not enabled");
});

var binary = myrequire('binary', function() { });
var inotify = myrequire('inotify', function() { });

var fibers = myrequire('fibers', function() {
    console.log("Delay operations loops will consume CPU cycles");
    console.log("Invoke using 'node-fibers' if node version < 0.5.2");
});

OUTPUT = exports.OUTPUT = "out";
INPUT = exports.INPUT = "in";
HIGH = exports.HIGH = 1;
LOW = exports.LOW = 0;
LSBFIRST = 1;  // used in: shiftOut(dataPin, clockPin, bitOrder, val)
MSBFIRST = 0;

var gpio = [];

pinMode = exports.pinMode = function(pin, mode)
{
    var n = pin.gpio;

    if(!gpio[n] || !gpio[n].path) {
        gpio[n] = {};

        // Ensure the pin is in GPIO mode
        if(pin.mux) {
            try {
                var muxfile = fs.openSync(
                    "/sys/kernel/debug/omap_mux/" + pin.mux, "w"
                );
                if(mode == OUTPUT)  fs.writeSync(muxfile, "7", null);
                    else fs.writeSync(muxfile, "37", null);
            } catch(ex3) {
                console.log("" + ex3);
                console.log("Unable to configure pinmux for: " + pin.name +
                    " (" + pin.mux + ")");
                console.log("Trying: mount -t debugfs none /sys/kernel/debug");
                //var state =
                //    fs.readFileSync("/sys/kernel/debug/omap_mux/" + pin.mux);
                //console.log("pinmux state: ");
                //console.log("" + state);

                // Configure the pinmux later once mount has run
                child_process.exec("mount -t debugfs none /sys/kernel/debug",
                    function(error, stderr, stdout) {
                        if(mode == OUTPUT) var muxfile = fs.writeFile("/sys/kernel/debug/omap_mux/" + pin.mux, "7");
                            else var muxfile = fs.writeFile("/sys/kernel/debug/omap_mux/" + pin.mux, "37");
                    }
                );
            }
        }

        // Export the GPIO controls
        try {
              var exists = path.existsSync("/sys/class/gpio/gpio" + n);
              if(exists) {
                      console.log("gpio: " + n + " already exported.");
                  } else {
                      try {
                          fs.writeFileSync("/sys/class/gpio/export", "" + n,null);
                      } catch(ex2) {
                          console.log(ex2);
                          console.log("Unable to export gpio: " + n);
                      }
                  }
            fs.writeFileSync("/sys/class/gpio/gpio" + n + "/direction",
                mode);
            gpio[n].path = "/sys/class/gpio/gpio" + n + "/value";
            return(true);
        } catch(ex) {
            // Perhaps we couldn't open it because it was allocated as an LED
            if(pin.led) {
                fs.writeFileSync(
                    "/sys/class/leds/beaglebone::" + pin.led + "/trigger",
                    "gpio");
                if(mode == OUTPUT) {
                    gpio[n].path =
                        "/sys/class/leds/beaglebone::" + pin.led +
                        "/brightness";
                } else {
                    gpio[n].path =
                        "/sys/class/leds/beaglebone::" + pin.led +
                        "/gpio";
                }
                return(true);
            }
        }
    }
};

digitalWrite = exports.digitalWrite = function(pin, value)
{
    fs.writeFileSync(gpio[pin.gpio].path, "" + value, null);
};

digitalRead = exports.digitalRead = function(pin)
{
    return fs.readFileSync(gpio[pin.gpio].path, null);
};

analogRead = exports.analogRead = function(pin)
{
    return fs.readFileSync("/sys/bus/platform/devices/tsc/ain" + (pin+1), null);
};

shiftOut = exports.shiftOut = function(dataPin, clockPin, bitOrder, val)
{
  var i;
  var bit;
  for (i = 0; i < 8; i++)
  {
    if (bitOrder == LSBFIRST)
    {
         bit = val & (1 << i);
    } else
    {
         bit = val & (1 << (7 - i));
    }

    digitalWrite(dataPin, bit);
    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);
  }
};

// Wait for some time
if(fibers.exists) {
    delay = exports.delay = function(milliseconds)
    {
        var fiber = Fiber.current;
        setTimeout(function() {
            fiber.run();
        }, milliseconds);
        yield();
    };
} else {
    delay = exports.delay = function(milliseconds)
    {
        var startTime = new Date().getTime();
        while(new Date().getTime() < startTime + milliseconds) {
        }
    };
}

// This is where everything is meant to happen
if(fibers.exists) {
    run = exports.run = function()
    {
        Fiber(function() {
            var fiber = Fiber.current;
            setup();
            if(typeof loop === "function") {
                while(true) {
                    loop();
                    setTimeout(function() {
                        fiber.run();
                    }, 0);
		            yield();
		        }
            }
        }).run();
    };
} else {
    run = exports.run = function()
    {
        setup();
        if(typeof loop === "function") {
            process.nextTick(function repeat() {
                loop();
                process.nextTick(repeat);
            });
        }
    };
}

// This is a helper function for web servers
var loadFile = function(uri, subdir, res, type) {
    var filename = path.join(subdir, uri);
    path.exists(
        filename,
        function(exists) {
            if(!exists) {
                res.writeHead(404, {"Content-Type": "text/plain"});
                res.write("Error 404: '" + uri + "' Not Found\n");
                res.end();
                return;
            }
            if(type == "binary") {
                fs.readFile(
                    filename,
                    "binary",
                    function(err, file) {
                        if(err) {
                            res.writeHead(500, {"Content-Type": "text/plain"});
                            res.write(err + "\n");
                            res.end();
                            return;
                        }
                        res.writeHead(200);
                        res.write(file, "binary");
                        res.end();
                    }
                );
            } else {
                fs.readFile(
                    filename,
                    encoding='utf8',
                    function(err, file) {
                        if(err) {
                            res.writeHead(500, {"Content-Type": "text/plain"});
                            res.write(err + "\n");
                            res.end();
                            return;
                        }
                        res.writeHead(200, {"Content-Type": type});
                        res.write("" + file);
                        res.end();
                    }
                );
            }
        }
    );
};

var addSocketListeners = function() {};
if(socket.exists) {
    addSocketListeners = function(server, onconnect) {
        var io = socket.listen(server);
        io.sockets.on('connection', function(socket) {
            console.log("New client connected");

            // on message
            socket.on('message', function(data) {
                console.log("Got message from client:", data);
            });

            // on disconnect
            socket.on('disconnect', function() {
                console.log("Client disconnected.");
            });

            // listen for requests and reads the debugfs entry async
            socket.on('listMux', function(pinname, fn) {
                console.log(pinname + ": " + bone[pinname].mux);
                path.exists("/sys/kernel/debug/omap_mux/" + bone[pinname].mux, function(exists) {
                    if(exists) {
                        fs.readFile("/sys/kernel/debug/omap_mux/" + bone[pinname].mux, 'utf8', function (err, data) {
                            fn(data, pinname);
                        });
                    } else {
                        // default mux
                        console.log(bone[pinname].mux + ": default mux");
                        fn("0", pinname);
                    }
                });
            });

            // call user-provided on-connect function
            if(typeof onconnect == 'function')
                onconnect(socket);

            // provide client basic platform information
            socket.emit('init', { 'platform': bone });
        });
    };
}

exports.Server = function(port, subdir, onconnect) {
    subdir = path.join(process.cwd(), subdir);
    var handler = function(req, res) {
        var uri = url.parse(req.url).pathname;
        if(uri == '/') {
            loadFile('index.html', subdir, res, "text/html");
        } else {
            if(uri.match(/\.js$/i)) {
                loadFile(uri, subdir, res, "application/javascript");
            } else if(uri.match(/\.css$/i)) {
                loadFile(uri, subdir, res, "text/css");
            } else if(uri.match(/\.htm(.)$/i)) {
                loadFile(uri, subdir, res, "text/html");
            } else if(uri.match(/\.(jpg|png|ico)$/i)) {
                loadFile(uri, subdir, res, "binary");
            } else {
                loadFile(uri, subdir, res, "text/plain");
            }
        }
    };
    this.server6 = http.createServer();
    this.server6.addListener('request', handler);
    addSocketListeners(this.server6, onconnect);
    this.server = http.createServer();
    this.server.addListener('request', handler);
    addSocketListeners(this.server, onconnect);
    this.begin = function() {
        this.server6.listen(port, '::0');
        this.server.listen(port);
    };
};
<|endoftext|>


<commit_before>(function($) {

	function defaultHandler(endpoint, data, callback) {
		$.post(endpoint, data)
			.done(function () {
		    callback();
		  })
		  .fail(function () {
		    alert("Something went wrong :/");
		    callback(true);
		  });
	}

	$.dingdong = function(options) {

		// parse options
		var opts = {};
		if (options) {
			if ($.type(options) === "object") {
				opts = options;
			} else if ($.type(options) === "string") {
				opts.endpoint = options;
			} else if ($.type(options) === "function") {
				opts.handler = options;
			} else {
				console.error("dingdong argument should be object (options), string (custom endpoint), or function (custom handler) :/");
			}
		}

		// fade options
		var fade = opts.fade !== false;
		var fadeOpen = opts.openFadeDuration || 100;
		var fadeCancel = opts.cancelFadeDuration || 100;
		var fadeSubmit = opts.submitFadeDuration || 1000;

		// custom text options
		var buttonText = opts.buttonText = "Feedback";
		var emailPlaceholder = opts.emailPlaceholder || "Your email address";
		var messagePlaceholder = opts.messagePlaceholder || "Send us your feedback or report an issue";
		var submitButtonText = opts.submitButtonText || "Send message";
		var submittedText = opts.submittedText || "Thanks!";
		var subscribeButtonText = opts.subscribeButtonText || "Subscribe";
		var fnamePlaceholder = opts.fnamePlaceholder || "First name";
		var lnamePlaceholder = opts.lnamePlaceholder || "Last name";
		var subscribeLabel = opts.subscribeLabel || "Subscribe to newsletter";

		// misc
		var messageRows = opts.messageRows || 7;
		var escapeToCancel = opts.escapeToCancel !== false;
		var endpoint = opts.endpoint || "/dingdong";

		// helper function for showing
		$.dingdongShow = function (mode) {
			$("#dingdong-submit").prop("disabled", false);
			$("#dingdong-submit").text(submitButtonText);
			$("#dingdong-message").val("");
			// intentionally dont clear email, fname, lname

			if (mode === "subscribeOnly") {
				$("#dingdong-subscribe").prop("checked", true);
				$("#dingdong-name-row").show();
				$("#dingdong-message-row").hide();
				$("#dingdong-submit").text(subscribeButtonText);
				$("#dingdong-fname").prop("required", true);
				$("#dingdong-lname").prop("required", true);
				$("#dingdong-message").prop("required", false);
			} else {
				$("#dingdong-subscribe").prop("checked", false);
				$("#dingdong-name-row").hide();
				$("#dingdong-message-row").show();
				$("#dingdong-submit").text(submitButtonText);
				$("#dingdong-fname").prop("required", false);
				$("#dingdong-lname").prop("required", false);
				$("#dingdong-message").prop("required", true);
			}

			if (mode === "subscribeOnly" || mode === "messageOnly") {
				$("#dingdong-subscribe-row").hide();
			} else {
				$("#dingdong-subscribe-row").show();
			}

			if (fade) {
				$("#dingdong").fadeIn(fadeOpen);
			} else {
				$("#dingdong").show();
			}
		}

		// helper function for canceling
		$.dingdongCancel = function () {
			if (fade) {
				$("#dingdong").fadeOut(fadeCancel);
			} else {
				$("#dingdong").hide();
			}
		}

		// helper function for hiding (aka after submit)
		$.dingdongHide = function () {
			if (fade) {
				$("#dingdong").fadeOut(fadeSubmit);
			} else {
				$("#dingdong").hide();
			}
			$("#dingdong-submit").text(submittedText);
		}

		// maybe build header option
		var header;
		if (opts.header) {
			header = [
				$("<div/>", { "class": "dingdong-row" }).append(
					$("<div/>", { id: "dingdong-header", html: opts.header })
				)
			];
		}

		// maybe build subscribe section
		var subscribe = [
			$("<div/>", { id: "dingdong-subscribe-row", "class": "dingdong-row" }).append(
				$("<label/>", { for: "dingdong-subscribe", text: subscribeLabel }).append(
					$("<span/>", { "class": "dingdong-switch" }).append(
						$("<input/>", { id: "dingdong-subscribe", name: "subscribe", type: "checkbox" }),
						$("<div/>", { "class": "dingdong-switch-slider" })
					)
				)
			),
			$("<div/>", { id: "dingdong-name-row", "class": "dingdong-row" }).append(
				$("<input/>", { id: "dingdong-fname", name: "fname", type: "text", placeholder: fnamePlaceholder, width: "50%" }),
				$("<input/>", { id: "dingdong-lname", name: "lname", type: "text", placeholder: lnamePlaceholder, width: "50%" })
			)
		];

		var message = [
			$("<div/>", { id: "dingdong-message-row", "class": "dingdong-row" }).append(
				$("<textarea/>", { id: "dingdong-message", name: "message", rows: messageRows, placeholder: messagePlaceholder, required: "required" })
			)
		];

		var email = [
			$("<div/>", { "class": "dingdong-row" }).append(
				$("<input/>", { id: "dingdong-email", name: "email", type: "email", placeholder: emailPlaceholder, required: "required" })
			)
		];

		var submit = [
			$("<button/>", { id: "dingdong-submit", type: "submit", text: submitButtonText })
		];

		// remove existing if $.dingdong has already been called
		$("#dingdong-button").remove();
		$("#dingdong").remove();

		// add dingdong button
		$("body").append(
			$("<button />", { id: "dingdong-button", style: "display: none", text: buttonText })
		);

		// add dingdong modal
		$("body").append(
			$("<div/>", { id: "dingdong", style: "display: none" }).append(
				$("<div/>", { id: "dingdong-box" }).append(
					$("<div/>", { id: "dingdong-close", text: "\u00D7" }),
					$("<form/>", { id: "dingdong-form" }).append(
						header,
						email,
						message,
						subscribe,
						submit
					)
				)
			)
		);

		// maybe listen for esc to cancel
		if (escapeToCancel) {
			$(document).keydown(function(e) {
		    if (e.keyCode == 27) {
		        $.dingdongCancel();
		    }
			});
		}

		// toggle name fields when subscribe checkbox changes
		$("#dingdong-subscribe").change(function () {
			var checked = $(this).is(":checked");
			if (checked) {
				$("#dingdong-name-row").slideDown();
			} else {
				$("#dingdong-name-row").slideUp();
			}
			$("#dingdong-fname").prop("required", checked);
			$("#dingdong-lname").prop("required", checked);
		});

		// show dingdong when button is clicked
		$("#dingdong-button").click(function () {
			$.dingdongShow();
		});

		// cancel dingdong when backdrop or close is clicked
		$("#dingdong, #dingdong-close").click(function () {
			$.dingdongCancel();
		});

		// prevent clicks inside the box from propagating
		// (otherwise any click inside will trigger above cancel)
		$("#dingdong-box").click(function (e) {
			e.stopPropagation();
		});

		// handle form submission (prevent default behavior since ajax)
		$("#dingdong-form").submit(function (e) {
			e.preventDefault();
			var data = {
				message: $("#dingdong-message").val(),
				email: $("#dingdong-email").val(),
				subscribe: $("#dingdong-subscribe").is(":checked"),
				fname: $("#dingdong-fname").val(),
				lname: $("#dingdong-lname").val()
			};
			function callback(err) {
				if (err) {
					$("#dingdong-submit").prop("disabled", false);
				} else {
					$.dingdongHide();
				}
			}
			$("#dingdong-submit").prop("disabled", true);
			if (opts.handler) {
				opts.handler(data, callback);
			} else {
				defaultHandler(opts.endpoint, data, callback);
			}
			return false;
		});

	}

}(jQuery));
<commit_msg>Removing "required" on fname and lname<commit_after>(function($) {

	function defaultHandler(endpoint, data, callback) {
		$.post(endpoint, data)
			.done(function () {
		    callback();
		  })
		  .fail(function () {
		    alert("Something went wrong :/");
		    callback(true);
		  });
	}

	$.dingdong = function(options) {

		// parse options
		var opts = {};
		if (options) {
			if ($.type(options) === "object") {
				opts = options;
			} else if ($.type(options) === "string") {
				opts.endpoint = options;
			} else if ($.type(options) === "function") {
				opts.handler = options;
			} else {
				console.error("dingdong argument should be object (options), string (custom endpoint), or function (custom handler) :/");
			}
		}

		// fade options
		var fade = opts.fade !== false;
		var fadeOpen = opts.openFadeDuration || 100;
		var fadeCancel = opts.cancelFadeDuration || 100;
		var fadeSubmit = opts.submitFadeDuration || 1000;

		// custom text options
		var buttonText = opts.buttonText = "Feedback";
		var emailPlaceholder = opts.emailPlaceholder || "Your email address";
		var messagePlaceholder = opts.messagePlaceholder || "Send us your feedback or report an issue";
		var submitButtonText = opts.submitButtonText || "Send message";
		var submittedText = opts.submittedText || "Thanks!";
		var subscribeButtonText = opts.subscribeButtonText || "Subscribe";
		var fnamePlaceholder = opts.fnamePlaceholder || "First name";
		var lnamePlaceholder = opts.lnamePlaceholder || "Last name";
		var subscribeLabel = opts.subscribeLabel || "Subscribe to newsletter";

		// misc
		var messageRows = opts.messageRows || 7;
		var escapeToCancel = opts.escapeToCancel !== false;
		var endpoint = opts.endpoint || "/dingdong";

		// helper function for showing
		$.dingdongShow = function (mode) {
			$("#dingdong-submit").prop("disabled", false);
			$("#dingdong-submit").text(submitButtonText);
			$("#dingdong-message").val("");
			// intentionally dont clear email, fname, lname

			if (mode === "subscribeOnly") {
				$("#dingdong-subscribe").prop("checked", true);
				$("#dingdong-name-row").show();
				$("#dingdong-message-row").hide();
				$("#dingdong-submit").text(subscribeButtonText);
				$("#dingdong-message").prop("required", false);
			} else {
				$("#dingdong-subscribe").prop("checked", false);
				$("#dingdong-name-row").hide();
				$("#dingdong-message-row").show();
				$("#dingdong-submit").text(submitButtonText);
				$("#dingdong-message").prop("required", true);
			}

			if (mode === "subscribeOnly" || mode === "messageOnly") {
				$("#dingdong-subscribe-row").hide();
			} else {
				$("#dingdong-subscribe-row").show();
			}

			if (fade) {
				$("#dingdong").fadeIn(fadeOpen);
			} else {
				$("#dingdong").show();
			}
		}

		// helper function for canceling
		$.dingdongCancel = function () {
			if (fade) {
				$("#dingdong").fadeOut(fadeCancel);
			} else {
				$("#dingdong").hide();
			}
		}

		// helper function for hiding (aka after submit)
		$.dingdongHide = function () {
			if (fade) {
				$("#dingdong").fadeOut(fadeSubmit);
			} else {
				$("#dingdong").hide();
			}
			$("#dingdong-submit").text(submittedText);
		}

		// maybe build header option
		var header;
		if (opts.header) {
			header = [
				$("<div/>", { "class": "dingdong-row" }).append(
					$("<div/>", { id: "dingdong-header", html: opts.header })
				)
			];
		}

		// maybe build subscribe section
		var subscribe = [
			$("<div/>", { id: "dingdong-subscribe-row", "class": "dingdong-row" }).append(
				$("<label/>", { for: "dingdong-subscribe", text: subscribeLabel }).append(
					$("<span/>", { "class": "dingdong-switch" }).append(
						$("<input/>", { id: "dingdong-subscribe", name: "subscribe", type: "checkbox" }),
						$("<div/>", { "class": "dingdong-switch-slider" })
					)
				)
			),
			$("<div/>", { id: "dingdong-name-row", "class": "dingdong-row" }).append(
				$("<input/>", { id: "dingdong-fname", name: "fname", type: "text", placeholder: fnamePlaceholder, width: "50%" }),
				$("<input/>", { id: "dingdong-lname", name: "lname", type: "text", placeholder: lnamePlaceholder, width: "50%" })
			)
		];

		var message = [
			$("<div/>", { id: "dingdong-message-row", "class": "dingdong-row" }).append(
				$("<textarea/>", { id: "dingdong-message", name: "message", rows: messageRows, placeholder: messagePlaceholder, required: "required" })
			)
		];

		var email = [
			$("<div/>", { "class": "dingdong-row" }).append(
				$("<input/>", { id: "dingdong-email", name: "email", type: "email", placeholder: emailPlaceholder, required: "required" })
			)
		];

		var submit = [
			$("<button/>", { id: "dingdong-submit", type: "submit", text: submitButtonText })
		];

		// remove existing if $.dingdong has already been called
		$("#dingdong-button").remove();
		$("#dingdong").remove();

		// add dingdong button
		$("body").append(
			$("<button />", { id: "dingdong-button", style: "display: none", text: buttonText })
		);

		// add dingdong modal
		$("body").append(
			$("<div/>", { id: "dingdong", style: "display: none" }).append(
				$("<div/>", { id: "dingdong-box" }).append(
					$("<div/>", { id: "dingdong-close", text: "\u00D7" }),
					$("<form/>", { id: "dingdong-form" }).append(
						header,
						email,
						message,
						subscribe,
						submit
					)
				)
			)
		);

		// maybe listen for esc to cancel
		if (escapeToCancel) {
			$(document).keydown(function(e) {
		    if (e.keyCode == 27) {
		        $.dingdongCancel();
		    }
			});
		}

		// toggle name fields when subscribe checkbox changes
		$("#dingdong-subscribe").change(function () {
			var checked = $(this).is(":checked");
			if (checked) {
				$("#dingdong-name-row").slideDown();
			} else {
				$("#dingdong-name-row").slideUp();
			}
			$("#dingdong-fname").prop("required", checked);
			$("#dingdong-lname").prop("required", checked);
		});

		// show dingdong when button is clicked
		$("#dingdong-button").click(function () {
			$.dingdongShow();
		});

		// cancel dingdong when backdrop or close is clicked
		$("#dingdong, #dingdong-close").click(function () {
			$.dingdongCancel();
		});

		// prevent clicks inside the box from propagating
		// (otherwise any click inside will trigger above cancel)
		$("#dingdong-box").click(function (e) {
			e.stopPropagation();
		});

		// handle form submission (prevent default behavior since ajax)
		$("#dingdong-form").submit(function (e) {
			e.preventDefault();
			var data = {
				message: $("#dingdong-message").val(),
				email: $("#dingdong-email").val(),
				subscribe: $("#dingdong-subscribe").is(":checked"),
				fname: $("#dingdong-fname").val(),
				lname: $("#dingdong-lname").val()
			};
			function callback(err) {
				if (err) {
					$("#dingdong-submit").prop("disabled", false);
				} else {
					$.dingdongHide();
				}
			}
			$("#dingdong-submit").prop("disabled", true);
			if (opts.handler) {
				opts.handler(data, callback);
			} else {
				defaultHandler(opts.endpoint, data, callback);
			}
			return false;
		});

	}

}(jQuery));
<|endoftext|>


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

  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Component = app.Component || require('./component.js');

  var SidebarModule = helper.inherits(function(props) {
    SidebarModule.super_.call(this, props);

    this.title = this.prop(props.title);
    this.content = this.prop(props.content);
  }, Component);

  var Sidebar = helper.inherits(function(props) {
    Sidebar.super_.call(this, props);
  }, Component);

  Sidebar.prototype.searchInputElement = function() {
    return dom.child(this.element(), 0, 0);
  };

  Sidebar.prototype.contentElement = function() {
    return dom.child(this.element(), 1);
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = Sidebar;
  } else {
    app.Sidebar = Sidebar;
  }
})(this.app || (this.app = {}));
<commit_msg>Make skeleton element of sidebar-module<commit_after>(function(app) {
  'use strict';

  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Component = app.Component || require('./component.js');

  var SidebarModule = helper.inherits(function(props) {
    SidebarModule.super_.call(this, props);

    this.title = this.prop(props.title);
    this.content = this.prop(props.content);
    this.parentElement = this.prop(null);
  }, Component);

  SidebarModule.prototype.redraw = function() {
    var element = this.element();
    var parentElement = this.parentElement();

    if (!parentElement && !element) {
      return;
    }

    // add element
    if (parentElement && !element) {
      element = dom.el('<div>');
      this.element(element);
      dom.append(parentElement, element);
      return;
    }

    // remove element
    if (!parentElement && element) {
      dom.remove(element);
      this.element(null);
      return;
    }
  };

  var Sidebar = helper.inherits(function(props) {
    Sidebar.super_.call(this, props);
  }, Component);

  Sidebar.prototype.searchInputElement = function() {
    return dom.child(this.element(), 0, 0);
  };

  Sidebar.prototype.contentElement = function() {
    return dom.child(this.element(), 1);
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = Sidebar;
  } else {
    app.Sidebar = Sidebar;
  }
})(this.app || (this.app = {}));
<|endoftext|>


<commit_before>import DataStore from 'classes/data-store';
import SearchResult from 'classes/search-result';
import Levenshtein from 'classes/levenshtein';
import SearchView from 'views/search';
import ListView from 'views/list';
import * as templates from 'templates';
import ajax from 'utils/ajax';

class SearchController {
    constructor(opts = {}) {
        // models
        this.lastSearch = '';
        this.store = new DataStore();
        this.searches = new DataStore();

        // views
        this.searchView = new SearchView({
            el: opts.searchEl
        });
        this.orgListView = new ListView({
            el: opts.orgListEl,
            template: templates.OrgListItem,
        });
        this.projectListView = new ListView({
            el: opts.projectListEl,
            template: templates.ProjectListItem,
        });
    }

    init() {
        return this.initStorage().then(() => {
            var store = this.store;
            this.initLevenshtein();
            this.initTextBox();
            this.orgListView.render(store.all('org'));
            this.projectListView.render(store.all('project'));
        });
    }

    initStorage() {
        var store = this.store;
        store.addType('org');
        store.addType('project');
        this.searches.addType('search');
        this.searches.registerModelFactory('search', SearchResult);

        function addProjects(projects) {
            var id = 1;
            projects.forEach(proj => {
                proj.id = id++;

                if (proj.organizationId) {
                    proj.organization = store.find('org', proj.organizationId);
                }

                return proj;
            });
            store.load('project', projects);
        }

        return ajax({url: '/data/organizations.json'})
            .then(orgs => {
                this.store.load('org', orgs);
                return ajax({url: '/data/projects.json'});
            }).then(addProjects);
    }

    initLevenshtein() {
        var levOpts = {
            type: 'substring',
            caseSensitive: false
        };
        this.lev = new Levenshtein(levOpts);
        this.lev.set('insertCost', 0);
        this.lev.set('deleteCost', Infinity);
    }

    initTextBox() {
        this.searchView.on('keyup', this.handleKeyup.bind(this));
    }

    handleKeyup(evt) {
        var value = evt.target.value;

        if (this.lastSearch.length < value.length) {
            // we're filtering current results
        } else {
            // we're widening current results
        }
    }
}

export default SearchController;
<commit_msg>Start building out search functionality<commit_after>import DataStore from 'classes/data-store';
import SearchResult from 'classes/search-result';
import Levenshtein from 'classes/levenshtein';
import SearchView from 'views/search';
import ListView from 'views/list';
import * as templates from 'templates';
import ajax from 'utils/ajax';

class SearchController {
    constructor(opts = {}) {
        // models
        this.lastSearch = '';
        this.store = new DataStore();

        // views
        this.searchView = new SearchView({
            el: opts.searchEl
        });
        this.orgListView = new ListView({
            el: opts.orgListEl,
            template: templates.OrgListItem,
        });
        this.projectListView = new ListView({
            el: opts.projectListEl,
            template: templates.ProjectListItem,
        });
    }

    init() {
        return this.initStorage().then(() => {
            var store = this.store;
            this.initLevenshtein();
            this.initTextBox();
            this.orgListView.render(store.all('org'));
            this.projectListView.render(store.all('project'));
        });
    }

    initStorage() {
        var store = this.store;
        store.addType('org');
        store.addType('project');
        store.addType('search');
        store.registerModelFactory('search', SearchResult);

        function addOrgs(orgs) {
            store.load('org', orgs);
            return ajax({url: '/data/projects.json'});
        }

        function addProjects(projects) {
            var id = 1;
            projects.forEach(proj => {
                proj.id = id++;

                if (proj.organizationId) {
                    proj.organization = store.find('org', proj.organizationId);
                }

                return proj;
            });
            store.load('project', projects);
        }

        return ajax({url: '/data/organizations.json'})
            .then(addOrgs)
            .then(addProjects)
            .then(() => {
                store.load('search', {
                    // initialize search results for empty search text box
                    id: '',
                    org: store.all('org'),
                    project: store.all('project'),
                });
            });
    }

    initLevenshtein() {
        var levOpts = {
            type: 'substring',
            caseSensitive: false
        };
        this.lev = new Levenshtein(levOpts);
        this.lev.set('insertCost', 0);
        this.lev.set('deleteCost', Infinity);
    }

    initTextBox() {
        this.searchView.on('keyup', this.handleKeyup.bind(this));
    }

    handleKeyup(evt) {
        var value = evt.target.value;
        var lastSearch = this.lastSearch;
        var store = this.store;
        var model;

        // if search has been previously cached in the database, use it
        model = store.find('search', value);

        if (!model) {
            if (lastSearch.length < value.length) {
                // we're filtering current results, use last results
                model = store.find('search', lastSearch);
            } else {
                // we're widening current results, start from scratch
                model = store.find('search', '');
            }

            // perform string approximation on models' attributes
            model = this.approximate(model, value);
            // store the search results back into the store
            store.load('search', model);
        }

        // apply user-supplied filters to the search results
        model = this.applyFilters(model);

        this.lastSearch = value;
        this.orgListView.render(model.org);
        this.projectListView.render(model.project);
    }

    approximate(model, searchString) {
        var ret = {};

        // model id is the value of the search itself
        // so that the data store can be queried easily
        ret.id = searchString;

        ret.org = model.org.slice(1);
        ret.project = model.project.slice(1);

        return ret;
    }

    applyFilters(model) {
        var ret = {};
        ret.org = model.org;
        ret.project = model.project;
        return ret;
    }
}

export default SearchController;
<|endoftext|>


<commit_before>var dataSource = require('./modules/db');

dataSource.discoverSchema('account', {owner: 'demo'}, function (err, schema) {
    console.log(JSON.stringify(schema, null, '  '));
});

dataSource.discoverAndBuildModels('account', {}, function (err, models) {
    models.Account.find(function (err, act) {
        if (err) {
            console.error(err);
        } else {
            console.log(act);
        }
    });
});

<commit_msg>Add onwer option to avoid confusions over other dbs<commit_after>var dataSource = require('./modules/db');

dataSource.discoverSchema('account', {owner: 'demo'}, function (err, schema) {
    console.log(JSON.stringify(schema, null, '  '));
});

dataSource.discoverAndBuildModels('account', {owner: 'demo'}, function (err, models) {
    models.Account.find(function (err, act) {
        if (err) {
            console.error(err);
        } else {
            console.log(act);
        }
    });
});

<|endoftext|>


<commit_before>define(['js/html/HtmlElement', 'underscore'], function(HtmlElement, _){

    /***
     * The WindowManager manages Windows on the Stage.
     *
     * @see js.core.Stage
     */
    return HtmlElement.inherit('js.core.WindowManager', {

        ctor: function() {

            this.$windows = [];
            this.$modalWindows = [];

            this.callBase();
        },

        defaults: {
            tagName: 'div',
            'class': 'window-manager'
        },

        /***
         * Adds a window to the WindowManager and shows it
         * @param {js.core.Window} window - window instance to show
         * @param {Function} [windowCloseCallback] - callback function invoked after the window the is closed
         * @param {Boolean} [modal=false] - if true a modal window in front of all other windows will be shown
         */
        show: function(window, windowCloseCallback, modal) {

            var self = this,
                list = modal ? this.$windows : this.$modalWindows,
                child = window;

            if (modal) {
                child = this.createComponent(HtmlElement, {
                    tagName: 'div',
                    componentClass: 'modal'
                });

                child.addChild(this.createComponent(HtmlElement, {
                    tagName: 'div',
                    'class': 'modal-backdrop back-drop'
                }));

                child.addChild(window);

                window.set('componentClass', 'modal window');
            }

            this.addChild(child);
            list.push(window);

            var closeHandler = function(e) {
                self.removeChild(child);
                list.splice(_.indexOf(list, window), 1);

                window.unbind('close', closeHandler);

                if (windowCloseCallback) {
                    windowCloseCallback(null, window, e.$);
                }
            };

            window.bind('close', closeHandler, this);
        }

    });

});<commit_msg>added modal-active class to window manager if modal popup is active<commit_after>define(['js/html/HtmlElement', 'underscore'], function(HtmlElement, _){

    /***
     * The WindowManager manages Windows on the Stage.
     *
     * @see js.core.Stage
     */
    return HtmlElement.inherit('js.core.WindowManager', {

        ctor: function() {

            this.$windows = [];
            this.$modalWindows = [];

            this.callBase();
        },

        defaults: {
            tagName: 'div',
            modalActive: false,
            'class': 'window-manager {modalActiveClass()}'
        },

        $classAttributes: ["modalActive"],

        modalActiveClass: function() {
            return this.$.modalActive ? "modal-active" : "";
        }.onChange("modalActive"),

        /***
         * Adds a window to the WindowManager and shows it
         * @param {js.core.Window} window - window instance to show
         * @param {Function} [windowCloseCallback] - callback function invoked after the window the is closed
         * @param {Boolean} [modal=false] - if true a modal window in front of all other windows will be shown
         */
        show: function(window, windowCloseCallback, modal) {

            var self = this,
                list = modal ? this.$windows : this.$modalWindows,
                child = window;

            if (modal) {
                child = this.createComponent(HtmlElement, {
                    tagName: 'div',
                    componentClass: 'modal'
                });

                child.addChild(this.createComponent(HtmlElement, {
                    tagName: 'div',
                    'class': 'modal-backdrop back-drop'
                }));

                child.addChild(window);

                window.set('componentClass', 'modal window');
                self.set("modalActive", true);
            }

            this.addChild(child);
            list.push(window);

            var closeHandler = function(e) {
                self.removeChild(child);
                list.splice(_.indexOf(list, window), 1);

                window.unbind('close', closeHandler);
                self.set("modalActive", false);

                if (windowCloseCallback) {
                    windowCloseCallback(null, window, e.$);
                }
            };

            window.bind('close', closeHandler, this);
        }

    });

});<|endoftext|>


<commit_before>//     JEFRi PostStore.js 0.1.0
//     (c) 2011-2012 David Souther
//     JEFRi is freely distributable under the MIT license.
//     For all details and documentation:
//     http://jefri.org

(function(_){
	var root = this;

	// ### Persistence Stores
	// TODO move this out

	// #### PostStore
	//
	// Handles POSTing a transaction to a remote JEFRi instance.
	root.JEFRi.PostStore = function(ec, options) {
		this.ec = ec;
		this.target = options && options.target;
		var self = this;

		var _send = function(url, transaction, pre, post) {
			_.trigger(transaction, pre);
			_.trigger(self, pre, transaction);
			_.trigger(self, 'sending', transaction);
			return _.post(url, {
				data    : transaction.toString(),
				dataType: "application/json"
			}).done(
				function(data) {
					//Always updateOnIntern
					ec.expand(data, true);
					_.trigger(self, 'sent', data);
					_.trigger(self, post, data);
					_.trigger(transaction, post, data);
				}
			);
		};

		if(this.target) {
			//Configured correctly, so we can safely transact.
			this.get = function(transaction) {
				var url = (this.target + "get");
				return _send(url, transaction, 'getting', 'gotten');
			};

			this.persist = function(transaction) {
				var url = (this.target + "persist");
				return _send(url, transaction, 'persisting', 'persisted');
			};
		} else {
			//No backing data store, so do nothing.
			this.get = this.persist = function(transaction) {
				return _.Deferred().resolve().promise();
			};
		}

		// Always asynchronous.
		this.is_async = function(){
			return true;
		};
	};
}.call(this, _, JEFRi));<commit_msg>Added execute function.<commit_after>//     JEFRi PostStore.js 0.1.0
//     (c) 2011-2012 David Souther
//     JEFRi is freely distributable under the MIT license.
//     For all details and documentation:
//     http://jefri.org

(function(_){
	var root = this;

	// ### PostStore
	//
	// Handles POSTing a transaction to a remote JEFRi instance.
	root.JEFRi.PostStore = function(ec, options) {
		this.ec = ec;
		this.target = options && options.target;
		var self = this;

		var _send = function(url, transaction, pre, post) {
			_.trigger(transaction, pre);
			_.trigger(self, pre, transaction);
			_.trigger(self, 'sending', transaction);
			return _.post(url, {
				data    : transaction.toString(),
				dataType: "application/json"
			}).done(
				function(data) {
					//Always updateOnIntern
					ec.expand(data, true);
					_.trigger(self, 'sent', data);
					_.trigger(self, post, data);
					_.trigger(transaction, post, data);
				}
			);
		};

		if(this.target) {
			//Configured correctly, so we can safely transact.
			this.get = function(transaction) {
				var url = (this.target + "get");
				return _send(url, transaction, 'getting', 'gotten');
			};

			this.persist = function(transaction) {
				var url = (this.target + "persist");
				return _send(url, transaction, 'persisting', 'persisted');
			};
		} else {
			//No backing data store, so do nothing.
			this.get = this.persist = function(transaction) {
				transaction.entities = [];
				_.trigger(transaction, "gotten");
				return _.Deferred().resolve().promise();
			};
		}

		// Always asynchronous.
		this.is_async = function(){
			return true;
		};
	};

	_.extend(root.JEFRi.PostStore.prototype, {
		execute: function(type, transaction){
			this[type](transaction);
		}
	});
}.call(this, _, JEFRi));<|endoftext|>


<commit_before>'use strict';

function draw_logic(){
    // Draw ground grass.
    buffer.fillStyle = '#131';
    buffer.fillRect(
      0,
      floor_position,
      width,
      y
    );

    buffer.fillStyle = split_state[0]
      ? '#323232'
      : '#646464';

    // Precalculate left wall split position.
    var precalc = (splits[0][0] * (1 / splits[0][2])) + x;

    // Draw left wall extra bit.
    if(player_position > 0){
        buffer.fillRect(
          0,
          0,
          1 + (player_position >= precalc ? precalc : player_position),
          height
        );
    }

    // Draw left wall closer than split.
    if(player_position < precalc){
        buffer.beginPath();
        buffer.moveTo(
          player_position,
          y - x
        );
        buffer.lineTo(
          precalc,
          (splits[0][1] * (1 / splits[0][2])) + y
        );
        buffer.lineTo(
          precalc,
          (splits[1][1] * (1 / splits[1][2])) + y
        );
        buffer.lineTo(
          player_position,
          y + x
        );
        buffer.closePath();
        buffer.fill();
    }

    // Draw left wall further than split.
    buffer.fillStyle = split_state[0]
      ? '#646464'
      : '#323232';
    buffer.beginPath();
    buffer.moveTo(
      precalc,
      (splits[0][1] * (1 / splits[0][2])) + y
    );
    buffer.lineTo(
      x,
      y
    );
    buffer.lineTo(
      precalc,
      (splits[1][1] * (1 / splits[1][2])) + y
    );
    buffer.closePath();
    buffer.fill();

    buffer.fillStyle = split_state[0]
      ? '#646464'
      : '#323232';

    // Precalculate right wall split position.
    precalc = (splits[2][0] * (1 / splits[2][2])) + x;

    // Draw right wall extra bit.
    if(player_position < 0){
        buffer.fillRect(
          width + player_position < precalc
            ? precalc - 1
            : width + player_position - 1,
          0,
          -player_position,
          height
        );
    }

    // Draw right wall closer than split.
    if(width + player_position > precalc){
        buffer.beginPath();
        buffer.moveTo(
          width + player_position,
          y - x
        );
        buffer.lineTo(
          precalc,
          (splits[2][1] * (1 / splits[2][2])) + y
        );
        buffer.lineTo(
          precalc,
          (splits[3][1] * (1 / splits[3][2])) + y
        );
        buffer.lineTo(
          width + player_position,
          y + x
        );
        buffer.closePath();
        buffer.fill();
    }

    // Draw right wall further than split.
    buffer.fillStyle = split_state[0]
      ? '#323232'
      : '#646464';

    buffer.beginPath();
    buffer.moveTo(
      precalc,
      (splits[2][1] * (1 / splits[2][2])) + y
    );
    buffer.lineTo(
      x,
      y
    );
    buffer.lineTo(
      precalc,
      (splits[3][1] * (1 / splits[3][2])) + y
    );
    buffer.closePath();
    buffer.fill();

    // Draw current frame count.
    buffer.fillStyle = '#fff';
    buffer.fillText(
      frame_counter,
      5,
      25
    );
    buffer.fillText(
      best,
      5,
      50
    );
}

function logic(){
    frame_counter += 1;

    // Get player movement.
    var player_dx = 0;
    if(key_left){
        player_dx += x / 20;
    }
    if(key_right){
        player_dx -= x / 20;
    }

    // Update player position.
    player_position += player_dx;

    // Make sure player stays in bounds.
    if(player_position > x / 1.5){
        player_position = x / 1.5;

    }else if(player_position < -x / 1.5){
        player_position = -x / 1.5;
    }

    // Move player forward by moving splits closer.
    for(var id in splits){
        splits[id][2] -= .05;

        // If splits reach player, reset splits.
        if(splits[id][2] < 0){
            splits[id][2] = 25;
            split_state[1] = true;
        }
    }

    // If it is time to reset split.
    if(split_state[1]){
        // Reset player position to start of new section.
        player_position = 0;

        // Switch split.
        split_state[1] = false;
        split_state[0] = !split_state[0];
    }
}

function resize_logic(){
    floor_position = y * (mode - 1);
}

function setmode_logic(newgame){
    split_state = [
      false,
      false,
    ];

    // Main menu mode.
    if(mode === 0){
        document.body.innerHTML = '

Cling to the Ground'
          + '
Walled Corridor

'
          + '
Best: ' + best + '
'
          + 'Reset Best

'
          + '

<input disabled value=ESC>Main Menu
'
          + '<input id=movement-keys maxlength=2>Move ←→
'
          + '<input id=restart-key maxlength=1>Restart

'
          + '
<input id=audio-volume max=1 min=0 step=0.01 type=range>Audio
'
          + '<input id=ms-per-frame>ms/Frame
'
          + 'Reset Settings

';
        update_settings();

    // New game mode.
    }else{
        if(newgame){
            save();
        }

        splits = [
          [-50, -50, 25],
          [-50, 50, 25],
          [50, -50, 25],
          [50, 50, 25],
        ];

        frame_counter = 0;
        player_position = 0;
    }
}

var floor_position = 0;
var frame_counter = 0;
var key_left = false;
var key_right = false;
var player_position = 0;
var split_state = [];
var splits = [];

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // ESC: return to main menu.
    if(key === 27){
        update_best(frame_counter);
        setmode(
          0,
          true
        );
        return;
    }

    key = String.fromCharCode(key);

    if(key === settings['movement-keys'][0]){
        key_left = true;

    }else if(key === settings['movement-keys'][1]){
        key_right = true;

    }else if(key === settings['restart-key']){
        update_best(frame_counter);
        setmode(mode);
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings['movement-keys'][0]){
        key_left = false;

    }else if(key === settings['movement-keys'][1]){
        key_right = false;
    }
};

window.onload = function(){
    init_bests('FractalRunner-2D3D.htm-');
    init_settings(
      'FractalRunner-2D3D.htm-',
      {
        'audio-volume':  1,
        'movement-keys': 'AD',
        'ms-per-frame': 25,
        'restart-key': 'H',
      }
    );
    init_canvas();
};
<commit_msg>switched to multiple bests code<commit_after>'use strict';

function draw_logic(){
    // Draw ground grass.
    buffer.fillStyle = '#131';
    buffer.fillRect(
      0,
      floor_position,
      width,
      y
    );

    buffer.fillStyle = split_state[0]
      ? '#323232'
      : '#646464';

    // Precalculate left wall split position.
    var precalc = (splits[0][0] * (1 / splits[0][2])) + x;

    // Draw left wall extra bit.
    if(player_position > 0){
        buffer.fillRect(
          0,
          0,
          1 + (player_position >= precalc ? precalc : player_position),
          height
        );
    }

    // Draw left wall closer than split.
    if(player_position < precalc){
        buffer.beginPath();
        buffer.moveTo(
          player_position,
          y - x
        );
        buffer.lineTo(
          precalc,
          (splits[0][1] * (1 / splits[0][2])) + y
        );
        buffer.lineTo(
          precalc,
          (splits[1][1] * (1 / splits[1][2])) + y
        );
        buffer.lineTo(
          player_position,
          y + x
        );
        buffer.closePath();
        buffer.fill();
    }

    // Draw left wall further than split.
    buffer.fillStyle = split_state[0]
      ? '#646464'
      : '#323232';
    buffer.beginPath();
    buffer.moveTo(
      precalc,
      (splits[0][1] * (1 / splits[0][2])) + y
    );
    buffer.lineTo(
      x,
      y
    );
    buffer.lineTo(
      precalc,
      (splits[1][1] * (1 / splits[1][2])) + y
    );
    buffer.closePath();
    buffer.fill();

    buffer.fillStyle = split_state[0]
      ? '#646464'
      : '#323232';

    // Precalculate right wall split position.
    precalc = (splits[2][0] * (1 / splits[2][2])) + x;

    // Draw right wall extra bit.
    if(player_position < 0){
        buffer.fillRect(
          width + player_position < precalc
            ? precalc - 1
            : width + player_position - 1,
          0,
          -player_position,
          height
        );
    }

    // Draw right wall closer than split.
    if(width + player_position > precalc){
        buffer.beginPath();
        buffer.moveTo(
          width + player_position,
          y - x
        );
        buffer.lineTo(
          precalc,
          (splits[2][1] * (1 / splits[2][2])) + y
        );
        buffer.lineTo(
          precalc,
          (splits[3][1] * (1 / splits[3][2])) + y
        );
        buffer.lineTo(
          width + player_position,
          y + x
        );
        buffer.closePath();
        buffer.fill();
    }

    // Draw right wall further than split.
    buffer.fillStyle = split_state[0]
      ? '#323232'
      : '#646464';

    buffer.beginPath();
    buffer.moveTo(
      precalc,
      (splits[2][1] * (1 / splits[2][2])) + y
    );
    buffer.lineTo(
      x,
      y
    );
    buffer.lineTo(
      precalc,
      (splits[3][1] * (1 / splits[3][2])) + y
    );
    buffer.closePath();
    buffer.fill();

    // Draw current frame count.
    buffer.fillStyle = '#fff';
    buffer.fillText(
      frame_counter,
      5,
      25
    );
    buffer.fillText(
      bests_bests['score'],
      5,
      50
    );
}

function logic(){
    frame_counter += 1;

    // Get player movement.
    var player_dx = 0;
    if(key_left){
        player_dx += x / 20;
    }
    if(key_right){
        player_dx -= x / 20;
    }

    // Update player position.
    player_position += player_dx;

    // Make sure player stays in bounds.
    if(player_position > x / 1.5){
        player_position = x / 1.5;

    }else if(player_position < -x / 1.5){
        player_position = -x / 1.5;
    }

    // Move player forward by moving splits closer.
    for(var id in splits){
        splits[id][2] -= .05;

        // If splits reach player, reset splits.
        if(splits[id][2] < 0){
            splits[id][2] = 25;
            split_state[1] = true;
        }
    }

    // If it is time to reset split.
    if(split_state[1]){
        // Reset player position to start of new section.
        player_position = 0;

        // Switch split.
        split_state[1] = false;
        split_state[0] = !split_state[0];
    }
}

function resize_logic(){
    floor_position = y * (mode - 1);
}

function setmode_logic(newgame){
    split_state = [
      false,
      false,
    ];

    // Main menu mode.
    if(mode === 0){
        document.body.innerHTML = '

Cling to the Ground'
          + '
Walled Corridor

'
          + '
Best: ' + bests_bests['score'] + '
'
          + 'Reset Best

'
          + '

<input disabled value=ESC>Main Menu
'
          + '<input id=movement-keys maxlength=2>Move ←→
'
          + '<input id=restart-key maxlength=1>Restart

'
          + '
<input id=audio-volume max=1 min=0 step=0.01 type=range>Audio
'
          + '<input id=ms-per-frame>ms/Frame
'
          + 'Reset Settings

';
        update_settings();

    // New game mode.
    }else{
        if(newgame){
            save();
        }

        splits = [
          [-50, -50, 25],
          [-50, 50, 25],
          [50, -50, 25],
          [50, 50, 25],
        ];

        frame_counter = 0;
        player_position = 0;
    }
}

var floor_position = 0;
var frame_counter = 0;
var key_left = false;
var key_right = false;
var player_position = 0;
var split_state = [];
var splits = [];

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // ESC: return to main menu.
    if(key === 27){
        bests_update(
          'score',
          frame_counter
        );
        setmode(
          0,
          true
        );
        return;
    }

    key = String.fromCharCode(key);

    if(key === settings['movement-keys'][0]){
        key_left = true;

    }else if(key === settings['movement-keys'][1]){
        key_right = true;

    }else if(key === settings['restart-key']){
        bests_update(
          'score',
          frame_counter
        );
        setmode(mode);
    }
};

window.onkeyup = function(e){
    var key = String.fromCharCode(e.keyCode || e.which);

    if(key === settings['movement-keys'][0]){
        key_left = false;

    }else if(key === settings['movement-keys'][1]){
        key_right = false;
    }
};

window.onload = function(){
    bests_init(
      'FractalRunner-2D3D.htm-',
      {
        'score': 0,
      }
    );
    init_settings(
      'FractalRunner-2D3D.htm-',
      {
        'audio-volume':  1,
        'movement-keys': 'AD',
        'ms-per-frame': 25,
        'restart-key': 'H',
      }
    );
    init_canvas();
};
<|endoftext|>