<commit_before>// Rendering modes

var GL = require('./gl.js');
var GLBuilders = require('./gl_builders.js');
var GLGeometry = require('./gl_geom.js').GLGeometry;
var shader_sources = require('./gl_shaders.js'); // built-in shaders

// Base

var RenderMode = {
    init: function (gl) {
        this.gl = gl;
        // this.gl_program = this.makeGLProgram();
        this.makeGLProgram();
    },
    refresh: function () {
        this.makeGLProgram();
    },
    // state: {},
    // updateState: function (new_state) {
    //     this.state = this.state || {};
    //     if (new_state != null) {
    //         for (var k in new_state) {
    //             this.state[k] = this.new_state[k];
    //         }
    //     }
    //     return this.state;
    // },
    defines: {},
    buildPolygons: function(){}, // build functions are no-ops until overriden
    buildLines: function(){},
    buildPoints: function(){}
};

// TODO: allow mode programs to be recompiled
RenderMode.makeGLProgram = function ()
{
    // Add any custom defines to built-in mode defines
    var defines = {}; // create a new object to avoid mutating a prototype value that may be shared with other modes
    if (this.defines != null) {
        for (var d in this.defines) {
            defines[d] = this.defines[d];
        }
    }
    if (this.shaders != null && this.shaders.defines != null) {
        for (var d in this.shaders.defines) {
            defines[d] = this.shaders.defines[d];
        }
    }

    // Get any custom code transforms
    var transforms = (this.shaders && this.shaders.transforms);

    // Create shader from custom URLs
    if (this.shaders && this.shaders.vertex_url && this.shaders.fragment_url) {
        this.gl_program = GL.Program.createProgramFromURLs(
            this.gl,
            this.shaders.vertex_url,
            this.shaders.fragment_url,
            { defines: defines, transforms: transforms }
        );
    }
    // Create shader from built-in source
    else {
        this.gl_program = new GL.Program(
            this.gl,
            shader_sources[this.vertex_shader_key],
            shader_sources[this.fragment_shader_key],
            { defines: defines, transforms: transforms }
        );
    }
};

RenderMode.updateUniforms = function ()
{
    // TODO: only update uniforms when changed
    if (this.shaders != null && this.shaders.uniforms != null) {
        for (var u in this.shaders.uniforms) {
            // Single float
            if (typeof this.shaders.uniforms[u] == 'number') {
                this.gl_program.uniform('1f', u, this.shaders.uniforms[u]);
            }
            else if (typeof this.shaders.uniforms[u] == 'object') {
                // float vectors (vec2, vec3, vec4)
                if (this.shaders.uniforms[u].length >= 2 && this.shaders.uniforms[u].length <= 4) {
                    this.gl_program.uniform(this.shaders.uniforms[u].length + 'fv', u, this.shaders.uniforms[u]);
                }
                // TODO: support arrays for more than 4 components
                // TODO: assume matrix for (typeof == Float32Array && length == 16)?
                // TODO: support non-float types? (int, texture sampler, etc.)
                // this.gl_program.uniform('1fv', u, this.shaders.uniforms[u]);
            }
        }
    }
};

RenderMode.update = function ()
{
    // Mode-specific animation
    if (typeof this.animation == 'function') {
        this.animation();
    }

    this.updateUniforms();
};

var Modes = {};
var ModeManager = {};

// Update built-in mode or create a new one
ModeManager.configureMode = function (name, settings)
{
    Modes[name] = Modes[name] || Object.create(Modes[settings.extends] || RenderMode);
    for (var s in settings) {
        Modes[name][s] = settings[s];
    }
    return Modes[name];
};

// Built-in rendering modes

/*** Plain polygons ***/

Modes.polygons = Object.create(RenderMode);

// Modes.polygons.init = function (gl)
// {
//     RenderMode.init.apply(this, arguments);
//     // this.state.colors = {};
// };

// Count uses of colors
// Modes.polygons.countColor = function (color)
// {g
//     var k = color.join(',');
//     if (this.state.colors[k] != null) {
//         this.state.colors[k]++;
//     }
//     else {
//         this.state.colors[k] = 1;
//     }
// };

Modes.polygons.vertex_shader_key = 'polygon_vertex';
Modes.polygons.fragment_shader_key = 'polygon_fragment';

// Modes.polygons.shaders.uniforms = {
//     // scale: 1.0
// };

