<commit_before>var express = require('express');
var app     = express();
var pak     = require('./package.json');
var Client  = require('node-rest-client').Client;
var client  = new Client();
var year    = new Date().getFullYear();
var envic   = require('envic')

var shortIt = {
	company:    process.env.COMPANY       || process.env.NAME || process.env.APPNAME || pak.name,
	domain:     process.env.DOMAIN        || process.env.NAME || process.env.APPNAME || pak.name,
	name:       process.env.APPNAME       || pak.name,
	version:    process.env.APPVERSION    || pak.version,
	url:        process.env.URL           || 'https://github.com/yieme/shortit',
	year:       process.env.YEAR          || (year > 2015) ? '2015-' + year : year,
	logoUrl:    process.env.LOGO_URL      || 'logo.png',
	faviconUrl: process.env.FAVICON_URL   || 'favicon.png',
	nopowered:  process.env.NO_POWERED_BY || false,
	headCode:   process.env.HEADCODE      || '',
	bodyCode:   process.env.BODYCODE      || '',
	header1:    process.env.HEADERNAM     || false,
	value1:     process.env.HEADERVAL     || false,
	header2:    process.env.HEADERNAM2    || false,
	value2:     process.env.HEADERVAL2    || false,
	server:     process.env.SERVER        || false
};

shortIt.nameVersion = shortIt.name + '/' + shortIt.version
var conPassThru    = process.env.CONSOLE_PASSTHRU // console pass-thru
var logPassThru    = process.env.LOG_PASSTHRU
var passThruReturn = process.env.PASSTHRU_MESSAGE || '{ok:1}'
var passThruMaxLen = (process.env.PASSTHRU_MAXLEN) ? parseInt(process.env.PASSTHRU_MAXLEN) : 0 // maximum length of pass-thru string
var footerLinks = '';
var buttonLinks = '';
var shorts  = require('./shorts.json');
var fs      = require('fs')
var gaTxt   = fs.readFileSync('./templates/ga.js')
var gaid    = envic('GA Id')
if (gaid) {
	gaTxt = gaTxt.replace('$GAID', gaid)
}
console.log('gaid:', gaid)
var shortsDataUrl = process.env.DATA_URL;
app.set('port', (process.env.PORT || 5000));
var template      = '

$msg';
var home          = '$company uses the $domain domain as part of a service to protect users from harmful activity, to provide value for the developer ecosystem, and as a quality signal for surfacing interesting events.';
var msg404        = 'Sorry, page not found';
var lastUpdate    = 0;
var started       = +new Date();
var refreshWait   = 5000; // 5 seconds between refresh requests
var reloadFrequency = process.env.RELOAD || 24*60*60*1000; /// daily default
var stats         = {};
//var Logger        = require('le_node');
var winston    = require('winston')
var logentriesConfig = {
	token:      process.env.LOGENTRIES,
	bufferSize: process.env.LOGENTRIES_BUFFER || 100,
	secure:     1,
	'console':  1
};
var logger      = new winston.Logger()
logger.add(winston.transports.Console)
if (logentriesConfig.token) {
	console.log('Log transport: LogEntries')
	var Logentries = require('winston-logentries')
	logger.add(new winston.transports.Logentries(logentriesConfig))
}
var logUrl = envic('LOG_URL')
if (logUrl) {
	console.log('Log transport: Http', logUrl.host)
	logger.add( winston.transports.Http, logUrl )
}
var log = {
	info:    (logentriesConfig.token) ? function(m) { logger.log('info',    m)} : console.log,
	warning: (logentriesConfig.token) ? function(m) { logger.log('warning', m)} : console.warn,
	error:   (logentriesConfig.token) ? function(m) { logger.log('error',   m)} : console.error
}

var logFirebase = envic('LOG_FIREBASE')
var firelogRef
if (logFirebase) {
	console.log('Log transport: Http', logFirebase.url)
	var Firebase = require('firebase');
	var firelogRef = new Firebase(logFirebase.url);
	firelogRef.auth(logFirebase.token, function(error, result) {
	  if (error) {
	    console.log("Firebase Authentication Failed!", error);
			firelogRef = undefined
	  } else {
	    console.log("Firebase Authenticated successfully with payload:", result.auth);
	    console.log("Firebase Auth expires at:", new Date(result.expires * 1000));
	  }
	})
}

var favicon_png   = '';
var logo_png      = '';

app.use(function customHeaders( req, res, next ){
  // Switch off the default 'X-Powered-By: Express' header
	if (shortIt.nopowered) {
		app.disable( 'x-powered-by' );
	} else {
  	res.setHeader( 'X-Powered-By', shortIt.nameVersion);
	}
	if (shortIt.server)  res.setHeader('Server', shortIt.server)
	if (shortIt.header1) res.setHeader(shortIt.header1, shortIt.value1)
	if (shortIt.header2) res.setHeader(shortIt.header2, shortIt.value2)
  next()
})

function bump(area) {
	var now   = new Date();
	var year  = now.getFullYear();
	var month = now.getMonth() + 1;
	month     = (month<=9) ? '0' + month : ''+ month;
	var day   = now.getDate();
	day       = (day <= 9) ? '0' + day : '' + day;
	var stat  = stats[area] || {};
	stat.tdd = stat.tdd || 0;
	stat.tdd++;
	stat[year]     = stat[year]     || {};
	stat[year].ytd = stat[year].ytd || 0;
	stat[year].ytd++;
	stat[year][month]      = stat[year][month]      || {};
	stat[year][month].mtd  = stat[year][month].mtd  || 0;
	stat[year][month].mtd++;
	stat[year][month][day] = stat[year][month][day] || 0;
	stat[year][month][day]++;
	stats[area] = stat;
}

function duration(val) {
	val = Math.round(val / 1000);
	if (val <= 59) return val + 's';
	val = Math.round(val / 60);
	if (val <= 59) return val + 'm';
	val = Math.round(val / 60);
	if (val <= 23) return val + 'h';
	val = Math.round(val / 24);
	return val + 'd';
}

function getShorts() {
	var now       = +new Date();
	var timeDelta = now - lastUpdate;
	if (timeDelta > refreshWait) {
		lastUpdate  = now;
		if (shortsDataUrl) {
			client.get(shortsDataUrl, function(data, response){
				log.info(shortsDataUrl +   ' loaded at: ' + new Date().toString());
				var parsed = JSON.parse(data);
				shorts     = parsed;
			});
		} else {
			log.error('DATA_URL not defined');
		}
	}
}

function sendJson(res, obj) {
	res.type('json');
	obj = obj || {};
	var json = JSON.stringify(obj, null, 2);
	res.send(json);
}

function notFound(res, short) {
	bump('_404');
	log.warning('/' + short + ' Not Found');
	if (shorts._404) return doShort('_404', res);
	render(res, '_404', msg404.replace('$short', short));
	res.status(404);
}

function doShort(short, res) {
	var url   = shorts[short];
	if (url) {
		url = url.url || url; // support firebase short: { id: short, url: url } formatted data
		res.redirect(302, url);
		log.info(short + ': ' + url);
		bump(short);
	} else {
		notFound(res, short);
	}
}

function render(res, name, $msg) {
	var result = template.replace('$msg', $msg);
	for(var max=10; max>0 && result.indexOf('$') >= 0; max--) {
		result = result
			.replace('$company',     shortIt.company)
			.replace('$url',         shortIt.url)
			.replace('$domain',      shortIt.domain)
			.replace('$year',        shortIt.year)
			.replace('$logoUrl',     shortIt.logoUrl)
			.replace('$faviconUrl',  shortIt.faviconUrl)
			.replace('$packageName', shortIt.name)
			.replace('$packageVer',  shortIt.version)
			.replace('$headCode',    shortIt.headCode)
			.replace('$bodyCode',    shortIt.bodyCode)
			.replace('$buttonLinks', buttonLinks)
			.replace('$footerLinks', footerLinks)
		;
	}
	res.send(result);
	bump(name);
	log.info('/' + name);
}

function renderPng(res, name, img) {
	res.type('png');
	res.send(img);
	name = name + '.png';
	bump(name);
	log.info('/' + name);
}

app.get('/favicon.png', function (req, res) {
	renderPng(res, 'favicon', favicon);
});

app.get('/logo.png', function (req, res) {
	renderPng(res, 'logo', logo);
});

app.get('/', function (req, res) {
	if (shorts._home) return doShort('_home', res);
	render(res, '_home', process.env.MESSAGE || home);
});

app.get('/_reload', function (req, res) {
	render(res, '_reload', 'Reload done.');
	getShorts();
});

app.get('/_stats', function (req, res) {
	bump('_stats');
	stats._running = duration(+new Date() - started);
	stats._updated = duration(+new Date() - lastUpdate);
	sendJson(res, stats);
	log.info('/_stats ' + JSON.stringify(stats));
});

app.get('/_stats/:short', function (req, res) {
	bump('_stats/*');
	sendJson(res, stats[req.params.short]);
	log.info('/_stats/' + req.params.short);
});

String.prototype.replaceIgnoreCase = function(strReplace, strWith) {
    var reg = new RegExp(strReplace, 'i'); // i=ignore case, g=global (ie all)
    return this.replace(reg, strWith);
};

if (conPassThru) { // console pass-thru
	app.get(conPassThru, function (req, res) {
		data = req.originalUrl.replaceIgnoreCase(conPassThru, '')
		if (data.substr(0,1) == '/') data = data.replace('/', '')
		if (data.substr(0,1) == '?') data = data.replace('?', '')
		if (passThruMaxLen && data.length > passThruMaxLen) {
			data = data.substr(0, passThruMaxLen)
		}
		console.log('data', data);
		res.send(passThruReturn)
	});
}

if (logPassThru) {
	app.get(logPassThru, function (req, res) {
		data = req.originalUrl.replaceIgnoreCase(logPassThru, '')
		if (data.substr(0,1) == '/') data = data.replace('/', '')
		if (data.substr(0,1) == '?') data = data.replace('?', '')
		if (passThruMaxLen && data.length > passThruMaxLen) {
			data = data.substr(0, passThruMaxLen)
		}
		log.info(data);
		if (firelogRef) {
			firelogRef.push(data)
		}
		res.send(passThruReturn)
	});
}

app.get('/:short', function (req, res) {
	doShort(req.params.short, res);
});

var server = app.listen(app.get('port'), function () {
  var host = server.address().address;
  var port = server.address().port;
  log.info(pak.name + ' ' + pak.version + ' listening on: ' + host + ' port: ' + port + ' at: ' + new Date().toString());
	if (!process.env.COMPANY) {
		log.warning('COMPANY not defined');
	}
	if (!process.env.DOMAIN) {
		log.warning('DOMAIN not defined');
	}
	if (!process.env.URL) {
		log.warning('URL not defined');
	}
});

