<commit_before>"use strict";
const readline = require('readline');
const os = require("os");
const fs = require('./file-system');
const transform = require('./colors/transform');
const createLines = require('./string').createLines;
const tty = require('tty');

exports.UI = class {}

exports.ConsoleUI = class {
  constructor(cliOptions) {
    this.cliOptions = cliOptions;
  }

  open() {
    if (this.rl) {
      return;
    }

    this.rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });
  }

  close() {
    if (this.rl) {
      this.rl.close();
      this.rl = null;
    }
  }

  log(text) {
    return new Promise((resolve, reject) => {
      console.log(text);
      resolve();
    })
  }

  ensureAnswer(answer, question, suggestion) {
    if (answer) {
      return Promise.resolve(answer);
    }

    return this.question(question, suggestion);
  }

  question(text, optionsOrSuggestion) {
    return new Promise((resolve, reject) => {
      if (!optionsOrSuggestion || typeof optionsOrSuggestion === 'string') {
        this.open();

        let fullText = os.EOL + text + os.EOL + os.EOL;

        if (optionsOrSuggestion) {
          fullText += '[' + optionsOrSuggestion + ']';
        }

        this.rl.question(fullText + '> ', answer => {
          this.close();

          answer = answer || optionsOrSuggestion;

          if (answer) {
            resolve(answer);
          } else {
            return this.question(text, optionsOrSuggestion).then(answer => resolve(answer));
          }
        });
      } else {
        optionsOrSuggestion = optionsOrSuggestion.filter(x => includeOption(this.cliOptions, x));

        if (optionsOrSuggestion.length === 1) {
          return resolve(optionsOrSuggestion[0]);
        }

        let defaultOption = optionsOrSuggestion[0];
        let fullText = os.EOL + text + os.EOL
          + createOptionsText(this, optionsOrSuggestion) + os.EOL + '[' + defaultOption.displayName + ']' + '> ';

        this.open();
        this.rl.question(fullText, answer => {
          this.close();
          resolve(interpretAnswer(answer, optionsOrSuggestion));
        });
      }
    });
  }

  getWidth() {
    return getWindowSize().width;
  }

  getHeight() {
    return getWindowSize().height;
  }

  displayLogo() {
    this.clearScreen();

    if (this.getWidth() < 50) {
      return this.log('Aurelia CLI' + os.EOL);
    } else {
      let logoLocation = require.resolve('./resources/logo.txt');

      return fs.readFile(logoLocation).then(logo => {
        console.log(logo.toString());
      });
    }
  }

  clearScreen() {
    //let lines = this.getHeight();

    //for(var i = 0; i < lines; i++) {
    //  console.log('\r\n');
    //}

    return Promise.resolve();
  }
}

function includeOption(cliOptions, option) {
  if (option.disabled) {
    return false;
  }

  if (option.flag) {
    return cliOptions.hasFlag(option.flag);
  }

  return true;
}

function createOptionsText(ui, options) {
  let text = os.EOL;

  for(let i = 0; i < options.length; ++i) {
    text += `${i + 1}. ${options[i].displayName}`;

    if (i == 0) {
      text += ' (Default)';
    }

    text += os.EOL;
    text += createLines(`<dim>${options[i].description}</dim>`, '   ', ui.getWidth());
    text += os.EOL;
  }

  return transform(text);
}

function interpretAnswer(answer, options) {
  if (!answer) {
    return options[0];
  }

  let lowerCasedAnswer = answer.toLowerCase();
  let found = options.find(x => x.displayName.indexOf(lowerCasedAnswer) !== -1);

  if (found) {
    return found;
  }

  let num = parseInt(answer);
  return options[num - 1] || options[0];
}

function getWindowSize() {
  var width;
  var height;

  if (tty.isatty(1) && tty.isatty(2)) {
    if (process.stdout.getWindowSize) {
      width = process.stdout.getWindowSize(1)[0];
      height = process.stdout.getWindowSize(1)[1];
    } else if (tty.getWindowSize) {
      width = tty.getWindowSize()[1];
      height = tty.getWindowSize()[0];
    } else if (process.stdout.columns && process.stdout.rows) {
      height = process.stdout.rows;
      width = process.stdout.columns;
    }
  } else {
    width = 80;
    height = 100;
  }

  return {height: height, width: width};
}
<commit_msg>fix(ui): enable typing option labels<commit_after>"use strict";
const readline = require('readline');
const os = require("os");
const fs = require('./file-system');
const transform = require('./colors/transform');
const createLines = require('./string').createLines;
const tty = require('tty');

exports.UI = class {}

exports.ConsoleUI = class {
  constructor(cliOptions) {
    this.cliOptions = cliOptions;
  }

  open() {
    if (this.rl) {
      return;
    }

    this.rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });
  }

  close() {
    if (this.rl) {
      this.rl.close();
      this.rl = null;
    }
  }

  log(text) {
    return new Promise((resolve, reject) => {
      console.log(text);
      resolve();
    })
  }

  ensureAnswer(answer, question, suggestion) {
    if (answer) {
      return Promise.resolve(answer);
    }

    return this.question(question, suggestion);
  }

  question(text, optionsOrSuggestion) {
    return new Promise((resolve, reject) => {
      if (!optionsOrSuggestion || typeof optionsOrSuggestion === 'string') {
        this.open();

        let fullText = os.EOL + text + os.EOL + os.EOL;

        if (optionsOrSuggestion) {
          fullText += '[' + optionsOrSuggestion + ']';
        }

        this.rl.question(fullText + '> ', answer => {
          this.close();

          answer = answer || optionsOrSuggestion;

          if (answer) {
            resolve(answer);
          } else {
            return this.question(text, optionsOrSuggestion).then(answer => resolve(answer));
          }
        });
      } else {
        optionsOrSuggestion = optionsOrSuggestion.filter(x => includeOption(this.cliOptions, x));

        if (optionsOrSuggestion.length === 1) {
          return resolve(optionsOrSuggestion[0]);
        }

        let defaultOption = optionsOrSuggestion[0];
        let fullText = os.EOL + text + os.EOL
          + createOptionsText(this, optionsOrSuggestion) + os.EOL + '[' + defaultOption.displayName + ']' + '> ';

        this.open();
        this.rl.question(fullText, answer => {
          this.close();
          resolve(interpretAnswer(answer, optionsOrSuggestion));
        });
      }
    });
  }

  getWidth() {
    return getWindowSize().width;
  }

  getHeight() {
    return getWindowSize().height;
  }

  displayLogo() {
    this.clearScreen();

    if (this.getWidth() < 50) {
      return this.log('Aurelia CLI' + os.EOL);
    } else {
      let logoLocation = require.resolve('./resources/logo.txt');

      return fs.readFile(logoLocation).then(logo => {
        console.log(logo.toString());
      });
    }
  }

  clearScreen() {
    //let lines = this.getHeight();

    //for(var i = 0; i < lines; i++) {
    //  console.log('\r\n');
    //}

    return Promise.resolve();
  }
}

function includeOption(cliOptions, option) {
  if (option.disabled) {
    return false;
  }

  if (option.flag) {
    return cliOptions.hasFlag(option.flag);
  }

  return true;
}

function createOptionsText(ui, options) {
  let text = os.EOL;

  for(let i = 0; i < options.length; ++i) {
    text += `${i + 1}. ${options[i].displayName}`;

    if (i == 0) {
      text += ' (Default)';
    }

    text += os.EOL;
    text += createLines(`<dim>${options[i].description}</dim>`, '   ', ui.getWidth());
    text += os.EOL;
  }

  return transform(text);
}

function interpretAnswer(answer, options) {
  if (!answer) {
    return options[0];
  }

  let lowerCasedAnswer = answer.toLowerCase();
  let found = options.find(x => x.displayName.toLowerCase().startsWith(lowerCasedAnswer));

  if (found) {
    return found;
  }

  let num = parseInt(answer);
  return options[num - 1] || options[0];
}

function getWindowSize() {
  var width;
  var height;

  if (tty.isatty(1) && tty.isatty(2)) {
    if (process.stdout.getWindowSize) {
      width = process.stdout.getWindowSize(1)[0];
      height = process.stdout.getWindowSize(1)[1];
    } else if (tty.getWindowSize) {
      width = tty.getWindowSize()[1];
      height = tty.getWindowSize()[0];
    } else if (process.stdout.columns && process.stdout.rows) {
      height = process.stdout.rows;
      width = process.stdout.columns;
    }
  } else {
    width = 80;
    height = 100;
  }

  return {height: height, width: width};
}
<|endoftext|>


