<commit_before>var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var fs = require('fs');
var path = require('path');
var chat = require('./chatCommands.js');

//Need to parse body with bodyparser to JSON
var jsonParser = bodyParser.json();

app.use(express.static(path.join(__dirname, './client')));

app.get('/', function(req,res){
  console.log("WEE")
})

/******************************************
 *******************************************
 *******************************************
 **************WEBHOOK STUFF****************
 *******************************************
 *******************************************
 *******************************************/
app.get('/webhook/', function(req, res) {
  if (req.query['hub.verify_token'] === 'this_is_my_token') {
    res.send(req.query['hub.challenge']);
  }
  res.send('Error, wrong validation token');
});

app.post('/webhook/', jsonParser, function(req, res) {
  messaging_events = req.body.entry[0].messaging;
  for (i = 0; i < messaging_events.length; i++) {
    event = req.body.entry[0].messaging[i];
    sender = event.sender.id;
    if (event.message && event.message.text) {
      text = event.message.text;
      if (text === 'Generic') {
        sendGenericMessage(sender);
        continue;
      }
      chat.sendTextMessage(sender, "Text received, echo: "+ text.substring(0, 200));
    }
  }
  res.sendStatus(200);
});

app.listen(process.env.PORT || 3000, function() {
  console.log('Server is lisening on port 3000');
});
<commit_msg>structured messages<commit_after>var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var fs = require('fs');
var path = require('path');
var chat = require('./chatCommands.js');

//Need to parse body with bodyparser to JSON
var jsonParser = bodyParser.json();

app.use(express.static(path.join(__dirname, './client')));

app.get('/', function(req,res){
  console.log("WEE")
})

/******************************************
 *******************************************
 *******************************************
 **************WEBHOOK STUFF****************
 *******************************************
 *******************************************
 *******************************************/
app.get('/webhook/', function(req, res) {
  if (req.query['hub.verify_token'] === 'this_is_my_token') {
    res.send(req.query['hub.challenge']);
  }
  res.send('Error, wrong validation token');
});

app.post('/webhook/', jsonParser, function(req, res) {
  messaging_events = req.body.entry[0].messaging;
  for (i = 0; i < messaging_events.length; i++) {
    event = req.body.entry[0].messaging[i];
    sender = event.sender.id;
    if (event.message && event.message.text) {
      text = event.message.text;
      if (text === 'Generic') {
        chat.sendGenericMessage(sender);
        continue;
      }
      chat.sendTextMessage(sender, "Text received, echo: "+ text.substring(0, 200));
    }
  }
  res.sendStatus(200);
});

app.listen(process.env.PORT || 3000, function() {
  console.log('Server is lisening on port 3000');
});
<|endoftext|>


<commit_before>var SQSWorker = require('sqs-worker');
var Accessory, Service, Characteristic, UUIDGen;

module.exports = function(homebridge) {

  // Accessory must be created from PlatformAccessory Constructor
  Accessory = homebridge.platformAccessory;

  // Service and Characteristic are from hap-nodejs
  Service = homebridge.hap.Service;
  Characteristic = homebridge.hap.Characteristic;
  UUIDGen = homebridge.hap.uuid;

  // For platform plugin to be considered as dynamic platform plugin,
  // registerPlatform(pluginName, platformName, constructor, dynamic), dynamic must be true
  homebridge.registerPlatform("homebridge-platform-sqs", "SQS", SQSPlatform, true);
}

function SQSPlatform(log, config, api) {

  //just capture the input, we'll set it up in accessories
  this.log = log;
  this.config = config;
  this.api = api;
}

SQSPlatform.prototype = {
  accessories: function(callback) {
    //For each device in cfg, create an accessory!
    var foundAccessories = this.config.accessories;
    var myAccessories = [];

    for (var i = 0; i < foundAccessories.length; i++) {
      var accessory = new SQSAccessory(this.log, foundAccessories[i]);
      myAccessories.push(accessory);
      this.log('Created ' + accessory.name + ' Accessory');
    }
    callback(myAccessories);
  },
  removeAccessory: function(accessory) {
    if (accessory) {
      this.api.unregisterPlatformAccessories("homebridge-amazondash", "AmazonDash", [accessory]);
    }
  }
}

//an accessorary, eg a button. This one is mostly just an on/off state button.
//SQS message toggles it, as does pressing it in the home app
function SQSAccessory(log, accessory) {
  this.log = log;
  this.accessory = accessory;
  this.name = this.accessory.name;
  this.buttonIsOn = false;
  this.startListener();
}

SQSAccessory.prototype = {
  startListener: function() {
    var self = this;

    //setup the SQS queue listener
    var options = {
      url: this.accessory.queueurl,
      region: this.accessory.region,
      accessKeyId: this.accessory.accesskey,
      secretAccessKey: this.accessory.secret,

      //eat the logging, make it goes out the Homebridge logging
      // mostly cos sqsworker is a bit noisy
      log: {
        info: function(a, b) {
          //self.log(a + " " + b);
        },
        error: function(a, b) {
          self.log("err:" + a + " " + b);
        }
      }
    };

    //setup the queue.
    this.queue = new SQSWorker(options, function(event, done) {
      self.log("message...");
      //if (self.accessory.verbose) {
        self.log(event);
      //}

      self.toggleButton();

      //report back to SQS that we are done - otherwise it'll resubmit the message
      var success = true;

      // Call `done` when you are done processing a message.
      // If everything went successfully and you don't want to see it any more,
      // set the second parameter to `true`.
      done(null, success);
    });

    //we should start by purging the queue, 'cos you dont want a load of state changes
    //coming in on startup
    this.queue.client.purgeQueue({
      QueueUrl: options.url
    }, function(err, data) {
      if (err) {
        self.log(err);
      }
      self.log("Purged the queue");
    });

  },

  toggleButton: function() {
    //toggle the internal state of the button
    this.buttonIsOn = !this.buttonIsOn;
    this.log(`${this.name}: SQS Button state change. New state is ${this.buttonIsOn}`);
    this.service.getCharacteristic(Characteristic.On).setValue(this.buttonIsOn);
  },

  identify: function(callback) {
    this.log("[" + this.name + "] Identify requested!");
    callback(); // success
  },

  getServices: function() {
    //get the services this accessory supports
    //this is were we setup the button, but if it was, eg, a fan, you'd make a fan here.

    var services = [];

    var informationService = new Service.AccessoryInformation();
    informationService
      .setCharacteristic(Characteristic.Manufacturer, 'AmazonSQS');

    var switchService = new Service.Switch(this.accessory.name);
    switchService
      .getCharacteristic(Characteristic.On)
      .on('get', this.getSPState.bind(this))
      .on('set', this.setSPState.bind(this));

    informationService
      .setCharacteristic(Characteristic.Model, 'QueueButton')
      .setCharacteristic(Characteristic.SerialNumber, '1.0');

    services.push(switchService, informationService);

    //keep the service, so we can turn it on/off later.
    this.service = switchService;

    return services;
  },

  getSPState: function(callback) {
    //homekit calling into us to get the state
    this.log(`${this.name}: Get State: ${this.buttonIsOn}`);
    callback(null, this.buttonIsOn);
  },

  setSPState: function(state, callback) {

    //homekit calling into us to set the state. state is 1 or 0
    if (state) {
      this.buttonIsOn = true;
    } else {
      this.buttonIsOn = false;
    }
    this.log(`${this.name}: Set State to ${this.buttonIsOn}`);
    callback(null, this.buttonIsOn);

  }
}
<commit_msg>less logging<commit_after>var SQSWorker = require('sqs-worker');
var Accessory, Service, Characteristic, UUIDGen;

module.exports = function(homebridge) {

  // Accessory must be created from PlatformAccessory Constructor
  Accessory = homebridge.platformAccessory;

  // Service and Characteristic are from hap-nodejs
  Service = homebridge.hap.Service;
  Characteristic = homebridge.hap.Characteristic;
  UUIDGen = homebridge.hap.uuid;

  // For platform plugin to be considered as dynamic platform plugin,
  // registerPlatform(pluginName, platformName, constructor, dynamic), dynamic must be true
  homebridge.registerPlatform("homebridge-platform-sqs", "SQS", SQSPlatform, true);
}

function SQSPlatform(log, config, api) {

  //just capture the input, we'll set it up in accessories
  this.log = log;
  this.config = config;
  this.api = api;
}

SQSPlatform.prototype = {
  accessories: function(callback) {
    //For each device in cfg, create an accessory!
    var foundAccessories = this.config.accessories;
    var myAccessories = [];

    for (var i = 0; i < foundAccessories.length; i++) {
      var accessory = new SQSAccessory(this.log, foundAccessories[i]);
      myAccessories.push(accessory);
      this.log('Created ' + accessory.name + ' Accessory');
    }
    callback(myAccessories);
  },
  removeAccessory: function(accessory) {
    if (accessory) {
      this.api.unregisterPlatformAccessories("homebridge-amazondash", "AmazonDash", [accessory]);
    }
  }
}

//an accessorary, eg a button. This one is mostly just an on/off state button.
//SQS message toggles it, as does pressing it in the home app
function SQSAccessory(log, accessory) {
  this.log = log;
  this.accessory = accessory;
  this.name = this.accessory.name;
  this.buttonIsOn = false;
  this.startListener();
}

SQSAccessory.prototype = {
  startListener: function() {
    var self = this;

    //setup the SQS queue listener
    var options = {
      url: this.accessory.queueurl,
      region: this.accessory.region,
      accessKeyId: this.accessory.accesskey,
      secretAccessKey: this.accessory.secret,

      //eat the logging, make it goes out the Homebridge logging
      // mostly cos sqsworker is a bit noisy
      log: {
        info: function(a, b) {
          //self.log(a + " " + b);
        },
        error: function(a, b) {
          self.log("err:" + a + " " + b);
        }
      }
    };

    //setup the queue.
    this.queue = new SQSWorker(options, function(event, done) {
      //self.log("message...");
      //if (self.accessory.verbose) {
      self.log(event);
      //}

      self.toggleButton();

      //report back to SQS that we are done - otherwise it'll resubmit the message
      var success = true;

      // Call `done` when you are done processing a message.
      // If everything went successfully and you don't want to see it any more,
      // set the second parameter to `true`.
      done(null, success);
    });

    //we should start by purging the queue, 'cos you dont want a load of state changes
    //coming in on startup
    this.queue.client.purgeQueue({
      QueueUrl: options.url
    }, function(err, data) {
      if (err) {
        self.log(err);
      }
      self.log("Purged the queue");
    });

  },

  toggleButton: function() {
    //toggle the internal state of the button
    this.buttonIsOn = !this.buttonIsOn;
    this.log(`${this.name}: SQS Button state change. New state is ${this.buttonIsOn}`);
    this.service.getCharacteristic(Characteristic.On).setValue(this.buttonIsOn);
  },

  identify: function(callback) {
    this.log("[" + this.name + "] Identify requested!");
    callback(); // success
  },

  getServices: function() {
    //get the services this accessory supports
    //this is were we setup the button, but if it was, eg, a fan, you'd make a fan here.

    var services = [];

    var informationService = new Service.AccessoryInformation();
    informationService
      .setCharacteristic(Characteristic.Manufacturer, 'AmazonSQS');

    var switchService = new Service.Switch(this.accessory.name);
    switchService
      .getCharacteristic(Characteristic.On)
      .on('get', this.getSPState.bind(this))
      .on('set', this.setSPState.bind(this));

    informationService
      .setCharacteristic(Characteristic.Model, 'QueueButton')
      .setCharacteristic(Characteristic.SerialNumber, '1.0');

    services.push(switchService, informationService);

    //keep the service, so we can turn it on/off later.
    this.service = switchService;

    return services;
  },

  getSPState: function(callback) {
    //homekit calling into us to get the state
    this.log(`${this.name}: Get State: ${this.buttonIsOn}`);
    callback(null, this.buttonIsOn);
  },

  setSPState: function(state, callback) {

    //homekit calling into us to set the state. state is 1 or 0
    if (state) {
      this.buttonIsOn = true;
    } else {
      this.buttonIsOn = false;
    }
    this.log(`${this.name}: Set State to ${this.buttonIsOn}`);
    callback(null, this.buttonIsOn);

  }
}
<|endoftext|>