function loadFile(path, cb) {
	fs.readFile('./' + path, 'utf8', function (err, data) {
	  if (data && !err) {
			log.info('Loaded ' + path);
		} else {
			log.warning('Unable to load ' + path);
		}
		data = data.replace('$analytics', (gaid) ? gaTxt : '')
		cb(data);
	});
}

function loadTemplate(name, cb) {
	loadFile('./templates/' + name + '.html', cb);
}

function loadPng(path, cb) {
	fs.readFile('./' + path, function (err, data) {
	  if (data && !err) {
			log.info('Loaded ' + path);
		} else {
			log.warning('Unable to load ' + path);
		}
		cb(data);
	});
}

loadTemplate('index', function(data) {
	template = data || '';
});
loadTemplate('home', function(data) {
	home = data || '';
});
loadTemplate('404', function(data) {
	msg404 = data || '';
});
loadTemplate('footerLink', function(data) {
	data = data || '';
	for (var i=1; i<=9; i++) {
		if (process.env['FOOTER'+i]) {
			footerLinks += data
				.replace('$url',  process.env[ 'FOOTER_URL' + i ])
				.replace('$text', process.env[ 'FOOTER'     + i ])
			;
		}
	}
});
loadTemplate('buttonLink', function(data) {
	data = data || '';
	for (var i=1; i<=9; i++) {
		if (process.env['BUTTON'+i]) {
			buttonLinks += data
				.replace('$url',  process.env[ 'BUTTON_URL' + i ])
				.replace('$text', process.env[ 'BUTTON'     + i ])
			;
		}
	}
});
loadPng('favicon.png', function(data) {
	favicon = data || null;
});
loadPng('logo.png', function(data) {
	logo = data || null;
});

getShorts();
setInterval(getShorts, reloadFrequency);
<commit_msg>analytics fix<commit_after>var express = require('express');
var app     = express();
var pak     = require('./package.json');
var Client  = require('node-rest-client').Client;
var client  = new Client();
var year    = new Date().getFullYear();
var envic   = require('envic')

var shortIt = {
	company:    process.env.COMPANY       || process.env.NAME || process.env.APPNAME || pak.name,
	domain:     process.env.DOMAIN        || process.env.NAME || process.env.APPNAME || pak.name,
	name:       process.env.APPNAME       || pak.name,
	version:    process.env.APPVERSION    || pak.version,
	url:        process.env.URL           || 'https://github.com/yieme/shortit',
	year:       process.env.YEAR          || (year > 2015) ? '2015-' + year : year,
	logoUrl:    process.env.LOGO_URL      || 'logo.png',
	faviconUrl: process.env.FAVICON_URL   || 'favicon.png',
	nopowered:  process.env.NO_POWERED_BY || false,
	headCode:   process.env.HEADCODE      || '',
	bodyCode:   process.env.BODYCODE      || '',
	header1:    process.env.HEADERNAM     || false,
	value1:     process.env.HEADERVAL     || false,
	header2:    process.env.HEADERNAM2    || false,
	value2:     process.env.HEADERVAL2    || false,
	server:     process.env.SERVER        || false
};

shortIt.nameVersion = shortIt.name + '/' + shortIt.version
var conPassThru    = process.env.CONSOLE_PASSTHRU // console pass-thru
var logPassThru    = process.env.LOG_PASSTHRU
var passThruReturn = process.env.PASSTHRU_MESSAGE || '{ok:1}'
var passThruMaxLen = (process.env.PASSTHRU_MAXLEN) ? parseInt(process.env.PASSTHRU_MAXLEN) : 0 // maximum length of pass-thru string
var footerLinks = '';
var buttonLinks = '';
var shorts  = require('./shorts.json');
var fs      = require('fs')
var gaTxt   = fs.readFileSync('./templates/ga.js')
var gaid    = envic('GA Id')
if (gaid) {
	gaTxt = gaTxt.replace('$GAID', gaid)
}
console.log('gaid:', gaid,'-',process.env.GA_ID)
var shortsDataUrl = process.env.DATA_URL;
app.set('port', (process.env.PORT || 5000));
var template      = '

$msg';
var home          = '$company uses the $domain domain as part of a service to protect users from harmful activity, to provide value for the developer ecosystem, and as a quality signal for surfacing interesting events.';
var msg404        = 'Sorry, page not found';
var lastUpdate    = 0;
var started       = +new Date();
var refreshWait   = 5000; // 5 seconds between refresh requests
var reloadFrequency = process.env.RELOAD || 24*60*60*1000; /// daily default
var stats         = {};
//var Logger        = require('le_node');
var winston    = require('winston')
var logentriesConfig = {
	token:      process.env.LOGENTRIES,
	bufferSize: process.env.LOGENTRIES_BUFFER || 100,
	secure:     1,
	'console':  1
};
var logger      = new winston.Logger()
logger.add(winston.transports.Console)
if (logentriesConfig.token) {
	console.log('Log transport: LogEntries')
	var Logentries = require('winston-logentries')
	logger.add(new winston.transports.Logentries(logentriesConfig))
}
var logUrl = envic('LOG_URL')
if (logUrl) {
	console.log('Log transport: Http', logUrl.host)
	logger.add( winston.transports.Http, logUrl )
}
var log = {
	info:    (logentriesConfig.token) ? function(m) { logger.log('info',    m)} : console.log,
	warning: (logentriesConfig.token) ? function(m) { logger.log('warning', m)} : console.warn,
	error:   (logentriesConfig.token) ? function(m) { logger.log('error',   m)} : console.error
}

var logFirebase = envic('LOG_FIREBASE')
var firelogRef
if (logFirebase) {
	console.log('Log transport: Http', logFirebase.url)
	var Firebase = require('firebase');
	var firelogRef = new Firebase(logFirebase.url);
	firelogRef.auth(logFirebase.token, function(error, result) {
	  if (error) {
	    console.log("Firebase Authentication Failed!", error);
			firelogRef = undefined
	  } else {
	    console.log("Firebase Authenticated successfully with payload:", result.auth);
	    console.log("Firebase Auth expires at:", new Date(result.expires * 1000));
	  }
	})
}

var favicon_png   = '';
var logo_png      = '';

app.use(function customHeaders( req, res, next ){
  // Switch off the default 'X-Powered-By: Express' header
	if (shortIt.nopowered) {
		app.disable( 'x-powered-by' );
	} else {
  	res.setHeader( 'X-Powered-By', shortIt.nameVersion);
	}
	if (shortIt.server)  res.setHeader('Server', shortIt.server)
	if (shortIt.header1) res.setHeader(shortIt.header1, shortIt.value1)
	if (shortIt.header2) res.setHeader(shortIt.header2, shortIt.value2)
  next()
})

function bump(area) {
	var now   = new Date();
	var year  = now.getFullYear();
	var month = now.getMonth() + 1;
	month     = (month<=9) ? '0' + month : ''+ month;
	var day   = now.getDate();
	day       = (day <= 9) ? '0' + day : '' + day;
	var stat  = stats[area] || {};
	stat.tdd = stat.tdd || 0;
	stat.tdd++;
	stat[year]     = stat[year]     || {};
	stat[year].ytd = stat[year].ytd || 0;
	stat[year].ytd++;
	stat[year][month]      = stat[year][month]      || {};
	stat[year][month].mtd  = stat[year][month].mtd  || 0;
	stat[year][month].mtd++;
	stat[year][month][day] = stat[year][month][day] || 0;
	stat[year][month][day]++;
	stats[area] = stat;
}

function duration(val) {
	val = Math.round(val / 1000);
	if (val <= 59) return val + 's';
	val = Math.round(val / 60);
	if (val <= 59) return val + 'm';
	val = Math.round(val / 60);
	if (val <= 23) return val + 'h';
	val = Math.round(val / 24);
	return val + 'd';
}

function getShorts() {
	var now       = +new Date();
	var timeDelta = now - lastUpdate;
	if (timeDelta > refreshWait) {
		lastUpdate  = now;
		if (shortsDataUrl) {
			client.get(shortsDataUrl, function(data, response){
				log.info(shortsDataUrl +   ' loaded at: ' + new Date().toString());
				var parsed = JSON.parse(data);
				shorts     = parsed;
			});
		} else {
			log.error('DATA_URL not defined');
		}
	}
}

function sendJson(res, obj) {
	res.type('json');
	obj = obj || {};
	var json = JSON.stringify(obj, null, 2);
	res.send(json);
}

function notFound(res, short) {
	bump('_404');
	log.warning('/' + short + ' Not Found');
	if (shorts._404) return doShort('_404', res);
	render(res, '_404', msg404.replace('$short', short));
	res.status(404);
}

function doShort(short, res) {
	var url   = shorts[short];
	if (url) {
		url = url.url || url; // support firebase short: { id: short, url: url } formatted data
		res.redirect(302, url);
		log.info(short + ': ' + url);
		bump(short);
	} else {
		notFound(res, short);
	}
}

function render(res, name, $msg) {
	var result = template.replace('$msg', $msg);
	for(var max=10; max>0 && result.indexOf('$') >= 0; max--) {
		result = result
			.replace('$company',     shortIt.company)
			.replace('$url',         shortIt.url)
			.replace('$domain',      shortIt.domain)
			.replace('$year',        shortIt.year)
			.replace('$logoUrl',     shortIt.logoUrl)
			.replace('$faviconUrl',  shortIt.faviconUrl)
			.replace('$packageName', shortIt.name)
			.replace('$packageVer',  shortIt.version)
			.replace('$headCode',    shortIt.headCode)
			.replace('$bodyCode',    shortIt.bodyCode)
			.replace('$buttonLinks', buttonLinks)
			.replace('$footerLinks', footerLinks)
		;
	}
	res.send(result);
	bump(name);
	log.info('/' + name);
}

function renderPng(res, name, img) {
	res.type('png');
	res.send(img);
	name = name + '.png';
	bump(name);
	log.info('/' + name);
}

app.get('/favicon.png', function (req, res) {
	renderPng(res, 'favicon', favicon);
});

app.get('/logo.png', function (req, res) {
	renderPng(res, 'logo', logo);
});

app.get('/', function (req, res) {
	if (shorts._home) return doShort('_home', res);
	render(res, '_home', process.env.MESSAGE || home);
});

app.get('/_reload', function (req, res) {
	render(res, '_reload', 'Reload done.');
	getShorts();
});

app.get('/_stats', function (req, res) {
	bump('_stats');
	stats._running = duration(+new Date() - started);
	stats._updated = duration(+new Date() - lastUpdate);
	sendJson(res, stats);
	log.info('/_stats ' + JSON.stringify(stats));
});

app.get('/_stats/:short', function (req, res) {
	bump('_stats/*');
	sendJson(res, stats[req.params.short]);
	log.info('/_stats/' + req.params.short);
});

String.prototype.replaceIgnoreCase = function(strReplace, strWith) {
    var reg = new RegExp(strReplace, 'i'); // i=ignore case, g=global (ie all)
    return this.replace(reg, strWith);
};

