<commit_before>
var ceils = 10;
var CW = a.width/ceils, CH = a.height/ceils, CM=CW>CH?CW:CH;
function get_color(idx){
    return 'hsl('+360/cities.length*idx+',70%,50%)';
}
function get_joint(x, y){
    return joints[x*ceils+y]; }
function close(dx, dy, am){
    return Math.abs(dx)<am && Math.abs(dy)<am; }
function City(idx){
    var x = Math.floor(Math.random()*ceils);
    var y = Math.floor(Math.random()*ceils);
    return {
        x: x, y: y,
        cx: (x+0.4)*CW,
        cy: (y+0.3)*CH,
        idx: idx,
        T: function(z){
	    c.fillStyle = get_color(idx);
            c.font='35px Sans'
	    c.fillText('⌂', this.cx, this.cy);
            c.font='20px Sans'
	}
    }
}
function Joint(x, y){
    return {
        x: x, y: y,
        t: 0,
        T: function(z){
            if (!this.t)
                return;
            c.beginPath();
            if (this.t&1){
                c.moveTo(CW*x, CH*(0.5+y));
                c.lineTo(CW*(1+x), CH*(0.5+y));
            }
            if (this.t&2){
                c.moveTo(CW*(0.5+x), CH*y);
                c.lineTo(CW*(0.5+x), CH*(1+y));
            }
            c.stroke();
        }
    }
}
function jointed(j1, j2){
    return (j1.y==j2.y && j1.x!=j2.x && j1.t&1 && j2.t&1) ||
        (j1.x==j2.x && j1.y!=j2.y && j1.t&2 && j2.t&2);
}
var dirs = [-2, 1, 2, -1];
function Train(dst, src){
    var speed = 0.05;
    var x = CW*(0.5+src.x), y = CH*(0.5+src.y);
    var dir = 1;
    return {
        x: x, y: y,
        j: get_joint(src.x, src.y),
        score: 100,
        P: function(jx, jy){
            dir = (dir+3)%4, i=0;
            for (i=0;i<4&&!this.N(jx, jy);i++)
                dir = (dir+1)%4;
        },
        N: function(jx, jy){
            var a = Math.abs(dirs[dir]), s = dirs[dir]/a,
                j = get_joint(jx+(a&1)*s, jy+(a&2)*s/2);
            return j && jointed(this.j, j) && (this.j = j);
        },
        T: function(z){
            c.fillStyle = get_color(dst.idx);
            c.fillRect(this.x, this.y, 6, 6);
            var dx = x - this.x, dy = y - this.y;
            var angle = Math.atan2(dy, dx);
            this.x += speed * z * Math.cos(angle);
            this.y += speed * z * Math.sin(angle);
            if (close(dx, dy, 2)){
                this.P(this.j.x, this.j.y);
                x = CW*(0.5+this.j.x), y = CH*(0.5+this.j.y);
            }
            if (close(dst.cx-x, dst.cy-y, CM/4)){
                Score(dst.cx, dst.cy, this.score);
                trains.splice(trains.indexOf(this), 1);
            }
            this.score -= z/1000;
        }
    }
}

var scores = [];
function Score(x, y, idx){
    var s = {
        x: x, y: y,
        T: function(z){
            c.fillStyle = get_color(idx);
            c.fillText(~~idx, x, y);
        }
    }
    GlobalScore+=~~idx;
    scores.push(s);
}

var S = Date.now();
var cities = [], joints = [], trains = [];
for (i=1; i<5; i++)
    cities.push(City(i))
for (i=0; i<ceils; i++)
    for (j=0; j<ceils; j++)
        joints[i*ceils+j] = Joint(i, j);
a.onclick = function(e){
    j = get_joint(Math.floor(e.pageX/(a.width/ceils)), Math.floor(e.pageY/(a.height/ceils)));
    j.t = (j.t+1)%4;
}
function Update(){
    if (cities.length*2<trains.length)
        return;
    if (TimePassed % Math.random() < 0.8)
        return;
    var dst = cities[Math.floor(Math.random()*100%cities.length)];
    var src = cities[Math.floor(Math.random()*100%cities.length)];
    if (!joints[src.x*ceils+src.y].t)
        return;
    trains.push(Train(dst, src, i));
}

var TimePassed = 0, LastTick = Date.now();
var GlobalScore = 0;
setInterval(function(){ GlobalScore-=100+TimePassed/a.width }, 10000);
setInterval(function(){ scores = [] }, 1000);
setInterval(function(){ cities.length<15 && cities.push(City(cities.length+1)) }, 40000);
(function L(){
    requestAnimationFrame(L);
    var D = Date.now()-LastTick;
    TimePassed += D;
    LastTick += D;
    Update();
    c.clearRect(0,0,a.width,a.height);
    c.fillStyle = 'green';
    c.fillRect(0,0,a.width,a.height);
    c.fill();
    var p = function(o){ o.T(D) }
    cities.forEach(p);
    joints.forEach(p);
    trains.forEach(p);
    scores.forEach(p);
    c.fillStyle = 'white';
    c.fillText(~~GlobalScore, 0, 20);
})()
<commit_msg>Final<commit_after>
var ceils = 10;
var CW = a.width/ceils, CH = a.height/ceils, CM=CW>CH?CW:CH;
function get_color(idx){
    return 'hsl('+360/cities.length*idx+',70%,50%)';
}
function get_joint(x, y){
    return joints[x*ceils+y]; }
function close(dx, dy, am){
    return Math.abs(dx)<am && Math.abs(dy)<am; }
function City(idx){
    var x = Math.floor(Math.random()*ceils);
    var y = Math.floor(Math.random()*ceils);
    return {
        x: x, y: y,
        cx: (x+0.4)*CW,
        cy: (y+0.3)*CH,
        idx: idx,
        T: function(z){
	    c.fillStyle = get_color(idx);
            c.font='35px Sans'
	    c.fillText('⌂', this.cx, this.cy);
            c.font='20px Sans'
	}
    }
}
function Joint(x, y){
    return {
        x: x, y: y,
        t: 0,
        T: function(z){
            if (!this.t)
                return;
            c.beginPath();
            if (this.t&1){
                c.moveTo(CW*x, CH*(0.5+y));
                c.lineTo(CW*(1+x), CH*(0.5+y));
            }
            if (this.t&2){
                c.moveTo(CW*(0.5+x), CH*y);
                c.lineTo(CW*(0.5+x), CH*(1+y));
            }
            c.stroke();
        }
    }
}
function jointed(j1, j2){
    return (j1.y==j2.y && j1.x!=j2.x && j1.t&1 && j2.t&1) ||
        (j1.x==j2.x && j1.y!=j2.y && j1.t&2 && j2.t&2);
}
var dirs = [-2, 1, 2, -1];
function Train(dst, src, num){
    var speed = 0.05;
    var x = CW*(0.5+src.x), y = CH*(0.5+src.y);
    var dir = 1, lz=Array(9);
    return {
        x: x, y: y,
        j: get_joint(src.x, src.y),
        score: 100,
        next: num && Train(dst, src, num-1),
        P: function(jx, jy){
            dir = (dir+3)%4, i=0;
            for (i=0;i<4&&!this.N(jx, jy);i++)
                dir = (dir+1)%4;
        },
        N: function(jx, jy){
            var a = Math.abs(dirs[dir]), s = dirs[dir]/a,
                j = get_joint(jx+(a&1)*s, jy+(a&2)*s/2);
            return j && jointed(this.j, j) && (this.j = j);
        },
        T: function(z){
            z=z||0;
            c.fillStyle = get_color(dst.idx);
            c.fillRect(this.x, this.y, 6, 6);
            var dx = x - this.x, dy = y - this.y;
            var angle = Math.atan2(dy, dx);
            this.x += speed * z * Math.cos(angle);
            this.y += speed * z * Math.sin(angle);
            if (close(dx, dy, 2)){
                this.P(this.j.x, this.j.y);
                x = CW*(0.5+this.j.x), y = CH*(0.5+this.j.y);
            }
            if (trains.indexOf(this)>=0 && close(dst.cx-this.x, dst.cy-this.y, 15)){
                Score(dst.cx, dst.cy, this.score);
                trains.splice(trains.indexOf(this), 1);
            }
            this.score -= z/1000;
            this.next && this.next.T(lz.shift());
            lz.push(z);
        }
    }
}

var scores = [];
function Score(x, y, idx){
    var s = {
        x: x, y: y,
        T: function(z){
            c.fillStyle = get_color(idx);
            c.fillText(~~idx, x, y);
        }
    }
    GlobalScore+=~~idx;
    tc++;
    scores.push(s);
}

var S = Date.now();
var cities = [], joints = [], trains = [];
for (i=1; i<5; i++)
    cities.push(City(i))
for (i=0; i<ceils; i++)
    for (j=0; j<ceils; j++)
        joints[i*ceils+j] = Joint(i, j);
a.onclick = function(e){
    j = get_joint(Math.floor(e.pageX/(a.width/ceils)), Math.floor(e.pageY/(a.height/ceils)));
    j.t = (j.t+1)%4;
}
function Update(){
    if (cities.length*2<trains.length)
        return;
    if (TimePassed % Math.random() < 0.8)
        return;
    var dst = cities[Math.floor(Math.random()*100%cities.length)];
    var src = cities[Math.floor(Math.random()*100%cities.length)];
    if (dst==src||!joints[src.x*ceils+src.y].t)
        return;
    trains.push(Train(dst, src, Math.floor(Math.random()*100%cities.length)+1));
}

var TimePassed = 0, LastTick = Date.now();
var GlobalScore = 0, tc = 0;
setInterval(function(){ GlobalScore-=100+TimePassed/a.width }, 10000);
setInterval(function(){ scores = [] }, 1000);
setInterval(function(){ cities.length<15 && cities.push(City(cities.length+1)) }, 40000);
(function L(){
    requestAnimationFrame(L);
    var D = Date.now()-LastTick;
    TimePassed += D;
    LastTick += D;
    Update();
    c.clearRect(0,0,a.width,a.height);
    c.fillStyle = 'green';
    c.fillRect(0,0,a.width,a.height);
    c.fill();
    var p = function(o){ o.T(D) }
    cities.forEach(p);
    joints.forEach(p);
    if (Math.abs(GlobalScore/10000)<1){
        trains.forEach(p);
        scores.forEach(p);
    } else
        c.fillText((GlobalScore/10000<0?'Good':'Bad')+' end: '+tc, a.width/2.5, a.height/2);
    c.fillStyle = 'white';
    c.fillText(tc, a.width, 20);
    c.fillText(~~GlobalScore, 0, 20);
})()
<|endoftext|>