<commit_before>const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const port = 3000

var route_main = require('./routes/route-main')
var route_family = require('./routes/route-family')
var route_locations = require('./routes/route-locations')

app.use(bodyParser.json())

app.use((err, request, response, next) => {
    // log the error, for now just console.log
    console.log(err);
    response.status(500).send('Something broke!')
});

app.all('/', function (req, res, next) {
  next() // pass control to the next handler
})

app.use('/', route_main)
app.use('/family', route_family)
app.use('/locations', route_locations)

app.listen(port)<commit_msg>Adding POST call to update family member's location - fix 6<commit_after>const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const port = 3000

var route_main = require('./routes/route-main')
var route_family = require('./routes/route-family')
var route_locations = require('./routes/route-locations')

app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

app.use((err, request, response, next) => {
    // log the error, for now just console.log
    console.log(err);
    response.status(500).send('Something broke!')
});

app.all('/', function (req, res, next) {
  next() // pass control to the next handler
})

app.use('/', route_main)
app.use('/family', route_family)
app.use('/locations', route_locations)

app.listen(port)<|endoftext|>


<commit_before>var Dbf = require(__dirname + '/lib/dbf'),
    Shp = require(__dirname + '/lib/shp');
/** getOpenLayersFeatures
 * @param {String} url - the base url for the shapefile, without extensions
 * @param {Function} callback Called with an array of OpenLayers.Feature.Vector for the given URL
 */

getFeatures("demo/TM_WORLD_BORDERS_SIMPL/TM_WORLD_BORDERS_SIMPL-0.3", function(err, data){
  console.log(JSON.stringify(data));
});

// loads and parses shapefile, returns geojson
function getFeatures(url, callback) {
  this.shpURL = url+'.shp';
  this.dbfURL = url+'.dbf';
  this.callback = callback;

  var instance = this;
  this.json = {
    type: "FeatureCollection",
    features: []
  };

  try {
    this.shpFile = new Shp(url);
    this.dbfFile = new Dbf(url);
  } catch(error) {
    console.error("Error parsing shapefile");
    return callback(error, null);
  }

  var recordsLength = instance.shpFile.records.length;
  for (var i = 0; i < recordsLength; i++) {
    var record = instance.shpFile.records[i];
    var attrs = instance.dbfFile.records[i];
    var feature = {
      type: "Feature",
      geometry: {},
      properties: {}
    };
//    console.log(record);
    feature.properties = attrs.values;

    switch(record.shapeType) {
      case Shp.ShpType.SHAPE_POINT:
        feature.geometry.type = Shp.GeoJsonType[record.shapeType];
        feature.geometry.coordinates = [record.shape.x, record.shape.y];
        break;
      case Shp.ShpType.SHAPE_POLYLINE:
        feature.geometry.type = Shp.GeoJsonType[record.shapeType];
        feature.geometry.coordinates = [];
        var pointsLen = record.shape.rings[0].length;
        for (var j = 0; j < pointsLen; j++) {
          feature.geometry.coordinates.push([record.shape.rings[0][j].x, record.shape.rings[0][j].y]);
        }
        break;
      case Shp.ShpType.SHAPE_POLYGON:
        feature.geometry.type = Shp.GeoJsonType[record.shapeType];
        feature.geometry.coordinates = [];
        var ringsLen = record.shape.rings.length;
        for (var j = 0; j < ringsLen; j++) {
          var ring = record.shape.rings[j];
          if (ring.length < 1) continue;
          var featureRing = feature.geometry.coordinates[j] = [];
          var ringLen = ring.length;
          for (var k = 0; k < ringLen; k++) {
            featureRing.push([ring[k].x, ring[k].y]);
          }
        }
        break;
      default:
        throw(new Error("Error converting SHP to geojson"))
    }

    this.json.features.push(feature);
  }
  callback(null, this.json);
}
/*
   function getOpenLayersFeatures(url, callback) {
   this.shpURL = url+'.shp';
   this.dbfURL = url+'.dbf';
   this.callback = callback;

   var instance = this;

// Parse into OL features
var parseShapefile = function () {
// we can assume that shapefile and dbf have loaded at this point, but check anyhow
if (!(instance.dbfFile && instance.shpFile)) return;

var features = [];

var recsLen = instance.shpFile.records.length;
for (var i = 0; i < recsLen; i++) {
var record = instance.shpFile.records[i];
var attrs = instance.dbfFile.records[i];

// turn shapefile geometry into WKT
// points are easy!
if (instance.shpFile.header.shapeType == ShpType.SHAPE_POINT) {
var wkt = 'POINT(' + record.shape.x + ' ' + record.shape.y + ')';
}

// lines: not too hard--
else if (instance.shpFile.header.shapeType == ShpType.SHAPE_POLYLINE) {
// prepopulate the first point
var points = [];//record.shape.rings[0].x + ' ' + record.shape.rings[0].y];
var pointsLen = record.shape.rings[0].length;
for (var j = 0; j < pointsLen; j++) {
points.push(record.shape.rings[0][j].x + ' ' + record.shape.rings[0][j].y);
}

var wkt = 'LINESTRING(' + points.join(', ') + ')';
}

// polygons: donuts
else if (instance.shpFile.header.shapeType == ShpType.SHAPE_POLYGON) {
var ringsLen = record.shape.rings.length;
var wktOuter = [];
for (var j = 0; j < ringsLen; j++) {
var ring = record.shape.rings[j];
if (ring.length < 1) continue;
var wktInner = [];//ring.x + ' ' + ring.y];
var ringLen = ring.length;
for (var k = 0; k < ringLen; k++) {
wktInner.push(ring[k].x + ' ' + ring[k].y);
}
wktOuter.push('(' + wktInner.join(', ') + ')');
}
var wkt = 'POLYGON(' + wktOuter.join(', ') + ')';
}

var the_geom = OpenLayers.Geometry.fromWKT(wkt);
features.push(new OpenLayers.Feature.Vector(the_geom, attrs));
}
callback(features);
};

var onShpFail = function() {
alert('failed to load ' + instance.shpURL);
};
var onDbfFail = function() {
alert('failed to load ' + instance.dbfURL);
}

var onShpComplete = function(oHTTP) {
var binFile = oHTTP.binaryResponse;
console.log('got data for ' + instance.shpURL + ', parsing shapefile');
instance.shpFile = new ShpFile(binFile);
if (instance.dbfFile) parseShapefile();
}

var onDbfComplete = function(oHTTP) {
  var binFile = oHTTP.binaryResponse;
  console.log('got data for ' + instance.dbfURL + ', parsing dbf file');
  instance.dbfFile = new DbfFile(binFile);
  if (instance.shpFile) parseShapefile();
}

this.shpLoader = new BinaryAjax(shpURL, onShpComplete, onShpFail);
this.dbfLoader = new BinaryAjax(dbfURL, onDbfComplete, onDbfFail);
}*/

module.exports = {

}

// ported from https://github.com/RandomEtc/shapefile-js/blob/master/src/ol_shapefile.js

<commit_msg>tweaks to allow both synch or async<commit_after>var Dbf = require(__dirname + '/lib/dbf'),
    Shp = require(__dirname + '/lib/shp');
/** getOpenLayersFeatures
 * @param {String} url - the base url for the shapefile, without extensions
 * @param {Function} callback Called with an array of OpenLayers.Feature.Vector for the given URL
 */

//getFeatures("demo/TM_WORLD_BORDERS_SIMPL/TM_WORLD_BORDERS_SIMPL-0.3", function(err, data){
//  console.log(JSON.stringify(data));
//});

// loads and parses shapefile, returns geojson
function getFeatures(url, callback) {
  this.shpURL = url+'.shp';
  this.dbfURL = url+'.dbf';
  this.callback = callback;

  var instance = this;
  this.json = {
    type: "FeatureCollection",
    features: []
  };

  try {
    this.shpFile = new Shp(url);
    this.dbfFile = new Dbf(url);
  } catch(error) {
    console.error("Error parsing shapefile");
    if (callback){
      callback(error, null);
    } else {
      throw new Error(error);
    }
  }

  var recordsLength = instance.shpFile.records.length;
  for (var i = 0; i < recordsLength; i++) {
    var record = instance.shpFile.records[i];
    var attrs = instance.dbfFile.records[i];
    var feature = {
      type: "Feature",
      geometry: {},
      properties: {}
    };
//    console.log(record);
    feature.properties = attrs.values;

    switch(record.shapeType) {
      case Shp.ShpType.SHAPE_POINT:
        feature.geometry.type = Shp.GeoJsonType[record.shapeType];
        feature.geometry.coordinates = [record.shape.x, record.shape.y];
        break;
      case Shp.ShpType.SHAPE_POLYLINE:
        feature.geometry.type = Shp.GeoJsonType[record.shapeType];
        feature.geometry.coordinates = [];
        var pointsLen = record.shape.rings[0].length;
        for (var j = 0; j < pointsLen; j++) {
          feature.geometry.coordinates.push([record.shape.rings[0][j].x, record.shape.rings[0][j].y]);
        }
        break;
      case Shp.ShpType.SHAPE_POLYGON:
        feature.geometry.type = Shp.GeoJsonType[record.shapeType];
        feature.geometry.coordinates = [];
        var ringsLen = record.shape.rings.length;
        for (var j = 0; j < ringsLen; j++) {
          var ring = record.shape.rings[j];
          if (ring.length < 1) continue;
          var featureRing = feature.geometry.coordinates[j] = [];
          var ringLen = ring.length;
          for (var k = 0; k < ringLen; k++) {
            featureRing.push([ring[k].x, ring[k].y]);
          }
        }
        break;
      default:
        throw(new Error("Error converting SHP to geojson"))
    }

    this.json.features.push(feature);
  }
  if (callback){
    callback(null, this.json);
  }
  return this.json;
}

module.exports = {
  readFileSync: getFeatures,
  readFile: getFeatures
}

// ported from https://github.com/RandomEtc/shapefile-js/blob/master/src/ol_shapefile.js

<|endoftext|>


<commit_before>var Botkit = require('botkit');
var BeepBoopBotkit = require('beepboop-botkit');
var StringArgv = require('string-argv');

var PORT = process.env.PORT
if (!PORT) {
    console.error('PORT is required');
    process.exit(1);
}

var VERIFY_TOKEN = process.env.SLACK_VERIFY_TOKEN
if (!VERIFY_TOKEN) {
  console.error('SLACK_VERIFY_TOKEN is required')
  process.exit(1)
}

var controller = Botkit.slackbot({
  // reconnect to Slack RTM when connection goes bad
  retry: Infinity,
  send_via_rtm: true,
  debug: false
});

console.log('Starting in Beep Boop multi-team mode')
var BeepBoop = BeepBoopBotkit.start(controller, { debug: true, scopes: ['channels:history'] })
var MarkovChain = require('markovchain');
var JSMegaHal = require('jsmegahal');

var COMMAND_MAPPINGS = {
    "/incaseofjoshrant": handle_incaseofjoshrant,
    "/markov": handle_markov,
    "/megahal": handle_megahal,
    "/echo": handle_echo
};

controller.setupWebserver(PORT, function(err, webserver) {
    if (err) {
        console.error(err)
        process.exit(1)
    }
    // Setup our slash command webhook endpoints
    controller.createWebhookEndpoints(webserver)
});

controller.on('slash_command', function(bot, message) {
    if (message.token !== VERIFY_TOKEN) {
        return bot.res.send(401, 'Unauthorized');
    }
    if (!COMMAND_MAPPINGS[message.command]) {
        bot.replyAcknowledge();
        return;
    }

    var params = StringArgv(message.text);

    COMMAND_MAPPINGS[message.command](bot, message, params);
});