if (conPassThru) { // console pass-thru
	app.get(conPassThru, function (req, res) {
		data = req.originalUrl.replaceIgnoreCase(conPassThru, '')
		if (data.substr(0,1) == '/') data = data.replace('/', '')
		if (data.substr(0,1) == '?') data = data.replace('?', '')
		if (passThruMaxLen && data.length > passThruMaxLen) {
			data = data.substr(0, passThruMaxLen)
		}
		console.log('data', data);
		res.send(passThruReturn)
	});
}

if (logPassThru) {
	app.get(logPassThru, function (req, res) {
		data = req.originalUrl.replaceIgnoreCase(logPassThru, '')
		if (data.substr(0,1) == '/') data = data.replace('/', '')
		if (data.substr(0,1) == '?') data = data.replace('?', '')
		if (passThruMaxLen && data.length > passThruMaxLen) {
			data = data.substr(0, passThruMaxLen)
		}
		log.info(data);
		if (firelogRef) {
			firelogRef.push(data)
		}
		res.send(passThruReturn)
	});
}

app.get('/:short', function (req, res) {
	doShort(req.params.short, res);
});

var server = app.listen(app.get('port'), function () {
  var host = server.address().address;
  var port = server.address().port;
  log.info(pak.name + ' ' + pak.version + ' listening on: ' + host + ' port: ' + port + ' at: ' + new Date().toString());
	if (!process.env.COMPANY) {
		log.warning('COMPANY not defined');
	}
	if (!process.env.DOMAIN) {
		log.warning('DOMAIN not defined');
	}
	if (!process.env.URL) {
		log.warning('URL not defined');
	}
});

function loadFile(path, cb) {
	fs.readFile('./' + path, 'utf8', function (err, data) {
	  if (data && !err) {
			log.info('Loaded ' + path);
		} else {
			log.warning('Unable to load ' + path);
		}
		data = data.replace('$analytics', (gaid) ? gaTxt : '')
		cb(data);
	});
}

function loadTemplate(name, cb) {
	loadFile('./templates/' + name + '.html', cb);
}

function loadPng(path, cb) {
	fs.readFile('./' + path, function (err, data) {
	  if (data && !err) {
			log.info('Loaded ' + path);
		} else {
			log.warning('Unable to load ' + path);
		}
		cb(data);
	});
}

loadTemplate('index', function(data) {
	template = data || '';
});
loadTemplate('home', function(data) {
	home = data || '';
});
loadTemplate('404', function(data) {
	msg404 = data || '';
});
loadTemplate('footerLink', function(data) {
	data = data || '';
	for (var i=1; i<=9; i++) {
		if (process.env['FOOTER'+i]) {
			footerLinks += data
				.replace('$url',  process.env[ 'FOOTER_URL' + i ])
				.replace('$text', process.env[ 'FOOTER'     + i ])
			;
		}
	}
});
loadTemplate('buttonLink', function(data) {
	data = data || '';
	for (var i=1; i<=9; i++) {
		if (process.env['BUTTON'+i]) {
			buttonLinks += data
				.replace('$url',  process.env[ 'BUTTON_URL' + i ])
				.replace('$text', process.env[ 'BUTTON'     + i ])
			;
		}
	}
});
loadPng('favicon.png', function(data) {
	favicon = data || null;
});
loadPng('logo.png', function(data) {
	logo = data || null;
});

getShorts();
setInterval(getShorts, reloadFrequency);
<|endoftext|>


<commit_before>var through = require('through2')

var destroyer = function(stream, stdout, stderr) {
  var destroyed = false
  return function(err) {
    if (destroyed) return
    destroyed = true

	if (err) stream.emit('error', err)

    stdout.emit('close')
    stderr.emit('close')
    stream.emit('close')
  }
}

var decode = function() {
  var stdout = through()
  var stderr = through()
  var buffer = through()

  var size = 0
  var header = null

  var flush = function(cb) {
    stdout.end(function() {
      stderr.end(cb)
    })
  }

  var transform = function(data, enc, cb) {
    buffer.write(data)

    while (true) {
      if (!header) {
        header = buffer.read(8)
        if (!header) return cb()

        if (header[0] === 1) next = stdout
        else next = stderr

        size = header.readUInt32BE(4)
      }

      var chunk = buffer.read(size)
      if (!chunk) return cb()

      header = null
      next.write(chunk)
    }

    next.write(cb)
  }

  var decoder = through(transform, flush)

  decoder.stdout = stdout
  decoder.stderr = stderr
  decoder.destroy = stdout.destroy = stderr.destroy = destroyer(decoder, stdout, stderr)

  return decoder
}

var encode = function(opts) {
  if (!opts) opts = {}
  var flushes = 0

  var flush = function(cb) {
    if (++flushes === 2 || !opts.halfOpen) return encoder.end(cb)
    cb()
  }

  var transformer = function(id) {
    return function(data, enc, cb) {
      var header = new Buffer([id,0,0,0,0,0,0,0])
      header.writeUInt32BE(data.length, 4)
      encoder.write(header)
      encoder.write(data, enc, cb)
    }
  }

  var encoder = through()
  var stdout = through(transformer(1), flush)
  var stderr = through(transformer(2), flush)

  encoder.stdout = stdout
  encoder.stderr = stderr
  encoder.destroy = stdout.destroy = stderr.destroy = destroyer(encoder, stdout, stderr)

  return encoder
}

module.exports = decode
module.exports.decode = decode
module.exports.encode = encode
<commit_msg>fix indent<commit_after>var through = require('through2')

var destroyer = function(stream, stdout, stderr) {
  var destroyed = false
  return function(err) {
    if (destroyed) return
    destroyed = true

    if (err) stream.emit('error', err)

    stdout.emit('close')
    stderr.emit('close')
    stream.emit('close')
  }
}

var decode = function() {
  var stdout = through()
  var stderr = through()
  var buffer = through()

  var size = 0
  var header = null

  var flush = function(cb) {
    stdout.end(function() {
      stderr.end(cb)
    })
  }

  var transform = function(data, enc, cb) {
    buffer.write(data)

    while (true) {
      if (!header) {
        header = buffer.read(8)
        if (!header) return cb()

        if (header[0] === 1) next = stdout
        else next = stderr

        size = header.readUInt32BE(4)
      }

      var chunk = buffer.read(size)
      if (!chunk) return cb()

      header = null
      next.write(chunk)
    }

    next.write(cb)
  }

  var decoder = through(transform, flush)

  decoder.stdout = stdout
  decoder.stderr = stderr
  decoder.destroy = stdout.destroy = stderr.destroy = destroyer(decoder, stdout, stderr)

  return decoder
}

var encode = function(opts) {
  if (!opts) opts = {}
  var flushes = 0

  var flush = function(cb) {
    if (++flushes === 2 || !opts.halfOpen) return encoder.end(cb)
    cb()
  }

  var transformer = function(id) {
    return function(data, enc, cb) {
      var header = new Buffer([id,0,0,0,0,0,0,0])
      header.writeUInt32BE(data.length, 4)
      encoder.write(header)
      encoder.write(data, enc, cb)
    }
  }

  var encoder = through()
  var stdout = through(transformer(1), flush)
  var stderr = through(transformer(2), flush)

  encoder.stdout = stdout
  encoder.stderr = stderr
  encoder.destroy = stdout.destroy = stderr.destroy = destroyer(encoder, stdout, stderr)

  return encoder
}

module.exports = decode
module.exports.decode = decode
module.exports.encode = encode
<|endoftext|>


<commit_before>var css = require('./css')
  , less = require('./less')
  , fs = require('fs')
  , path = require('path')
  , mkdirp = require('mkdirp')
  , writer = require('write-to-path')

module.exports = function (opts, cb) {
  if (typeof opts === 'string') opts = {entry: opts};
  if (typeof cb === 'string') opts.output = cb;

  if (opts.entry.substr(-4) === 'less') {
    less(opts, complete)
  } else {
    css(opts, complete)
  }

  function complete (err, src) {
    if (opts.transform && !err) src = opts.transform(src)

    if (opts.output) {
      // we definitely have to write the file
      var outputPath = path.resolve(process.cwd(), opts.output)
        , outputDir = path.dirname(outputPath)
        , writeFile = writer(outputPath, {debug: opts.debug})

      if (!fs.existsSync(outputDir)) mkdirp.sync(outputDir)

      // we might need to call a callback also
      if (typeof cb === 'function') {
        var _cb = cb
        cb = function (err, src) {
          writeFile(err, src)
          _cb(err, src)
        }
      } else {
        cb = writeFile
      }
    }

    cb(err, src)
  }
}
<commit_msg>Use rework-assets as a post-build step for LESS when needed<commit_after>var css = require('./css')
  , less = require('./less')
  , fs = require('fs')
  , path = require('path')
  , mkdirp = require('mkdirp')
  , writer = require('write-to-path')
  , rework = require('rework')
  , assets = require('rework-assets')
  , isLess

module.exports = function (opts, cb) {
  if (typeof opts === 'string') opts = {entry: opts};
  if (typeof cb === 'string') opts.output = cb;

  if (opts.entry.substr(-4) === 'less') {
    isLess = true
    less(opts, complete)
  } else {
    css(opts, complete)
  }

  function complete (err, src) {
    if (opts.transform && !err) src = opts.transform(src)

    if (isLess && opts.assets) {
      var resolvedPath = path.resolve(process.cwd(), opts.output)

      src = rework(src)
        .use(assets({
          src: path.dirname(resolvedPath)
          , dest: opts.assets.dest || ''
          , prefix: opts.assets.prefix || ''
        }))
        .toString({
          sourcemap: opts.debug || opts.sourcemap
          , compress: opts.compress
        })
    }

    if (opts.output) {
      // we definitely have to write the file
      var outputPath = path.resolve(process.cwd(), opts.output)
        , outputDir = path.dirname(outputPath)
        , writeFile = writer(outputPath, {debug: opts.debug})

      if (!fs.existsSync(outputDir)) mkdirp.sync(outputDir)

      // we might need to call a callback also
      if (typeof cb === 'function') {
        var _cb = cb
        cb = function (err, src) {
          writeFile(err, src)
          _cb(err, src)
        }
      } else {
        cb = writeFile
      }
    }

    cb(err, src)
  }
}
<|endoftext|>


<commit_before>var fs = require('fs')
var postcss = require('postcss')
var ejs = require('ejs')
var nano = require('cssnano')

var mdParse = require('./lib/md_parse')
var highlight = require('./lib/css_highlight')

