<commit_before>var isBrowser = require('is-browser');
var plask     = isBrowser ? {} : require('plask');

//TODO: update width and height if not passed but data is Image or Canvas
function Texture2D(ctx, data, width, height, options) {
    this._ctx        = ctx;
    var gl           = ctx.getGL();
    this._handle     = gl.createTexture();
    this._target     = gl.TEXTURE_2D;
    this._width      = width;
    this._height     = height;

    var internalFormat  = (options && options.format) || gl.RGBA;
    var format          = (options && options.format) || gl.RGBA;
    var repeat          = (options && options.repeat) || false;
    var dataType        = (options && options.type  ) || gl.UNSIGNED_BYTE;
    var flip            = (options && options.flip  ) || false;
    var magFilter       = (options && options.magFilter  ) || gl.LINEAR;
    var minFilter       = (options && options.minFilter  ) || gl.LINEAR;
    var lod             = 0;
    var compressed      = (options && options.compressed) || false;

    //TODO: Should we push stack here?
    ctx.bindTexture(this, 0);

    var wrapS = repeat ? gl.REPEAT : gl.CLAMP_TO_EDGE;
    var wrapT = repeat ? gl.REPEAT : gl.CLAMP_TO_EDGE;

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);

    if (format == gl.DEPTH_COMPONENT && !ctx.isSupported(ctx.CAPS_DEPTH_TEXTURE)) {
        throw new Error('TextureCube - Depth Texture format is not supported');
    }

    if (dataType == gl.FLOAT && !ctx.isSupported(ctx.CAPS_TEXTURE_FLOAT)) {
        throw new Error('TextureCube - Float type is not supported');
    }

    if (dataType == gl.HALF_FLOAT && !ctx.isSupported(ctx.CAPS_TEXTURE_HALF_FLOAT)) {
        throw new Error('TextureCube - Half Float type is not supported');
    }

    this.update(data, width, height, options);
}

//TODO: update width and height if not passed but data is Image or Canvas
Texture2D.prototype.update = function(data, width, height, options) {
    var ctx = this._ctx;
    var gl  = ctx.getGL();

    //TODO: Should we push stack here?
    ctx.bindTexture(this, 0);

    //TODO: this should remember settings from constructor
    var internalFormat  = (options && options.format) || gl.RGBA;
    var format          = (options && options.format) || gl.RGBA;
    var repeat          = (options && options.repeat) || false;
    var dataType        = (options && options.type  ) || gl.UNSIGNED_BYTE;
    var flip            = (options && options.flip  ) || false;
    var lod             = (options && options.lod   ) || 0;
    var compressed      = (options && options.compressed) || false;

    if (!data) {
        gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, width, height, 0, format, dataType, null);
    }
    else if (isBrowser) {
        if (compressed == 'dxt1') {
            var ext = gl.getExtension('WEBGL_compressed_texture_s3tc');
            gl.compressedTexImage2D(gl.TEXTURE_2D, lod, ext.COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, 0, data);
        }
        if (compressed == 'dxt5') {
            var ext = gl.getExtension('WEBGL_compressed_texture_s3tc');
            gl.compressedTexImage2D(gl.TEXTURE_2D, lod, ext.COMPRESSED_RGBA_S3TC_DXT5_EXT, width, height, 0, data);
        }
        else {
            //gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, width, height, 0, format, dataType, data);
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip);
            //Image, ImageData or Canvas
            if (data.width && data.height) {
                gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, format, dataType, data);
            }
            //Array buffer
            else {
                //TODO: set flip flag
                gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, width, height, 0, format, dataType, data);
            }
        }
    }
    else { //assuming Plask
        if (data instanceof plask.SkCanvas) {
            if (flip) {
              gl.texImage2DSkCanvas(this._target, lod, data);
            }
            else {
              gl.texImage2DSkCanvasNoFlip(this._target, lod, data);
            }
        }
        else {
            if (compressed) {
                if (compressed == 'dxt1') {
                    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, 0, data);
                }
                if (compressed == 'dxt5') {
                    gl.compressedTexImage2D(gl.TEXTURE_2D, lod, gl.COMPRESSED_RGBA_S3TC_DXT5_EXT, width, height, 0, data);
                }
            }
            else {
                gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, width, height, 0, format, dataType, data);
            }
        }
    }
}

Texture2D.prototype._bindInternal = function() {
    var gl  = this._ctx.getGL();
    gl.bindTexture(this._target, this._handle);
}

Texture2D.prototype.getHandle = function() {
    return this._handle;
}

Texture2D.prototype.getTarget = function() {
    return this._target;
}

Texture2D.prototype.getWidth = function() {
    return this._width;
}

Texture2D.prototype.getHeight = function() {
    return this._height;
}

Texture2D.prototype.dispose = function(){
    var gl  = this._ctx.getGL();
    gl.deleteTexture(this._handle);
    this._width = 0;
    this._height = 0;
};

module.exports = Texture2D;
<commit_msg>Added not about Plask ignoring format and internal format for Texture2D<commit_after>var isBrowser = require('is-browser');
var plask     = isBrowser ? {} : require('plask');

//TODO: update width and height if not passed but data is Image or Canvas
function Texture2D(ctx, data, width, height, options) {
    this._ctx        = ctx;
    var gl           = ctx.getGL();
    this._handle     = gl.createTexture();
    this._target     = gl.TEXTURE_2D;
    this._width      = width;
    this._height     = height;

    var internalFormat  = (options && options.format) || gl.RGBA;
    var format          = (options && options.format) || gl.RGBA;
    var repeat          = (options && options.repeat) || false;
    var dataType        = (options && options.type  ) || gl.UNSIGNED_BYTE;
    var flip            = (options && options.flip  ) || false;
    var magFilter       = (options && options.magFilter  ) || gl.LINEAR;
    var minFilter       = (options && options.minFilter  ) || gl.LINEAR;
    var lod             = 0;
    var compressed      = (options && options.compressed) || false;

    //TODO: Should we push stack here?
    ctx.bindTexture(this, 0);

    var wrapS = repeat ? gl.REPEAT : gl.CLAMP_TO_EDGE;
    var wrapT = repeat ? gl.REPEAT : gl.CLAMP_TO_EDGE;

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);

    if (format == gl.DEPTH_COMPONENT && !ctx.isSupported(ctx.CAPS_DEPTH_TEXTURE)) {
        throw new Error('TextureCube - Depth Texture format is not supported');
    }

    if (dataType == gl.FLOAT && !ctx.isSupported(ctx.CAPS_TEXTURE_FLOAT)) {
        throw new Error('TextureCube - Float type is not supported');
    }

    if (dataType == gl.HALF_FLOAT && !ctx.isSupported(ctx.CAPS_TEXTURE_HALF_FLOAT)) {
        throw new Error('TextureCube - Half Float type is not supported');
    }

    this.update(data, width, height, options);
}

//TODO: update width and height if not passed but data is Image or Canvas
Texture2D.prototype.update = function(data, width, height, options) {
    var ctx = this._ctx;
    var gl  = ctx.getGL();

    //TODO: Should we push stack here?
    ctx.bindTexture(this, 0);

    //TODO: this should remember settings from constructor
    var internalFormat  = (options && options.format) || gl.RGBA;
    var format          = (options && options.format) || gl.RGBA;
    var repeat          = (options && options.repeat) || false;
    var dataType        = (options && options.type  ) || gl.UNSIGNED_BYTE;
    var flip            = (options && options.flip  ) || false;
    var lod             = (options && options.lod   ) || 0;
    var compressed      = (options && options.compressed) || false;

    if (!data) {
        gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, width, height, 0, format, dataType, null);
    }
    else if (isBrowser) {
        if (compressed == 'dxt1') {
            var ext = gl.getExtension('WEBGL_compressed_texture_s3tc');
            gl.compressedTexImage2D(gl.TEXTURE_2D, lod, ext.COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, 0, data);
        }
        if (compressed == 'dxt5') {
            var ext = gl.getExtension('WEBGL_compressed_texture_s3tc');
            gl.compressedTexImage2D(gl.TEXTURE_2D, lod, ext.COMPRESSED_RGBA_S3TC_DXT5_EXT, width, height, 0, data);
        }
        else {
            //gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, width, height, 0, format, dataType, data);
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip);
            //Image, ImageData or Canvas
            if (data.width && data.height) {
                gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, format, dataType, data);
            }
            //Array buffer
            else {
                //TODO: set flip flag
                gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, width, height, 0, format, dataType, data);
            }
        }
    }
    else { //assuming Plask
        if (data instanceof plask.SkCanvas) {
            //FIXME: using SKCanvas methods ignores format and internal format which forces RGBA and doesn't allow e.g. SRGB
            if (flip) {
              gl.texImage2DSkCanvas(this._target, lod, data);
            }
            else {
              gl.texImage2DSkCanvasNoFlip(this._target, lod, data);
            }
        }
        else {
            if (compressed) {
                if (compressed == 'dxt1') {
                    gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, 0, data);
                }
                if (compressed == 'dxt5') {
                    gl.compressedTexImage2D(gl.TEXTURE_2D, lod, gl.COMPRESSED_RGBA_S3TC_DXT5_EXT, width, height, 0, data);
                }
            }
            else {
                gl.texImage2D(gl.TEXTURE_2D, lod, internalFormat, width, height, 0, format, dataType, data);
            }
        }
    }
}

Texture2D.prototype._bindInternal = function() {
    var gl  = this._ctx.getGL();
    gl.bindTexture(this._target, this._handle);
}

Texture2D.prototype.getHandle = function() {
    return this._handle;
}

Texture2D.prototype.getTarget = function() {
    return this._target;
}

Texture2D.prototype.getWidth = function() {
    return this._width;
}

Texture2D.prototype.getHeight = function() {
    return this._height;
}

Texture2D.prototype.dispose = function(){
    var gl  = this._ctx.getGL();
    gl.deleteTexture(this._handle);
    this._width = 0;
    this._height = 0;
};

module.exports = Texture2D;
<|endoftext|>


<commit_before>/**
@module ember
@submodule ember-templates
*/

import shouldDisplay from 'ember-views/streams/should_display';
import decodeEachKey from 'ember-htmlbars/utils/decode-each-key';

