<commit_before>(function() {
    //Features TODO:
    // * Methods (https://github.com/obiot/melonJS/blob/master/src/entity/entity.js)
    //      - flipX
    //      - flipY
    //      - doWalk
    //      - doClimb
    //      - doJump
    //      - forceJump
    //      - checkSlope
    //      - updateMovement (slopes/breakable tiles)
    gf.Entity = gf.SceneObject.extend({
        //initializes a new entity with the start position (pos)
        //and properties (settings). Many of these properties can
        //be specified in Tiled.
        init: function(pos, settings) {
            /****************************************************************************
             * Properties that are defined in the `settings` object,
             * these can be specified in the properties of the object layer
             * in Tiled, and overriden on a per-object basis
             ****************************************************************************/
            this.type = gf.types.ENTITY.NEUTRAL;

            //scale of the entity
            this.scale = 1;

            //can collide with other entities
            this.isCollidable = true;

            //can collide with the map when moving
            this.isMapCollidable = true;

            //is the entity visible
            this.isVisible = true;

            //is an entity
            this.isEntity = true;

            //you can still set these in Tiled by using "x|y" notation
            //velocity of the entity (units per tick)
            this.velocity = new THREE.Vector2(0, 0);

            //max velocity to cap the entity at (units per tick)
            this.maxVelocity = new THREE.Vector2(15, 15);

            //acceleration of the entity when moving (units per second)
            this.accel = new THREE.Vector2(250, 250);

            //size of the hitbox
            this.hitSize = new THREE.Vector2(0, 0);

            //offset from the center to have the hitbox NOT IMPLEMENTED
            this.hitOffset = new THREE.Vector2(0, 0);

            //the name of this entitiy
            this.name = '';

            //friction to apply to this entities movement
            this.friction = settings.friction || gf.game.friction;

            //gravity of the world
            this.gravity = settings.gravity || gf.game.gravity;

            //entity alive
            this.alive = true;

            //entity falling (read only)
            this.falling = false;

            //entity jumping (read only)
            this.jumping = false;

            /****************************************************************************
             * Call base constructor
             ****************************************************************************/
            this._super(settings);

            /****************************************************************************
             * Create the actual object for the scene
             ****************************************************************************/
            //if the hitbox size isn't set, use the same as normal size
            if(this.hitSize.x === 0 && this.hitSize.y === 0)
                this.hitSize = this.size.clone();

            //scale size vectors
            this.scaledSize = this.size.clone().multiplyScalar(this.scale);
            this.scaledHitSize = this.hitSize.clone().multiplyScalar(this.scale);
            this.scaledHitOffset = this.hitOffset.clone().multiplyScalar(this.scale);

            //create main entity mesh
            this._createMesh();

            //create a second mesh for the hitbox
            this._createHitboxMesh();

            //set default position
            this.setPosition(pos);
        },
        //calculates distance between this object and another
        distanceTo: function(obj) {
            var dx = this._hitboxMesh.position.x - entity._hitboxMesh.position.x,
                dy = this._hitboxMesh.position.y - entity._hitboxMesh.position.y;

            return Math.sqrt(dx*dx + dy*dy);
        },
        //computes the velocity taking into account gravity, friction, etc
        computeVelocity: function(vel) {
            //apply gravity
            if(this.gravity) {
                vel.y -= !this.onladder ? (this.gravity * gf.game._delta) : 0;

                //check if falling/jumping
                this.falling = (vel.y > 0);
                this.jumping = this.falling ? false : this.jumping;
            }

            //apply friction
            if(this.friction.x) vel.x = gf.utils.applyFriction(vel.x, this.friction.x);
            if(this.friction.y) vel.y = gf.utils.applyFriction(vel.y, this.friction.y);

            //cap velocity
            if(vel.x) vel.x = gf.utils.clamp(vel.x, -this.maxVelocity.x, this.maxVelocity.x);
            if(vel.y) vel.y = gf.utils.clamp(vel.y, -this.maxVelocity.y, this.maxVelocity.y);

            return this;
        },
        //from http://gamedev.stackexchange.com/questions/586/what-is-the-fastest-way-to-work-out-2d-bounding-box-intersection
        intersects: function(entity)  {
            return (Math.abs(this._hitboxMesh.position.x - entity._hitboxMesh.position.x) * 2 < (this.hitSize.x + entity.hitSize.x)) &&
                    (Math.abs(this._hitboxMesh.position.y - entity._hitboxMesh.position.y) * 2 < (this.hitSize.y + entity.hitSize.y));
        },
        checkCollision: function(entity) {
            //response vector
            var p = new THREE.Vector2(0, 0);

            //check if hitboxes intersect
            if (this.intersects(entity)) {
                //compute delta between this & entity
                var dx = this._hitboxMesh.position.x - entity._hitboxMesh.position.x,
                    dy = this._hitboxMesh.position.y - entity._hitboxMesh.position.y;

                //compute penetration depth for both axis
                p.x = dx / 2;
                p.y = dy / 2;

                //check and "normalize" axis
                /*if (p.x < p.y) {
                    p.y = 0;
                    p.x = dx < 0 ? -p.x : p.x;
                } else {
                    p.x = 0;
                    p.y = dy < 0 ? -p.y : p.y;
                }*/
            }

            return p;
        },
        addToScene: function(scene) {
            this._super(scene);

            if(this._hitboxMesh) scene.add(this._hitboxMesh);

            return this;
        },
        addToPool: function(name) {
            return gf.entityPool.add(name || this.name, this);
        },
        removeFromScene: function(scene) {
            this._super(scene);

            if(this._hitboxMesh) scene.remove(this._hitboxMesh);

            return this;
        },
        updateMovement: function() {
            if(this.velocity.x === 0 && this.velocity.y === 0) return;

            var colliders = gf.game.world !== undefined ? gf.game.world.checkCollision(this._hitboxMesh, this.scaledHitSize, this.velocity) : [];

            //update flags
            this.onladder = false;

            //collisions
            var self = this;
            gf.utils.each(colliders, function(i, collider) {
                var tile = collider.tile,
                    axis = collider.axis;

                self.onladder = (tile.type == gf.types.COLLISION.LADDER ? true : self.onladder);

                //if a solid tile
                if(tile.type == gf.types.COLLISION.SOLID) {
                    //if it is a slope, apply the normal
                    if(tile.normal && (!self.velocity.x || !self.velocity.y)) {
                        var badMovement = tile.normal.clone().multiplyScalar(self.velocity.dot(tile.normal)),
                            newMovement = self.velocity.clone().subSelf(badMovement);

                        self.velocity.addSelf(newMovement);
                        return false;
                    }
                    //otherwise just stop movement
                    else {
                        self.velocity[axis] = 0;
                    }
                }
            });

            //TODO: Edge rolling (if you are on the tip edge of a blocking tile, roll around it)

            //apply gravity, friction, etc to this velocity
            this.computeVelocity(this.velocity);

            //do the actual entity movement
            this.moveEntity();

            gf.debug._playerColliders = colliders;
            gf.debug._playerColliders.dirty = true;

            return colliders;
        },
        moveEntity: function(vel) {
            //optionally override current velocity
            vel = vel || this.velocity;

            if(vel.x === 0 && vel.y === 0) return;

            //update the entity position
            this._mesh.translateX(vel.x);
            this._mesh.translateY(vel.y);

            //also update the hitbox mesh if it is different
            if(this._hitboxMesh) {
                this._hitboxMesh.translateX(vel.x);
                this._hitboxMesh.translateY(vel.y);
            }

            //onMove event
            this.onMove(vel);

            //emit movement
            gf.event.publish(gf.types.EVENT.ENTITY_MOVE + '.' + this.id, vel);

            return this;
        },
        //On Collision Event
        // called when this object is collided into by another, by default if something collides with
        // a collectable entity we remove the collectable
        //vec - Collision Vector (THREE.Vector2)
        //obj - Colliding object (gf.Entity)
        onCollision: function(vec, obj) {
            if(this.collidable && this.type == gf.types.ENTIY.COLLECTABLE)
                gf.game.removeObject(this);

            return this;
        },

        //On Move Event
        // called when this entity moves
        //vel - Velocity the entity moved (THREE.Vector2)
        onMove: function(vel) {
            return this;
        },

        //On Tile Break Event
        // called when a tile is broken
        //tile - the tile that is broken
        onTileBreak: function(tile) {
            return this;
        },

        //Privates
        _doSetPos: function(x, y, z) {
            this._super(x, y, z);

            if(this._hitboxMesh) {
                this._hitboxMesh.position.set(x, y, z);
                if(this.hitOffset) {
                    this._hitboxMesh.translateX(this.hitOffset.x);
                    this._hitboxMesh.translateY(this.hitOffset.y);
                }
            }
        },
        _createMesh: function() {
            if(this._mesh) return;

            this._materials = [];

            this._materials.push(new THREE.MeshBasicMaterial({ transparent: true }));

            //add outline material if needed
            if(gf.debug.showOutline) {
                this._materials.push(new THREE.MeshBasicMaterial({
                    color: gf.debug.outlineColor,
                    wireframe: true,
                    wireframeLinewidth: 1
                }));
            }

            this._geom = new THREE.PlaneGeometry(this.scaledSize.x, this.scaledSize.y);
            this._mesh = THREE.SceneUtils.createMultiMaterialObject(this._geom, this._materials);//new THREE.Mesh(this._geom, this._materials);

            //multimaterials object doesn't have .geometry defined
            this._mesh.geometry = this._geom;

            //set visible
            //this._mesh.visible = this.isVisible;
        },
        _createHitboxMesh: function() {
            if(this._hitboxMesh) return;

            this._hitboxMaterial = new THREE.MeshBasicMaterial({
                color: gf.debug.hitboxColor,
                wireframe: gf.debug.showHitbox,
                wireframeLinewidth: 1
            });

            this._hitboxGeom = new THREE.PlaneGeometry(1, 1);

            this._hitboxMesh = new THREE.Mesh(this._hitboxGeom, this._hitboxMaterial);
            this._hitboxMesh.scale.set(this.scaledHitSize.x, this.scaledHitSize.y, 1);
        },
    });
})();<commit_msg>Fix an issue when debug is turned off<commit_after>(function() {
    //Features TODO:
    // * Methods (https://github.com/obiot/melonJS/blob/master/src/entity/entity.js)
    //      - flipX
    //      - flipY
    //      - doWalk
    //      - doClimb
    //      - doJump
    //      - forceJump
    //      - checkSlope
    //      - updateMovement (slopes/breakable tiles)
    gf.Entity = gf.SceneObject.extend({
        //initializes a new entity with the start position (pos)
        //and properties (settings). Many of these properties can
        //be specified in Tiled.
        init: function(pos, settings) {
            /****************************************************************************
             * Properties that are defined in the `settings` object,
             * these can be specified in the properties of the object layer
             * in Tiled, and overriden on a per-object basis
             ****************************************************************************/
            this.type = gf.types.ENTITY.NEUTRAL;

            //scale of the entity
            this.scale = 1;

            //can collide with other entities
            this.isCollidable = true;

            //can collide with the map when moving
            this.isMapCollidable = true;

            //is the entity visible
            this.isVisible = true;

            //is an entity
            this.isEntity = true;

            //you can still set these in Tiled by using "x|y" notation
            //velocity of the entity (units per tick)
            this.velocity = new THREE.Vector2(0, 0);

            //max velocity to cap the entity at (units per tick)
            this.maxVelocity = new THREE.Vector2(15, 15);

            //acceleration of the entity when moving (units per second)
            this.accel = new THREE.Vector2(250, 250);

            //size of the hitbox
            this.hitSize = new THREE.Vector2(0, 0);

            //offset from the center to have the hitbox NOT IMPLEMENTED
            this.hitOffset = new THREE.Vector2(0, 0);

            //the name of this entitiy
            this.name = '';

            //friction to apply to this entities movement
            this.friction = settings.friction || gf.game.friction;

            //gravity of the world
            this.gravity = settings.gravity || gf.game.gravity;

            //entity alive
            this.alive = true;

            //entity falling (read only)
            this.falling = false;

            //entity jumping (read only)
            this.jumping = false;

            /****************************************************************************
             * Call base constructor
             ****************************************************************************/
            this._super(settings);

            /****************************************************************************
             * Create the actual object for the scene
             ****************************************************************************/
            //if the hitbox size isn't set, use the same as normal size
            if(this.hitSize.x === 0 && this.hitSize.y === 0)
                this.hitSize = this.size.clone();

            //scale size vectors
            this.scaledSize = this.size.clone().multiplyScalar(this.scale);
            this.scaledHitSize = this.hitSize.clone().multiplyScalar(this.scale);
            this.scaledHitOffset = this.hitOffset.clone().multiplyScalar(this.scale);

            //create main entity mesh
            this._createMesh();

            //create a second mesh for the hitbox
            this._createHitboxMesh();

            //set default position
            this.setPosition(pos);
        },
        //calculates distance between this object and another
        distanceTo: function(obj) {
            var dx = this._hitboxMesh.position.x - entity._hitboxMesh.position.x,
                dy = this._hitboxMesh.position.y - entity._hitboxMesh.position.y;

            return Math.sqrt(dx*dx + dy*dy);
        },
        //computes the velocity taking into account gravity, friction, etc
        computeVelocity: function(vel) {
            //apply gravity
            if(this.gravity) {
                vel.y -= !this.onladder ? (this.gravity * gf.game._delta) : 0;

                //check if falling/jumping
                this.falling = (vel.y > 0);
                this.jumping = this.falling ? false : this.jumping;
            }

            //apply friction
            if(this.friction.x) vel.x = gf.utils.applyFriction(vel.x, this.friction.x);
            if(this.friction.y) vel.y = gf.utils.applyFriction(vel.y, this.friction.y);

            //cap velocity
            if(vel.x) vel.x = gf.utils.clamp(vel.x, -this.maxVelocity.x, this.maxVelocity.x);
            if(vel.y) vel.y = gf.utils.clamp(vel.y, -this.maxVelocity.y, this.maxVelocity.y);

            return this;
        },
        //from http://gamedev.stackexchange.com/questions/586/what-is-the-fastest-way-to-work-out-2d-bounding-box-intersection
        intersects: function(entity)  {
            return (Math.abs(this._hitboxMesh.position.x - entity._hitboxMesh.position.x) * 2 < (this.hitSize.x + entity.hitSize.x)) &&
                    (Math.abs(this._hitboxMesh.position.y - entity._hitboxMesh.position.y) * 2 < (this.hitSize.y + entity.hitSize.y));
        },
        checkCollision: function(entity) {
            //response vector
            var p = new THREE.Vector2(0, 0);

            //check if hitboxes intersect
            if (this.intersects(entity)) {
                //compute delta between this & entity
                var dx = this._hitboxMesh.position.x - entity._hitboxMesh.position.x,
                    dy = this._hitboxMesh.position.y - entity._hitboxMesh.position.y;

                //compute penetration depth for both axis
                p.x = dx / 2;
                p.y = dy / 2;

                //check and "normalize" axis
                /*if (p.x < p.y) {
                    p.y = 0;
                    p.x = dx < 0 ? -p.x : p.x;
                } else {
                    p.x = 0;
                    p.y = dy < 0 ? -p.y : p.y;
                }*/
            }

            return p;
        },
        addToScene: function(scene) {
            this._super(scene);

            if(this._hitboxMesh) scene.add(this._hitboxMesh);

            return this;
        },
        addToPool: function(name) {
            return gf.entityPool.add(name || this.name, this);
        },
        removeFromScene: function(scene) {
            this._super(scene);

            if(this._hitboxMesh) scene.remove(this._hitboxMesh);

            return this;
        },
        updateMovement: function() {
            if(this.velocity.x === 0 && this.velocity.y === 0) return;

            var colliders = gf.game.world !== undefined ? gf.game.world.checkCollision(this._hitboxMesh, this.scaledHitSize, this.velocity) : [];

            //update flags
            this.onladder = false;

            //collisions
            var self = this;
            gf.utils.each(colliders, function(i, collider) {
                var tile = collider.tile,
                    axis = collider.axis;

                self.onladder = (tile.type == gf.types.COLLISION.LADDER ? true : self.onladder);

                //if a solid tile
                if(tile.type == gf.types.COLLISION.SOLID) {
                    //if it is a slope, apply the normal
                    if(tile.normal && (!self.velocity.x || !self.velocity.y)) {
                        var badMovement = tile.normal.clone().multiplyScalar(self.velocity.dot(tile.normal)),
                            newMovement = self.velocity.clone().subSelf(badMovement);

                        self.velocity.addSelf(newMovement);
                        return false;
                    }
                    //otherwise just stop movement
                    else {
                        self.velocity[axis] = 0;
                    }
                }
            });

            //TODO: Edge rolling (if you are on the tip edge of a blocking tile, roll around it)

            //apply gravity, friction, etc to this velocity
            this.computeVelocity(this.velocity);

            //do the actual entity movement
            this.moveEntity();

            gf.debug._playerColliders = colliders;
            gf.debug._playerColliders.dirty = true;

            return colliders;
        },
        moveEntity: function(vel) {
            //optionally override current velocity
            vel = vel || this.velocity;

            if(vel.x === 0 && vel.y === 0) return;

            //update the entity position
            this._mesh.translateX(vel.x);
            this._mesh.translateY(vel.y);

            //also update the hitbox mesh if it is different
            if(this._hitboxMesh) {
                this._hitboxMesh.translateX(vel.x);
                this._hitboxMesh.translateY(vel.y);
            }

            //onMove event
            this.onMove(vel);

            //emit movement
            gf.event.publish(gf.types.EVENT.ENTITY_MOVE + '.' + this.id, vel);

            return this;
        },
        //On Collision Event
        // called when this object is collided into by another, by default if something collides with
        // a collectable entity we remove the collectable
        //vec - Collision Vector (THREE.Vector2)
        //obj - Colliding object (gf.Entity)
        onCollision: function(vec, obj) {
            if(this.collidable && this.type == gf.types.ENTIY.COLLECTABLE)
                gf.game.removeObject(this);

            return this;
        },

        //On Move Event
        // called when this entity moves
        //vel - Velocity the entity moved (THREE.Vector2)
        onMove: function(vel) {
            return this;
        },

        //On Tile Break Event
        // called when a tile is broken
        //tile - the tile that is broken
        onTileBreak: function(tile) {
            return this;
        },

        //Privates
        _doSetPos: function(x, y, z) {
            this._super(x, y, z);

            if(this._hitboxMesh) {
                this._hitboxMesh.position.set(x, y, z);
                if(this.hitOffset) {
                    this._hitboxMesh.translateX(this.hitOffset.x);
                    this._hitboxMesh.translateY(this.hitOffset.y);
                }
            }
        },
        _createMesh: function() {
            if(this._mesh) return;

            this._materials = [];

            this._materials.push(new THREE.MeshBasicMaterial({ transparent: true }));

            //add outline material if needed
            if(gf.debug.showOutline) {
                this._materials.push(new THREE.MeshBasicMaterial({
                    color: gf.debug.outlineColor,
                    wireframe: true,
                    wireframeLinewidth: 1
                }));
            }

            this._geom = new THREE.PlaneGeometry(this.scaledSize.x, this.scaledSize.y);
            this._mesh = THREE.SceneUtils.createMultiMaterialObject(this._geom, this._materials);//new THREE.Mesh(this._geom, this._materials);

            //multimaterials object doesn't have .geometry defined
            this._mesh.geometry = this._geom;

            //set visible
            //this._mesh.visible = this.isVisible;
        },
        _createHitboxMesh: function() {
            if(this._hitboxMesh) return;

            this._hitboxMaterial = new THREE.MeshBasicMaterial({
                color: gf.debug.hitboxColor,
                wireframe: gf.debug.showHitbox,
                wireframeLinewidth: 1,
                transparent: true,
                opacity: gf.debug.showHitbox ? 0.8 : 0
            });

            this._hitboxGeom = new THREE.PlaneGeometry(1, 1);

            this._hitboxMesh = new THREE.Mesh(this._hitboxGeom, this._hitboxMaterial);
            this._hitboxMesh.scale.set(this.scaledHitSize.x, this.scaledHitSize.y, 1);
        },
    });
})();<|endoftext|>