module.exports = postcss.plugin('postcss-style-guide', function (processedCSS, options) {

    options = options || {}
    options.theme = options.theme !== undefined ? options.theme : 'default'
    options.name = options.name !== undefined ? options.name : 'Style Guide'
    options.file = options.file !== undefined ? options.file : 'styleguide'

    var themeName = 'psg-theme-' + options.theme
    var themePath
    if (options.theme === 'default') {
        themePath = __dirname + '/node_modules/' + themeName
    }
    else {
        themePath = 'node_modules/' + themeName
    }

    options.template = fs.readFileSync(themePath + '/template.ejs', 'utf-8').trim()
    options.style = fs.readFileSync(themePath + '/style.css', 'utf-8').trim()

    var maps = []
    return function (root) {
        var rootStyle = root.toString().trim()

        root.eachComment(function (comment) {
            if (comment.parent.type === 'root') {
                var rule = comment.next()
                var tmp = []
                while (rule !== null && (rule.type === 'rule' || rule.type === 'atrule')) {
                    tmp.push(rule.toString().trim())
                    rule = rule.next() || null
                }

                var tmplRule = tmp.join('\n')
                maps.push({
                    rule: highlight(tmplRule),
                    html: mdParse(comment.text)
                })
            }
        })

        generate(maps, processedCSS, rootStyle, options)

        return root
    }
})

function generate (maps, css, rootStyle, options) {
    var codeStyle = fs.readFileSync(__dirname + '/node_modules/highlight.js/styles/github.css', 'utf-8').trim()

    var assign = {
        projectName: options.name,
        processedCSS: nano(css),
        rootStyle: nano(rootStyle),
        tmplStyle: nano(options.style),
        codeStyle: nano(codeStyle),
        maps: maps
    }

    var html = ejs.render(options.template, assign)
    fs.writeFile(options.file + '.html', html, function (err) {
        if (err) {
            throw err
        }
        console.log('Successed to generate style guide')
    })
}
<commit_msg>successfully created style guide<commit_after>var fs = require('fs')
var postcss = require('postcss')
var ejs = require('ejs')
var nano = require('cssnano')

var mdParse = require('./lib/md_parse')
var highlight = require('./lib/css_highlight')

module.exports = postcss.plugin('postcss-style-guide', function (processedCSS, options) {

    options = options || {}
    options.theme = options.theme !== undefined ? options.theme : 'default'
    options.name = options.name !== undefined ? options.name : 'Style Guide'
    options.file = options.file !== undefined ? options.file : 'styleguide'

    var themeName = 'psg-theme-' + options.theme
    var themePath
    if (options.theme === 'default') {
        themePath = __dirname + '/node_modules/' + themeName
    }
    else {
        themePath = 'node_modules/' + themeName
    }

    options.template = fs.readFileSync(themePath + '/template.ejs', 'utf-8').trim()
    options.style = fs.readFileSync(themePath + '/style.css', 'utf-8').trim()

    var maps = []
    return function (root) {
        var rootStyle = root.toString().trim()

        root.eachComment(function (comment) {
            if (comment.parent.type === 'root') {
                var rule = comment.next()
                var tmp = []
                while (rule !== null && (rule.type === 'rule' || rule.type === 'atrule')) {
                    tmp.push(rule.toString().trim())
                    rule = rule.next() || null
                }

                var tmplRule = tmp.join('\n')
                maps.push({
                    rule: highlight(tmplRule),
                    html: mdParse(comment.text)
                })
            }
        })

        generate(maps, processedCSS, rootStyle, options)

        return root
    }
})

function generate (maps, css, rootStyle, options) {
    var codeStyle = fs.readFileSync(__dirname + '/node_modules/highlight.js/styles/github.css', 'utf-8').trim()

    var assign = {
        projectName: options.name,
        processedCSS: nano(css),
        rootStyle: nano(rootStyle),
        tmplStyle: nano(options.style),
        codeStyle: nano(codeStyle),
        maps: maps
    }

    var html = ejs.render(options.template, assign)
    fs.writeFile(options.file + '.html', html, function (err) {
        if (err) {
            throw err
        }
        console.log('Successfully created style guide!')
    })
}
<|endoftext|>


<commit_before>require('dotenv').config();

const path = require('path');
const express = require('express');
const axios = require('axios');
const serveStatic = require('serve-static');
const PORT = process.env.PORT || 3000;

const app = express();

// Define routes
app.use(require('./routes'));
// Define path or admin page
app.use(serveStatic(path.join(__dirname, 'public'), {
  maxAge: '1d',
  setHeaders: setCustomCacheControl
}));

function setCustomCacheControl (res, path) {
  if (serveStatic.mime.lookup(path) === 'text/html') {
    // Custom Cache-Control for HTML files
    res.setHeader('Cache-Control', 'public, max-age=0')
  }
}
//app.use('/', express.static('./public'));
// Set rendering mechanism. Though not used anywhere for now
app.set('views', './views');
app.set('view engine', 'pug');

const server = app.listen(PORT, function () {
    console.log('Server is running on http://localhost:' + PORT);
});

<commit_msg>Disable etag<commit_after>require('dotenv').config();

const path = require('path');
const express = require('express');
const axios = require('axios');
const serveStatic = require('serve-static');
const PORT = process.env.PORT || 3000;

const app = express();

// Define routes
app.use(require('./routes'));
// Define path or admin page
app.use(serveStatic(path.join(__dirname, 'public'), {
  maxAge: '1d',
  setHeaders: setCustomCacheControl,
  etag: false
}));

function setCustomCacheControl (res, path) {
  if (serveStatic.mime.lookup(path) === 'text/html') {
    // Custom Cache-Control for HTML files
    res.setHeader('Cache-Control', 'public, max-age=0')
  }
}
//app.use('/', express.static('./public'));
// Set rendering mechanism. Though not used anywhere for now
app.set('views', './views');
app.set('view engine', 'pug');

const server = app.listen(PORT, function () {
    console.log('Server is running on http://localhost:' + PORT);
});

<|endoftext|>


<commit_before>'use strict';

var contpara  = require('continuable-para')
var pull      = require('pull-stream')
var pl        = require('pull-level')
var paramap   = require('pull-paramap')
var replicate = require('./replicate')
var timestamp = require('monotonic-timestamp')
var Feed      = require('./feed')
var assert    = require('assert')
var msgpack   = require('msgpack-js')

//this makes msgpack a valid level codec.
msgpack.buffer = true

//var u         = require('./util')

//53 bit integer
var MAX_INT  = 0x1fffffffffffff

function isString (s) {
  return 'string' === typeof s
}

function isFunction (f) {
  return 'function' === typeof f
}

var isBuffer = Buffer.isBuffer
var isArray = Array.isArray
function isObject (o) { return o && 'object' === typeof o }

function traverse (obj, each) {
  if(Buffer.isBuffer(obj) || !isObject(obj)) return
  if(!isArray(obj)) each(obj)
  for(var k in obj) {
    if(isObject(obj[k])) traverse(obj[k], each)
  }
}

function indexLinks (msg, each) {
  traverse(msg, function (obj) {
    if(obj.$rel && (obj.$msg || obj.$ext || obj.$feed)) each(obj)
  })
}

module.exports = function (db, opts) {

  var logDB   = db.sublevel('log')
  var feedDB  = db.sublevel('fd')
  var clockDB = db.sublevel('clk')
  var lastDB  = db.sublevel('lst')
  var indexDB = db.sublevel('idx', {valueEncoding: msgpack})
  var appsDB  = db.sublevel('app')

  function get (db, key) {
    return function (cb) { db.get(encode(key), cb) }
  }

  db.opts = opts

  var isHash = opts.isHash

  var validation = require('./validation')(db, opts)

  db.pre(function (op, add, _batch) {
    var msg = op.value
    var id = op.key
    // index by sequence number
    add({
      key: [msg.author, msg.sequence], value: id,
      type: 'put', prefix: clockDB
    })

    // index my timestamp, used to generate feed.
    add({
      key: [msg.timestamp, msg.author], value: id,
      type: 'put', prefix: feedDB
    })

    // index the latest message from each author
    add({
      key: msg.author, value: msg.sequence,
      type: 'put', prefix: lastDB
    })

    // index messages in the order _received_
    // this will be used to pass to plugins which
    // must create their indexes asyncly.
    add({
      key: timestamp(), value: id,
      type: 'put', prefix: logDB
    })

    add({
      key: ['type', msg.value.type.toString().substring(0, 32), msg.timestamp],
      value: id, type: 'put', prefix: indexDB
    })

    indexLinks(msg.value, function (link) {

      if(isHash(link.$feed)) {
        add({
          key: ['feed', msg.author, link.$rel, link.$feed, msg.sequence, id],
          value: link,
          type: 'put', prefix: indexDB
        })
        add({
          key: ['_feed', link.$feed, link.$rel, msg.author, msg.sequence, id],
          value: link,
          type: 'put', prefix: indexDB
        })
      }

      if(isHash(link.$msg)) {
        // do not need forward index here, because
        // it's cheap to just read the message.

        add({
          key: ['_msg', link.$msg, link.$rel, id], value: link,
          type: 'put', prefix: indexDB
        })
      }

      //TODO, add $ext links

    })

  })

  db.getPublicKey = function (id, cb) {
    function cont (cb) {
      clockDB.get([id, 1], function (err, hash) {
      if(err) return cb(err)
        db.get(hash, function (err, msg) {
          if(err) return cb(err)
          cb(null, msg.value.public)
        })
      })
    }
    return cb ? cont(cb) : cont
  }

  //msg must be an already valid message, with signature.
  //since creating this involves some state (it must increment
  //the sequence and point to the previous message)
  //it's recommended to append messages via a Feed object
  //which will manage that for you. (see feed.js)

  db.add = function (msg, cb) {
    //check that msg is valid (follows from end of database)
    //then insert into database.
    var n = 1
    validation.validate(msg, function (err, msg, hash) {
      if(--n) throw new Error('called twice')
      cb && cb(err, msg, hash)
    })
  }

  db.createFeedStream = function (opts) {
    opts = opts || {}
    opts.keys = false
    return pull(
      pl.read(feedDB, opts),
      paramap(function (key, cb) {
        db.get(key, cb)
      })
    )
  }

  db.latest = function (opts) {
    return pull(
      pl.read(lastDB),
      pull.map(function (data) {
        var d = {id: data.key, sequence: data.value}
        return d
      })
    )
  }

  db.createHistoryStream = function (id, seq, live) {
    if(!Buffer.isBuffer(id)) {
      live = !!id.live
      seq = id.seq
      id = id.id
    }
    return pull(
      pl.read(clockDB, {
        gte:  [id, seq],
        lte:  [id, MAX_INT],
        tail: live, live: live,
        keys: false
      }),
      paramap(function (key, cb) {
        db.get(key, cb)
      })
    )
  }

  //writeStream - used in replication.
  db.createWriteStream = function (cb) {
    return pull(
      paramap(function (data, cb) {
        db.add(data, cb)
      }),
      pull.drain(null, cb)
    )
  }

  db.createReplicationStream = function (opts, cb) {
    if(!cb) cb = opts, opts = {}
    return replicate(db, opts, cb || function (err) {
      if(err) throw err
    })
  }

  db.createFeed = function (keys) {
    if(!keys)
      keys = opts.keys.generate()
    return Feed(db, keys, opts)
  }

  db.createLatestLookupStream = function () {
    return paramap(function (id, cb) {
      return lastDB.get(id, function (err, seq) {
        cb(null, {id: id, sequence: err ? 0 : seq})
      })
    })
  }

  db.getLatest = function (id, cb) {
    lastDB.get(id, function (err, v) {
      if(err) return cb(err)
      clockDB.get([id, v], function (err, hash) {
        if(err) return cb(err)
        db.get(hash, cb)
      })
    })
  }

  db.createLogStream = function (opts) {
    opts = opts || {}
    var _opts = {
      gt : opts.gt || 0, tail: opts.tail || false
    }
    return pull(
      pl.read(logDB, _opts),
      paramap(function (data, cb) {
        var key = data.value
        var seq = data.key
        db.get(key, function (err, value) {
          cb(err, {key: key, value: value, timestamp: seq})
        })
      })
    )
  }

  var HI = undefined, LO = null

  db.messagesByType = function (type) {
    return pull(
      pl.read(indexDB, {
        gte: ['type', type, LO, LO],
        lte: ['type', type, HI, HI],
        keys: false
      }),
      paramap(function (id, cb) {
        db.get(id, function (err, msg) {
          cb(null, msg)
        })
      }),
      pull.filter()
    )
  }

  function idOpts (fn) {
    return function (opts, rel) {
      if(!opts) throw new Error('must have opts')
      //legacy interface.
      if(Buffer.isBuffer(opts))
        return fn(opts, rel)

      return fn(opts.id, opts.rel)
    }
  }

  db.messagesLinkedToMessage = idOpts(function (hash, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['_msg', hash, rel || LO, LO],
        lte: ['_msg', hash, rel || LO, HI],
      }),
      paramap(function (op, cb) {
        if(!op.key[3]) return cb()
        db.get(op.key[3], function (err, msg) {
          cb(null, msg)
        })
      }),
      pull.filter(Boolean)
    )
  })

  db.messagesLinkedToFeed =
  db.feedsLinkedToFeed = idOpts(function (id, rel) {

    return pull(
      pl.read(indexDB, {
        gte: ['_feed', id, rel || LO, LO],
        lte: ['_feed', id, rel || HI, HI]
      }),
      pull.map(function (op) {
        return {
          source: op.key[3], dest: op.key[1],
          rel: op.key[2], message: op.key[5]
        }
      })
    )
  })

  db.messagesLinkedFromFeed =
  db.feedsLinkedFromFeed = idOpts(function (id, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['feed', id, rel || LO, LO],
        lte: ['feed', id, rel || HI, HI]
      }),
      pull.map(function (op) {
        return {
          source: op.key[1], dest: op.key[3],
          rel: op.key[2], message: op.key[5]
        }
      })
    )
  })

  return db
}
<commit_msg>index messages by insert time<commit_after>'use strict';