/**
  The `{{#each}}` helper loops over elements in a collection. It is an extension
  of the base Handlebars `{{#each}}` helper.

  The default behavior of `{{#each}}` is to yield its inner block once for every
  item in an array.

  ```javascript
  var developers = [{name: 'Yehuda'},{name: 'Tom'}, {name: 'Paul'}];
  ```

  ```handlebars
  {{#each developers key="name" as |person|}}
    {{person.name}}
    {{! `this` is whatever it was outside the #each }}
  {{/each}}
  ```

  The same rules apply to arrays of primitives.

  ```javascript
  var developerNames = ['Yehuda', 'Tom', 'Paul']
  ```

  ```handlebars
  {{#each developerNames key="@index" as |name|}}
    {{name}}
  {{/each}}
  ```

  ### Specifying Keys

  The `key` option is used to tell Ember how to determine if the array being
  iterated over with `{{#each}}` has changed between renders. By helping Ember
  detect that some elements in the array are the same, DOM elements can be
  re-used, significantly improving rendering speed.

  For example, here's the `{{#each}}` helper with its `key` set to `id`:

  ```handlebars
  {{#each model key="id" as |item|}}
  {{/each}}
  ```

  When this `{{#each}}` re-renders, Ember will match up the previously rendered
  items (and reorder the generated DOM elements) based on each item's `id`
  property.

  By default the item's own reference is used.

  ### {{else}} condition

  `{{#each}}` can have a matching `{{else}}`. The contents of this block will render
  if the collection is empty.

  ```handlebars
  {{#each developers as |person|}}
    {{person.name}}
  {{else}}
    <p>Sorry, nobody is available for this task.</p>
  {{/each}}
  ```

  @method each
  @for Ember.Templates.helpers
  @public
*/
export default function eachHelper(params, hash, blocks) {
  var list = params[0];
  var keyPath = hash.key;

  if (shouldDisplay(list)) {
    forEach(list, (item, i) => {
      var key = decodeEachKey(item, keyPath, i);

      blocks.template.yieldItem(key, [item, i]);
    });
  } else if (blocks.inverse.yield) {
    blocks.inverse.yield();
  }
}

function forEach(iterable, cb) {
  return iterable.forEach ? iterable.forEach(cb) : Array.prototype.forEach.call(iterable, cb);
}
<commit_msg>[DOC release] Document on index block param for each helper<commit_after>/**
@module ember
@submodule ember-templates
*/

import shouldDisplay from 'ember-views/streams/should_display';
import decodeEachKey from 'ember-htmlbars/utils/decode-each-key';

/**
  The `{{#each}}` helper loops over elements in a collection. It is an extension
  of the base Handlebars `{{#each}}` helper.

  The default behavior of `{{#each}}` is to yield its inner block once for every
  item in an array passing the item as the first param to the block.

  ```javascript
  var developers = [{name: 'Yehuda'},{name: 'Tom'}, {name: 'Paul'}];
  ```

  ```handlebars
  {{#each developers key="name" as |person|}}
    {{person.name}}
    {{! `this` is whatever it was outside the #each }}
  {{/each}}
  ```

  The same rules apply to arrays of primitives.

  ```javascript
  var developerNames = ['Yehuda', 'Tom', 'Paul']
  ```

  ```handlebars
  {{#each developerNames key="@index" as |name|}}
    {{name}}
  {{/each}}
  ```

  During iteration, the index of each item in the array is provided as a second block param.

  ```handlebars
  <ul>
    {{#each people as |person index|}}
      <li>Hello, {{person.name}}! You're number {{index}} in line</li>
    {{/each}}
  </ul>
  ```

  ### Specifying Keys

  The `key` option is used to tell Ember how to determine if the array being
  iterated over with `{{#each}}` has changed between renders. By helping Ember
  detect that some elements in the array are the same, DOM elements can be
  re-used, significantly improving rendering speed.

  For example, here's the `{{#each}}` helper with its `key` set to `id`:

  ```handlebars
  {{#each model key="id" as |item|}}
  {{/each}}
  ```

  When this `{{#each}}` re-renders, Ember will match up the previously rendered
  items (and reorder the generated DOM elements) based on each item's `id`
  property.

  By default the item's own reference is used.

  ### {{else}} condition

  `{{#each}}` can have a matching `{{else}}`. The contents of this block will render
  if the collection is empty.

  ```handlebars
  {{#each developers as |person|}}
    {{person.name}}
  {{else}}
    <p>Sorry, nobody is available for this task.</p>
  {{/each}}
  ```

  @method each
  @for Ember.Templates.helpers
  @public
*/
export default function eachHelper(params, hash, blocks) {
  var list = params[0];
  var keyPath = hash.key;

  if (shouldDisplay(list)) {
    forEach(list, (item, i) => {
      var key = decodeEachKey(item, keyPath, i);

      blocks.template.yieldItem(key, [item, i]);
    });
  } else if (blocks.inverse.yield) {
    blocks.inverse.yield();
  }
}

function forEach(iterable, cb) {
  return iterable.forEach ? iterable.forEach(cb) : Array.prototype.forEach.call(iterable, cb);
}
<|endoftext|>


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

    function makeCircle(fill) {
        var N = 50; //number of triangles for circle
        var dtheta = 2*pi/N;
        var sind = sin(dtheta), cosd = cos(dtheta);
        var y=0, z=-1, r=1;
        var newy, newz;

        console.log("fill = ", fill);

        var m;
        m = { pos: [] }
        if (fill) {
            m.index = [];
            m.pos.push( vec(0, 0, 0) );
        }
        for (var i=1; i<1+N; i++) {
            m.pos.push( vec(0,y,z) );
            if (fill) m.index.push( 0,i,(i%N)+1 );
            newy = y*cosd + z*sind;
            newz = z*cosd - y*sind;
            r = sqrt(newy*newy + newz*newz);
            y = newy/r;
            z = newz/r;
        }
        if (!fill) m.pos.push(m.pos[0]);

        console.log(m);
        return m;
    }

    function circle(args) {
        if (!(this instanceof circle)) return new circle(args);
        args = args || {};
        if (args.canvas !== undefined) {
            this.canvas = args.canvas;
            delete args.canvas;
        } else {
            this.canvas = canvas.selected;
        }
        if (this.canvas) {
            this.canvas.__activate();
        }

        var R = args.radius || 1; delete args.radius;
        console.log("args.fill = ",args.fill);
        args.fill = args.fill || false;
        args.pos = args.pos || vec(0,0,0);
        args.axis = args.axis || vec(1,0,0);
        args.up = args.up || vec(0,1,0);
        //args.normal = vec(1,0,0);
        args.color = args.color || vec(1,1,1);
        args.opacity = args.opacity || 1;
        args.shininess = args.shininess || 1;
        args.emissive = args.emissive || 0;

        var m = makeCircle(args.fill);

        if (args.fill) {
            var v = [];
            for (var i=0; i<m.pos.length; i++) {
                //vec(R*mi.x, R*mi.y, R*mi.z),
                v.push( vertex({    pos: m.pos[i].multiply(R),  normal: vec(1,0,0),
                                    color: args.color,          opacity: args.opacity,
                                    shininess: args.shininess,  emissive: args.emissive
                }) );
            }

            var t = [];
            for (var i=0; i<m.index.length; i+=3) {
                t.push( triangle({ v0: v[m.index[i]], v1: v[m.index[i+1]], v2: v[m.index[i+2]] }) );
            }

            return compound( t, { pos: args.pos, axis: args.axis, up: args.up } );
        } else {
            var p = m.pos;
            for (var i=0; i<p.length; i++) { p[i] = p[i].multiply(R); }
            return curve({radius: 0.02*R, origin: args.pos, pos: p, axis: args.axis, up: args.up,
                        color: args.color, opacity: args.opacity, shininess: args.shininess,
                        emissive: args.emissive })
        }
    }

    var global = window
    function Export( exports ) {
        if (!global.gsast) global.gsast = {}
        for(var id in exports) {
            if (!global[id]) global[id] = exports[id]
            gsast[id] = exports[id]
        }
    }

    var exports = { circle: circle }
    Export(exports)
}) ();
<commit_msg>Get circle without fill to reorient with axis.<commit_after>;(function () {
    "use strict";

    function makeCircle(fill) {
        var N = 50; //number of triangles for circle
        var dtheta = 2*pi/N;
        var sind = sin(dtheta), cosd = cos(dtheta);
        var y=0, z=-1, r=1;
        var newy, newz;

        var m;
        m = { pos: [] }
        if (fill) {
            m.index = [];
            m.pos.push( vec(0, 0, 0) );
        }
        for (var i=1; i<1+N; i++) {
            m.pos.push( vec(0,y,z) );
            if (fill) m.index.push( 0,i,(i%N)+1 );
            newy = y*cosd + z*sind;
            newz = z*cosd - y*sind;
            r = sqrt(newy*newy + newz*newz);
            y = newy/r;
            z = newz/r;
        }
        if (!fill) m.pos.push(m.pos[0]);

        return m;
    }

    function circle(args) {
        if (!(this instanceof circle)) return new circle(args);
        args = args || {};
        if (args.canvas !== undefined) {
            this.canvas = args.canvas;
            delete args.canvas;
        } else {
            this.canvas = canvas.selected;
        }
        if (this.canvas) {
            this.canvas.__activate();
        }

        args.fill = args.fill || false;
        var R = args.radius || 1; delete args.radius;
        args.pos = args.pos || vec(0,0,0);
        args.axis = args.axis || vec(1,0,0);
        args.up = args.up || vec(0,1,0);
        args.color = args.color || vec(1,1,1);
        args.opacity = args.opacity || 1;
        args.shininess = args.shininess || 1;
        args.emissive = args.emissive || 0;

        var m = makeCircle(args.fill);

        if (args.fill) {
            var v = [];
            for (var i=0; i<m.pos.length; i++) {
                v.push( vertex({    pos: m.pos[i].multiply(R),  normal: vec(1,0,0),
                                    color: args.color,          opacity: args.opacity,
                                    shininess: args.shininess,  emissive: args.emissive
                }) );
            }

            var t = [];
            for (var i=0; i<m.index.length; i+=3) {
                t.push( triangle({ v0: v[m.index[i]], v1: v[m.index[i+1]], v2: v[m.index[i+2]] }) );
            }

            return compound( t, { pos: args.pos, axis: args.axis, up: args.up } );
        } else {
            var p = m.pos;
            for (var i=0; i<p.length; i++) { p[i] = p[i].multiply(R); }
            var curv = curve({pos: p, color: args.color, opacity: args.opacity, shininess: args.shininess, emissive: args.emissive })
            curv.origin=args.pos; curv.axis=args.axis; curv.up=args.up;     //radius: 0.02*R,
            return curv;
        }
    }

    var global = window
    function Export( exports ) {
        if (!global.gsast) global.gsast = {}
        for(var id in exports) {
            if (!global[id]) global[id] = exports[id]
            gsast[id] = exports[id]
        }
    }

    var exports = { circle: circle }
    Export(exports)
}) ();
<|endoftext|>