Modes.polygons.makeGLGeometry = function (vertex_data)
{
    var geom = new GLGeometry(this.gl, this.gl_program, vertex_data, [
        { name: 'a_position', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_normal', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_color', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_layer', size: 1, type: gl.FLOAT, normalized: false }
    ]);
    geom.geometry_count = geom.vertex_count / 3;

    return geom;
};

Modes.polygons.buildPolygons = function (polygons, style, vertex_data)
{
    // Color and layer number are currently constant across vertices
    var vertex_constants = [
        style.color[0], style.color[1], style.color[2],
        style.layer_num
    ];
    // this.countColor(style.color);

    // Outlines have a slightly different set of constants, because the layer number is modified
    if (style.outline.color) {
        var outline_vertex_constants = [
            style.outline.color[0], style.outline.color[1], style.outline.color[2],
            style.layer_num - 0.5 // outlines sit between layers, underneath current layer but above the one below
        ];
        // this.countColor(style.outline.color);
    }

    // Extruded polygons (e.g. 3D buildings)
    if (style.extrude && style.height) {
        GLBuilders.buildExtrudedPolygons(
            polygons,
            style.z,
            style.height,
            style.min_height,
            vertex_data,
            {
                vertex_constants: vertex_constants
            }
        );
    }
    // Regular polygons
    else {
        GLBuilders.buildPolygons(
            polygons,
            style.z,
            vertex_data,
            {
                normals: true,
                vertex_constants: vertex_constants
            }
        );

        // Callback-base builder (for future exploration)
        // var normal_vertex_constants = [0, 0, 1].concat(vertex_constants);
        // GLBuilders.buildPolygons2(
        //     polygons,
        //     z,
        //     function (vertices) {
        //         // var vs = vertices.positions;
        //         // for (var v in vs) {
        //         //     // var bc = [(v % 3) ? 0 : 1, ((v + 1) % 3) ? 0 : 1, ((v + 2) % 3) ? 0 : 1];
        //         //     // var bc = [centroid.x, centroid.y, 0];
        //         //     // vs[v] = vertices.positions[v].concat(z, 0, 0, 1, bc);

        //         //     // vs[v] = vertices.positions[v].concat(z, 0, 0, 1);
        //         //     vs[v] = vertices.positions[v].concat(0, 0, 1);
        //         // }

        //         GL.addVertices(vertices.positions, normal_vertex_constants, vertex_data);

        //         // GL.addVerticesByAttributeLayout(
        //         //     [
        //         //         { name: 'a_position', data: vertices.positions },
        //         //         { name: 'a_normal', data: [0, 0, 1] },
        //         //         { name: 'a_color', data: [style.color[0], style.color[1], style.color[2]] },
        //         //         { name: 'a_layer', data: style.layer_num }
        //         //     ],
        //         //     vertex_data
        //         // );

        //         // GL.addVerticesMultipleAttributes([vertices.positions], normal_vertex_constants, vertex_data);
        //     }
        // );
    }

    // Polygon outlines
    if (style.outline.color && style.outline.width) {
        for (var mpc=0; mpc < polygons.length; mpc++) {
            GLBuilders.buildPolylines(polygons[mpc], style.layer_num - 0.5, style.outline.width, vertex_data, { closed_polygon: true, remove_tile_edges: true, vertex_constants: outline_vertex_constants });
        }
    }
};

Modes.polygons.buildLines = function (lines, style, vertex_data)
{
    // TOOD: reduce redundancy of constant calc between builders
    // Color and layer number are currently constant across vertices
    var vertex_constants = [
        style.color[0], style.color[1], style.color[2],
        style.layer_num
    ];

    // Outlines have a slightly different set of constants, because the layer number is modified
    if (style.outline.color) {
        var outline_vertex_constants = [
            style.outline.color[0], style.outline.color[1], style.outline.color[2],
            style.layer_num - 0.5 // outlines sit between layers, underneath current layer but above the one below
        ];
    }

    // Main lines
    GLBuilders.buildPolylines(
        lines,
        style.z,
        style.width,
        vertex_data,
        {
            vertex_constants: vertex_constants
        }
    );

    // Line outlines
    if (style.outline.color && style.outline.width) {
        GLBuilders.buildPolylines(
            lines,
            style.z,
            style.width + 2 * style.outline.width,
            vertex_data,
            {
                vertex_constants: outline_vertex_constants
            }
        );
    }
};

Modes.polygons.buildPoints = function (points, style, vertex_data)
{
    // TOOD: reduce redundancy of constant calc between builders
    // Color and layer number are currently constant across vertices
    var vertex_constants = [
        style.color[0], style.color[1], style.color[2],
        style.layer_num
    ];

    GLBuilders.buildQuadsForPoints(
        points,
        style.size * 2,
        style.size * 2,
        style.z,
        vertex_data,
        {
            normals: true,
            texcoords: false,
            vertex_constants: vertex_constants
        }
    );
};

/*** Simplified polygon shader ***/

Modes.polygons_simple = Object.create(Modes.polygons);

Modes.polygons_simple.vertex_shader_key = 'simple_polygon_vertex';
Modes.polygons_simple.fragment_shader_key = 'simple_polygon_fragment';

/*** Points w/simple distance field rendering ***/

Modes.points = Object.create(RenderMode);

Modes.points.vertex_shader_key = 'point_vertex';
Modes.points.fragment_shader_key = 'point_fragment';

Modes.points.defines = {
    'EFFECT_SCREEN_COLOR': true
};

Modes.points.makeGLGeometry = function (vertex_data)
{
    return new GLGeometry(renderer.gl, this.gl_program, vertex_data, [
        { name: 'a_position', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_texcoord', size: 2, type: gl.FLOAT, normalized: false },
        { name: 'a_color', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_layer', size: 1, type: gl.FLOAT, normalized: false }
    ]);
};

Modes.points.buildPoints = function (points, style, vertex_data)
{
    // TOOD: reduce redundancy of constant calc between builders
    // Color and layer number are currently constant across vertices
    var vertex_constants = [
        style.color[0], style.color[1], style.color[2],
        style.layer_num
    ];

    GLBuilders.buildQuadsForPoints(
        points,
        style.size * 2,
        style.size * 2,
        style.z,
        vertex_data,
        {
            normals: false,
            texcoords: true,
            vertex_constants: vertex_constants
        }
    );
};

if (module !== undefined) {
    module.exports = {
        ModeManager: ModeManager,
        Modes: Modes
    };
}
<commit_msg>add a reference to parent class on custom render modes, for use in overloaded geometry builders<commit_after>// Rendering modes

var GL = require('./gl.js');
var GLBuilders = require('./gl_builders.js');
var GLGeometry = require('./gl_geom.js').GLGeometry;
var shader_sources = require('./gl_shaders.js'); // built-in shaders

// Base

var RenderMode = {
    init: function (gl) {
        this.gl = gl;
        // this.gl_program = this.makeGLProgram();
        this.makeGLProgram();
    },
    refresh: function () {
        this.makeGLProgram();
    },
    // state: {},
    // updateState: function (new_state) {
    //     this.state = this.state || {};
    //     if (new_state != null) {
    //         for (var k in new_state) {
    //             this.state[k] = this.new_state[k];
    //         }
    //     }
    //     return this.state;
    // },
    defines: {},
    buildPolygons: function(){}, // build functions are no-ops until overriden
    buildLines: function(){},
    buildPoints: function(){}
};

// TODO: allow mode programs to be recompiled
RenderMode.makeGLProgram = function ()
{
    // Add any custom defines to built-in mode defines
    var defines = {}; // create a new object to avoid mutating a prototype value that may be shared with other modes
    if (this.defines != null) {
        for (var d in this.defines) {
            defines[d] = this.defines[d];
        }
    }
    if (this.shaders != null && this.shaders.defines != null) {
        for (var d in this.shaders.defines) {
            defines[d] = this.shaders.defines[d];
        }
    }

    // Get any custom code transforms
    var transforms = (this.shaders && this.shaders.transforms);

    // Create shader from custom URLs
    if (this.shaders && this.shaders.vertex_url && this.shaders.fragment_url) {
        this.gl_program = GL.Program.createProgramFromURLs(
            this.gl,
            this.shaders.vertex_url,
            this.shaders.fragment_url,
            { defines: defines, transforms: transforms }
        );
    }
    // Create shader from built-in source
    else {
        this.gl_program = new GL.Program(
            this.gl,
            shader_sources[this.vertex_shader_key],
            shader_sources[this.fragment_shader_key],
            { defines: defines, transforms: transforms }
        );
    }
};

RenderMode.updateUniforms = function ()
{
    // TODO: only update uniforms when changed
    if (this.shaders != null && this.shaders.uniforms != null) {
        for (var u in this.shaders.uniforms) {
            // Single float
            if (typeof this.shaders.uniforms[u] == 'number') {
                this.gl_program.uniform('1f', u, this.shaders.uniforms[u]);
            }
            else if (typeof this.shaders.uniforms[u] == 'object') {
                // float vectors (vec2, vec3, vec4)
                if (this.shaders.uniforms[u].length >= 2 && this.shaders.uniforms[u].length <= 4) {
                    this.gl_program.uniform(this.shaders.uniforms[u].length + 'fv', u, this.shaders.uniforms[u]);
                }
                // TODO: support arrays for more than 4 components
                // TODO: assume matrix for (typeof == Float32Array && length == 16)?
                // TODO: support non-float types? (int, texture sampler, etc.)
                // this.gl_program.uniform('1fv', u, this.shaders.uniforms[u]);
            }
        }
    }
};

RenderMode.update = function ()
{
    // Mode-specific animation
    if (typeof this.animation == 'function') {
        this.animation();
    }

    this.updateUniforms();
};

var Modes = {};
var ModeManager = {};

// Update built-in mode or create a new one
ModeManager.configureMode = function (name, settings)
{
    Modes[name] = Modes[name] || Object.create(Modes[settings.extends] || RenderMode);
    if (Modes[settings.extends]) {
        Modes[name].parent = Modes[settings.extends]; // explicit 'super' class access
    }

    for (var s in settings) {
        Modes[name][s] = settings[s];
    }
    return Modes[name];
};

// Built-in rendering modes

/*** Plain polygons ***/

Modes.polygons = Object.create(RenderMode);

// Modes.polygons.init = function (gl)
// {
//     RenderMode.init.apply(this, arguments);
//     // this.state.colors = {};
// };

// Count uses of colors
// Modes.polygons.countColor = function (color)
// {g
//     var k = color.join(',');
//     if (this.state.colors[k] != null) {
//         this.state.colors[k]++;
//     }
//     else {
//         this.state.colors[k] = 1;
//     }
// };

Modes.polygons.vertex_shader_key = 'polygon_vertex';
Modes.polygons.fragment_shader_key = 'polygon_fragment';

// Modes.polygons.shaders.uniforms = {
//     // scale: 1.0
// };

Modes.polygons.makeGLGeometry = function (vertex_data)
{
    var geom = new GLGeometry(this.gl, this.gl_program, vertex_data, [
        { name: 'a_position', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_normal', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_color', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_layer', size: 1, type: gl.FLOAT, normalized: false }
    ]);
    geom.geometry_count = geom.vertex_count / 3;

    return geom;
};

Modes.polygons.buildPolygons = function (polygons, style, vertex_data)
{
    // Color and layer number are currently constant across vertices
    var vertex_constants = [
        style.color[0], style.color[1], style.color[2],
        style.layer_num
    ];
    // this.countColor(style.color);

    // Outlines have a slightly different set of constants, because the layer number is modified
    if (style.outline.color) {
        var outline_vertex_constants = [
            style.outline.color[0], style.outline.color[1], style.outline.color[2],
            style.layer_num - 0.5 // outlines sit between layers, underneath current layer but above the one below
        ];
        // this.countColor(style.outline.color);
    }

    // Extruded polygons (e.g. 3D buildings)
    if (style.extrude && style.height) {
        GLBuilders.buildExtrudedPolygons(
            polygons,
            style.z,
            style.height,
            style.min_height,
            vertex_data,
            {
                vertex_constants: vertex_constants
            }
        );
    }
    // Regular polygons
    else {
        GLBuilders.buildPolygons(
            polygons,
            style.z,
            vertex_data,
            {
                normals: true,
                vertex_constants: vertex_constants
            }
        );

        // Callback-base builder (for future exploration)
        // var normal_vertex_constants = [0, 0, 1].concat(vertex_constants);
        // GLBuilders.buildPolygons2(
        //     polygons,
        //     z,
        //     function (vertices) {
        //         // var vs = vertices.positions;
        //         // for (var v in vs) {
        //         //     // var bc = [(v % 3) ? 0 : 1, ((v + 1) % 3) ? 0 : 1, ((v + 2) % 3) ? 0 : 1];
        //         //     // var bc = [centroid.x, centroid.y, 0];
        //         //     // vs[v] = vertices.positions[v].concat(z, 0, 0, 1, bc);

        //         //     // vs[v] = vertices.positions[v].concat(z, 0, 0, 1);
        //         //     vs[v] = vertices.positions[v].concat(0, 0, 1);
        //         // }

        //         GL.addVertices(vertices.positions, normal_vertex_constants, vertex_data);

        //         // GL.addVerticesByAttributeLayout(
        //         //     [
        //         //         { name: 'a_position', data: vertices.positions },
        //         //         { name: 'a_normal', data: [0, 0, 1] },
        //         //         { name: 'a_color', data: [style.color[0], style.color[1], style.color[2]] },
        //         //         { name: 'a_layer', data: style.layer_num }
        //         //     ],
        //         //     vertex_data
        //         // );

        //         // GL.addVerticesMultipleAttributes([vertices.positions], normal_vertex_constants, vertex_data);
        //     }
        // );
    }

    // Polygon outlines
    if (style.outline.color && style.outline.width) {
        for (var mpc=0; mpc < polygons.length; mpc++) {
            GLBuilders.buildPolylines(polygons[mpc], style.layer_num - 0.5, style.outline.width, vertex_data, { closed_polygon: true, remove_tile_edges: true, vertex_constants: outline_vertex_constants });
        }
    }
};

Modes.polygons.buildLines = function (lines, style, vertex_data)
{
    // TOOD: reduce redundancy of constant calc between builders
    // Color and layer number are currently constant across vertices
    var vertex_constants = [
        style.color[0], style.color[1], style.color[2],
        style.layer_num
    ];

    // Outlines have a slightly different set of constants, because the layer number is modified
    if (style.outline.color) {
        var outline_vertex_constants = [
            style.outline.color[0], style.outline.color[1], style.outline.color[2],
            style.layer_num - 0.5 // outlines sit between layers, underneath current layer but above the one below
        ];
    }

    // Main lines
    GLBuilders.buildPolylines(
        lines,
        style.z,
        style.width,
        vertex_data,
        {
            vertex_constants: vertex_constants
        }
    );

    // Line outlines
    if (style.outline.color && style.outline.width) {
        GLBuilders.buildPolylines(
            lines,
            style.z,
            style.width + 2 * style.outline.width,
            vertex_data,
            {
                vertex_constants: outline_vertex_constants
            }
        );
    }
};

Modes.polygons.buildPoints = function (points, style, vertex_data)
{
    // TOOD: reduce redundancy of constant calc between builders
    // Color and layer number are currently constant across vertices
    var vertex_constants = [
        style.color[0], style.color[1], style.color[2],
        style.layer_num
    ];

    GLBuilders.buildQuadsForPoints(
        points,
        style.size * 2,
        style.size * 2,
        style.z,
        vertex_data,
        {
            normals: true,
            texcoords: false,
            vertex_constants: vertex_constants
        }
    );
};

/*** Simplified polygon shader ***/

Modes.polygons_simple = Object.create(Modes.polygons);

Modes.polygons_simple.vertex_shader_key = 'simple_polygon_vertex';
Modes.polygons_simple.fragment_shader_key = 'simple_polygon_fragment';

/*** Points w/simple distance field rendering ***/

Modes.points = Object.create(RenderMode);

Modes.points.vertex_shader_key = 'point_vertex';
Modes.points.fragment_shader_key = 'point_fragment';

Modes.points.defines = {
    'EFFECT_SCREEN_COLOR': true
};

Modes.points.makeGLGeometry = function (vertex_data)
{
    return new GLGeometry(renderer.gl, this.gl_program, vertex_data, [
        { name: 'a_position', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_texcoord', size: 2, type: gl.FLOAT, normalized: false },
        { name: 'a_color', size: 3, type: gl.FLOAT, normalized: false },
        { name: 'a_layer', size: 1, type: gl.FLOAT, normalized: false }
    ]);
};

Modes.points.buildPoints = function (points, style, vertex_data)
{
    // TOOD: reduce redundancy of constant calc between builders
    // Color and layer number are currently constant across vertices
    var vertex_constants = [
        style.color[0], style.color[1], style.color[2],
        style.layer_num
    ];

    GLBuilders.buildQuadsForPoints(
        points,
        style.size * 2,
        style.size * 2,
        style.z,
        vertex_data,
        {
            normals: false,
            texcoords: true,
            vertex_constants: vertex_constants
        }
    );
};

if (module !== undefined) {
    module.exports = {
        ModeManager: ModeManager,
        Modes: Modes
    };
}
<|endoftext|>


<commit_before>// neural network random art generator

//Position of left hand side of floor
var base1

//Position of right hand side of floor
var base2;
//Length of floor
//var baseLength;

// Variables related to moving ball// settings

// actual size of generated image
var sizeh  = 32*5;
var sizew = sizeh;
var sizeImage = sizeh*sizew;

var nH, nW, nImage;
var mask;

// settings of nnet:
var networkSize = 16;
var nHidden = 8;
var nOut = 3; // r, g, b layers

// support variables:
var img;
var img2;
var G = new R.Graph(false);

var playing = false;
var face;

//Position of left hand side of floor
var base1

//Position of right hand side of floor
var base2;
//Length of floor
//var baseLength;

// Variables related to moving ball
var position;
var velocity;
var r = 6;
var speed = 10;

var initModel = function() {
  "use strict";

  var model = [];
  var i;

  var randomSize = 1.0;

  // define the model below:
  model.w_in = R.RandMat(networkSize, 3, 0, randomSize); // x, y, and bias

  for (i = 0; i < nHidden; i++) {
    model['w_'+i] = R.RandMat(networkSize, networkSize, 0, randomSize);
  }

  model.w_out = R.RandMat(nOut, networkSize, 0, randomSize); // output layer

  return model;
};

var forwardNetwork = function(G, model, x_, y_) {
  // x_, y_ is a normal javascript float, will be converted to a mat object below
  // G is a graph to amend ops to
  var x = new R.Mat(3, 1); // input
  var i;
  x.set(0, 0, x_);
  x.set(1, 0, y_);
  x.set(2, 0, 1.0); // bias.
  var out;
  out = G.tanh(G.mul(model.w_in, x));
  for (i = 0; i < nHidden; i++) {
    out = G.tanh(G.mul(model['w_'+i], out));
  }
  out = G.sigmoid(G.mul(model.w_out, out));
  return out;
};

function getColorAt(model, x, y) {
  // function that returns a color given coordintes (x, y)
  // (x, y) are scaled to -0.5 -> 0.5 for image recognition later
  // but it can be behond the +/- 0.5 for generation above and beyond
  // recognition limits
  var r, g, b;
  var out = forwardNetwork(G, model, x, y);

  r = out.w[0]*255.0;
  g = out.w[1]*255.0;
  b = out.w[2]*255.0;

  return color(r, g, b);
}

function genImage(img, model) {
  var i, j, m, n;
  img.loadPixels();
  for (i = 0, m=img.width; i < m; i++) {
    for (j = 0, n=img.height; j < n; j++) {
      img.set(i, j, getColorAt(model, i/sizeh-0.5,j/sizew-0.5));
    }
  }
  img.updatePixels();
}

function setup() {

	"use strict";
	var myCanvas;

	myCanvas = createCanvas(windowWidth-25, windowHeight-25);
	myCanvas.parent("mainContainer");
	nW = Math.max(Math.floor(sizew/sizew), 1);
	nH = Math.max(Math.floor(sizeh/sizeh), 1);
	nImage = nH*nW;
	mask = R.zeros(nImage);

	img = createImage(sizeh, sizew);
	model = initModel();
	genImage(img, model);

	face = createVideo('videos/fakeface.mp4');
	face.position(windowWidth/2,windowHeight/2)
	face.parent("mainContainer");
	face.hide();
	face.loop();

  //createGround();

  //start ellipse at middle top of screen
  position = createVector(width/2, 0);

  //calculate initial random velocity
  velocity = p5.Vector.random2D();
  velocity.mult(speed);
}

function getRandomLocation() {
  var i, result=0, r;
  for (i=0;i<nImage;i++) {
    result += mask[i];
  }
  if (result === nImage) {
    mask = R.zeros(nImage);
  }
  do {
    r = R.randi(0, nImage);
  } while (mask[r] !== 0);
  mask[r] = 1;
  return r;
}

class Line {
	constructor(n,l) {
		this.x = [];
		this.y = [];
		this.segNum = n;
		this.segLength = l;
		//this.model = model

		for (var i = 0; i < this.segNum; i++) {
			this.x[i] = 0;
			this.y[i] = 0;
		}
	}
	dragSegment(i, xin, yin) {
		var dx = xin - this.x[i];
		var dy = yin - this.y[i];
		var angle = atan2(dy, dx);
		this.x[i] = xin - cos(angle) * this.segLength;
		this.y[i] = yin - sin(angle) * this.segLength;
		this.segment(this.x[i], this.y[i], angle, model);
	}

	segment(x, y, a, model) {
		push();
		translate(x, y);
		rotate(a);
		stroke(getColorAt(model, x, y));
		line(0, 0, this.segLength, 0);
		pop();

	}
}

//l = new Line(20,18);

class Point {
	constructor(x,y,z){
		this.x = x;
		this.y = y;
		this.z = z;
	}
}

function draw() {
	var n = getRandomLocation();
	var row = Math.floor(n/nW);
	var col = n % nW;

	var iwidth = face.width;
	var iheight = face.height;
	tint(255, 127);
	image(face, windowWidth/2-iwidth/2,windowHeight/2+iheight/2, iwidth, iheight);
//	l.dragSegment(0, mouseX, mouseY);
//	for( var i=0; i<l.x.length-1; i++) {
//		l.dragSegment(i+1, l.x[i], l.y[i]);
//	}

  //draw background
  fill(0, 12);
  noStroke();
  rect(0, 0, width, height);

  //draw ellipse
	stroke(getColorAt(model, position.x/windowWidth-0.5, position.y/windowHeight - 0.5));
  fill(getColorAt(model, position.x/windowWidth-0.5, position.y/windowHeight - 0.5));
  ellipse(position.x, position.y, r*2, r*2);

  //move ellipse
  position.add(velocity);

  //normalized incidence vector
  incidence = p5.Vector.mult(velocity, -1);
  incidence.normalize();

  // detect and handle collision with base

  // detect boundary collision
  // right
  if (position.x > width - r) {
    position.x = width - r;
    velocity.x *= -1;
  }
  // left
  if (position.x < r) {
    position.x = r;
    velocity.x *= -1;
  }
  // top
  if ( position.y < r ) {
    position.y = r;
    velocity.y *= -1;
  }
  // top
  if ( position.y > height) {
    position.y = r;
    velocity.y *= -1;
  }

}
<commit_msg>Updated art.<commit_after>// neural network random art generator

//Position of left hand side of floor
var base1

//Position of right hand side of floor
var base2;
//Length of floor
//var baseLength;

// Variables related to moving ball// settings

// actual size of generated image
var sizeh  = 32*5;
var sizew = sizeh;
var sizeImage = sizeh*sizew;

var nH, nW, nImage;
var mask;

// settings of nnet:
var networkSize = 16;
var nHidden = 8;
var nOut = 3; // r, g, b layers

// support variables:
var img;
var img2;
var G = new R.Graph(false);

var playing = false;
var face;

//Position of left hand side of floor
var base1

//Position of right hand side of floor
var base2;
//Length of floor
//var baseLength;

// Variables related to moving ball
var position;
var velocity;
var r = 6;
var speed = 10;

var initModel = function() {
  "use strict";

  var model = [];
  var i;

  var randomSize = 1.0;

  // define the model below:
  model.w_in = R.RandMat(networkSize, 3, 0, randomSize); // x, y, and bias

  for (i = 0; i < nHidden; i++) {
    model['w_'+i] = R.RandMat(networkSize, networkSize, 0, randomSize);
  }

  model.w_out = R.RandMat(nOut, networkSize, 0, randomSize); // output layer

  return model;
};

var forwardNetwork = function(G, model, x_, y_) {
  // x_, y_ is a normal javascript float, will be converted to a mat object below
  // G is a graph to amend ops to
  var x = new R.Mat(3, 1); // input
  var i;
  x.set(0, 0, x_);
  x.set(1, 0, y_);
  x.set(2, 0, 1.0); // bias.
  var out;
  out = G.tanh(G.mul(model.w_in, x));
  for (i = 0; i < nHidden; i++) {
    out = G.tanh(G.mul(model['w_'+i], out));
  }
  out = G.sigmoid(G.mul(model.w_out, out));
  return out;
};

function getColorAt(model, x, y) {
  // function that returns a color given coordintes (x, y)
  // (x, y) are scaled to -0.5 -> 0.5 for image recognition later
  // but it can be behond the +/- 0.5 for generation above and beyond
  // recognition limits
  var r, g, b;
  var out = forwardNetwork(G, model, x, y);

  r = out.w[0]*255.0;
  g = out.w[1]*255.0;
  b = out.w[2]*255.0;

  return color(r, g, b);
}

function genImage(img, model) {
  var i, j, m, n;
  img.loadPixels();
  for (i = 0, m=img.width; i < m; i++) {
    for (j = 0, n=img.height; j < n; j++) {
      img.set(i, j, getColorAt(model, i/sizeh-0.5,j/sizew-0.5));
    }
  }
  img.updatePixels();
}

function setup() {

	"use strict";
	var myCanvas;

	myCanvas = createCanvas(windowWidth-25, windowHeight-25);
	myCanvas.parent("mainContainer");
	nW = Math.max(Math.floor(sizew/sizew), 1);
	nH = Math.max(Math.floor(sizeh/sizeh), 1);
	nImage = nH*nW;
	mask = R.zeros(nImage);

	img = createImage(sizeh, sizew);
	model = initModel();
	genImage(img, model);

	face = createVideo('videos/fakeface.mp4');
	face.position(windowWidth/2,windowHeight/2)
	face.parent("mainContainer");
	face.hide();
	face.loop();

  //createGround();

  //start ellipse at middle top of screen
  position = createVector(width/2, 0);

  //calculate initial random velocity
  velocity = p5.Vector.random2D();
  velocity.mult(speed);
}

function getRandomLocation() {
  var i, result=0, r;
  for (i=0;i<nImage;i++) {
    result += mask[i];
  }
  if (result === nImage) {
    mask = R.zeros(nImage);
  }
  do {
    r = R.randi(0, nImage);
  } while (mask[r] !== 0);
  mask[r] = 1;
  return r;
}

class Line {
	constructor(n,l) {
		this.x = [];
		this.y = [];
		this.segNum = n;
		this.segLength = l;
		//this.model = model

		for (var i = 0; i < this.segNum; i++) {
			this.x[i] = 0;
			this.y[i] = 0;
		}
	}
	dragSegment(i, xin, yin) {
		var dx = xin - this.x[i];
		var dy = yin - this.y[i];
		var angle = atan2(dy, dx);
		this.x[i] = xin - cos(angle) * this.segLength;
		this.y[i] = yin - sin(angle) * this.segLength;
		this.segment(this.x[i], this.y[i], angle, model);
	}

	segment(x, y, a, model) {
		push();
		translate(x, y);
		rotate(a);
		stroke(getColorAt(model, x, y));
		line(0, 0, this.segLength, 0);
		pop();

	}
}

//l = new Line(20,18);

class Point {
	constructor(x,y,z){
		this.x = x;
		this.y = y;
		this.z = z;
	}
}

function draw() {
	var n = getRandomLocation();
	var row = Math.floor(n/nW);
	var col = n % nW;

	var iwidth = face.width;
	var iheight = face.height;
	tint(255, 127);
	image(face, windowWidth/2-iwidth/2,windowHeight/2-iheight/2, iwidth, iheight);
//	l.dragSegment(0, mouseX, mouseY);
//	for( var i=0; i<l.x.length-1; i++) {
//		l.dragSegment(i+1, l.x[i], l.y[i]);
//	}

  //draw background
  fill(0, 12);
  noStroke();
  rect(0, 0, width, height);

  //draw ellipse
	stroke(getColorAt(model, position.x/windowWidth-0.5, position.y/windowHeight - 0.5));
  fill(getColorAt(model, position.x/windowWidth-0.5, position.y/windowHeight - 0.5));
  ellipse(position.x, position.y, r*2, r*2);

  //move ellipse
  position.add(velocity);

  //normalized incidence vector
  incidence = p5.Vector.mult(velocity, -1);
  incidence.normalize();

  // detect and handle collision with base

  // detect boundary collision
  // right
  if (position.x > width - r) {
    position.x = width - r;
    velocity.x *= -1;
  }
  // left
  if (position.x < r) {
    position.x = r;
    velocity.x *= -1;
  }
  // top
  if ( position.y < r ) {
    position.y = r;
    velocity.y *= -1;
  }
  // top
  if ( position.y > height) {
    position.y = r;
    velocity.y *= -1;
  }

}
<|endoftext|>


<commit_before>(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['d3'], factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory(require('d3'));
    } else {
        // Browser globals (root is window)
        root.markmap = factory(root.d3);
    }
}(this, function (d3) {

var assign = Object.assign || function(dst, src) {
  // poor man's Object.assign()
  for (var k in src) {
    if (src.hasOwnProperty(k)) {
      dst[k] = src[k];
    }
  }
  return dst;
};

var depthMaxSize = {};
var yByDepth = {};

function traverseMinDistance(node) {
  var val = Infinity;
  if (node.children) {
    val = Math.min.apply(null, node.children.map(traverseMinDistance));
    if (node.children.length > 1) {
      val = Math.min(val, Math.abs(node.children[0].x - node.children[1].x));
    }
  }
  return val;
}

function getLabelWidth(d) {
  // 5 per character and 25 bonus for rounded corner
  return d.name.length * 5 + 25;
}

function traverseLabelWidth(d, offset) {
  d.y += offset;
  if (d.name !== '' && d.children && d.children.length === 1 && d.children[0].name === '') {
    var child = d.children[0];
    offset += d.y + getLabelWidth(d) - child.y;
    child.y += offset;
    if (child.children) {
      child.children.forEach(function(c) {
        traverseLabelWidth(c, offset);
      });
    }
  }
}

// Set depth width to all nodes
function traverseBranchIdAndDepthWidth(node, branch) {
  node.branch = branch;
  node.depthWidth = depthMaxSize[node.depth];
  if (node.children) {
    node.children.forEach(function(d) {
      traverseBranchIdAndDepthWidth(d, branch);
    });
  }
}

// Depth width = max width of nodes in depth
function traverseDepthSize(node) {
  var d = node.depth;
  var s = getLabelWidth(node);
  depthMaxSize[d] = (depthMaxSize[d] === undefined || depthMaxSize[d] < s) ? s : depthMaxSize[d];

  if (node.children) {
    node.children.forEach(function(n) {
      traverseDepthSize(n);
    });
  }
}

function Markmap(svg, data, options) {
  if (!(this instanceof Markmap)) return new Markmap(svg, data, options);
  this.init(svg, data, options);
}

var defaultPreset = {
  nodeHeight: 20,
  nodeWidth: 180,
  spacingVertical: 10,
  spacingHorizontal: 120,
  duration: 750,
  layout: 'tree',
  color: 'gray',
  linkShape: 'diagonal',
  renderer: 'boxed'
};

assign(Markmap.prototype, {
  getInitialState: function() {
    return {
      zoomScale: 1,
      zoomTranslate: [0, 0],
      autoFit: true
    };
  },
  presets: {
    'default': defaultPreset,
    'colorful': assign(assign({}, defaultPreset), {
      nodeHeight: 10,
      renderer: 'basic',
      color: 'category20'
    })
  },
  helperNames: ['layout', 'linkShape', 'color'],
  layouts: {
    tree: function() {
      return d3.layout.tree();
    }
  },
  linkShapes: {
    diagonal: function() {
      return d3.svg.diagonal()
        .projection(function(d) { return [d.y, d.x]; });
    },
    bracket: function() {
      return function(d) {
        return "M" + d.source.y + "," + d.source.x
            + "V" + d.target.x + "H" + d.target.y;
      };
    }
  },
  colors: assign(
    {gray: function() {return function() {return '#929292';}}},
    d3.scale
  ),
  init: function(svg, data, options) {
    options = options || {};

    svg = svg.datum ? svg : d3.select(svg);

    this.helpers = {};
    this.i = 0;
    var state = this.state = this.getInitialState();
    this.set(this.presets[options.preset || 'default']);
    state.height = svg.node().getBoundingClientRect().height;
    state.width = svg.node().getBoundingClientRect().width;
    this.set(options);

    // disable panning using right mouse button
    svg.on("mousedown", function() {
      var ev = d3.event;
      if (ev.button === 2) {
        ev.stopImmediatePropagation();
      }
    });

    var zoom = this.zoom = d3.behavior.zoom()
       .on("zoom", function() {
         this.updateZoom(d3.event.translate, d3.event.scale);
       }.bind(this));

    this.svg = svg
      .call(zoom)
      .append("g");

    this.updateZoom(state.zoomTranslate, state.zoomScale);

    this.setData(data);
    this.update(state.root);

    if (options.autoFit === undefined || options.autoFit === null) {
      state.autoFit = false;
    }
  },
  updateZoom: function(translate, scale) {
    var state = this.state;
    state.zoomTranslate = translate;
    state.zoomScale = scale;
    this.zoom.translate(state.zoomTranslate)
        .scale(state.zoomScale);
    this.svg.attr("transform", "translate(" + state.zoomTranslate + ")" + " scale(" + state.zoomScale + ")")
  },
  set: function(values) {
    if (values.preset) {
      this.set(this.presets[values.preset]);
    }
    var state = this.state;
    var helpers = this.helpers;
    this.helperNames.forEach(function(h) {
      if (!helpers[h] || (values[h] && values[h] !== state[h])) {
        helpers[h] = this[h+'s'][values[h] || state[h]]();
      }
    }.bind(this));
    assign(state, values || {});
    return this;
  },
  setData: function(data) {
    traverseDepthSize(data);

    data.depthWidth = depthMaxSize[data.depth];
    if (data.children) {
      data.children.forEach(function(d, i) {
        traverseBranchIdAndDepthWidth(d, i);
      });
    }

    var state = this.state;
    state.root = data;
    state.root.x0 = state.height / 2;
    state.root.y0 = 0;

    // function collapse(d) {
    //   if (d.children) {
    //     d._children = d.children;
    //     d._children.forEach(collapse);
    //     d.children = null;
    //   }
    // }
    //root.children.forEach(collapse);
    return this;
  },
  update: function(source) {
    var state = this.state;
    source = source || state.root;
    var res = this.layout(state);
    if (state.autoFit) {
      var minX = d3.min(res.nodes, function(d) {return d.x;});
      var minY = d3.min(res.nodes, function(d) {return d.y;});
      var maxX = d3.max(res.nodes, function(d) {return d.x;});
      var maxY = d3.max(res.nodes, function(d) {return d.y;});
      var realHeight = maxX - minX;
      var realWidth = maxY - minY + state.nodeWidth;
      var scale = Math.min(state.height / realHeight, state.width / realWidth, 1);
      var translate = [
        (state.width-realWidth*scale)/2-minY*scale,
        (state.height-realHeight*scale)/2-minX*scale
      ];
      this.updateZoom(translate, scale);
    }
    this.render(source, res.nodes, res.links);
    return this;
  },
  layout: function(state) {
    var layout = this.helpers.layout;

    var offset = state.root.x !== undefined ? state.root.x : state.root.x0;

    // Compute the new tree layout.
    var nodes = layout.nodes(state.root).reverse(),
        links = layout.links(nodes);

    // Normalize
    var ratio = (state.nodeHeight + state.spacingVertical) / traverseMinDistance(state.root);
    offset -= state.root.x * ratio;

    for (d in depthMaxSize) {
      var y = 0;
      for (var i = 1; i < parseInt(d); i++) {
        y += depthMaxSize[i] + state.spacingHorizontal;
      }
      yByDepth[d] = y;
    }

    nodes.forEach(function(d) {
      d.y = yByDepth[parseInt(d.depth)+1];
      d.x = d.x * ratio + offset;
    });

    //traverseLabelWidth(root, 0);

    return {
      nodes: nodes,
      links: links
    };
  },
  render: function(source, nodes, links) {
    this.renderers[this.state.renderer].call(this, source, nodes, links);
  },
  renderers: {
    boxed: function(source, nodes, links) {
      var svg = this.svg;
      var state = this.state;
      var color = this.helpers.color;
      this.renderers.basic.call(this, source, nodes, links);
      var node = svg.selectAll("g.markmap-node");

      node.select('rect')
        .attr("y", -state.nodeHeight/2)
        .attr('rx', 10)
        .attr('ry', 10)
        .attr('height', state.nodeHeight)
        .attr('fill', function(d) { return d3.rgb(color(d.branch)).brighter(1.2); })
        .attr('stroke', function(d) { return color(d.branch); })
        .attr('stroke-width', 1);

      node.select('text')
       .attr("dy", "3")

      svg.selectAll("path.markmap-link")
        .attr('stroke-width', 1);
    },
    basic: function(source, nodes, links) {
      var svg = this.svg;
      var state = this.state;
      var color = this.helpers.color;
      var linkShape = this.helpers.linkShape;

      function linkWidth(d) {
        var depth = d.depth;
        if (d.name !== '' && d.children && d.children.length === 1 && d.children[0].name === '') {
          depth += 1;
        }
        return Math.max(6 - 2*depth, 1.5);
      }

      // Update the nodes…
      var node = svg.selectAll("g.markmap-node")
          .data(nodes, function(d) { return d.id || (d.id = ++this.i); }.bind(this));

      // Enter any new nodes at the parent's previous position.
      var nodeEnter = node.enter().append("g")
          .attr("class", "markmap-node")
          .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
          .on("click", this.click.bind(this));

      nodeEnter.append('rect')
        .attr('class', 'markmap-node-rect')
        .attr("y", function(d) { return -linkWidth(d) / 2 })
        .attr('x', function(d) { return d.depthWidth; })
        .attr('width', 0)
        .attr('height', linkWidth)
        .attr('fill', function(d) { return color(d.branch); });

      nodeEnter.append("circle")
          .attr('class', 'markmap-node-circle')
          .attr('cx', function(d) { return d.depthWidth; })
          .attr('stroke', function(d) { return color(d.branch); })
          .attr("r", 1e-6)
          .style("fill", function(d) { return d._children ? color(d.branch) : ''; });

      nodeEnter.append("text")
          .attr('class', 'markmap-node-text')
          .attr("x", function(d) { return d.depthWidth; })
          .attr("dy", "-5")
          .attr("text-anchor", function(d) { return "start"; })
          .text(function(d) { return d.name; })
          .style("fill-opacity", 1e-6);

      // Transition nodes to their new position.
      var nodeUpdate = node.transition()
          .duration(state.duration)
          .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

      nodeUpdate.select('rect')
        .attr('x', -1)
        .attr('width', function(d) {
          // Make small length node has enough width
          return (d.children || d._children) ? d.depthWidth + 2 : getLabelWidth(d);
        });

      nodeUpdate.select("circle")
          .attr("r", 4.5)
          .style("fill", function(d) { return d._children ? color(d.branch) : ''; })
          .style('display', function(d) {
            var hasChildren = d.children || d._children;
            return hasChildren ?  'inline' : 'none';
          });

      nodeUpdate.select("text")
          .attr("x", 10)
          .style("fill-opacity", 1);

      // Transition exiting nodes to the parent's new position.
      var nodeExit = node.exit().transition()
          .duration(state.duration)
          .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
          .remove();

      nodeExit.select('rect')
        .attr('x', function(d) { return d.depthWidth; })
        .attr('width', 0);

      nodeExit.select("circle")
          .attr("r", 1e-6);

      nodeExit.select("text")
          .style("fill-opacity", 1e-6)
          .attr("x", function(d) { return d.depthWidth; });

      // Update the links…
      var link = svg.selectAll("path.markmap-link")
          .data(links, function(d) { return d.target.id; });

      // Enter any new links at the parent's previous position.
      link.enter().insert("path", "g")
          .attr("class", "markmap-link")
          .attr('stroke', function(d) { return color(d.target.branch); })
          .attr('stroke-width', function(l) {return linkWidth(l.target);})
          .attr("d", function(d) {
            var o = {x: source.x0, y: source.y0 + d.source.depthWidth};
            return linkShape({source: o, target: o});
          });

      // Transition links to their new position.
      link.transition()
          .duration(state.duration)
          .attr("d", function(d) {
            var s = {x: d.source.x, y: d.source.y + d.source.depthWidth};
            var t = {x: d.target.x, y: d.target.y};
            return linkShape({source: s, target: t});
          });

      // Transition exiting nodes to the parent's new position.
      link.exit().transition()
          .duration(state.duration)
          .attr("d", function(d) {
            var o = {x: source.x, y: source.y + d.source.depthWidth};
            return linkShape({source: o, target: o});
          })
          .remove();

      // Stash the old positions for transition.
      nodes.forEach(function(d) {
        d.x0 = d.x;
        d.y0 = d.y;
      });
    }
  },
  // Toggle children on click.
  click: function(d) {
    if (d.children) {
      d._children = d.children;
      d.children = null;
    } else {
      d.children = d._children;
      d._children = null;
    }
    this.update(d);
  }

});

return Markmap;

}));
<commit_msg>Move 2 global vars to state<commit_after>(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['d3'], factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory(require('d3'));
    } else {
        // Browser globals (root is window)
        root.markmap = factory(root.d3);
    }
}(this, function (d3) {

var assign = Object.assign || function(dst, src) {
  // poor man's Object.assign()
  for (var k in src) {
    if (src.hasOwnProperty(k)) {
      dst[k] = src[k];
    }
  }
  return dst;
};

function traverseMinDistance(node) {
  var val = Infinity;
  if (node.children) {
    val = Math.min.apply(null, node.children.map(traverseMinDistance));
    if (node.children.length > 1) {
      val = Math.min(val, Math.abs(node.children[0].x - node.children[1].x));
    }
  }
  return val;
}

function getLabelWidth(d) {
  // 5 per character and 25 bonus for rounded corner
  return d.name.length * 5 + 25;
}

function traverseLabelWidth(d, offset) {
  d.y += offset;
  if (d.name !== '' && d.children && d.children.length === 1 && d.children[0].name === '') {
    var child = d.children[0];
    offset += d.y + getLabelWidth(d) - child.y;
    child.y += offset;
    if (child.children) {
      child.children.forEach(function(c) {
        traverseLabelWidth(c, offset);
      });
    }
  }
}

// Set depth width to all nodes
function traverseBranchIdAndDepthWidth(node, branch, state) {
  node.branch = branch;
  node.depthWidth = state.depthMaxSize[node.depth];
  if (node.children) {
    node.children.forEach(function(d) {
      traverseBranchIdAndDepthWidth(d, branch, state);
    });
  }
}

// Depth width = max width of nodes in depth
function traverseDepthSize(node, state) {
  var d = node.depth;
  var s = getLabelWidth(node);
  state.depthMaxSize[d] = Math.max(state.depthMaxSize[d] || 0, s);

  if (node.children) {
    node.children.forEach(function(n) {
      traverseDepthSize(n, state);
    });
  }
}

function Markmap(svg, data, options) {
  if (!(this instanceof Markmap)) return new Markmap(svg, data, options);
  this.init(svg, data, options);
}

var defaultPreset = {
  nodeHeight: 20,
  nodeWidth: 180,
  spacingVertical: 10,
  spacingHorizontal: 120,
  duration: 750,
  layout: 'tree',
  color: 'gray',
  linkShape: 'diagonal',
  renderer: 'boxed'
};

assign(Markmap.prototype, {
  getInitialState: function() {
    return {
      zoomScale: 1,
      zoomTranslate: [0, 0],
      autoFit: true,
      depthMaxSize: {},
      yByDepth: {}
    };
  },
  presets: {
    'default': defaultPreset,
    'colorful': assign(assign({}, defaultPreset), {
      nodeHeight: 10,
      renderer: 'basic',
      color: 'category20'
    })
  },
  helperNames: ['layout', 'linkShape', 'color'],
  layouts: {
    tree: function() {
      return d3.layout.tree();
    }
  },
  linkShapes: {
    diagonal: function() {
      return d3.svg.diagonal()
        .projection(function(d) { return [d.y, d.x]; });
    },
    bracket: function() {
      return function(d) {
        return "M" + d.source.y + "," + d.source.x
            + "V" + d.target.x + "H" + d.target.y;
      };
    }
  },
  colors: assign(
    {gray: function() {return function() {return '#929292';}}},
    d3.scale
  ),
  init: function(svg, data, options) {
    options = options || {};

    svg = svg.datum ? svg : d3.select(svg);

    this.helpers = {};
    this.i = 0;
    var state = this.state = this.getInitialState();
    this.set(this.presets[options.preset || 'default']);
    state.height = svg.node().getBoundingClientRect().height;
    state.width = svg.node().getBoundingClientRect().width;
    this.set(options);

    // disable panning using right mouse button
    svg.on("mousedown", function() {
      var ev = d3.event;
      if (ev.button === 2) {
        ev.stopImmediatePropagation();
      }
    });

    var zoom = this.zoom = d3.behavior.zoom()
       .on("zoom", function() {
         this.updateZoom(d3.event.translate, d3.event.scale);
       }.bind(this));

    this.svg = svg
      .call(zoom)
      .append("g");

    this.updateZoom(state.zoomTranslate, state.zoomScale);

    this.setData(data);
    this.update(state.root);

    if (options.autoFit === undefined || options.autoFit === null) {
      state.autoFit = false;
    }
  },
  updateZoom: function(translate, scale) {
    var state = this.state;
    state.zoomTranslate = translate;
    state.zoomScale = scale;
    this.zoom.translate(state.zoomTranslate)
        .scale(state.zoomScale);
    this.svg.attr("transform", "translate(" + state.zoomTranslate + ")" + " scale(" + state.zoomScale + ")")
  },
  set: function(values) {
    if (values.preset) {
      this.set(this.presets[values.preset]);
    }
    var state = this.state;
    var helpers = this.helpers;
    this.helperNames.forEach(function(h) {
      if (!helpers[h] || (values[h] && values[h] !== state[h])) {
        helpers[h] = this[h+'s'][values[h] || state[h]]();
      }
    }.bind(this));
    assign(state, values || {});
    return this;
  },
  setData: function(data) {
    var state = this.state;
    traverseDepthSize(data, state);

    data.depthWidth = state.depthMaxSize[data.depth];
    if (data.children) {
      data.children.forEach(function(d, i) {
        traverseBranchIdAndDepthWidth(d, i, state);
      });
    }

    var state = this.state;
    state.root = data;
    state.root.x0 = state.height / 2;
    state.root.y0 = 0;

    // function collapse(d) {
    //   if (d.children) {
    //     d._children = d.children;
    //     d._children.forEach(collapse);
    //     d.children = null;
    //   }
    // }
    //root.children.forEach(collapse);
    return this;
  },
  update: function(source) {
    var state = this.state;
    source = source || state.root;
    var res = this.layout(state);
    if (state.autoFit) {
      var minX = d3.min(res.nodes, function(d) {return d.x;});
      var minY = d3.min(res.nodes, function(d) {return d.y;});
      var maxX = d3.max(res.nodes, function(d) {return d.x;});
      var maxY = d3.max(res.nodes, function(d) {return d.y;});
      var realHeight = maxX - minX;
      var realWidth = maxY - minY + state.nodeWidth;
      var scale = Math.min(state.height / realHeight, state.width / realWidth, 1);
      var translate = [
        (state.width-realWidth*scale)/2-minY*scale,
        (state.height-realHeight*scale)/2-minX*scale
      ];
      this.updateZoom(translate, scale);
    }
    this.render(source, res.nodes, res.links);
    return this;
  },
  layout: function(state) {
    var layout = this.helpers.layout;

    var offset = state.root.x !== undefined ? state.root.x : state.root.x0;

    // Compute the new tree layout.
    var nodes = layout.nodes(state.root).reverse(),
        links = layout.links(nodes);

    // Normalize
    var ratio = (state.nodeHeight + state.spacingVertical) / traverseMinDistance(state.root);
    offset -= state.root.x * ratio;

    for (d in state.depthMaxSize) {
      var y = 0;
      for (var i = 1; i < parseInt(d); i++) {
        y += state.depthMaxSize[i] + state.spacingHorizontal;
      }
      state.yByDepth[d] = y;
    }

    nodes.forEach(function(d) {
      d.y = state.yByDepth[parseInt(d.depth)+1];
      d.x = d.x * ratio + offset;
    });

    //traverseLabelWidth(root, 0);

    return {
      nodes: nodes,
      links: links
    };
  },
  render: function(source, nodes, links) {
    this.renderers[this.state.renderer].call(this, source, nodes, links);
  },
  renderers: {
    boxed: function(source, nodes, links) {
      var svg = this.svg;
      var state = this.state;
      var color = this.helpers.color;
      this.renderers.basic.call(this, source, nodes, links);
      var node = svg.selectAll("g.markmap-node");

      node.select('rect')
        .attr("y", -state.nodeHeight/2)
        .attr('rx', 10)
        .attr('ry', 10)
        .attr('height', state.nodeHeight)
        .attr('fill', function(d) { return d3.rgb(color(d.branch)).brighter(1.2); })
        .attr('stroke', function(d) { return color(d.branch); })
        .attr('stroke-width', 1);

      node.select('text')
       .attr("dy", "3")

      svg.selectAll("path.markmap-link")
        .attr('stroke-width', 1);
    },
    basic: function(source, nodes, links) {
      var svg = this.svg;
      var state = this.state;
      var color = this.helpers.color;
      var linkShape = this.helpers.linkShape;

      function linkWidth(d) {
        var depth = d.depth;
        if (d.name !== '' && d.children && d.children.length === 1 && d.children[0].name === '') {
          depth += 1;
        }
        return Math.max(6 - 2*depth, 1.5);
      }

      // Update the nodes…
      var node = svg.selectAll("g.markmap-node")
          .data(nodes, function(d) { return d.id || (d.id = ++this.i); }.bind(this));

      // Enter any new nodes at the parent's previous position.
      var nodeEnter = node.enter().append("g")
          .attr("class", "markmap-node")
          .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
          .on("click", this.click.bind(this));

      nodeEnter.append('rect')
        .attr('class', 'markmap-node-rect')
        .attr("y", function(d) { return -linkWidth(d) / 2 })
        .attr('x', function(d) { return d.depthWidth; })
        .attr('width', 0)
        .attr('height', linkWidth)
        .attr('fill', function(d) { return color(d.branch); });

      nodeEnter.append("circle")
          .attr('class', 'markmap-node-circle')
          .attr('cx', function(d) { return d.depthWidth; })
          .attr('stroke', function(d) { return color(d.branch); })
          .attr("r", 1e-6)
          .style("fill", function(d) { return d._children ? color(d.branch) : ''; });

      nodeEnter.append("text")
          .attr('class', 'markmap-node-text')
          .attr("x", function(d) { return d.depthWidth; })
          .attr("dy", "-5")
          .attr("text-anchor", function(d) { return "start"; })
          .text(function(d) { return d.name; })
          .style("fill-opacity", 1e-6);

      // Transition nodes to their new position.
      var nodeUpdate = node.transition()
          .duration(state.duration)
          .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

      nodeUpdate.select('rect')
        .attr('x', -1)
        .attr('width', function(d) {
          // Make small length node has enough width
          return (d.children || d._children) ? d.depthWidth + 2 : getLabelWidth(d);
        });

      nodeUpdate.select("circle")
          .attr("r", 4.5)
          .style("fill", function(d) { return d._children ? color(d.branch) : ''; })
          .style('display', function(d) {
            var hasChildren = d.children || d._children;
            return hasChildren ?  'inline' : 'none';
          });

      nodeUpdate.select("text")
          .attr("x", 10)
          .style("fill-opacity", 1);

      // Transition exiting nodes to the parent's new position.
      var nodeExit = node.exit().transition()
          .duration(state.duration)
          .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
          .remove();

      nodeExit.select('rect')
        .attr('x', function(d) { return d.depthWidth; })
        .attr('width', 0);

      nodeExit.select("circle")
          .attr("r", 1e-6);

      nodeExit.select("text")
          .style("fill-opacity", 1e-6)
          .attr("x", function(d) { return d.depthWidth; });

      // Update the links…
      var link = svg.selectAll("path.markmap-link")
          .data(links, function(d) { return d.target.id; });

      // Enter any new links at the parent's previous position.
      link.enter().insert("path", "g")
          .attr("class", "markmap-link")
          .attr('stroke', function(d) { return color(d.target.branch); })
          .attr('stroke-width', function(l) {return linkWidth(l.target);})
          .attr("d", function(d) {
            var o = {x: source.x0, y: source.y0 + d.source.depthWidth};
            return linkShape({source: o, target: o});
          });

      // Transition links to their new position.
      link.transition()
          .duration(state.duration)
          .attr("d", function(d) {
            var s = {x: d.source.x, y: d.source.y + d.source.depthWidth};
            var t = {x: d.target.x, y: d.target.y};
            return linkShape({source: s, target: t});
          });

      // Transition exiting nodes to the parent's new position.
      link.exit().transition()
          .duration(state.duration)
          .attr("d", function(d) {
            var o = {x: source.x, y: source.y + d.source.depthWidth};
            return linkShape({source: o, target: o});
          })
          .remove();

      // Stash the old positions for transition.
      nodes.forEach(function(d) {
        d.x0 = d.x;
        d.y0 = d.y;
      });
    }
  },
  // Toggle children on click.
  click: function(d) {
    if (d.children) {
      d._children = d.children;
      d.children = null;
    } else {
      d.children = d._children;
      d._children = null;
    }
    this.update(d);
  }

});

return Markmap;

}));
<|endoftext|>


<commit_before>/**
 * The base HudItem that represents an element of a hud on the screen.
 *
 * @module gf
 * @class HudItem
 * @extends GuiItem
 * @constructor
 * @param pos {Array|Vector|Point} The starting position of the sprite
 * @param settings {Object} Settings to override the defauls
 */
gf.HudItem = function(pos, settings) {
    /**
     * The value of the item
     *
     * @property name
     * @type Mixed
     * @default ''
     */
    this.value = '';

    /**
     * Sets whether or not you can drag the HudItem around
     *
     * @property draggable
     * @type Boolean
     * @default false
     */
    this.draggable = false;

    /**
     * [read only] Describes if the current item is being dragged or not
     *
     * @property dragging
     * @type Boolean
     * @default false
     * @readOnly
     */
    this.dragging = false;

    /**
     * The font to use for text
     *
     * @property font
     * @type Font
     */
    this.font = null;

    gf.GuiItem.call(this, pos, settings);

    /**
     * The initial value of the item to reset to
     *
     * @property initialValue
     * @type Mixed
     */
    this.initialValue = this.value;

    if(this.font instanceof gf.Font)
        this.addChild(this.font);
    else {
        this.font = new gf.Font();
        this.addChild(this.font);
    }

    this.sprites = new gf.ObjectPool(PIXI.Sprite, this);
};

gf.inherits(gf.HudItem, gf.GuiItem, {
    /**
     * Resets the value to the initialValue
     *
     * @method reset
     * @return {HudItem} Returns itself for chainability
     */
    reset: function() {
        return this.set(this.initialValue);
    },
    /**
     * Sets the value of the item
     *
     * @method set
     * @return {HudItem} Returns itself for chainability
     */
    set: function(val) {
        this.font.setText(val);
        this.value = val;
        return this;
    },

    onDragStart: function() {},
    onDragEnd: function() {},

    click: function() {},
    mousedown: function(e) {
        if(!this.draggable) return;

        this.dragging = {
            x: e.clientX,
            y: e.clientY
        };
        this.onDragStart(e);
    },
    mouseup: function(e) {
        this.dragging = false;
        this.onDragEnd(e);
    },
    mousemove: function(e) {
        if(!this.draggable || !this.dragging) return;

        var diffX = e.clientX - this.dragging.x,
            diffY = e.clientY - this.dragging.y,
            pos = gf.utils.getPosition(this.elm);

        this.dragging.x = e.clientX;
        this.dragging.y = e.clientY;

        this.elm.style.top = pos.top + diffY;
        this.elm.style.left = pos.left + diffX;
    }
});
<commit_msg>do an initial set in ctor<commit_after>/**
 * The base HudItem that represents an element of a hud on the screen.
 *
 * @module gf
 * @class HudItem
 * @extends GuiItem
 * @constructor
 * @param pos {Array|Vector|Point} The starting position of the sprite
 * @param settings {Object} Settings to override the defauls
 */
gf.HudItem = function(pos, settings) {
    /**
     * The value of the item
     *
     * @property name
     * @type Mixed
     * @default ''
     */
    this.value = '';

    /**
     * Sets whether or not you can drag the HudItem around
     *
     * @property draggable
     * @type Boolean
     * @default false
     */
    this.draggable = false;

    /**
     * [read only] Describes if the current item is being dragged or not
     *
     * @property dragging
     * @type Boolean
     * @default false
     * @readOnly
     */
    this.dragging = false;

    /**
     * The font to use for text
     *
     * @property font
     * @type Font
     */
    this.font = null;

    gf.GuiItem.call(this, pos, settings);

    /**
     * The initial value of the item to reset to
     *
     * @property initialValue
     * @type Mixed
     */
    this.initialValue = this.value;

    if(this.font instanceof gf.Font)
        this.addChild(this.font);
    else {
        this.font = new gf.Font();
        this.addChild(this.font);
    }

    this.sprites = new gf.ObjectPool(PIXI.Sprite, this);
    this.set(this.value);
};

gf.inherits(gf.HudItem, gf.GuiItem, {
    /**
     * Resets the value to the initialValue
     *
     * @method reset
     * @return {HudItem} Returns itself for chainability
     */
    reset: function() {
        return this.set(this.initialValue);
    },
    /**
     * Sets the value of the item
     *
     * @method set
     * @return {HudItem} Returns itself for chainability
     */
    set: function(val) {
        this.font.setText(val);
        this.value = val;
        return this;
    },

    onDragStart: function() {},
    onDragEnd: function() {},

    click: function() {},
    mousedown: function(e) {
        if(!this.draggable) return;

        this.dragging = {
            x: e.clientX,
            y: e.clientY
        };
        this.onDragStart(e);
    },
    mouseup: function(e) {
        this.dragging = false;
        this.onDragEnd(e);
    },
    mousemove: function(e) {
        if(!this.draggable || !this.dragging) return;

        var diffX = e.clientX - this.dragging.x,
            diffY = e.clientY - this.dragging.y,
            pos = gf.utils.getPosition(this.elm);

        this.dragging.x = e.clientX;
        this.dragging.y = e.clientY;

        this.elm.style.top = pos.top + diffY;
        this.elm.style.left = pos.left + diffX;
    }
});
<|endoftext|>


<commit_before>import {PluginError} from 'gulp-util';
import through from 'through2';
import {spawn} from 'child_process';
import childProcessData from 'child-process-data';

const PLUGIN_NAME = 'gulp-antlr4';

export default function (_outputDir) {
  const outputDir = _outputDir && _outputDir.output || _outputDir;

  if (typeof outputDir !== 'string') {
    throw new PluginError(PLUGIN_NAME,
      new TypeError(`Requires a proper output option`));
  }

  const CLASSPATH = process.env.CLASSPATH;

  if (!CLASSPATH) {
    throw new PluginError(PLUGIN_NAME,
      new ReferenceError(`$CLASSPATH is not defined`));
  }

  const matchJar = CLASSPATH.match(
    /.*:((\d|\w|\/|-|_|\.|\~)+antlr-\d+\.\d+-complete\.jar):.*/);

  if (matchJar === null) {
    throw new PluginError(PLUGIN_NAME,
      new ReferenceError(`Cannot find ANTLR jar file`));
  }

  return through.obj(function (file, encoding, callback) {
    if (file.isNull()) {
      return callback(null, file);
    }

    if (file.isStream()) {
      this.emit('error', new PluginError(PLUGIN_NAME,
        'Streams not supported!'));
    } else if (file.isBuffer()) {
      childProcessData(spawn('java', ['org.antlr.v4.Tool',
        '-Dlanguage=JavaScript', '-o', outputDir, file.history[0]]))
      .then(() => {
        callback(null, file);
      }, err => {
        this.emit('error', new PluginError(PLUGIN_NAME,
          new Error(err)));
      });
    }
  });
}
<commit_msg>Generate parser only for g4 files<commit_after>import {PluginError} from 'gulp-util';
import through from 'through2';
import path from 'path';
import {spawn} from 'child_process';
import childProcessData from 'child-process-data';

const PLUGIN_NAME = 'gulp-antlr4';

export default function (_antlrDir) {
  const antlrDir = _antlrDir && _antlrDir.dir || _antlrDir;

  if (typeof antlrDir !== 'string') {
    throw new PluginError(PLUGIN_NAME,
      new TypeError(`You must provide the directory where to write or read
     the generated lexing and parsing tools (option 'dir')`));
  }

  const CLASSPATH = process.env.CLASSPATH;

  if (!CLASSPATH) {
    throw new PluginError(PLUGIN_NAME,
      new ReferenceError(`Environment variable CLASSPATH is not defined`));
  }

  // Not matching '~' as it is not understood by Java anyway
  const matchJar = CLASSPATH.match(
    /.*:((\d|\w|\/|-|_|\.)+antlr-\d+\.\d+-complete\.jar):.*/);

  if (matchJar === null) {
    throw new PluginError(PLUGIN_NAME,
      new ReferenceError(`Cannot find ANTLR 4 .jar file`));
  }

  return through.obj(function (file, encoding, callback) {
    if (file.isNull()) {
      return callback(null, file);
    }

    if (file.isStream()) {
      this.emit('error', new PluginError(PLUGIN_NAME,
        'Streams not supported!'));
    } else if (file.isBuffer()) {
      const inputFile = file.history[0];

      switch (path.extname(inputFile)) {
      case '.g4':
        return childProcessData(spawn('java', ['org.antlr.v4.Tool',
          '-Dlanguage=JavaScript', '-o', antlrDir, inputFile]))
        .then(() => {
          callback(null, file);
        }, err => {
          this.emit('error', new PluginError(PLUGIN_NAME,
            new Error(err)));
        });

      default:
        return callback(null, file);
      }
    }
  });
}
<|endoftext|>


<commit_before>import makeDebug from 'debug';
import fp from 'mostly-func';
import { isSelected, selectNext, selectTail, splitHead } from '../helpers';

const debug = makeDebug('mostly:feathers-mongoose:hooks:assoc');

const defaultOptions = {
  idField: 'id'
};

// associcate current data as a foreign key to another service
export default function assoc(target, opts) {
  opts = Object.assign({}, defaultOptions, opts);

  return function(hook) {
    let options = Object.assign({}, opts);

    if (hook.type !== 'after') {
      throw new Error(`The 'assoc' hook should only be used as a 'after' hook.`);
    }

    if (!options.service || !options.field) {
      throw new Error('You need to provide a service and a field');
    }

    const assocField = function (data, params, target) {
      const service = hook.app.service(options.service);

      // pass infomation of the $select and specified by options.fallThrough
      const selection = { $select: params.query.$select };
      params = options.fallThrough
        ? fp.pick(options.fallThrough, params)
        : {};
      params.query = selection;

      if (Array.isArray(data)) {
        params.query = fp.merge(params.query, {
          [options.field]: { $in: fp.map(fp.prop(options.idField), data) },
        });
      } else {
        params.query = fp.merge(params.query, {
          [options.field]: fp.prop(options.idField, data)
        });
      }
      params.populate = false; // prevent recursive populate
      params.paginate = false; // disable paginate

      debug('assoc =>', target, options.service, params.query);

      return service.find(params).then((results) => {
        const filterById = function (id) {
          return fp.filter(obj => {
            let prop = Array.concat([], obj[options.field] || []);
            prop = fp.map(fp.toString, prop); // convert ObjectId
            return prop.indexOf(id) >= 0;
          });
        };
        const assocResult = function (results) {
          return fp.map((item) => {
            let values = filterById(item[options.idField])(results);
            if (values) {
              return fp.assoc(target, values, item);
            }
            return item;
          });
        };
        results = results && results.data || results;
        if (Array.isArray(data)) {
          return assocResult(results)(data);
        } else {
          return fp.assoc(target, results, data);
        }
      });
    };

    let data = hook.result && hook.result.data || hook.result;

    if (fp.isNil(data) || fp.isEmpty(data)) return hook;

    // each assoc field should have its own params
    let params = fp.assign({ query: {} }, hook.params);

    // target must be specified by $select to assoc
    if (!isSelected(target, params.query.$select)) return hook;

    // $select with * for next level
    if (params.query.$select) {
      params.query.$select = selectNext(target, params.query.$select);
    }

    return assocField(data, params, target, options).then(result => {
      if (hook.result.data) {
        hook.result.data = result;
      } else {
        hook.result = result;
      }
      return hook;
    });
  };
}

<commit_msg>assoc with filter/sort/limit<commit_after>import makeDebug from 'debug';
import fp from 'mostly-func';
import { isSelected, selectNext, selectTail, splitHead } from '../helpers';

const debug = makeDebug('mostly:feathers-mongoose:hooks:assoc');

const defaultOptions = {
  idField: 'id'
};

// associcate current data as a foreign key to another service
export default function assoc(target, opts) {
  opts = Object.assign({}, defaultOptions, opts);

  return function(hook) {
    let options = Object.assign({}, opts);

    if (hook.type !== 'after') {
      throw new Error(`The 'assoc' hook should only be used as a 'after' hook.`);
    }

    if (!options.service || !options.field) {
      throw new Error('You need to provide a service and a field');
    }

    const assocField = function (data, params, target) {
      const service = hook.app.service(options.service);

      // pass infomation of the $select and specified by options.fallThrough
      const selection = { $select: params.query.$select };
      params = options.fallThrough
        ? fp.pick(options.fallThrough, params)
        : {};
      params.query = selection;

      if (Array.isArray(data)) {
        params.query = fp.merge(params.query, {
          [options.field]: { $in: fp.map(fp.prop(options.idField), data) },
        });
      } else {
        params.query = fp.merge(params.query, {
          [options.field]: fp.prop(options.idField, data)
        });
      }
      params.populate = false; // prevent recursive populate
      params.paginate = false; // disable paginate

      // filter
      if (options.filters && options.filters.length > 0) {
        for (const filter of options.filters) {
          if (filter.field && filter.value) {
            const value = typeof filter.value === 'function'
              ? filter.value.call(null, hook) : filter.value;
            params.query[filter.field] = Array.isArray(value)? { $in: value } : value;
          }
        }
      }
      // sort
      if (options.sort) {
        params.query.$sort = options.sort;
      }
      // limit
      if (options.limit) {
        params.query.$limit = options.limit;
      }

      debug('assoc =>', target, options.service, params.query);

      return service.find(params).then((results) => {
        const filterById = function (id) {
          return fp.filter(obj => {
            let prop = Array.concat([], obj[options.field] || []);
            prop = fp.map(fp.toString, prop); // convert ObjectId
            return prop.indexOf(id) >= 0;
          });
        };
        const assocResult = function (results) {
          return fp.map((item) => {
            let values = filterById(item[options.idField])(results);
            if (values) {
              return fp.assoc(target, values, item);
            }
            return item;
          });
        };
        results = results && results.data || results;
        if (Array.isArray(data)) {
          return assocResult(results)(data);
        } else {
          return fp.assoc(target, results, data);
        }
      });
    };

    let data = hook.result && hook.result.data || hook.result;

    if (fp.isNil(data) || fp.isEmpty(data)) return hook;

    // each assoc field should have its own params
    let params = fp.assign({ query: {} }, hook.params);

    // target must be specified by $select to assoc
    if (!isSelected(target, params.query.$select)) return hook;

    // $select with * for next level
    if (params.query.$select) {
      params.query.$select = selectNext(target, params.query.$select);
    }

    return assocField(data, params, target, options).then(result => {
      if (hook.result.data) {
        hook.result.data = result;
      } else {
        hook.result = result;
      }
      return hook;
    });
  };
}

<|endoftext|>


<commit_before>import api from './../api';
import moment from 'moment';
import db from '../data/database';

const { getSyncToken, setSyncToken } = require('../api/utilities/token');

export async function handleCalendarWebhook(headers) {
  // headers not used
  const syncToken = await getSyncToken(headers);
  const response = await api({
    action: 'calendarListDelta',
    syncToken,
  });

  const { items: changes, nextSyncToken } = response;

  changes.forEach(item => {
    if (item.status === 'cancelled') {
      handleCancel(item);
    } else if (item.status === 'confirmed') {
      handleUpsert(item);
    } else {
      console.log(`unhandled status-${item.id}`);
    }
  });

  // save only when there is nextSyncToken otherwise it screws others
  if (nextSyncToken) {
    await setSyncToken({
      syncToken: nextSyncToken,
      lastUpdated: moment(),
    });
  }

  console.log(changes);
}

async function handleCancel(item) {
  await db.remove(`event:${item.id}`);
}

async function handleUpsert(item) {
  if (item.id.indexOf('_') !== 0) {
    await db.upsert(`event:${item.id}`, item);
  } else {
    console.log(`item.id =${item.id} ignored`);
  }
}

const functionToCall = {
  cancelled: handleCancel,
  confirmed: handleUpsert,
};

export default handleCalendarWebhook;
<commit_msg>cannot ignore old appointments<commit_after>import api from './../api';
import moment from 'moment';
import db from '../data/database';

const { getSyncToken, setSyncToken } = require('../api/utilities/token');

export async function handleCalendarWebhook(headers) {
  // headers not used
  const syncToken = await getSyncToken(headers);
  const response = await api({
    action: 'calendarListDelta',
    syncToken,
  });

  const { items: changes, nextSyncToken } = response;

  changes.forEach(item => {
    if (item.status === 'cancelled') {
      handleCancel(item);
    } else if (item.status === 'confirmed') {
      handleUpsert(item);
    } else {
      console.log(`unhandled status-${item.id}`);
    }
  });

  // save only when there is nextSyncToken otherwise it screws others
  if (nextSyncToken) {
    await setSyncToken({
      syncToken: nextSyncToken,
      lastUpdated: moment(),
    });
  }

  console.log(changes);
}

async function handleCancel(item) {
  await db.remove(`event:${item.id}`);
}

async function handleUpsert(item) {
  if (item.creator.email === 'rarebeauty@soho.sg') {
    console.log('-----THIS APPOINTMENT NOT CREATED BY THE APP---');
    console,log(item);
    return;
  }
  await db.upsert(`event:${item.id}`, item);
}

const functionToCall = {
  cancelled: handleCancel,
  confirmed: handleUpsert,
};

export default handleCalendarWebhook;
<|endoftext|>


<commit_before>'use strict';

angular.module('classBrowserUHApp.offeredclass', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/offeredclass', {
        templateUrl: 'views/offeredclass/offeredclass.html',
        controller: 'OfferedClassCtrl'
    });
}])