var contpara  = require('continuable-para')
var pull      = require('pull-stream')
var pl        = require('pull-level')
var paramap   = require('pull-paramap')
var replicate = require('./replicate')
var timestamp = require('monotonic-timestamp')
var Feed      = require('./feed')
var assert    = require('assert')
var msgpack   = require('msgpack-js')
var ltgt      = require('ltgt')

//this makes msgpack a valid level codec.
msgpack.buffer = true

//var u         = require('./util')

//53 bit integer
var MAX_INT  = 0x1fffffffffffff

function isString (s) {
  return 'string' === typeof s
}

function isFunction (f) {
  return 'function' === typeof f
}

var isBuffer = Buffer.isBuffer
var isArray = Array.isArray
function isObject (o) { return o && 'object' === typeof o }

function traverse (obj, each) {
  if(Buffer.isBuffer(obj) || !isObject(obj)) return
  if(!isArray(obj)) each(obj)
  for(var k in obj) {
    if(isObject(obj[k])) traverse(obj[k], each)
  }
}

function indexLinks (msg, each) {
  traverse(msg, function (obj) {
    if(obj.$rel && (obj.$msg || obj.$ext || obj.$feed)) each(obj)
  })
}

module.exports = function (db, opts) {

  var logDB   = db.sublevel('log')
  var feedDB  = db.sublevel('fd')
  var clockDB = db.sublevel('clk')
  var lastDB  = db.sublevel('lst')
  var indexDB = db.sublevel('idx', {valueEncoding: msgpack})
  var appsDB  = db.sublevel('app')

  function get (db, key) {
    return function (cb) { db.get(encode(key), cb) }
  }

  db.opts = opts

  var isHash = opts.isHash

  var validation = require('./validation')(db, opts)

  db.pre(function (op, add, _batch) {
    var msg = op.value
    var id = op.key
    // index by sequence number
    add({
      key: [msg.author, msg.sequence], value: id,
      type: 'put', prefix: clockDB
    })

    // index my timestamp, used to generate feed.
    add({
      key: [msg.timestamp, msg.author], value: id,
      type: 'put', prefix: feedDB
    })

    // index the latest message from each author
    add({
      key: msg.author, value: msg.sequence,
      type: 'put', prefix: lastDB
    })

    var localtime = timestamp()

    // index messages in the order _received_
    // this will be used to pass to plugins which
    // must create their indexes asyncly.
    add({
      key: localtime, value: id,
      type: 'put', prefix: logDB
    })

    add({
      key: ['type', msg.value.type.toString().substring(0, 32), localtime],
      value: id, type: 'put', prefix: indexDB
    })

    indexLinks(msg.value, function (link) {

      if(isHash(link.$feed)) {
        add({
          key: ['feed', msg.author, link.$rel, link.$feed, msg.sequence, id],
          value: link,
          type: 'put', prefix: indexDB
        })
        add({
          key: ['_feed', link.$feed, link.$rel, msg.author, msg.sequence, id],
          value: link,
          type: 'put', prefix: indexDB
        })
      }

      if(isHash(link.$msg)) {
        // do not need forward index here, because
        // it's cheap to just read the message.

        add({
          key: ['_msg', link.$msg, link.$rel, id], value: link,
          type: 'put', prefix: indexDB
        })
      }

      //TODO, add $ext links

    })

  })

  db.getPublicKey = function (id, cb) {
    function cont (cb) {
      clockDB.get([id, 1], function (err, hash) {
      if(err) return cb(err)
        db.get(hash, function (err, msg) {
          if(err) return cb(err)
          cb(null, msg.value.public)
        })
      })
    }
    return cb ? cont(cb) : cont
  }

  //msg must be an already valid message, with signature.
  //since creating this involves some state (it must increment
  //the sequence and point to the previous message)
  //it's recommended to append messages via a Feed object
  //which will manage that for you. (see feed.js)

  db.add = function (msg, cb) {
    //check that msg is valid (follows from end of database)
    //then insert into database.
    var n = 1
    validation.validate(msg, function (err, msg, hash) {
      if(--n) throw new Error('called twice')
      cb && cb(err, msg, hash)
    })
  }

  db.createFeedStream = function (opts) {
    opts = opts || {}
    opts.keys = false
    return pull(
      pl.read(feedDB, opts),
      paramap(function (key, cb) {
        db.get(key, cb)
      })
    )
  }

  db.latest = function (opts) {
    return pull(
      pl.read(lastDB),
      pull.map(function (data) {
        var d = {id: data.key, sequence: data.value}
        return d
      })
    )
  }

  db.createHistoryStream = function (id, seq, live) {
    if(!Buffer.isBuffer(id)) {
      live = !!id.live
      seq = id.seq
      id = id.id
    }
    return pull(
      pl.read(clockDB, {
        gte:  [id, seq],
        lte:  [id, MAX_INT],
        tail: live, live: live,
        keys: false
      }),
      paramap(function (key, cb) {
        db.get(key, cb)
      })
    )
  }

  //writeStream - used in replication.
  db.createWriteStream = function (cb) {
    return pull(
      paramap(function (data, cb) {
        db.add(data, cb)
      }),
      pull.drain(null, cb)
    )
  }

  db.createReplicationStream = function (opts, cb) {
    if(!cb) cb = opts, opts = {}
    return replicate(db, opts, cb || function (err) {
      if(err) throw err
    })
  }

  db.createFeed = function (keys) {
    if(!keys)
      keys = opts.keys.generate()
    return Feed(db, keys, opts)
  }

  db.createLatestLookupStream = function () {
    return paramap(function (id, cb) {
      return lastDB.get(id, function (err, seq) {
        cb(null, {id: id, sequence: err ? 0 : seq})
      })
    })
  }

  db.getLatest = function (id, cb) {
    lastDB.get(id, function (err, v) {
      if(err) return cb(err)
      clockDB.get([id, v], function (err, hash) {
        if(err) return cb(err)
        db.get(hash, cb)
      })
    })
  }

  db.createLogStream = function (opts) {
    opts = opts || {}
    var _opts = {
      gt : opts.gt || 0, tail: opts.tail || false
    }
    return pull(
      pl.read(logDB, _opts),
      paramap(function (data, cb) {
        var key = data.value
        var seq = data.key
        db.get(key, function (err, value) {
          cb(err, {key: key, value: value, timestamp: seq})
        })
      })
    )
  }

  var HI = undefined, LO = null

  db.messagesByType = function (opts) {
    if(!opts)
      throw new Error('must provide {type: string} to messagesByType')
    if(isString(opts))
      opts = {type: opts}

    ltgt.toLtgt(opts, opts, function (value) {
      return ['type', opts.type, value]
    }, LO, HI)
    //default keys to false
    var keys = opts.keys = opts.keys === true
    return pull(
      pl.read(indexDB, opts),
      paramap(function (data, cb) {
        var id = keys ? data.value : data
        db.get(id, function (err, msg) {
          cb(null, keys ? {key: id, ts: data.key[2], value: msg} : msg)
        })
      }),
      pull.filter()
    )
  }

  function idOpts (fn) {
    return function (opts, rel) {
      if(!opts) throw new Error('must have opts')
      //legacy interface.
      if(Buffer.isBuffer(opts))
        return fn(opts, rel)

      return fn(opts.id, opts.rel)
    }
  }

  db.messagesLinkedToMessage = idOpts(function (hash, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['_msg', hash, rel || LO, LO],
        lte: ['_msg', hash, rel || LO, HI],
      }),
      paramap(function (op, cb) {
        if(!op.key[3]) return cb()
        db.get(op.key[3], function (err, msg) {
          cb(null, msg)
        })
      }),
      pull.filter(Boolean)
    )
  })

  db.messagesLinkedToFeed =
  db.feedsLinkedToFeed = idOpts(function (id, rel) {

    return pull(
      pl.read(indexDB, {
        gte: ['_feed', id, rel || LO, LO],
        lte: ['_feed', id, rel || HI, HI]
      }),
      pull.map(function (op) {
        return {
          source: op.key[3], dest: op.key[1],
          rel: op.key[2], message: op.key[5]
        }
      })
    )
  })

  db.messagesLinkedFromFeed =
  db.feedsLinkedFromFeed = idOpts(function (id, rel) {
    return pull(
      pl.read(indexDB, {
        gte: ['feed', id, rel || LO, LO],
        lte: ['feed', id, rel || HI, HI]
      }),
      pull.map(function (op) {
        return {
          source: op.key[1], dest: op.key[3],
          rel: op.key[2], message: op.key[5]
        }
      })
    )
  })

  return db
}
<|endoftext|>