<commit_before>var http = require('http');
var url = require('url');
var Stream = require('stream');
var Frame = require('./frame');
var Builder = require('./builder');
var runner = require('./runner');

var Argo = function(_http) {
  this._router = {};
  this._routerKeys = [];
  this.builder = new Builder();
  this._http = _http || http;

  var that = this;
  var incoming = this._http.IncomingMessage.prototype;

  if (!incoming._argoModified) {
    var _addHeaderLine = incoming._addHeaderLine;

    incoming._addHeaderLine = function(field, value) {
      this._rawHeaderNames = this._rawHeaderNames || {};
      this._rawHeaderNames[field.toLowerCase()] = field;

      _addHeaderLine.call(this, field, value);
    };

    incoming.body = null;
    incoming.getBody = that._getBody();
    incoming._argoModified = true;
  }

  var serverResponse = this._http.ServerResponse.prototype;
  if (!serverResponse._argoModified) {
    serverResponse.body = null;
    serverResponse.getBody = that._getBody();

    serverResponse._argoModified = true;
  }
};

Argo.prototype._getBody = function() {
  var that = this;
  return function(callback) {
    if (this.body) {
      callback(null, this.body);
      return;
    }
    var buf = [];
    var len = 0;

    this.on('data', function(chunk) {
      buf.push(chunk);
      len += chunk.length;
    });

    this.on('end', function() {
      var body;
      if (buf.length && Buffer.isBuffer(buf[0])) {
        body = new Buffer(len);
        var i = 0;
        buf.forEach(function(chunk) {
          chunk.copy(body, i, 0, chunk.length);
          i += chunk.length;
        });
      } else if (buf.length) {
        body = buf.join('');
      }

      this.body = body;

      callback(null, body);
    });
  };
};

Argo.prototype.include = function(mod) {
  var p = mod.package(this);
  p.install();
  return this;
};

Argo.prototype.listen = function(port) {
  runner.listen(this, port);
  return this;
};

Argo.prototype.use = function(middleware) {
  if (middleware.package) {
    return this.include(middleware);
  }
  this.builder.use(middleware);
  return this;
};

Argo.prototype.target = function(url) {
  return this.use(function(addHandler) {
    addHandler('request', function(env, next) {
      env.target.url = url + (env.request.url || '');
      next(env);
    });
  });
};

Argo.prototype.embed = function() {
  this.buildCore();

  this.builder.run(this._target);
  this.builder.use(function(addHandler) {
    addHandler('response', { affinity: 'sink' }, function(env) {
      if (env.argo.oncomplete) {
        env.argo.oncomplete(env);
      };
    });
  });

  return this.builder.build();
}

Argo.prototype.buildCore = function() {
  var that = this;

  that.builder.use(function(addHandler) {
    addHandler('request', function(env, next) {
      env.argo._http = that._http;
      next(env);
    });
  });

  var hasRoutes = false;
  for (var prop in that._router) {
    if (!hasRoutes && that._router.hasOwnProperty(prop)) {
      hasRoutes = true;
    }
  }

  if (hasRoutes) {
    that.builder.use(function addRouteHandlers(handlers) {
     that._route(that._router, handlers);
    });
  }
};

Argo.prototype.build = function() {
  var that = this;

  that.buildCore();

  that.builder.run(that._target);

  // response ender
  that.builder.use(function(handle) {
    handle('response', { affinity: 'sink' }, function(env, next) {
      if (env.response.body) {
        var body = env.response.body;
        if (typeof body === 'string') {
          env.response.setHeader('Content-Length', body ? body.length : 0);
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end(body);
        } else if (body instanceof Stream) {
          env.response.writeHead(env.response.statusCode, env.response.headers);
          body.pipe(env.response);
        } else if (typeof body === 'object') {
          body = new Buffer(JSON.stringify(body), 'utf-8');
          if (!env.response.getHeader('Content-Type')) {
            env.response.setHeader('Content-Type', 'application/json; charset=UTF-8');
          }
          env.response.setHeader('Content-Length', body ? body.length : 0);
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end(body.toString('utf-8'));
        }
      } else {
        var contentLength = env.response.getHeader('Content-Length');
        if (contentLength == '0') {
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end();
        } else if (env.target.response) {
          env.target.response.getBody(function(err, body) {
            env.response.setHeader('Content-Length', body ? body.length : 0);
            env.response.writeHead(env.response.statusCode, env.response.headers);
            env.response.end(body);
          });
        } else {
          env.response.setHeader('Content-Length', '0');
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end();
        }
      }
    });
  });

  return that.builder.build();
};

Argo.prototype.call = function(env) {
  var app = this.build();
  return app.flow(env);
}

Argo.prototype.route = function(path, options, handlers) {
  if (typeof(options) === 'function') {
    handlers = options;
    options = {};
  }

  options.methods = options.methods || ['*'];
  if (!this._router[path]) {
    this._router[path] = {};
  }

  var that = this;
  options.methods.forEach(function(method) {
    that._router[path][method.toLowerCase()] = handlers;
  });

  that._routerKeys.push(path);
  that._routerKeys.sort(function(a, b) {
    if (a.length > b.length) {
      return -1;
    } else if (a.length < b.length) {
      return 1;
    }

    return 0;
  });

  return this;
};

var methods = {
  'get': 'GET',
  'post': 'POST',
  'put': 'PUT',
  'del': 'DELETE',
  'head': 'HEAD',
  'options': 'OPTIONS',
  'trace': 'TRACE'
};

Object.keys(methods).forEach(function(method) {
  Argo.prototype[method] = function(path, options, handlers) {
    if (typeof(options) === 'function') {
      handlers = options;
      options = {};
    }
    options.methods = [methods[method]];
    return this.route(path, options, handlers);
  };
});

Argo.prototype.map = function(path, options, handler) {
  if (typeof(options) === 'function') {
    handler = options;
    options = {};
  }

  options.methods = options.methods || ['*'];
  if (!this._router[path]) {
    this._router[path] = {};
  }

  function generateHandler(path, handler) {
    var argo = new Argo();
    handler(argo);

    var app = argo.embed();

    return function(addHandler) {
      addHandler('request', function mapHandler(env, next) {
        env.argo.frames = env.argo.frames || [];

        var frame = new Frame();
        frame.routed = env.argo._routed;
        frame.routedResponseHandler = env.argo._routedResponseHandler;

        env.argo._routed = false;
        env.argo._routedResponseHandler = null;

        if (env.request.url[env.request.url.length - 1] === '/') {
          env.request.url = env.request.url.substr(0, env.request.url.length - 1);
        }

        if (env.argo.frames.length) {
          pathLength = 0;
          env.argo.frames.forEach(function(frame) {
            pathLength += frame.routeUri.length;
          });
        }

        frame.routeUri = path || '/';

        env.request.url = env.request.url.substr(frame.routeUri.length);
        env.request.url = env.request.url || '/';

        // TODO: See if this can work in a response handler here.

        if (env.argo.oncomplete) {
          frame.oncomplete = env.argo.oncomplete;
        }

        env.argo.currentFrame = frame;
        env.argo.frames.push(frame);

        env.argo.oncomplete = function(env) {
          var frame = env.argo.frames.pop();

          env.argo._routed = frame.routed;
          env.argo._routedResponseHandler = frame.routedResponseHandler;
          env.request.url = frame.routeUri + env.request.url;
          env.argo.oncomplete = frame.oncomplete;

          next(env);
        };

        app.flow(env);
      });
    };
  };

  return this.route(path, options, generateHandler(path, handler));
};

Argo.prototype._pipeline = function(name) {
  return this.builder.pipelineMap[name];
};

Argo.prototype._addRouteHandlers = function(handlers) {
  return function add(name, opts, cb) {
    if (typeof opts === 'function') {
      cb = opts;
      opts = null;
    }

    if (name === 'request') {
      handlers.request = cb;
    } else if (name === 'response') {
      handlers.response = cb;
    }
  };
};

function RouteHandlers() {
  this.request = null;
  this.response = null;
}

Argo.prototype._routeRequestHandler = function(router) {
  var that = this;
  return function routeRequestHandler(env, next) {
    env.argo._routed = false;

    var search = env.request.url;

    var routerKey;
    if (search === '/' && that._router['/']) {
      routerKey = '/';
    } else {
      that._routerKeys.forEach(function(key) {
        if (!routerKey && key !== '*' && search.search(key) !== -1 && key !== '/') {
          routerKey = key;
        }
      });
    }

    if (!routerKey && that._router['*']) {
      routerKey = '*';
    }

    if (routerKey &&
        (!router[routerKey][env.request.method.toLowerCase()] &&
         !router[routerKey]['*'])) {
      env.response.statusCode = 405;
      next(env);
      return;
    }

    if (routerKey &&
        (router[routerKey][env.request.method.toLowerCase()] ||
         router[routerKey]['*'])) {
      env.argo._routed = true;

      var method = env.request.method.toLowerCase();
      var fn = router[routerKey][method] ? router[routerKey][method]
        : router[routerKey]['*'];

      var handlers = new RouteHandlers();
      fn(that._addRouteHandlers(handlers));

      env.argo._routedResponseHandler = handlers.response || null;

      if (handlers.request) {
        handlers.request(env, next);
      } else {
        next(env);
        return;
      }
    }

    if (!env.argo._routed) {
      next(env);
    }
  };
};

Argo.prototype._routeResponseHandler = function(router) {
  var that = this;
  return function routeResponseHandler(env, next) {
    if (!env.argo._routed) {
      if (env.response.statusCode !== 405) {
        env.response.statusCode = 404;
      }

      next(env);
      return;
    }

    if (env.argo._routedResponseHandler) {
      env.argo._routedResponseHandler(env, next);
      return;
    } else {
      next(env);
      return;
    }
  };
};

Argo.prototype._route = function(router, handle) {
  handle('request', this._routeRequestHandler(router));
  handle('response', { affinity: 'hoist' }, this._routeResponseHandler(router));
};