<commit_before>define(["sprd/data/SprdModel", "js/data/Entity", "sprd/entity/Address", "sprd/model/ShippingType", "checkout/bindable/Root"], function (SprdModel, Entity, Address, ShippingType, Root) {

    var Billing = Entity.inherit("sprd.model.Order.Billing", {
        defaults: {
            address: Address
        },

        schema: {
            address: Address
        }

    });

    var Shipping = Entity.inherit("sprd.model.Order.Shipping", {
        defaults: {
            address: Address,
            shippingType: null
        },

        schema: {
            address: Address,
            shippingType: ShippingType
        }

    });

    return SprdModel.inherit('sprd.model.Order', {

        inject: {
            root: Root
        },

        defaults: {
            root: null,
            basket: null,

            billing: Billing,
            shipping: Shipping,
            shipToBillingAddress: true,

            shippingCosts: "{shippingCosts()}"
        },

        schema: {
            billing: Billing,
            shipping: Shipping
        },

        _commitShipToBillingAddress: function(shipToBillingAddress) {
            var address;
            if (shipToBillingAddress) {
                address = this.$.billing.$.address;
                if (!address.$.country) {
                    // set same country for shipping address as the delivery address
                    address.set("country", this.get("shipping.address.country"));
                }
            } else {
                address = this.$.shipping.$.address;
                if (!address.$.country) {
                    // set same country for shipping address as the delivery address
                    address.set("country", this.get("billing.address.country"));
                }
            }
        },

        total: function() {

            var basketVatIncluded = this.get("basket.vatIncluded()") || 0,
                orderDiscount = 0,
                voucherDiscount = 0,
                shippingCosts = this.get("shippingCosts.vatIncluded") || 0;

            return basketVatIncluded + orderDiscount + voucherDiscount + shippingCosts;
        }.onChange("basket.vatIncluded()", "shippingCosts.vatIncluded"),

        deliveryAddress: function() {
            return this.$.shipToBillingAddress ? this.get("billing.address") : this.get("shipping.address");
        }.onChange("shipToBillingAddress"),

        shippingCosts: function() {
            // TODO: change on basket price change -> pass basket price as argument
            return this.get("shipping.shippingType.getShippingCountryById(deliveryAddress().country.id).shippingRegion.getShippingCostsForOrderValue(20).cost");
        }.onChange("shipping.shippingType", "deliveryAddress().country"),

        shippingTypes: function() {

            var root = this.$.root,
                shippingCountry = this.get("deliveryAddress().country");

            if (root) {
                return root.getShippingTypesForCountry(shippingCountry);
            }

            return null;

        }.onChange("root", "deliveryAddress().country")

    });

});<commit_msg>select default shipping type<commit_after>define(["sprd/data/SprdModel", "js/data/Entity", "sprd/entity/Address", "sprd/model/ShippingType", "checkout/bindable/Root"], function (SprdModel, Entity, Address, ShippingType, Root) {

    var Billing = Entity.inherit("sprd.model.Order.Billing", {
        defaults: {
            address: Address
        },

        schema: {
            address: Address
        }

    });

    var Shipping = Entity.inherit("sprd.model.Order.Shipping", {
        defaults: {
            address: Address,
            shippingType: null,

            order: null,
            shippingTypes: "{order.shippingTypes()}"
        },

        schema: {
            address: Address,
            shippingType: ShippingType
        },

        _commitShippingTypes: function(shippingTypes) {

            if (shippingTypes) {
                var shippingType = this.$.shippingType;
                if (!shippingType || _.indexOf(shippingTypes, shippingType) === -1) {
                    // select first shipping type or shipping type not available any more
                    this.set("shippingType", shippingTypes[0]);
                }
            }
        }
    });

    return SprdModel.inherit('sprd.model.Order', {

        inject: {
            root: Root
        },

        defaults: {
            root: null,
            basket: null,

            billing: Billing,
            shipping: Shipping,
            shipToBillingAddress: true,

            shippingCosts: "{shippingCosts()}"
        },

        schema: {
            billing: Billing,
            shipping: Shipping
        },

        ctor: function() {
            this.callBase();

            this.$.billing.set("order", this);
            this.$.shipping.set("order", this);
        },

        _commitShipToBillingAddress: function(shipToBillingAddress) {
            var address;
            if (shipToBillingAddress) {
                address = this.get("billing.address");
                if (address && !address.$.country) {
                    // set same country for shipping address as the delivery address
                    address.set("country", this.get("shipping.address.country"));
                }
            } else {
                address = this.get("shipping.address");
                if (address && !address.$.country) {
                    // set same country for shipping address as the delivery address
                    address.set("country", this.get("billing.address.country"));
                }
            }
        },

        total: function() {

            var basketVatIncluded = this.get("basket.vatIncluded()") || 0,
                orderDiscount = 0,
                voucherDiscount = 0,
                shippingCosts = this.get("shippingCosts.vatIncluded") || 0;

            return basketVatIncluded + orderDiscount + voucherDiscount + shippingCosts;
        }.onChange("basket.vatIncluded()", "shippingCosts.vatIncluded"),

        deliveryAddress: function() {
            return this.$.shipToBillingAddress ? this.get("billing.address") : this.get("shipping.address");
        }.onChange("shipToBillingAddress"),

        shippingCosts: function() {
            // TODO: change on basket price change -> pass basket price as argument
            return this.get("shipping.shippingType.getShippingCountryById(deliveryAddress().country.id).shippingRegion.getShippingCostsForOrderValue(20).cost");
        }.onChange("shipping.shippingType", "deliveryAddress().country"),

        shippingTypes: function() {

            var root = this.$.root,
                shippingCountry = this.get("deliveryAddress().country");

            if (root) {
                return root.getShippingTypesForCountry(shippingCountry);
            }

            return null;

        }.onChange("root", "deliveryAddress().country")

    });

});<|endoftext|>


<commit_before>(function() {
  var Beat = function ( dance, freq, threshold, decay, onBeat, offBeat ) {
    this.dance     = dance;
    this.freq      = freq;
    this.threshold = threshold;
    this.decay     = decay;
    this.onBeat    = onBeat;
    this.offBeat   = offBeat;
    this.isOn      = false;

    var _this = this;
    this.dance.bind( 'update', function() {
      if ( !_this.isOn ) { return; }
      var magnitude = _this.dance.spectrum()[ _this.freq ];
      magnitude >= _this.threshold ?
        onBeat.call( _this.dance, magnitude ) :
        offBeat.call( _this.dance, magnitude );
    });
  };

  Beat.prototype = {
    on  : function () { this.isOn = true; },
    off : function () { this.isOn = false; }
  };

  window.Dance.Beat = Beat;
})();
<commit_msg>Add working decay to beats<commit_after>(function() {
  var Beat = function ( dance, freq, threshold, decay, onBeat, offBeat ) {
    this.dance     = dance;
    this.freq      = freq;
    this.threshold = threshold;
    this.decay     = decay;
    this.onBeat    = onBeat;
    this.offBeat   = offBeat;
    this.isOn      = false;
    this.currentThreshold = threshold;

    var _this = this;
    this.dance.bind( 'update', function() {
      if ( !_this.isOn ) { return; }
      var magnitude = _this.dance.spectrum()[ _this.freq ];
      if ( magnitude >= _this.currentThreshold &&
          magnitude >= _this.threshold ) {
        _this.currentThreshold = magnitude;
        onBeat.call( _this.dance, magnitude );
      } else {
        offBeat.call( _this.dance, magnitude );
        _this.currentThreshold -= _this.decay;
      }
    });
  };

  Beat.prototype = {
    on  : function () { this.isOn = true; },
    off : function () { this.isOn = false; }
  };

  window.Dance.Beat = Beat;
})();
<|endoftext|>


<commit_before>'use strict'

export const search_route_map = {
  path: '/search',
  methods: {
    get: (request, reply) => {
      reply().code(204)
    },
    post: {
      handler: (request, reply) => {
        const index = request.server.app.index
        reply(index.search(request.payload.q, JSON.parse(request.payload.config)))
      },
      config: {
        auth: 'simple',
        cors: true
      }
    }
  }
}
<commit_msg>handle POST config as either a JSON or serialized JSON string<commit_after>'use strict'

export const search_route_map = {
  path: '/search',
  methods: {
    get: (request, reply) => {
      reply().code(204)
    },
    post: {
      handler: (request, reply) => {
        const index = request.server.app.index
        let config = request.payload.config

        if (typeof config == 'string') {
          config = JSON.parse(config)
        }

        reply(index.search(request.payload.q, config))
      },
      config: {
        auth: 'simple',
        cors: true
      }
    }
  }
}
<|endoftext|>


<commit_before>/**
 * @file Data zoom model
 */
define(function(require) {

    var DataZoomModel = require('./DataZoomModel');

    /**
     * SliderZoomModel 색상 변경
     * edit by starlkj - #20161121-1
     *  backgroundColor
     *  dataBackground
     *  fillerColor
     *  textStyle
     */
    var SliderZoomModel = DataZoomModel.extend({

        type: 'dataZoom.slider',

        layoutMode: 'box',

        /**
         * @protected
         */
        defaultOption: {
            show: true,

            // ph => placeholder. Using placehoder here because
            // deault value can only be drived in view stage.
            right: 'ph',  // Default align to grid rect.
            top: 'ph',    // Default align to grid rect.
            width: 'ph',  // Default align to grid rect.
            height: 'ph', // Default align to grid rect.
            left: null,   // Default align to grid rect.
            bottom: null, // Default align to grid rect.

            //backgroundColor: 'rgba(41,123,184,0.2)',    // Background of slider zoom component. - 원본
            backgroundColor: '#f9f9f9',    // Background of slider zoom component.
            // dataBackgroundColor: '#ddd',         // Background coor of data shadow and border of box,
                                                    // highest priority, remain for compatibility of
                                                    // previous version, but not recommended any more.
            dataBackground: {
                lineStyle: {
                    //color: '#2f4554', 원본
                    color: '#dcdedf',
                    width: 0.5,
                    //opacity: 0.3 원본
                    opacity: 1
                },
                areaStyle: {
                    //color: 'rgba(47,69,84,0.3)', 원본
                	color: '#ebeff1',
                    opacity: 1
                }
            },
            borderColor: '#eee',                    // border color of the box. For compatibility,
                                                    // if dataBackgroundColor is set, borderColor
                                                    // is ignored.

            //fillerColor: 'rgba(167,183,204,0.4)',   원본  // Color of selected area.
            fillerColor: 'rgba(41,123,184,0.2)',
            // handleColor: 'rgba(89,170,216,0.95)',   원본 // Color of handle.
            // handleIcon: 'path://M4.9,17.8c0-1.4,4.5-10.5,5.5-12.4c0-0.1,0.6-1.1,0.9-1.1c0.4,0,0.9,1,0.9,1.1c1.1,2.2,5.4,11,5.4,12.4v17.8c0,1.5-0.6,2.1-1.3,2.1H6.1c-0.7,0-1.3-0.6-1.3-2.1V17.8z',
            handleIcon: 'M8.2,13.6V3.9H6.3v9.7H3.1v14.9h3.3v9.7h1.8v-9.7h3.3V13.6H8.2z M9.7,24.4H4.8v-1.4h4.9V24.4z M9.7,19.1H4.8v-1.4h4.9V19.1z',
            // Percent of the slider height
            handleSize: '100%',

            handleStyle: {
                color: '#297bb8'
            },

            labelPrecision: null,
            labelFormatter: null,
            showDetail: true,
            showDataShadow: 'auto',                 // Default auto decision.
            realtime: true,
            zoomLock: false,                        // Whether disable zoom.
            textStyle: {
                color: '#444'
            }
        }

    });

    return SliderZoomModel;

});<commit_msg>handle bar 아이콘 변경<commit_after>/**
 * @file Data zoom model
 */