.controller('OfferedClassCtrl', ['$scope', '$http', '$q', '$rootScope', function ($scope, $http, $q, $rootScope) {

    $rootScope.httpService.getData('resources/format.json').then(function(result) {
        $scope.format = result;
    });

    $rootScope.httpService.getData('resources/terms.json').then(function(result) {
        $scope.terms = result;
    });

    $rootScope.httpService.getData('resources/status.json').then(function(result) {
        $scope.status = result;
    });

    $rootScope.httpService.getData('resources/session.json').then(function(result) {
        $scope.session = result;
    });
}]);<commit_msg>Added departments/subjects.<commit_after>'use strict';

angular.module('classBrowserUHApp.offeredclass', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/offeredclass', {
        templateUrl: 'views/offeredclass/offeredclass.html',
        controller: 'OfferedClassCtrl'
    });
}])

.controller('OfferedClassCtrl', ['$scope', '$http', '$q', '$rootScope', function ($scope, $http, $q, $rootScope) {

    $rootScope.httpService.getData('resources/format.json').then(function(result) {
        $scope.format = result;
    });

    $rootScope.httpService.getData('resources/terms.json').then(function(result) {
        $scope.terms = result;
    });

    $rootScope.httpService.getData('resources/status.json').then(function(result) {
        $scope.status = result;
    });

    $rootScope.httpService.getData('resources/session.json').then(function(result) {
        $scope.session = result;
    });

    $rootScope.httpService.getData('resources/subjects.json').then(function(result) {
        $scope.departments = result;
    });
}]);<|endoftext|>