Argo.prototype._target = function(env, next) {
  if (env.response._headerSent || env.target.skip) {
    next(env);
    return;
  }
  var start = +Date.now();

  if (env.target && env.target.url) {
    var options = {};
    options.method = env.request.method || 'GET';

    // TODO: Make Agent configurable.
    options.agent = new env.argo._http.Agent();
    options.agent.maxSockets = 1024;

    var parsed = url.parse(env.target.url);
    options.hostname = parsed.hostname;
    options.port = parsed.port || 80;
    options.path = parsed.path;

    options.headers = env.request.headers;
    options.headers['Connection'] = 'keep-alive';
    options.headers['Host'] = options.hostname;

    if (parsed.auth) {
      options.auth = parsed.auth;
    }

    var req = env.argo._http.request(options, function(res) {
      for (var key in res.headers) {
        var headerName = res._rawHeaderNames[key] || key;
        env.response.setHeader(headerName, res.headers[key]);
      }

      env.target.response = res;

      if (next) {
        var duration = (+Date.now() - start);
        next(env);
      }
    });

    env.request.getBody(function(err, body) {
      if (body) {
        req.write(body);
      }

      req.end();
    });
  } else {
    next(env);
  }
};

module.exports = function(_http) { return new Argo(_http) };
<commit_msg>Fixing bug introduced by pipeworks migration.<commit_after>var http = require('http');
var url = require('url');
var Stream = require('stream');
var Frame = require('./frame');
var Builder = require('./builder');
var runner = require('./runner');

var Argo = function(_http) {
  this._router = {};
  this._routerKeys = [];
  this.builder = new Builder();
  this._http = _http || http;

  var that = this;
  var incoming = this._http.IncomingMessage.prototype;

  if (!incoming._argoModified) {
    var _addHeaderLine = incoming._addHeaderLine;

    incoming._addHeaderLine = function(field, value) {
      this._rawHeaderNames = this._rawHeaderNames || {};
      this._rawHeaderNames[field.toLowerCase()] = field;

      _addHeaderLine.call(this, field, value);
    };

    incoming.body = null;
    incoming.getBody = that._getBody();
    incoming._argoModified = true;
  }

  var serverResponse = this._http.ServerResponse.prototype;
  if (!serverResponse._argoModified) {
    serverResponse.body = null;
    serverResponse.getBody = that._getBody();

    serverResponse._argoModified = true;
  }
};

Argo.prototype._getBody = function() {
  var that = this;
  return function(callback) {
    if (this.body) {
      callback(null, this.body);
      return;
    }
    var buf = [];
    var len = 0;

    this.on('data', function(chunk) {
      buf.push(chunk);
      len += chunk.length;
    });

    this.on('end', function() {
      var body;
      if (buf.length && Buffer.isBuffer(buf[0])) {
        body = new Buffer(len);
        var i = 0;
        buf.forEach(function(chunk) {
          chunk.copy(body, i, 0, chunk.length);
          i += chunk.length;
        });
      } else if (buf.length) {
        body = buf.join('');
      }

      this.body = body;

      callback(null, body);
    });
  };
};

Argo.prototype.include = function(mod) {
  var p = mod.package(this);
  p.install();
  return this;
};

Argo.prototype.listen = function(port) {
  runner.listen(this, port);
  return this;
};

Argo.prototype.use = function(middleware) {
  if (middleware.package) {
    return this.include(middleware);
  }
  this.builder.use(middleware);
  return this;
};

Argo.prototype.target = function(url) {
  return this.use(function(addHandler) {
    addHandler('request', function(env, next) {
      env.target.url = url + (env.request.url || '');
      next(env);
    });
  });
};

Argo.prototype.embed = function() {
  this.buildCore();

  this.builder.run(this._target);
  this.builder.use(function(addHandler) {
    addHandler('response', { affinity: 'sink' }, function(env, next) {
      console.log(env.toString());
      if (env.argo.oncomplete) {
        env.argo.oncomplete(env);
      };
    });
  });

  return this.builder.build();
}

Argo.prototype.buildCore = function() {
  var that = this;

  that.builder.use(function(addHandler) {
    addHandler('request', function(env, next) {
      env.argo._http = that._http;
      next(env);
    });
  });

  var hasRoutes = false;
  for (var prop in that._router) {
    if (!hasRoutes && that._router.hasOwnProperty(prop)) {
      hasRoutes = true;
    }
  }

  if (hasRoutes) {
    that.builder.use(function addRouteHandlers(handlers) {
     that._route(that._router, handlers);
    });
  }
};

Argo.prototype.build = function() {
  var that = this;

  that.buildCore();

  that.builder.run(that._target);

  // response ender
  that.builder.use(function(handle) {
    handle('response', { affinity: 'sink' }, function(env, next) {
      if (env.response.body) {
        var body = env.response.body;
        if (typeof body === 'string') {
          env.response.setHeader('Content-Length', body ? body.length : 0);
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end(body);
        } else if (body instanceof Stream) {
          env.response.writeHead(env.response.statusCode, env.response.headers);
          body.pipe(env.response);
        } else if (typeof body === 'object') {
          body = new Buffer(JSON.stringify(body), 'utf-8');
          if (!env.response.getHeader('Content-Type')) {
            env.response.setHeader('Content-Type', 'application/json; charset=UTF-8');
          }
          env.response.setHeader('Content-Length', body ? body.length : 0);
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end(body.toString('utf-8'));
        }
      } else {
        var contentLength = env.response.getHeader('Content-Length');
        if (contentLength == '0') {
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end();
        } else if (env.target.response) {
          env.target.response.getBody(function(err, body) {
            env.response.setHeader('Content-Length', body ? body.length : 0);
            env.response.writeHead(env.response.statusCode, env.response.headers);
            env.response.end(body);
          });
        } else {
          env.response.setHeader('Content-Length', '0');
          env.response.writeHead(env.response.statusCode, env.response.headers);
          env.response.end();
        }
      }
    });
  });

  return that.builder.build();
};

Argo.prototype.call = function(env) {
  var app = this.build();
  return app.flow(env);
}

Argo.prototype.route = function(path, options, handlers) {
  if (typeof(options) === 'function') {
    handlers = options;
    options = {};
  }

  options.methods = options.methods || ['*'];
  if (!this._router[path]) {
    this._router[path] = {};
  }

  var that = this;
  options.methods.forEach(function(method) {
    that._router[path][method.toLowerCase()] = handlers;
  });

  that._routerKeys.push(path);
  that._routerKeys.sort(function(a, b) {
    if (a.length > b.length) {
      return -1;
    } else if (a.length < b.length) {
      return 1;
    }

    return 0;
  });

  return this;
};

var methods = {
  'get': 'GET',
  'post': 'POST',
  'put': 'PUT',
  'del': 'DELETE',
  'head': 'HEAD',
  'options': 'OPTIONS',
  'trace': 'TRACE'
};

Object.keys(methods).forEach(function(method) {
  Argo.prototype[method] = function(path, options, handlers) {
    if (typeof(options) === 'function') {
      handlers = options;
      options = {};
    }
    options.methods = [methods[method]];
    return this.route(path, options, handlers);
  };
});

Argo.prototype.map = function(path, options, handler) {
  if (typeof(options) === 'function') {
    handler = options;
    options = {};
  }

  options.methods = options.methods || ['*'];
  if (!this._router[path]) {
    this._router[path] = {};
  }

  function generateHandler(path, handler) {
    var argo = new Argo();
    handler(argo);

    var app = argo.embed();

    return function(addHandler) {
      addHandler('request', function mapHandler(env, next) {
        env.argo.frames = env.argo.frames || [];

        var frame = new Frame();
        frame.routed = env.argo._routed;
        frame.routedResponseHandler = env.argo._routedResponseHandler;

        env.argo._routed = false;
        env.argo._routedResponseHandler = null;

        if (env.request.url[env.request.url.length - 1] === '/') {
          env.request.url = env.request.url.substr(0, env.request.url.length - 1);
        }

        if (env.argo.frames.length) {
          pathLength = 0;
          env.argo.frames.forEach(function(frame) {
            pathLength += frame.routeUri.length;
          });
        }

        frame.routeUri = path || '/';

        env.request.url = env.request.url.substr(frame.routeUri.length);
        env.request.url = env.request.url || '/';

        // TODO: See if this can work in a response handler here.

        if (env.argo.oncomplete) {
          frame.oncomplete = env.argo.oncomplete;
        }

        env.argo.currentFrame = frame;
        env.argo.frames.push(frame);

        env.argo.oncomplete = function(env) {
          var frame = env.argo.frames.pop();

          env.argo._routed = frame.routed;
          env.argo._routedResponseHandler = frame.routedResponseHandler;
          env.request.url = frame.routeUri + env.request.url;
          env.argo.oncomplete = frame.oncomplete;

          next(env);
        };

        app.flow(env);
      });
    };
  };

  return this.route(path, options, generateHandler(path, handler));
};

Argo.prototype._pipeline = function(name) {
  return this.builder.pipelineMap[name];
};

Argo.prototype._addRouteHandlers = function(handlers) {
  return function add(name, opts, cb) {
    if (typeof opts === 'function') {
      cb = opts;
      opts = null;
    }

    if (name === 'request') {
      handlers.request = cb;
    } else if (name === 'response') {
      handlers.response = cb;
    }
  };
};

function RouteHandlers() {
  this.request = null;
  this.response = null;
}

Argo.prototype._routeRequestHandler = function(router) {
  var that = this;
  return function routeRequestHandler(env, next) {
    env.argo._routed = false;

    var search = env.request.url;

    var routerKey;
    if (search === '/' && that._router['/']) {
      routerKey = '/';
    } else {
      that._routerKeys.forEach(function(key) {
        if (!routerKey && key !== '*' && search.search(key) !== -1 && key !== '/') {
          routerKey = key;
        }
      });
    }

    if (!routerKey && that._router['*']) {
      routerKey = '*';
    }

    if (routerKey &&
        (!router[routerKey][env.request.method.toLowerCase()] &&
         !router[routerKey]['*'])) {
      env.response.statusCode = 405;
      next(env);
      return;
    }

    if (routerKey &&
        (router[routerKey][env.request.method.toLowerCase()] ||
         router[routerKey]['*'])) {
      env.argo._routed = true;

      var method = env.request.method.toLowerCase();
      var fn = router[routerKey][method] ? router[routerKey][method]
        : router[routerKey]['*'];

      var handlers = new RouteHandlers();
      fn(that._addRouteHandlers(handlers));

      env.argo._routedResponseHandler = handlers.response || null;

      if (handlers.request) {
        handlers.request(env, next);
      } else {
        next(env);
        return;
      }
    }

    if (!env.argo._routed) {
      next(env);
    }
  };
};

Argo.prototype._routeResponseHandler = function(router) {
  var that = this;
  return function routeResponseHandler(env, next) {
    if (!env.argo._routed) {
      if (env.response.statusCode !== 405) {
        env.response.statusCode = 404;
      }

      next(env);
      return;
    }

    if (env.argo._routedResponseHandler) {
      env.argo._routedResponseHandler(env, next);
      return;
    } else {
      next(env);
      return;
    }
  };
};