<commit_before>'use strict';

var fs = require('graceful-fs');

// http://stackoverflow.com/a/10589791/586382
function validDate(date) {
  return date instanceof Date && !isNaN(date.valueOf());
}

function utimes(writePath, stat, cb) {
  var mtime = stat.mtime;

  if (validDate(mtime)) {
    var atime = stat.atime || new Date();

    if(validDate(atime)) {
      return fs.utimes(writePath, atime, mtime, cb);
    }
  }

  cb();
}

module.exports = utimes;
<commit_msg>simplify utimes helper<commit_after>'use strict';

var fs = require('graceful-fs');

// http://stackoverflow.com/a/10589791/586382
function validDate(date) {
  return date instanceof Date && !isNaN(date.valueOf());
}

function utimes(writePath, stat, cb) {
  var mtime = stat.mtime;
  var atime = stat.atime || new Date();

  if (validDate(mtime) && validDate(atime)) {
    return fs.utimes(writePath, atime, mtime, cb);
  }

  cb();
}

module.exports = utimes;
<|endoftext|>


<commit_before>#! /usr/bin/env node
"use strict";

var _ = require('underscore');
var pkginfo = require('pkginfo')(module);
var ansi = require('ansi');
var cursor = ansi(process.stdout);

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

var argv = require('yargs')
  .usage('Collating grep based on regexp capture with visual progress and result.\nUsage: $0 [flags] [pattern] [input files]')
  .example('$0 (\\d+)\\W+\\d+$', 'Count apache http access log lines by response code')
  .version(pkginfo.version, 'version')
  .boolean('verbose')
  .alias('v', 'verbose')
  .boolean('skip_result')
  .check(function(argv, options) {
    if (argv['_'] &&  argv['_'].length > 0) {
      return true;
    } else {
      throw new Error('Missing required pattern')
    }
  })
  .argv;