<commit_before>import {HttpClientConfiguration} from './http-client-configuration';
import {RequestInit, Interceptor} from './interfaces';

/**
* An HTTP client based on the Fetch API.
*/
export class HttpClient {
  /**
  * The current number of active requests.
  * Requests being processed by interceptors are considered active.
  */
  activeRequestCount: number = 0;

  /**
  * Indicates whether or not the client is currently making one or more requests.
  */
  isRequesting: boolean = false;

  /**
  * Indicates whether or not the client has been configured.
  */
  isConfigured: boolean = false;

  /**
  * The base URL set by the config.
  */
  baseUrl: string = '';

  /**
  * The default request init to merge with values specified at request time.
  */
  defaults: RequestInit = null;

  /**
  * The interceptors to be run during requests.
  */
  interceptors: Interceptor[] = [];

  /**
  * Creates an instance of HttpClient.
  */
  constructor() {
    if (typeof fetch === 'undefined') {
      throw new Error('HttpClient requires a Fetch API implementation, but the current environment doesn\'t support it. You may need to load a polyfill such as https://github.com/github/fetch');
    }
  }

  /**
  * Configure this client with default settings to be used by all requests.
  *
  * @param config A configuration object, or a function that takes a config
  * object and configures it.
  * @returns The chainable instance of this HttpClient.
  * @chainable
  */
  configure(config: RequestInit|(config: HttpClientConfiguration) => void|HttpClientConfiguration): HttpClient {
    let normalizedConfig;

    if (typeof config === 'object') {
      normalizedConfig = { defaults: config };
    } else if (typeof config === 'function') {
      normalizedConfig = new HttpClientConfiguration();
      normalizedConfig.baseUrl = this.baseUrl;
      normalizedConfig.defaults = Object.assign({}, this.defaults);
      normalizedConfig.interceptors = this.interceptors;

      let c = config(normalizedConfig);
      if (HttpClientConfiguration.prototype.isPrototypeOf(c)) {
        normalizedConfig = c;
      }
    } else {
      throw new Error('invalid config');
    }

    let defaults = normalizedConfig.defaults;
    if (defaults && Headers.prototype.isPrototypeOf(defaults.headers)) {
      // Headers instances are not iterable in all browsers. Require a plain
      // object here to allow default headers to be merged into request headers.
      throw new Error('Default headers must be a plain object.');
    }

    this.baseUrl = normalizedConfig.baseUrl;
    this.defaults = defaults;
    this.interceptors = normalizedConfig.interceptors || [];
    this.isConfigured = true;

    return this;
  }