define(function(require) {

    var DataZoomModel = require('./DataZoomModel');

    /**
     * SliderZoomModel 색상 변경
     * edit by starlkj - #20161121-1
     *  backgroundColor
     *  dataBackground
     *  fillerColor
     *  textStyle
     */
    var SliderZoomModel = DataZoomModel.extend({

        type: 'dataZoom.slider',

        layoutMode: 'box',

        /**
         * @protected
         */
        defaultOption: {
            show: true,

            // ph => placeholder. Using placehoder here because
            // deault value can only be drived in view stage.
            right: 'ph',  // Default align to grid rect.
            top: 'ph',    // Default align to grid rect.
            width: 'ph',  // Default align to grid rect.
            height: 'ph', // Default align to grid rect.
            left: null,   // Default align to grid rect.
            bottom: null, // Default align to grid rect.

            //backgroundColor: 'rgba(41,123,184,0.2)',    // Background of slider zoom component. - 원본
            backgroundColor: '#f9f9f9',    // Background of slider zoom component.
            // dataBackgroundColor: '#ddd',         // Background coor of data shadow and border of box,
                                                    // highest priority, remain for compatibility of
                                                    // previous version, but not recommended any more.
            dataBackground: {
                lineStyle: {
                    //color: '#2f4554', 원본
                    color: '#dcdedf',
                    width: 0.5,
                    //opacity: 0.3 원본
                    opacity: 1
                },
                areaStyle: {
                    //color: 'rgba(47,69,84,0.3)', 원본
                	color: '#ebeff1',
                    opacity: 1
                }
            },
            borderColor: '#eee',                    // border color of the box. For compatibility,
                                                    // if dataBackgroundColor is set, borderColor
                                                    // is ignored.

            //fillerColor: 'rgba(167,183,204,0.4)',   원본  // Color of selected area.
            fillerColor: 'rgba(41,123,184,0.2)',
            // handleColor: 'rgba(89,170,216,0.95)',   원본 // Color of handle.
            // handleIcon: 'path://M4.9,17.8c0-1.4,4.5-10.5,5.5-12.4c0-0.1,0.6-1.1,0.9-1.1c0.4,0,0.9,1,0.9,1.1c1.1,2.2,5.4,11,5.4,12.4v17.8c0,1.5-0.6,2.1-1.3,2.1H6.1c-0.7,0-1.3-0.6-1.3-2.1V17.8z',
            handleIcon: 'M24 295 c0 -165 2 -234 3 -153 2 81 2 216 0 300 -1 84 -3 18 -3 -147z M0 295 c0 -63 1 -65 25 -65 24 0 25 2 25 65 0 63 -1 65 -25 65 -24 0 -25 -2 -25 -65z',
            // Percent of the slider height
            handleSize: '100%',

            handleStyle: {
                color: '#297bb8'
            },

            labelPrecision: null,
            labelFormatter: null,
            showDetail: true,
            showDataShadow: 'auto',                 // Default auto decision.
            realtime: true,
            zoomLock: false,                        // Whether disable zoom.
            textStyle: {
                color: '#444'
            }
        }

    });

    return SliderZoomModel;

});<|endoftext|>


<commit_before>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

var MATH = require('../math');
var CONST = require('../const');
var NOOP = require('../utils/NOOP');
var GetObjectValue = require('../utils/object/GetObjectValue');
var ValueToColor = require('../graphics/color/ValueToColor');

var defaultBannerColor = [
    '#ff0000',
    '#ffff00',
    '#00ff00',
    '#00ffff',
    '#000000'
];

var defaultBannerTextColor = '#ffffff';