// receive an interactive message, and reply with a message that will replace the original
controller.on('interactive_message_callback', function(bot, message) {
    if (message.token !== VERIFY_TOKEN) {
        return bot.res.send(401, 'Unauthorized');
    }

    return bot.res.send(200, ''); //do nothing
});

// ============ various slash command handlers =============

function handle_incaseofjoshrant(bot, message, params) {
    bot.replyPublicDelayed(message, {
        "response_type": "in_channel",
        "attachments": [{
            "title": '@' + message.user_name + ' activated emergency alert procedure',
            "image_url": "http://i.imgur.com/wtYhyuN.png"
        }]
    }, function() {
        return bot.res.send(200, '');
    });
}

function handle_markov(bot, message, params) {
    //Hack in and get our access token
    var workerKey = Object.keys(BeepBoop.workers)[0];
    var token = BeepBoop.workers[workerKey].resource.SlackAccessToken;

    var count = 500;
    if (params && params.length > 0) {
        count = Number(params[0]);
    }

    //Get our message history
    bot.api.channels.history({
        channel: message.channel_id,
        token: token,
        count: count
    }, function(err, data) {

        var m = new MarkovChain('');
        for (var i = 0; i < data.messages.length; i++) {
            if (data.messages[i].user) {
                m.parse(data.messages[i].text);
            }
        }

        var title = "@" + message.user_name + " requested a markov chain based on the last " + count + " messages";

        var text = m.process();
        bot.replyPublicDelayed(message, {
            "response_type": "in_channel",
            "attachments": [{
                 "title": title,
                "text": text
            }]
        }, function() {
            return bot.res.send(200, '');
        });
    });
}

function handle_megahal(bot, message, params) {
    //Hack in and get our access token
    var workerKey = Object.keys(BeepBoop.workers)[0];
    var token = BeepBoop.workers[workerKey].resource.SlackAccessToken;

    var count = 1000;
    var order = 2;
    var question = undefined;
    if (params && params.length > 0) {
        question = params.join(' ');
    }

    //Get our message history
    bot.api.channels.history({
        channel: message.channel_id,
        token: token,
        count: count
    }, function(err, data) {

        var m = new JSMegaHal(order);
        var currentUser = null;
        var currentMessage = null;
        for (var i = 0; i < data.messages.length; i++) {
            var msg = data.messages[i];

            if (!msg.user) {
                continue;
            }

            if (msg.user !== currentUser) {
                if (currentMessage) {
                    console.log("Adding: " + currentMessage);
                    m.add(currentMessage);
                }
                currentUser = msg.user;
                currentMessage = msg.text;
            } else {
                //Same user with multiple messages should be combined
                currentMessage += '. ' + msg.text;
            }
        }

        console.log("Adding: " + currentMessage);
        m.add(currentMessage);

        var title = null;
        if (question) {
            title = "@" + message.user_name + " requested a megahal response to: '" + question + "'";
        } else {
            title = "@" + message.user_name + " requested a random megahal response";
        }

        var text = m.getReply(question);
        bot.replyPublicDelayed(message, {
            "response_type": "in_channel",
            "attachments": [{
                 "title": title,
                "text": text
            }]
        }, function() {
            return bot.res.send(200, '');
        });
    });
}

function handle_echo(bot, message, params) {
    var text = 'Whatever...'
    if (params) {
        var obj = null;
        switch (params[0]) {
            case "beepboop":
                obj = BeepBoop;
                break;
            case "beepboopbotkit":
                obj = BeepBoopBotkit;
                break;
            case "controller":
                obj = controller;
                break;
            case "message":
                obj = message;
                break;
            default:
                obj = bot;
                break;
        }
        for (var i = 1; i < params.length; i++) {
            obj = obj[params[i]];
            if (obj === null || obj === undefined) {
                text = "Couldnt find " + params[i] + " in " + obj;
                break;
            }
        }

        if (obj == null || obj == undefined) {
            text = 'null/undefined';
        } else if (obj instanceof String) {
            text = obj + ':(String)';
        } else if (obj instanceof Number) {
            text = obj + ':(Number)';
        } else if (obj instanceof Object) {
            text = obj + ':(Object) has keys ' + Object.keys(obj);
        } else {
            text = obj + ':(' + typeof obj + ') has keys ' + Object.keys(obj);
        }
    }
    bot.replyPublicDelayed(message, {
        "response_type": "in_channel",
        "attachments": [{
            "title": '/echo ' + params.join(' '),
            "text": text
        }]
    }, function() {
        return bot.res.send(200, '');
    });
}

<commit_msg>less logs<commit_after>var Botkit = require('botkit');
var BeepBoopBotkit = require('beepboop-botkit');
var StringArgv = require('string-argv');

var PORT = process.env.PORT
if (!PORT) {
    console.error('PORT is required');
    process.exit(1);
}

var VERIFY_TOKEN = process.env.SLACK_VERIFY_TOKEN
if (!VERIFY_TOKEN) {
  console.error('SLACK_VERIFY_TOKEN is required')
  process.exit(1)
}

var controller = Botkit.slackbot({
  // reconnect to Slack RTM when connection goes bad
  retry: Infinity,
  send_via_rtm: true,
  debug: false
});

console.log('Starting in Beep Boop multi-team mode')
var BeepBoop = BeepBoopBotkit.start(controller, { debug: true, scopes: ['channels:history'] })
var MarkovChain = require('markovchain');
var JSMegaHal = require('jsmegahal');

var COMMAND_MAPPINGS = {
    "/incaseofjoshrant": handle_incaseofjoshrant,
    "/markov": handle_markov,
    "/megahal": handle_megahal,
    "/echo": handle_echo
};

controller.setupWebserver(PORT, function(err, webserver) {
    if (err) {
        console.error(err)
        process.exit(1)
    }
    // Setup our slash command webhook endpoints
    controller.createWebhookEndpoints(webserver)
});

controller.on('slash_command', function(bot, message) {
    if (message.token !== VERIFY_TOKEN) {
        return bot.res.send(401, 'Unauthorized');
    }
    if (!COMMAND_MAPPINGS[message.command]) {
        bot.replyAcknowledge();
        return;
    }

    var params = StringArgv(message.text);

    COMMAND_MAPPINGS[message.command](bot, message, params);
});

// receive an interactive message, and reply with a message that will replace the original
controller.on('interactive_message_callback', function(bot, message) {
    if (message.token !== VERIFY_TOKEN) {
        return bot.res.send(401, 'Unauthorized');
    }

    return bot.res.send(200, ''); //do nothing
});

// ============ various slash command handlers =============

function handle_incaseofjoshrant(bot, message, params) {
    bot.replyPublicDelayed(message, {
        "response_type": "in_channel",
        "attachments": [{
            "title": '@' + message.user_name + ' activated emergency alert procedure',
            "image_url": "http://i.imgur.com/wtYhyuN.png"
        }]
    }, function() {
        return bot.res.send(200, '');
    });
}

function handle_markov(bot, message, params) {
    //Hack in and get our access token
    var workerKey = Object.keys(BeepBoop.workers)[0];
    var token = BeepBoop.workers[workerKey].resource.SlackAccessToken;

    var count = 500;
    if (params && params.length > 0) {
        count = Number(params[0]);
    }

    //Get our message history
    bot.api.channels.history({
        channel: message.channel_id,
        token: token,
        count: count
    }, function(err, data) {

        var m = new MarkovChain('');
        for (var i = 0; i < data.messages.length; i++) {
            if (data.messages[i].user) {
                m.parse(data.messages[i].text);
            }
        }

        var title = "@" + message.user_name + " requested a markov chain based on the last " + count + " messages";

        var text = m.process();
        bot.replyPublicDelayed(message, {
            "response_type": "in_channel",
            "attachments": [{
                 "title": title,
                "text": text
            }]
        }, function() {
            return bot.res.send(200, '');
        });
    });
}

function handle_megahal(bot, message, params) {
    //Hack in and get our access token
    var workerKey = Object.keys(BeepBoop.workers)[0];
    var token = BeepBoop.workers[workerKey].resource.SlackAccessToken;

    var count = 1000;
    var order = 2;
    var question = undefined;
    if (params && params.length > 0) {
        question = params.join(' ');
    }

    //Get our message history
    bot.api.channels.history({
        channel: message.channel_id,
        token: token,
        count: count
    }, function(err, data) {

        var m = new JSMegaHal(order);
        var currentUser = null;
        var currentMessage = null;
        for (var i = 0; i < data.messages.length; i++) {
            var msg = data.messages[i];

            if (!msg.user) {
                continue;
            }

            if (msg.user !== currentUser) {
                if (currentMessage) {
                    m.add(currentMessage);
                }
                currentUser = msg.user;
                currentMessage = msg.text;
            } else {
                //Same user with multiple messages should be combined
                currentMessage += '. ' + msg.text;
            }
        }

        m.add(currentMessage);

        var title = null;
        if (question) {
            title = "@" + message.user_name + " requested a megahal response to: '" + question + "'";
        } else {
            title = "@" + message.user_name + " requested a random megahal response";
        }

        var text = m.getReply(question);
        bot.replyPublicDelayed(message, {
            "response_type": "in_channel",
            "attachments": [{
                 "title": title,
                "text": text
            }]
        }, function() {
            return bot.res.send(200, '');
        });
    });
}

function handle_echo(bot, message, params) {
    var text = 'Whatever...'
    if (params) {
        var obj = null;
        switch (params[0]) {
            case "beepboop":
                obj = BeepBoop;
                break;
            case "beepboopbotkit":
                obj = BeepBoopBotkit;
                break;
            case "controller":
                obj = controller;
                break;
            case "message":
                obj = message;
                break;
            default:
                obj = bot;
                break;
        }
        for (var i = 1; i < params.length; i++) {
            obj = obj[params[i]];
            if (obj === null || obj === undefined) {
                text = "Couldnt find " + params[i] + " in " + obj;
                break;
            }
        }

        if (obj == null || obj == undefined) {
            text = 'null/undefined';
        } else if (obj instanceof String) {
            text = obj + ':(String)';
        } else if (obj instanceof Number) {
            text = obj + ':(Number)';
        } else if (obj instanceof Object) {
            text = obj + ':(Object) has keys ' + Object.keys(obj);
        } else {
            text = obj + ':(' + typeof obj + ') has keys ' + Object.keys(obj);
        }
    }
    bot.replyPublicDelayed(message, {
        "response_type": "in_channel",
        "attachments": [{
            "title": '/echo ' + params.join(' '),
            "text": text
        }]
    }, function() {
        return bot.res.send(200, '');
    });
}

<|endoftext|>


<commit_before>var fs = require('fs')

var isBuffer = Buffer.isBuffer
var Notify = require('pull-notify')
var Live = require('pull-live')
var pull = require('pull-stream/pull')
var Map = require('pull-stream/throughs/map')

var Blocks = require('block-reader')

function frame (data) {
  var length = data.reduce(function (total, e) { return total + e.value.length }, 0)
  var b = new Buffer(length + data.length * 8)
  var offset = 0
  for(var i = 0; i < data.length; i++) {
    var item = data[i]
    //mutate the items
    var buf = item.value
    item.offset = 0 + offset
    b.writeUInt32BE(buf.length, 0 + offset) //start
    b.writeUInt32BE(buf.length, 4+buf.length + offset) //end
    item.value.copy(b, 4 + offset, 0, buf.length)
    offset += buf.length + 8
  }
  return b
}

function format (opts) {
  var keys = opts.keys === true //default to false
  var values = opts.value !== false //default to true
  return Map(function (data) {
    return keys && values ? data : values ? data.value : data.key
  })
}