  /**
  * Starts the process of fetching a resource. Default configuration parameters
  * will be applied to the Request. The constructed Request will be passed to
  * registered request interceptors before being sent. The Response will be passed
  * to registered Response interceptors before it is returned.
  *
  * See also https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
  *
  * @param input The resource that you wish to fetch. Either a
  * Request object, or a string containing the URL of the resource.
  * @param init An options object containing settings to be applied to
  * the Request.
  * @returns A Promise for the Response from the fetch request.
  */
  fetch(input: Request|string, init?: RequestInit): Promise<Response> {
    this::trackRequestStart();

    let request = Promise.resolve().then(() => this::buildRequest(input, init, this.defaults));
    let promise = processRequest(request, this.interceptors)
      .then(result => {
        let response = null;

        if (Response.prototype.isPrototypeOf(result)) {
          response = result;
        } else if (Request.prototype.isPrototypeOf(result)) {
          request = Promise.resolve(result);
          response = fetch(result);
        } else {
          throw new Error(`An invalid result was returned by the interceptor chain. Expected a Request or Response instance, but got [${result}]`);
        }

        return request.then(_request => processResponse(response, this.interceptors, _request));
      });

    return this::trackRequestEndWith(promise);
  }
}

const absoluteUrlRegexp = /^([a-z][a-z0-9+\-.]*:)?\/\//i;