<commit_before>'use strict';

const globalModulesDir = require('global-modules');
const yarnGlobalModulesDir = require('yarn-global-modules')();
const addonPath = require.resolve('ember-cli/blueprints/addon/index', {
  paths: [ yarnGlobalModulesDir, globalModulesDir ]
});

const path = require('path');
const Addon = require(addonPath);
const stringUtil = require('ember-cli-string-utils');
const walkSync = require('walk-sync');
const existsSync = require('exists-sync');
const uniq = require('ember-cli-lodash-subset').uniq;
const sortPackageJson = require('sort-package-json');
const fs = require('fs-extra');

const stringifyAndNormalizePath = require.resolve('ember-cli/lib/utilities/stringify-and-normalize', {
  paths: [ yarnGlobalModulesDir, globalModulesDir ]
});
const stringifyAndNormalize = require(stringifyAndNormalizePath);

module.exports = Object.assign({}, Addon, {
  description: 'Creates a stand-alone Engine for Ember.js.',

  locals(options) {
    let superLocals = Addon.locals(...arguments);

    let engineName = options.entity.name;
    let engineModulePrefix = stringUtil.dasherize(engineName);

    return Object.assign(superLocals, {
      engineModulePrefix,
      isLazy: !!options.lazy,
      includeRoutesInApplication: !options.excludeRoutesFromApplication,
      welcome: false
    });
  },

  availableOptions: [
    {
      name: 'type',
      type: [ 'routable', 'routeless' ],
      default: 'routable',
      aliases: [
        { 'routable': 'routable' },
        { 'routeless': 'routeless' }
      ]
    },
    {
      name: 'lazy',
      type: Boolean,
      default: false,
      description: 'Whether this Engine should load lazily or not'
    },
    {
      name: 'exclude-routes-from-application',
      type: Boolean,
      description: 'Whether this Engine should exclude its routes from the applications vendor file or not'
    }
  ],

  install(options) {
    this.options = options;
    return this._super.install.apply(this, arguments);
  },

  uninstall(options) {
    this.options = options;
    return this._super.uninstall.apply(this, arguments);
  },

  filesPath() {
    let type = this._getEngineType();
    return path.join(this.path, "files", type + '-files');
  },

  files() {
    if (this._files) { return this._files; }

    this._appBlueprint = this.lookupBlueprint('app');
    let appFiles = this._appBlueprint.files();

    this._addonBlueprint = this.lookupBlueprint('addon');
    let addonFiles = this._addonBlueprint.files();

    let filesPath = this.filesPath(this.options);
    let engineFiles = [];
    if (existsSync(filesPath)) {
      engineFiles = walkSync(filesPath);
    }

    let files = uniq(appFiles.concat(addonFiles).concat(engineFiles));

    let addonGitKeep = files.indexOf('addon/.gitkeep');
    files.splice(addonGitKeep, 1);

    // Remove app/.gitkeep, engines don't need app directories
    let appGitKeep = files.indexOf('app/.gitkeep');
    files.splice(appGitKeep, 1);

    return this._files = files;
  },

  srcPath(file) {
    let type = this._getEngineType();
    let engineFilePath = path.join(this.path, "files", type + '-files', file);
    let addonFilePath = path.resolve(this._addonBlueprint.path, 'files', file);
    if (existsSync(engineFilePath)) {
      return engineFilePath;
    } else if (existsSync(addonFilePath)) {
      return addonFilePath;
    } else {
      return path.resolve(this._appBlueprint.path, 'files', file);
    }
  },

  updatePackageJson(contents) {
    contents = Addon.updatePackageJson.apply(this, arguments);
    contents = JSON.parse(contents)

    // Add `ember-engines` to devDependencies by default
    contents.devDependencies['ember-engines'] = '^0.8.5';

    return stringifyAndNormalize(sortPackageJson(contents));
  },

  _getEngineType() {
    if (this._engineType) { return this._engineType; }
    return this._engineType = this.options && this.options.type || 'routable';
  },

  afterInstall() {
    let type = this._getEngineType();
    let packagePath = path.join(this.path, 'files', type + '-files', 'package.json');
    let bowerPath = path.join(this.path, 'files', type + '-files', 'bower.json');

    [packagePath, bowerPath].forEach(filePath => {
      fs.removeSync(filePath);
    });
  }

});
<commit_msg>Bump used ember-engines version<commit_after>'use strict';

const globalModulesDir = require('global-modules');
const yarnGlobalModulesDir = require('yarn-global-modules')();
const addonPath = require.resolve('ember-cli/blueprints/addon/index', {
  paths: [ yarnGlobalModulesDir, globalModulesDir ]
});

const path = require('path');
const Addon = require(addonPath);
const stringUtil = require('ember-cli-string-utils');
const walkSync = require('walk-sync');
const existsSync = require('exists-sync');
const uniq = require('ember-cli-lodash-subset').uniq;
const sortPackageJson = require('sort-package-json');
const fs = require('fs-extra');

const stringifyAndNormalizePath = require.resolve('ember-cli/lib/utilities/stringify-and-normalize', {
  paths: [ yarnGlobalModulesDir, globalModulesDir ]
});
const stringifyAndNormalize = require(stringifyAndNormalizePath);

module.exports = Object.assign({}, Addon, {
  description: 'Creates a stand-alone Engine for Ember.js.',

  locals(options) {
    let superLocals = Addon.locals(...arguments);

    let engineName = options.entity.name;
    let engineModulePrefix = stringUtil.dasherize(engineName);

    return Object.assign(superLocals, {
      engineModulePrefix,
      isLazy: !!options.lazy,
      includeRoutesInApplication: !options.excludeRoutesFromApplication,
      welcome: false
    });
  },

  availableOptions: [
    {
      name: 'type',
      type: [ 'routable', 'routeless' ],
      default: 'routable',
      aliases: [
        { 'routable': 'routable' },
        { 'routeless': 'routeless' }
      ]
    },
    {
      name: 'lazy',
      type: Boolean,
      default: false,
      description: 'Whether this Engine should load lazily or not'
    },
    {
      name: 'exclude-routes-from-application',
      type: Boolean,
      description: 'Whether this Engine should exclude its routes from the applications vendor file or not'
    }
  ],

  install(options) {
    this.options = options;
    return this._super.install.apply(this, arguments);
  },

  uninstall(options) {
    this.options = options;
    return this._super.uninstall.apply(this, arguments);
  },

  filesPath() {
    let type = this._getEngineType();
    return path.join(this.path, "files", type + '-files');
  },

  files() {
    if (this._files) { return this._files; }

    this._appBlueprint = this.lookupBlueprint('app');
    let appFiles = this._appBlueprint.files();

    this._addonBlueprint = this.lookupBlueprint('addon');
    let addonFiles = this._addonBlueprint.files();

    let filesPath = this.filesPath(this.options);
    let engineFiles = [];
    if (existsSync(filesPath)) {
      engineFiles = walkSync(filesPath);
    }

    let files = uniq(appFiles.concat(addonFiles).concat(engineFiles));

    let addonGitKeep = files.indexOf('addon/.gitkeep');
    files.splice(addonGitKeep, 1);

    // Remove app/.gitkeep, engines don't need app directories
    let appGitKeep = files.indexOf('app/.gitkeep');
    files.splice(appGitKeep, 1);

    return this._files = files;
  },

  srcPath(file) {
    let type = this._getEngineType();
    let engineFilePath = path.join(this.path, "files", type + '-files', file);
    let addonFilePath = path.resolve(this._addonBlueprint.path, 'files', file);
    if (existsSync(engineFilePath)) {
      return engineFilePath;
    } else if (existsSync(addonFilePath)) {
      return addonFilePath;
    } else {
      return path.resolve(this._appBlueprint.path, 'files', file);
    }
  },

  updatePackageJson(contents) {
    contents = Addon.updatePackageJson.apply(this, arguments);
    contents = JSON.parse(contents)

    // Add `ember-engines` to devDependencies by default
    contents.devDependencies['ember-engines'] = '^0.8.12';

    return stringifyAndNormalize(sortPackageJson(contents));
  },

  _getEngineType() {
    if (this._engineType) { return this._engineType; }
    return this._engineType = this.options && this.options.type || 'routable';
  },

  afterInstall() {
    let type = this._getEngineType();
    let packagePath = path.join(this.path, 'files', type + '-files', 'package.json');
    let bowerPath = path.join(this.path, 'files', type + '-files', 'bower.json');

    [packagePath, bowerPath].forEach(filePath => {
      fs.removeSync(filePath);
    });
  }

});
<|endoftext|>


<commit_before>'use strict';

module.exports = Point;

/**
 * A standalone point geometry with useful accessor, comparison, and
 * modification methods.
 *
 * @class Point
 * @param {Number} x the x-coordinate. this could be longitude or screen
 * pixels, or any other sort of unit.
 * @param {Number} y the y-coordinate. this could be latitude or screen
 * pixels, or any other sort of unit.
 * @example
 * var point = new Point(-77, 38);
 */
function Point(x, y) {
    this.x = x;
    this.y = y;
}