module.exports = function (file, length) {

  var notify = Notify()
  length = length || 1024
  var blocks = Blocks(file, length, 'a+')

  var queue = [], writing = false
  //TODO: check current size of file!
  var offset = -1

  function write () {
    if(writing) return
    if(!queue.length) return
    writing = true
    var data = []
    var framed = frame(queue)
    var _queue = queue
    queue = []
    blocks.append(framed, function (err, _offset) {
      writing = false
      while(_queue.length) {
        var q = _queue.shift()
        var o = (_offset - framed.length) + q.offset
        offset = Math.max(offset, o)
        q.cb(err, o)
      }
      if(queue.length) write()
    })
  }

  var log
  return log = {
    //create a stream between any two records.
    //read the first value, then scan forward or backwards
    //in the direction of the log

    //using pull-live this way means that things added in real-time are buffered
    //in memory until they are read, that means less predictable memory usage.
    //instead, we should track the offset we are up to, and wait if necessary.
    stream: Live(function (opts) {
      var reverse = opts && opts.reverse
      var next = reverse ? (opts && opts.max || blocks.size()) : (opts && opts.min || 0)
      var diff = reverse ? -1 : 1
      var get = reverse ? log.getPrevious : log.get
      var end = offset
      return pull(function (abort, cb) {
        if(abort) cb(abort)
        else if(reverse ? next <= 0 : next > end)
          cb(true)
        else
          get(next, function (err, value) {
            if(err) return cb(true) //err)
            else if(!value || !value.length) return cb(true)
            else {
              var _offset = next
              next = next + (value.length + 8)*diff
              cb(null, {key: _offset, value: value})
            }
          })
      }, format(opts))
    }, function (opts) {
      return pull(notify.listen(), format(opts))
    }),
    //if value is an array of buffers, then treat that as a batch.
    append: function (value, cb) {
      if(!isBuffer(value)) throw new Error('value must be a buffer')
      queue.push({value: value, cb: function (err, offset) {
        if(err) return cb(err)
        notify({key: offset, value: value})
        cb(null, offset)
      }})
      write()
    },
    get: function (offset, cb) {
      //read the block that offset is in.
      //if offset is near the end of the block, read two blocks.
      blocks.readUInt32BE(offset, function (err, length) {
        if(err) return cb(err)
        blocks.read(offset + 4, offset+4 + length, cb)
      })
    },
    //get the record _before_ the given offset.
    getPrevious: function (_offset, cb) {
      //don't read before start of file...
      _offset = _offset || blocks.size()
      if(_offset == 0) return cb(new Error('attempted read previous to first object'))
      blocks.readUInt32BE(_offset - 4, function (err, length) {
        if(err) return cb(err)
        blocks.read(_offset - 4 - length, _offset - 4, cb)
      })
    },
  }
}
<commit_msg>basic batch append<commit_after>var fs = require('fs')

var isBuffer = Buffer.isBuffer
var Notify = require('pull-notify')
var Live = require('pull-live')
var pull = require('pull-stream/pull')
var Map = require('pull-stream/throughs/map')

var Blocks = require('block-reader')

function frame (data) {
  var length = data.reduce(function (total, e) { return total + e.value.length }, 0)
  var b = new Buffer(length + data.length * 8)
  var offset = 0
  for(var i = 0; i < data.length; i++) {
    var item = data[i]
    //mutate the items
    var buf = item.value
    item.offset = 0 + offset
    b.writeUInt32BE(buf.length, 0 + offset) //start
    b.writeUInt32BE(buf.length, 4+buf.length + offset) //end
    item.value.copy(b, 4 + offset, 0, buf.length)
    offset += buf.length + 8
  }
  return b
}

function format (opts) {
  var keys = opts.keys === true //default to false
  var values = opts.value !== false //default to true
  return Map(function (data) {
    return keys && values ? data : values ? data.value : data.key
  })
}

module.exports = function (file, length) {

  var notify = Notify()
  length = length || 1024
  var blocks = Blocks(file, length, 'a+')

  var queue = [], writing = false
  //TODO: check current size of file!
  var offset = -1

  try {
    offset = fs.statSync(file).size
  } catch(_) {}

  function write () {
    if(writing) return
    if(!queue.length) return
    writing = true
    var data = []
    var framed = frame(queue)
    var _queue = queue
    queue = []
    blocks.append(framed, function (err, _offset) {
      writing = false
      while(_queue.length) {
        var q = _queue.shift()
        var o = (_offset - framed.length) + q.offset
        offset = Math.max(offset, o)
        q.cb(err, o)
      }
      if(queue.length) write()
    })
  }

  var log
  return log = {
    //create a stream between any two records.
    //read the first value, then scan forward or backwards
    //in the direction of the log

    //using pull-live this way means that things added in real-time are buffered
    //in memory until they are read, that means less predictable memory usage.
    //instead, we should track the offset we are up to, and wait if necessary.
    stream: Live(function (opts) {
      var reverse = opts && opts.reverse
      var next = reverse ? (opts && opts.max || blocks.size()) : (opts && opts.min || 0)
      var diff = reverse ? -1 : 1
      var get = reverse ? log.getPrevious : log.get
      var end = offset
      return pull(function (abort, cb) {
        if(abort) cb(abort)
        else if(reverse ? next <= 0 : next > end)
          cb(true)
        else
          get(next, function (err, value) {
            if(err) return cb(true) //err)
            else if(!value || !value.length) return cb(true)
            else {
              var _offset = next
              next = next + (value.length + 8)*diff
              cb(null, {key: _offset, value: value})
            }
          })
      }, format(opts))
    }, function (opts) {
      return pull(notify.listen(), format(opts))
    }),
    //if value is an array of buffers, then treat that as a batch.
    append: function (value, cb) {
      //TODO: make this like, actually durable...
      if(Array.isArray(value)) {
        var offsets = []
        value.forEach(function (v) {
          queue.push({value: v, cb: function (err, offset) {
            offsets.push(offset)
            if(offsets.length === value.length)
              cb(null, offsets)
          }})
        })

        return write()
      }
      if(!isBuffer(value)) throw new Error('value must be a buffer')
      queue.push({value: value, cb: function (err, offset) {
        if(err) return cb(err)
        notify({key: offset, value: value})
        cb(null, offset)
      }})
      write()
    },
    get: function (offset, cb) {
      //read the block that offset is in.
      //if offset is near the end of the block, read two blocks.
      blocks.readUInt32BE(offset, function (err, length) {
        if(err) return cb(err)
        blocks.read(offset + 4, offset+4 + length, cb)
      })
    },
    //get the record _before_ the given offset.
    getPrevious: function (_offset, cb) {
      //don't read before start of file...
      _offset = _offset || blocks.size()
      if(_offset == 0) return cb(new Error('attempted read previous to first object'))
      blocks.readUInt32BE(_offset - 4, function (err, length) {
        if(err) return cb(err)
        blocks.read(_offset - 4 - length, _offset - 4, cb)
      })
    },
  }
}

<|endoftext|>


<commit_before>#!/usr/bin/env node

var path = require('path')

var program = require('commander')
var gulp = require('gulp')
var sass = require('gulp-sass')
var less = require('gulp-less')
var babel = require('gulp-babel')
var rename = require("gulp-rename")
var gutil = require('gulp-util')
var plumber = require('gulp-plumber')
var gap = require('gulp-append-prepend')
var pug = require('gulp-pug')
var sourcemaps = require('gulp-sourcemaps')
var bro = require("gulp-bro") // browserify
var markdown = require('gulp-markdown')
var uglify = require('gulp-uglify')
var autoprefixer = require('gulp-autoprefixer')
var cleanCSS = require('gulp-clean-css')
var imagemin = require('gulp-imagemin')
var imageminPngquant = require('imagemin-pngquant')
var webp = require('gulp-webp')
var async = require("async")

var CWD = process.cwd()
var ROOT = __dirname
var CWD_name = CWD.split(path.sep)[CWD.split(path.sep).length - 1] // directory name of CWD

var browserSync = require("browser-sync");
var bs = browserSync.create();

var ts = require('gulp-typescript');

var zip = require('gulp-zip');

var noop = () => {}

var excludeArr = program.exclude ? program.exclude.split(':').map(v => "!" + v) : [];