<commit_before>define(function (require) {
    'use strict';
    var $ = require('jquery');
    var monaco = require('monaco');
    var cpp = require('vs/basic-languages/src/cpp');

    // We need to create a new definition for cpp so we can remove invalid keywords

    function definition() {
        var cppp = $.extend(true, {}, cpp.language); // deep copy

        function removeKeyword(keyword) {
            var index = cppp.keywords.indexOf(keyword);
            if (index > -1) {
                cppp.keywords.splice(index, 1);
            }
        }

        removeKeyword("array");
        removeKeyword("in");
        removeKeyword("interface");
        removeKeyword("ref");

        return cppp;
    }

    monaco.languages.register({id: 'cppp'});
    monaco.languages.setLanguageConfiguration('cppp', cpp.conf);
    monaco.languages.setMonarchTokensProvider('cppp', definition());
});
<commit_msg>Remove non-standard keywords and add missing ones<commit_after>define(function (require) {
    'use strict';
    var $ = require('jquery');
    var monaco = require('monaco');
    var cpp = require('vs/basic-languages/src/cpp');

    // We need to create a new definition for cpp so we can remove invalid keywords

    function definition() {
        var cppp = $.extend(true, {}, cpp.language); // deep copy

        function removeKeyword(keyword) {
            var index = cppp.keywords.indexOf(keyword);
            if (index > -1) {
                cppp.keywords.splice(index, 1);
            }
        }

        function removeKeywords(keywords) {
            for (var i = 0; i < keywords.length; ++i) {
                removeKeyword(keywords[i]);
            }
        }

        function addKeywords(keywords) {
            // (Ruben) Done one by one as if you just push them all, Monaco complains that they're not strings, but as
            // far as I can tell, they indeed are all strings. This somehow fixes it. If you know how to fix it, plz go
            for (var i = 0; i < keywords.length; ++i) {
                cppp.keywords.push(keywords[i]);
            }
        }

        // We remove everything that's not an identifier, underscore reserved name and not an official C++ keyword...
        removeKeywords(["abstract", "amp", "array", "cpu", "delegate", "each", "event", "final", "finally", "gcnew",
            "generic", "in", "initonly", "interface", "interior_ptr", "internal", "literal", "partial", "pascal",
            "pin_ptr", "property", "ref", "restrict", "safe_cast", "sealed", "title_static", "where"]);

        addKeywords(["alignas", "alignof", "and", "and_eq", "asm", "bitand", "bitor", "char16_t", "char32_t", "compl",
            "not", "not_eq", "or", "or_eq", "xor", "xor_eq"]);

        return cppp;
    }

    monaco.languages.register({id: 'cppp'});
    monaco.languages.setLanguageConfiguration('cppp', cpp.conf);
    monaco.languages.setMonarchTokensProvider('cppp', definition());
});
<|endoftext|>


<commit_before>// ==UserScript==
// @name         GitHub Code Guides
// @version      1.1.0
// @description  A userscript that allows you to add one or more vertical guidelines to the code
// @license      https://creativecommons.org/licenses/by-sa/4.0/
// @namespace    http://github.com/Mottie
// @include      https://github.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @run-at       document-idle
// @author       Rob Garrison
// @updateURL    https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-code-guides.user.js
// @downloadURL  https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-code-guides.user.js
// ==/UserScript==
/* copy into textarea to check the guides
         1         2         3         4         5         6         7         8
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345
*/
/* global document, prompt, GM_getValue, GM_setValue, GM_registerMenuCommand */
/* jshint esnext:true, unused:true */
(() => {
	"use strict";
	const style = document.createElement("style");
	// eslint-disable-next-line one-var
	let guides = GM_getValue("ghcg-guides", [{
			chars: 80,
			color: "rgba(0, 0, 0, .3)",
			width: 0.2
		}]),
		font = GM_getValue("ghcg-font", "Menlo");

	function addGuides(vals) {
		let css = "";
		// to align the guides *after* the setting, we need to add 1, then add
		// another 0.1 to give the guide a tiny bit of white space to the left
		vals.forEach(guide => {
			let start = parseFloat(guide.chars) + 1.1;
			// eslint-disable-next-line one-var
			const size = parseFloat(guide.width) || 0.2,
				// each line needs to be at least 0.2ch in width to be visible
				end = (start + (size > 0.2 ? size : 0.2)).toFixed(1),
				color = guide.color || "rgba(0, 0, 0, .3)";
			start = start.toFixed(1);
			css += `transparent ${start}ch, ${color} ${start}ch, ${color} ${end}ch, transparent ${end}ch, `;
		});
		style.textContent = `
			span.blob-code-inner {
				font-family: "${font}", Consolas, "Liberation Mono", Menlo, Courier, monospace !important;
			}
			span.blob-code-inner, td.blob-code-inner {
				display: block !important;
				background: linear-gradient(to right, transparent 0%, ${css} transparent 100%) !important;
			}
		`;
	}

	function validateGuides(vals) {
		let last = 0;
		const valid = [];
		if (!Array.isArray(vals)) {
			console.log("Code-Guides Userscript: Invalid guidelines", vals);
			return;
		}
		// Object.keys() creates an array of string values
		const lines = vals.sort((a, b) => parseFloat(a.chars) - parseFloat(b.chars));
		lines.forEach(line => {
			const num = parseFloat(line.chars);
			// 0.2 is the width of the "ch" in CSS to make it visible
			if (num >= last + line.width) {
				valid.push(line);
				last = num;
			}
		});
		if (valid.length) {
			guides = valid;
			GM_setValue("ghcg-guides", valid);
			GM_setValue("ghcg-font", font);
			addGuides(valid);
		}
	}

	document.querySelector("head").appendChild(style);
	validateGuides(guides);

	// Add GM options
	GM_registerMenuCommand("Set code guideline position & color", () => {
		let val = prompt(`Enter valid JSON [{ "chars":80, "color":"#f00", "width":0.2 }, ...}`, JSON.stringify(guides));
		if (val !== null) {
			try {
				val = JSON.parse(val);
				validateGuides(val);
			} catch (err) {
				console.log(err);
			}
		}
	});

	GM_registerMenuCommand("Set code guideline default font", () => {
		const val = prompt("Enter code font (monospaced)", font);
		if (val !== null) {
			font = val;
			validateGuides(guides);
		}
	});
})();
<commit_msg>Code-Guides: no guides on non-code lines. Fixes #10<commit_after>// ==UserScript==
// @name         GitHub Code Guides
// @version      1.1.0
// @description  A userscript that allows you to add one or more vertical guidelines to the code
// @license      https://creativecommons.org/licenses/by-sa/4.0/
// @namespace    http://github.com/Mottie
// @include      https://github.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @run-at       document-idle
// @author       Rob Garrison
// @updateURL    https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-code-guides.user.js
// @downloadURL  https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-code-guides.user.js
// ==/UserScript==
/* copy into textarea to check the guides
         1         2         3         4         5         6         7         8
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345
*/
/* global document, prompt, GM_getValue, GM_setValue, GM_registerMenuCommand */
/* jshint esnext:true, unused:true */
(() => {
	"use strict";
	const style = document.createElement("style");
	// eslint-disable-next-line one-var
	let guides = GM_getValue("ghcg-guides", [{
			chars: 80,
			color: "rgba(0, 0, 0, .3)",
			width: 0.2
		}]),
		font = GM_getValue("ghcg-font", "Menlo");

	function addGuides(vals) {
		let css = "";
		// to align the guides *after* the setting, we need to add 1, then add
		// another 0.1 to give the guide a tiny bit of white space to the left
		vals.forEach(guide => {
			let start = parseFloat(guide.chars) + 1.1;
			// eslint-disable-next-line one-var
			const size = parseFloat(guide.width) || 0.2,
				// each line needs to be at least 0.2ch in width to be visible
				end = (start + (size > 0.2 ? size : 0.2)).toFixed(1),
				color = guide.color || "rgba(0, 0, 0, .3)";
			start = start.toFixed(1);
			css += `transparent ${start}ch, ${color} ${start}ch, ${color} ${end}ch, transparent ${end}ch, `;
		});
		style.textContent = `
			span.blob-code-inner {
				font-family: "${font}", Consolas, "Liberation Mono", Menlo, Courier, monospace !important;
			}
			span.blob-code-inner, td.blob-code-inner:not(.blob-code-hunk) {
				display: block !important;
				background: linear-gradient(to right, transparent 0%, ${css} transparent 100%) !important;
			}
		`;
	}

	function validateGuides(vals) {
		let last = 0;
		const valid = [];
		if (!Array.isArray(vals)) {
			console.log("Code-Guides Userscript: Invalid guidelines", vals);
			return;
		}
		// Object.keys() creates an array of string values
		const lines = vals.sort((a, b) => parseFloat(a.chars) - parseFloat(b.chars));
		lines.forEach(line => {
			const num = parseFloat(line.chars);
			// 0.2 is the width of the "ch" in CSS to make it visible
			if (num >= last + line.width) {
				valid.push(line);
				last = num;
			}
		});
		if (valid.length) {
			guides = valid;
			GM_setValue("ghcg-guides", valid);
			GM_setValue("ghcg-font", font);
			addGuides(valid);
		}
	}

	document.querySelector("head").appendChild(style);
	validateGuides(guides);

	// Add GM options
	GM_registerMenuCommand("Set code guideline position & color", () => {
		let val = prompt(`Enter valid JSON [{ "chars":80, "color":"#f00", "width":0.2 }, ...}`, JSON.stringify(guides));
		if (val !== null) {
			try {
				val = JSON.parse(val);
				validateGuides(val);
			} catch (err) {
				console.log(err);
			}
		}
	});

	GM_registerMenuCommand("Set code guideline default font", () => {
		const val = prompt("Enter code font (monospaced)", font);
		if (val !== null) {
			font = val;
			validateGuides(guides);
		}
	});
})();
<|endoftext|>


<commit_before>import "babel-polyfill";
import TransportNodeHid from "@ledgerhq/hw-transport-node-hid";
import express from "express";
import cors from "cors";
import bodyParser from "body-parser";

var app = express();

const PORT = process.env.PORT || 8435;

TransportNodeHid.create(5000, process.env.DEBUG || false).then(
  transport => {
    app.use(cors());

    let pending = false;
    app.post("/", bodyParser.json(), async (req, res) => {
      if (!req.body) return res.sendStatus(400);
      let data = null,
        error = null;
      if (pending) {
        return res
          .status(400)
          .json({ error: "an exchange query was already pending" });
      }
      pending = true;
      try {
        data = await transport.exchange(req.body.apduHex, req.body.statusList);
      } catch (e) {
        error = e.toString();
      }
      pending = false;
      const result = { data, error };
      console.log(req.body, " => ", result);
      res.json(result);
    });

    app.listen(PORT, () => {
      console.log("hw-transport-http-proxy-debug listening on " + PORT + "...");
    });
  },
  e => {
    console.error(e);
    process.exit(1);
  }
);
<commit_msg>better logs<commit_after>import "babel-polyfill";
import TransportNodeHid from "@ledgerhq/hw-transport-node-hid";
import express from "express";
import cors from "cors";
import bodyParser from "body-parser";