var fs = require('fs');

var match = argv._[0];

var re = new RegExp(match);

var linebyline = require('linebyline');

cursor.horizontalAbsolute(0).eraseLine();

updateRow({});

//TODO handle stdin

processFileIndex(1, {}, function(error, result) {
  cursor.reset();
  //console.dir(result);
  if (!argv.skip_result) {
    cursor.horizontalAbsolute(0).eraseLine();
    dumpAllMatches(result);
  }
  //TODO grep exit status 0=one or more matches, 1=zero matches, >1 error
});

function processFileIndex(index, matchByKey, callback) {
  if (index < argv._.length) {
    var file = argv._[index];
    if (argv.verbose) {
      console.log('File: ' + file);
    }
    processFile(file, matchByKey, function(err, result) {
      //TODO record errors?
      return processFileIndex(index+1, matchByKey, callback);
    });
  } else {
    return callback(null, matchByKey);
  }
}

function writeBar(barWidth, total, writer) {
  if (barWidth > 0) {
    cursor.bg.black();
    _.times(barWidth, function (i) {
      writer.write(' ');
    });
  } else {
    cursor.bg.grey();
    writer.write(' ');
  }
  cursor.bg.reset();
  _.times(total - barWidth, function (i) {
    writer.write(' ');
  })
}

function dumpAllMatches(matches) {
  cursor.horizontalAbsolute(0);
  var sorted = _.chain(matches)
    .pairs()
    .sortBy(function(p) {return p[1]})
    .reverse()
    .value();
  var total = _.reduce(sorted, function(mem, p) {return mem+p[1];}, 0);
  _.each(sorted, function(p) {
    //console.log(p[0]+': '+p[1]);
    var barWidth = Math.round(p[1] / total * 20);
    writeBar(barWidth, barWidth + 1, cursor);
    cursor.write(p[0]).write(': ').write(''+p[1]).write('  ');
    console.log();
  });
}

function updateRow(matches) {
  lineWriter.resetLine();
  var sorted = _.chain(matches)
    .pairs()
    .sortBy(function(p) {return p[1]})
    .reverse()
    .value();
  var total = _.reduce(sorted, function(mem, p) {return mem+p[1];}, 0);
  cursor.buffer();
  _.each(sorted, function(p) {
      //console.log(p[0]+': '+p[1]);

      var barWidth = Math.round(p[1] / total * 10);
      writeBar(barWidth, barWidth + 1, lineWriter);

    lineWriter.write(p[0]);
    lineWriter.write(': ');
    lineWriter.write(''+p[1]);
    lineWriter.write('  ');

    });
  cursor.flush();
}

function processFile(file, matches, callback) {
  var lastTick = new Date().getTime();
  var ll = linebyline(file);
  ll.on('line', function (line, lineNumber) {
    var matchArray = line.match(re);
    if (matchArray && matchArray.length > 0) {
      if (argv.verbose) {
        console.log(lineNumber, 'Found: ', matchArray[1]);
      }
      matches[matchArray[1]] = (matches[matchArray[1]] || 0) + 1;
      var currentTick = new Date().getTime();
      if (currentTick - lastTick > 50) {
        updateRow(matches);
        lastTick = currentTick;
      }
    }
  })
    .on('error', function (e) {
      console.log('Failed to process ' + file + ' due to: ' + e);
    })
    .on('close', function () {
      //console.log('closed');
      updateRow(matches);
      return callback(null, matches);
    });
}
<commit_msg>Add --full for full results without styling<commit_after>#!/usr/bin/env node
"use strict";

var _ = require('underscore');
var pkginfo = require('pkginfo')(module);
var ansi = require('ansi');
var cursor = ansi(process.stdout);

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

var argv = require('yargs')
  .usage('Collating grep based on regexp capture with visual progress and result.\nUsage: $0 [flags] [pattern] [input files]')
  .example('$0 \'(\\d+)\\W+\\d+$\' access.log', 'Count apache http access log lines by response code')
  .version(pkginfo.version, 'version')
  .boolean('verbose')
  .alias('verbose', 'v')
  .describe('verbose', 'Verbose logging')
  .boolean('full')
  .alias('full', 'f')
  .describe('full', 'Generate full output without any styling')
  .boolean('skip_results')
  .describe('skip_results', 'Do not show full results')
  .check(function(argv, options) {
    if (argv['_'] &&  argv['_'].length > 1) {
      return true;
    } else if (argv['_'] &&  argv['_'].length == 1) {
      throw new Error('No input files')
    } else {
      throw new Error('Missing required pattern')
    }
  })
  .argv;

var fs = require('fs');

process.on('SIGINT', function () {
  console.log('Got a SIGINT. Aborting.');
  process.exit(0);
});

var match = argv._[0];

var re = new RegExp(match);

var linebyline = require('linebyline');

cursor.horizontalAbsolute(0).eraseLine();

updateRow({});

//TODO handle stdin

processFileIndex(1, {}, function(error, result) {
  cursor.reset();
  //console.dir(result);
  if (argv.full) {
    dumpAllMatchesPlain(result);
  } else if (!argv.skip_results) {
    cursor.horizontalAbsolute(0).eraseLine();
    dumpAllMatches(result);
  }
  //TODO grep exit status 0=one or more matches, 1=zero matches, >1 error
});

function processFileIndex(index, matchByKey, callback) {
  if (index < argv._.length) {
    var file = argv._[index];
    if (argv.verbose) {
      console.log('File: ' + file);
    }
    processFile(file, matchByKey, function(err, result) {
      //TODO record errors?
      return processFileIndex(index+1, matchByKey, callback);
    });
  } else {
    return callback(null, matchByKey);
  }
}

function writeBar(barWidth, total, writer) {
  if (barWidth > 0) {
    cursor.bg.black();
    _.times(barWidth, function (i) {
      writer.write(' ');
    });
  } else {
    cursor.bg.grey();
    writer.write(' ');
  }
  cursor.bg.reset();
  _.times(total - barWidth, function (i) {
    writer.write(' ');
  })
}

function dumpAllMatchesPlain(matches) {
  var sorted = _.chain(matches)
    .pairs()
    .sortBy(function(p) {return p[1]})
    .reverse()
    .value();
  _.each(sorted, function(p) {
    console.log(p[0]+': '+p[1]);
  });
}

function dumpAllMatches(matches) {
  cursor.horizontalAbsolute(0);
  var sorted = _.chain(matches)
    .pairs()
    .sortBy(function(p) {return p[1]})
    .reverse()
    .value();
  var total = _.reduce(sorted, function(mem, p) {return mem+p[1];}, 0);
  _.each(sorted, function(p) {
    //console.log(p[0]+': '+p[1]);
    var barWidth = Math.round(p[1] / total * 20);
    writeBar(barWidth, barWidth + 1, cursor);
    cursor.write(p[0]).write(': ').write(''+p[1]).write('  ');
    console.log();
  });
}

function updateRow(matches) {
  if (argv.full) {
    return;
  }
  lineWriter.resetLine();
  var sorted = _.chain(matches)
    .pairs()
    .sortBy(function(p) {return p[1]})
    .reverse()
    .value();
  var total = _.reduce(sorted, function(mem, p) {return mem+p[1];}, 0);
  cursor.buffer();
  _.each(sorted, function(p) {
      //console.log(p[0]+': '+p[1]);

      var barWidth = Math.round(p[1] / total * 10);
      writeBar(barWidth, barWidth + 1, lineWriter);

    lineWriter.write(p[0]);
    lineWriter.write(': ');
    lineWriter.write(''+p[1]);
    lineWriter.write('  ');

    });
  cursor.flush();
}