var build = {
    sass: function (func = noop) {
        console.log('begin: \t sass built');

        var srcArr = [path.resolve(CWD, '**/*.scss'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(program.sourcemap ? sourcemaps.init() : gutil.noop())
            .pipe(sass().on('error', sass.logError))
            .pipe(autoprefixer({
                browsers: ['last 2 versions'],
                cascade: false
            }))
            .pipe(program.minify ? cleanCSS({
                compatibility: 'ie8'
            }) : gutil.noop())
            .pipe(program.sourcemap ? sourcemaps.write('./maps') : gutil.noop())
            .on('end', function () {
                console.log('done: \t sass built');
                func()
            })
            .pipe(gulp.dest(dist));
    },
    less: function (func = noop) {
        console.log('begin: \t less built');
        var srcArr = [path.resolve(CWD, '**/*.less'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(program.sourcemap ? sourcemaps.init() : gutil.noop())
            .pipe(less().on('error', sass.logError))
            .pipe(autoprefixer({
                browsers: ['last 2 versions'],
                cascade: false
            }))
            .pipe(program.minify ? cleanCSS({
                compatibility: 'ie8'
            }) : gutil.noop())
            .pipe(program.sourcemap ? sourcemaps.write('./maps') : gutil.noop())
            .on('end', function () {
                console.log('done: \t less built');
                func();
            })
            .pipe(gulp.dest(dist));
    },
    es6: function (func = noop) {
        console.log('begin: \t es6 built');
        var srcArr = [path.resolve(CWD, '**/*.es6'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(plumber())
            .pipe(babel({
                // presets: ["babel-preset-es2015", "babel-preset-es2016", "babel-preset-es2017"].map(require.resolve)
                presets: [
                    [require.resolve('babel-preset-env'), {
                        "targets": {
                            "browsers": ["last 2 versions", "safari >= 7"]
                        }
                    }], require.resolve("babel-preset-stage-0"), require.resolve("babel-preset-stage-1"), require.resolve("babel-preset-stage-2"), require.resolve("babel-preset-stage-3")
                ]
            }))
            // .pipe(program.browserify ? bro() : gutil.noop())
            .pipe(program.babelpolyfill ? gap.prependFile(path.resolve(ROOT, 'lib/polyfill.min.js')) : gutil.noop())
            .on('error', function (e) {
                gutil.log(e);
            })
            .pipe(rename(function (path) {
                path.extname = ".js"
            }))
            // .pipe(program.minify ? uglify() : gutil.noop())
            .pipe(gulp.dest(dist))
            .pipe(program.browserify ? bro() : gutil.noop())
            .pipe(program.minify ? uglify() : gutil.noop())
            .on('end', function () {
                console.log('done: \t es6 built');
                func();
            })
            .pipe(gulp.dest(dist))
    },
    pug: function (func = noop) {
        console.log('begin: \t pug built');
        var srcArr = [path.resolve(CWD, '**/*.pug'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(pug({
                pretty: true
            }))
            .on('error', function (e) {
                gutil.log(e);
            })
            .on('end', function () {
                console.log('done: \t pug built');
                func();
            })
            .pipe(rename(function (path) {
                path.extname = ".html"
            }))
            .pipe(gulp.dest(dist));
    },
    markdown: function () {
        console.log('begin: \t markdown built');
        var srcArr = [path.resolve(CWD, '**/*.md'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(markdown())
            .on('error', function (e) {
                gutil.log(e);
            })
            .on('end', function () {
                console.log('done: \t markdown built');
            })
            .pipe(rename(function (path) {
                path.extname = ".html"
            }))
            .pipe(gulp.dest(dist));
    },
    imageMin: function () {
        console.log('begin: \t imageMin built');
        var srcArr = [path.resolve(CWD, '**/*.png'), path.resolve(CWD, '**/*.jpg'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .on('error', function (e) {
                gutil.log(e);
            })
            .on('end', function () {
                console.log('done: \t imageMin built');
            })
            .pipe(imagemin([
                imagemin.gifsicle({
                    interlaced: true
                }),
                imagemin.jpegtran({
                    progressive: true
                }),
                imageminPngquant({
                    // quality: "80"
                    verbose: true
                })
            ]))
            .pipe(gulp.dest(dist));
    },
    image2Webp: () => {
        console.log('Begin ImageMin');
        async.parallel([
                function (callback) {
                    build.jpg2Webp().then(callback);
                },
                function (callback) {
                    build.png2Webp().then(callback);
                }
            ],
            // optional callback
            function (err, results) {
                // the results array will equal ['one','two'] even though
                // the second function had a shorter timeout.
                console.log('Done ImageMin');
            });
    },
    png2Webp: () => {
        return new Promise((resolve, reject) => {
            var srcArr = [path.resolve(CWD, '**/*.png'), '!**/node_modules/**/*'].concat(excludeArr);
            var dist = path.resolve(CWD, './');
            gulp.src(srcArr)
                .on('error', function (e) {
                    gutil.log(e);
                    reject(e)
                })
                .on('end', function () {
                    console.log('done: \t webp built');
                    resolve();
                })
                .pipe(webp())
                .pipe(rename(function (path) {
                    path.basename += ".png"
                }))
                .pipe(gulp.dest(dist));
        });
    },
    jpg2Webp: () => {
        return new Promise((resolve, reject) => {
            var srcArr = [path.resolve(CWD, '**/*.jpg'), '!**/node_modules/**/*'].concat(excludeArr);
            var dist = path.resolve(CWD, './');
            gulp.src(srcArr)
                .on('error', function (e) {
                    gutil.log(e);
                    reject(e)
                })
                .on('end', function () {
                    console.log('done: \t webp built');
                    resolve();
                })
                .pipe(webp())
                .pipe(rename(function (path) {
                    path.basename += ".jpg"
                }))
                .pipe(gulp.dest(dist));
        });
    },
    startServer: () => {
        bs.init({
            server: CWD,
            open: "external"
        });
    },
    typescript: () => {
        console.log('begin: \t typescript built');
        return new Promise((resolve, reject) => {
            var srcArr = [path.resolve(CWD, '**/*.ts'), '!**/node_modules/**/*', "!**/*.d.ts"].concat(excludeArr);
            var dist = path.resolve(CWD, './');
            gulp.src(srcArr)
                .pipe(ts({
                    noImplicitAny: true,
                    target: "es5",
                    declaration: true
                }, ts.reporter.longReporter(true)))
                .on('end', function () {
                    console.log('done: \t typescript built');
                    resolve();
                })
                .pipe(gulp.dest(dist));
        });
    },
    zip: () => {
        console.log('begin: \t zip built');
        return new Promise((resolve, reject) => {
            var srcArr = [path.resolve(CWD, '**/*'), '!**/node_modules/**/*', "!**/*.d.ts", "!**/*.scss", "!**/*.es6", "!**/*.less", "!**/*.pug"].concat(excludeArr);
            var dist = path.resolve(CWD, './../');
            gulp.src(srcArr)
                .pipe(zip(CWD_name + '.zip'))
                .on('error', function (e) {
                    gutil.log(e);
                    reject(e)
                })
                .on('end', function () {
                    console.log('done: \t zip built');
                    resolve();
                })
                .pipe(gulp.dest(dist));
        });
    }
};

gulp.task('sass:watch', function () {
    gulp.watch(['**/*.scss', '!**/node_modules/**/*'], {
        cwd: CWD
    }, () => {
        build.sass(() => {
            if (program.server) {
                bs.reload("*.css");
            }
        });
    });
});
gulp.task('less:watch', function () {
    gulp.watch(['**/*.less', '!**/node_modules/**/*'], {
        cwd: CWD
    }, () => {
        build.less(() => {
            if (program.server) {
                bs.reload("*.css");
            }
        })
    });
});
gulp.task('es6:watch', function () {
    gulp.watch(['**/*.es6', '!**/node_modules/**/*'], {
        cwd: CWD
    }, () => {
        build.es6(() => {
            if (program.server) {
                bs.reload("*.js");
            }
        })
    });
});
gulp.task('pug:watch', function () {
    gulp.watch(['**/*.pug', '!**/node_modules/**/*'], {
        cwd: CWD
    }, () => {
        build.pug(() => {
            if (program.server) {
                setTimeout(() => {
                    bs.reload();
                }, 100);

            }
        })
    });
});
gulp.task('markdown:watch', function () {
    gulp.watch(['**/*.md', '!**/node_modules/**/*'], {
        cwd: CWD
    }, build.markdown);
});

gulp.task('typescript:watch', function () {
    gulp.watch(['**/*.ts', '!**/node_modules/**/*'], {
        cwd: CWD
    }, build.typescript);
});

program
    .version('0.1.0')
    .usage('[options] <file ...>')
    .option('-p, --babelpolyfill', 'use babel-polyfill. Default: false')
    .option('-b, --build', 'build only')
    .option('--br, --browserify', 'browserify modules')
    .option('-w, --watch', 'watch mode')
    .option('-s, --sourcemap', 'write sourcemap')
    .option('-m, --minify', 'minify')
    .option('-x, --exclude <string>', 'exclude glob pattern. E.g. "**/*.min.js:**/*.min.css"')
    .option('--webp', 'generate webp')
    .option('--zip', 'zip project for release')
    .option('--server', 'start static server')
    .parse(process.argv);

// console.log(program.exclude);

if(program.zip) {
    build.zip();
}

if (program.webp) {
    build.image2Webp();
}

if (program.build) {
    build.sass();
    build.less();
    build.es6();
    build.pug();
    build.markdown();
    build.imageMin();
    build.typescript();
}

if(program.watch){
    gulp.start(["sass:watch", 'less:watch', 'es6:watch', 'pug:watch', 'markdown:watch', "typescript:watch"], function () {
        console.log('laziness is ready...');
    });
}

if (program.server) {
    build.startServer()
}<commit_msg>clean<commit_after>#!/usr/bin/env node

var path = require('path')

var program = require('commander')
var gulp = require('gulp')
var sass = require('gulp-sass')
var less = require('gulp-less')
var babel = require('gulp-babel')
var rename = require("gulp-rename")
var gutil = require('gulp-util')
var plumber = require('gulp-plumber')
var gap = require('gulp-append-prepend')
var pug = require('gulp-pug')
var sourcemaps = require('gulp-sourcemaps')
var bro = require("gulp-bro") // browserify
var markdown = require('gulp-markdown')
var uglify = require('gulp-uglify')
var autoprefixer = require('gulp-autoprefixer')
var cleanCSS = require('gulp-clean-css')
var imagemin = require('gulp-imagemin')
var imageminPngquant = require('imagemin-pngquant')
var webp = require('gulp-webp')
var async = require("async")

var CWD = process.cwd()
var ROOT = __dirname
var CWD_name = CWD.split(path.sep)[CWD.split(path.sep).length - 1] // directory name of CWD

var browserSync = require("browser-sync");
var bs = browserSync.create();

var ts = require('gulp-typescript');

var zip = require('gulp-zip');

var noop = () => {}

var excludeArr = program.exclude ? program.exclude.split(':').map(v => "!" + v) : [];

var build = {
    sass: function (func = noop) {
        console.log('begin: \t sass built');

        var srcArr = [path.resolve(CWD, '**/*.scss'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(program.sourcemap ? sourcemaps.init() : gutil.noop())
            .pipe(sass().on('error', sass.logError))
            .pipe(autoprefixer({
                browsers: ['last 2 versions'],
                cascade: false
            }))
            .pipe(program.minify ? cleanCSS({
                compatibility: 'ie8'
            }) : gutil.noop())
            .pipe(program.sourcemap ? sourcemaps.write('./maps') : gutil.noop())
            .on('end', function () {
                console.log('done: \t sass built');
                func()
            })
            .pipe(gulp.dest(dist));
    },
    less: function (func = noop) {
        console.log('begin: \t less built');
        var srcArr = [path.resolve(CWD, '**/*.less'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(program.sourcemap ? sourcemaps.init() : gutil.noop())
            .pipe(less().on('error', sass.logError))
            .pipe(autoprefixer({
                browsers: ['last 2 versions'],
                cascade: false
            }))
            .pipe(program.minify ? cleanCSS({
                compatibility: 'ie8'
            }) : gutil.noop())
            .pipe(program.sourcemap ? sourcemaps.write('./maps') : gutil.noop())
            .on('end', function () {
                console.log('done: \t less built');
                func();
            })
            .pipe(gulp.dest(dist));
    },
    es6: function (func = noop) {
        console.log('begin: \t es6 built');
        var srcArr = [path.resolve(CWD, '**/*.es6'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(plumber())
            .pipe(babel({
                // presets: ["babel-preset-es2015", "babel-preset-es2016", "babel-preset-es2017"].map(require.resolve)
                presets: [
                    [require.resolve('babel-preset-env'), {
                        "targets": {
                            "browsers": ["last 2 versions", "safari >= 7"]
                        }
                    }], require.resolve("babel-preset-stage-0"), require.resolve("babel-preset-stage-1"), require.resolve("babel-preset-stage-2"), require.resolve("babel-preset-stage-3")
                ]
            }))
            // .pipe(program.browserify ? bro() : gutil.noop())
            .pipe(program.babelpolyfill ? gap.prependFile(path.resolve(ROOT, 'lib/polyfill.min.js')) : gutil.noop())
            .on('error', function (e) {
                gutil.log(e);
            })
            .pipe(rename(function (path) {
                path.extname = ".js"
            }))
            // .pipe(program.minify ? uglify() : gutil.noop())
            .pipe(gulp.dest(dist))
            .pipe(program.browserify ? bro() : gutil.noop())
            .pipe(program.minify ? uglify() : gutil.noop())
            .on('end', function () {
                console.log('done: \t es6 built');
                func();
            })
            .pipe(gulp.dest(dist))
    },
    pug: function (func = noop) {
        console.log('begin: \t pug built');
        var srcArr = [path.resolve(CWD, '**/*.pug'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(pug({
                pretty: true
            }))
            .on('error', function (e) {
                gutil.log(e);
            })
            .on('end', function () {
                console.log('done: \t pug built');
                func();
            })
            .pipe(rename(function (path) {
                path.extname = ".html"
            }))
            .pipe(gulp.dest(dist));
    },
    markdown: function () {
        console.log('begin: \t markdown built');
        var srcArr = [path.resolve(CWD, '**/*.md'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .pipe(markdown())
            .on('error', function (e) {
                gutil.log(e);
            })
            .on('end', function () {
                console.log('done: \t markdown built');
            })
            .pipe(rename(function (path) {
                path.extname = ".html"
            }))
            .pipe(gulp.dest(dist));
    },
    imageMin: function () {
        console.log('begin: \t imageMin built');
        var srcArr = [path.resolve(CWD, '**/*.png'), path.resolve(CWD, '**/*.jpg'), '!**/node_modules/**/*'].concat(excludeArr);
        var dist = path.resolve(CWD, './');
        return gulp.src(srcArr)
            .on('error', function (e) {
                gutil.log(e);
            })
            .on('end', function () {
                console.log('done: \t imageMin built');
            })
            .pipe(imagemin([
                imagemin.gifsicle({
                    interlaced: true
                }),
                imagemin.jpegtran({
                    progressive: true
                }),
                imageminPngquant({
                    // quality: "80"
                    verbose: true
                })
            ]))
            .pipe(gulp.dest(dist));
    },
    image2Webp: () => {
        console.log('Begin ImageMin');
        async.parallel([
                function (callback) {
                    build.jpg2Webp().then(callback);
                },
                function (callback) {
                    build.png2Webp().then(callback);
                }
            ],
            // optional callback
            function (err, results) {
                // the results array will equal ['one','two'] even though
                // the second function had a shorter timeout.
                console.log('Done ImageMin');
            });
    },
    png2Webp: () => {
        return new Promise((resolve, reject) => {
            var srcArr = [path.resolve(CWD, '**/*.png'), '!**/node_modules/**/*'].concat(excludeArr);
            var dist = path.resolve(CWD, './');
            gulp.src(srcArr)
                .on('error', function (e) {
                    gutil.log(e);
                    reject(e)
                })
                .on('end', function () {
                    console.log('done: \t webp built');
                    resolve();
                })
                .pipe(webp())
                .pipe(rename(function (path) {
                    path.basename += ".png"
                }))
                .pipe(gulp.dest(dist));
        });
    },
    jpg2Webp: () => {
        return new Promise((resolve, reject) => {
            var srcArr = [path.resolve(CWD, '**/*.jpg'), '!**/node_modules/**/*'].concat(excludeArr);
            var dist = path.resolve(CWD, './');
            gulp.src(srcArr)
                .on('error', function (e) {
                    gutil.log(e);
                    reject(e)
                })
                .on('end', function () {
                    console.log('done: \t webp built');
                    resolve();
                })
                .pipe(webp())
                .pipe(rename(function (path) {
                    path.basename += ".jpg"
                }))
                .pipe(gulp.dest(dist));
        });
    },
    startServer: () => {
        bs.init({
            server: CWD,
            open: "external"
        });
    },
    typescript: () => {
        console.log('begin: \t typescript built');
        return new Promise((resolve, reject) => {
            var srcArr = [path.resolve(CWD, '**/*.ts'), '!**/node_modules/**/*', "!**/*.d.ts"].concat(excludeArr);
            var dist = path.resolve(CWD, './');
            gulp.src(srcArr)
                .pipe(ts({
                    noImplicitAny: true,
                    target: "es5",
                    declaration: true
                }, ts.reporter.longReporter(true)))
                .on('end', function () {
                    console.log('done: \t typescript built');
                    resolve();
                })
                .pipe(gulp.dest(dist));
        });
    },
    zip: () => {
        console.log('begin: \t zip built');
        return new Promise((resolve, reject) => {
            var srcArr = [path.resolve(CWD, '**/*'), '!**/node_modules/**/*', "!**/*.d.ts", "!**/*.scss", "!**/*.es6", "!**/*.less", "!**/*.pug"].concat(excludeArr);
            var dist = path.resolve(CWD, './../');
            gulp.src(srcArr)
                .pipe(zip(CWD_name + '.zip'))
                .on('error', function (e) {
                    gutil.log(e);
                    reject(e)
                })
                .on('end', function () {
                    console.log('done: \t zip built');
                    resolve();
                })
                .pipe(gulp.dest(dist));
        });
    }
};

gulp.task('sass:watch', function () {
    gulp.watch(['**/*.scss', '!**/node_modules/**/*'], {
        cwd: CWD
    }, () => {
        build.sass(() => {
            if (program.server) {
                bs.reload("*.css");
            }
        });
    });
});
gulp.task('less:watch', function () {
    gulp.watch(['**/*.less', '!**/node_modules/**/*'], {
        cwd: CWD
    }, () => {
        build.less(() => {
            if (program.server) {
                bs.reload("*.css");
            }
        })
    });
});
gulp.task('es6:watch', function () {
    gulp.watch(['**/*.es6', '!**/node_modules/**/*'], {
        cwd: CWD
    }, () => {
        build.es6(() => {
            if (program.server) {
                bs.reload("*.js");
            }
        })
    });
});
gulp.task('pug:watch', function () {
    gulp.watch(['**/*.pug', '!**/node_modules/**/*'], {
        cwd: CWD
    }, () => {
        build.pug(() => {
            if (program.server) {
                setTimeout(() => {
                    bs.reload();
                }, 100);

            }
        })
    });
});
gulp.task('markdown:watch', function () {
    gulp.watch(['**/*.md', '!**/node_modules/**/*'], {
        cwd: CWD
    }, build.markdown);
});

gulp.task('typescript:watch', function () {
    gulp.watch(['**/*.ts', '!**/node_modules/**/*'], {
        cwd: CWD
    }, build.typescript);
});

program
    .version('0.1.0')
    .usage('[options] <file ...>')
    .option('-p, --babelpolyfill', 'use babel-polyfill. Default: false')
    .option('-b, --build', 'build only')
    .option('--br, --browserify', 'browserify modules')
    .option('-w, --watch', 'watch mode')
    .option('-s, --sourcemap', 'write sourcemap')
    .option('-m, --minify', 'minify')
    .option('-x, --exclude <string>', 'exclude glob pattern. E.g. "**/*.min.js:**/*.min.css"')
    .option('--webp', 'generate webp')
    .option('--zip', 'zip project for release')
    .option('--server', 'start static server')
    .parse(process.argv);

if(program.zip) {
    build.zip();
}

if (program.webp) {
    build.image2Webp();
}

if (program.build) {
    build.sass();
    build.less();
    build.es6();
    build.pug();
    build.markdown();
    build.imageMin();
    build.typescript();
}

if(program.watch){
    gulp.start(["sass:watch", 'less:watch', 'es6:watch', 'pug:watch', 'markdown:watch', "typescript:watch"], function () {
        console.log('laziness is ready...');
    });
}

if (program.server) {
    build.startServer()
}<|endoftext|>


<commit_before>'use strict';

/*!
 * monic-loader
 * https://github.com/MonicBuilder/monic-loader
 *
 * Released under the MIT license
 * https://github.com/MonicBuilder/monic-loader/blob/master/LICENSE
 */

const
	$C = require('collection.js/compiled'),
	parent = module.parent;

const
	path = require('path'),
	loaderUtils = require('loader-utils'),
	monic = require('monic');

module.exports = function (source, inputSourceMap) {
	this.cacheable && this.cacheable();

	const
		optsIsObj = /^\?(?:\{|\[)/.test(this.query),
		cb = this.async();

	let
		opts = loaderUtils.parseQuery(this.query);

	opts = $C(opts).reduce((map, val, key) => {
		if ({flags: true, labels: true}[key] && !optsIsObj) {
			map[key] = $C(val.split('|')).reduce((map, el) => {
				if (key === 'labels') {
					map[el] = true;

				} else {
					el = el.split(':');
					map[el[0]] = el[1] || true;
				}

				return map;
			}, {});

		} else {
			map[key] = parse(val);
		}

		return map;
	}, {});

	opts = Object.assign({}, this.options.monic, opts, {
		inputSourceMap,
		sourceMaps: this.sourceMap,
		content: source,
		saveFiles: false
	});

	opts.replacers = opts.replacers || [];
	opts.replacers.push((content, file) => {
		this.addDependency(file);
		return content;
	});

	monic.compile(this.resourcePath, opts, (err, data, sourceMap) => {
		cb(err, data, sourceMap && sourceMap.map);
	});
};

function toJS(str) {
	return new Function(
		'module',
		'exports',
		'require',
		'__filename',
		'__dirname',
		`return ${str}`

	)(parent, parent.exports, parent.require, parent.filename, path.dirname(parent.filename));
}

function parse(val) {
	try {
		if (typeof val === 'object') {
			$C(val).set((el) => toJS(el));
		}

		return val;

	} catch (ignore) {
		return val;
	}
}
<commit_msg>:wrench:<commit_after>'use strict';

/*!
 * monic-loader
 * https://github.com/MonicBuilder/monic-loader
 *
 * Released under the MIT license
 * https://github.com/MonicBuilder/monic-loader/blob/master/LICENSE
 */

const
	$C = require('collection.js/compiled'),
	parent = module.parent;

const
	path = require('path'),
	loaderUtils = require('loader-utils'),
	monic = require('monic');

module.exports = function (source, inputSourceMap) {
	this.cacheable && this.cacheable();

	const
		optsIsObj = /^\?(?:\{|\[)/.test(this.query),
		cb = this.async();

	let
		opts = loaderUtils.parseQuery(this.query);

	opts = $C(opts).reduce((map, val, key) => {
		if ({flags: true, labels: true}[key] && !optsIsObj) {
			map[key] = $C(val.split('|')).reduce((map, el) => {
				if (key === 'labels') {
					map[el] = true;

				} else {
					el = el.split(':');
					map[el[0]] = el[1] || true;
				}

				return map;
			}, {});

		} else {
			map[key] = parse(val);
		}

		return map;
	}, {});

	opts = Object.assign({}, this.options.monic, opts, {
		inputSourceMap,
		sourceMaps: this.sourceMap,
		content: source,
		saveFiles: false
	});

	const files = {};
	opts.replacers = opts.replacers || [];
	opts.replacers.push((content, file) => {
		files[path.normalize(file)] = true;
		return content;
	});

	monic.compile(this.resourcePath, opts, (err, data, sourceMap) => {
		$C(files).forEach((el, file) => this.addDependency(file));
		cb(err, data, sourceMap && sourceMap.map);
	});
};

function toJS(str) {
	return new Function(
		'module',
		'exports',
		'require',
		'__filename',
		'__dirname',
		`return ${str}`

	)(parent, parent.exports, parent.require, parent.filename, path.dirname(parent.filename));
}

function parse(val) {
	try {
		if (typeof val === 'object') {
			$C(val).set((el) => toJS(el));
		}

		return val;

	} catch (ignore) {
		return val;
	}
}
<|endoftext|>


<commit_before>// gulpur - gulp with ES.next
// Copyright (c) 2014 Shinnosuke Watanabe
// https://github.com/shinnn/gulpur

'use strict';

var minimist = require('minimist');
var traceur = require('traceur');

var argv = minimist(process.argv, {
  'default': {
    gulpfile: 'gulpfile.js'
  }
});

traceur.require.makeDefault(function(path) {
  return path.endsWith(argv.gulpfile);
});

require('gulp/bin/gulp.js');
<commit_msg>add shebang<commit_after>#!/usr/bin/env node

// gulpur - gulp with ES.next
// Copyright (c) 2014 Shinnosuke Watanabe
// https://github.com/shinnn/gulpur

'use strict';

var minimist = require('minimist');
var traceur = require('traceur');

var argv = minimist(process.argv, {
  'default': {
    gulpfile: 'gulpfile.js'
  }
});

traceur.require.makeDefault(function(path) {
  return path.endsWith(argv.gulpfile);
});

require('gulp/bin/gulp.js');
<|endoftext|>


<commit_before>var _      = require('underscore'),
    ginga  = require('ginga'),
    queue  = require('queue-async'),
    params = ginga.params;

function Wait(parent){
  this._parent = parent;
  this._stack = [];
}
var W = Wait.prototype;
W.parent = function(){
  return this._parent;
};
W.add = function(fn){
  this._stack.push(fn);
  return this;
};
W.invoke = function(){
  _.invoke(this._stack, 'apply', null, arguments);
  this._stack = [];
  return this;
};
W.ended = function(){
  return this._stack.length === 0;
};

module.exports = function( db ){
  var count    = 0,
      queued   = {};

  function Transaction(){
    this.db = db;
    this._id = count;
    count++;

    this._q = queue();
    this.defer = this._q.defer.bind(this._q);

    this._wait = {};
    this._map = {};
    this._deps = {};
    this._batch = [];
  }

  //lock during get, put, del
  function lock(ctx, next){
    //check sublevel
    if(ctx.params.opts &&
      ctx.params.opts.prefix &&
      typeof ctx.params.opts.prefix.sublevel === 'function')
      ctx.prefix = ctx.params.opts.prefix;

    ctx.hash = JSON.stringify(ctx.params.key);
    //key + sublevel prefix hash
    if(ctx.prefix)
      ctx.hash = JSON.stringify([ctx.prefix.prefix(), ctx.params.key]);

    var wait = this._wait[ctx.hash];
    if(wait){
      if(wait.ended()){
        //skip if lock acquired
        next();
      }else{
        //not done waiting -> add to wait list
        wait.add(next);
      }
    }else{
      wait = new Wait(this).add(next);
      var i, j, l;

      if(queued[ctx.hash]){
        //check deadlock and push queue
        for(i = 0, l = queued[ctx.hash].length; i < l; i++){
          var tx = queued[ctx.hash][i].parent();
          if(tx._deps[this._id]){
            wait.invoke(new Error('Deadlock'));
            return;
          }
          this._deps[tx._id] = true;
          for(j in tx._deps)
            this._deps[j] = true;
        }
        queued[ctx.hash].push(wait);
      }else{
        //no queue in hash; lock immediately
        queued[ctx.hash] = [];
        wait.invoke();
      }
      this._wait[ctx.hash] = wait;
    }
  }

  function get(ctx, done){
    if(ctx.hash in this._map){
      done(null, this._map[ctx.hash]);
      return;
    }

    var self = this;
    var _db = db;
    if(ctx.prefix)
      _db = ctx.prefix;

    _db.get.apply(
      _db, [].concat(ctx.args, function(err, val){
        self._map[ctx.hash] = val;
        done(err, val);
      })
    );
  }

  function put(ctx, done){
    this._batch.push(_.extend({
      type: 'put',
      key: ctx.params.key,
      value: ctx.params.value
    }, ctx.params.opts));

    this._map[ctx.hash] = ctx.params.value;

    done(null);
  }

  function del(ctx, done){
    this._batch.push(_.extend({
      type: 'del',
      key: ctx.params.key
    }, ctx.params.opts));

    this._map[ctx.hash] = undefined;

    done(null);
  }

  function commit(ctx, next){
    var self = this;

    //defer waiting locks
    for(var hash in this._wait){
      var wait = this._wait[hash];
      var add = wait.add.bind(wait);
      if(!wait.ended())
        this._q.defer(add);
    }
    this._q.awaitAll(function(err){
      if(err)
        return next(err);
      db.batch(self._batch, function(err, res){
        if(err) next(err);
        else next();
      });
    });
  }

  //release after rollback, commit
  function release(ctx, done){
    var hash, wait;
    for(hash in this._wait){
      wait = this._wait[hash];
      if(wait.ended()){
        if(queued[hash].length > 0){
          queued[hash].shift().invoke();
        }else{
          delete queued[hash];
        }
      }else{
        //clean up waiting jobs
        var idx = queued[hash].indexOf(this._wait[hash]);
        if(idx > -1)
          queued[hash].splice(idx, 1);
      }
    }

    this._q = queue();
    this._wait = {};
    this._map = {};
    this._deps = {};
    this._batch = [];

    done(null);
  }

  ginga(Transaction.prototype)
    .define('get', params('key','opts?'), lock, get)
    .define('put', params('key','value','opts?'), lock, put)
    .define('del', params('key','opts?'), lock, del)
    .define('rollback', release)
    .define('commit', commit, release);

  db.transaction = db.transaction || function(){
    return new Transaction();
  };
  return db;
};
<commit_msg>Tweaks<commit_after>var _      = require('underscore'),
    ginga  = require('ginga'),
    queue  = require('queue-async'),
    params = ginga.params;

function Wait(parent){
  this._parent = parent;
  this._stack = [];
}
var W = Wait.prototype;
W.parent = function(){
  return this._parent;
};
W.add = function(fn){
  this._stack.push(fn);
  return this;
};
W.invoke = function(){
  _.invoke(this._stack, 'apply', null, arguments);
  this._stack = [];
  return this;
};
W.ended = function(){
  return this._stack.length === 0;
};

module.exports = function( db ){
  var count    = 0,
      queued   = {};

  function Transaction(){
    this.db = db;
    this._id = count;
    count++;

    this._q = queue();
    this.defer = this._q.defer.bind(this._q);

    this._wait = {};
    this._map = {};
    this._deps = {};
    this._batch = [];
  }

  //lock during get, put, del
  function lock(ctx, next){
    //check sublevel
    if(ctx.params.opts &&
      ctx.params.opts.prefix &&
      typeof ctx.params.opts.prefix.sublevel === 'function')
      ctx.prefix = ctx.params.opts.prefix;

    ctx.hash = JSON.stringify(ctx.params.key);
    //key + sublevel prefix hash
    if(ctx.prefix)
      ctx.hash = JSON.stringify([ctx.prefix.prefix(), ctx.params.key]);

    var wait = this._wait[ctx.hash];
    if(wait){
      if(wait.ended()){
        //skip if lock acquired
        next();
      }else{
        //not done waiting -> add to wait list
        wait.add(next);
      }
    }else{
      wait = new Wait(this).add(next);
      var i, j, l;

      if(queued[ctx.hash]){
        //check deadlock and push queue
        for(i = 0, l = queued[ctx.hash].length; i < l; i++){
          var tx = queued[ctx.hash][i].parent();
          if(tx._deps[this._id]){
            wait.invoke(new Error('Deadlock'));
            return;
          }
          this._deps[tx._id] = true;
          for(j in tx._deps)
            this._deps[j] = true;
        }
        queued[ctx.hash].push(wait);
      }else{
        //no queue in hash; lock immediately
        queued[ctx.hash] = [];
        wait.invoke();
      }
      this._wait[ctx.hash] = wait;
    }
  }

  function get(ctx, done){
    if(ctx.hash in this._map){
      done(null, this._map[ctx.hash]);
      return;
    }

    var self = this;
    var _db = db;
    if(ctx.prefix)
      _db = ctx.prefix;

    _db.get.apply(
      _db, [].concat(ctx.args, function(err, val){
        self._map[ctx.hash] = val;
        done(err, val);
      })
    );
  }

  function put(ctx, done){
    this._batch.push(_.extend({
      type: 'put',
      key: ctx.params.key,
      value: ctx.params.value
    }, ctx.params.opts));

    this._map[ctx.hash] = ctx.params.value;

    done(null);
  }

  function del(ctx, done){
    this._batch.push(_.extend({
      type: 'del',
      key: ctx.params.key
    }, ctx.params.opts));

    this._map[ctx.hash] = undefined;

    done(null);
  }

  function commit(ctx, next){
    var self = this;

    //defer waiting locks
    for(var hash in this._wait){
      var wait = this._wait[hash];
      var add = wait.add.bind(wait);
      if(!wait.ended())
        this._q.defer(add);
    }
    this._q.awaitAll(function(err){
      if(err)
        return next(err);
      db.batch(self._batch, function(err, res){
        if(err) next(err);
        else next();
      });
    });
  }

  //release after rollback, commit
  function release(ctx, done){
    var hash, wait;
    for(hash in this._wait){
      wait = this._wait[hash];
      if(wait.ended()){
        if(queued[hash].length > 0){
          queued[hash].shift().invoke();
        }else{
          delete queued[hash];
        }
      }else{
        //clean up waiting jobs
        var idx = queued[hash].indexOf(this._wait[hash]);
        if(idx > -1)
          queued[hash].splice(idx, 1);
      }
      delete this._wait[hash];
    }

    done(null);
  }

  ginga(Transaction.prototype)
    .define('get', params('key','opts?'), lock, get)
    .define('put', params('key','value','opts?'), lock, put)
    .define('del', params('key','opts?'), lock, del)
    .define('rollback', release)
    .define('commit', commit, release);

  db.transaction = db.transaction || function(){
    return new Transaction();
  };
  return db;
};
<|endoftext|>


<commit_before>(function() {
window.Domt = Domt;

Domt.Error = DomtError;
Domt.ns = {
	repeat: 'repeat',
	bind: 'bind',
	holder: 'holder',
	expr: '[*]'
};

Domt.filters = {
	upper: function(val) {
		return (val + "").toUpperCase();
	},
	lower: function(val) {
		return (val + "").toLowerCase();
	},
	br: function(val) {
		return (val + "").replace(/\n/g, "
");
	},
	esc: function(val) {
		return encodeURIComponent(val + "");
	}
};

function Holder(node) {
	if (!(this instanceof Holder)) return new Holder(node);
	var container, REPEAT = Domt.ns.repeat;
	if (node.tagName == "SCRIPT" && node.type == "text/template") {
		container = node;
		var origHolder = node[Domt.ns.holder];
		if (origHolder) {
			this.repeat = origHolder.repeat;
			this.template = origHolder.template;
		} else {
			this.repeat = container.getAttribute(REPEAT);
			var doc = document.implementation.createHTMLDocument();
			var div = doc.createElement('div');
			div.innerHTML = container.text.replace(/^\s+|\s+$/g, '');
			var childs = div.childNodes;
			if (childs.length == 1) {
				this.template = childs[0];
			}	else {
				throw new DomtError("template with children 1 != " + childs.length);
			}
		}
		container.removeAttribute(REPEAT);
	} else {
		this.template = node;
		container = document.createElement("script");
		container.type = "text/template";
		this.repeat = node.getAttribute(REPEAT);
		node.removeAttribute(REPEAT);
		node.parentNode.insertBefore(container, node);
		var div = document.createElement("div");
		div.appendChild(node);
		container.text = div.innerHTML;
	}
	this.container = container;
	container[Domt.ns.holder] = this;
	return this;
};
Holder.prototype.close = function() {
	var node = this.container;
	if (this.repeat !== undefined) {
		node.setAttribute(Domt.ns.repeat, this.repeat);
	}
};

function iterate(obj, fun) {
	if (obj == null) return;
	if (Object.prototype.toString.call(obj) === '[object Array]') {
		for (var i=0, len=obj.length; i < len; i++) fun(i, obj[i]);
	} else if (obj.length !== undefined && typeof obj.item == "function") {
		obj = Array.prototype.slice.call(obj, 0);
		for (var i=0, len=obj.length; i < len; i++) fun(i, obj[i]);
	} else if (obj instanceof Object) {
		var keys = obj.keys();
		for (var i=0, len=keys.length; i < len; i++) fun(keys[i], obj[keys[i]]);
	}
};

function Domt(parent) {
	if (!(this instanceof Domt)) return new Domt(parent);
	if (!parent) throw new DomtError("missing parent");
	if (typeof parent == "string") {
		parent = document.querySelector(parent);
	}
	this.parent = parent;

	this.reBind = new RegExp("^" + Domt.ns.bind + "-(.*)$", "i");

	var delims = Domt.ns.expr.split('*');
	if (delims.length != 2) throw new DomtError("bad Domt.ns.expr");
	var start = '\\' + delims[0], end = '\\' + delims[1];
	this.reExpr = new RegExp(start + '([^' + start + end + ']+)' + end, "g");
};

Domt.prototype.merge = function(obj, opts) {
	var node, current, holder, container, path, i, len,
		parent = this.parent;
	opts = opts || {};
	if (!opts.norepeat) {
		// repeat
		var REPEAT = '[' + Domt.ns.repeat + ']';
		if (parent.hasAttribute(Domt.ns.repeat)) node = parent;
		var holders = [];
		do {
			if (!node) continue;
			holder = Holder(node);
			holders.push(holder);
			container = holder.container;
			path = holder.repeat;
			// get data
			current = find(obj, path);
			if (current.value === undefined) {
				// nothing to repeat, merge and restore repeat
				Domt(holder.template).merge(obj, {norepeat: true});
			} else iterate(current.value, function(key, val) {
				var clone = holder.template.cloneNode();
				Domt(clone).merge(val, {strip: true});
				container.parentNode.insertBefore(clone, container);
			});
		} while ((node = parent.querySelector(REPEAT)));

		len = holders.length;
		for (i=0; i < len; i++) {
			holders[i].close();
		}
	}

	var binds = parent.querySelectorAll('[' + Domt.ns.bind + ']');
	node = parent;
	i = 0;
	len = binds.length;
	var val, reExpr = this.reExpr, reBind = this.reBind;
	do {
		path = node.getAttribute(Domt.ns.bind);
		current = find(obj, path);
		if (current.value === undefined) continue;
		iterate(node.attributes, function(i, att) { // iterates over a copy
			var match = reBind.exec(att.name);
			if (!match || match.length != 2) return;
			if (opts.strip) node.removeAttribute(att.name);
			var name = match[1];
			if (!att.value) {
				if (name == "text") val = node.innerText;
				else if (name == "html") val = node.innerHTML;
				else val = node.getAttribute(name);
				val = val.replace(reExpr, function(str, path) {
					return find(current.value, path).value;
				});
			} else {
				val = find(current.value, att.value).value;
			}
			replace(node, name, val);
		});
	} while (i < len && (node = binds.item(i++)));
	return this;
};

function replace(node, name, val) {
	if (val === undefined) return;
	if (name == "text") node.innerText = val;
	else if (name == "html") node.innerHTML = val;
	else if (val !== null) node.setAttribute(name, val);
	else node.removeAttribute(name);
}

function find(scope, path) {
	if (!scope) return {scope: scope};
	var name, val = scope, filters, filter;
	path = (path || "").split('|');
	filters = path;
	path = path.shift();
	path = path ? path.split('.') : [];
	if (typeof val == "function") val = val(scope, path);
	while ((name = path.shift()) !== undefined) {
		scope = val;
		val = scope[name];
		if (typeof val == "function") val = val(scope, path);
		if (!val) break;
	}
	if (val != null) {
		for (var i=0; i < filters.length; i++) {
			filter = Domt.filters[filters[i]];
			if (filter) val = filter(val);
		}
	}
	return {
		scope: scope,
		value: val
	};
};

function DomtError(message) {
  this.name = arguments.callee.name;
  this.message = message;
}
DomtError.prototype = new Error();
DomtError.prototype.constructor = DomtError;

})();
<commit_msg>Idempotent merges<commit_after>(function() {
window.Domt = Domt;

Domt.Error = DomtError;
Domt.ns = {
	repeat: 'repeat',
	bind: 'bind',
	holder: 'holder',
	expr: '[*]'
};

Domt.filters = {
	upper: function(val) {
		return (val + "").toUpperCase();
	},
	lower: function(val) {
		return (val + "").toLowerCase();
	},
	br: function(val) {
		return (val + "").replace(/\n/g, "
");
	},
	esc: function(val) {
		return encodeURIComponent(val + "");
	}
};

function Holder(node) {
	if (!(this instanceof Holder)) return new Holder(node);
	var container, REPEAT = Domt.ns.repeat;
	if (node.tagName == "SCRIPT" && node.type == "text/template") {
		container = node;
		var origHolder = node[Domt.ns.holder];
		if (origHolder) {
			this.repeat = origHolder.repeat;
			this.template = origHolder.template;
		} else {
			this.repeat = container.getAttribute(REPEAT);
			var doc = document.implementation.createHTMLDocument();
			var div = doc.createElement('div');
			div.innerHTML = container.text.replace(/^\s+|\s+$/g, '');
			var childs = div.childNodes;
			if (childs.length == 1) {
				this.template = childs[0];
			}	else {
				throw new DomtError("template with children 1 != " + childs.length);
			}
		}
		container.removeAttribute(REPEAT);
	} else {
		this.template = node;
		container = document.createElement("script");
		container.type = "text/template";
		this.repeat = node.getAttribute(REPEAT);
		node.removeAttribute(REPEAT);
		node.parentNode.insertBefore(container, node);
		var div = document.createElement("div");
		div.appendChild(node);
		container.text = div.innerHTML;
	}
	this.container = container;
	container[Domt.ns.holder] = this;
	return this;
};
Holder.prototype.close = function() {
	var node = this.container;
	if (this.repeat !== undefined) {
		node.setAttribute(Domt.ns.repeat, this.repeat);
	}
};

function iterate(obj, fun) {
	if (obj == null) return;
	if (Object.prototype.toString.call(obj) === '[object Array]') {
		for (var i=0, len=obj.length; i < len; i++) fun(i, obj[i]);
	} else if (obj.length !== undefined && typeof obj.item == "function") {
		obj = Array.prototype.slice.call(obj, 0);
		for (var i=0, len=obj.length; i < len; i++) fun(i, obj[i]);
	} else if (obj instanceof Object) {
		var keys = obj.keys();
		for (var i=0, len=keys.length; i < len; i++) fun(keys[i], obj[keys[i]]);
	}
};

function Domt(parent) {
	if (!(this instanceof Domt)) return new Domt(parent);
	if (!parent) throw new DomtError("missing parent");
	if (typeof parent == "string") {
		parent = document.querySelector(parent);
	}
	this.parent = parent;

	this.reBind = new RegExp("^" + Domt.ns.bind + "-(.*)$", "i");

	var delims = Domt.ns.expr.split('*');
	if (delims.length != 2) throw new DomtError("bad Domt.ns.expr");
	var start = '\\' + delims[0], end = '\\' + delims[1];
	this.reExpr = new RegExp(start + '([^' + start + end + ']+)' + end, "g");
};

Domt.prototype.merge = function(obj, opts) {
	var node, current, holder, container, path, i, len,
		parent = this.parent;
	opts = opts || {};
	if (!opts.norepeat) {
		// repeat
		var REPEAT = '[' + Domt.ns.repeat + ']';
		if (parent.hasAttribute(Domt.ns.repeat)) node = parent;
		var holders = [];
		do {
			if (!node) continue;
			holder = Holder(node);
			holders.push(holder);
			container = holder.container;
			path = holder.repeat;
			// get data
			current = find(obj, path);
			if (current.value === undefined) {
				// nothing to repeat, merge and restore repeat
				Domt(holder.template).merge(obj, {norepeat: true});
			} else iterate(current.value, function(key, val) {
				var clone = holder.template.cloneNode();
				Domt(clone).merge(val, {strip: true});
				container.parentNode.insertBefore(clone, container);
			});
		} while ((node = parent.querySelector(REPEAT)));

		len = holders.length;
		for (i=0; i < len; i++) {
			holders[i].close();
		}
	}

	var binds = parent.querySelectorAll('[' + Domt.ns.bind + ']');
	node = parent;
	i = 0;
	len = binds.length;
	var val, reExpr = this.reExpr, reBind = this.reBind;
	do {
		path = node.getAttribute(Domt.ns.bind);
		current = find(obj, path);
		if (current.value === undefined) continue;
		iterate(node.attributes, function(i, att) { // iterates over a copy
			var match = reBind.exec(att.name);
			if (!match || match.length != 2) return;
			if (opts.strip) node.removeAttribute(att.name);
			var name = match[1];
			if (name == "text") val = node.innerText;
			else if (name == "html") val = node.innerHTML;
			else val = node.getAttribute(name);
			var replacements = 0, initial = val;
			if (att.value) initial = att.value;
			val = initial.replace(reExpr, function(str, path) {
				replacements++;
				return find(current.value, path).value;
			});
			if (replacements) {
				if (!att.value) att.value = initial;
			} else {
				val = find(current.value, att.value).value;
			}
			replace(node, name, val);
		});
	} while (i < len && (node = binds.item(i++)));
	return this;
};

function replace(node, name, val) {
	if (val === undefined) return;
	if (name == "text") node.innerText = val;
	else if (name == "html") node.innerHTML = val;
	else if (val !== null) node.setAttribute(name, val);
	else node.removeAttribute(name);
}

function find(scope, path) {
	if (!scope) return {scope: scope};
	var name, val = scope, filters, filter;
	path = (path || "").split('|');
	filters = path;
	path = path.shift();
	path = path ? path.split('.') : [];
	if (typeof val == "function") val = val(scope, path);
	while ((name = path.shift()) !== undefined) {
		scope = val;
		val = scope[name];
		if (typeof val == "function") val = val(scope, path);
		if (!val) break;
	}
	if (val != null) {
		for (var i=0; i < filters.length; i++) {
			filter = Domt.filters[filters[i]];
			if (filter) val = filter(val);
		}
	}
	return {
		scope: scope,
		value: val
	};
};

function DomtError(message) {
  this.name = arguments.callee.name;
  this.message = message;
}
DomtError.prototype = new Error();
DomtError.prototype.constructor = DomtError;

})();
<|endoftext|>


<commit_before>var bodyParser = require('body-parser');
var config = require('./config');
var fs = require('fs');
var execSync = require('child_process').execSync;
var express = require('express');

var app = express();

var TOKEN = process.env.GITHUB_TOKEN;
var REPO = config.repo;

// Clone repository.
if (!fs.existsSync('aframe')) {
  console.log('Cloning A-Frame repository...');
  execSync(`git clone https://${TOKEN}@github.com/${REPO}.git`, {stdio:[0, 1, 2]});
}

// Git config.
// execSync('git config user.email aframebot@gmail.com');

// Set up Express.
app.set('port', (process.env.PORT || 5000));
app.use(bodyParser.json());
app.get('/', function (req, res) {
  res.send('AFRO');
})

// Webhook handler.
app.post('/postreceive', function (req, res) {
  var data = req.body;

  if (data.repository.full_name === 'aframevr/aframe') {
    bumpDist(data);
  }

  res.send(data);
})

// Express listen.
app.listen(app.get('port'), function () {
  console.log('Node app is running on port', app.get('port'));
})

// Bump A-Frame master build on every commit.
function bumpDist (data) {
  var hasCodeChanges = data.repository.head_commit.modified.filter(function (file) {
    return file.indexOf('src/' === 0) || file.indexOf('vendor/') === 0 ||
           file === 'package.json';
  }).length;

  if (!hasCodeChanges) { return; }

  execSync('git pull --rebase origin master', {cwd: 'aframe'});  // Rebase.
  execSync('npm install', {cwd: 'aframe'});  // Install.
  execSync('npm run dist', {cwd: 'aframe'});  // Bump.
  execSync('git commit -m "bump dist"', {cwd: 'aframe'});  // Commit.
  execSync(`git push https://${TOKEN}@github.com/${REPO}.git master`,
           {cwd: 'aframe'});  // Push.
}
<commit_msg>inherit stdio<commit_after>var bodyParser = require('body-parser');
var config = require('./config');
var fs = require('fs');
var execSync = require('child_process').execSync;
var express = require('express');

var app = express();

var TOKEN = process.env.GITHUB_TOKEN;
var REPO = config.repo;

// Clone repository.
if (!fs.existsSync('aframe')) {
  execSync(`git clone https://${TOKEN}@github.com/${REPO}.git`, {stdio: 'inherit'});
}

// Git config.
// execSync('git config user.email aframebot@gmail.com');

// Set up Express.
app.set('port', (process.env.PORT || 5000));
app.use(bodyParser.json());
app.get('/', function (req, res) {
  res.send('AFRO');
})

// Webhook handler.
app.post('/postreceive', function (req, res) {
  var data = req.body;

  if (data.repository.full_name === 'aframevr/aframe') {
    bumpDist(data);
  }

  res.send(data);
})

// Express listen.
app.listen(app.get('port'), function () {
  console.log('Node app is running on port', app.get('port'));
})

// Bump A-Frame master build on every commit.
function bumpDist (data) {
  var hasCodeChanges = data.repository.head_commit.modified.filter(function (file) {
    return file.indexOf('src/' === 0) || file.indexOf('vendor/') === 0 ||
           file === 'package.json';
  }).length;

  if (!hasCodeChanges) { return; }

  execSync('git pull --rebase origin master', {cwd: 'aframe'});  // Rebase.
  execSync('npm install', {cwd: 'aframe'});  // Install.
  execSync('npm run dist', {cwd: 'aframe'});  // Bump.
  execSync('git commit -m "bump dist"', {cwd: 'aframe'});  // Commit.
  execSync(`git push https://${TOKEN}@github.com/${REPO}.git master`,
           {cwd: 'aframe'});  // Push.
}
<|endoftext|>