var app = express();

const PORT = process.env.PORT || 8435;

TransportNodeHid.create(5000, process.env.DEBUG || false).then(
  transport => {
    app.use(cors());

    let pending = false;
    app.post("/", bodyParser.json(), async (req, res) => {
      if (!req.body) return res.sendStatus(400);
      let data = null,
        error = null;
      if (pending) {
        return res
          .status(400)
          .json({ error: "an exchange query was already pending" });
      }
      pending = true;
      try {
        data = await transport.exchange(req.body.apduHex, req.body.statusList);
      } catch (e) {
        error = e.toString();
      }
      pending = false;
      const result = { data, error };
      if (data) console.log("APDU:", req.body.apduHex, "=>", data);
      else
        console.log(
          "APDU failed:",
          req.body.apduHex,
          req.body.statusList,
          "=>",
          error
        );
      res.json(result);
    });

    app.listen(PORT, () => {
      console.log("hw-transport-http-proxy-debug listening on " + PORT + "...");
    });
  },
  e => {
    console.error(e);
    process.exit(1);
  }
);
<|endoftext|>


<commit_before>import { requiredIfNoSingleImage } from "./MapBalloon";

describe("MapBalloon", () => {
  describe("requiredIfNoSingleImage", () => {
    test("prop should be optional if singleImage exists", () => {
      const propTypeMock = jest.fn();
      const props = {
        singleImage: "an image url"
      };
      const args = [props, "another argument"];
      requiredIfNoSingleImage(propTypeMock)(...args);

      expect(propTypeMock).toBeCalledWith(...args);
    });
    test("prop should be required if singleImage does not exists", () => {
      const propTypeMock = { isRequired: jest.fn() };
      const props = {};
      const args = [props, "another argument"];
      requiredIfNoSingleImage(propTypeMock)(...args);

      expect(propTypeMock.isRequired).toBeCalledWith(...args);
    });
  });
});
<commit_msg>test(map-balloon): add tests for onPinClick and onBalloonClick<commit_after>import React from "react";
import Adapter from "enzyme-adapter-react-16";
import Enzyme, { shallow } from "enzyme";

import MapBalloon, { requiredIfNoSingleImage } from "./MapBalloon";
import Pin from "./styledComponents/Pin";
import Balloon from "./styledComponents/Balloon";

Enzyme.configure({ adapter: new Adapter() });

describe("MapBalloon", () => {
  describe("click events", () => {
    let reference, event, onPinClickSpy, onBalloonClickSpy, commonProps;
    beforeEach(() => {
      reference = "some Id";
      event = {};
      onPinClickSpy = jest.fn();
      onBalloonClickSpy = jest.fn();
      commonProps = {
        reference,
        x: 400,
        y: 400,
        caption: "Paloma Orchards",
        imageSet: [
          {
            image: "https://picsum.photos/640/?random",
            name: "Romaine Lettuce"
          }
        ]
      };
    });
    afterEach(() => {
      reference = null;
      event = null;
      onPinClickSpy.mockReset();
      onBalloonClickSpy.mockReset();
      commonProps = null;
    });

    describe("onPinClick", () => {
      test("should pass the reference", () => {
        const wrapper = shallow(
          <MapBalloon onPinClick={onPinClickSpy} {...commonProps} />
        );
        wrapper.find(Pin).simulate("click", event);

        expect(onPinClickSpy).toHaveBeenCalledTimes(1);
        expect(onPinClickSpy).toHaveBeenCalledWith(reference, event);
      });
    });

    describe("onBalloonClick", () => {
      test("should pass the reference", () => {
        const wrapper = shallow(
          <MapBalloon onBalloonClick={onBalloonClickSpy} {...commonProps} />
        );
        wrapper.find(Balloon).simulate("click", event);

        expect(onBalloonClickSpy).toHaveBeenCalledTimes(1);
        expect(onBalloonClickSpy).toHaveBeenCalledWith(reference, event);
      });
    });
  });

  describe("requiredIfNoSingleImage", () => {
    test("prop should be optional if singleImage exists", () => {
      const propTypeMock = jest.fn();
      const props = {
        singleImage: "an image url"
      };
      const args = [props, "another argument"];
      requiredIfNoSingleImage(propTypeMock)(...args);

      expect(propTypeMock).toBeCalledWith(...args);
    });
    test("prop should be required if singleImage does not exists", () => {
      const propTypeMock = { isRequired: jest.fn() };
      const props = {};
      const args = [props, "another argument"];
      requiredIfNoSingleImage(propTypeMock)(...args);

      expect(propTypeMock.isRequired).toBeCalledWith(...args);
    });
  });
});
<|endoftext|>


<commit_before>import { Compute } from './Compute'

class Watch {
  constructor(type) {
    this.id = 'Watch_' + Watch.nextWatchId++
    this.name = null
    this.type = type
    this.executedCount = 0
    this.controller = null
    this.modulePath = ''
    this.subscribers = []
    this.dependencyMap = null
  }
  create(controller, modulePath, name) {
    this.name = name
    this.controller = controller
    this.modulePath = modulePath

    return this
  }
  onUpdate(changes, force) {
    if (!this.subscribers) {
      // It has been deleted before in this batch: ignore.
      return
    }
    this.subscribers.forEach((subscription) => {
      subscription.cb(changes, force)
    })
    if (this.controller.devtools) {
      this.controller.devtools.updateComputedMap(this, this.subscribers)
    }
  }
  subscribe(watcher, cb) {
    if (!this.dependencyMap) {
      this.dependencyMap = this.createDependencyMap()
      this.controller.dependencyStore.addEntity(this, this.dependencyMap)
      if (this.controller.devtools) {
        this.controller.devtools.updateWatchMap(this, this.dependencyMap)
        this.controller.devtools.sendWatchMap([], [], 0, 0)
      }
    }

    for (var x = 0; x < this.subscribers.length; x++) {
      if (this.subscribers[x].watcher === watcher) {
        return this.subscribers[x].unsubscribe
      }
    }

    const subscription = {
      unsubscribe: () => {
        this.subscribers.splice(this.subscribers.indexOf(subscription), 1)
      },
      cb,
      watcher,
    }

    if (watcher instanceof Compute) {
      this.subscribers.unshift(subscription)
    } else {
      this.subscribers.push(subscription)
    }

    if (this.controller.devtools) {
      this.controller.devtools.updateComputedMap(this, this.subscribers)
    }

    return subscription.unsubscribe
  }
  destroy() {
    this.subscribers.forEach((subscription) => subscription.unsubscribe())
    this.subscribers = null
    if (this.dependencyMap) {
      this.controller.dependencyStore.removeEntity(this, this.dependencyMap)
      if (this.controller.devtools) {
        this.controller.devtools.updateWatchMap(this, null, this.dependencyMap)
        this.controller.devtools.sendWatchMap([], [], 0, 0)
      }
    }
  }
  toJSON() {
    return {
      id: this.id,
      executedCount: this.executedCount,
      type: this.type,
      name: this.name,
    }
  }
}

Watch.nextWatchId = 0

export default Watch
<commit_msg>fix(cerebral): remove unnecessary optimization causing shared computed bug<commit_after>import { Compute } from './Compute'

class Watch {
  constructor(type) {
    this.id = 'Watch_' + Watch.nextWatchId++
    this.name = null
    this.type = type
    this.executedCount = 0
    this.controller = null
    this.modulePath = ''
    this.subscribers = []
    this.dependencyMap = null
  }
  create(controller, modulePath, name) {
    this.name = name
    this.controller = controller
    this.modulePath = modulePath

    return this
  }
  onUpdate(changes, force) {
    if (!this.subscribers) {
      // It has been deleted before in this batch: ignore.
      return
    }
    this.subscribers.forEach((subscription) => {
      subscription.cb(changes, force)
    })
    if (this.controller.devtools) {
      this.controller.devtools.updateComputedMap(this, this.subscribers)
    }
  }
  subscribe(watcher, cb) {
    if (!this.dependencyMap) {
      this.dependencyMap = this.createDependencyMap()
      this.controller.dependencyStore.addEntity(this, this.dependencyMap)
      if (this.controller.devtools) {
        this.controller.devtools.updateWatchMap(this, this.dependencyMap)
        this.controller.devtools.sendWatchMap([], [], 0, 0)
      }
    }

    const subscription = {
      unsubscribe: () => {
        this.subscribers.splice(this.subscribers.indexOf(subscription), 1)
      },
      cb,
      watcher,
    }

    if (watcher instanceof Compute) {
      this.subscribers.unshift(subscription)
    } else {
      this.subscribers.push(subscription)
    }

    if (this.controller.devtools) {
      this.controller.devtools.updateComputedMap(this, this.subscribers)
    }

    return subscription.unsubscribe
  }
  destroy() {
    this.subscribers.forEach((subscription) => subscription.unsubscribe())
    this.subscribers = null
    if (this.dependencyMap) {
      this.controller.dependencyStore.removeEntity(this, this.dependencyMap)
      if (this.controller.devtools) {
        this.controller.devtools.updateWatchMap(this, null, this.dependencyMap)
        this.controller.devtools.sendWatchMap([], [], 0, 0)
      }
    }
  }
  toJSON() {
    return {
      id: this.id,
      executedCount: this.executedCount,
      type: this.type,
      name: this.name,
    }
  }
}

Watch.nextWatchId = 0

export default Watch
<|endoftext|>


<commit_before>// Copyright (c) 2016, Matt Godbolt
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

"use strict";
var _ = require('underscore');
var $ = require('jquery');
var EventEmitter = require('events');
var options = require('./options');

function makeFontSizeDropdown(elem, interval, obj, buttonDropdown) {
    var factor = obj.isFontOfStr ? 10 : 14;
    var step = 0.05;
    var found = false;

    var onWheelEvent = function (e) {
        e.preventDefault();
        var selectedId = elem.find('.active').index();
        if (e.originalEvent.deltaY >= 0 && selectedId < elem.children().length - 1) {
            selectedId++;
        } else if (e.originalEvent.deltaY < 0 && selectedId > 0) {
            selectedId--;
        }
        elem.children().eq(selectedId).trigger('click');
    };

    var onClickEvent = function () {
        // Toggle off the selection of the others
        $(this)
            .addClass('active')
            .siblings().removeClass('active');
        // Send the data
        obj.scale = $(this).data('value');
        obj.apply();
        obj.emit('change');
    };

    for (var i = interval[0]; i <= interval[1]; i += step) {
        step *= 1.2;
        var newElement = $('<button></button>');
        newElement.attr('data-value', i);
        newElement.addClass('font-option dropdown-item btn btn-light btn-sm');
        if (!found && (i === obj.scale || Math.floor(i) === obj.scale)) {
            found = true;
            newElement.addClass('active');
        }
        newElement.text(Math.round(i * factor));
        newElement
            .appendTo(elem)
            .click(onClickEvent);
    }

    if (buttonDropdown) {
        buttonDropdown.on('wheel', onWheelEvent);
    }
}