Argo.prototype._route = function(router, handle) {
  handle('request', this._routeRequestHandler(router));
  handle('response', { affinity: 'hoist' }, this._routeResponseHandler(router));
};

Argo.prototype._target = function(env, next) {
  if (env.response._headerSent || env.target.skip) {
    next(env);
    return;
  }
  var start = +Date.now();

  if (env.target && env.target.url) {
    var options = {};
    options.method = env.request.method || 'GET';

    // TODO: Make Agent configurable.
    options.agent = new env.argo._http.Agent();
    options.agent.maxSockets = 1024;

    var parsed = url.parse(env.target.url);
    options.hostname = parsed.hostname;
    options.port = parsed.port || 80;
    options.path = parsed.path;

    options.headers = env.request.headers;
    options.headers['Connection'] = 'keep-alive';
    options.headers['Host'] = options.hostname;

    if (parsed.auth) {
      options.auth = parsed.auth;
    }

    var req = env.argo._http.request(options, function(res) {
      for (var key in res.headers) {
        var headerName = res._rawHeaderNames[key] || key;
        env.response.setHeader(headerName, res.headers[key]);
      }

      env.target.response = res;

      if (next) {
        var duration = (+Date.now() - start);
        next(env);
      }
    });

    env.request.getBody(function(err, body) {
      if (body) {
        req.write(body);
      }

      req.end();
    });
  } else {
    next(env);
  }
};

module.exports = function(_http) { return new Argo(_http) };
<|endoftext|>


<commit_before>// var cron = require('node-cron');
const git = require('simple-git');
const firebase = require('firebase')
const config = require('./config')

// const path = __dirname + '/iotos';
// git(path).then etc..

firebase.initializeApp(config);

var ref = firebase.database().ref().child("servers")

ref.on('value', function (data) {
	if (data.val(config.device) == "pull") {
		deploy();
	} else {
		console.log('normal')
	}
})

function deploy () {
  console.log('Starting Deploying aplication ... :-)');
  // git(path).pull('origin', 'master')
	git()
	.then(function() {
		console.log('Starting pull ...');
	})
	.pull(function(err, update) {
		if(update && update.summary.changes) {
			console.log('processing and restarting app...');
			require('child_process').exec('npm restart app');
		}
		})
	.then(function() {
	console.log('pull done.');
	});
}

// var task = cron.schedule('*/1 * * * *', function() {
//   console.log('running a task every minute');
//   deploy ()
//   // task.stop();
// });<commit_msg>update project<commit_after>// var cron = require('node-cron');
const git = require('simple-git');
const firebase = require('firebase')
const config = require('./config')

// const path = __dirname + '/iotos';
// git(path).then etc..

firebase.initializeApp(config);

var ref = firebase.database().ref().child("servers")

ref.on('value', function (data) {
	if (data.val(config.device) == "pull") {
		deploy();
	} else {
		console.log('normal')
	}
})

function deploy () {
  console.log('Starting Deploying aplication ... :-)');
  // git(path).pull('origin', 'master')
	git()
	.then(function() {
		console.log('Starting pull ...');
	})
	.pull(function(err, update) {
		if(update && update.summary.changes) {
			console.log('processing and restarting app ...');
			require('child_process').exec('npm restart app');
		}
		})
	.then(function() {
	console.log('pull done.');
	});
}

// var task = cron.schedule('*/1 * * * *', function() {
//   console.log('running a task every minute');
//   deploy ()
//   // task.stop();
// });<|endoftext|>


<commit_before>/* Copyright (c) 2012-2013 Brian Cavalier */
(function(define, global) {
define(function() {

	var avow, nextTick, defaultConfig, call, fcall, undef;

	call = Function.prototype.call;
	fcall = call.bind(call);

	// Use process.nextTick or setImmediate if available, fallback to setTimeout
	nextTick = (function () {
		var globalSetTimeout = setTimeout;
		/*global setImmediate,process*/
		return typeof setImmediate === 'function'
			? setImmediate.bind(global)
			: typeof process === 'object'
				? process.nextTick
				: function(task) { globalSetTimeout(task, 0); };
	}());

	// Default configuration
	defaultConfig = {
		nextTick:  nextTick,
		unhandled: noop,
		handled:   noop,
		protect:   noop
	};

	// Create the default module instance
	// This is what you get when you require('avow')
	avow = constructAvow(defaultConfig);

	// You can use require('avow').construct(options) to
	// construct a custom configured version of avow
	avow.construct = constructAvow;

	return avow;

	// This constructs configured instances of the avow module
	function constructAvow(config) {

		var nextTick, onHandled, onUnhandled, protect;

		// Grab the config params, use defaults where necessary
		nextTick    = config.nextTick  || defaultConfig.nextTick;
		onHandled   = config.handled   || defaultConfig.handled;
		onUnhandled = config.unhandled || defaultConfig.unhandled;
		protect     = config.protect   || defaultConfig.protect;

		// Add resolve and reject methods.
		promise.from   = from;
		promise.reject = reject;

		return promise;

		// Trusted promise constructor
		function Promise(then) {
			this.then = then;
			protect(this);
		}

		// Return a pending promise whose fate is determined by resolver
		function promise(resolver) {
			var self, value, handled, handlers = [];

			self = new Promise(then);

			// Call the resolver to seal the promise's fate
			try {
				resolver(promiseResolve, promiseReject);
			} catch(e) {
				promiseReject(e);
			}

			// Return the promise
			return self;

			// Register handlers with this promise
			function then(onFulfilled, onRejected) {
				if (!handled) {
					handled = true;
					onHandled(self);
				}

				return promise(function(resolve, reject) {
					handlers
						// Call handlers later, after resolution
						? handlers.push(function(value) {
							value.then(onFulfilled, onRejected).then(resolve, reject);
						})
						// Call handlers soon, but not in the current stack
						: nextTick(function() {
							value.then(onFulfilled, onRejected).then(resolve, reject);
						});
				});
			}

			// Resolve with a value, promise, or thenable
			function promiseResolve(value) {
				if(!handlers) {
					return;
				}

				resolve(from(value));
			}

			// Reject with reason verbatim
			function promiseReject(reason) {
				if(!handlers) {
					return;
				}

				if(!handled) {
					onUnhandled(self, reason);
				}

				resolve(reject(reason));
			}

			// For all handlers, run the Promise Resolution Procedure on this promise
			function resolve(x) {
				var queue = handlers;
				handlers = undef;
				value = x;

				nextTick(function () {
					queue.forEach(function (handler) {
						handler(value);
					});
				});
			}
		}

		// Return a trusted promise for x, where
		// - if x is a Promise, return it
		// - if x is a value, return a promise that will eventually fulfill with x
		// - if x is a thenable, assimilate it and return a promise whose fate
		//   follows that of x.
		function from(x) {
			if(x instanceof Promise) {
				return x;
			} else if (x !== Object(x)) {
				return fulfilled(x);
			}

			return promise(function(resolve, reject) {
				nextTick(function() {
					try {
						// We must check and assimilate in the same tick, but not the
						// current tick, careful only to access promiseOrValue.then once.
						var untrustedThen = x.then;

						if(typeof untrustedThen === 'function') {
							fcall(untrustedThen, x, resolve, reject);
						} else {
							// It's a value, create a fulfilled wrapper
							resolve(fulfilled(x));
						}

					} catch(e) {
						// Something went wrong, reject
						reject(e);
					}
				});
			});
		}

		// Return a rejected promise
		function reject(reason) {
			return new Promise(function (_, onRejected) {
				return promise(function(resolve, reject) {
					if(typeof onRejected == 'function') {
						resolve(onRejected(reason));
					} else {
						reject(reason);
					}
				});
			});
		}

		// private
		// create an already-fulfilled promise used to break assimilation recursion
		function fulfilled(value) {
			var self = new Promise(function (onFulfilled) {
				try {
					return typeof onFulfilled == 'function' ? from(onFulfilled(value)) : self;
				} catch (e) {
					return reject(e);
				}
			});

			return self;
		}
	}

	function noop() {}

});
})(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }, this);<commit_msg>Add vert.x support. Minor code and comment reorg<commit_after>/* Copyright (c) 2012-2013 Brian Cavalier */
(function(define, global) {
define(function() {

	var avow, nextTick, defaultConfig, setTimeout, bind, uncurryThis, call, undef;

	bind = Function.prototype.bind;
	uncurryThis = bind.bind(bind.call);
	call = uncurryThis(bind.call);

	// Prefer setImmediate, cascade to node, vertx and finally setTimeout
	/*global setImmediate,process,vertx*/
	setTimeout = global.setTimeout;
	nextTick = typeof setImmediate === 'function' ? setImmediate.bind(global)
		: typeof process === 'object' ? process.nextTick // Node
		: typeof vertx === 'object' ? vertx.runOnLoop // vert.x
			: function(task) { setTimeout(task, 0); }; // fallback

	// Default configuration
	defaultConfig = {
		nextTick:  nextTick,
		unhandled: noop,
		handled:   noop,
		protect:   noop
	};

	// Create the default module instance
	// This is what you get when you require('avow')
	avow = constructAvow(defaultConfig);

	// You can use require('avow').construct(options) to
	// construct a custom configured version of avow
	avow.construct = constructAvow;

	return avow;

	// This constructs configured instances of the avow module
	function constructAvow(config) {

		var nextTick, onHandled, onUnhandled, protect;

		// Grab the config params, use defaults where necessary
		nextTick    = config.nextTick  || defaultConfig.nextTick;
		onHandled   = config.handled   || defaultConfig.handled;
		onUnhandled = config.unhandled || defaultConfig.unhandled;
		protect     = config.protect   || defaultConfig.protect;

		// Add lift and reject methods.
		promise.lift    = lift;
		promise.reject  = reject;

		return promise;

		// Return a trusted promise for x.  Where if x is a
		// - Promise, return it
		// - value, return a promise that will eventually fulfill with x
		// - thenable, assimilate it and return a promise whose fate follows that of x.
		function lift(x) {
			return promise(function(resolve) {
				resolve(x);
			});
		}

		// Return a rejected promise
		function reject(reason) {
			return promise(function(_, reject) {
				reject(reason);
			});
		}

		// Return a pending promise whose fate is determined by resolver
		function promise(resolver) {
			var self, value, handled, handlers = [];

			self = new Promise(then);

			// Call the resolver to seal the promise's fate
			try {
				resolver(promiseResolve, promiseReject);
			} catch(e) {
				promiseReject(e);
			}

			// Return the promise
			return self;

			// Register handlers with this promise
			function then(onFulfilled, onRejected) {
				if (!handled) {
					handled = true;
					onHandled(self);
				}

				return promise(function(resolve, reject) {
					handlers
						// Call handlers later, after resolution
						? handlers.push(function(value) {
							value.then(onFulfilled, onRejected).then(resolve, reject);
						})
						// Call handlers soon, but not in the current stack
						: nextTick(function() {
							value.then(onFulfilled, onRejected).then(resolve, reject);
						});
				});
			}

			// Resolve with a value, promise, or thenable
			function promiseResolve(value) {
				if(!handlers) {
					return;
				}

				resolve(coerce(value));
			}

			// Reject with reason verbatim
			function promiseReject(reason) {
				if(!handlers) {
					return;
				}

				if(!handled) {
					onUnhandled(self, reason);
				}

				resolve(rejected(reason));
			}

			// For all handlers, run the Promise Resolution Procedure on this promise
			function resolve(x) {
				var queue = handlers;
				handlers = undef;
				value = x;

				nextTick(function () {
					queue.forEach(function (handler) {
						handler(value);
					});
				});
			}
		}

		// Private

		// Trusted promise constructor
		function Promise(then) {
			this.then = then;
			protect(this);
		}

		// Coerce x to a promise
		function coerce(x) {
			if(x instanceof Promise) {
				return x;
			} else if (x !== Object(x)) {
				return fulfilled(x);
			}

			return promise(function(resolve, reject) {
				nextTick(function() {
					try {
						// We must check and assimilate in the same tick, but not the
						// current tick, careful only to access promiseOrValue.then once.
						var untrustedThen = x.then;

						if(typeof untrustedThen === 'function') {
							call(untrustedThen, x, resolve, reject);
						} else {
							// It's a value, create a fulfilled wrapper
							resolve(fulfilled(x));
						}
					} catch(e) {
						// Something went wrong, reject
						reject(e);
					}
				});
			});
		}

		// create an already-fulfilled promise used to break assimilation recursion
		function fulfilled(x) {
			var self = new Promise(function (onFulfilled) {
				try {
					return typeof onFulfilled == 'function'
						? coerce(onFulfilled(x)) : self;
				} catch (e) {
					return rejected(e);
				}
			});

			return self;
		}

		// create an already-rejected promise
		function rejected(x) {
			var self = new Promise(function (_, onRejected) {
				try {
					return typeof onRejected == 'function'
						? coerce(onRejected(x)) : self;
				} catch (e) {
					return rejected(e);
				}
			});

			return self;
		}
	}

	function noop() {}

});
})(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); }, this);<|endoftext|>