Point.prototype = {

    /**
     * Clone this point, returning a new point that can be modified
     * without affecting the old one.
     * @return {Point} the clone
     */
    clone: function() { return new Point(this.x, this.y); },

    /**
     * Add this point's x & y coordinates to another point,
     * yielding a new point.
     * @param {Point} p the other point
     * @return {Point} output point
     */
    add:     function(p) { return this.clone()._add(p); },

    /**
     * Subtract this point's x & y coordinates to from point,
     * yielding a new point.
     * @param {Point} p the other point
     * @return {Point} output point
     */
    sub:     function(p) { return this.clone()._sub(p); },

    /**
     * Multiply this point's x & y coordinates with from point,
     * yielding a new point.
     * @param {Point} k the other point
     * @return {Point} output point
     */
    mult:    function(k) { return this.clone()._mult(k); },

    /**
     * Divide this point's x & y coordinates with from point,
     * yielding a new point.
     * @param {Point} k the other point
     * @return {Point} output point
     */
    div:     function(k) { return this.clone()._div(k); },

    /**
     * Rotate this point around the 0, 0 origin by an angle a,
     * given in radians
     * @param {Number} a angle to rotate around, in radians
     * @return {Point} output point
     */
    rotate:  function(a) { return this.clone()._rotate(a); },

    /**
     * Rotate this point around p point by an angle a,
     * given in radians
     * @param {Number} a angle to rotate around, in radians
     * @param {Point} p Point to rotate around
     * @return {Point} output point
     */
    rotateAround:  function(a,p) { return this.clone()._rotateAround(a,p); },

    /**
     * Multiply this point by a 4x1 transformation matrix
     * @param {Array<Number>} m transformation matrix
     * @return {Point} output point
     */
    matMult: function(m) { return this.clone()._matMult(m); },

    /**
     * Calculate this point but as a unit vector from 0, 0, meaning
     * that the distance from the resulting point to the 0, 0
     * coordinate will be equal to 1 and the angle from the resulting
     * point to the 0, 0 coordinate will be the same as before.
     * @return {Point} unit vector point
     */
    unit:    function() { return this.clone()._unit(); },

    /**
     * Compute a perpendicular point, where the new y coordinate
     * is the old x coordinate and the new x coordinate is the old y
     * coordinate multiplied by -1
     * @return {Point} perpendicular point
     */
    perp:    function() { return this.clone()._perp(); },

    /**
     * Return a version of this point with the x & y coordinates
     * rounded to integers.
     * @return {Point} rounded point
     */
    round:   function() { return this.clone()._round(); },

    /**
     * Return the magitude of this point: this is the Euclidean
     * distance from the 0, 0 coordinate to this point's x and y
     * coordinates.
     * @return {Number} magnitude
     */
    mag: function() {
        return Math.sqrt(this.x * this.x + this.y * this.y);
    },

    /**
     * Judge whether this point is equal to another point, returning
     * true or false.
     * @param {Point} other the other point
     * @return {boolean} whether the points are equal
     */
    equals: function(other) {
        return this.x === other.x &&
               this.y === other.y;
    },

    /**
     * Calculate the distance from this point to another point
     * @param {Point} p the other point
     * @return {Number} distance
     */
    dist: function(p) {
        return Math.sqrt(this.distSqr(p));
    },

    /**
     * Calculate the distance from this point to another point,
     * without the square root step. Useful if you're comparing
     * relative distances.
     * @param {Point} p the other point
     * @return {Number} distance
     */
    distSqr: function(p) {
        var dx = p.x - this.x,
            dy = p.y - this.y;
        return dx * dx + dy * dy;
    },

    /**
     * Get the angle from the 0, 0 coordinate to this point, in radians
     * coordinates.
     * @return {Number} angle
     */
    angle: function() {
        return Math.atan2(this.y, this.x);
    },

    /**
     * Get the angle from this point to another point, in radians
     * @param {Point} b the other point
     * @return {Number} angle
     */
    angleTo: function(b) {
        return Math.atan2(this.y - b.y, this.x - b.x);
    },

    /**
     * Get the angle between this point and another point, in radians
     * @param {Point} b the other point
     * @return {Number} angle
     */
    angleWith: function(b) {
        return this.angleWithSep(b.x, b.y);
    },

    /*
     * Find the angle of the two vectors, solving the formula for
     * the cross product a x b = |a||b|sin(θ) for θ.
     * @param {Number} x the x-coordinate
     * @param {Number} y the y-coordinate
     * @return {Number} the angle in radians
     */
    angleWithSep: function(x, y) {
        return Math.atan2(
            this.x * y - this.y * x,
            this.x * x + this.y * y);
    },

    _matMult: function(m) {
        var x = m[0] * this.x + m[1] * this.y,
            y = m[2] * this.x + m[3] * this.y;
        this.x = x;
        this.y = y;
        return this;
    },

    _add: function(p) {
        this.x += p.x;
        this.y += p.y;
        return this;
    },

    _sub: function(p) {
        this.x -= p.x;
        this.y -= p.y;
        return this;
    },

    _mult: function(k) {
        this.x *= k;
        this.y *= k;
        return this;
    },

    _div: function(k) {
        this.x /= k;
        this.y /= k;
        return this;
    },

    _unit: function() {
        this._div(this.mag());
        return this;
    },

    _perp: function() {
        var y = this.y;
        this.y = this.x;
        this.x = -y;
        return this;
    },

    _rotate: function(angle) {
        var cos = Math.cos(angle),
            sin = Math.sin(angle),
            x = cos * this.x - sin * this.y,
            y = sin * this.x + cos * this.y;
        this.x = x;
        this.y = y;
        return this;
    },

    _rotateAround: function(angle, p) {
        var cos = Math.cos(angle),
            sin = Math.sin(angle),
            x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y),
            y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
        this.x = x;
        this.y = y;
        return this;
    },

    _round: function() {
        this.x = Math.round(this.x);
        this.y = Math.round(this.y);
        return this;
    }
};

/**
 * Construct a point from an array if necessary, otherwise if the input
 * is already a Point, or an unknown type, return it unchanged
 * @param {Array<Number>|Point|*} a any kind of input value
 * @return {Point} constructed point, or passed-through value.
 * @example
 * // this
 * var point = Point.convert([0, 1]);
 * // is equivalent to
 * var point = new Point(0, 1);
 */
Point.convert = function (a) {
    if (a instanceof Point) {
        return a;
    }
    if (Array.isArray(a)) {
        return new Point(a[0], a[1]);
    }
    return a;
};
<commit_msg>fix on mult function<commit_after>'use strict';

module.exports = Point;

/**
 * A standalone point geometry with useful accessor, comparison, and
 * modification methods.
 *
 * @class Point
 * @param {Number} x the x-coordinate. this could be longitude or screen
 * pixels, or any other sort of unit.
 * @param {Number} y the y-coordinate. this could be latitude or screen
 * pixels, or any other sort of unit.
 * @example
 * var point = new Point(-77, 38);
 */
function Point(x, y) {
    this.x = x;
    this.y = y;
}

Point.prototype = {

    /**
     * Clone this point, returning a new point that can be modified
     * without affecting the old one.
     * @return {Point} the clone
     */
    clone: function() { return new Point(this.x, this.y); },

    /**
     * Add this point's x & y coordinates to another point,
     * yielding a new point.
     * @param {Point} p the other point
     * @return {Point} output point
     */
    add:     function(p) { return this.clone()._add(p); },

    /**
     * Subtract this point's x & y coordinates to from point,
     * yielding a new point.
     * @param {Point} p the other point
     * @return {Point} output point
     */
    sub:     function(p) { return this.clone()._sub(p); },

    /**
     * Multiply this point's x & y coordinates with from point,
     * yielding a new point.
     * @param {Point} k the other point
     * @return {Point} output point
     */
    mult:    function(k) { return this.clone()._mult(k); },

    /**
     * Divide this point's x & y coordinates with from point,
     * yielding a new point.
     * @param {Point} k the other point
     * @return {Point} output point
     */
    div:     function(k) { return this.clone()._div(k); },

    /**
     * Rotate this point around the 0, 0 origin by an angle a,
     * given in radians
     * @param {Number} a angle to rotate around, in radians
     * @return {Point} output point
     */
    rotate:  function(a) { return this.clone()._rotate(a); },

    /**
     * Rotate this point around p point by an angle a,
     * given in radians
     * @param {Number} a angle to rotate around, in radians
     * @param {Point} p Point to rotate around
     * @return {Point} output point
     */
    rotateAround:  function(a,p) { return this.clone()._rotateAround(a,p); },

    /**
     * Multiply this point by a 4x1 transformation matrix
     * @param {Array<Number>} m transformation matrix
     * @return {Point} output point
     */
    matMult: function(m) { return this.clone()._matMult(m); },

    /**
     * Calculate this point but as a unit vector from 0, 0, meaning
     * that the distance from the resulting point to the 0, 0
     * coordinate will be equal to 1 and the angle from the resulting
     * point to the 0, 0 coordinate will be the same as before.
     * @return {Point} unit vector point
     */
    unit:    function() { return this.clone()._unit(); },

    /**
     * Compute a perpendicular point, where the new y coordinate
     * is the old x coordinate and the new x coordinate is the old y
     * coordinate multiplied by -1
     * @return {Point} perpendicular point
     */
    perp:    function() { return this.clone()._perp(); },

    /**
     * Return a version of this point with the x & y coordinates
     * rounded to integers.
     * @return {Point} rounded point
     */
    round:   function() { return this.clone()._round(); },

    /**
     * Return the magitude of this point: this is the Euclidean
     * distance from the 0, 0 coordinate to this point's x and y
     * coordinates.
     * @return {Number} magnitude
     */
    mag: function() {
        return Math.sqrt(this.x * this.x + this.y * this.y);
    },

    /**
     * Judge whether this point is equal to another point, returning
     * true or false.
     * @param {Point} other the other point
     * @return {boolean} whether the points are equal
     */
    equals: function(other) {
        return this.x === other.x &&
               this.y === other.y;
    },

    /**
     * Calculate the distance from this point to another point
     * @param {Point} p the other point
     * @return {Number} distance
     */
    dist: function(p) {
        return Math.sqrt(this.distSqr(p));
    },

    /**
     * Calculate the distance from this point to another point,
     * without the square root step. Useful if you're comparing
     * relative distances.
     * @param {Point} p the other point
     * @return {Number} distance
     */
    distSqr: function(p) {
        var dx = p.x - this.x,
            dy = p.y - this.y;
        return dx * dx + dy * dy;
    },

    /**
     * Get the angle from the 0, 0 coordinate to this point, in radians
     * coordinates.
     * @return {Number} angle
     */
    angle: function() {
        return Math.atan2(this.y, this.x);
    },

    /**
     * Get the angle from this point to another point, in radians
     * @param {Point} b the other point
     * @return {Number} angle
     */
    angleTo: function(b) {
        return Math.atan2(this.y - b.y, this.x - b.x);
    },

    /**
     * Get the angle between this point and another point, in radians
     * @param {Point} b the other point
     * @return {Number} angle
     */
    angleWith: function(b) {
        return this.angleWithSep(b.x, b.y);
    },

    /*
     * Find the angle of the two vectors, solving the formula for
     * the cross product a x b = |a||b|sin(θ) for θ.
     * @param {Number} x the x-coordinate
     * @param {Number} y the y-coordinate
     * @return {Number} the angle in radians
     */
    angleWithSep: function(x, y) {
        return Math.atan2(
            this.x * y - this.y * x,
            this.x * x + this.y * y);
    },

    _matMult: function(m) {
        var x = m[0] * this.x + m[1] * this.y,
            y = m[2] * this.x + m[3] * this.y;
        this.x = x;
        this.y = y;
        return this;
    },

    _add: function(p) {
        this.x += p.x;
        this.y += p.y;
        return this;
    },

    _sub: function(p) {
        this.x -= p.x;
        this.y -= p.y;
        return this;
    },

    _mult: function(k) {
        this.x *= k.x;
        this.y *= k.y;
        return this;
    },

    _div: function(k) {
        this.x /= k;
        this.y /= k;
        return this;
    },

    _unit: function() {
        this._div(this.mag());
        return this;
    },

    _perp: function() {
        var y = this.y;
        this.y = this.x;
        this.x = -y;
        return this;
    },

    _rotate: function(angle) {
        var cos = Math.cos(angle),
            sin = Math.sin(angle),
            x = cos * this.x - sin * this.y,
            y = sin * this.x + cos * this.y;
        this.x = x;
        this.y = y;
        return this;
    },

    _rotateAround: function(angle, p) {
        var cos = Math.cos(angle),
            sin = Math.sin(angle),
            x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y),
            y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
        this.x = x;
        this.y = y;
        return this;
    },

    _round: function() {
        this.x = Math.round(this.x);
        this.y = Math.round(this.y);
        return this;
    }
};