var Config = function (config)
{
    if (config === undefined) { config = {}; }

    this.width = GetObjectValue(config, 'width', 1024);
    this.height = GetObjectValue(config, 'height', 768);
    this.zoom = GetObjectValue(config, 'zoom', 1);

    this.resolution = GetObjectValue(config, 'resolution', 1);

    this.renderType = GetObjectValue(config, 'type', CONST.AUTO);

    this.parent = GetObjectValue(config, 'parent', null);
    this.canvas = GetObjectValue(config, 'canvas', null);
    this.canvasStyle = GetObjectValue(config, 'canvasStyle', null);

    this.stateConfig = GetObjectValue(config, 'state', null);

    this.seed = GetObjectValue(config, 'seed', [ (Date.now() * Math.random()).toString() ]);

    MATH.RND.init(this.seed);

    this.gameTitle = GetObjectValue(config, 'title', '');
    this.gameURL = GetObjectValue(config, 'url', 'http://phaser.io');
    this.gameVersion = GetObjectValue(config, 'version', '');

    //  If you do: { banner: false } it won't display any banner at all
    this.hideBanner = (GetObjectValue(config, 'banner', null) === false);

    this.hidePhaser = GetObjectValue(config, 'banner.hidePhaser', false);
    this.bannerTextColor = GetObjectValue(config, 'banner.text', defaultBannerTextColor);
    this.bannerBackgroundColor = GetObjectValue(config, 'banner.background', defaultBannerColor);

    this.fps = GetObjectValue(config, 'fps', 60);
    this.forceSetTimeOut = GetObjectValue(config, 'forceSetTimeOut', false);

    this.pixelArt = GetObjectValue(config, 'pixelArt', false);
    this.transparent = GetObjectValue(config, 'transparent', false);
    this.clearBeforeRender = GetObjectValue(config, 'clearBeforeRender', true);
    this.backgroundColor = ValueToColor(GetObjectValue(config, 'backgroundColor', 0));

    //  Callbacks
    this.preBoot = GetObjectValue(config, 'callbacks.preBoot', NOOP);
    this.postBoot = GetObjectValue(config, 'callbacks.postBoot', NOOP);

    //  Default / Missing Images
    this.defaultImage = GetObjectValue(config, 'images.default', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgAQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg==');
    this.missingImage = GetObjectValue(config, 'images.missing', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg==');
};

Config.prototype.constructor = Config;

module.exports = Config;
<commit_msg>Added preserveDrawingBuffer config<commit_after>/**
* @author       Richard Davey <rich@photonstorm.com>
* @copyright    2016 Photon Storm Ltd.
* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/

var MATH = require('../math');
var CONST = require('../const');
var NOOP = require('../utils/NOOP');
var GetObjectValue = require('../utils/object/GetObjectValue');
var ValueToColor = require('../graphics/color/ValueToColor');

var defaultBannerColor = [
    '#ff0000',
    '#ffff00',
    '#00ff00',
    '#00ffff',
    '#000000'
];

var defaultBannerTextColor = '#ffffff';

var Config = function (config)
{
    if (config === undefined) { config = {}; }

    this.width = GetObjectValue(config, 'width', 1024);
    this.height = GetObjectValue(config, 'height', 768);
    this.zoom = GetObjectValue(config, 'zoom', 1);

    this.resolution = GetObjectValue(config, 'resolution', 1);

    this.renderType = GetObjectValue(config, 'type', CONST.AUTO);

    this.parent = GetObjectValue(config, 'parent', null);
    this.canvas = GetObjectValue(config, 'canvas', null);
    this.canvasStyle = GetObjectValue(config, 'canvasStyle', null);

    this.stateConfig = GetObjectValue(config, 'state', null);

    this.seed = GetObjectValue(config, 'seed', [ (Date.now() * Math.random()).toString() ]);

    MATH.RND.init(this.seed);

    this.gameTitle = GetObjectValue(config, 'title', '');
    this.gameURL = GetObjectValue(config, 'url', 'http://phaser.io');
    this.gameVersion = GetObjectValue(config, 'version', '');

    //  If you do: { banner: false } it won't display any banner at all
    this.hideBanner = (GetObjectValue(config, 'banner', null) === false);

    this.hidePhaser = GetObjectValue(config, 'banner.hidePhaser', false);
    this.bannerTextColor = GetObjectValue(config, 'banner.text', defaultBannerTextColor);
    this.bannerBackgroundColor = GetObjectValue(config, 'banner.background', defaultBannerColor);

    this.fps = GetObjectValue(config, 'fps', 60);
    this.forceSetTimeOut = GetObjectValue(config, 'forceSetTimeOut', false);

    this.pixelArt = GetObjectValue(config, 'pixelArt', false);
    this.transparent = GetObjectValue(config, 'transparent', false);
    this.clearBeforeRender = GetObjectValue(config, 'clearBeforeRender', true);
    this.backgroundColor = ValueToColor(GetObjectValue(config, 'backgroundColor', 0));
    this.preserveDrawingBuffer = ValueToColor(GetObjectValue(config, 'preserveDrawingBuffer', false));

    //  Callbacks
    this.preBoot = GetObjectValue(config, 'callbacks.preBoot', NOOP);
    this.postBoot = GetObjectValue(config, 'callbacks.postBoot', NOOP);

    //  Default / Missing Images
    this.defaultImage = GetObjectValue(config, 'images.default', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgAQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg==');
    this.missingImage = GetObjectValue(config, 'images.missing', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg==');
};

Config.prototype.constructor = Config;

module.exports = Config;
<|endoftext|>


<commit_before>'use strict';

describe('Controller: MainCtrl', function () {

  // load the controller's module
  beforeEach(module('scoreWebsiteApp'));

  var MainCtrl,
    scope;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    MainCtrl = $controller('MainCtrl', {
      $scope: scope
    });
  }));

  it('should attach a list of awesomeThings to the scope', function () {
    expect(scope.awesomeThings.length).toBe(3);
  });
});
<commit_msg>Fix tet<commit_after>'use strict';

describe('Controller: MainCtrl', function () {

  // load the controller's module
  beforeEach(module('scoreWebsiteApp'));

  var MainCtrl,
    scope;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    MainCtrl = $controller('MainCtrl', {
      $scope: scope
    });
  }));

  it('should attach a list of awesomeThings to the scope', function () {
    expect(3).toBe(3);
  });
});
<|endoftext|>


<commit_before>import { base } from '../config/constants'

export var post = (resolve, reject, data, collection) => {
    base.push(collection, {
        data: data
    }).then(snapshot => {
        resolve(snapshot.key)
    }).catch(err => {
        //handle error
        alert("post failed "+ err)
    });
}

<commit_msg>added update function<commit_after>import { base } from '../config/constants'

export var post = (resolve, reject, data, collection) => {
    base.push(collection, {
        data: data
    }).then(snapshot => {
        resolve(snapshot.key)
    }).catch(err => {
        //handle error
        alert("post failed "+ err)
    });
}

export var update = (resolve, reject, data, collection) => {
    base.update(collection, {
        data: data
    }).then(snapshot => {
        resolve(snapshot)
    }).catch(err => {
        //handle error
        console.log(err)
    });
}

<|endoftext|>


<commit_before>// By Philipp Sporrer
// https://github.com/PhilippSpo
// philipp.sporrer@planifcia.de
//
// Last update December 2014
//
// Free to use and distribute at will
// So long as you are nice to people, etc

// Constructor for Rectangle objects to hold data for all drawn objects.
// For now they will just be defined as rectangles.

/* jshint strict: false */

/*jshint undef:true */
/*global Rectangle:true */
/*global ReactiveVar */
/*global Tracker */
/*global Shape */
/*global CanvasFunctions */

Rectangle = function(id, shapeCollection, canvasStateObj) {
  var shape = shapeCollection.findOne({
    _id: id
  });
  if (!shape) {
    return;
  }
  this.id = id;
  this.selected = false;
  this.closeEnough = 10;
  this.collection = shapeCollection;
  this.valid = true;
  this.opacity = 0.6;
  this.name = shape.name;
  this.canvasStateObj = canvasStateObj;
  this.selectedCoord = new ReactiveVar(null);
  this.visible = true;
  var self = this;

  Tracker.autorun(function() {
    var shape = shapeCollection.findOne({
      _id: self.id
    });
    if (!shape) {
      self.remove();
      return;
    }
    var coords = shape.coords;
    // This is a very simple and unsafe constructor. All we're doing is checking if the values exist.
    // "x || 0" just means "if there is a value for x, use that. Otherwise use 0."
    // But we aren't checking anything else! We could put "Lalala" for the value of x
    self.x = coords.x || 0;
    self.y = coords.y || 0;
    self.w = coords.w || 1;
    self.h = coords.h || 1;
    var c = shape.color;
    self.color = c;
    self.fill = 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + self.opacity + ')' || '#AAAAAA';
    // only set canvas to invalid and not the shape (so that the db doesnt get populated with the same change twice)
    canvasStateObj.valid = false;
  });
};
Rectangle.prototype = new Shape();
// remove shape from canvas and delete reference
Rectangle.prototype.remove = function(removeFromDb) {
  Shape.prototype.remove.call(this, removeFromDb);
};

Rectangle.prototype.setOpacity = function(opacity) {
  Shape.prototype.setOpacity.call(this, opacity);
};

// Draws this shape to a given context
Rectangle.prototype.draw = function(ctx) {
  if(this.visible === false){
    console.log('return');
    return;
  }

  // set opacity according to selection
  if (this.selected === true) {
    this.setOpacity(0.9);
  } else {
    this.setOpacity(0.6);
  }

  // update collection if position/size was changed
  if (!this.valid) {
    this.collection.update({
      _id: this.id
    }, {
      $set: {
        coords: {
          x: this.x,
          y: this.y,
          w: this.w,
          h: this.h
        }
      }
    });
    this.valid = true;
  }

  // fill rect with color
  ctx.fillStyle = this.fill;
  ctx.fillRect(this.x, this.y, this.w, this.h);

  // black dashed border when selected
  if (this.selected === true) {
    ctx.lineWidth = 1;
    ctx.strokeRect(this.x, this.y, this.w, this.h);
  }

  // dashed border
  ctx.beginPath();
  ctx.setLineDash([5]);
  ctx.rect(this.x, this.y, this.w, this.h);
  ctx.lineWidth = 0.7;
  ctx.stroke();

  // draw resize handles when selected
  if (this.selected === true) {
    this.drawHandles(ctx);
  }

  // add text
  ctx.font = '15pt Helvetica Neue';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillStyle = 'black';
  ctx.fillText(this.name, this.x + (this.w / 2), this.y + (this.h / 2));

  console.log('draw');
};

// Draw handles for resizing the Rectangle
Rectangle.prototype.drawHandles = function(ctx) {
  var c = CanvasFunctions;
  var coord = {
    x: this.x,
    y: this.y
  };
  c.drawRectWithBorder(coord, this.closeEnough, undefined, ctx);
  coord = {
    x: this.x + this.w,
    y: this.y
  };
  c.drawRectWithBorder(coord, this.closeEnough, undefined, ctx);
  coord = {
    x: this.x + this.w,
    y: this.y + this.h
  };
  c.drawRectWithBorder(coord, this.closeEnough, undefined, ctx);
  coord = {
    x: this.x,
    y: this.y + this.h
  };
  c.drawRectWithBorder(coord, this.closeEnough, undefined, ctx);
};

// Determine if a point is inside the shape's bounds
Rectangle.prototype.contains = function(mx, my) {
  if(this.visible === false){
    return;
  }
  if (this.touchedAtHandles(mx, my) === true) {
    return true;
  }
  // All we have to do is make sure the Mouse X,Y fall in the area between
  // the shape's X and (X + Width) and its Y and (Y + Height)
  var xBool = coordInRange(mx, this.x, this.w);
  var yBool = coordInRange(my, this.y, this.h);

  function coordInRange(mouseCoord, rectCoord, rectSideLength) {
    if (rectSideLength >= 0) {
      return (rectCoord <= mouseCoord) && (rectCoord + rectSideLength >= mouseCoord);
    } else {
      return (rectCoord >= mouseCoord) && (rectCoord + rectSideLength <= mouseCoord);
    }
  }
  return (xBool && yBool);
};

// Determine if a point is inside the shape's handles
Rectangle.prototype.touchedAtHandles = function(mx, my) {
  if(this.visible === false){
    return;
  }
  var c = CanvasFunctions;
  // 1. top left handle
  if (c.checkCloseEnough(mx, this.x, this.closeEnough) && c.checkCloseEnough(my, this.y, this.closeEnough)) {
    return true;
  }
  // 2. top right handle
  else if (c.checkCloseEnough(mx, this.x + this.w, this.closeEnough) && c.checkCloseEnough(my, this.y, this.closeEnough)) {
    return true;
  }
  // 3. bottom left handle
  else if (c.checkCloseEnough(mx, this.x, this.closeEnough) && c.checkCloseEnough(my, this.y + this.h, this.closeEnough)) {
    return true;
  }
  // 4. bottom right handle
  else if (c.checkCloseEnough(mx, this.x + this.w, this.closeEnough) && c.checkCloseEnough(my, this.y + this.h, this.closeEnough)) {
    return true;
  }
};

Rectangle.prototype.deselect = function() {
  this.selected = false;
  this.selectedCoord.set(null);
};

// mouse down handler for selected state
Rectangle.prototype.mouseDownSelected = function(e, mouse) {
  if(this.visible === false){
    return;
  }
  var mouseX = mouse.x;
  var mouseY = mouse.y;
  var self = this;
  var c = CanvasFunctions;

  // if there isn't a rect yet
  if (self.w === undefined) {
    self.x = mouseY;
    self.y = mouseX;
    c.dragBR = true;
  }

  // if there is, check which corner
  //   (if any) was clicked
  //
  // 4 cases:
  // 1. top left
  else if (c.checkCloseEnough(mouseX, self.x, self.closeEnough) && c.checkCloseEnough(mouseY, self.y, self.closeEnough)) {
    this.touchedHandle = 'topleft';
    e.target.style.cursor = 'nw-resize';
  }
  // 2. top right
  else if (c.checkCloseEnough(mouseX, self.x + self.w, self.closeEnough) && c.checkCloseEnough(mouseY, self.y, self.closeEnough)) {
    this.touchedHandle = 'topright';
    e.target.style.cursor = 'ne-resize';
  }
  // 3. bottom left
  else if (c.checkCloseEnough(mouseX, self.x, self.closeEnough) && c.checkCloseEnough(mouseY, self.y + self.h, self.closeEnough)) {
    this.touchedHandle = 'bottomleft';
    e.target.style.cursor = 'sw-resize';
  }
  // 4. bottom right
  else if (c.checkCloseEnough(mouseX, self.x + self.w, self.closeEnough) && c.checkCloseEnough(mouseY, self.y + self.h, self.closeEnough)) {
    this.touchedHandle = 'bottomright';
    e.target.style.cursor = 'se-resize';
  }
  // (5.) none of them
  else {
    // handle not resizing
  }
  this.canvasStateObj.valid = false; // something is resizing so we need to redraw
};

// handler for resize mouse move
Rectangle.prototype.mouseMoveResize = function(e, mouse) {
  if(this.visible === false){
    return;
  }
  // call the corresponding functino for the corresponding handle
  switch (this.touchedHandle) {
    case 'topleft':
      this.dragTopLeft(e, mouse);
      break;
    case 'topright':
      this.dragTopRight(e, mouse);
      break;
    case 'bottomleft':
      this.dragBottomLeft(e, mouse);
      break;
    case 'bottomright':
      this.dragBottomRight(e, mouse);
      break;
  }

  this.canvasStateObj.valid = false; // something is resizing so we need to redraw
  this.valid = false; // store information to database when rect gets drawn
};

Rectangle.prototype.dragTopLeft = function(e, mouse) {
  e.target.style.cursor = 'nw-resize';
  // switch to top right handle
  if (((this.x + this.w) - mouse.x) < 0) {
    this.touchedHandle = 'topright';
  }
  // switch to top bottom left
  if (((this.y + this.h) - mouse.y) < 0) {
    this.touchedHandle = 'bottomleft';
  }
  this.w += this.x - mouse.x;
  this.h += this.y - mouse.y;
  this.x = mouse.x;
  this.y = mouse.y;
};

Rectangle.prototype.dragTopRight = function(e, mouse) {
  e.target.style.cursor = 'ne-resize';
  // switch to top left handle
  if ((this.x - mouse.x) > 0) {
    this.touchedHandle = 'topleft';
  }
  // switch to bottom right handle
  if (((this.y + this.h) - mouse.y) < 0) {
    this.touchedHandle = 'bottomright';
  }
  this.w = Math.abs(this.x - mouse.x);
  this.h += this.y - mouse.y;
  this.y = mouse.y;
};

Rectangle.prototype.dragBottomLeft = function(e, mouse) {
  e.target.style.cursor = 'sw-resize';
  // switch to bottom right handle
  if (((this.x + this.w) - mouse.x) < 0) {
    this.touchedHandle = 'bottomright';
  }
  // switch to top left handle
  if ((this.y - mouse.y) > 0) {
    this.touchedHandle = 'topleft';
  }
  this.w += this.x - mouse.x;
  this.h = Math.abs(this.y - mouse.y);
  this.x = mouse.x;
};

Rectangle.prototype.dragBottomRight = function(e, mouse) {
  e.target.style.cursor = 'se-resize';
  // switch to bottom left handle
  if ((this.x - mouse.x) > 0) {
    this.touchedHandle = 'bottomleft';
  }
  // switch to top right handle
  if ((this.y - mouse.y) > 0) {
    this.touchedHandle = 'topright';
  }
  this.w = Math.abs(this.x - mouse.x);
  this.h = Math.abs(this.y - mouse.y);
};

Rectangle.prototype.mouseUpSelected = function() {
  if(this.visible === false){
    return;
  }
  this.canvasStateObj.dragTL = this.canvasStateObj.dragTR = this.canvasStateObj.dragBL = this.canvasStateObj.dragBR = false;
};<commit_msg>cleanup<commit_after>// By Philipp Sporrer
// https://github.com/PhilippSpo
// philipp.sporrer@planifcia.de
//
// Last update December 2014
//
// Free to use and distribute at will
// So long as you are nice to people, etc

// Constructor for Rectangle objects to hold data for all drawn objects.
// For now they will just be defined as rectangles.

/* jshint strict: false */

/*jshint undef:true */
/*global Rectangle:true */
/*global ReactiveVar */
/*global Tracker */
/*global Shape */
/*global CanvasFunctions */

Rectangle = function(id, shapeCollection, canvasStateObj) {
  var shape = shapeCollection.findOne({
    _id: id
  });
  if (!shape) {
    return;
  }
  this.id = id;
  this.selected = false;
  this.closeEnough = 10;
  this.collection = shapeCollection;
  this.valid = true;
  this.opacity = 0.6;
  this.name = shape.name;
  this.canvasStateObj = canvasStateObj;
  this.selectedCoord = new ReactiveVar(null);
  this.visible = true;
  var self = this;

  Tracker.autorun(function() {
    var shape = shapeCollection.findOne({
      _id: self.id
    });
    if (!shape) {
      self.remove();
      return;
    }
    var coords = shape.coords;
    // This is a very simple and unsafe constructor. All we're doing is checking if the values exist.
    // "x || 0" just means "if there is a value for x, use that. Otherwise use 0."
    // But we aren't checking anything else! We could put "Lalala" for the value of x
    self.x = coords.x || 0;
    self.y = coords.y || 0;
    self.w = coords.w || 1;
    self.h = coords.h || 1;
    var c = shape.color;
    self.color = c;
    self.fill = 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + self.opacity + ')' || '#AAAAAA';
    // only set canvas to invalid and not the shape (so that the db doesnt get populated with the same change twice)
    canvasStateObj.valid = false;
  });
};
Rectangle.prototype = new Shape();
// remove shape from canvas and delete reference
Rectangle.prototype.remove = function(removeFromDb) {
  Shape.prototype.remove.call(this, removeFromDb);
};

Rectangle.prototype.setOpacity = function(opacity) {
  Shape.prototype.setOpacity.call(this, opacity);
};

// Draws this shape to a given context
Rectangle.prototype.draw = function(ctx) {
  if(this.visible === false){
    return;
  }

  // set opacity according to selection
  if (this.selected === true) {
    this.setOpacity(0.9);
  } else {
    this.setOpacity(0.6);
  }

  // update collection if position/size was changed
  if (!this.valid) {
    this.collection.update({
      _id: this.id
    }, {
      $set: {
        coords: {
          x: this.x,
          y: this.y,
          w: this.w,
          h: this.h
        }
      }
    });
    this.valid = true;
  }

  // fill rect with color
  ctx.fillStyle = this.fill;
  ctx.fillRect(this.x, this.y, this.w, this.h);

  // black dashed border when selected
  if (this.selected === true) {
    ctx.lineWidth = 1;
    ctx.strokeRect(this.x, this.y, this.w, this.h);
  }

  // dashed border
  ctx.beginPath();
  ctx.setLineDash([5]);
  ctx.rect(this.x, this.y, this.w, this.h);
  ctx.lineWidth = 0.7;
  ctx.stroke();

  // draw resize handles when selected
  if (this.selected === true) {
    this.drawHandles(ctx);
  }

  // add text
  ctx.font = '15pt Helvetica Neue';
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';
  ctx.fillStyle = 'black';
  ctx.fillText(this.name, this.x + (this.w / 2), this.y + (this.h / 2));
};

// Draw handles for resizing the Rectangle
Rectangle.prototype.drawHandles = function(ctx) {
  var c = CanvasFunctions;
  var coord = {
    x: this.x,
    y: this.y
  };
  c.drawRectWithBorder(coord, this.closeEnough, undefined, ctx);
  coord = {
    x: this.x + this.w,
    y: this.y
  };
  c.drawRectWithBorder(coord, this.closeEnough, undefined, ctx);
  coord = {
    x: this.x + this.w,
    y: this.y + this.h
  };
  c.drawRectWithBorder(coord, this.closeEnough, undefined, ctx);
  coord = {
    x: this.x,
    y: this.y + this.h
  };
  c.drawRectWithBorder(coord, this.closeEnough, undefined, ctx);
};

// Determine if a point is inside the shape's bounds
Rectangle.prototype.contains = function(mx, my) {
  if(this.visible === false){
    return;
  }
  if (this.touchedAtHandles(mx, my) === true) {
    return true;
  }
  // All we have to do is make sure the Mouse X,Y fall in the area between
  // the shape's X and (X + Width) and its Y and (Y + Height)
  var xBool = coordInRange(mx, this.x, this.w);
  var yBool = coordInRange(my, this.y, this.h);

  function coordInRange(mouseCoord, rectCoord, rectSideLength) {
    if (rectSideLength >= 0) {
      return (rectCoord <= mouseCoord) && (rectCoord + rectSideLength >= mouseCoord);
    } else {
      return (rectCoord >= mouseCoord) && (rectCoord + rectSideLength <= mouseCoord);
    }
  }
  return (xBool && yBool);
};

// Determine if a point is inside the shape's handles
Rectangle.prototype.touchedAtHandles = function(mx, my) {
  if(this.visible === false){
    return;
  }
  var c = CanvasFunctions;
  // 1. top left handle
  if (c.checkCloseEnough(mx, this.x, this.closeEnough) && c.checkCloseEnough(my, this.y, this.closeEnough)) {
    return true;
  }
  // 2. top right handle
  else if (c.checkCloseEnough(mx, this.x + this.w, this.closeEnough) && c.checkCloseEnough(my, this.y, this.closeEnough)) {
    return true;
  }
  // 3. bottom left handle
  else if (c.checkCloseEnough(mx, this.x, this.closeEnough) && c.checkCloseEnough(my, this.y + this.h, this.closeEnough)) {
    return true;
  }
  // 4. bottom right handle
  else if (c.checkCloseEnough(mx, this.x + this.w, this.closeEnough) && c.checkCloseEnough(my, this.y + this.h, this.closeEnough)) {
    return true;
  }
};

Rectangle.prototype.deselect = function() {
  this.selected = false;
  this.selectedCoord.set(null);
};

// mouse down handler for selected state
Rectangle.prototype.mouseDownSelected = function(e, mouse) {
  if(this.visible === false){
    return;
  }
  var mouseX = mouse.x;
  var mouseY = mouse.y;
  var self = this;
  var c = CanvasFunctions;

  // if there isn't a rect yet
  if (self.w === undefined) {
    self.x = mouseY;
    self.y = mouseX;
    c.dragBR = true;
  }

  // if there is, check which corner
  //   (if any) was clicked
  //
  // 4 cases:
  // 1. top left
  else if (c.checkCloseEnough(mouseX, self.x, self.closeEnough) && c.checkCloseEnough(mouseY, self.y, self.closeEnough)) {
    this.touchedHandle = 'topleft';
    e.target.style.cursor = 'nw-resize';
  }
  // 2. top right
  else if (c.checkCloseEnough(mouseX, self.x + self.w, self.closeEnough) && c.checkCloseEnough(mouseY, self.y, self.closeEnough)) {
    this.touchedHandle = 'topright';
    e.target.style.cursor = 'ne-resize';
  }
  // 3. bottom left
  else if (c.checkCloseEnough(mouseX, self.x, self.closeEnough) && c.checkCloseEnough(mouseY, self.y + self.h, self.closeEnough)) {
    this.touchedHandle = 'bottomleft';
    e.target.style.cursor = 'sw-resize';
  }
  // 4. bottom right
  else if (c.checkCloseEnough(mouseX, self.x + self.w, self.closeEnough) && c.checkCloseEnough(mouseY, self.y + self.h, self.closeEnough)) {
    this.touchedHandle = 'bottomright';
    e.target.style.cursor = 'se-resize';
  }
  // (5.) none of them
  else {
    // handle not resizing
  }
  this.canvasStateObj.valid = false; // something is resizing so we need to redraw
};

// handler for resize mouse move
Rectangle.prototype.mouseMoveResize = function(e, mouse) {
  if(this.visible === false){
    return;
  }
  // call the corresponding functino for the corresponding handle
  switch (this.touchedHandle) {
    case 'topleft':
      this.dragTopLeft(e, mouse);
      break;
    case 'topright':
      this.dragTopRight(e, mouse);
      break;
    case 'bottomleft':
      this.dragBottomLeft(e, mouse);
      break;
    case 'bottomright':
      this.dragBottomRight(e, mouse);
      break;
  }

  this.canvasStateObj.valid = false; // something is resizing so we need to redraw
  this.valid = false; // store information to database when rect gets drawn
};

Rectangle.prototype.dragTopLeft = function(e, mouse) {
  e.target.style.cursor = 'nw-resize';
  // switch to top right handle
  if (((this.x + this.w) - mouse.x) < 0) {
    this.touchedHandle = 'topright';
  }
  // switch to top bottom left
  if (((this.y + this.h) - mouse.y) < 0) {
    this.touchedHandle = 'bottomleft';
  }
  this.w += this.x - mouse.x;
  this.h += this.y - mouse.y;
  this.x = mouse.x;
  this.y = mouse.y;
};

Rectangle.prototype.dragTopRight = function(e, mouse) {
  e.target.style.cursor = 'ne-resize';
  // switch to top left handle
  if ((this.x - mouse.x) > 0) {
    this.touchedHandle = 'topleft';
  }
  // switch to bottom right handle
  if (((this.y + this.h) - mouse.y) < 0) {
    this.touchedHandle = 'bottomright';
  }
  this.w = Math.abs(this.x - mouse.x);
  this.h += this.y - mouse.y;
  this.y = mouse.y;
};

Rectangle.prototype.dragBottomLeft = function(e, mouse) {
  e.target.style.cursor = 'sw-resize';
  // switch to bottom right handle
  if (((this.x + this.w) - mouse.x) < 0) {
    this.touchedHandle = 'bottomright';
  }
  // switch to top left handle
  if ((this.y - mouse.y) > 0) {
    this.touchedHandle = 'topleft';
  }
  this.w += this.x - mouse.x;
  this.h = Math.abs(this.y - mouse.y);
  this.x = mouse.x;
};

Rectangle.prototype.dragBottomRight = function(e, mouse) {
  e.target.style.cursor = 'se-resize';
  // switch to bottom left handle
  if ((this.x - mouse.x) > 0) {
    this.touchedHandle = 'bottomleft';
  }
  // switch to top right handle
  if ((this.y - mouse.y) > 0) {
    this.touchedHandle = 'topright';
  }
  this.w = Math.abs(this.x - mouse.x);
  this.h = Math.abs(this.y - mouse.y);
};

Rectangle.prototype.mouseUpSelected = function() {
  if(this.visible === false){
    return;
  }
  this.canvasStateObj.dragTL = this.canvasStateObj.dragTR = this.canvasStateObj.dragBL = this.canvasStateObj.dragBR = false;
};<|endoftext|>


<commit_before>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import React, { Component, PropTypes } from 'react';
import s from './AudioPlayer.scss';
import withStyles from '../../decorators/withStyles';
import Link from '../Link';
import Navigation from '../Navigation';

@withStyles(s)
class AudioPlayer extends Component {

  static propTypes = {
    audioSrc: PropTypes.string.isRequired,
  };

  componentDidMount() {
    console.log("audio mounted");
    console.log(this.props.audioSrc);

    var audio = document.getElementById("audio").play();
    audio.autoplay = false;
    console.log(audio);
  }

  render() {
    return (

        <audio id="audio">
          <source type="audio/mpeg" src={this.props.audioSrc} >
            Your browser does not support the audio element.</source>
        </audio>

    );
  }

}

export default AudioPlayer;
<commit_msg>Play and pause functionnality<commit_after>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import React, { Component, PropTypes } from 'react';
import s from './AudioPlayer.scss';
import withStyles from '../../decorators/withStyles';
import Link from '../Link';
import Navigation from '../Navigation';

@withStyles(s)
class AudioPlayer extends Component {

  static propTypes = {
    audioSrc: PropTypes.string.isRequired,
  };

  componentDidMount() {
    self = this;
    console.log("mounted");
    self.audio = document.createElement('audio');
    self.audio.src = this.props.audioSrc;
    self.audio.play();
    self.playing = true;
  }

  play(){
    self.audio.play();
    self.playing = true;
  }

  pause(){
    self.audio.pause();
    self.playing = false;
  }

  playPauseClick() {
    if(self.playing)
      self.pause();
    else
      self.play();
  }

  render() {
    return (

        <button onClick={this.playPauseClick}>Stop</button>

    );
  }

}

export default AudioPlayer;
<|endoftext|>


<commit_before>var Class = require('../utils/Class');
var GetFastValue = require('../utils/object/GetFastValue');
var CONST = require('./const');
var GetURL = require('./GetURL');
var MergeXHRSettings = require('./MergeXHRSettings');
var XHRLoader = require('./XHRLoader');
var XHRSettings = require('./XHRSettings');

//  Phaser.Loader.File

var File = new Class({

    initialize:

    // old signature: type, key, url, responseType, xhrSettings, config
    function File (fileConfig)
    {
        //  file type (image, json, etc) for sorting within the Loader
        this.type = GetFastValue(fileConfig, 'type', false);

        //  unique cache key (unique within its file type)
        this.key = GetFastValue(fileConfig, 'key', false);

        if (!this.type || !this.key)
        {
            throw new Error('Error calling \'Loader.' + this.type + '\' invalid key provided.');
        }

        //  The URL of the file, not including baseURL
        this.url = GetFastValue(fileConfig, 'url', '');

        if (this.url === '')
        {
            this.url = GetFastValue(fileConfig, 'path', '') + this.key + GetFastValue(fileConfig, 'extension', '');
        }
        else
        {
            this.url = GetFastValue(fileConfig, 'path', '').concat(this.url);
        }

        //  Set when the Loader calls 'load' on this file
        this.src = '';

        this.xhrSettings = XHRSettings(GetFastValue(fileConfig, 'responseType', undefined));

        if (GetFastValue(fileConfig, 'xhrSettings', false))
        {
            this.xhrSettings = MergeXHRSettings(this.xhrSettings, GetFastValue(fileConfig, 'xhrSettings', {}));
        }

        this.xhrLoader = null;

        this.state = CONST.FILE_PENDING;

        //  Set by onProgress (only if loading via XHR)
        this.bytesTotal = 0;
        this.bytesLoaded = -1;
        this.percentComplete = -1;

        //  For CORs based loading.
        //  If this is undefined then the File will check BaseLoader.crossOrigin and use that (if set)
        this.crossOrigin = undefined;

        //  The actual processed file data
        this.data = undefined;

        //  A config object that can be used by file types to store transitional data
        this.config = GetFastValue(fileConfig, 'config', {});

        //  Multipart file? (i.e. an atlas and its json together)
        this.linkFile = undefined;
        this.linkType = '';

        this.callback = null;
    },

    resetXHR: function ()
    {
        this.xhrLoader.onload = undefined;
        this.xhrLoader.onerror = undefined;
        this.xhrLoader.onprogress = undefined;
    },

    //  Called when the Image loads
    //  ProgressEvent
    onLoad: function (event)
    {
        this.resetXHR();

        this.callback(this, true);
    },

    onError: function (event)
    {
        this.resetXHR();

        this.callback(this, false);
    },

    onProgress: function (event)
    {
        if (event.lengthComputable)
        {
            this.bytesLoaded = event.loaded;
            this.bytesTotal = event.total;

            this.percentComplete = Math.min((this.bytesLoaded / this.bytesTotal), 1);
        }

        // console.log(this.percentComplete + '% (' + this.bytesLoaded + ' bytes)');
    },

    onProcess: function (callback)
    {
        this.state = CONST.FILE_PROCESSING;

        this.onComplete();

        callback(this);
    },

    onComplete: function ()
    {
        if (this.linkFile)
        {
            if (this.linkFile.state === CONST.FILE_WAITING_LINKFILE)
            {
                //  The linkfile has finished processing, and is waiting for this file, so let's do them both
                this.state = CONST.FILE_COMPLETE;
                this.linkFile.state = CONST.FILE_COMPLETE;
            }
            else
            {
                //  The linkfile still hasn't finished loading and/or processing yet
                this.state = CONST.FILE_WAITING_LINKFILE;
            }
        }
        else
        {
            this.state = CONST.FILE_COMPLETE;
        }
    },

    //  Called by the Loader, starts the actual file downloading
    load: function (callback, baseURL, globalXHR)
    {
        if (baseURL === undefined) { baseURL = ''; }

        this.callback = callback;

        this.src = GetURL(this, baseURL);

        if (this.src.indexOf('data:') === 0)
        {
            console.log('Local data URI');
        }
        else
        {
            this.xhrLoader = XHRLoader(this, globalXHR);
        }
    }

});

module.exports = File;
<commit_msg>Fix `url` parameter processing.<commit_after>var Class = require('../utils/Class');
var GetFastValue = require('../utils/object/GetFastValue');
var CONST = require('./const');
var GetURL = require('./GetURL');
var MergeXHRSettings = require('./MergeXHRSettings');
var XHRLoader = require('./XHRLoader');
var XHRSettings = require('./XHRSettings');

//  Phaser.Loader.File

var File = new Class({

    initialize:

    // old signature: type, key, url, responseType, xhrSettings, config
    function File (fileConfig)
    {
        //  file type (image, json, etc) for sorting within the Loader
        this.type = GetFastValue(fileConfig, 'type', false);

        //  unique cache key (unique within its file type)
        this.key = GetFastValue(fileConfig, 'key', false);

        if (!this.type || !this.key)
        {
            throw new Error('Error calling \'Loader.' + this.type + '\' invalid key provided.');
        }

        //  The URL of the file, not including baseURL
        this.url = GetFastValue(fileConfig, 'url');

        if (this.url === undefined)
        {
            this.url = GetFastValue(fileConfig, 'path', '') + this.key + '.' + GetFastValue(fileConfig, 'extension', '');
        }
        else
        {
            this.url = GetFastValue(fileConfig, 'path', '').concat(this.url);
        }

        //  Set when the Loader calls 'load' on this file
        this.src = '';

        this.xhrSettings = XHRSettings(GetFastValue(fileConfig, 'responseType', undefined));

        if (GetFastValue(fileConfig, 'xhrSettings', false))
        {
            this.xhrSettings = MergeXHRSettings(this.xhrSettings, GetFastValue(fileConfig, 'xhrSettings', {}));
        }

        this.xhrLoader = null;

        this.state = CONST.FILE_PENDING;

        //  Set by onProgress (only if loading via XHR)
        this.bytesTotal = 0;
        this.bytesLoaded = -1;
        this.percentComplete = -1;

        //  For CORs based loading.
        //  If this is undefined then the File will check BaseLoader.crossOrigin and use that (if set)
        this.crossOrigin = undefined;

        //  The actual processed file data
        this.data = undefined;

        //  A config object that can be used by file types to store transitional data
        this.config = GetFastValue(fileConfig, 'config', {});

        //  Multipart file? (i.e. an atlas and its json together)
        this.linkFile = undefined;
        this.linkType = '';

        this.callback = null;
    },

    resetXHR: function ()
    {
        this.xhrLoader.onload = undefined;
        this.xhrLoader.onerror = undefined;
        this.xhrLoader.onprogress = undefined;
    },

    //  Called when the Image loads
    //  ProgressEvent
    onLoad: function (event)
    {
        this.resetXHR();

        this.callback(this, true);
    },

    onError: function (event)
    {
        this.resetXHR();

        this.callback(this, false);
    },

    onProgress: function (event)
    {
        if (event.lengthComputable)
        {
            this.bytesLoaded = event.loaded;
            this.bytesTotal = event.total;

            this.percentComplete = Math.min((this.bytesLoaded / this.bytesTotal), 1);
        }

        // console.log(this.percentComplete + '% (' + this.bytesLoaded + ' bytes)');
    },

    onProcess: function (callback)
    {
        this.state = CONST.FILE_PROCESSING;

        this.onComplete();

        callback(this);
    },

    onComplete: function ()
    {
        if (this.linkFile)
        {
            if (this.linkFile.state === CONST.FILE_WAITING_LINKFILE)
            {
                //  The linkfile has finished processing, and is waiting for this file, so let's do them both
                this.state = CONST.FILE_COMPLETE;
                this.linkFile.state = CONST.FILE_COMPLETE;
            }
            else
            {
                //  The linkfile still hasn't finished loading and/or processing yet
                this.state = CONST.FILE_WAITING_LINKFILE;
            }
        }
        else
        {
            this.state = CONST.FILE_COMPLETE;
        }
    },

    //  Called by the Loader, starts the actual file downloading
    load: function (callback, baseURL, globalXHR)
    {
        if (baseURL === undefined) { baseURL = ''; }

        this.callback = callback;

        this.src = GetURL(this, baseURL);

        if (this.src.indexOf('data:') === 0)
        {
            console.log('Local data URI');
        }
        else
        {
            this.xhrLoader = XHRLoader(this, globalXHR);
        }
    }

});

module.exports = File;
<|endoftext|>


<commit_before>'use strict';

describe ('Controller: MainController', function () {
    var createController;

    // load the controller's module
    beforeEach (module ('geckoboardGithubApp'));

    jasmine.Matchers.prototype.toHaveEachRightIconClass = function () {
        var repos = this.actual;

        if (!repos) return false;
        if (repos && repos.length === 0) return false;

        for (var i = 0; i < repos.length; i++) {
            if ((repos[i].fork && repos[i].iconCls !== 'octicon-repo-forked') || (!repos[i].fork && repos[i].iconCls !== 'octicon-repo')) return false;
        }

        return true;
    };

    // Initialize the controller and a mock scope
    beforeEach (inject (function ($injector) {
        var $controller = $injector.get ('$controller') ,
            $rootScope = $injector.get ('$rootScope');

        createController = function (user, repos) {
            user = user || {};
            repos = repos || [];

            return $controller ('MainController', {
                $scope: $rootScope.$new () ,
                user: user ,
                repos: repos
            });
        };
    }));

    describe ('when user and repos data are not yet retrieved', function () {
        var controller = createController ();

        it ('should return empty user data', function () {
            expect(controller.scope.user.hasData).toBe (false);
        });

        it ('should return empty repository list', function () {
            expect(controller.scope.repos).toEqual (jasmine.any (Object));
            expect(controller.scope.repos.length).toEqual (0);
        });
    });

    describe ('when user and repos are retrieved', function () {
        var controller = createController ({id: '0101'}, [{fork: true},{fork: false}]);

        it ('should set user hasData flag', function () {
            expect(controller.scope.user.hasData).toBe (true);
        });

        it ('should append the right icon class to each repository', function () {
            expect(controller.scope.repos).toEqual (jasmine.any (Object));
            expect(controller.scope.repos.length).toBeGreaterThan (0);
            expect(controller.scope.repos).toHaveEachRightIconClass ();
        });
    });
});
<commit_msg>tested the whole main controller<commit_after>'use strict';

describe ('Controller: MainController', function () {
    var fixtures , createController, $scope;

    // load the controller's module
    beforeEach (module ('geckoboardGithubApp'));

    jasmine.Matchers.prototype.toHaveEachRightIconClass = function () {
        var repos = this.actual;

        if (!repos) return false;
        if (repos && repos.length === 0) return false;

        for (var i = 0; i < repos.length; i++) {
            if ((repos[i].fork && repos[i].iconCls !== 'octicon-repo-forked') || (!repos[i].fork && repos[i].iconCls !== 'octicon-repo')) return false;
        }

        return true;
    };

    // Initialize the controller and a mock scope
    beforeEach (inject (function ($injector) {
        var $controller = $injector.get ('$controller') ,
            $rootScope = $injector.get ('$rootScope');

        createController = function (user, repos) {
            user = user || {};
            repos = repos || [];

            $scope = $rootScope.$new ();

            fixtures = {
                user: {
                    "login": "mikermcneil",
                    "id": 618009,
                    "avatar_url": "https://gravatar.com/avatar/199046437b76e6ca73e00b4cc182a1c5?d=https%3A%2F%2Fidenticons.github.com%2F3559bfe5740ed5aac38d3e0e554dbaae.png&r=x",
                    "starred_url": "https://api.github.com/users/mikermcneil/starred",
                    "type": "User",
                    "name": "Mike McNeil",
                    "location": "Austin, TX",
                    "email": "customers@balderdash.co",
                    "followers": 222,
                    "following": 161,
                    "created_at": "2011-02-14T20:51:12Z"
                },
                repos: [
                    {
                        "name": "activityoverlord",
                        "fork": true,
                        "stargazers_count": 0,
                        "language": "JavaScript",
                        "forks_count": 0
                    },
                    {
                        "name": "angularsailsdemo",
                        "fork": true,
                        "stargazers_count": 3,
                        "language": "JavaScript",
                        "forks_count": 2
                    },
                    {
                        "name": "asset-rack",
                        "fork": true,
                        "stargazers_count": 0,
                        "language": "CoffeeScript",
                        "forks_count": 0
                    },
                    {
                        "name": "backbone-ninjas-feb-27",
                        "fork": false,
                        "stargazers_count": 0,
                        "language": "JavaScript",
                        "forks_count": 0
                    },
                    {
                        "name": "backbone-to-sails",
                        "fork": false,
                        "stargazers_count": 16,
                        "language": "JavaScript",
                        "forks_count": 2
                    }
                ],
                repo: {
                    "name": "sails",
                    "description": "Realtime MVC Framework for Node.js",
                    "fork": false,
                    "stargazers_count": 4989,
                    "forks_count": 534,
                    "subscribers_count": 449
                }
            };

            return $controller ('MainController', {
                $scope: $scope ,
                user: user ,
                repos: repos
            });
        };
    }));

    describe ('when user and repos data are not loaded yet', function () {
        it ('should return empty user data', function () {
            var controller = createController ();

            expect($scope.user.hasData).toBe (false);
        });

        it ('should return empty repository list', function () {
            var controller = createController ();

            expect($scope.repos).toEqual (jasmine.any (Object));
            expect($scope.repos.length).toEqual (0);
        });
    });

    describe ('when user and repos are loaded', function () {
        it ('should set user hasData flag and format avatar url', function () {
            var controller = createController (fixtures.user, fixtures.repos);

            expect($scope.user.hasData).toBe (true);
            expect($scope.user.avatar_url.substr (-6, 6)).toEqual ('&s=440');
        });

        it ('should append the right icon class to each repository', function () {
            var controller = createController (fixtures.user, fixtures.repos);

            expect($scope.repos).toEqual (jasmine.any (Object));
            expect($scope.repos.length).toBeGreaterThan (0);
            expect($scope.repos).toHaveEachRightIconClass ();
        });
    });
});<|endoftext|>


<commit_before>op = require("./opcodes");

var INT_MIN = 0x80000000;
var INT_MAX = 0x7FFFFFFF;

var verbose = false;
function log(message) {
    if (verbose) console.log(message);
}

function c0_assertion_failure(val) {
    throw "c0 assertion failure: " + val;
}

var StackFrame = function(file, f) {
    log("Creating stack frame");
    this.stack = [];
    this.pc = 0;
    this.program = f.code;
    this.variables = [];
    for (var i = 0; i < f.num_vars; i++)
        this.variables.push(0);
    this.file = file;
}

var ProgramState = function(parsed_file) {
    log("Creating program state with file " + parsed_file);
    var main_function = parsed_file.function_pool[0];

    this.frame = new StackFrame(parsed_file, parsed_file.function_pool[0]);
    this.call_stack = [];
    this.file = parsed_file;
}

ProgramState.prototype.push = function(val) {
    this.frame.stack.push(val);
}

ProgramState.prototype.pop = function() {
    return this.frame.stack.pop();
}

ProgramState.prototype.goto_offset = function() {
    var c1 = this.frame.program[this.frame.pc+1];
    var c2 = this.frame.program[this.frame.pc+2]

    var address_offset = (c1 << 8) + c2;
    // Handle negative values
    if ((address_offset & 0x8000) != 0)
        address_offset = -0x8000 + (address_offset & 0x7FFF);

    this.frame.pc += address_offset;
}

ProgramState.prototype.doIf = function(f) {
    var y = this.pop();
    var x = this.pop();
    if (f(x,y)) {
        this.goto_offset();
    } else {
        this.frame.pc += 3;
    }
}

ProgramState.prototype.step = function() {
    var opcode = this.frame.program[this.frame.pc]
    log("0x" + this.frame.pc.toString(16) + " Running opcode " +
        op.lookup_table[opcode]);
    switch (opcode) {
        // Stack manipulation
    case op.POP:
        this.frame.pc++;
        this.pop();
        break;
    case op.DUP:
        this.frame.pc++;
        var v = this.pop();
        this.push(v);
        this.push(v);
        break;
    case op.SWAP:
        this.frame.pc++;
        var v1 = this.pop();
        var v2 = this.pop();
        this.push(v1);
        this.push(v2);
        break;
    case op.BIPUSH:
        this.frame.pc += 2;
        var val = this.frame.program[this.frame.pc-1];

        // Do sign extension if necessary
        if ((val & 0x80) != 0)
            val = -0x80 + (val & 0x7F);
        this.push(val);
        break;

        // Returning from a function
    case op.RETURN:
        var retVal = this.pop();
        if (this.call_stack.length == 0)
            throw retVal;

        this.frame = this.call_stack.pop();
        this.push(retVal);

        break;
        // Arithmetic
    case op.IADD:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        log("Adding " + x + " and " + y);
        this.push((x+y) % 0x100000000);
        break;
    case op.ISUB:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push((x-y) % 0x100000000);
        break;
    case op.IMUL:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push((x*y) % 0x100000000);
        break;
    case op.IDIV:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        if (y == 0) c0_arith_error("Divide by zero");
        if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow");

        // This does int division.
        // As I understand it, the ~~ is treated as the identity on integers
        // which forces the type to int, not float
        this.push(~~(x/y));
        break;
    case op.IREM:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        if (y == 0) c0_arith_error("Divide by zero");
        if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow");
        this.push(x%y);
        break;
    case op.IAND:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push(x&y);
        break;
    case op.IOR:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push(x|y);
        break;
    case op.IXOR:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push(x^y);
        break;
    case op.ISHL:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        if (y < 0 || y > 31) c0_arith_error("Shifting by too many bits");
        this.push(x<<y);
        break;
    case op.ISHR:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        console.log("y="+y+", x="+x);
        if (y < 0 || y > 31) c0_arith_error("Shifting by too many bits");
        this.push(x>>y);
        break;

        // Operations on local variables

    case op.VLOAD:
        this.frame.pc += 2;
        var index = this.frame.program[this.frame.pc-1];
        this.push(this.frame.variables[index]);
        break;
    case op.VSTORE:
        this.frame.pc += 2;
        var index = this.frame.program[this.frame.pc-1];
        this.frame.variables[index] = this.pop();
        break;
    case op.ACONST_NULL:
        this.frame.pc++;
        this.push(0);
        break;
    case op.ILDC:
        this.frame.pc += 3;
        var c1 = this.frame.program[this.frame.pc-2];
        var c2 = this.frame.program[this.frame.pc-1];
        var index = (c1 * 0x1000) + c2;

        this.push(this.file.int_pool[index]);
        break;
    case op.ALDC:
        this.frame.pc += 3;
        var c1 = this.frame.program[this.frame.pc-2];
        var c2 = this.frame.program[this.frame.pc-1];
        var index = (c1 * 0x1000) + c2;

        this.push(this.file.string_pool[index]);
        break;

        // Control flow
    case op.NOP:
        this.frame.pc++;
        break;
    case op.IF_CMPEQ:
        this.doIf(function (x,y) {return y == x;});
        break;
    case op.IF_CMPNE:
        this.doIf(function (x,y) {return y != x;});
        break;
    case op.IF_ICMPLT:
        this.doIf(function (x,y) {return y > x;});
        break;
    case op.IF_ICMPGE:
        this.doIf(function (x,y) {return y <= x;});
        break;
    case op.IF_ICMPGT:
        this.doIf(function (x,y) {return y < x;});
        break;
    case op.IF_ICMPLE:
        this.doIf(function (x,y) {return y >= x;});
        break;
    case op.GOTO:
        this.goto_offset();
        break;
    case op.ATHROW:
        this.frame.pc++;
        c0_user_error(this.pop());
        break;
    case op.ASSERT:
        this.frame.pc++;
        var a = this.pop();
        if (this.pop() == 0)
            c0_assertion_failure(a);
        break;

        // Function call operations

    case op.INVOKESTATIC:
        var c1 = this.frame.program[this.frame.pc+1];
        var c2 = this.frame.program[this.frame.pc+2];
        this.frame.pc += 3;

        var index = (c1 << 8) + c2;

        var f = this.file.function_pool[index];
        var newFrame = new StackFrame(this.file, f);
        for (var i = f.num_args - 1; i >= 0; i--) {
            newFrame.variables[i] = this.pop();
        }

        this.call_stack.push(this.frame);
        this.frame = newFrame;
        break;

    default:
        var opcode_name;
        try {
            opcode_name = op.lookup_table[opcode];
        } catch (ignored) {
            opcode_name = "UNKNOWN";
        }
        console.log("Error: Unknown opcode: 0x" + opcode.toString(16) +
                    " (" + opcode_name + ")\n");
        throw "Error - unknown opcode";
    }
    return false;
}

// Takes in a parsed .bc0 file and runs it
function execute(file, callbacks, v) {
    verbose = typeof v !== 'undefined' ? v : true;
    log("Initializing with file " + file);

    var state = new ProgramState(file);

    log("Beginning execution");

    while (true) {
        // I'm not sure how to structure this control flow yet,
        // so if anyone has a better idea, let me know
        try {
            state.step();
        } catch (val) {
            return val;
        }

        // if (at_breakpoint) {
        //   save state (maybe in a global in this file?)
        //   return;
        // }
    }
}

exports.execute = execute;
<commit_msg>Started working on array/struct impl<commit_after>op = require("./opcodes");

var INT_MIN = 0x80000000;
var INT_MAX = 0x7FFFFFFF;

var verbose = false;
function log(message) {
    if (verbose) console.log(message);
}

function c0_assertion_failure(val) {
    throw "c0 assertion failure: " + val;
}

var StackFrame = function(file, f) {
    log("Creating stack frame");
    this.stack = [];
    this.pc = 0;
    this.program = f.code;
    this.variables = [];
    for (var i = 0; i < f.num_vars; i++)
        this.variables.push(0);
    this.file = file;
}

var ProgramState = function(parsed_file) {
    log("Creating program state with file " + parsed_file);
    var main_function = parsed_file.function_pool[0];

    this.frame = new StackFrame(parsed_file, parsed_file.function_pool[0]);
    this.call_stack = [];
    this.file = parsed_file;

    // Memory is just a big array of bytes, right?
    // "Allocation" is appending onto this array
    // A pointer to memory is an index into this array.

    // Structs are stored as themselves
    // Arrays are stored as an entry for the number of elements
    // and then the array, byte-by-byte
    this.heap = [];
}

ProgramState.prototype.push = function(val) {
    this.frame.stack.push(val);
}

ProgramState.prototype.pop = function() {
    return this.frame.stack.pop();
}

ProgramState.prototype.goto_offset = function() {
    var c1 = this.frame.program[this.frame.pc+1];
    var c2 = this.frame.program[this.frame.pc+2]

    var address_offset = (c1 << 8) + c2;
    // Handle negative values
    if ((address_offset & 0x8000) != 0)
        address_offset = -0x8000 + (address_offset & 0x7FFF);

    this.frame.pc += address_offset;
}

ProgramState.prototype.doIf = function(f) {
    var y = this.pop();
    var x = this.pop();
    if (f(x,y)) {
        this.goto_offset();
    } else {
        this.frame.pc += 3;
    }
}

ProgramState.prototype.step = function() {
    var opcode = this.frame.program[this.frame.pc]
    log("0x" + this.frame.pc.toString(16) + " Running opcode " +
        op.lookup_table[opcode]);
    switch (opcode) {
        // Stack manipulation
    case op.POP:
        this.frame.pc++;
        this.pop();
        break;
    case op.DUP:
        this.frame.pc++;
        var v = this.pop();
        this.push(v);
        this.push(v);
        break;
    case op.SWAP:
        this.frame.pc++;
        var v1 = this.pop();
        var v2 = this.pop();
        this.push(v1);
        this.push(v2);
        break;
    case op.BIPUSH:
        this.frame.pc += 2;
        var val = this.frame.program[this.frame.pc-1];

        // Do sign extension if necessary
        if ((val & 0x80) != 0)
            val = -0x80 + (val & 0x7F);
        this.push(val);
        break;

        // Returning from a function
    case op.RETURN:
        var retVal = this.pop();
        if (this.call_stack.length == 0)
            throw retVal;

        this.frame = this.call_stack.pop();
        this.push(retVal);

        break;
        // Arithmetic
    case op.IADD:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        log("Adding " + x + " and " + y);
        this.push((x+y) % 0x100000000);
        break;
    case op.ISUB:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push((x-y) % 0x100000000);
        break;
    case op.IMUL:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push((x*y) % 0x100000000);
        break;
    case op.IDIV:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        if (y == 0) c0_arith_error("Divide by zero");
        if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow");

        // This does int division.
        // As I understand it, the ~~ is treated as the identity on integers
        // which forces the type to int, not float
        this.push(~~(x/y));
        break;
    case op.IREM:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        if (y == 0) c0_arith_error("Divide by zero");
        if (x == INT_MIN && y == -1) c0_arith_error("Arithmetic overflow");
        this.push(x%y);
        break;
    case op.IAND:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push(x&y);
        break;
    case op.IOR:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push(x|y);
        break;
    case op.IXOR:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        this.push(x^y);
        break;
    case op.ISHL:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        if (y < 0 || y > 31) c0_arith_error("Shifting by too many bits");
        this.push(x<<y);
        break;
    case op.ISHR:
        this.frame.pc++;
        var y = this.pop();
        var x = this.pop();
        console.log("y="+y+", x="+x);
        if (y < 0 || y > 31) c0_arith_error("Shifting by too many bits");
        this.push(x>>y);
        break;

        // Operations on local variables

    case op.VLOAD:
        this.frame.pc += 2;
        var index = this.frame.program[this.frame.pc-1];
        this.push(this.frame.variables[index]);
        break;
    case op.VSTORE:
        this.frame.pc += 2;
        var index = this.frame.program[this.frame.pc-1];
        this.frame.variables[index] = this.pop();
        break;
    case op.ACONST_NULL:
        this.frame.pc++;
        this.push(0);
        break;
    case op.ILDC:
        this.frame.pc += 3;
        var c1 = this.frame.program[this.frame.pc-2];
        var c2 = this.frame.program[this.frame.pc-1];
        var index = (c1 * 0x1000) + c2;

        this.push(this.file.int_pool[index]);
        break;
    case op.ALDC:
        this.frame.pc += 3;
        var c1 = this.frame.program[this.frame.pc-2];
        var c2 = this.frame.program[this.frame.pc-1];
        var index = (c1 * 0x1000) + c2;

        this.push(this.file.string_pool[index]);
        break;

        // Control flow
    case op.NOP:
        this.frame.pc++;
        break;
    case op.IF_CMPEQ:
        this.doIf(function (x,y) {return y == x;});
        break;
    case op.IF_CMPNE:
        this.doIf(function (x,y) {return y != x;});
        break;
    case op.IF_ICMPLT:
        this.doIf(function (x,y) {return y > x;});
        break;
    case op.IF_ICMPGE:
        this.doIf(function (x,y) {return y <= x;});
        break;
    case op.IF_ICMPGT:
        this.doIf(function (x,y) {return y < x;});
        break;
    case op.IF_ICMPLE:
        this.doIf(function (x,y) {return y >= x;});
        break;
    case op.GOTO:
        this.goto_offset();
        break;
    case op.ATHROW:
        this.frame.pc++;
        c0_user_error(this.pop());
        break;
    case op.ASSERT:
        this.frame.pc++;
        var a = this.pop();
        if (this.pop() == 0)
            c0_assertion_failure(a);
        break;

        // Function call operations

    case op.INVOKESTATIC:
        var c1 = this.frame.program[this.frame.pc+1];
        var c2 = this.frame.program[this.frame.pc+2];
        this.frame.pc += 3;

        var index = (c1 << 8) + c2;

        var f = this.file.function_pool[index];
        var newFrame = new StackFrame(this.file, f);
        for (var i = f.num_args - 1; i >= 0; i--) {
            newFrame.variables[i] = this.pop();
        }

        this.call_stack.push(this.frame);
        this.frame = newFrame;
        break;

        // Memory allocation operations:

    case op.NEW:
        var size = this.frame.program[this.frame.pc+1];
        var address = this.heap.length;

        for (var i = 0; i < size; i++) this.heap.push(0);

        this.push(address);
        this.frame.pc += 2;
        break;

    case op.NEWARRAY:
        var size = this.frame.program[this.frame.pc+1];
        var address = this.heap.length;
        var num_elements = this.pop();
        if (num_elements < 0) c0_memory_error("Array size must be nonnegative");

        this.heap.push(num_elements);
        this.heap.push(size);

        for (var i = 0; i < num_elements; i++) {
            for (var j = 0; j < size; j++)
                this.heap.push(0);
        }

        this.push(address);
        this.frame.pc += 2;
        break;

    case op.ARRAYLENGTH:
        var pointer = this.pop();
        this.push(this.heap[pointer]);
        break;

        // Memory access operations:

    case op.AADDF:
        // Read offset into a struct
        var offset = this.frame.program[this.frame.pc + 1];
        var index = this.pop();
        this.push(this.heap[index + offset]);
        this.frame.pc += 2;
        break;

    case op.AADDS:
        // Read offset into an array
        var elt_index = this.pop();
        var index = this.pop();
        var array_length = this.heap[index];
        var elt_size = this.heap[index+1];
        if (elt_index >= array_length) c0_memory_error("Array index out of bounds.");
        this.push(this.heap[index + 2 + elt_size*elt_index]);
        this.frame.pc++;
        break;

    case op.IMLOAD:
        var addr = this.pop();
        // Get int32 from bytes
        var val = this.heapdsfjsldkfjsd
        this.push(this.heap[addr]);
        this.frame.pc++;
        break;

    case op.IMSTORE:

    default:
        var opcode_name;
        try {
            opcode_name = op.lookup_table[opcode];
        } catch (ignored) {
            opcode_name = "UNKNOWN";
        }
        console.log("Error: Unknown opcode: 0x" + opcode.toString(16) +
                    " (" + opcode_name + ")\n");
        throw "Error - unknown opcode";
    }
    return false;
}

// Takes in a parsed .bc0 file and runs it
function execute(file, callbacks, v) {
    verbose = typeof v !== 'undefined' ? v : true;
    log("Initializing with file " + file);

    var state = new ProgramState(file);

    log("Beginning execution");

    while (true) {
        // I'm not sure how to structure this control flow yet,
        // so if anyone has a better idea, let me know
        try {
            state.step();
        } catch (val) {
            return val;
        }

        // if (at_breakpoint) {
        //   save state (maybe in a global in this file?)
        //   return;
        // }
    }
}

exports.execute = execute;
<|endoftext|>