<commit_before>(function(){

	//call the UI page "home"

//	App.load('home');

	//poll gyro
	setInterval(function(){

		$.getJSON( "http://localhost:8080/nervousnet-api/raw-sensor-data/Gyroscope", function( data ) {

		});

	}, 1000);

})();

	 $(document).ready( function() {
				var graphinstance = new Graph( $('#mygraph') );

				var data = {
				  x: 0.5,
				  dx: 0.2,
				  y: []
				};
				for ( var i = 1, l = 30; i < l; i += 1 ) {
				  data.y.push( Math.sin( i * 0.2 + 0.5 ) );
				}

				graphinstance.newSerie( "serieTest" ).setLabel( "My serie" ).autoAxis().setData( data ).setMarkers();

				graphinstance.redraw();
				graphinstance.drawSeries();
	});
<commit_msg>bugfix<commit_after>(function(){

	//call the UI page "home"

//	App.load('home');

	//poll gyro
	setInterval(function(){

		$.getJSON( "http://localhost:8080/nervousnet-api/raw-sensor-data/Gyroscope", function( data ) {

		});

	}, 1000);

})();

	 $(document).ready( function() {
				var graphinstance = new Graph( $('#mygraph') );

				graphinstance.getXAxis().forceMin( 0 );
	graphinstance.getXAxis().forceMax( 50 );

	graphinstance.getYAxis().forceMin( 0 );
	graphinstance.getYAxis().forceMax( 50 );

	graphinstance.updateAxes();

	var shape = graphinstance.newShape( {
	  type: 'peakboundariescenter',
	  pos: {
	    x: 10,
	    y: 10
	  },
	  fillColor: 'rgba(200, 100, 100, 0.5)',
	  strokeColor: 'black',
	  locked: false,
	  selectable: true,

	  label: {
	    position: {
	      x: 4,
	      y: 3
	    },
	    text: 'test'
	  }
	} );

	shape.setData( 'pos', {
	  x: 10
	} );
	shape.setData( 'pos2', {
	  x: 2
	} );
	shape.setData( 'posCenter', {
	  x: 3
	} );

	shape.setY( 20 );

	shape.draw();

	graphinstance.redraw();
	graphinstance.drawSeries();
	});
<|endoftext|>


<commit_before>import h from 'virtual-dom/h'
import diff from 'virtual-dom/diff'
import patch from 'virtual-dom/patch'
import createElement from 'virtual-dom/create-element'

class Thunk {
  constructor(renderFn, state, shouldUpdate) {
    this.type = 'Thunk';
    this.renderFn = renderFn;
    this.state = state;
    this.shouldUpdate = shouldUpdate;
  }

  render(previous) {
    var previousState = previous ? previous.state : null;
    if (this.shouldUpdate(previousState)) {
      return this.renderFn(this.state);
    }
    return previous.vnode;
  }
}

export class Component {
  constructor(state) {
    this.state = state || {};
    this.name = this.constructor.name;
    this.thunk = new Thunk((state) => {
      return h(this.name, {}, [this.render(state)]);
    }, this.state, this.shouldUpdate);
  }

  render(state) {
    return h();
  }

  bind(root) {
    this.node = createElement(this.thunk);
    root.appendChild(this.node);
  }

  set(newState) {
    this.state = newState;
    let newThunk = new Thunk((state) => {
      return h(this.name, {}, [this.render(state)]);
    }, this.state, this.shouldUpdate);
    let patches = diff(this.thunk, newThunk);
    this.node = patch(this.node, patches);
    this.thunk = newThunk
  }

  shouldUpdate(previousState) {
    if (!previousState || !this.state) {
      return true;
    }
    let previousType = typeof previousState;
    let currentType = typeof this.state;
    if (previousType != currentType) {
      return true;
    }
    switch (currentType) {
    case 'object': // shallow check
      let previousKeys = Object.keys(previousState);
      let currentKeys = Object.keys(this.state);
      if (previousKeys.length != currentKeys.length) {
        return true;
      }
      let len = currentKeys.length;
      for (let i = 0; i < len; i++) {
        let key = currentKeys[i];
        if (previousState[key] !== this.state[key]) {
          return true;
        }
      }
      return false;
    default:
      return !(previousState === this.state);
    }
  }
}

export function e(selector, properties, children) {
  switch (typeof selector) {
  case 'string':
    return h(selector, properties, children);
  default:
    return new selector(properties).thunk;
  }
}

<commit_msg>do not set default state to {}<commit_after>import h from 'virtual-dom/h'
import diff from 'virtual-dom/diff'
import patch from 'virtual-dom/patch'
import createElement from 'virtual-dom/create-element'

class Thunk {
  constructor(renderFn, state, shouldUpdate) {
    this.type = 'Thunk';
    this.renderFn = renderFn;
    this.state = state;
    this.shouldUpdate = shouldUpdate;
  }

  render(previous) {
    var previousState = previous ? previous.state : null;
    if (this.shouldUpdate(previousState)) {
      return this.renderFn(this.state);
    }
    return previous.vnode;
  }
}

export class Component {
  constructor(state) {
    this.state = state;
    this.name = this.constructor.name;
    this.thunk = new Thunk((state) => {
      return h(this.name, {}, [this.render(state)]);
    }, this.state, this.shouldUpdate);
  }

  render(state) {
    return h();
  }

  bind(root) {
    this.node = createElement(this.thunk);
    root.appendChild(this.node);
  }

  set(newState) {
    this.state = newState;
    let newThunk = new Thunk((state) => {
      return h(this.name, {}, [this.render(state)]);
    }, this.state, this.shouldUpdate);
    let patches = diff(this.thunk, newThunk);
    this.node = patch(this.node, patches);
    this.thunk = newThunk
  }

  shouldUpdate(previousState) {
    if (!previousState || !this.state) {
      return true;
    }
    let previousType = typeof previousState;
    let currentType = typeof this.state;
    if (previousType != currentType) {
      return true;
    }
    switch (currentType) {
    case 'object': // shallow check
      let previousKeys = Object.keys(previousState);
      let currentKeys = Object.keys(this.state);
      if (previousKeys.length != currentKeys.length) {
        return true;
      }
      let len = currentKeys.length;
      for (let i = 0; i < len; i++) {
        let key = currentKeys[i];
        if (previousState[key] !== this.state[key]) {
          return true;
        }
      }
      return false;
    default:
      return !(previousState === this.state);
    }
  }
}

export function e(selector, properties, children) {
  switch (typeof selector) {
  case 'string':
    return h(selector, properties, children);
  default:
    return new selector(properties).thunk;
  }
}

<|endoftext|>


<commit_before>var tags = {};

function scrollToBody() {
	console.log("scrolling to body");
	$("html, body").animate({
		scrollTop: $("#body").offset().top
	}, 1000);
}

$(document).ready(function(){
	$(window).resize();

    showAllPostPreviews();
    var hash = decodeURI(window.location.hash);
    if (hash) {
        showPost(hash.substring(1, hash.length));
    }
});

$(window).resize(function(){
	if ($(this).width() < 1000) {
		$("#otherInfos").css("width", "90%");
		$("#content").css("width", "90%");
	} else {
		$("#otherInfos").css("width", "25%");
		$("#content").css("width", "60%");
	}
});