function FontScale(domRoot, state, fontSelectorOrEditor) {
    EventEmitter.call(this);
    this.domRoot = domRoot;
    this.scale = state.fontScale || options.defaultFontScale;
    this.fontSelectorOrEditor = fontSelectorOrEditor;
    this.isFontOfStr = typeof(this.fontSelectorOrEditor) === "string";
    this.apply();
    makeFontSizeDropdown(this.domRoot.find('.font-size-list'), [0.3, 3], this, this.domRoot.find('.fs-button'));
}

_.extend(FontScale.prototype, EventEmitter.prototype);

FontScale.prototype.apply = function () {
    if (this.isFontOfStr) {
        this.domRoot.find(this.fontSelectorOrEditor).css('font-size', (10 * this.scale) + "pt");
    } else {
        this.fontSelectorOrEditor.updateOptions({
            fontSize: 14 * this.scale
        });
    }
};

FontScale.prototype.addState = function (state) {
    if (this.scale !== 1.0)
        state.fontScale = this.scale;
};

FontScale.prototype.setScale = function (scale) {
    this.scale = scale;
    this.apply();
};

module.exports = FontScale;
<commit_msg>Fix font size selector duplicates<commit_after>// Copyright (c) 2016, Matt Godbolt
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

"use strict";
var _ = require('underscore');
var $ = require('jquery');
var EventEmitter = require('events');
var options = require('./options');

function makeFontSizeDropdown(elem, interval, obj, buttonDropdown) {
    var factor = obj.isFontOfStr ? 10 : 14;
    var step = 0.05;
    var found = false;

    var onWheelEvent = function (e) {
        e.preventDefault();
        var selectedId = elem.find('.active').index();
        if (e.originalEvent.deltaY >= 0 && selectedId < elem.children().length - 1) {
            selectedId++;
        } else if (e.originalEvent.deltaY < 0 && selectedId > 0) {
            selectedId--;
        }
        elem.children().eq(selectedId).trigger('click');
    };

    var onClickEvent = function () {
        // Toggle off the selection of the others
        $(this)
            .addClass('active')
            .siblings().removeClass('active');
        // Send the data
        obj.scale = $(this).data('value');
        obj.apply();
        obj.emit('change');
    };
    var lastElement = -1;
    for (var i = interval[0]; i <= interval[1]; i += step) {
        step *= 1.2;
        var displayValue = Math.round(i * factor);
        if (displayValue !== lastElement) {
            lastElement = displayValue;
            var newElement = $('<button></button>');
            newElement.attr('data-value', i);
            newElement.addClass('font-option dropdown-item btn btn-light btn-sm');
            if (!found && (i === obj.scale || Math.floor(i) === obj.scale)) {
                found = true;
                newElement.addClass('active');
            }
            newElement.text(displayValue);
            newElement
                .appendTo(elem)
                .click(onClickEvent);
        }
    }

    if (buttonDropdown) {
        buttonDropdown.on('wheel', onWheelEvent);
    }
}

function FontScale(domRoot, state, fontSelectorOrEditor) {
    EventEmitter.call(this);
    this.domRoot = domRoot;
    this.scale = state.fontScale || options.defaultFontScale;
    this.fontSelectorOrEditor = fontSelectorOrEditor;
    this.isFontOfStr = typeof (this.fontSelectorOrEditor) === "string";
    this.apply();
    makeFontSizeDropdown(this.domRoot.find('.font-size-list'), [0.3, 3], this, this.domRoot.find('.fs-button'));
}

_.extend(FontScale.prototype, EventEmitter.prototype);

FontScale.prototype.apply = function () {
    if (this.isFontOfStr) {
        this.domRoot.find(this.fontSelectorOrEditor).css('font-size', (10 * this.scale) + "pt");
    } else {
        this.fontSelectorOrEditor.updateOptions({
            fontSize: 14 * this.scale
        });
    }
};

FontScale.prototype.addState = function (state) {
    if (this.scale !== 1.0)
        state.fontScale = this.scale;
};

FontScale.prototype.setScale = function (scale) {
    this.scale = scale;
    this.apply();
};

module.exports = FontScale;
<|endoftext|>


<commit_before>var areas = [];
var selectedArea;

/* Custom topojson class courtesy of Ryan Clark */
L.TopoJSON = L.GeoJSON.extend({
    addData: function(jsonData) {
        if (jsonData.type === "Topology") {
            for (var key in jsonData.objects) {
                geojson = topojson.feature(jsonData, jsonData.objects[key]);
                L.GeoJSON.prototype.addData.call(this, geojson);
            }
        } else {
            L.GeoJSON.prototype.addData.call(this, jsonData);
        }
    }
});

function initMap() {
    map.setView([51.5, -0.5], 8);
    mapLink = 'OpenStreetMap';
    // load a tile layer
    L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors © CartoDB, CartoDB attributions',
        maxZoom: 20,
        minZoom: 0,
        clickable: false
    }).addTo(map);
    $.getJSON('./data/topo_lad.json')
        .done(addTopoData);
}

function loadData() {
    $.ajax({
        url: "./data/lad_complexity.json",
        dataType: 'json'
    }).done(function(data) {
        complexityData = data;
        initMap();
    });
}

function addTopoData(data) {
    topoLayer.addData(data);
    topoLayer.addTo(map);
    topoLayer.eachLayer(handleLayer);
    areaChanged();
}

function handleLayer(layer) {
    var complexity = complexityData[layer.feature.id].value;
    layer.feature.properties.complexity = complexity;
    layer.setStyle({
        fillColor: colorScale(complexity).hex(),
        fillOpacity: 0.6,
        weight: 0.5,
        opacity: 1,
        color: 'white',
        dashArray: '1',
        smoothFactor: 0.5,
        clickable: false
    });
    layer.on('click', function(e) {
        console.log(e.target.feature.properties.LAD13NM);
        $('#areas').val(e.target.feature.properties.LAD13NM);
        areaChanged();
    });
}

function selectLayer(layer) {
    layer.bringToFront();
    layer.setStyle({
        weight: 5,
        opacity: 1,
        color: 'grey'
    });
    info.update(layer.feature.properties);
}

function deselectLayer(layer) {
    layer.bringToBack();
    layer.setStyle({
        weight: 1,
        opacity: 0.5,
        fillOpacity: 0.7,
        color: 'white'
    });
}

// Change the selected element in the dropdown
function updateAreaList() {

}

//function called when the selected area is changed
function areaChanged() {
    if (selectedArea === undefined) {
        //get the selected area name
        selectedArea = $("#areas").val();
    } else {
        var deselectId = reverseLookup[selectedArea].LAD14CD;
        topoLayer.eachLayer(function(layer) {
            if (layer.feature.id == deselectId) {
                deselectLayer(layer);
            }
        });
    }
    selectedArea = $("#areas").val();
    analyze();
    var id = reverseLookup[selectedArea].LAD14CD;
    topoLayer.eachLayer(function(layer) {
        if (layer.feature.id == id) {
            selectLayer(layer);
            map.fitBounds(layer.getBounds(), {padding: [100, 100]});
        }
    });
}

function parseData(business_numbers, business_proportions, prob, prod_complexity, growth_data) {
    var marker_data = [];
    var x = [];
    var y = [];
    var color = [];
    var text = [];
    var size = [];
    var selectedArea = $("#areas").val() !== undefined ? $("#areas").val() : "City of London";
    var id = reverseLookup[selectedArea].LAD14CD;
    for (var key in business_proportions[id]) {
        if (key !== "growth" && key !== "LAD14NM") {
            var proportional_businesses = business_proportions[id][key];
            var probability = prob[id][key];
            var complexity_value = prod_complexity[key].score;
            var growth_value = growth_data[id][key];
            x.push(growth_value);
            y.push(probability);
            color.push(complexity_value);
            text.push('Industry: ' + '' + key + '
' +
                'Number of businesses: ' + business_numbers[id][key] + '
' +
                'Probability of growth in industry in area: ' +
                probability + '
' + 'Product Complexity: ' + complexity_value + '
' +
                'Business growth 2010 - 2015: ' + growth_value);
            size.push(proportional_businesses * 100);
        }
    }
    marker_data = [{
        x: x,
        y: y,
        mode: 'markers',
        marker: {
            sizemode: 'area',
            size: size,
            sizeref: '2em',
            autocolorscale: false,
            colorscale: 'Portland',
            cmin: -2.5,
            cmax: 2.5,
            color: color,
            colorbar: {
                titleside: 'right',
                outlinecolor: 'rgba(68,68,68,0)',
                ticks: 'none',
                ticklen: 0,
                tickfont: 'Arial',
                fontsize: 4
            }
        },
        text: text,
        hoverinfo: 'text'
    }];
    return marker_data;
}

function analyze() {
    var data = parseData(
        business_numbers,
        business_proportions,
        probabilities,
        product_complexity,
        business_growth
    );

    var layout = {
        showlegend: false,
        autosize: true,
        xaxis: {
            title: 'Sector Growth 2011 - 2015',
            autorange: true,
            zeroline: false,
            dtick: 0.5,
        },
        yaxis: {
            title: 'Probability of Growth in Sector in Area in 2016',
            zeroline: false,
            dtick: 0.1
        },
        margin: {
            t: 10
        },
        hovermode: 'closest',
    };
    Plotly.newPlot('chart', data, layout, {
        displayModeBar: false
    });
}

// Initialise global map and layer variables
var map = new L.map('map');
var topoLayer = new L.TopoJSON();
var colorScale = chroma
    .scale(chroma.brewer.YlOrRd)
    .domain([-2.1227372118474177, 2.397453389303414]);

// Information control
var info = L.control();

info.onAdd = function(map) {
    this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
    this.update();
    return this._div;
};

// method that we will use to update the control based on feature properties passed
info.update = function(props) {
    this._div.innerHTML = '
Local Authority Complexity
' + (props ?
        '' + props.LAD13NM + '
Score: ' +
        props.complexity.toFixed(2).toString() + ''
        : '');
};

info.addTo(map);