function processFile(file, matches, callback) {
  var lastTick = new Date().getTime();
  var ll = linebyline(file);
  ll.on('line', function (line, lineNumber) {
    var matchArray = line.match(re);
    if (matchArray && matchArray.length > 0) {
      if (argv.verbose) {
        console.log(lineNumber, 'Found: ', matchArray[1]);
      }
      matches[matchArray[1]] = (matches[matchArray[1]] || 0) + 1;
      var currentTick = new Date().getTime();
      if (currentTick - lastTick > 50) {
        updateRow(matches);
        lastTick = currentTick;
      }
    }
  })
    .on('error', function (e) {
      console.log('Failed to process ' + file + ' due to: ' + e);
    })
    .on('close', function () {
      //console.log('closed');
      updateRow(matches);
      return callback(null, matches);
    });
}
<|endoftext|>


<commit_before>var $document, canvas, context;

chrome.extension.sendMessage({}, function(response) {
	var readyStateCheckInterval = setInterval(function() {
	if (document.readyState === "complete") {
		clearInterval(readyStateCheckInterval);

		// init canvas
		canvas = document.createElement('canvas');
		context = canvas.getContext('2d');
		$document = $(document);
		canvas.id = 'webotate';
		canvas.height = $document.height();
		canvas.width = $document.width();
		canvas.style.backgroundColor = 'transparent';
		canvas.style.position = 'absolute';
		canvas.style.zIndex = 9001;
		// initially canvas is display: none
		canvas.style.display = 'none';
		$('body').prepend(canvas);

		// init canvas events
		initCanvasEvents();

	}
	}, 10);
});

// toggle visibility of canvas on page action press
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
	if(request.data === 'DisplayBlock') {
		canvas.style.display = 'block';
		sendResponse();
	} else if(request.data === 'DisplayNone') {
		canvas.style.display = 'none';
		sendResponse();
	}
});

var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;

function redraw(){
	context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas

	context.strokeStyle = "#df4b26";
	context.lineJoin = "round";
	context.lineWidth = 5;

	for(var i=0; i < clickX.length; i++) {
		context.beginPath();
		if(clickDrag[i] && i){
			context.moveTo(clickX[i-1], clickY[i-1]);
		} else {
			context.moveTo(clickX[i]-1, clickY[i]);
		}
		context.lineTo(clickX[i], clickY[i]);
		context.closePath();
		context.stroke();
	}
}

function addClick(x, y, dragging)
{
	clickX.push(x);
	clickY.push(y);
	clickDrag.push(dragging);
}

function initCanvasEvents() {
	var $canvas = $(canvas);

	$canvas.mousedown(function(e){
		var mouseX = e.pageX - this.offsetLeft;
		var mouseY = e.pageY - this.offsetTop;

		paint = true;
		addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
		redraw();
	});

	$canvas.mousemove(function(e){
		if(paint){
			addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
			redraw();
		}
	});

	$canvas.mouseup(function(e){
		paint = false;
	});

	$canvas.mouseleave(function(e){
		paint = false;
	});
}<commit_msg>add draw() that doesn't draw every point and clear whole canvas<commit_after>var $document, canvas, context;

chrome.extension.sendMessage({}, function(response) {
	var readyStateCheckInterval = setInterval(function() {
	if (document.readyState === "complete") {
		clearInterval(readyStateCheckInterval);

		// init canvas
		canvas = document.createElement('canvas');
		context = canvas.getContext('2d');
		$document = $(document);
		canvas.id = 'webotate';
		canvas.height = $document.height();
		canvas.width = $document.width();
		canvas.style.backgroundColor = 'transparent';
		canvas.style.position = 'absolute';
		canvas.style.zIndex = 9001;
		canvas.style.cursor = 'crosshair';
		// initially canvas is display: none
		canvas.style.display = 'none';
		$('body').prepend(canvas);

		// init canvas events
		initCanvasEvents();

	}
	}, 10);
});

// toggle visibility of canvas on page action press
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
	if(request.data === 'DisplayBlock') {
		canvas.style.display = 'block';
		sendResponse();
	} else if(request.data === 'DisplayNone') {
		canvas.style.display = 'none';
		sendResponse();
	}
});

var clickX = [];
var clickY = [];
var clickDrag = [];
var paint;

function redraw() {
	context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas

	context.strokeStyle = '#df4b26';
	context.lineJoin = 'round';
	context.lineWidth = 5;

	for(var i = 0; i < clickX.length; i++) {
		context.beginPath();
		if(clickDrag[i] && i){
			context.moveTo(clickX[i-1], clickY[i-1]);
		} else {
			context.moveTo(clickX[i]-1, clickY[i]);
		}
		context.lineTo(clickX[i], clickY[i]);
		context.closePath();
		context.stroke();
	}
}

function draw() {
	context.strokeStyle = '#df4b26';
	context.lineJoin = 'round';
	context.lineWidth = 5;

	context.beginPath();
	if(clickDrag[clickX.length - 1])
		context.moveTo(clickX[clickX.length - 2], clickY[clickY.length - 2]);
	else
		context.moveTo(clickX[clickX.length - 1] - 1, clickY[clickY.length - 1]);
	context.lineTo(clickX[clickX.length - 1], clickY[clickY.length - 1]);
	context.closePath();
	context.stroke();
}

function addClick(x, y, dragging)
{
	clickX.push(x);
	clickY.push(y);
	clickDrag.push(dragging);
}

function initCanvasEvents() {
	var $canvas = $(canvas);

	$canvas.mousedown(function(e){
		var mouseX = e.pageX - this.offsetLeft;
		var mouseY = e.pageY - this.offsetTop;

		paint = true;
		addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
		draw();
	});

	$canvas.mousemove(function(e){
		if(paint){
			addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
			draw();
		}
	});

	$canvas.mouseup(function(e){
		paint = false;
	});

	$canvas.mouseleave(function(e){
		paint = false;
	});
}<|endoftext|>


<commit_before>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2015, Olivier Biot, Jason Oster, Aaron McLeod
 * http://www.melonjs.org/
 *
 */
(function () {
    /*
     * PRIVATE STUFF
     */

    // Reference to base class
    var api = me.input;

    var bindings = {};

    var remap = new Map([
        // Firefox mappings
        [
            "45e-28e-Xbox 360 Wired Controller",
            {
                "axes" : [ 0, 1, 4, 2, 3, 5 ],
                "buttons" : [ 12, 13, 14, 15, 9, 8, 10, 11, 4, 5, 16, 0, 1, 3, 4 ]
            }
        ],
        [
            "54c-268-PLAYSTATION(R)3 Controller",
            {
                "axes" : [ 0, 1, 2, 3, 4, 5 ],
                "buttons" : [ 8, 10, 11, 9, 12, 15, 13, 14, 6, 7, 4, 5, 3, 1, 0, 2, 16 ]
            }
        ],
        [
            "2836-1-OUYA Game Controller",
            {
                "axes" : [ 0, -1, 1, -1, -1, 4, -1, 2, -1, 3, -1, 5 ],
                "buttons" : [ -1, -1, -1, 0, 2, 3, 1, 4, 5, 10, 11, 12, 13, 14, 15, 6, 7 ]
            }
        ],

        // Chrome mappings
        [
            "OUYA Game Controller (Vendor: 2836 Product: 0001)",
            {
                "axes" : [ 0, 1, 4, 2, 3, 5 ],
                "buttons" : [ 0, 2, 3, 1, 4, 5, 10, 11, 12, 13, 14, 15, 6, 7 ]
            }
        ]
    ]);

    /**
     * Update gamepad status
     * @ignore
     */
    api._updateGamepads = function () {
        var gamepads = navigator.getGamepads();
        var e = {};

        // Trigger bound keycodes
        Object.keys(bindings).forEach(function (index) {
            if (!gamepads[index]) {
                return;
            }

            gamepads[index].buttons.forEach(function (current, button) {
                // Remap buttons if necessary
                if (gamepads[index].mapping !== "standard") {
                    var mapping = remap.get(gamepads[index].id);
                    if (mapping) {
                        button = mapping.buttons[button];
                    }
                }

                // Get mapped button
                var last = bindings[index][button];
                if (!last) {
                    return;
                }

                // Edge detection
                if (!last.pressed && current.pressed) {
                    last.pressed = true;
                    api._keydown(e, last.keyCode, button + 256);
                }
                else if (last.pressed && !current.pressed) {
                    last.pressed = false;
                    api._keyup(e, last.keyCode, button + 256);
                }
            });
        });
    };

    /*
     * PUBLIC STUFF
     */

    /**
     * Standard gamepad mapping information

     *

     *
Face buttons: FACE_1, FACE_2, FACE_3, FACE_4

     *
D-Pad: UP, DOWN, LEFT, RIGHT

     *
Shoulder buttons: L1, L2, R1, R2

     *
Analog stick (clicks): L_STICK, R_STICK

     *
Others: SELECT (BACK), START (FORWARD), HOME

     *

     * @public
     * @name GAMEPAD
     * @enum {Number}
     * @memberOf me.input
     * @see https://w3c.github.io/gamepad/#remapping
     */
    api.GAMEPAD = {
        "FACE_1"    : 0,
        "FACE_2"    : 1,
        "FACE_3"    : 2,
        "FACE_4"    : 3,
        "L1"        : 4,
        "L2"        : 5,
        "R1"        : 6,
        "R2"        : 7,
        "SELECT"    : 8,
        "BACK"      : 8,
        "START"     : 9,
        "FORWARD"   : 9,
        "L_STICK"   : 10,
        "R_STICK"   : 11,
        "UP"        : 12,
        "DOWN"      : 13,
        "LEFT"      : 14,
        "RIGHT"     : 15,
        "HOME"      : 16
    };

    /**
     * Associate a gamepad event to an action
     * @name bindGamepad
     * @memberOf me.input
     * @public
     * @function
     * @param {Number} index Gamepad index
     * @param {me.input.GAMEPAD} button
     * @param {me.input.KEY} keyCode
     * @example
     * // enable the keyboard
     * me.input.bindKey(me.input.KEY.X, "shoot");
     * // map the lower action button on the first gamepad to the X key
     * me.input.bindGamepad(0, me.input.GAMEPAD.ACTION_0, me.input.KEY.X);
     */
    api.bindGamepad = function (index, button, keyCode) {
        // Throw an exception if no action is defined for the specified keycode
        if (!api._KeyBinding[keyCode]) {
            throw new me.Error("no action defined for keycode " + keyCode);
        }

        // Allocate bindings if not defined
        if (!bindings[index]) {
            bindings[index] = {};
        }

        // Map the gamepad button to the keycode
        bindings[index][button] = {
            "keyCode" : keyCode,
            "pressed" : false
        };
    };

    /**
     * unbind the defined keycode
     * @name unbindGamepad
     * @memberOf me.input
     * @public
     * @function
     * @param {Number} index Gamepad index
     * @param {me.input.GAMEPAD} button
     * @example
     * me.input.unbindGamepad(0, me.input.GAMEPAD.ACTION_0);
     */
    api.unbindGamepad = function (index, button) {
        if (!bindings[index]) {
            throw new me.Error("no bindings for gamepad " + index);
        }

        bindings[index][button] = {};
    };
})();
<commit_msg>Fix documentation [skip ci]<commit_after>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2015, Olivier Biot, Jason Oster, Aaron McLeod
 * http://www.melonjs.org/
 *
 */