function showPostsPreviews(posts) {
	$("#shareLink").html("");
    if (posts != null) {
		// posts found
		$("#content").html("");
        for (i in posts) {
			var html = "";
			html += "

"
			$("#content").append(html);
			var xhttp = new XMLHttpRequest();
			xhttp["postId"] = posts[i];
			xhttp.onreadystatechange = function() {
			    if (this.readyState == 4 && this.status == 200) {
					var info = JSON.parse(this.responseText);
		            if (info == null) {
		                return;
		            }

					var html = "";
		            html += "
";
		            html += info.title;
		            html += "

";
		            html += info.timestamp;
		            html += "

";
		            html += info.extract;
		            html += " Read more...

Tags: ";
		            for (j in info.tags) {
		                html += "";
		                html += info.tags[j] + ", ";

		                // add tags to tags
						if ($.inArray(this["postId"], tags[info.tags[j]]) == -1) {
							tags[info.tags[j]].push(this["postId"]);
						}
		                /*if (tags[info.tags[j]] == null) {
		                    tags[info.tags[j]] = [this["postId"]];
		                } else {

		                }*/
		            }
		            html = html.substring(0, html.length - 2);
		            html += "
";

			        $("#" + this["postId"]).html(html);
			    }
			};
            xhttp.open("GET", posts[i] + "/info.json", true);
			xhttp.timeout = 2000;
            xhttp.send();
        }
    } else {
        // no posts
		$("#content").html("No Posts. ");
    }
}

function showAllPostPreviews() {
	var xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
	    if (this.readyState == 4 && this.status == 200) {
			var posts = JSON.parse(this.responseText).posts;
			showPostsPreviews(posts);
		}
	};
    xhttp.open("GET", "postSum.json", true);
	xhttp.timeout = 2000;
    xhttp.send();
}