// Area Selection Control
//extend the L.Control class to create a custom drop down box
// initially with simple placeholder text
var AreaControl = L.Control.extend({
    initialize: function(name, options) {
        L.Util.setOptions(this, options);
    },
    //function to be called when the control is added to the map
    onAdd: function(map) {
        //create the control container with a css class name
        var container = L.DomUtil.create('div', 'dropdown');
        //jquery method to retrieve JSON object
        $.getJSON("data/LAD_2014_UK_NC.json",
            function(data) {
                //create the htmlString that will form the
                //innerHTML of the forces dropdown
                var htmlString = '<select id=areas ' +
                    'onchange="areaChanged()">';
                //create individual area <option> tags within the
                //<select> tag
                $.each(data, function(i, item) {
                    areas[i] = item;
                    htmlString = htmlString + '<option>' +
                        areas[i].LAD14NM + '</option>';
                });

                //close the select tag
                htmlString += '</select>';

                //update the dropdown list innerHTML
                //with the list of forces
                container.innerHTML = htmlString;

                //allow a user to select a single option
                container.firstChild.onmousedown =
                    container.firstChild.ondblclick =
                        L.DomEvent.stopPropagation;

            });
        analyze();
        return container;
    }
});

map.addControl(new AreaControl('areas', {
    position: 'topright'
}));

/* Dynamic resizing */
$(window).on("resize", function() {
    var h = $(window).height();
    $("#map").height(h - (h * 0.2));
    map.invalidateSize();
}).trigger("resize");

loadData();
<commit_msg>Update numbers to fixed floating point two places. Embolden values. New axes titles. Closes #28.<commit_after>var areas = [];
var selectedArea;

/* Custom topojson class courtesy of Ryan Clark */
L.TopoJSON = L.GeoJSON.extend({
    addData: function(jsonData) {
        if (jsonData.type === "Topology") {
            for (var key in jsonData.objects) {
                geojson = topojson.feature(jsonData, jsonData.objects[key]);
                L.GeoJSON.prototype.addData.call(this, geojson);
            }
        } else {
            L.GeoJSON.prototype.addData.call(this, jsonData);
        }
    }
});

function initMap() {
    map.setView([51.5, -0.5], 8);
    mapLink = 'OpenStreetMap';
    // load a tile layer
    L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors © CartoDB, CartoDB attributions',
        maxZoom: 20,
        minZoom: 0,
        clickable: false
    }).addTo(map);
    $.getJSON('./data/topo_lad.json')
        .done(addTopoData);
}

function loadData() {
    $.ajax({
        url: "./data/lad_complexity.json",
        dataType: 'json'
    }).done(function(data) {
        complexityData = data;
        initMap();
    });
}

function addTopoData(data) {
    topoLayer.addData(data);
    topoLayer.addTo(map);
    topoLayer.eachLayer(handleLayer);
    areaChanged();
}

function handleLayer(layer) {
    var complexity = complexityData[layer.feature.id].value;
    layer.feature.properties.complexity = complexity;
    layer.setStyle({
        fillColor: colorScale(complexity).hex(),
        fillOpacity: 0.6,
        weight: 0.5,
        opacity: 1,
        color: 'white',
        dashArray: '1',
        smoothFactor: 0.5,
        clickable: false
    });
    layer.on('click', function(e) {
        console.log(e.target.feature.properties.LAD13NM);
        $('#areas').val(e.target.feature.properties.LAD13NM);
        areaChanged();
    });
}

function selectLayer(layer) {
    layer.bringToFront();
    layer.setStyle({
        weight: 5,
        opacity: 1,
        color: 'grey'
    });
    info.update(layer.feature.properties);
}

function deselectLayer(layer) {
    layer.bringToBack();
    layer.setStyle({
        weight: 1,
        opacity: 0.5,
        fillOpacity: 0.7,
        color: 'white'
    });
}

// Change the selected element in the dropdown
function updateAreaList() {

}

//function called when the selected area is changed
function areaChanged() {
    if (selectedArea === undefined) {
        //get the selected area name
        selectedArea = $("#areas").val();
    } else {
        var deselectId = reverseLookup[selectedArea].LAD14CD;
        topoLayer.eachLayer(function(layer) {
            if (layer.feature.id == deselectId) {
                deselectLayer(layer);
            }
        });
    }
    selectedArea = $("#areas").val();
    analyze();
    var id = reverseLookup[selectedArea].LAD14CD;
    topoLayer.eachLayer(function(layer) {
        if (layer.feature.id == id) {
            selectLayer(layer);
            map.fitBounds(layer.getBounds(), {padding: [100, 100]});
        }
    });
}

function parseData(business_numbers, business_proportions, prob, prod_complexity, growth_data) {
    var marker_data = [];
    var x = [];
    var y = [];
    var color = [];
    var text = [];
    var size = [];
    var selectedArea = $("#areas").val() !== undefined ? $("#areas").val() : "City of London";
    var id = reverseLookup[selectedArea].LAD14CD;
    for (var key in business_proportions[id]) {
        if (key !== "growth" && key !== "LAD14NM") {
            var proportional_businesses = business_proportions[id][key];
            var probability = prob[id][key];
            var complexity_value = prod_complexity[key].score;
            var growth_value = growth_data[id][key] * 100;
            x.push(growth_value);
            y.push(probability);
            color.push(complexity_value);
            text.push('Industry: ' + '' + key + '
' +
                'Number of businesses: ' + business_numbers[id][key] + '
' +
                'Probability of growth in industry in area: ' +
                probability.toFixed(2) + '
' + 'Product Complexity: ' + complexity_value.toFixed(2) + '
' +
                'Business growth 2010 - 2015: ' + growth_value.toFixed(2) + '');
            size.push(proportional_businesses * 100);
        }
    }
    marker_data = [{
        x: x,
        y: y,
        mode: 'markers',
        marker: {
            sizemode: 'area',
            size: size,
            sizeref: '2em',
            autocolorscale: false,
            colorscale: 'Portland',
            cmin: -2.5,
            cmax: 2.5,
            color: color,
            colorbar: {
                titleside: 'right',
                outlinecolor: 'rgba(68,68,68,0)',
                ticks: 'none',
                ticklen: 0,
                tickfont: 'Arial',
                fontsize: 4
            }
        },
        text: text,
        hoverinfo: 'text'
    }];
    return marker_data;
}

function analyze() {
    var data = parseData(
        business_numbers,
        business_proportions,
        probabilities,
        product_complexity,
        business_growth
    );

    var layout = {
        showlegend: false,
        autosize: true,
        xaxis: {
            title: 'Percentage (%) growth by sector 2011 - 2015',
            autorange: true,
            zeroline: false,
            dtick: 10,
        },
        yaxis: {
            title: 'Probability of Growth by Sector 2016',
            zeroline: false,
            dtick: 0.1
        },
        margin: {
            t: 10
        },
        hovermode: 'closest',
    };
    Plotly.newPlot('chart', data, layout, {
        displayModeBar: false
    });
}

// Initialise global map and layer variables
var map = new L.map('map');
var topoLayer = new L.TopoJSON();
var colorScale = chroma
    .scale(chroma.brewer.YlOrRd)
    .domain([-2.1227372118474177, 2.397453389303414]);

// Information control
var info = L.control();

info.onAdd = function(map) {
    this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
    this.update();
    return this._div;
};

// method that we will use to update the control based on feature properties passed
info.update = function(props) {
    this._div.innerHTML = '
Local Authority Complexity
' + (props ?
        '' + props.LAD13NM + '
Score: ' +
        props.complexity.toFixed(2).toString() + ''
        : '');
};

info.addTo(map);

// Area Selection Control
//extend the L.Control class to create a custom drop down box
// initially with simple placeholder text
var AreaControl = L.Control.extend({
    initialize: function(name, options) {
        L.Util.setOptions(this, options);
    },
    //function to be called when the control is added to the map
    onAdd: function(map) {
        //create the control container with a css class name
        var container = L.DomUtil.create('div', 'dropdown');
        //jquery method to retrieve JSON object
        $.getJSON("data/LAD_2014_UK_NC.json",
            function(data) {
                //create the htmlString that will form the
                //innerHTML of the forces dropdown
                var htmlString = '<select id=areas ' +
                    'onchange="areaChanged()">';
                //create individual area <option> tags within the
                //<select> tag
                $.each(data, function(i, item) {
                    areas[i] = item;
                    htmlString = htmlString + '<option>' +
                        areas[i].LAD14NM + '</option>';
                });

                //close the select tag
                htmlString += '</select>';

                //update the dropdown list innerHTML
                //with the list of forces
                container.innerHTML = htmlString;

                //allow a user to select a single option
                container.firstChild.onmousedown =
                    container.firstChild.ondblclick =
                        L.DomEvent.stopPropagation;

            });
        analyze();
        return container;
    }
});

map.addControl(new AreaControl('areas', {
    position: 'topright'
}));

/* Dynamic resizing */
$(window).on("resize", function() {
    var h = $(window).height();
    $("#map").height(h - (h * 0.2));
    map.invalidateSize();
}).trigger("resize");

loadData();
<|endoftext|>


<commit_before>import should from 'should';
import { transformString } from '../src/transform';

function test(input, output) {
  it(input, () => should(transformString(input)).equal(output));
}

describe('transform', () => {
  it('should turn a string into a string',
    () => transformString("()").should.be.a.String());

  describe('variables', () => {
    test('(let a 2)', 'var a = 2;');
    test('(let a 2 b 4 c 5)', 'var a = 2;var b = 4;var c = 5;');
    test('(let a (+ 1 2))', 'var a = (1 + 2);');
  });

  describe('math', () => {
    test('(+ 1 2)', '1 + 2');
    test('(- 9 6)', '9 - 6');
    test('(* 2 3)', '2 * 3');
    test('(/ 4 2)', '4 / 2');
    test('(* (+ 2 4) (- 5 3))', '(2 + 4) * (5 - 3)');
    test('(+ 2 3 4 5)', '2 + 3 + 4 + 5');

    test('(Math.pow 2 4)', 'Math.pow(2, 4)');
    test('(Math.abs -4)', 'Math.abs(-4)');
    test('(Math.pow (* 2 3) (- 2 4))', 'Math.pow((2 * 3), (2 - 4))');
  });

  describe('control flow', () => {
    describe('if else', () => {});
    describe('for loops', () => {});
    describe('while loops', () => {});
  });

  describe.only('function literals', () => {
    test('(function ())', 'function () {return null;}');
    test('(function () 4)', 'function () {return 4;}');
    test('(function (x y) (+ x y))', 'function (x, y) {return (x + y);}');
    test('(function adder (x y) (+ x y))', 'function adder(x, y) {return (x + y);}');
    test('(function (x) (function (y) (+ x y)))', 'function (x) {return function (y) { return (x + y);};}');
  });

  describe('function calls', () => {
    test('(some_func 1 2 3)', 'some_func(1, 2, 3)');
    test('(func 1 (nested 2 3))', 'func(1, nested(2, 3))');
    test('(empty_func)', 'empty_func()');
  });

  describe('data structures', () => {
    describe('arrays', () => {});
    describe('objects', () => {});
  });

  describe('modules', () => {
    test(`
      (module testEm
        (+ 1 2))
      `,
      `module('testEm', function (require, export) {1 + 2;})`);
    test(`
      (module testEm
        (export varA (+ 1 2)))
      `,
      `module('testEm', function (require, export) {export('varA', (1 + 2));})`);
    test(`
      (module testEmA
        (require testEmB (varA)))
      `,
      `module('testEmA', function (require, export) {var testEmB = require('testEmB');var varA = testEmB['varA'];})`);
    test(`
      (module testEmA
        (require testEmB
          (varA
           varB
           varC)))
      `,
      `module('testEmA', function (require, export) {var testEmB = require('testEmB');var varA = testEmB['varA'];var varB = testEmB['varB'];var varC = testEmB['varC'];})`);
  });

  describe('calling methods on dynamic entities', () => {});
});
<commit_msg>fix up those two tests by removing the last of the extraneous parenthesis<commit_after>import should from 'should';
import { transformString } from '../src/transform';