(function () {
    /*
     * PRIVATE STUFF
     */

    // Reference to base class
    var api = me.input;

    var bindings = {};

    var remap = new Map([
        // Firefox mappings
        [
            "45e-28e-Xbox 360 Wired Controller",
            {
                "axes" : [ 0, 1, 4, 2, 3, 5 ],
                "buttons" : [ 12, 13, 14, 15, 9, 8, 10, 11, 4, 5, 16, 0, 1, 3, 4 ]
            }
        ],
        [
            "54c-268-PLAYSTATION(R)3 Controller",
            {
                "axes" : [ 0, 1, 2, 3, 4, 5 ],
                "buttons" : [ 8, 10, 11, 9, 12, 15, 13, 14, 6, 7, 4, 5, 3, 1, 0, 2, 16 ]
            }
        ],
        [
            "2836-1-OUYA Game Controller",
            {
                "axes" : [ 0, -1, 1, -1, -1, 4, -1, 2, -1, 3, -1, 5 ],
                "buttons" : [ -1, -1, -1, 0, 2, 3, 1, 4, 5, 10, 11, 12, 13, 14, 15, 6, 7 ]
            }
        ],

        // Chrome mappings
        [
            "OUYA Game Controller (Vendor: 2836 Product: 0001)",
            {
                "axes" : [ 0, 1, 4, 2, 3, 5 ],
                "buttons" : [ 0, 2, 3, 1, 4, 5, 10, 11, 12, 13, 14, 15, 6, 7 ]
            }
        ]
    ]);

    /**
     * Update gamepad status
     * @ignore
     */
    api._updateGamepads = function () {
        var gamepads = navigator.getGamepads();
        var e = {};

        // Trigger bound keycodes
        Object.keys(bindings).forEach(function (index) {
            if (!gamepads[index]) {
                return;
            }

            gamepads[index].buttons.forEach(function (current, button) {
                // Remap buttons if necessary
                if (gamepads[index].mapping !== "standard") {
                    var mapping = remap.get(gamepads[index].id);
                    if (mapping) {
                        button = mapping.buttons[button];
                    }
                }

                // Get mapped button
                var last = bindings[index][button];
                if (!last) {
                    return;
                }

                // Edge detection
                if (!last.pressed && current.pressed) {
                    last.pressed = true;
                    api._keydown(e, last.keyCode, button + 256);
                }
                else if (last.pressed && !current.pressed) {
                    last.pressed = false;
                    api._keyup(e, last.keyCode, button + 256);
                }
            });
        });
    };

    /*
     * PUBLIC STUFF
     */

    /**
     * Standard gamepad mapping information

     *

     *
Face buttons: FACE_1, FACE_2, FACE_3, FACE_4

     *
D-Pad: UP, DOWN, LEFT, RIGHT

     *
Shoulder buttons: L1, L2, R1, R2

     *
Analog stick (clicks): L_STICK, R_STICK

     *
Others: SELECT (BACK), START (FORWARD), HOME

     *

     * @public
     * @name GAMEPAD
     * @enum {Number}
     * @memberOf me.input
     * @see https://w3c.github.io/gamepad/#remapping
     */
    api.GAMEPAD = {
        "FACE_1"    : 0,
        "FACE_2"    : 1,
        "FACE_3"    : 2,
        "FACE_4"    : 3,
        "L1"        : 4,
        "L2"        : 5,
        "R1"        : 6,
        "R2"        : 7,
        "SELECT"    : 8,
        "BACK"      : 8,
        "START"     : 9,
        "FORWARD"   : 9,
        "L_STICK"   : 10,
        "R_STICK"   : 11,
        "UP"        : 12,
        "DOWN"      : 13,
        "LEFT"      : 14,
        "RIGHT"     : 15,
        "HOME"      : 16
    };

    /**
     * Associate a gamepad event to a keycode
     * @name bindGamepad
     * @memberOf me.input
     * @public
     * @function
     * @param {Number} index Gamepad index
     * @param {me.input.GAMEPAD} button
     * @param {me.input.KEY} keyCode
     * @example
     * // enable the keyboard
     * me.input.bindKey(me.input.KEY.X, "shoot");
     * // map the lower action button on the first gamepad to the X key
     * me.input.bindGamepad(0, me.input.GAMEPAD.ACTION_0, me.input.KEY.X);
     */
    api.bindGamepad = function (index, button, keyCode) {
        // Throw an exception if no action is defined for the specified keycode
        if (!api._KeyBinding[keyCode]) {
            throw new me.Error("no action defined for keycode " + keyCode);
        }

        // Allocate bindings if not defined
        if (!bindings[index]) {
            bindings[index] = {};
        }

        // Map the gamepad button to the keycode
        bindings[index][button] = {
            "keyCode" : keyCode,
            "pressed" : false
        };
    };

    /**
     * unbind the defined keycode
     * @name unbindGamepad
     * @memberOf me.input
     * @public
     * @function
     * @param {Number} index Gamepad index
     * @param {me.input.GAMEPAD} button
     * @example
     * me.input.unbindGamepad(0, me.input.GAMEPAD.ACTION_0);
     */
    api.unbindGamepad = function (index, button) {
        if (!bindings[index]) {
            throw new me.Error("no bindings for gamepad " + index);
        }

        bindings[index][button] = {};
    };
})();
<|endoftext|>


<commit_before>/*jslint node: true*/

"use strict";
var fs = require('fs'),
    path = require('path'),
    util = require('util'),
    http = require('http'),
    moment = require('moment');

function asArray(a) {
    if (Array.isArray(a)) {
        return a;
    } else if (a === null || a === undefined) {
        return [];
    } else {
        return [a];
    }
}

function Client(settings) {
    this.verbose  = !!settings.verbose; // false if not set

//    this.server   = settings.server   || "win-api-acc.westtoer.be";
    this.server   = settings.server   || "api.westtoer.tdms.acc.saga.be";
    this.version  = settings.version  || "v1";
    this.clientid = settings.clientid || "westtoer";
    this.secret   = settings.secret   || "no-secret";

    this.baseURI = "http://" + this.server + "/api/" + this.version + "/";
    this.authURI = "http://" + this.server + "/oauth/v2/token?grant_type=client_credentials&client_id=" +
        encodeURIComponent(this.clientid) + "&client_secret=" + encodeURIComponent(this.secret);

    // we initialize in a stopped modus
    this.stop();
}
Client.DEFAULT_PAGE = 1;
Client.DEFAULT_SIZE = 10;

function ProductQuery(tpl) {
    if (tpl !== undefined && tpl.constructor === ProductQuery) {  // clone - constructor
        this.format = tpl.format;
        this.types = tpl.types.slice(0);
        this.touristictypes = tpl.touristictypes.slice(0);
        this.sizeVal = tpl.sizeVal;
        this.pageNum = tpl.pageNum;
        this.channels = tpl.channels.slice(0);
        this.lastmodExpr = tpl.lastmodExpr;
        this.softDelState = tpl.softDelState;
        this.pubState = tpl.pubState;
        this.bulkMode = tpl.bulkMode;
    } else { // nothing to clone, use defaults
        this.format = 'xml';
        this.types = ['accommodation']; //default zou alle types moeten kunnen bevatten
        this.touristictypes = [];
        this.sizeVal = Client.DEFAULT_SIZE;
        this.pageNum = Client.DEFAULT_PAGE;
        this.channels = [];
        this.bulkMode = false;
    }
}
ProductQuery.prototype.clone = function () {
    return new ProductQuery(this);
};

// paging
ProductQuery.prototype.page = function (page) {
    this.pageNum = Number(page) || Client.DEFAULT_PAGE;
    return this;
};
ProductQuery.prototype.size = function (size) {
    this.sizeVal = Number(size) || 10;
    return this;
};

// qrybuilder formats
ProductQuery.prototype.asJSON_HAL = function () {
    this.format = 'json+hal';
    return this;
};
ProductQuery.prototype.asJSON = function () {
    this.format = 'json';
    return this;
};
ProductQuery.prototype.asXML = function () {
    this.format = 'xml';
    return this;
};
ProductQuery.prototype.bulk = function () {
    this.bulkMode = true;
    return this;
};

//qrybuilder type filter
ProductQuery.prototype.forTypes = function (newtypes) {
    this.types = asArray(newtypes);
    return this;
};
ProductQuery.prototype.andType = function (singletype) {
    return this.types.push(singletype);
};