function showTagPostsPreviews(tagName) {
	showPostsPreviews(tags[tagName]);
	$("#content").prepend("
Tag: " + tagName + "
");
}

function showPost(name) {
	var html = "";
	html = $("
").append($("#" + name).clone()).html();
	$("#content").html(html);
	$("#" + name + ">.postTitle").css("font-size", "40px");

	var xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
	    if (this.readyState == 4 && this.status == 200) {
			if (this.responseText != null) {
				var escapedContent = this.responseText.replace(/&/g, "&")
									.replace(/\n/g, "
")
									.replace(/        /g, "        ")
									.replace(/\t/g, "        ")
									//.replace(/</g, "<")
									//.replace(/>/g, ">")
									//.replace(/"/g, """)
									.replace(/'/g, "'")
									;

				$("#content>#" + name + ">.postExtract").html("
"+ escapedContent + "
");
				//$("#shareLink").html("Link to this page (URL does not work):
http://blog.zhukaihan.com/index.html#" + name + "
");
		    } else {
		        $("#content>#" + name + ">.postExtract").html("
No Such Article.
");
		    }
		}
	};
	xhttp.open("GET", name + "/content", true);
	xhttp.timeout = 2000;
	xhttp.send();

	scrollToBody();
}
<commit_msg>Update Code<commit_after>var tags = {};

function scrollToBody() {
	console.log("scrolling to body");
	$("html, body").animate({
		scrollTop: $("#body").offset().top
	}, 1000);
}

$(document).ready(function(){
	$(window).resize();

    showAllPostPreviews();
    var hash = decodeURI(window.location.hash);
    if (hash) {
        showPost(hash.substring(1, hash.length));
    }
});

$(window).resize(function(){
	if ($(this).width() < 1000) {
		$("#otherInfos").css("width", "90%");
		$("#content").css("width", "90%");
	} else {
		$("#otherInfos").css("width", "25%");
		$("#content").css("width", "60%");
	}
});

function showPostsPreviews(posts) {
	$("#shareLink").html("");
    if (posts != null) {
		// posts found
		$("#content").html("");
        for (i in posts) {
			var html = "";
			html += "

"
			$("#content").append(html);
			var xhttp = new XMLHttpRequest();
			xhttp["postId"] = posts[i];
			xhttp.onreadystatechange = function() {
			    if (this.readyState == 4 && this.status == 200) {
					var info = JSON.parse(this.responseText);
		            if (info == null) {
		                return;
		            }

					var html = "";
		            html += "
";
		            html += info.title;
		            html += "

";
		            html += info.timestamp;
		            html += "

";
		            html += info.extract;
		            html += " Read more...

Tags: ";
		            for (j in info.tags) {
		                html += "";
		                html += info.tags[j] + ", ";

		                // add tags to tags
		                if (tags[info.tags[j]] == null) {
		                    tags[info.tags[j]] = [this["postId"]];
		                } else {
		                    if ($.inArray(this["postId"], tags[info.tags[j]]) == -1) {
		                        tags[info.tags[j]].push(this["postId"]);
		                    }
		                }
		            }
		            html = html.substring(0, html.length - 2);
		            html += "
";

			        $("#" + this["postId"]).html(html);
			    }
			};
            xhttp.open("GET", posts[i] + "/info.json", true);
			xhttp.timeout = 2000;
            xhttp.send();
        }
    } else {
        // no posts
		$("#content").html("No Posts. ");
    }
}

function showAllPostPreviews() {
	var xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
	    if (this.readyState == 4 && this.status == 200) {
			var posts = JSON.parse(this.responseText).posts;
			showPostsPreviews(posts);
		}
	};
    xhttp.open("GET", "postSum.json", true);
	xhttp.timeout = 2000;
    xhttp.send();
}

function showTagPostsPreviews(tagName) {
	showPostsPreviews(tags[tagName]);
	$("#content").prepend("
Tag: " + tagName + "
");
}

function showPost(name) {
	var html = "";
	html = $("
").append($("#" + name).clone()).html();
	$("#content").html(html);
	$("#" + name + ">.postTitle").css("font-size", "40px");

	var xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
	    if (this.readyState == 4 && this.status == 200) {
			if (this.responseText != null) {
				var escapedContent = this.responseText.replace(/&/g, "&")
									.replace(/\n/g, "
")
									.replace(/        /g, "        ")
									.replace(/\t/g, "        ")
									//.replace(/</g, "<")
									//.replace(/>/g, ">")
									//.replace(/"/g, """)
									.replace(/'/g, "'")
									;

				$("#content>#" + name + ">.postExtract").html("
"+ escapedContent + "
");
				//$("#shareLink").html("Link to this page (URL does not work):
http://blog.zhukaihan.com/index.html#" + name + "
");
		    } else {
		        $("#content>#" + name + ">.postExtract").html("
No Such Article.
");
		    }
		}
	};
	xhttp.open("GET", name + "/content", true);
	xhttp.timeout = 2000;
	xhttp.send();

	scrollToBody();
}
<|endoftext|>


<commit_before>import { createSelector } from 'reselect';
import { createSearchAction, getSearchSelectors } from 'redux-search';
import faker from 'faker';
import Immutable from 'immutable';
import keymirror from 'keymirror';
import { env, api, logger } from './commons';
import _ from 'lodash';
import React, { PropTypes } from 'react';

api.init({
  latency: 100
});

export const SearchOptions = Immutable.Record({
  limit: 10,
  page: 1,
  pages: 0,
  total: 0
});

export const State = Immutable.Record({
  plugins: Immutable.OrderedMap(),
  isFetching: false,
  searchOptions: SearchOptions,
  labelFilter: Immutable.Record({//fixme: that should become label: search, sort: field
    field: 'title',
    searchField: null,
    asc: false,
    search: []
  })
});
/*
buildDate: "Mar 03, 2011"
dependencies: Array[0]
developers: Array[1]
excerpt: "This (experimental) plug-in exposes the jenkins build extension
 points (SCM, Build, Publish) to a groovy scripting environment that has
  some DSL-style extensions for ease of development."
gav: "jenkins:AdaptivePlugin:0.1"
labels: Array[2]
name: "AdaptivePlugin"
releaseTimestamp: "2011-03-03T16:49:24.00Z"
requiredCore: "1.398"
scm: "github.com"
sha1: "il8z91iDnqVMu78Ghj8q2swCpdk="
title: "Jenkins Adaptive DSL Plugin"
url: "http://updates.jenkins-ci.org/download/plugins/AdaptivePlugin/0.1/AdaptivePlugin.hpi"
version: "0.1"
wiki: "https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Adaptive+Plugin"
*/
// Immutable Data attributes must be accessible as getters
const Record = Immutable.Record({
  id: null,
  name: null,
  title: '',
  buildDate: null,
  releaseTimestamp: null,
  version: null,
  wiki: '',
  excerpt: '',
  iconDom: null,
  requiredCore: null,
  developers: [],
  labels: [],
  dependencies: []
});

export const ACTION_TYPES = keymirror({
  CLEAR_PLUGIN_DATA: null,
  FETCH_PLUGIN_DATA: null,
  SET_PLUGIN_DATA: null,
  SET_LABEL_FILTER: null,
  SET_QUERY_INFO: null
});

export const actionHandlers = {
  [ACTION_TYPES.CLEAR_PLUGIN_DATA](state) {
    return state.set('plugins', Immutable.Map());
  },
  [ACTION_TYPES.FETCH_PLUGIN_DATA](state, {}): State {
    return state.set('isFetching', !state.isFetching);
  },
  [ACTION_TYPES.SET_PLUGIN_DATA](state, { payload }): State {
    return state.set('plugins', payload);
  },
  [ACTION_TYPES.SET_LABEL_FILTER](state, { payload }): State {
    return state.set('labelFilter', payload);
  },
  [ACTION_TYPES.SET_QUERY_INFO](state, { payload }): State {
    return state.set('searchOptions', payload);
  }
};

export const actions = {
    //FIXME: This should not inject React DOM here, but.... hack...
  makeIcon(title, type){
    title = title
      .replace('Jenkins ','')
      .replace('jenkins ','')
      .replace(' Plugin','')
      .replace(' Plug-in','')
      .replace(' lugin','');
    type = type || '';
    const colors = ['#6D6B6D','#DCD9D8','#D33833','#335061','#81B0C4','#709aaa','#000'];
    const color = colors[Math.floor(Math.random() * (colors.length - 1))];
    const iconClass=`i ${type}  color${color}`;
    const color = colors[(title.length % 7)]; //pick color based on chars in the name to make semi-random, but fixed color per-plugin
    const iconClass=`i ${type};
    color = ${color}`;

    const firstLetter = title.substring(0,1).toUpperCase();
    const firstSpace = title.indexOf(' ') + 1;
    const nextIndx = (firstSpace === 0)?
        1: firstSpace;
    const nextLetter = title.substring(nextIndx,nextIndx + 1);

    return (

        {firstLetter}
        {nextLetter}

    );
  },

  clearPluginData: () => ({ type: ACTION_TYPES.CLEAR_PLUGIN_DATA }),

  fetchPluginData: () => ({ type: ACTION_TYPES.FETCH_PLUGIN_DATA }),

  setFilter(filter) {
    return (dispatch) => {
      dispatch({
        type: ACTION_TYPES.SET_LABEL_FILTER,
        payload: filter
      });
    };
  },

  generatePluginData(query={}) {
    return (dispatch, getState) => {
      logger.log(query);
      let url;
      if (query.category) {
        const CATEGORY_URL = '/getCategories';
        url = `${CATEGORY_URL}?id=${query.category}`;
      }else if(query.latest){
        url = '/latest';
      }else {
        const PLUGINS_URL = '/plugins';
        url = `${PLUGINS_URL}?page=${query.page || 1}&limit=${query.limit || 10}&q=${query.q || ''}`;
      }
      logger.log(query, url);
      dispatch(actions.clearPluginData());
      dispatch(actions.fetchPluginData());
      const plugins = {};

      return api.getJSON(url,(error, data) => {
        if (data) {
          const searchOptions = new SearchOptions({
            limit: data.limit,
            page: data.page,
            pages: data.pages,
            total: data.total
          });

          const items = data.docs;
          _.forEach(items, (item) => {
            _.set(item, 'id', item.sha1);
            _.set(item, 'iconDom', actions.makeIcon(item.title));
            plugins[item.id] = new Record(item);
          });
          const recordsMap = Immutable.Map(plugins);
          dispatch({
            type: ACTION_TYPES.SET_PLUGIN_DATA,
            payload: recordsMap
          });
          dispatch({
            type: ACTION_TYPES.SET_QUERY_INFO,
            payload: searchOptions
          });
          dispatch(actions.fetchPluginData());
        }
      });
    };
  },
  searchPluginData: createSearchAction('plugins')
};

export function groupAndCountLabels(recordsMap) {
  const labelMap = _.map(
      _.groupBy(
        _.flatten(recordsMap.toArray().map((a) => a.labels)
      )
    ), (array, item) => {
      return {
        value: array.length,
        key: item
      };
    }
  );
  return Immutable.List(labelMap);
}

export const resources = state => state.resources;
export const resourceSelector = (resourceName, state) => state.resources.get(resourceName);
export const plugins = createSelector([resources], resources => resources.plugins);
export const searchOptions = createSelector([resources], resources => resources.searchOptions);

export const isFetching = createSelector([resources], resources => resources.isFetching);
export const labelFilter = createSelector([resources], resources => resources.labelFilter);

const pluginSelectors = getSearchSelectors({ resourceName: 'plugins', resourceSelector });
export const searchText = pluginSelectors.text;
export const filteredList = createSelector([pluginSelectors.result], result => Immutable.List(result));

export const getVisiblePlugins = createSelector(
  [ filteredList, plugins ],
  (filteredList, plugins) => {
    return filteredList.map(
      (id) => {
        return plugins.get(id);
      });
  }
);

export const totalSize = createSelector(
  [ searchOptions ],
  ( searchOptions ) => {
    return searchOptions.total || 0;
  }
);

export const filterVisibleList = createSelector (
  [getVisiblePlugins, labelFilter],
  (plugins, labelFilter) => {

    if (labelFilter instanceof Function) {
      labelFilter = labelFilter();
    }

    const list  = plugins
    .filter(
      item => {
        if ( !labelFilter.searchField || !labelFilter.search || !labelFilter.search.length > 0) {
          return true;
        }
        const matchIndex = _.findIndex(item[labelFilter.searchField], (i) => {
          let match = false;
          labelFilter.search.some(searchFilter => {
            match = (i === searchFilter);
            return match;
          });
          return match;
        });
        return ( matchIndex >= 0);
      }
    )
    .sortBy(plugin => {
      return plugin[labelFilter.field];}, (plugin, nextPlugin) => {
      if (labelFilter.asc) {
        return nextPlugin.localeCompare(plugin);
      } else {
        return plugin.localeCompare(nextPlugin);
      }
    });
    logger.warn(`xxx ${list}`);
    return list;
  }
);

export const getVisiblePluginsLabels = createSelector(
  [ filterVisibleList ],
  ( plugins ) => {
    return groupAndCountLabels(plugins);
  }
);

export function reducer(state = new State(), action: Object): State {
  const { type } = action;
  if (type in actionHandlers) {
    return actionHandlers[type](state, action);
  } else {
    return state;
  }
}
<commit_msg>[issue/WEBSITE-89] fix typo<commit_after>import { createSelector } from 'reselect';
import { createSearchAction, getSearchSelectors } from 'redux-search';
import faker from 'faker';
import Immutable from 'immutable';
import keymirror from 'keymirror';
import { env, api, logger } from './commons';
import _ from 'lodash';
import React, { PropTypes } from 'react';

api.init({
  latency: 100
});

export const SearchOptions = Immutable.Record({
  limit: 10,
  page: 1,
  pages: 0,
  total: 0
});

export const State = Immutable.Record({
  plugins: Immutable.OrderedMap(),
  isFetching: false,
  searchOptions: SearchOptions,
  labelFilter: Immutable.Record({//fixme: that should become label: search, sort: field
    field: 'title',
    searchField: null,
    asc: false,
    search: []
  })
});
/*
buildDate: "Mar 03, 2011"
dependencies: Array[0]
developers: Array[1]
excerpt: "This (experimental) plug-in exposes the jenkins build extension
 points (SCM, Build, Publish) to a groovy scripting environment that has
  some DSL-style extensions for ease of development."
gav: "jenkins:AdaptivePlugin:0.1"
labels: Array[2]
name: "AdaptivePlugin"
releaseTimestamp: "2011-03-03T16:49:24.00Z"
requiredCore: "1.398"
scm: "github.com"
sha1: "il8z91iDnqVMu78Ghj8q2swCpdk="
title: "Jenkins Adaptive DSL Plugin"
url: "http://updates.jenkins-ci.org/download/plugins/AdaptivePlugin/0.1/AdaptivePlugin.hpi"
version: "0.1"
wiki: "https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Adaptive+Plugin"
*/
// Immutable Data attributes must be accessible as getters
const Record = Immutable.Record({
  id: null,
  name: null,
  title: '',
  buildDate: null,
  releaseTimestamp: null,
  version: null,
  wiki: '',
  excerpt: '',
  iconDom: null,
  requiredCore: null,
  developers: [],
  labels: [],
  dependencies: []
});

export const ACTION_TYPES = keymirror({
  CLEAR_PLUGIN_DATA: null,
  FETCH_PLUGIN_DATA: null,
  SET_PLUGIN_DATA: null,
  SET_LABEL_FILTER: null,
  SET_QUERY_INFO: null
});

export const actionHandlers = {
  [ACTION_TYPES.CLEAR_PLUGIN_DATA](state) {
    return state.set('plugins', Immutable.Map());
  },
  [ACTION_TYPES.FETCH_PLUGIN_DATA](state, {}): State {
    return state.set('isFetching', !state.isFetching);
  },
  [ACTION_TYPES.SET_PLUGIN_DATA](state, { payload }): State {
    return state.set('plugins', payload);
  },
  [ACTION_TYPES.SET_LABEL_FILTER](state, { payload }): State {
    return state.set('labelFilter', payload);
  },
  [ACTION_TYPES.SET_QUERY_INFO](state, { payload }): State {
    return state.set('searchOptions', payload);
  }
};

export const actions = {
    //FIXME: This should not inject React DOM here, but.... hack...
  makeIcon(title, type){
    title = title
      .replace('Jenkins ','')
      .replace('jenkins ','')
      .replace(' Plugin','')
      .replace(' Plug-in','')
      .replace(' lugin','');
    type = type || '';
    const colors = ['#6D6B6D','#DCD9D8','#D33833','#335061','#81B0C4','#709aaa','#000'];
    const color = colors[(title.length % 7)]; //pick color based on chars in the name to make semi-random, but fixed color per-plugin
    const iconClass=`i ${type};
    color = ${color}`;

    const firstLetter = title.substring(0,1).toUpperCase();
    const firstSpace = title.indexOf(' ') + 1;
    const nextIndx = (firstSpace === 0)?
        1: firstSpace;
    const nextLetter = title.substring(nextIndx,nextIndx + 1);

    return (

        {firstLetter}
        {nextLetter}

    );
  },

  clearPluginData: () => ({ type: ACTION_TYPES.CLEAR_PLUGIN_DATA }),

  fetchPluginData: () => ({ type: ACTION_TYPES.FETCH_PLUGIN_DATA }),

  setFilter(filter) {
    return (dispatch) => {
      dispatch({
        type: ACTION_TYPES.SET_LABEL_FILTER,
        payload: filter
      });
    };
  },

  generatePluginData(query={}) {
    return (dispatch, getState) => {
      logger.log(query);
      let url;
      if (query.category) {
        const CATEGORY_URL = '/getCategories';
        url = `${CATEGORY_URL}?id=${query.category}`;
      }else if(query.latest){
        url = '/latest';
      }else {
        const PLUGINS_URL = '/plugins';
        url = `${PLUGINS_URL}?page=${query.page || 1}&limit=${query.limit || 10}&q=${query.q || ''}`;
      }
      logger.log(query, url);
      dispatch(actions.clearPluginData());
      dispatch(actions.fetchPluginData());
      const plugins = {};

      return api.getJSON(url,(error, data) => {
        if (data) {
          const searchOptions = new SearchOptions({
            limit: data.limit,
            page: data.page,
            pages: data.pages,
            total: data.total
          });

          const items = data.docs;
          _.forEach(items, (item) => {
            _.set(item, 'id', item.sha1);
            _.set(item, 'iconDom', actions.makeIcon(item.title));
            plugins[item.id] = new Record(item);
          });
          const recordsMap = Immutable.Map(plugins);
          dispatch({
            type: ACTION_TYPES.SET_PLUGIN_DATA,
            payload: recordsMap
          });
          dispatch({
            type: ACTION_TYPES.SET_QUERY_INFO,
            payload: searchOptions
          });
          dispatch(actions.fetchPluginData());
        }
      });
    };
  },
  searchPluginData: createSearchAction('plugins')
};

export function groupAndCountLabels(recordsMap) {
  const labelMap = _.map(
      _.groupBy(
        _.flatten(recordsMap.toArray().map((a) => a.labels)
      )
    ), (array, item) => {
      return {
        value: array.length,
        key: item
      };
    }
  );
  return Immutable.List(labelMap);
}

export const resources = state => state.resources;
export const resourceSelector = (resourceName, state) => state.resources.get(resourceName);
export const plugins = createSelector([resources], resources => resources.plugins);
export const searchOptions = createSelector([resources], resources => resources.searchOptions);

export const isFetching = createSelector([resources], resources => resources.isFetching);
export const labelFilter = createSelector([resources], resources => resources.labelFilter);

const pluginSelectors = getSearchSelectors({ resourceName: 'plugins', resourceSelector });
export const searchText = pluginSelectors.text;
export const filteredList = createSelector([pluginSelectors.result], result => Immutable.List(result));

export const getVisiblePlugins = createSelector(
  [ filteredList, plugins ],
  (filteredList, plugins) => {
    return filteredList.map(
      (id) => {
        return plugins.get(id);
      });
  }
);

export const totalSize = createSelector(
  [ searchOptions ],
  ( searchOptions ) => {
    return searchOptions.total || 0;
  }
);

export const filterVisibleList = createSelector (
  [getVisiblePlugins, labelFilter],
  (plugins, labelFilter) => {

    if (labelFilter instanceof Function) {
      labelFilter = labelFilter();
    }

    const list  = plugins
    .filter(
      item => {
        if ( !labelFilter.searchField || !labelFilter.search || !labelFilter.search.length > 0) {
          return true;
        }
        const matchIndex = _.findIndex(item[labelFilter.searchField], (i) => {
          let match = false;
          labelFilter.search.some(searchFilter => {
            match = (i === searchFilter);
            return match;
          });
          return match;
        });
        return ( matchIndex >= 0);
      }
    )
    .sortBy(plugin => {
      return plugin[labelFilter.field];}, (plugin, nextPlugin) => {
      if (labelFilter.asc) {
        return nextPlugin.localeCompare(plugin);
      } else {
        return plugin.localeCompare(nextPlugin);
      }
    });
    logger.warn(`xxx ${list}`);
    return list;
  }
);

export const getVisiblePluginsLabels = createSelector(
  [ filterVisibleList ],
  ( plugins ) => {
    return groupAndCountLabels(plugins);
  }
);

export function reducer(state = new State(), action: Object): State {
  const { type } = action;
  if (type in actionHandlers) {
    return actionHandlers[type](state, action);
  } else {
    return state;
  }
}
<|endoftext|>


<commit_before>var chai     = require('chai'),
    assert   = require('chai').assert,
    expect   = require('chai').expect,
    scv      = require('../scv.js'),
    chaihttp = require('chai-http'),
    should   = chai.should(),
    config   = require('../../config.js'),
    effector = require('../helper/effectors.js'),
    server   = require('../../app.js');

    chai.use(chaihttp);

describe('Initial test', function(){
    it('1+1 should be 2', function(){
        assert.equal(1+1, 2, 'The answer should be 2')
    });

    it('Scv should respond', function(){
        var result = scv.hello();
        expect(result).to.be.not.null;
    });

    it('Scv should respond whats going on? scv ready.', function(){
        var result = scv.hello();
        assert.equal(result,"What's going on? SCV ready.", "Should say What's going on? SCV ready.");
    });
});

describe('Ensure config file is valid', function(){
    it('Config file should be populated', function(){
        expect(config).to.be.not.null;
    });

    it('Check config.scv', function(){
        expect(config.scv).to.be.not.null;
    });

    it('Check config.facebook', function(){
        expect(config.scv).to.be.not.null;
    });
});

describe('Helper effectors.js (isAscii)', function(){
    it('Verify string (whats 1+1) is ascii', function(){
        var input = "what's 1+1";
        var result = effector.isAscii(input);
        assert.isTrue(result);
    });

    it('Verify string (嗨，我喜歡藍色的顏色) is NOT ascii', function(){
        var input = "嗨，我喜歡藍色的顏色";
        var result = effector.isAscii(input);
        assert.isFalse(result);
    });

    it('Verify string (Hi Unë si blu ngjyra) is NOT ascii', function(){
        var input = "Hi Unë si blu ngjyra";
        var result = effector.isAscii(input);
        assert.isFalse(result);
    });

    it('Verify string (Привет мне нравится синий цвет) is NOT ascii', function(){
        var input = "Привет мне нравится синий цвет";
        var result = effector.isAscii(input);
        assert.isFalse(result);
    });
});

describe('Helper effectors.js (getEquation)', function(){
    it('whats 1+1 returns 1+1', function(){
        var input = "what's 1+1";
        var result = effector.getEquation(input);
        assert.equal(result,"1+1");
    });

    it('Can you tell me what is 3*1+4-6 returns 3*1+4-6', function(){
        var input = "Can you tell me what is 3*1+4-6";
        var result = effector.getEquation(input);
        assert.equal(result,"3*1+4-6");
    });

     it('Can you tell me what is (1+2)*6/2 please? return (1+2)*6/2', function(){
        var input = "Can you tell me what is (1+2)*6/2 please?";
        var result = effector.getEquation(input);
        assert.equal(result,"(1+2)*6/2");
    });
});

describe('Helper effectors.js (computeAnswer)', function(){
    it('(1+2)^2 should return 9', function(){
        var input = "(1+2)^2";
        var result = effector.computeAnswer(input);
        assert.equal(result,"9");
    });

    it('12+60-23 should return 49', function(){
        var input = "12+60-23";
        var result = effector.computeAnswer(input);
        assert.equal(result,"49");
    });

    it('(5 + 3) * 12 / 3 should return 32', function(){
        var input = "(5 + 3) * 12 / 3";
        var result = effector.computeAnswer(input);
        assert.equal(result,"32");
    });

    it('1*2^2/6 should return  0.6666666666666666', function(){
        var input = "1*2^2/6";
        var result = effector.computeAnswer(input);
        assert.equal(result,"0.6666666666666666");
    });
    it('2*2+1*+2 should fail', function(){
        var input = "2*2+1+*2";
        var result = effector.computeAnswer(input);
        assert.equal(result, config.scv.error4);
    });
});

describe('/GET ping', function(){
    it('Ping should respond with a whats going on? scv ready.', function(done){
        chai.request(server)
            .get("/api/ping")
            .end((err, res) => {
                res.should.have.status(200);
                res.should.be.a("object");
                assert.equal(res.body.response,"What's going on? SCV ready.", "Should say What's going on? SCV ready.");
              done();
            });
    });
});
<commit_msg>added more test cases<commit_after>var chai     = require('chai'),
    assert   = require('chai').assert,
    expect   = require('chai').expect,
    scv      = require('../scv.js'),
    chaihttp = require('chai-http'),
    should   = chai.should(),
    config   = require('../../config.js'),
    effector = require('../helper/effectors.js'),
    server   = require('../../app.js');

    chai.use(chaihttp);

describe('Initial test', function(){
    it('1+1 should be 2', function(){
        assert.equal(1+1, 2, 'The answer should be 2')
    });

    it('Scv should respond', function(){
        var result = scv.hello();
        expect(result).to.be.not.null;
    });

    it('Scv should respond whats going on? scv ready.', function(){
        var result = scv.hello();
        assert.equal(result,"What's going on? SCV ready.", "Should say What's going on? SCV ready.");
    });
});

describe('Ensure config file is valid', function(){
    it('Config file should be populated', function(){
        expect(config).to.be.not.null;
    });

    it('Check config.scv', function(){
        expect(config.scv).to.be.not.null;
    });

    it('Check config.facebook', function(){
        expect(config.scv).to.be.not.null;
    });
});

describe('Helper effectors.js (isAscii)', function(){
    it('Verify string (whats 1+1) is ascii', function(){
        var input = "what's 1+1";
        var result = effector.isAscii(input);
        assert.isTrue(result);
    });

    it('Verify string (嗨，我喜歡藍色的顏色) is NOT ascii', function(){
        var input = "嗨，我喜歡藍色的顏色";
        var result = effector.isAscii(input);
        assert.isFalse(result);
    });

    it('Verify string (Hi Unë si blu ngjyra) is NOT ascii', function(){
        var input = "Hi Unë si blu ngjyra";
        var result = effector.isAscii(input);
        assert.isFalse(result);
    });

    it('Verify string (Привет мне нравится синий цвет) is NOT ascii', function(){
        var input = "Привет мне нравится синий цвет";
        var result = effector.isAscii(input);
        assert.isFalse(result);
    });
});

describe('Helper effectors.js (getEquation)', function(){
    it('whats 1+1 returns 1+1', function(){
        var input = "what's 1+1";
        var result = effector.getEquation(input);
        assert.equal(result,"1+1");
    });

    it('Can you tell me what is 3*1+4-6 returns 3*1+4-6', function(){
        var input = "Can you tell me what is 3*1+4-6";
        var result = effector.getEquation(input);
        assert.equal(result,"3*1+4-6");
    });

    it('Can you tell me what is (1+2)*6/2 please? return (1+2)*6/2', function(){
        var input = "Can you tell me what is (1+2)*6/2 please?";
        var result = effector.getEquation(input);
        assert.equal(result,"(1+2)*6/2");
    });

    it('<script>alert("I am trying to be malicious")</script>', function(){
        var input = "<script>alert('I am trying to be malicious')</script>";
        var result = effector.getEquation(input);
        assert.equal(result,"()/");
    });

    it('xss java', function(){
        var input = "<IMG SRC=javascript:alert('XSS')>";
        var result = effector.getEquation(input);
        assert.equal(result,"106971189711599114105112116589710810111411640398883833941");
    });
});

describe('Helper effectors.js (computeAnswer)', function(){
    it('(1+2)^2 should return 9', function(){
        var input = "(1+2)^2";
        var result = effector.computeAnswer(input);
        assert.equal(result,"9");
    });

    it('12+60-23 should return 49', function(){
        var input = "12+60-23";
        var result = effector.computeAnswer(input);
        assert.equal(result,"49");
    });

    it('(5 + 3) * 12 / 3 should return 32', function(){
        var input = "(5 + 3) * 12 / 3";
        var result = effector.computeAnswer(input);
        assert.equal(result,"32");
    });

    it('1*2^2/6 should return  0.6666666666666666', function(){
        var input = "1*2^2/6";
        var result = effector.computeAnswer(input);
        assert.equal(result,"0.6666666666666666");
    });
    it('2*2+1*+2 should fail', function(){
        var input = "2*2+1+*2";
        var result = effector.computeAnswer(input);
        assert.equal(result, config.scv.error4);
    });
});

describe('/GET ping', function(){
    it('Ping should respond with a whats going on? scv ready.', function(done){
        chai.request(server)
            .get("/api/ping")
            .end((err, res) => {
                res.should.have.status(200);
                res.should.be.a("object");
                assert.equal(res.body.response,"What's going on? SCV ready.", "Should say What's going on? SCV ready.");
              done();
            });
    });
});
<|endoftext|>