function test(input, output) {
  it(input, () => should(transformString(input)).equal(output));
}

describe('transform', () => {
  it('should turn a string into a string',
    () => transformString("()").should.be.a.String());

  describe('variables', () => {
    test('(let a 2)', 'var a = 2;');
    test('(let a 2 b 4 c 5)', 'var a = 2;var b = 4;var c = 5;');
    test('(let a (+ 1 2))', 'var a = (1 + 2);');
  });

  describe('math', () => {
    test('(+ 1 2)', '1 + 2');
    test('(- 9 6)', '9 - 6');
    test('(* 2 3)', '2 * 3');
    test('(/ 4 2)', '4 / 2');
    test('(* (+ 2 4) (- 5 3))', '(2 + 4) * (5 - 3)');
    test('(+ 2 3 4 5)', '2 + 3 + 4 + 5');

    test('(Math.pow 2 4)', 'Math.pow(2, 4)');
    test('(Math.abs -4)', 'Math.abs(-4)');
    test('(Math.pow (* 2 3) (- 2 4))', 'Math.pow((2 * 3), (2 - 4))');
  });

  describe('control flow', () => {
    describe('if else', () => {});
    describe('for loops', () => {});
    describe('while loops', () => {});
  });

  describe.only('function literals', () => {
    test('(function ())', 'function () {return null;}');
    test('(function () 4)', 'function () {return 4;}');
    test('(function (x y) (+ x y))', 'function (x, y) {return x + y;}');
    test('(function adder (x y) (+ x y))', 'function adder(x, y) {return x + y;}');
    test('(function (x) (function (y) (+ x y)))', 'function (x) {return function (y) { return x + y;};}');
  });

  describe('function calls', () => {
    test('(some_func 1 2 3)', 'some_func(1, 2, 3)');
    test('(func 1 (nested 2 3))', 'func(1, nested(2, 3))');
    test('(empty_func)', 'empty_func()');
  });

  describe('data structures', () => {
    describe('arrays', () => {});
    describe('objects', () => {});
  });

  describe('modules', () => {
    test(`
      (module testEm
        (+ 1 2))
      `,
      `module('testEm', function (require, export) {1 + 2;})`);
    test(`
      (module testEm
        (export varA (+ 1 2)))
      `,
      `module('testEm', function (require, export) {export('varA', (1 + 2));})`);
    test(`
      (module testEmA
        (require testEmB (varA)))
      `,
      `module('testEmA', function (require, export) {var testEmB = require('testEmB');var varA = testEmB['varA'];})`);
    test(`
      (module testEmA
        (require testEmB
          (varA
           varB
           varC)))
      `,
      `module('testEmA', function (require, export) {var testEmB = require('testEmB');var varA = testEmB['varA'];var varB = testEmB['varB'];var varC = testEmB['varC'];})`);
  });

  describe('calling methods on dynamic entities', () => {});
});
<|endoftext|>


<commit_before>var JSM = {
	mainVersion : 0,
	subVersion : 20
};

JSM.Eps = 0.00000001;
JSM.Inf = 9999999999;
JSM.RadDeg = 57.29577951308232;
JSM.DegRad = 0.017453292519943;

JSM.IsZero = function (a)
{
	return Math.abs (a) < JSM.Eps;
};

JSM.IsPositive = function (a)
{
	return a > JSM.Eps;
};

JSM.IsNegative = function (a)
{
	return a < -JSM.Eps;
};

JSM.IsLower = function (a, b)
{
	return b - a > JSM.Eps;
};

JSM.IsGreater = function (a, b)
{
	return a - b > JSM.Eps;
};

JSM.IsEqual = function (a, b)
{
	return Math.abs (b - a) < JSM.Eps;
};

JSM.IsEqualWithEps = function (a, b, eps)
{
	return Math.abs (b - a) < eps;
};

JSM.IsLowerOrEqual = function (a, b)
{
	return JSM.IsLower (a, b) || JSM.IsEqual (a, b);
};

JSM.IsGreaterOrEqual = function (a, b)
{
	return JSM.IsGreater (a, b) || JSM.IsEqual (a, b);
};

JSM.Minimum = function (a, b)
{
	return JSM.IsLower (a, b) ? a : b;
};

JSM.Maximum = function (a, b)
{
	return JSM.IsGreater (a, b) ? a : b;
};

JSM.ArcSin = function (value)
{
	if (JSM.IsGreaterOrEqual (value, 1.0)) {
		return Math.PI / 2.0;
	} else if (JSM.IsLowerOrEqual (value, -1.0)) {
		return - Math.PI / 2.0;
	}

	return Math.asin (value);
};

JSM.ArcCos = function (value)
{
	if (JSM.IsGreaterOrEqual (value, 1.0)) {
		return 0.0;
	} else if (JSM.IsLowerOrEqual (value, -1.0)) {
		return Math.PI;
	}

	return Math.acos (value);
};

JSM.RandomInt = function (from, to)
{
	return Math.floor ((Math.random () * (to - from + 1)) + from);
};

JSM.SeededRandomInt = function (from, to, seed)
{
    var random = ((seed * 9301 + 49297) % 233280) / 233280;
	return Math.floor ((random * (to - from + 1)) + from);
};

JSM.ValueOrDefault = function (val, def)
{
	if (val === undefined || val === null) {
		return def;
	}
	return val;
};

JSM.Assert = function (condition, message)
{
	if (!condition) {
		var alertText = 'Assertion failed.';
		if (message !== undefined && message !== null) {
			alertText += ' ' + message;
		}
		alert (alertText);
	}
};
<commit_msg>Upgrade version in development branch.<commit_after>var JSM = {
	mainVersion : 0,
	subVersion : 21
};

JSM.Eps = 0.00000001;
JSM.Inf = 9999999999;
JSM.RadDeg = 57.29577951308232;
JSM.DegRad = 0.017453292519943;

JSM.IsZero = function (a)
{
	return Math.abs (a) < JSM.Eps;
};

JSM.IsPositive = function (a)
{
	return a > JSM.Eps;
};

JSM.IsNegative = function (a)
{
	return a < -JSM.Eps;
};

JSM.IsLower = function (a, b)
{
	return b - a > JSM.Eps;
};

JSM.IsGreater = function (a, b)
{
	return a - b > JSM.Eps;
};

JSM.IsEqual = function (a, b)
{
	return Math.abs (b - a) < JSM.Eps;
};

JSM.IsEqualWithEps = function (a, b, eps)
{
	return Math.abs (b - a) < eps;
};

JSM.IsLowerOrEqual = function (a, b)
{
	return JSM.IsLower (a, b) || JSM.IsEqual (a, b);
};

JSM.IsGreaterOrEqual = function (a, b)
{
	return JSM.IsGreater (a, b) || JSM.IsEqual (a, b);
};

JSM.Minimum = function (a, b)
{
	return JSM.IsLower (a, b) ? a : b;
};

JSM.Maximum = function (a, b)
{
	return JSM.IsGreater (a, b) ? a : b;
};

JSM.ArcSin = function (value)
{
	if (JSM.IsGreaterOrEqual (value, 1.0)) {
		return Math.PI / 2.0;
	} else if (JSM.IsLowerOrEqual (value, -1.0)) {
		return - Math.PI / 2.0;
	}

	return Math.asin (value);
};

JSM.ArcCos = function (value)
{
	if (JSM.IsGreaterOrEqual (value, 1.0)) {
		return 0.0;
	} else if (JSM.IsLowerOrEqual (value, -1.0)) {
		return Math.PI;
	}

	return Math.acos (value);
};

JSM.RandomInt = function (from, to)
{
	return Math.floor ((Math.random () * (to - from + 1)) + from);
};

JSM.SeededRandomInt = function (from, to, seed)
{
    var random = ((seed * 9301 + 49297) % 233280) / 233280;
	return Math.floor ((random * (to - from + 1)) + from);
};

JSM.ValueOrDefault = function (val, def)
{
	if (val === undefined || val === null) {
		return def;
	}
	return val;
};

JSM.Assert = function (condition, message)
{
	if (!condition) {
		var alertText = 'Assertion failed.';
		if (message !== undefined && message !== null) {
			alertText += ' ' + message;
		}
		alert (alertText);
	}
};
<|endoftext|>


<commit_before>/* global app, Backbone, StateMachine,
   mozRTCPeerConnection, mozRTCSessionDescription, tnetbin */
/**
 * Talkilla models and collections.
 */