function trackRequestStart() {
  this.isRequesting = !!(++this.activeRequestCount);
}

function trackRequestEnd() {
  this.isRequesting = !!(--this.activeRequestCount);
}

function trackRequestEndWith(promise) {
  let handle = this::trackRequestEnd;
  promise.then(handle, handle);
  return promise;
}

function parseHeaderValues(headers) {
  let parsedHeaders = {};
  for (let name in headers || {}) {
    if (headers.hasOwnProperty(name)) {
      parsedHeaders[name] = (typeof headers[name] === 'function') ? headers[name]() : headers[name];
    }
  }
  return parsedHeaders;
}

function buildRequest(input, init) {
  let defaults = this.defaults || {};
  let request;
  let body;
  let requestContentType;

  let parsedDefaultHeaders = parseHeaderValues(defaults.headers);
  if (Request.prototype.isPrototypeOf(input)) {
    request = input;
    requestContentType = new Headers(request.headers).get('Content-Type');
  } else {
    init || (init = {});
    body = init.body;
    let bodyObj = body ? { body } : null;
    let requestInit = Object.assign({}, defaults, { headers: {} }, init, bodyObj);
    requestContentType = new Headers(requestInit.headers).get('Content-Type');
    request = new Request(getRequestUrl(this.baseUrl, input), requestInit);
  }
  if (!requestContentType) {
    if (new Headers(parsedDefaultHeaders).has('content-type')) {
      request.headers.set('Content-Type', new Headers(parsedDefaultHeaders).get('content-type'));
    } else if (body && isJSON(body)) {
      request.headers.set('Content-Type', 'application/json');
    }
  }
  setDefaultHeaders(request.headers, parsedDefaultHeaders);
  if (body && Blob.prototype.isPrototypeOf(body) && body.type) {
    // work around bug in IE & Edge where the Blob type is ignored in the request
    // https://connect.microsoft.com/IE/feedback/details/2136163
    request.headers.set('Content-Type', body.type);
  }
  return request;
}