//qrybuilder touristic_type filter
ProductQuery.prototype.forTouristicTypes = function (newtypes) {
    this.touristictypes = asArray(newtypes);
    return this;
};
ProductQuery.prototype.andTouristicType = function (singletype) {
    return this.touristictypes.push(singletype);
};

//qrybuilder lastmod filter
ProductQuery.prototype.lastmod = function (expr) {
    this.lastmodExpr = expr;
    return this;
};
function dateFormat(s) {
    if (s === undefined || s === null) {
        return "*";
    }
    return moment(s).format('YYYY-MM-DD');
}
ProductQuery.prototype.lastmodBetween = function (from, to) {
    from = dateFormat(from);
    to = dateFormat(to);
    return this.lastmod("[" + from + " TO " + to + "}"); // start boundary is inclusive, end-boundary is exclusive
};

//qrybuilder delete filter
ProductQuery.prototype.removed = function () {
    this.softDelState = true;
    return this;
};
ProductQuery.prototype.active = function () {
    this.softDelState = false;
    return this;
};
ProductQuery.prototype.ignoreRemoved = function () {
    this.softDelState = undefined;
    return this;
};

//qrybuilder pubchannel filter
ProductQuery.prototype.forChannels = function (chs) {
    this.channels = asArray(chs);
    return this;
};
ProductQuery.prototype.andChannel = function (ch) {
    return this.channels.push(ch);
};

//qrybuilder published filter
ProductQuery.prototype.published = function () {
    this.pubState = true;
    return this;
};
ProductQuery.prototype.hidden = function () {
    this.pubState = false;
    return this;
};
ProductQuery.prototype.ignorePublished = function () {
    this.pubState = undefined;
    return this;
};

ProductQuery.addURI = function (key, value, unsetVal) {
    if (value === unsetVal) {
        return "";
    } // else
    return "&" + key + "=" + encodeURIComponent(value);
};

ProductQuery.addQueryVal = function (set, key, value) {
    if (value === undefined) {
        return;
    } // else
    return set.push("+" + key + ":" + value);
};

ProductQuery.addQueryList = function (set, key, valList) {
    if (valList === undefined || valList.length === 0) {
        return;
    } // else

    if (valList.length === 1) {
        set.push("+" + key + ":" + valList[0]);
    } else {
        set.push("+" + key + ":(" + valList.join(' OR ') + ")");
    }
};

ProductQuery.prototype.getURI = function (client) {
    var uri, q = [],
        expired = client.token_expires < Date.now();

    if (client.token === null || expired) {
        throw "client has no active (" + !expired + ") token (" + client.token + ")";
    }
    if (this.types === undefined || this.types === null || this.types.length === 0) {
        throw "no types specified for fetch";
    }

    uri = client.baseURI + (this.bulkMode ? "bulk/" : "") + this.types.join(',') +
        "?format=" + this.format +
        "&access_token=" + encodeURIComponent(client.token);

    if (!this.bulkMode) { // paging is meaningless in bulk mode
        uri += ProductQuery.addURI("size", this.sizeVal, Client.DEFAULT_SIZE);
        uri += ProductQuery.addURI("page", this.pageNum, Client.DEFAULT_PAGE);
    }

    ProductQuery.addQueryVal(q, "metadata.tdms__update_date", this.lastmodExpr);
    ProductQuery.addQueryVal(q, "metadata.tdms__deleted", this.softDelState);
    ProductQuery.addQueryVal(q, "publishing_channels.tdms__published", this.pubState);

    ProductQuery.addQueryList(q, "publishing_channels.tdms__publishing_channel.@code", this.channels);
    ProductQuery.addQueryList(q, "metadata.tdms__touristic_product_type.@code", this.touristictypes);

    if (q.length > 0) {
        uri += "&q=" + encodeURIComponent(q.join(' '));
    }

    return uri;
};

function getResponse(uri, cb, verbose) {
    verbose = verbose || false;
    if (verbose) {
        console.log("call uri [%s]", uri);
    }

    http.get(uri, function (res) {
        cb(null, res);
    }).on('error', function (e) {
        cb(e);
    });
}

function streamData(uri, sink, cb, verbose) {
    getResponse(uri, function (e, res) {
        if (e) {
            sink.emit('error', e);
        } //else
        if (res.statusCode !== 200) {
            sink.emit('error', "error reading uri [" + uri + "] to stream - response.status == " + res.statusCode);
        } // else
        res.pipe(sink);
        cb(res);
    }, verbose);
}

function getData(uri, cb, verbose) {
    getResponse(uri, function (e, res) {
        var data = "";
        if (e) {
            return cb(e);
        } //else
        if (res.statusCode !== 200) {
            cb("error reading uri [" + uri + "] - status == " + res.statusCode);
        } // else
        res
            .on('data', function (chunk) {
                data += chunk;
            })
            .on('end', function () {
                cb(null, data);
            })
            .on('error', cb);
    }, verbose);
}

function getJSON(uri, cb, verbose) {
    getData(uri, function (e, data) {
        if (e) {
            return cb(e);
        }
        //else
        cb(null, JSON.parse(data));
    }, verbose);
}

function getXML(uri, cb, verbose) {
    //TODO parse XML to DOM ?
    getData(uri, cb, verbose);
}

Client.prototype.stop = function () {
    clearTimeout(this.token_refresh);
    this.token = null;
    this.token_expires = Date.now();
    this.token_refresh = null;
};

Client.prototype.start = function (cb) {
    var me = this, SLACK_MILLIS = 1000, exp_in_millis;

    if (me.token_refresh !== null) { // already started...
        if (cb) {
            return cb(null); // no errors, but no token object either
        }
        return;
    }

    // else
    getJSON(this.authURI, function (e, resp) {
        if (e) {
            console.error("ERROR: %j", e);
            return cb(e);
        }

        me.token = resp.access_token;
        exp_in_millis = resp.expires_in * 1000;
        me.token_expires = Date.now() + exp_in_millis;
        if (exp_in_millis > SLACK_MILLIS) { // we assume at least 1s slack to operate
            me.token_refresh = setTimeout(function () {
                me.start();
            }, exp_in_millis - SLACK_MILLIS);
        } else {
            console.warn("token validity too short to organize self-refresh");
        }
        if (me.verbose) {
            console.log("got token %s - valid for %d - till %s", me.token, resp.expires_in, moment(me.token_expires));
        }

        if (cb) {
            cb(e, resp);
        }
    }, this.verbose);
};

Client.prototype.fetch = function (qry, cb) {
    if (arguments.length < 2) {
        cb = qry;
        qry = new ProductQuery();
    }

    if (qry.format === 'json') {
        getJSON(qry.getURI(this), function (e, resp) {
            cb(e, resp);
        }, this.verbose);
    } else if (qry.format === 'json+hal') {
        getJSON(qry.getURI(this), function (e, resp) {
            if (e) {
                cb(e);
            } // else
            var meta = resp, EMB = "_embedded", emb = meta[EMB];
            resp = emb.items;
            delete emb.items;
            cb(e, resp, meta);
        }, this.verbose);
    } else if (qry.format === 'xml') {
        getXML(qry.getURI(this), function (e, resp) {
            cb(e, resp);
        }, this.verbose);
    }
};

Client.prototype.stream = function (qry, sink, cb) {
    if (arguments.length < 2) {
        sink = qry;
        qry = new ProductQuery();
    }
    cb = cb || function (res) {}; // do nothing callback

    streamData(qry.getURI(this), sink, cb, this.verbose);
};

module.exports.client = function (settings) {
    return new Client(settings);
};
module.exports.query = function (service) {
    service = service || 'product';
    if (service === 'product') {
        return new ProductQuery();
    }
    throw "unknown service request";
};
<commit_msg>more complete error-handling (case where both e and res where undefined got triggered from dns not working --> getaddress  error)<commit_after>/*jslint node: true*/

"use strict";
var fs = require('fs'),
    path = require('path'),
    util = require('util'),
    http = require('http'),
    moment = require('moment');

function asArray(a) {
    if (Array.isArray(a)) {
        return a;
    } else if (a === null || a === undefined) {
        return [];
    } else {
        return [a];
    }
}

function Client(settings) {
    this.verbose  = !!settings.verbose; // false if not set

//    this.server   = settings.server   || "win-api-acc.westtoer.be";
    this.server   = settings.server   || "api.westtoer.tdms.acc.saga.be";
    this.version  = settings.version  || "v1";
    this.clientid = settings.clientid || "westtoer";
    this.secret   = settings.secret   || "no-secret";

    this.baseURI = "http://" + this.server + "/api/" + this.version + "/";
    this.authURI = "http://" + this.server + "/oauth/v2/token?grant_type=client_credentials&client_id=" +
        encodeURIComponent(this.clientid) + "&client_secret=" + encodeURIComponent(this.secret);

    // we initialize in a stopped modus
    this.stop();
}
Client.DEFAULT_PAGE = 1;
Client.DEFAULT_SIZE = 10;

function ProductQuery(tpl) {
    if (tpl !== undefined && tpl.constructor === ProductQuery) {  // clone - constructor
        this.format = tpl.format;
        this.types = tpl.types.slice(0);
        this.touristictypes = tpl.touristictypes.slice(0);
        this.sizeVal = tpl.sizeVal;
        this.pageNum = tpl.pageNum;
        this.channels = tpl.channels.slice(0);
        this.lastmodExpr = tpl.lastmodExpr;
        this.softDelState = tpl.softDelState;
        this.pubState = tpl.pubState;
        this.bulkMode = tpl.bulkMode;
    } else { // nothing to clone, use defaults
        this.format = 'xml';
        this.types = ['accommodation']; //default zou alle types moeten kunnen bevatten
        this.touristictypes = [];
        this.sizeVal = Client.DEFAULT_SIZE;
        this.pageNum = Client.DEFAULT_PAGE;
        this.channels = [];
        this.bulkMode = false;
    }
}
ProductQuery.prototype.clone = function () {
    return new ProductQuery(this);
};