(function(app, Backbone, StateMachine) {
  "use strict";

  /**
   * Call model.
   *
   * Attributes:
   * - {Object} incomingData
   *
   * Fired when #start() is called and the pending call timeout is reached with
   * no response from the other side.
   * @event offer-timeout
   * @param {Object} options Current call start options (see #start)
   */
  app.models.Call = Backbone.Model.extend({
    timer: undefined,
    media: undefined,

    /**
     * Call model constructor.
     * @param  {Object}  attributes  Model attributes
     * @param  {Object}  options     Model options
     *
     * Options:
     * - {app.models.WebRTCCall}  media      Media object
     */
    initialize: function(attributes, options) {
      this.set(attributes || {});

      this.media = options && options.media;
      this.peer = options && options.peer;

      this.state = StateMachine.create({
        initial: 'ready',
        events: [
          // Call initiation scenario
          {name: 'start',     from: 'ready',    to: 'pending'},
          {name: 'establish', from: 'pending',  to: 'ongoing'},

          // Incoming call scenario
          {name: 'incoming',  from: 'ready',    to: 'incoming'},
          {name: 'accept',    from: 'incoming', to: 'pending'},
          {name: 'ignore',    from: 'incoming', to: 'terminated'},
          {name: 'complete',  from: 'pending',  to: 'ongoing'},

          // Call hangup
          {name: 'hangup',    from: '*',        to: 'terminated'}
        ],
        callbacks: {
          onenterstate: function(event, from, to) {
            this.trigger("change:state", to, from, event);
            this.trigger("state:" + event);
            this.trigger("state:to:" + to);
          }.bind(this)
        }
      });

      this.media.on("offer-ready", function(offer) {
        this.trigger("send-offer", {
          peer: this.peer.get("nick"),
          offer: offer
        });
      }.bind(this));

      this.media.on("answer-ready", function(answer) {
        this.trigger("send-answer", {
          peer: this.peer.get("nick"),
          answer: answer
        });

        // XXX Change transition to complete/ongoing here as
        // this is the best place we've got currently to know that
        // the incoming call is now ongoing. When WebRTC platform
        // support comes for connection notifications, we'll want
        // to handle this differently.
        this.state.complete();
      }.bind(this));
    },

    /**
     * Starts an outbound call.
     *
     * @param {Object} options object containing:
     *
     * - video: set to true to enable video
     * - audio: set to true to enable audio
     */
    start: function(options) {
      this._startTimer({
        callData: options,
        timeout: app.options.PENDING_CALL_TIMEOUT
      });
      this.state.start();
      this.media.initiate(options);
    },

    /**
     * Starts a call based on an incoming call request
     * @param {Object} options object containing:
     *
     * - video: set to true to enable video
     * - audio: set to true to enable audio
     * - offer: information for the media object
     *
     * Other items may be set according to the requirements for the particular
     * media.
     */
    incoming: function(options) {
      this.set({
        incomingData: options
      });
      this.state.incoming();
    },

    /**
     * Completes the connection for an outbound call
     * @param {Object} options object containing:
     *
     * - answer: {Object} answer object
     *
     * Other items may be set according to the requirements for the particular
     * media.
     */
    establish: function(options) {
      var answer = options && options.answer;
      if (!answer)
        throw new Error("Invalid answer, can't establish connection.");

      clearTimeout(this.timer);
      this.media.once('connection-established', this.state.establish,
                                                this.state);
      this.media.establish(answer);
    },

    /**
     * Accepts a pending incoming call.
     */
    accept: function() {
      var data = this.get('incomingData');
      this.media.answer(data && data.offer);
      this.state.accept();
    },

    /**
     * Ignores an incoming call.
     */
    ignore: function() {
      this.state.ignore();
    },

    /**
     * Hangs up a call
     */
    hangup: function() {
      clearTimeout(this.timer);
      this.state.hangup();
      this.media.terminate();
    },

    /**
     * Starts the outgoing pending call timer.
     * @param {Object} options:
     *      - {Number} timeout   Timeout in ms
     *      - {Object} callData  Current outgoing pending call data
     */
    _startTimer: function(options) {
      if (!options || !options.timeout)
        return;

      var onTimeout = function() {
        this.trigger('offer-timeout', options.callData);
      }.bind(this);

      this.timer = setTimeout(onTimeout, options.timeout);
    }
  });

  app.models.Notification = Backbone.Model.extend({
    defaults: {type:    "default",
               message: "empty message"}
  });

  app.models.TextChatEntry = Backbone.Model.extend({
    defaults: {nick: undefined,
               message: undefined,
               date: new Date().getTime()}
  });

  app.models.TextChat = Backbone.Collection.extend({
    model: app.models.TextChatEntry
  });

  app.models.User = Backbone.Model.extend({
    defaults: {nick: undefined,
               avatar: "img/default-avatar.png",
               presence: "disconnected"},

    initialize: function() {
      // If the user has signed in or out, trigger the appropraite
      // change
      this.on("change", function() {
        if (this.isLoggedIn() && !this.wasLoggedIn())
          this.trigger('signin');
        else if (!this.isLoggedIn() && this.wasLoggedIn())
          this.trigger('signout');
      }.bind(this));
    },

    /**
     * Returns true if the user is logged in.
     */
    isLoggedIn: function() {
      return this.get('presence') !== "disconnected" &&
        this.get('nick') !== undefined;
    },

    /**
     * Returns true if the user was logged in prior to the last change
     * on the model. Returns false if there have been no changes.
     */
    wasLoggedIn: function() {
      return this.previous('presence') !== "disconnected" &&
        this.previous('nick') !== undefined;
    }
  });

  app.models.UserSet = Backbone.Collection.extend({
    model: app.models.User,

    initialize: function(models, options) {
      this.models = models || [];
      this.options = options;
      // register the talkilla.users event
      app.port.on('talkilla.users', function(users) {
        this.reset(users);
      }.bind(this));
    }
  });
})(app, Backbone, StateMachine);
<commit_msg>Fix jshint errors<commit_after>/* global app, Backbone, StateMachine */
/**
 * Talkilla models and collections.
 */
(function(app, Backbone, StateMachine) {
  "use strict";

  /**
   * Call model.
   *
   * Attributes:
   * - {Object} incomingData
   *
   * Fired when #start() is called and the pending call timeout is reached with
   * no response from the other side.
   * @event offer-timeout
   * @param {Object} options Current call start options (see #start)
   */
  app.models.Call = Backbone.Model.extend({
    timer: undefined,
    media: undefined,

    /**
     * Call model constructor.
     * @param  {Object}  attributes  Model attributes
     * @param  {Object}  options     Model options
     *
     * Options:
     * - {app.models.WebRTCCall}  media      Media object
     */
    initialize: function(attributes, options) {
      this.set(attributes || {});

      this.media = options && options.media;
      this.peer = options && options.peer;

      this.state = StateMachine.create({
        initial: 'ready',
        events: [
          // Call initiation scenario
          {name: 'start',     from: 'ready',    to: 'pending'},
          {name: 'establish', from: 'pending',  to: 'ongoing'},

          // Incoming call scenario
          {name: 'incoming',  from: 'ready',    to: 'incoming'},
          {name: 'accept',    from: 'incoming', to: 'pending'},
          {name: 'ignore',    from: 'incoming', to: 'terminated'},
          {name: 'complete',  from: 'pending',  to: 'ongoing'},

          // Call hangup
          {name: 'hangup',    from: '*',        to: 'terminated'}
        ],
        callbacks: {
          onenterstate: function(event, from, to) {
            this.trigger("change:state", to, from, event);
            this.trigger("state:" + event);
            this.trigger("state:to:" + to);
          }.bind(this)
        }
      });

      this.media.on("offer-ready", function(offer) {
        this.trigger("send-offer", {
          peer: this.peer.get("nick"),
          offer: offer
        });
      }.bind(this));

      this.media.on("answer-ready", function(answer) {
        this.trigger("send-answer", {
          peer: this.peer.get("nick"),
          answer: answer
        });

        // XXX Change transition to complete/ongoing here as
        // this is the best place we've got currently to know that
        // the incoming call is now ongoing. When WebRTC platform
        // support comes for connection notifications, we'll want
        // to handle this differently.
        this.state.complete();
      }.bind(this));
    },

    /**
     * Starts an outbound call.
     *
     * @param {Object} options object containing:
     *
     * - video: set to true to enable video
     * - audio: set to true to enable audio
     */
    start: function(options) {
      this._startTimer({
        callData: options,
        timeout: app.options.PENDING_CALL_TIMEOUT
      });
      this.state.start();
      this.media.initiate(options);
    },

    /**
     * Starts a call based on an incoming call request
     * @param {Object} options object containing:
     *
     * - video: set to true to enable video
     * - audio: set to true to enable audio
     * - offer: information for the media object
     *
     * Other items may be set according to the requirements for the particular
     * media.
     */
    incoming: function(options) {
      this.set({
        incomingData: options
      });
      this.state.incoming();
    },

    /**
     * Completes the connection for an outbound call
     * @param {Object} options object containing:
     *
     * - answer: {Object} answer object
     *
     * Other items may be set according to the requirements for the particular
     * media.
     */
    establish: function(options) {
      var answer = options && options.answer;
      if (!answer)
        throw new Error("Invalid answer, can't establish connection.");

      clearTimeout(this.timer);
      this.media.once('connection-established', this.state.establish,
                                                this.state);
      this.media.establish(answer);
    },

    /**
     * Accepts a pending incoming call.
     */
    accept: function() {
      var data = this.get('incomingData');
      this.media.answer(data && data.offer);
      this.state.accept();
    },

    /**
     * Ignores an incoming call.
     */
    ignore: function() {
      this.state.ignore();
    },

    /**
     * Hangs up a call
     */
    hangup: function() {
      clearTimeout(this.timer);
      this.state.hangup();
      this.media.terminate();
    },

    /**
     * Starts the outgoing pending call timer.
     * @param {Object} options:
     *      - {Number} timeout   Timeout in ms
     *      - {Object} callData  Current outgoing pending call data
     */
    _startTimer: function(options) {
      if (!options || !options.timeout)
        return;

      var onTimeout = function() {
        this.trigger('offer-timeout', options.callData);
      }.bind(this);

      this.timer = setTimeout(onTimeout, options.timeout);
    }
  });

  app.models.Notification = Backbone.Model.extend({
    defaults: {type:    "default",
               message: "empty message"}
  });

  app.models.TextChatEntry = Backbone.Model.extend({
    defaults: {nick: undefined,
               message: undefined,
               date: new Date().getTime()}
  });

  app.models.TextChat = Backbone.Collection.extend({
    model: app.models.TextChatEntry
  });

  app.models.User = Backbone.Model.extend({
    defaults: {nick: undefined,
               avatar: "img/default-avatar.png",
               presence: "disconnected"},

    initialize: function() {
      // If the user has signed in or out, trigger the appropraite
      // change
      this.on("change", function() {
        if (this.isLoggedIn() && !this.wasLoggedIn())
          this.trigger('signin');
        else if (!this.isLoggedIn() && this.wasLoggedIn())
          this.trigger('signout');
      }.bind(this));
    },

    /**
     * Returns true if the user is logged in.
     */
    isLoggedIn: function() {
      return this.get('presence') !== "disconnected" &&
        this.get('nick') !== undefined;
    },

    /**
     * Returns true if the user was logged in prior to the last change
     * on the model. Returns false if there have been no changes.
     */
    wasLoggedIn: function() {
      return this.previous('presence') !== "disconnected" &&
        this.previous('nick') !== undefined;
    }
  });

  app.models.UserSet = Backbone.Collection.extend({
    model: app.models.User,

    initialize: function(models, options) {
      this.models = models || [];
      this.options = options;
      // register the talkilla.users event
      app.port.on('talkilla.users', function(users) {
        this.reset(users);
      }.bind(this));
    }
  });
})(app, Backbone, StateMachine);
<|endoftext|>