function getRequestUrl(baseUrl, url) {
  if (absoluteUrlRegexp.test(url)) {
    return url;
  }

  return (baseUrl || '') + url;
}

function setDefaultHeaders(headers, defaultHeaders) {
  for (let name in defaultHeaders || {}) {
    if (defaultHeaders.hasOwnProperty(name) && !headers.has(name)) {
      headers.set(name, defaultHeaders[name]);
    }
  }
}

function processRequest(request, interceptors) {
  return applyInterceptors(request, interceptors, 'request', 'requestError');
}

function processResponse(response, interceptors, request) {
  return applyInterceptors(response, interceptors, 'response', 'responseError', request);
}

function applyInterceptors(input, interceptors, successName, errorName, ...interceptorArgs) {
  return (interceptors || [])
    .reduce((chain, interceptor) => {
      let successHandler = interceptor[successName];
      let errorHandler = interceptor[errorName];

      return chain.then(
        successHandler && (value => interceptor::successHandler(value, ...interceptorArgs)) || identity,
        errorHandler && (reason => interceptor::errorHandler(reason, ...interceptorArgs)) || thrower);
    }, Promise.resolve(input));
}

function isJSON(str) {
  try {
    JSON.parse(str);
  }
  catch (err) {
    return false;
  }
  return true;
}