// paging
ProductQuery.prototype.page = function (page) {
    this.pageNum = Number(page) || Client.DEFAULT_PAGE;
    return this;
};
ProductQuery.prototype.size = function (size) {
    this.sizeVal = Number(size) || 10;
    return this;
};

// qrybuilder formats
ProductQuery.prototype.asJSON_HAL = function () {
    this.format = 'json+hal';
    return this;
};
ProductQuery.prototype.asJSON = function () {
    this.format = 'json';
    return this;
};
ProductQuery.prototype.asXML = function () {
    this.format = 'xml';
    return this;
};
ProductQuery.prototype.bulk = function () {
    this.bulkMode = true;
    return this;
};

//qrybuilder type filter
ProductQuery.prototype.forTypes = function (newtypes) {
    this.types = asArray(newtypes);
    return this;
};
ProductQuery.prototype.andType = function (singletype) {
    return this.types.push(singletype);
};

//qrybuilder touristic_type filter
ProductQuery.prototype.forTouristicTypes = function (newtypes) {
    this.touristictypes = asArray(newtypes);
    return this;
};
ProductQuery.prototype.andTouristicType = function (singletype) {
    return this.touristictypes.push(singletype);
};

//qrybuilder lastmod filter
ProductQuery.prototype.lastmod = function (expr) {
    this.lastmodExpr = expr;
    return this;
};
function dateFormat(s) {
    if (s === undefined || s === null) {
        return "*";
    }
    return moment(s).format('YYYY-MM-DD');
}
ProductQuery.prototype.lastmodBetween = function (from, to) {
    from = dateFormat(from);
    to = dateFormat(to);
    return this.lastmod("[" + from + " TO " + to + "}"); // start boundary is inclusive, end-boundary is exclusive
};

//qrybuilder delete filter
ProductQuery.prototype.removed = function () {
    this.softDelState = true;
    return this;
};
ProductQuery.prototype.active = function () {
    this.softDelState = false;
    return this;
};
ProductQuery.prototype.ignoreRemoved = function () {
    this.softDelState = undefined;
    return this;
};

//qrybuilder pubchannel filter
ProductQuery.prototype.forChannels = function (chs) {
    this.channels = asArray(chs);
    return this;
};
ProductQuery.prototype.andChannel = function (ch) {
    return this.channels.push(ch);
};

//qrybuilder published filter
ProductQuery.prototype.published = function () {
    this.pubState = true;
    return this;
};
ProductQuery.prototype.hidden = function () {
    this.pubState = false;
    return this;
};
ProductQuery.prototype.ignorePublished = function () {
    this.pubState = undefined;
    return this;
};

ProductQuery.addURI = function (key, value, unsetVal) {
    if (value === unsetVal) {
        return "";
    } // else
    return "&" + key + "=" + encodeURIComponent(value);
};

ProductQuery.addQueryVal = function (set, key, value) {
    if (value === undefined) {
        return;
    } // else
    return set.push("+" + key + ":" + value);
};

ProductQuery.addQueryList = function (set, key, valList) {
    if (valList === undefined || valList.length === 0) {
        return;
    } // else

    if (valList.length === 1) {
        set.push("+" + key + ":" + valList[0]);
    } else {
        set.push("+" + key + ":(" + valList.join(' OR ') + ")");
    }
};

ProductQuery.prototype.getURI = function (client) {
    var uri, q = [],
        expired = client.token_expires < Date.now();

    if (client.token === null || expired) {
        throw "client has no active (" + !expired + ") token (" + client.token + ")";
    }
    if (this.types === undefined || this.types === null || this.types.length === 0) {
        throw "no types specified for fetch";
    }

    uri = client.baseURI + (this.bulkMode ? "bulk/" : "") + this.types.join(',') +
        "?format=" + this.format +
        "&access_token=" + encodeURIComponent(client.token);

    if (!this.bulkMode) { // paging is meaningless in bulk mode
        uri += ProductQuery.addURI("size", this.sizeVal, Client.DEFAULT_SIZE);
        uri += ProductQuery.addURI("page", this.pageNum, Client.DEFAULT_PAGE);
    }

    ProductQuery.addQueryVal(q, "metadata.tdms__update_date", this.lastmodExpr);
    ProductQuery.addQueryVal(q, "metadata.tdms__deleted", this.softDelState);
    ProductQuery.addQueryVal(q, "publishing_channels.tdms__published", this.pubState);

    ProductQuery.addQueryList(q, "publishing_channels.tdms__publishing_channel.@code", this.channels);
    ProductQuery.addQueryList(q, "metadata.tdms__touristic_product_type.@code", this.touristictypes);

    if (q.length > 0) {
        uri += "&q=" + encodeURIComponent(q.join(' '));
    }

    return uri;
};

function getResponse(uri, cb, verbose) {
    verbose = verbose || false;
    if (verbose) {
        console.log("call uri [%s]", uri);
    }

    http.get(uri, function (res) {
        cb(null, res);
    }).on('error', function (e) {
        cb(e);
    });
}

function streamData(uri, sink, cb, verbose) {
    getResponse(uri, function (e, res) {
        if (e) {
            sink.emit('error', e);
        } //else
        if (res === undefined || res === null) {
            sink.emit('error', "error reading uri [" + uri + "] - no response object.");
        }
        if (res.statusCode !== 200) {
            sink.emit('error', "error reading uri [" + uri + "] to stream - response.status == " + res.statusCode);
        } // else
        res.pipe(sink);
        cb(res);
    }, verbose);
}

function getData(uri, cb, verbose) {
    getResponse(uri, function (e, res) {
        var data = "";
        if (e) {
            return cb(e);
        } //else
        if (res === undefined || res === null) {
            return cb("error reading uri [" + uri + "] - no response object.");
        }
        if (res.statusCode !== 200) {
            return cb("error reading uri [" + uri + "] - status == " + res.statusCode);
        } // else
        res
            .on('data', function (chunk) {
                data += chunk;
            })
            .on('end', function () {
                cb(null, data);
            })
            .on('error', cb);
    }, verbose);
}

function getJSON(uri, cb, verbose) {
    getData(uri, function (e, data) {
        if (e) {
            return cb(e);
        }
        //else
        cb(null, JSON.parse(data));
    }, verbose);
}

function getXML(uri, cb, verbose) {
    //TODO parse XML to DOM ?
    getData(uri, cb, verbose);
}

Client.prototype.stop = function () {
    clearTimeout(this.token_refresh);
    this.token = null;
    this.token_expires = Date.now();
    this.token_refresh = null;
};

Client.prototype.start = function (cb) {
    var me = this, SLACK_MILLIS = 1000, exp_in_millis;

    if (me.token_refresh !== null) { // already started...
        if (cb) {
            return cb(null); // no errors, but no token object either
        }
        return;
    }

    // else
    getJSON(this.authURI, function (e, resp) {
        if (e) {
            console.error("ERROR: %j", e);
            return cb(e);
        }

        me.token = resp.access_token;
        exp_in_millis = resp.expires_in * 1000;
        me.token_expires = Date.now() + exp_in_millis;
        if (exp_in_millis > SLACK_MILLIS) { // we assume at least 1s slack to operate
            me.token_refresh = setTimeout(function () {
                me.start();
            }, exp_in_millis - SLACK_MILLIS);
        } else {
            console.warn("token validity too short to organize self-refresh");
        }
        if (me.verbose) {
            console.log("got token %s - valid for %d - till %s", me.token, resp.expires_in, moment(me.token_expires));
        }

        if (cb) {
            cb(e, resp);
        }
    }, this.verbose);
};

Client.prototype.fetch = function (qry, cb) {
    if (arguments.length < 2) {
        cb = qry;
        qry = new ProductQuery();
    }

    if (qry.format === 'json') {
        getJSON(qry.getURI(this), function (e, resp) {
            cb(e, resp);
        }, this.verbose);
    } else if (qry.format === 'json+hal') {
        getJSON(qry.getURI(this), function (e, resp) {
            if (e) {
                cb(e);
            } // else
            var meta = resp, EMB = "_embedded", emb = meta[EMB];
            resp = emb.items;
            delete emb.items;
            cb(e, resp, meta);
        }, this.verbose);
    } else if (qry.format === 'xml') {
        getXML(qry.getURI(this), function (e, resp) {
            cb(e, resp);
        }, this.verbose);
    }
};

Client.prototype.stream = function (qry, sink, cb) {
    if (arguments.length < 2) {
        sink = qry;
        qry = new ProductQuery();
    }
    cb = cb || function (res) {}; // do nothing callback

    streamData(qry.getURI(this), sink, cb, this.verbose);
};

module.exports.client = function (settings) {
    return new Client(settings);
};
module.exports.query = function (service) {
    service = service || 'product';
    if (service === 'product') {
        return new ProductQuery();
    }
    throw "unknown service request";
};
<|endoftext|>


<commit_before>var NativeWindow = require('./bindings').Window,
    EventEmitter = process.EventEmitter,
    _hasOwn = Object.prototype.hasOwnProperty,
    handlers = new WeakMap;

module.exports = Window;

function Window(win){
  if (!(this instanceof Window))
    return new Window(win);

  var handler = new WindowHandler(win, this);
  var window = Proxy.create(handler, Window.prototype);
  handlers.set(window, handler);

  win.transition = function transition(newHandler, props){
    handler.__proto__ = newHandler;
    for (var k in props) {
      handler[k] = props[k];
    }
    return window;
  };

  win.imbue = function imbue(){
    var windowProto = window.__proto__;
    installMethods(windowProto);
    windowProto._events = handler.wrapper._events;
    ['on', 'off', 'emit', 'once'].forEach(function(key){
      windowProto[key] = EventEmitter.prototype[key];
    });
    window.emit('ready');
  };

  return window;
}

Object.keys(NativeWindow).forEach(function(key){
  if (typeof NativeWindow[key] === 'function') {
    Window[key] = NativeWindow[key];
  }
});