/**
 * Construct a point from an array if necessary, otherwise if the input
 * is already a Point, or an unknown type, return it unchanged
 * @param {Array<Number>|Point|*} a any kind of input value
 * @return {Point} constructed point, or passed-through value.
 * @example
 * // this
 * var point = Point.convert([0, 1]);
 * // is equivalent to
 * var point = new Point(0, 1);
 */
Point.convert = function (a) {
    if (a instanceof Point) {
        return a;
    }
    if (Array.isArray(a)) {
        return new Point(a[0], a[1]);
    }
    return a;
};
<|endoftext|>


<commit_before>var resolve = require('path').resolve;
var formatMessage = require('format-message');

var setupFormatter = (function() {
  var instance;

  return function(translations, locale) {
    if(!!instance)
      return;

    var messages = translations.messages;

    instance = formatMessage.setup({
      translations: { 'id-id': messages },
      locale: 'id-id',
      missingTranslation: 'ignore'
    });

    return;
  }
})();

var loadLocaleData = function(localeLoader) {
  localeLoader = require(resolve(process.cwd(), localeLoader));

  return localeLoader();
}

module.exports = function messageFormat({ types: t }) {
  return {
    visitor: {
      CallExpression(path, { opts }) {
        var callee = path.node.callee.name;
        var translation_target = path.node.arguments[0].value;
        var translation_value = formatMessage(translation_target);
        var { translations, locale } = loadLocaleData(opts.localeLoader);

        setupFormatter(translations, locale);

        if (callee === '__') {
          path.replaceWith(t.StringLiteral(translation_value));
        }
      },
    },
  };
};

<commit_msg>0.1.2 - Bug Fix, format was called before setup<commit_after>var resolve = require('path').resolve;
var formatMessage = require('format-message');

var setupFormatter = (function() {
  var instance;

  return function(translations, locale) {
    if(!!instance)
      return;

    var messages = translations.messages;

    instance = formatMessage.setup({
      translations: { 'id-id': messages },
      locale: 'id-id',
      missingTranslation: 'ignore'
    });

    return;
  }
})();

var loadLocaleData = function(localeLoader) {
  localeLoader = require(resolve(process.cwd(), localeLoader));

  return localeLoader();
}

module.exports = function messageFormat({ types: t }) {
  return {
    visitor: {
      CallExpression(path, { opts }) {
        var callee = path.node.callee.name;
        var translation_target = path.node.arguments[0].value;
        var { translations, locale } = loadLocaleData(opts.localeLoader);
        var translation_value;

        setupFormatter(translations, locale);
        translation_value = formatMessage(translation_target);

        if (callee === '__') {
          path.replaceWith(t.StringLiteral(translation_value));
        }
      },
    },
  };
};

<|endoftext|>


<commit_before>module.exports = {
    "parser": "babel-eslint",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        }
    },
    "ecmaFeatures": {
        "jsx": true
    },
    "env": {
		"amd": true,
		"browser": true,
		"jquery": true,
		"node": true,
		"es6": true,
		"worker": true
	},
    "plugins": [
        "react"
    ],
    "rules": {
        // require the use of === and !==
        "eqeqeq": 2,

        // 	disallow trailing commas
        "comma-dangle": [2, "never"],

        // enforce consistent indentation of 4 spaces
        "indent": [ "error", 4 ],

        // allow the use of console
        "no-console": 0,

        // disallow the use of debugger
        "no-debugger": 2,

        // 	disallow unnecessary semicolons
        "no-extra-semi": 2,

        // 	disallow unnecessary parentheses only around function expressions
        "no-extra-parens": [ 2, "functions" ],

        // allow irregular whitespace outside of strings and comments
        "no-irregular-whitespace": 0,

        // allow the use of undeclared and disallow use of unused variables
        "no-undef": 0,
        "no-unused-vars": [2, { "args": "none", "ignoreRestSiblings": true }],

        // enforce consistent spacing inside braces
        "object-curly-spacing": [2, "always"],

        // require semicolons instead of ASI
        "semi": 2,

        // enforces spacing after semicolons and disallows spacing before semicolons
        "semi-spacing": 2,

        // require single quotes where possible and allow strings to use backtick
        "quotes": [2, "single", { "allowTemplateLiterals": true }],

        // 	enforce valid JSDoc comments
        "valid-jsdoc": [
          2,
          { "requireReturn": false }
        ],

        // React rules

        // enforces closing bracket after props always
        "react/jsx-closing-bracket-location": [
          2,
          {
            "selfClosing": "after-props",
            "nonEmpty": "after-props"
          }
        ],

        // enforce spaces between curly braces
        "react/jsx-curly-spacing": 2,

        // do not enforce consistent props indentation
        "react/jsx-indent-props": 0,

        // do not enforce max props per line
        "react/jsx-max-props-per-line": 0,

        // prevent duplicate props in JSX
        "react/jsx-no-duplicate-props": 2,

        // allow unwrapped literals (e.g. {'test'} vs test)
        "react/jsx-no-literals": 0,

        // disallow undeclared variables
        "react/jsx-no-undef": 2,

        // require prop types to be alpha sorted
        "react/sort-prop-types": 2,

        // do not enforce alpha sorted props passed in
        "react/jsx-sort-props": 0,

        // prevent React to be incorrectly marked as unused
        "react/jsx-uses-react": 2,

        // [revent variables used in JSX to be incorrectly marked as unused
        "react/jsx-uses-vars": 2,

        // allow usage of dangerous JSX properties
        "react/no-danger": 0,

        // prevent usage of setState in componentDidMount
        "react/no-did-mount-set-state": 2,

        // prevent uage of setSate in componentDidUpdate
        "react/no-did-update-set-state": 2,

        // prevent direct mutation of this.state
        "react/no-direct-mutation-state": 2,

        // prevent multiple component definition per file except for stateless components
        "react/no-multi-comp": [
          2,
          { "ignoreStateless": true }
        ],

        // allow usage of setState
        "react/no-set-state": 0,

        // warn on usage of unknown DOM property
        "react/no-unknown-property": 1,

        // prevent missing props validation in a React component definition
        "react/prop-types": [2, { "ignore": ["children"] }],

        // prevent missing React when using JSX
        "react/react-in-jsx-scope": 0,

        // prevent extra closing tags for components without children
        "react/self-closing-comp": 2,

        // enforce component methods order
        "react/sort-comp": 2,

        // prevent missing parentheses around multilines JSX
        "react/wrap-multilines": 2
      }
};
<commit_msg>Update deprecated rule<commit_after>module.exports = {
    "parser": "babel-eslint",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        }
    },
    "ecmaFeatures": {
        "jsx": true
    },
    "env": {
		"amd": true,
		"browser": true,
		"jquery": true,
		"node": true,
		"es6": true,
		"worker": true
	},
    "plugins": [
        "react"
    ],
    "rules": {
        // require the use of === and !==
        "eqeqeq": 2,

        // 	disallow trailing commas
        "comma-dangle": [2, "never"],

        // enforce consistent indentation of 4 spaces
        "indent": [ "error", 4 ],

        // allow the use of console
        "no-console": 0,

        // disallow the use of debugger
        "no-debugger": 2,

        // 	disallow unnecessary semicolons
        "no-extra-semi": 2,

        // 	disallow unnecessary parentheses only around function expressions
        "no-extra-parens": [ 2, "functions" ],

        // allow irregular whitespace outside of strings and comments
        "no-irregular-whitespace": 0,

        // allow the use of undeclared and disallow use of unused variables
        "no-undef": 0,
        "no-unused-vars": [2, { "args": "none", "ignoreRestSiblings": true }],

        // enforce consistent spacing inside braces
        "object-curly-spacing": [2, "always"],

        // require semicolons instead of ASI
        "semi": 2,

        // enforces spacing after semicolons and disallows spacing before semicolons
        "semi-spacing": 2,

        // require single quotes where possible and allow strings to use backtick
        "quotes": [2, "single", { "allowTemplateLiterals": true }],

        // 	enforce valid JSDoc comments
        "valid-jsdoc": [
          2,
          { "requireReturn": false }
        ],

        // React rules

        // enforces closing bracket after props always
        "react/jsx-closing-bracket-location": [
          2,
          {
            "selfClosing": "after-props",
            "nonEmpty": "after-props"
          }
        ],

        // enforce spaces between curly braces
        "react/jsx-curly-spacing": 2,

        // do not enforce consistent props indentation
        "react/jsx-indent-props": 0,

        // do not enforce max props per line
        "react/jsx-max-props-per-line": 0,

        // prevent duplicate props in JSX
        "react/jsx-no-duplicate-props": 2,

        // allow unwrapped literals (e.g. {'test'} vs test)
        "react/jsx-no-literals": 0,

        // disallow undeclared variables
        "react/jsx-no-undef": 2,

        // require prop types to be alpha sorted
        "react/sort-prop-types": 2,

        // do not enforce alpha sorted props passed in
        "react/jsx-sort-props": 0,

        // prevent React to be incorrectly marked as unused
        "react/jsx-uses-react": 2,

        // [revent variables used in JSX to be incorrectly marked as unused
        "react/jsx-uses-vars": 2,

        // allow usage of dangerous JSX properties
        "react/no-danger": 0,

        // prevent usage of setState in componentDidMount
        "react/no-did-mount-set-state": 2,

        // prevent uage of setSate in componentDidUpdate
        "react/no-did-update-set-state": 2,

        // prevent direct mutation of this.state
        "react/no-direct-mutation-state": 2,

        // prevent multiple component definition per file except for stateless components
        "react/no-multi-comp": [
          2,
          { "ignoreStateless": true }
        ],

        // allow usage of setState
        "react/no-set-state": 0,

        // warn on usage of unknown DOM property
        "react/no-unknown-property": 1,

        // prevent missing props validation in a React component definition
        "react/prop-types": [2, { "ignore": ["children"] }],

        // prevent missing React when using JSX
        "react/react-in-jsx-scope": 0,

        // prevent extra closing tags for components without children
        "react/self-closing-comp": 2,

        // enforce component methods order
        "react/sort-comp": 2,

        // prevent missing parentheses around multilines JSX
        "react/jsx-wrap-multilines": 2
      }
};
<|endoftext|>