function identity(x) {
  return x;
}

function thrower(x) {
  throw x;
}
<commit_msg>feat(http-client): Expose HttpClient to interceptors<commit_after>import {HttpClientConfiguration} from './http-client-configuration';
import {RequestInit, Interceptor} from './interfaces';

/**
* An HTTP client based on the Fetch API.
*/
export class HttpClient {
  /**
  * The current number of active requests.
  * Requests being processed by interceptors are considered active.
  */
  activeRequestCount: number = 0;

  /**
  * Indicates whether or not the client is currently making one or more requests.
  */
  isRequesting: boolean = false;

  /**
  * Indicates whether or not the client has been configured.
  */
  isConfigured: boolean = false;

  /**
  * The base URL set by the config.
  */
  baseUrl: string = '';

  /**
  * The default request init to merge with values specified at request time.
  */
  defaults: RequestInit = null;

  /**
  * The interceptors to be run during requests.
  */
  interceptors: Interceptor[] = [];

  /**
  * Creates an instance of HttpClient.
  */
  constructor() {
    if (typeof fetch === 'undefined') {
      throw new Error('HttpClient requires a Fetch API implementation, but the current environment doesn\'t support it. You may need to load a polyfill such as https://github.com/github/fetch');
    }
  }

  /**
  * Configure this client with default settings to be used by all requests.
  *
  * @param config A configuration object, or a function that takes a config
  * object and configures it.
  * @returns The chainable instance of this HttpClient.
  * @chainable
  */
  configure(config: RequestInit|(config: HttpClientConfiguration) => void|HttpClientConfiguration): HttpClient {
    let normalizedConfig;

    if (typeof config === 'object') {
      normalizedConfig = { defaults: config };
    } else if (typeof config === 'function') {
      normalizedConfig = new HttpClientConfiguration();
      normalizedConfig.baseUrl = this.baseUrl;
      normalizedConfig.defaults = Object.assign({}, this.defaults);
      normalizedConfig.interceptors = this.interceptors;

      let c = config(normalizedConfig);
      if (HttpClientConfiguration.prototype.isPrototypeOf(c)) {
        normalizedConfig = c;
      }
    } else {
      throw new Error('invalid config');
    }

    let defaults = normalizedConfig.defaults;
    if (defaults && Headers.prototype.isPrototypeOf(defaults.headers)) {
      // Headers instances are not iterable in all browsers. Require a plain
      // object here to allow default headers to be merged into request headers.
      throw new Error('Default headers must be a plain object.');
    }

    this.baseUrl = normalizedConfig.baseUrl;
    this.defaults = defaults;
    this.interceptors = normalizedConfig.interceptors || [];
    this.isConfigured = true;

    return this;
  }

  /**
  * Starts the process of fetching a resource. Default configuration parameters
  * will be applied to the Request. The constructed Request will be passed to
  * registered request interceptors before being sent. The Response will be passed
  * to registered Response interceptors before it is returned.
  *
  * See also https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
  *
  * @param input The resource that you wish to fetch. Either a
  * Request object, or a string containing the URL of the resource.
  * @param init An options object containing settings to be applied to
  * the Request.
  * @returns A Promise for the Response from the fetch request.
  */
  fetch(input: Request|string, init?: RequestInit): Promise<Response> {
    this::trackRequestStart();

    let request = Promise.resolve().then(() => this::buildRequest(input, init, this.defaults));
    let promise = processRequest(request, this.interceptors, this)
      .then(result => {
        let response = null;

        if (Response.prototype.isPrototypeOf(result)) {
          response = result;
        } else if (Request.prototype.isPrototypeOf(result)) {
          request = Promise.resolve(result);
          response = fetch(result);
        } else {
          throw new Error(`An invalid result was returned by the interceptor chain. Expected a Request or Response instance, but got [${result}]`);
        }

        return request.then(_request => processResponse(response, this.interceptors, _request, this));
      });

    return this::trackRequestEndWith(promise);
  }
}

const absoluteUrlRegexp = /^([a-z][a-z0-9+\-.]*:)?\/\//i;

function trackRequestStart() {
  this.isRequesting = !!(++this.activeRequestCount);
}

function trackRequestEnd() {
  this.isRequesting = !!(--this.activeRequestCount);
}

function trackRequestEndWith(promise) {
  let handle = this::trackRequestEnd;
  promise.then(handle, handle);
  return promise;
}

function parseHeaderValues(headers) {
  let parsedHeaders = {};
  for (let name in headers || {}) {
    if (headers.hasOwnProperty(name)) {
      parsedHeaders[name] = (typeof headers[name] === 'function') ? headers[name]() : headers[name];
    }
  }
  return parsedHeaders;
}

function buildRequest(input, init) {
  let defaults = this.defaults || {};
  let request;
  let body;
  let requestContentType;

  let parsedDefaultHeaders = parseHeaderValues(defaults.headers);
  if (Request.prototype.isPrototypeOf(input)) {
    request = input;
    requestContentType = new Headers(request.headers).get('Content-Type');
  } else {
    init || (init = {});
    body = init.body;
    let bodyObj = body ? { body } : null;
    let requestInit = Object.assign({}, defaults, { headers: {} }, init, bodyObj);
    requestContentType = new Headers(requestInit.headers).get('Content-Type');
    request = new Request(getRequestUrl(this.baseUrl, input), requestInit);
  }
  if (!requestContentType) {
    if (new Headers(parsedDefaultHeaders).has('content-type')) {
      request.headers.set('Content-Type', new Headers(parsedDefaultHeaders).get('content-type'));
    } else if (body && isJSON(body)) {
      request.headers.set('Content-Type', 'application/json');
    }
  }
  setDefaultHeaders(request.headers, parsedDefaultHeaders);
  if (body && Blob.prototype.isPrototypeOf(body) && body.type) {
    // work around bug in IE & Edge where the Blob type is ignored in the request
    // https://connect.microsoft.com/IE/feedback/details/2136163
    request.headers.set('Content-Type', body.type);
  }
  return request;
}

function getRequestUrl(baseUrl, url) {
  if (absoluteUrlRegexp.test(url)) {
    return url;
  }

  return (baseUrl || '') + url;
}

function setDefaultHeaders(headers, defaultHeaders) {
  for (let name in defaultHeaders || {}) {
    if (defaultHeaders.hasOwnProperty(name) && !headers.has(name)) {
      headers.set(name, defaultHeaders[name]);
    }
  }
}

function processRequest(request, interceptors, http) {
  return applyInterceptors(request, interceptors, 'request', 'requestError', http);
}

function processResponse(response, interceptors, request, http) {
  return applyInterceptors(response, interceptors, 'response', 'responseError', request, http);
}

function applyInterceptors(input, interceptors, successName, errorName, ...interceptorArgs) {
  return (interceptors || [])
    .reduce((chain, interceptor) => {
      let successHandler = interceptor[successName];
      let errorHandler = interceptor[errorName];

      return chain.then(
        successHandler && (value => interceptor::successHandler(value, ...interceptorArgs)) || identity,
        errorHandler && (reason => interceptor::errorHandler(reason, ...interceptorArgs)) || thrower);
    }, Promise.resolve(input));
}

function isJSON(str) {
  try {
    JSON.parse(str);
  }
  catch (err) {
    return false;
  }
  return true;
}

function identity(x) {
  return x;
}

function thrower(x) {
  throw x;
}
<|endoftext|>