var installMethods = function(){
  var windowMethods = [
    'openDevTools', 'closeDevTools', 'minimize', 'maximize',
    'restore', 'drag', 'show', 'hide', 'setPosition', 'setSize'
  ].map(function(key){
    var method = NativeWindow.prototype[key];
    if (typeof method === 'function') {
      return new Function('h', 'm', 'return function '+key+'(){ m.apply(h.get(this).window, arguments); return this }')(handlers,method);
    }
  }).filter(Boolean);

  return function installMethods(o){
    windowMethods.forEach(function(method){
      o[method.name] = method;
    })
  }
}();

Window.prototype.__proto__ = EventEmitter.prototype;
installMethods(Window.prototype);

function WindowHandler(win, wrapper){
  this.window = win;
  this.wrapper = wrapper;
}

WindowHandler.prototype = {
  keys: function keys(){
    return Object.keys(this.wrapper);
  },
  enumerate: function enumerate(){
    var i=0, k=[];
    for (k[i++] in this.wrapper);
    return k;
  },
  getOwnPropertyNames: function getOwnPropertyNames(){
    return Object.getOwnPropertyNames(this.wrapper);
  },
  get: function get(rcvr, key){
    return this.wrapper[key];
  },
  set: function set(rcvr, key, value){
    this.wrapper[key] = value;
    return true;
  },
  has: function has(key){
    return key in this.wrapper;
  },
  hasOwn: function hasOwn(key){
    return _hasOwn.call(this.wrapper, key);
  },
  delete: function delete_(key){
    delete this.wrapper[key];
    return true;
  },
  defineProperty: function defineProperty(key, desc){
    Object.defineProperty(this.wrapper, key, desc);
    return true;
  },
  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(key){
    var desc = Object.getOwnPropertyDescriptor(this.wrapper, key);
    if (desc) {
      desc.configurable = true;
    }
    return desc;
  }
};
<commit_msg>add "frame" to window for accessors that modify properties<commit_after>var NativeWindow = require('./bindings').Window,
    App = require('./bindings').App,
    EventEmitter = process.EventEmitter,
    _hasOwn = Object.prototype.hasOwnProperty,
    _slice = Array.prototype.slice,
    _apply = Function.prototype.apply,
    _bind = Function.prototype.bind,
    handlers = new WeakMap;

module.exports = Window;

function Window(win){
  if (!(this instanceof Window))
    return new Window(win);

  var handler = new WindowHandler(win, this);
  var window = Proxy.create(handler, Window.prototype);
  handlers.set(window, handler);

  win.transition = function transition(newHandler, props){
    handler.__proto__ = newHandler;
    for (var k in props) {
      handler[k] = props[k];
    }
    return window;
  };

  win.imbue = function imbue(){
    var windowProto = window.__proto__;
    installMethods(windowProto);
    windowProto._events = handler.target._events;
    ['on', 'off', 'emit', 'once'].forEach(function(key){
      windowProto[key] = EventEmitter.prototype[key];
    });
    window.frame = new Frame(win);
    window.emit('ready');
  };

  return window;
}

Object.keys(NativeWindow).forEach(function(key){
  if (typeof NativeWindow[key] === 'function') {
    Window[key] = NativeWindow[key];
  }
});

var installMethods = function(){
  var windowMethods = [
    'openDevTools', 'closeDevTools', 'minimize', 'maximize',
    'restore', 'drag', 'show', 'hide', 'setPosition', 'setSize'
  ].map(function(key){
    var method = NativeWindow.prototype[key];
    if (typeof method === 'function') {
      return new Function('h', 'm', 'return function '+key+'(){ m.apply(h.get(this).window, arguments); return this }')(handlers,method);
    }
  }).filter(Boolean);

  return function installMethods(o){
    windowMethods.forEach(function(method){
      o[method.name] = method;
    })
  }
}();

Window.prototype.__proto__ = EventEmitter.prototype;
installMethods(Window.prototype);

function Reflector(target){
  this.target = target;
}

Reflector.prototype = {
  keys: function keys(){
    return Object.keys(this.target);
  },
  enumerate: function enumerate(){
    var i=0, k=[];
    for (k[i++] in this.target);
    return k;
  },
  getOwnPropertyNames: function getOwnPropertyNames(){
    return Object.getOwnPropertyNames(this.target);
  },
  get: function get(rcvr, key){
    return this.target[key];
  },
  set: function set(rcvr, key, value){
    this.target[key] = value;
    return true;
  },
  has: function has(key){
    return key in this.target;
  },
  hasOwn: function hasOwn(key){
    return _hasOwn.call(this.target, key);
  },
  delete: function delete_(key){
    delete this.target[key];
    return true;
  },
  defineProperty: function defineProperty(key, desc){
    Object.defineProperty(this.target, key, desc);
    return true;
  },
  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(key){
    var desc = Object.getOwnPropertyDescriptor(this.target, key);
    desc && (desc.configurable = true);
    return desc;
  },
  apply: function apply(rcvr, args){
    return _apply.call(this.target, rcvr, args);
  },
  construct: function construct(args){
    return new (_bind.apply(this.target, [null].concat(args)));
  }
};

function RefType(properties, accessors){
  this.refs = Object.create(null);
  if (Array.isArray(properties)) {
    this.names = properties;
    properties.forEach(function(key){
      this[key] = key;
    }, this.refs);
  } else {
    this.names = Object.keys(properties);
    this.names.forEach(function(key){
      this[key] = properties[key];
    }, this.refs);
  }

  this.accessors = Object.create(null);
  if (accessors) {
    var accessorNames = Object.keys(accessors);
    this.names = this.names.concat(accessorNames);
    accessorNames.forEach(function(key){
      this[key] = Object.getOwnPropertyDescriptor(accessors, key);
    }, this.accessors);
  }

  function RefHandler(ref, target){
    this.ref = ref;
    this.target = target;
  }

  RefHandler.prototype = this;

  var Ctor = function(ref){
    return Proxy.create(new RefHandler(ref, this), Ctor.prototype);
  };
  return Ctor;
}

RefType.prototype = {
  keys: function keys(){
    return this.names.concat(Object.keys(this.target));
  },
  enumerate: function enumerate(){
    var i = this.names.length, k = this.names.slice();
    for (k[i++] in this.target);
    return k;
  },
  getOwnPropertyNames: function getOwnPropertyNames(){
    return this.names.concat(Object.getOwnPropertyNames(this.target));
  },
  get: function get(rcvr, key){
    if (key in this.refs) {
      return this.ref[this.refs[key]];
    } else if (key in this.accessors) {
      return this.accessors[key].get.call(this.ref);
    } else {
      return this.target[key];
    }
  },
  set: function set(rcvr, key, value){
    if (key in this.refs) {
      this.ref[this.refs[key]] = value;
    } else if (key in this.accessors) {
      this.accessors[key].set.call(this.ref, value);
    } else {
      this.target[key] = value;
    }
    return true;
  },
  has: function has(key){
    return key in this.refs || key in this.accessors || key in this.target;
  },
  hasOwn: function hasOwn(key){
    return key in this.refs || key in this.accessors || _hasOwn.call(this.target, key);
  },
  delete: function delete_(key){
    if (key in this.refs) {
      delete this.ref[this.refs[key]];
    } else {
      delete this.target[key];
    }
    return true;
  },
  defineProperty: function defineProperty(key, desc){
    if (key in this.refs) {
      Object.defineProperty(this.ref, this.refs[key], desc);
    } else if (key in this.accessors) {
      this.accessors[key].set.call(this.ref, desc.value);
    } else {
      Object.defineProperty(this.target, key, desc);
    }
    return true;
  },
  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(key){
    if (key in this.refs) {
      var desc = Object.getOwnPropertyDescriptor(this.ref, this.refs[key]);
    } else if (key in this.accessors) {
      return {
        enumerable: true, configurable: true, writable: true,
        value: this.accessors[key].get.call(this.ref)
      };
    } else {
      var desc = Object.getOwnPropertyDescriptor(this.target, key);
    }
    desc && (desc.configurable = true);
    return desc;
  },
  apply: function apply(rcvr, args){
    return _apply.call(this.ref, rcvr, args);
  },
  construct: function construct(args){
    return new (_bind.apply(this.ref, [null].concat(args)));
  }
};

function WindowHandler(win, target){
  this.window = win;
  this.target = target;
}

WindowHandler.prototype = Object.create(Reflector.prototype);

var Frame = new RefType(['left', 'top', 'width', 'height', 'title'], {
  get right(){
    return App.prototype.screenWidth() - this.left - this.width;
  },
  set right(v){
    this.width = Math.max(0, App.prototype.screenWidth() - this.left - v);
  },
  get bottom(){
    return App.prototype.screenHeight() - this.top - this.height;
  },
  set bottom(v){
    this.height = Math.max(0, App.prototype.screenHeight() - this.top - v);
  }
});
<|endoftext|>


<commit_before>"use strict";

/**
 * Yields the items that don't qualify the condition.
 *
 * @this {Iterable<T>}
 * @ntime O(n)
 * @dspace O(1)
 * @example Basic Usage
 *
 * ```javascript
 * [1,2,3,4]::drop(function () {
 *   return this % 2 === 0;
 * }) // yields 1, 3
 * ```
*/
export function * drop <T> (
    condition : () => boolean,
) {
};
<commit_msg>Implemented iterable/drop.<commit_after>"use strict";

/**
 * Yields the items that don't qualify the condition.
 *
 * @this {Iterable<T>}
 * @ntime O(n)
 * @dspace O(1)
 * @example Basic Usage
 *
 * ```javascript
 * [1,2,3,4]::drop(function () {
 *   return this % 2 === 0;
 * }) // yields 1, 3
 * ```
*/
export function * drop <T> (
    condition : (_this : T) => boolean,
) {
    for ( const item of this ) {
        if ( !item::condition() ) { yield item; }
    }
};
<|endoftext|>