<commit_before>import { app, Menu } from 'electron';
import { EventEmitter } from 'events';
import { getMainWindow } from './mainWindow';
import i18n from '../i18n/index.js';

const createTemplate = ({
	appName,
	servers = [],
	currentServerUrl = null,
	showTrayIcon = true,
	showUserStatusInTray = true,
	showFullScreen = false,
	showMenuBar = true,
	showServerList = true,
	showWindowOnUnreadChanged = false,
}, events) => ([
	{
		label: process.platform === 'darwin' ? appName : i18n.__('&File'),
		submenu: [
			...(process.platform === 'darwin' ? [
				{
					label: i18n.__('About %s', appName),
					click: () => events.emit('about'),
				},
				{
					type: 'separator',
				},
				{
					submenu: [],
					role: 'services',
				},
				{
					type: 'separator',
				},
				{
					accelerator: 'Command+H',
					role: 'hide',
				},
				{
					accelerator: 'Command+Alt+H',
					role: 'hideothers',
				},
				{
					role: 'unhide',
				},
				{
					type: 'separator',
				},
			] : []),
			// {
			// 	label: i18n.__('Preferences'),
			// 	accelerator: 'CommandOrControl+,',
			// 	click: () => events.emit('preferences'),
			// },
			...(process.platform !== 'darwin' ? [
				{
					label: i18n.__('Add &new server'),
					accelerator: 'CommandOrControl+N',
					click: () => events.emit('add-new-server'),
				},
			] : []),
			{
				type: 'separator',
			},
			{
				id: 'quit',
				label: i18n.__('&Quit %s', appName),
				accelerator: 'CommandOrControl+Q',
				click: () => events.emit('quit'),
			},
		],
	},
	{
		label: i18n.__('&Edit'),
		submenu: [
			{
				label: i18n.__('&Undo'),
				accelerator: 'CommandOrControl+Z',
				role: 'undo',
			},
			{
				label: i18n.__('&Redo'),
				accelerator: process.platform === 'win32' ? 'Control+Y' : 'CommandOrControl+Shift+Z',
				role: 'redo',
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Cu&t'),
				accelerator: 'CommandOrControl+X',
				role: 'cut',
			},
			{
				label: i18n.__('&Copy'),
				accelerator: 'CommandOrControl+C',
				role: 'copy',
			},
			{
				label: i18n.__('&Paste'),
				accelerator: 'CommandOrControl+V',
				role: 'paste',
			},
			{
				label: i18n.__('Select &all'),
				accelerator: 'CommandOrControl+A',
				role: 'selectall',
			},
		],
	},
	{
		label: i18n.__('&View'),
		submenu: [
			{
				label: i18n.__('&Reload'),
				accelerator: 'CommandOrControl+R',
				click: () => events.emit('reload-server'),
			},
			{
				label: i18n.__('Reload ignoring cache'),
				click: () => events.emit('reload-server', { ignoringCache: true }),
			},
			{
				label: i18n.__('Clear trusted certificates'),
				click: () => events.emit('reload-server', { ignoringCache: true, clearCertificates: true }),
			},
			{
				label: i18n.__('Open &DevTools'),
				accelerator: process.platform === 'darwin' ? 'Command+Alt+I' : 'Ctrl+Shift+I',
				click: () => events.emit('open-devtools-for-server'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('&Back'),
				accelerator: process.platform === 'darwin' ? 'Command+Left' : 'Alt+Left',
				click: () => events.emit('go-back'),
			},
			{
				label: i18n.__('&Forward'),
				accelerator: process.platform === 'darwin' ? 'Command+Right' : 'Alt+Right',
				click: () => events.emit('go-forward'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Tray icon'),
				type: 'checkbox',
				checked: showTrayIcon,
				click: () => events.emit('toggle', 'showTrayIcon'),
			},
			...(process.platform === 'darwin' ? [
				{
					label: i18n.__('User status in tray'),
					type: 'checkbox',
					enabled: showTrayIcon,
					checked: showTrayIcon && showUserStatusInTray,
					click: () => events.emit('toggle', 'showUserStatusInTray'),
				},
				{
					label: i18n.__('Full screen'),
					type: 'checkbox',
					checked: showFullScreen,
					accelerator: 'Control+Command+F',
					click: () => events.emit('toggle', 'showFullScreen'),
				},
			] : []),
			...(process.platform !== 'darwin' ? [
				{
					label: i18n.__('Menu bar'),
					type: 'checkbox',
					checked: showMenuBar,
					click: () => events.emit('toggle', 'showMenuBar'),
				},
			] : []),
			{
				label: i18n.__('Server list'),
				type: 'checkbox',
				checked: showServerList,
				click: () => events.emit('toggle', 'showServerList'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Reset zoom'),
				accelerator: 'CommandOrControl+0',
				role: 'resetzoom',
			},
			{
				label: i18n.__('Zoom in'),
				accelerator: 'CommandOrControl+Plus',
				role: 'zoomin',
			},
			{
				label: i18n.__('Zoom out'),
				accelerator: 'CommandOrControl+-',
				role: 'zoomout',
			},
		],
	},
	{
		label: i18n.__('&Window'),
		id: 'window',
		role: 'window',
		submenu: [
			...(process.platform === 'darwin' ? [
				{
					label: i18n.__('Add &new server'),
					accelerator: 'CommandOrControl+N',
					click: () => events.emit('add-new-server'),
				},
				{
					type: 'separator',
				},
			] : []),
			...servers.map((host, i) => ({
				label: host.title.replace(/&/g, '&&'),
				type: currentServerUrl ? 'radio' : 'normal',
				checked: currentServerUrl === host.url,
				accelerator: `CommandOrControl+${ i + 1 }`,
				id: host.url,
				click: () => events.emit('select-server', host),
			})),
			{
				type: 'separator',
			},
			{
				label: i18n.__('&Reload'),
				accelerator: 'CommandOrControl+Shift+R',
				click: () => events.emit('reload-app'),
			},
			{
				label: i18n.__('Toggle &DevTools'),
				click: () => events.emit('toggle-devtools'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Show on unread messages'),
				type: 'checkbox',
				checked: showWindowOnUnreadChanged,
				click: () => events.emit('toggle', 'showWindowOnUnreadChanged'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Minimize'),
				accelerator: 'CommandOrControl+M',
				role: 'minimize',
			},
			{
				label: i18n.__('Close'),
				accelerator: 'CommandOrControl+W',
				role: 'close',
			},
		],
	},
	{
		label: i18n.__('&Help'),
		role: 'help',
		submenu: [
			{
				label: i18n.__('Documentation'),
				click: () => events.emit('open-url', 'https://rocket.chat/docs'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Report issue'),
				click: () => events.emit('open-url', 'https://github.com/RocketChat/Rocket.Chat/issues'),
			},
			{
				label: i18n.__('Reset app data'),
				click: () => events.emit('reset-app-data'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Learn more'),
				click: () => events.emit('open-url', 'https://rocket.chat'),
			},
			{
				id: 'about',
				label: i18n.__('About %s', appName),
				click: () => events.emit('about'),
			},
		],
	},
]);

class Menus extends EventEmitter {
	constructor() {
		super();
		this.state = {};
		this.on('update', this.update.bind(this));
	}

	setState(partialState) {
		this.state = {
			...this.state,
			...partialState,
		};
		this.update();
	}

	getItem(id) {
		return Menu.getApplicationMenu().getMenuItemById(id);
	}

	async update() {
		const template = createTemplate({ appName: app.getName(), ...this.state }, this);
		const menu = Menu.buildFromTemplate(template);
		Menu.setApplicationMenu(menu);

		if (process.platform !== 'darwin') {
			const { showMenuBar } = this.state;
			const mainWindow = await getMainWindow();
			mainWindow.setAutoHideMenuBar(!showMenuBar);
			mainWindow.setMenuBarVisibility(!!showMenuBar);
		}
	}
}

export default new Menus();
<commit_msg>Make menus update invoke its listeners<commit_after>import { app, Menu } from 'electron';
import { EventEmitter } from 'events';
import { getMainWindow } from './mainWindow';
import i18n from '../i18n/index.js';

const createTemplate = ({
	appName,
	servers = [],
	currentServerUrl = null,
	showTrayIcon = true,
	showUserStatusInTray = true,
	showFullScreen = false,
	showMenuBar = true,
	showServerList = true,
	showWindowOnUnreadChanged = false,
}, events) => ([
	{
		label: process.platform === 'darwin' ? appName : i18n.__('&File'),
		submenu: [
			...(process.platform === 'darwin' ? [
				{
					label: i18n.__('About %s', appName),
					click: () => events.emit('about'),
				},
				{
					type: 'separator',
				},
				{
					submenu: [],
					role: 'services',
				},
				{
					type: 'separator',
				},
				{
					accelerator: 'Command+H',
					role: 'hide',
				},
				{
					accelerator: 'Command+Alt+H',
					role: 'hideothers',
				},
				{
					role: 'unhide',
				},
				{
					type: 'separator',
				},
			] : []),
			// {
			// 	label: i18n.__('Preferences'),
			// 	accelerator: 'CommandOrControl+,',
			// 	click: () => events.emit('preferences'),
			// },
			...(process.platform !== 'darwin' ? [
				{
					label: i18n.__('Add &new server'),
					accelerator: 'CommandOrControl+N',
					click: () => events.emit('add-new-server'),
				},
			] : []),
			{
				type: 'separator',
			},
			{
				id: 'quit',
				label: i18n.__('&Quit %s', appName),
				accelerator: 'CommandOrControl+Q',
				click: () => events.emit('quit'),
			},
		],
	},
	{
		label: i18n.__('&Edit'),
		submenu: [
			{
				label: i18n.__('&Undo'),
				accelerator: 'CommandOrControl+Z',
				role: 'undo',
			},
			{
				label: i18n.__('&Redo'),
				accelerator: process.platform === 'win32' ? 'Control+Y' : 'CommandOrControl+Shift+Z',
				role: 'redo',
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Cu&t'),
				accelerator: 'CommandOrControl+X',
				role: 'cut',
			},
			{
				label: i18n.__('&Copy'),
				accelerator: 'CommandOrControl+C',
				role: 'copy',
			},
			{
				label: i18n.__('&Paste'),
				accelerator: 'CommandOrControl+V',
				role: 'paste',
			},
			{
				label: i18n.__('Select &all'),
				accelerator: 'CommandOrControl+A',
				role: 'selectall',
			},
		],
	},
	{
		label: i18n.__('&View'),
		submenu: [
			{
				label: i18n.__('&Reload'),
				accelerator: 'CommandOrControl+R',
				click: () => events.emit('reload-server'),
			},
			{
				label: i18n.__('Reload ignoring cache'),
				click: () => events.emit('reload-server', { ignoringCache: true }),
			},
			{
				label: i18n.__('Clear trusted certificates'),
				click: () => events.emit('reload-server', { ignoringCache: true, clearCertificates: true }),
			},
			{
				label: i18n.__('Open &DevTools'),
				accelerator: process.platform === 'darwin' ? 'Command+Alt+I' : 'Ctrl+Shift+I',
				click: () => events.emit('open-devtools-for-server'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('&Back'),
				accelerator: process.platform === 'darwin' ? 'Command+Left' : 'Alt+Left',
				click: () => events.emit('go-back'),
			},
			{
				label: i18n.__('&Forward'),
				accelerator: process.platform === 'darwin' ? 'Command+Right' : 'Alt+Right',
				click: () => events.emit('go-forward'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Tray icon'),
				type: 'checkbox',
				checked: showTrayIcon,
				click: () => events.emit('toggle', 'showTrayIcon'),
			},
			...(process.platform === 'darwin' ? [
				{
					label: i18n.__('User status in tray'),
					type: 'checkbox',
					enabled: showTrayIcon,
					checked: showTrayIcon && showUserStatusInTray,
					click: () => events.emit('toggle', 'showUserStatusInTray'),
				},
				{
					label: i18n.__('Full screen'),
					type: 'checkbox',
					checked: showFullScreen,
					accelerator: 'Control+Command+F',
					click: () => events.emit('toggle', 'showFullScreen'),
				},
			] : []),
			...(process.platform !== 'darwin' ? [
				{
					label: i18n.__('Menu bar'),
					type: 'checkbox',
					checked: showMenuBar,
					click: () => events.emit('toggle', 'showMenuBar'),
				},
			] : []),
			{
				label: i18n.__('Server list'),
				type: 'checkbox',
				checked: showServerList,
				click: () => events.emit('toggle', 'showServerList'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Reset zoom'),
				accelerator: 'CommandOrControl+0',
				role: 'resetzoom',
			},
			{
				label: i18n.__('Zoom in'),
				accelerator: 'CommandOrControl+Plus',
				role: 'zoomin',
			},
			{
				label: i18n.__('Zoom out'),
				accelerator: 'CommandOrControl+-',
				role: 'zoomout',
			},
		],
	},
	{
		label: i18n.__('&Window'),
		id: 'window',
		role: 'window',
		submenu: [
			...(process.platform === 'darwin' ? [
				{
					label: i18n.__('Add &new server'),
					accelerator: 'CommandOrControl+N',
					click: () => events.emit('add-new-server'),
				},
				{
					type: 'separator',
				},
			] : []),
			...servers.map((host, i) => ({
				label: host.title.replace(/&/g, '&&'),
				type: currentServerUrl ? 'radio' : 'normal',
				checked: currentServerUrl === host.url,
				accelerator: `CommandOrControl+${ i + 1 }`,
				id: host.url,
				click: () => events.emit('select-server', host),
			})),
			{
				type: 'separator',
			},
			{
				label: i18n.__('&Reload'),
				accelerator: 'CommandOrControl+Shift+R',
				click: () => events.emit('reload-app'),
			},
			{
				label: i18n.__('Toggle &DevTools'),
				click: () => events.emit('toggle-devtools'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Show on unread messages'),
				type: 'checkbox',
				checked: showWindowOnUnreadChanged,
				click: () => events.emit('toggle', 'showWindowOnUnreadChanged'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Minimize'),
				accelerator: 'CommandOrControl+M',
				role: 'minimize',
			},
			{
				label: i18n.__('Close'),
				accelerator: 'CommandOrControl+W',
				role: 'close',
			},
		],
	},
	{
		label: i18n.__('&Help'),
		role: 'help',
		submenu: [
			{
				label: i18n.__('Documentation'),
				click: () => events.emit('open-url', 'https://rocket.chat/docs'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Report issue'),
				click: () => events.emit('open-url', 'https://github.com/RocketChat/Rocket.Chat/issues'),
			},
			{
				label: i18n.__('Reset app data'),
				click: () => events.emit('reset-app-data'),
			},
			{
				type: 'separator',
			},
			{
				label: i18n.__('Learn more'),
				click: () => events.emit('open-url', 'https://rocket.chat'),
			},
			{
				id: 'about',
				label: i18n.__('About %s', appName),
				click: () => events.emit('about'),
			},
		],
	},
]);

class Menus extends EventEmitter {
	constructor() {
		super();
		this.state = {};
		this.on('update', this.update.bind(this));
	}

	setState(partialState) {
		this.state = {
			...this.state,
			...partialState,
		};
		this.emit('update');
	}

	getItem(id) {
		return Menu.getApplicationMenu().getMenuItemById(id);
	}

	async update() {
		const template = createTemplate({ appName: app.getName(), ...this.state }, this);
		const menu = Menu.buildFromTemplate(template);
		Menu.setApplicationMenu(menu);

		if (process.platform !== 'darwin') {
			const { showMenuBar } = this.state;
			const mainWindow = await getMainWindow();
			mainWindow.setAutoHideMenuBar(!showMenuBar);
			mainWindow.setMenuBarVisibility(!!showMenuBar);
		}
	}
}

export default new Menus();
<|endoftext|>


<commit_before>/*
   Copyright (C) 2014  James Ye  Simon Shields

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
/* the gnustomp-forkbomb style guide:
   Single tabs for indentation
   Single quotes for strings
   Opening braces on the same line as the statement
   Spaces around operators
   Empty line after a function defenition
*/

var http = require('http'),
	fs = require('fs'),
	jade = require('jade'),
	url = require('url'),
	forcedETagUpdateCounter = 0;

require('./variables.js'); // set globals appropriate to status - dev (DEBUG = true) or release (DEBUG = false)
if (!RELEASE) {
	GIT_RV = fs.readFileSync('.git/refs/heads/master').toString().trim();
	var watcher = fs.watch('.git/refs/heads/master', { persistent: false }, function() {
		'use strict';
		GIT_RV = fs.readFileSync('.git/refs/heads/master').toString().trim();
	});
}
else {
	GIT_RV = 'TODO'; // TODO
}

var jade_opts = {
	pretty: DEBUG,
	compileDebug: DEBUG
};

process.on('SIGHUP', function() {
	'use strict';
	forcedETagUpdateCounter++;
	console.log('ETagUpdateCounts: ' + forcedETagUpdateCounter);
});

function httpHeaders(res, response, contentType, dynamic, headers) {
	'use strict';
	var date;
	dynamic = dynamic || false;
	headers = headers || {};
	if (dynamic || DEBUG) { // disable caching
		headers['Cache-Control'] = 'no-cache';
	}
	else if (!dynamic) {
		date = new Date();
		date.setYear(date.getFullYear() + 1);
		headers.Expires = date.toGMTString();
		//	headers.ETag = GIT_RV+'_'+forcedETagUpdateCounter;	// TODO better ETags. This *will* work in production because new git revisions will be the only way updates occur.
		// SIGHUP'ing the process will force every client to re-request resources.
	}
	headers['Content-Type'] = contentType + '; charset=UTF-8';
	res.writeHead(response, headers);
	return res;
}

function ISE() {
	'use strict';
	return '<!DOCTYPE html><link rel="stylesheet" href="/style/common.css" /><title>500 Internal Server Error</title>
Oops :(
';
}

function compile_jade(path) {
	'use strict';
	try {
		var mopts = jade_opts;
		mopts.filename = path;
		return jade.compile(fs.readFileSync(path), mopts);
	}
	catch (e) {
		console.error('!!! Failed to compile jade "'+path+'"!!! Stack trace:');
		console.error(e.stack);
		return ISE;
	}
}

function onRequest(req, res) {
	/*jshint validthis: true*/
	'use strict';
	console.log('[' + this.name + ']', req.method, req.url);
	if (req.headers['if-none-match'] == GIT_RV+'_'+forcedETagUpdateCounter && !DEBUG) {
		res.writeHead(304);
		res.end();
		return;
	}
	var j, uri = url.parse(req.url, true);
	if (uri.pathname === '/') {
		j = compile_jade('dynamic/index.jade');
		httpHeaders(res, (j == ISE ? 500 : 200), 'text/html', true);
		res.end(j({'minified': MINIFY, 'page': ''}));
	} else if (uri.pathname.match('/style/.*[.]css$') && fs.existsSync(uri.pathname.slice(1).slice(0,-4)+'.min.css')) {
		httpHeaders(res, 200, 'text/css');
		j = uri.pathname.slice(1);
		if (MINIFY) {
			j = j.slice(0,-4) + '.min.css';
		}
		fs.createReadStream(j).pipe(res);
	} else if (uri.pathname.match('/script/.*[.]js$') && fs.existsSync(uri.pathname.slice(1).slice(0,-3)+'.min.js')) {
		httpHeaders(res, 200, 'application/javascript');
		j = uri.pathname.slice(1);
		if (MINIFY) {
			j = j.slice(0,-3) + '.min.js';
		}
		fs.createReadStream(j).pipe(res);
	} else {
		httpHeaders(res, 404, 'text/html');
		fs.createReadStream('static/404.html').pipe(res);
	}
}

function onListening() {
	/*jshint validthis: true*/
	'use strict';
	console.log('[' + this.name + '] Listening on http://' + this.address().address + ':' + this.address().port + '/');
}
console.log('[master] SBHS-Timetable-Node revision ' + GIT_RV.substr(0, 6) + ' loading...');
var ipv4server = http.createServer(),
	ipv6server = http.createServer();

ipv4server.name = 'ipv4server';
ipv6server.name = 'ipv6server';

ipv4server.on('request', onRequest);
ipv6server.on('request', onRequest);

ipv4server.on('listening', onListening);
ipv6server.on('listening', onListening);

ipv4server.listen(8080, '0.0.0.0');
if (IPV6) {
	ipv6server.listen(8080, '::');
}
<commit_msg>Variable names!<commit_after>/*
   Copyright (C) 2014  James Ye  Simon Shields

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
/* the gnustomp-forkbomb style guide:
   Single tabs for indentation
   Single quotes for strings
   Opening braces on the same line as the statement
   Spaces around operators
   Empty line after a function defenition
*/

var http = require('http'),
	fs = require('fs'),
	jade = require('jade'),
	url = require('url'),
	forcedETagUpdateCounter = 0;

require('./variables.js'); // set globals appropriate to status - dev (DEBUG = true) or release (DEBUG = false)
if (!RELEASE) {
	GIT_RV = fs.readFileSync('.git/refs/heads/master').toString().trim();
	var watcher = fs.watch('.git/refs/heads/master', { persistent: false }, function() {
		'use strict';
		GIT_RV = fs.readFileSync('.git/refs/heads/master').toString().trim();
	});
}
else {
	GIT_RV = 'TODO'; // TODO
}

var jade_opts = {
	pretty: DEBUG,
	compileDebug: DEBUG
};

process.on('SIGHUP', function() {
	'use strict';
	forcedETagUpdateCounter++;
	console.log('ETagUpdateCounts: ' + forcedETagUpdateCounter);
});

function httpHeaders(res, response, contentType, dynamic, headers) {
	'use strict';
	var date;
	dynamic = dynamic || false;
	headers = headers || {};
	if (dynamic || DEBUG) { // disable caching
		headers['Cache-Control'] = 'no-cache';
	}
	else if (!dynamic) {
		date = new Date();
		date.setYear(date.getFullYear() + 1);
		headers.Expires = date.toGMTString();
		//	headers.ETag = GIT_RV+'_'+forcedETagUpdateCounter;	// TODO better ETags. This *will* work in production because new git revisions will be the only way updates occur.
		// SIGHUP'ing the process will force every client to re-request resources.
	}
	headers['Content-Type'] = contentType + '; charset=UTF-8';
	res.writeHead(response, headers);
	return res;
}

function ISE() {
	'use strict';
	return '<!DOCTYPE html><link rel="stylesheet" href="/style/common.css" /><title>500 Internal Server Error</title>
Oops :(
';
}

function compile_jade(path) {
	'use strict';
	try {
		var mopts = jade_opts;
		mopts.filename = path;
		return jade.compile(fs.readFileSync(path), mopts);
	}
	catch (e) {
		console.error('!!! Failed to compile jade "'+path+'"!!! Stack trace:');
		console.error(e.stack);
		return ISE;
	}
}

function onRequest(req, res) {
	/*jshint validthis: true*/
	'use strict';
	console.log('[' + this.name + ']', req.method, req.url);
	if (req.headers['if-none-match'] == GIT_RV+'_'+forcedETagUpdateCounter && !DEBUG) {
		res.writeHead(304);
		res.end();
		return;
	}
	var target, uri = url.parse(req.url, true);
	if (uri.pathname === '/') {
		target = compile_jade('dynamic/index.jade');
		httpHeaders(res, (target == ISE ? 500 : 200), 'text/html', true);
		res.end(target({'minified': MINIFY, 'page': ''}));
	} else if (uri.pathname.match('/style/.*[.]css$') && fs.existsSync(uri.pathname.slice(1).slice(0,-4)+'.min.css')) {
		httpHeaders(res, 200, 'text/css');
		target = uri.pathname.slice(1);
		if (MINIFY) {
			target = target.slice(0,-4) + '.min.css';
		}
		fs.createReadStream(target).pipe(res);
	} else if (uri.pathname.match('/script/.*[.]js$') && fs.existsSync(uri.pathname.slice(1).slice(0,-3)+'.min.js')) {
		httpHeaders(res, 200, 'application/javascript');
		target = uri.pathname.slice(1);
		if (MINIFY) {
			target = target.slice(0,-3) + '.min.js';
		}
		fs.createReadStream(target).pipe(res);
	} else {
		httpHeaders(res, 404, 'text/html');
		fs.createReadStream('static/404.html').pipe(res);
	}
}

function onListening() {
	/*jshint validthis: true*/
	'use strict';
	console.log('[' + this.name + '] Listening on http://' + this.address().address + ':' + this.address().port + '/');
}
console.log('[master] SBHS-Timetable-Node revision ' + GIT_RV.substr(0, 6) + ' loading...');
var ipv4server = http.createServer(),
	ipv6server = http.createServer();

ipv4server.name = 'ipv4server';
ipv6server.name = 'ipv6server';

ipv4server.on('request', onRequest);
ipv6server.on('request', onRequest);

ipv4server.on('listening', onListening);
ipv6server.on('listening', onListening);

ipv4server.listen(8080, '0.0.0.0');
if (IPV6) {
	ipv6server.listen(8080, '::');
}
<|endoftext|>


<commit_before>/**
 * @file ListItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Checkbox from '../Checkbox';
import Radio from '../Radio';
import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import TouchRipple from '../TouchRipple';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';

export default class ListItem extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            checked: props.checked
        };

        this.checkboxChangeHandler = ::this.checkboxChangeHandler;
        this.radioChangeHandler = ::this.radioChangeHandler;
        this.touchTapHandler = ::this.touchTapHandler;

    }

    checkboxChangeHandler(checked) {
        this.setState({
            checked
        }, () => {

            const {onSelect, onDeselect} = this.props;

            if (checked) {
                onSelect && onSelect();
            } else {
                onDeselect && onDeselect();
            }

        });
    }

    radioChangeHandler() {

        const {checked} = this.state;

        if (!checked) {
            this.setState({
                checked: true
            }, () => {
                const {onSelect} = this.props;
                onSelect && onSelect();
            });
        }

    }

    touchTapHandler(e) {

        e.preventDefault();

        const {disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly) {
            return;
        }

        const {onTouchTap} = this.props;
        onTouchTap && onTouchTap(e);

        const {selectMode} = this.props;

        switch (selectMode) {
            case SelectMode.MULTI_SELECT:
                this.checkboxChangeHandler(!this.state.checked);
                return;
            case SelectMode.SINGLE_SELECT:
                this.radioChangeHandler();
                return;
        }

    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.checked !== this.state.checked) {
            this.setState({
                checked: nextProps.checked
            });
        }
    }

    render() {

        const {

                index, className, style, theme, data, text, desc, iconCls, rightIconCls, tip, tipPosition,
                disabled, isLoading, disableTouchRipple, rippleDisplayCenter, renderer, itemRenderer, readOnly,

                selectTheme, selectMode, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                onMouseEnter, onMouseLeave

            } = this.props,
            {checked} = this.state,

            listItemClassName = (theme ? ` theme-${theme}` : '') + (checked ? ' activated' : '')
                + (className ? ' ' + className : ''),
            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left';

        return (
            <TipProvider className='block'
                         text={tip}
                         tipPosition={tipPosition}>

                    {
                        selectMode === SelectMode.SINGLE_SELECT ?
                            <Radio className="list-item-select"
                                   theme={selectTheme}
                                   checked={checked}
                                   disabled={disabled || isLoading}
                                   uncheckedIconCls={radioUncheckedIconCls}
                                   checkedIconCls={radioCheckedIconCls}
                                   disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        selectMode === SelectMode.MULTI_SELECT ?
                            <Checkbox className="list-item-select"
                                      theme={selectTheme}
                                      checked={checked}
                                      disabled={disabled || isLoading}
                                      uncheckedIconCls={checkboxUncheckedIconCls}
                                      checkedIconCls={checkboxCheckedIconCls}
                                      indeterminateIconCls={checkboxIndeterminateIconCls}
                                      disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        isLoading && loadingIconPosition === 'left' ?

                                <CircularLoading className="button-loading-icon"
                                                 size="small"/>

                            :
                            (
                                iconCls ?
                                    <i className={`button-icon button-icon-left ${iconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        itemRenderer && typeof itemRenderer === 'function' ?
                            itemRenderer(data, index)
                            :
                            (
                                renderer && typeof renderer === 'function' ?
                                    renderer(data, index)
                                    :
                                    (
                                        desc ?

                                                    {text}

                                                    {desc}

                                            :
                                            text
                                    )
                            )
                    }

                    {
                        isLoading && loadingIconPosition === 'right' ?
                            <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                             size="small"/>
                            :
                            (
                                rightIconCls ?
                                    <i className={`button-icon button-icon-right ${rightIconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        disableTouchRipple || readOnly ?
                            null
                            :
                            <TouchRipple ref="touchRipple"
                                         className={disabled || isLoading ? 'hidden' : ''}
                                         displayCenter={rippleDisplayCenter}/>
                    }

            </TipProvider>
        );

    }
};

ListItem.propTypes = {

    index: PropTypes.number,

    className: PropTypes.string,
    style: PropTypes.object,
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    text: PropTypes.any,
    desc: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    disableTouchRipple: PropTypes.bool,
    rippleDisplayCenter: PropTypes.bool,
    checked: PropTypes.bool,
    readOnly: PropTypes.bool,

    iconCls: PropTypes.string,
    rightIconCls: PropTypes.string,

    tip: PropTypes.string,
    tipPosition: PropTypes.oneOf(Util.enumerateValue(Position)),

    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    itemRenderer: PropTypes.func,
    renderer: PropTypes.func,

    onTouchTap: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func

};

ListItem.defaultProps = {

    index: 0,

    className: null,
    style: null,
    theme: null,

    selectTheme: null,
    selectMode: SelectMode.NORMAL,

    data: null,
    value: null,
    text: null,
    desc: null,

    disabled: false,
    isLoading: false,
    disableTouchRipple: false,
    rippleDisplayCenter: false,
    checked: false,
    readOnly: false,

    iconCls: null,
    rightIconCls: null,

    tip: null,
    tipPosition: Position.BOTTOM,

    radioUncheckedIconCls: 'fa fa-check',
    radioCheckedIconCls: 'fa fa-check',
    checkboxUncheckedIconCls: 'fa fa-square-o',
    checkboxCheckedIconCls: 'fa fa-check-square',
    checkboxIndeterminateIconCls: 'fa fa-minus-square'

};<commit_msg>optimize ListItem<commit_after>/**
 * @file ListItem component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Checkbox from '../Checkbox';
import Radio from '../Radio';
import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import TouchRipple from '../TouchRipple';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';

export default class ListItem extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            checked: props.checked
        };

        this.checkboxChangeHandler = ::this.checkboxChangeHandler;
        this.radioChangeHandler = ::this.radioChangeHandler;
        this.touchTapHandler = ::this.touchTapHandler;

    }

    checkboxChangeHandler(checked) {
        this.setState({
            checked
        }, () => {

            const {onSelect, onDeselect} = this.props;

            if (checked) {
                onSelect && onSelect();
            } else {
                onDeselect && onDeselect();
            }

        });
    }

    radioChangeHandler() {

        const {checked} = this.state;

        if (!checked) {
            this.setState({
                checked: true
            }, () => {
                const {onSelect} = this.props;
                onSelect && onSelect();
            });
        }

    }

    touchTapHandler(e) {

        e.preventDefault();

        const {disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly) {
            return;
        }

        const {onTouchTap} = this.props;
        onTouchTap && onTouchTap(e);

        switch (this.props.selectMode) {
            case SelectMode.MULTI_SELECT:
                this.checkboxChangeHandler(!this.state.checked);
                return;
            case SelectMode.SINGLE_SELECT:
                this.radioChangeHandler();
                return;
        }

    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.checked !== this.state.checked) {
            this.setState({
                checked: nextProps.checked
            });
        }
    }

    render() {

        const {

                index, className, style, theme, data, text, desc, iconCls, rightIconCls, tip, tipPosition,
                disabled, isLoading, disableTouchRipple, rippleDisplayCenter, renderer, itemRenderer, readOnly,

                selectTheme, selectMode, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                onMouseEnter, onMouseLeave

            } = this.props,
            {checked} = this.state,

            listItemClassName = (theme ? ` theme-${theme}` : '') + (checked ? ' activated' : '')
                + (className ? ' ' + className : ''),
            loadingIconPosition = (rightIconCls && !iconCls) ? 'right' : 'left';

        return (
            <TipProvider className='block'
                         text={tip}
                         tipPosition={tipPosition}>

                    {
                        selectMode === SelectMode.SINGLE_SELECT && (radioUncheckedIconCls || radioCheckedIconCls) ?
                            <Radio className="list-item-select"
                                   theme={selectTheme}
                                   checked={checked}
                                   disabled={disabled || isLoading}
                                   uncheckedIconCls={radioUncheckedIconCls}
                                   checkedIconCls={radioCheckedIconCls}
                                   disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        selectMode === SelectMode.MULTI_SELECT ?
                            <Checkbox className="list-item-select"
                                      theme={selectTheme}
                                      checked={checked}
                                      disabled={disabled || isLoading}
                                      uncheckedIconCls={checkboxUncheckedIconCls}
                                      checkedIconCls={checkboxCheckedIconCls}
                                      indeterminateIconCls={checkboxIndeterminateIconCls}
                                      disableTouchRipple={true}/>
                            :
                            null
                    }

                    {
                        isLoading && loadingIconPosition === 'left' ?

                                <CircularLoading className="button-loading-icon"
                                                 size="small"/>

                            :
                            (
                                iconCls ?
                                    <i className={`button-icon button-icon-left ${iconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        itemRenderer && typeof itemRenderer === 'function' ?
                            itemRenderer(data, index)
                            :
                            (
                                renderer && typeof renderer === 'function' ?
                                    renderer(data, index)
                                    :
                                    (
                                        desc ?

                                                    {text}

                                                    {desc}

                                            :
                                            text
                                    )
                            )
                    }

                    {
                        isLoading && loadingIconPosition === 'right' ?
                            <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                             size="small"/>
                            :
                            (
                                rightIconCls ?
                                    <i className={`button-icon button-icon-right ${rightIconCls}`}
                                       aria-hidden="true">
                                    :
                                    null
                            )
                    }

                    {
                        disableTouchRipple || readOnly ?
                            null
                            :
                            <TouchRipple ref="touchRipple"
                                         className={disabled || isLoading ? 'hidden' : ''}
                                         displayCenter={rippleDisplayCenter}/>
                    }

            </TipProvider>
        );

    }
};

ListItem.propTypes = {

    index: PropTypes.number,

    className: PropTypes.string,
    style: PropTypes.object,
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.object]),
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    text: PropTypes.any,
    desc: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    disableTouchRipple: PropTypes.bool,
    rippleDisplayCenter: PropTypes.bool,
    checked: PropTypes.bool,
    readOnly: PropTypes.bool,

    iconCls: PropTypes.string,
    rightIconCls: PropTypes.string,

    tip: PropTypes.string,
    tipPosition: PropTypes.oneOf(Util.enumerateValue(Position)),

    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    itemRenderer: PropTypes.func,
    renderer: PropTypes.func,

    onTouchTap: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func

};

ListItem.defaultProps = {

    index: 0,

    className: null,
    style: null,
    theme: Theme.DEFAULT,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    data: null,
    value: null,
    text: null,
    desc: null,

    disabled: false,
    isLoading: false,
    disableTouchRipple: false,
    rippleDisplayCenter: false,
    checked: false,
    readOnly: false,

    iconCls: null,
    rightIconCls: null,

    tip: null,
    tipPosition: Position.BOTTOM,

    radioUncheckedIconCls: '',
    radioCheckedIconCls: '',
    checkboxUncheckedIconCls: 'fa fa-square-o',
    checkboxCheckedIconCls: 'fa fa-check-square',
    checkboxIndeterminateIconCls: 'fa fa-minus-square'

};<|endoftext|>


<commit_before>module.exports = function(grunt) {

  grunt.initConfig({
    'json-minify': {
      build: {
        files: 'dist/mathmaps/*/*.js'
      }
    },
    gitclone: {
      'speech-rule-engine': {
        options: {
          repository: 'https://github.com/zorkow/speech-rule-engine.git',
          branch: 'v2.2.1',
          cwd: '.'
        }
      }
    },
    'uglify': {
      mathmaps: {
        files: {
          'dist/mathmaps/mathmaps_ie.js': 'dist/mathmaps/mathmaps_ie.js'
        }
      },
      build: {
        files: {
          'dist/accessibility-menu.js': 'extensions/accessibility-menu.js',
          'dist/explorer.js': 'extensions/explorer.js',
          'dist/auto-collapse.js': 'extensions/auto-collapse.js',
          'dist/collapsible.js': 'extensions/collapsible.js',
          'dist/semantic-enrich.js': 'extensions/semantic-enrich.js'
        },
        options: {
          beautify: {
            ascii_only: true
          }
        }
      }
    },
    shell: {
      clean_dist: {
        command: 'rm -rf dist'
      },
      make_dist: {
        command: 'mkdir -p dist'
      },
      clean_sre: {
        command: 'rm -rf speech-rule-engine'
      },
      clean_node: {
        command: 'rm -rf node_modules'
      },
      prepare: {
        command: [
          '<%= shell.clean_dist.command %>',
          '<%= shell.make_dist.command %>'
        ].join('&&')
      },
      clean: {
        command: [
          '<%= shell.clean_node.command %>',
          '<%= shell.clean_sre.command %>',
          '<%= shell.clean_dist.command %>'
        ].join('&&')
      },
      compile: {
        command: [
          'npm install',
          'npm install --only=dev',
          'npm install wicked-good-xpath',
          'make mathjax'
        ].join('&&'),
        options: {
          execOptions: {
            cwd: 'speech-rule-engine'
          }
        }
      },
      copy: [
        'cp speech-rule-engine/lib/mathjax-sre.js dist/mathjax-sre.js',
        'cp speech-rule-engine/node_modules/wicked-good-xpath/dist/wgxpath.install.js dist/',
        'cp -R speech-rule-engine/src/mathmaps dist/',
        'cp extensions/*.ogg dist/',
        'cp extensions/*.mp3 dist/',
        'rm dist/mathmaps/math_map.js',
        'rm dist/mathmaps/.htaccess'
      ].join('&&')
    }
  });

  // Cloning git repos.
  grunt.loadNpmTasks('grunt-git');
  // Run shell commands.
  grunt.loadNpmTasks('grunt-shell');
  // Minify JSON files.
  grunt.loadNpmTasks('grunt-json-minify');
  // Minify regular files.
  grunt.loadNpmTasks('grunt-contrib-uglify');

  grunt.registerTask('default', [
    'shell:prepare',
    'gitclone',
    'shell:compile',
    'shell:copy',
    'json-minify',
    'uglify',
    'shell:clean_sre'
  ]);

};
<commit_msg>Changes to grunt file.<commit_after>module.exports = function(grunt) {

  grunt.initConfig({
    gitclone: {
      'speech-rule-engine': {
        options: {
          repository: 'https://github.com/zorkow/speech-rule-engine.git',
          branch: 'v2.2.2',
          cwd: '.'
        }
      }
    },
    'uglify': {
      build: {
        files: {
          'dist/accessibility-menu.js': 'extensions/accessibility-menu.js',
          'dist/explorer.js': 'extensions/explorer.js',
          'dist/auto-collapse.js': 'extensions/auto-collapse.js',
          'dist/collapsible.js': 'extensions/collapsible.js',
          'dist/semantic-enrich.js': 'extensions/semantic-enrich.js'
        },
        options: {
          beautify: {
            ascii_only: true
          }
        }
      }
    },
    shell: {
      clean_dist: {
        command: 'rm -rf dist'
      },
      make_dist: {
        command: 'mkdir -p dist'
      },
      clean_sre: {
        command: 'rm -rf speech-rule-engine'
      },
      clean_node: {
        command: 'rm -rf node_modules'
      },
      prepare: {
        command: [
          '<%= shell.clean_dist.command %>',
          '<%= shell.make_dist.command %>'
        ].join('&&')
      },
      clean: {
        command: [
          '<%= shell.clean_node.command %>',
          '<%= shell.clean_sre.command %>',
          '<%= shell.clean_dist.command %>'
        ].join('&&')
      },
      compile: {
        command: [
          'npm install',
          'npm install --only=dev',
          'npm install wicked-good-xpath',
          'make mathjax',
          'make maps',
          'make iemaps'
        ].join('&&'),
        options: {
          execOptions: {
            cwd: 'speech-rule-engine'
          }
        }
      },
      copy: [
        'cp speech-rule-engine/lib/mathjax-sre.js dist/mathjax-sre.js',
        'cp speech-rule-engine/node_modules/wicked-good-xpath/dist/wgxpath.install.js dist/',
        'cp -R speech-rule-engine/lib/mathmaps dist/',
        'cp extensions/*.ogg dist/',
        'cp extensions/*.mp3 dist/'
      ].join('&&')
    }
  });

  // Cloning git repos.
  grunt.loadNpmTasks('grunt-git');
  // Run shell commands.
  grunt.loadNpmTasks('grunt-shell');
  // Minify regular files.
  grunt.loadNpmTasks('grunt-contrib-uglify');

  grunt.registerTask('default', [
    'shell:prepare',
    'gitclone',
    'shell:compile',
    'shell:copy',
    'uglify',
    'shell:clean_sre'
  ]);

};
<|endoftext|>


<commit_before>module.exports = function (grunt) {
  'use strict';

  grunt.initConfig({
    jshint: {
      options: {
        camelcase: true,
        eqeqeq: true,
        forin: true,
        immed: true,
        indent: 2,
        latedef: true,
        newcap: true,
        noarg: true,
        noempty: true,
        nonew: true,
        strict: true,
        trailing: true,
        undef: true,
        unused: true
      },
      build: {
        src: ['Gruntfile.js'],
        options: {
          node: true
        }
      },
      javascripts: {
        src: ['app/javascripts/**/*.js', 'test/**/*.js'],
        options: {
          browser: true,
          globals: {
            // Ember
            Ember: true,

            // RequireJS
            define: true,
            require: true,

            // Jasmine
            describe: true,
            expect: true,
            it: true
          }
        }
      }
    },
    clean: {
      tmp: ['tmp']
    },
    concat: {
      javascripts: {
        files: {
          'tmp/aurora-application.js': ['app/javascripts/**/*.js']
        }
      }
    },
    copy: {
      html: {
        files: {
          'tmp/index.html': ['app/index.html']
        }
      }
    },
    emberTemplates: {
      templates: {
        options: {
          templateBasePath: 'app',
          templateCompilerPath: 'bower_components/ember/ember-template-compiler.js',
          templateName: function (name) {
            return 'aurora' + name;
          },
          templateRegistration: function (name, contents) {
            return "define('" + name + "', [], function () { return " + contents + "});";
          },
          handlebarsPath: 'bower_components/handlebars/handlebars.js'
        },
        files: {
          'tmp/aurora-templates.js': ['app/templates/**/*.hbs']
        }
      }
    },
    connect: {
      server: {
        options: {
          base: ['bower_components', 'tmp'],
          livereload: true
        }
      }
    },
    karma: {
      options: {
        frameworks: ['jasmine'],
        browsers: ['PhantomJS'],
        files: [
          'bower_components/jquery/jquery.js',
          'bower_components/handlebars/handlebars.runtime.js',
          'bower_components/ember/ember.js',
          'bower_components/ember-data/ember-data.js',
          'bower_components/almond/almond.js',
          'app/javascripts/**/*.js',
          'tmp/aurora-templates.js',
          'test/**/*.js'
        ]
      },
      unit: {
        singleRun: true
      }
    },
    watch: {
      html: {
        options: {
          livereload: true
        },
        files: ['app/index.html'],
        tasks: ['build:html']
      },
      javascripts: {
        options: {
          livereload: true
        },
        files: ['app/javascripts/**/*.js'],
        tasks: ['build:javascripts']
      },
      templates: {
        options: {
          livereload: true
        },
        files: ['app/templates/**/*.hbs'],
        tasks: ['build:templates']
      },
      vendor: {
        options: {
          livereload: true
        },
        files: ['bower_components/**/*.js']
      },
      tests: {
        options: {
          livereload: false
        },
        files: [
          'bower_components/**/*.js',
          'app/javascripts/**/*.js',
          'app/templates/**/*.hbs',
          'test/**/*.js'
        ],
        tasks: ['build:templates', 'karma:unit']
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-ember-templates');
  grunt.loadNpmTasks('grunt-karma');

  grunt.registerTask('default', ['lint', 'test']);

  grunt.registerTask('build', 'Compile all source files.', ['build:html', 'build:javascripts', 'build:templates']);
  grunt.registerTask('build:html', 'Compile HTML.', ['copy:html']);
  grunt.registerTask('build:javascripts', 'Compile Javascripts.', ['concat:javascripts']);
  grunt.registerTask('build:templates', 'Compile Handlebars templates.', ['emberTemplates:templates']);

  grunt.registerTask('lint', 'Lint all Javascript files.', ['jshint']);

  grunt.registerTask('server', 'Start an Aurora development server.', ['clean', 'build', 'connect:server', 'watch']);

  grunt.registerTask('test', 'Run all tests.', ['build:templates', 'karma:unit']);
  grunt.registerTask('test:watch', 'Automatically run all tests when changes are made.', ['build:templates', 'karma:unit', 'watch:tests']);
};
<commit_msg>[build] Load test helper first.<commit_after>module.exports = function (grunt) {
  'use strict';

  grunt.initConfig({
    jshint: {
      options: {
        camelcase: true,
        eqeqeq: true,
        forin: true,
        immed: true,
        indent: 2,
        latedef: true,
        newcap: true,
        noarg: true,
        noempty: true,
        nonew: true,
        strict: true,
        trailing: true,
        undef: true,
        unused: true
      },
      build: {
        src: ['Gruntfile.js'],
        options: {
          node: true
        }
      },
      javascripts: {
        src: ['app/javascripts/**/*.js', 'test/**/*.js'],
        options: {
          browser: true,
          globals: {
            // Ember
            Ember: true,

            // RequireJS
            define: true,
            require: true,

            // Jasmine
            describe: true,
            expect: true,
            it: true
          }
        }
      }
    },
    clean: {
      tmp: ['tmp']
    },
    concat: {
      javascripts: {
        files: {
          'tmp/aurora-application.js': ['app/javascripts/**/*.js']
        }
      }
    },
    copy: {
      html: {
        files: {
          'tmp/index.html': ['app/index.html']
        }
      }
    },
    emberTemplates: {
      templates: {
        options: {
          templateBasePath: 'app',
          templateCompilerPath: 'bower_components/ember/ember-template-compiler.js',
          templateName: function (name) {
            return 'aurora' + name;
          },
          templateRegistration: function (name, contents) {
            return "define('" + name + "', [], function () { return " + contents + "});";
          },
          handlebarsPath: 'bower_components/handlebars/handlebars.js'
        },
        files: {
          'tmp/aurora-templates.js': ['app/templates/**/*.hbs']
        }
      }
    },
    connect: {
      server: {
        options: {
          base: ['bower_components', 'tmp'],
          livereload: true
        }
      }
    },
    karma: {
      options: {
        frameworks: ['jasmine'],
        browsers: ['PhantomJS'],
        files: [
          'bower_components/jquery/jquery.js',
          'bower_components/handlebars/handlebars.runtime.js',
          'bower_components/ember/ember.js',
          'bower_components/ember-data/ember-data.js',
          'bower_components/almond/almond.js',
          'test/test_helper.js',
          'app/javascripts/**/*.js',
          'tmp/aurora-templates.js',
          'test/**/*.js'
        ]
      },
      unit: {
        singleRun: true
      }
    },
    watch: {
      html: {
        options: {
          livereload: true
        },
        files: ['app/index.html'],
        tasks: ['build:html']
      },
      javascripts: {
        options: {
          livereload: true
        },
        files: ['app/javascripts/**/*.js'],
        tasks: ['build:javascripts']
      },
      templates: {
        options: {
          livereload: true
        },
        files: ['app/templates/**/*.hbs'],
        tasks: ['build:templates']
      },
      vendor: {
        options: {
          livereload: true
        },
        files: ['bower_components/**/*.js']
      },
      tests: {
        options: {
          livereload: false
        },
        files: [
          'bower_components/**/*.js',
          'app/javascripts/**/*.js',
          'app/templates/**/*.hbs',
          'test/**/*.js'
        ],
        tasks: ['build:templates', 'karma:unit']
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-ember-templates');
  grunt.loadNpmTasks('grunt-karma');

  grunt.registerTask('default', ['lint', 'test']);

  grunt.registerTask('build', 'Compile all source files.', ['build:html', 'build:javascripts', 'build:templates']);
  grunt.registerTask('build:html', 'Compile HTML.', ['copy:html']);
  grunt.registerTask('build:javascripts', 'Compile Javascripts.', ['concat:javascripts']);
  grunt.registerTask('build:templates', 'Compile Handlebars templates.', ['emberTemplates:templates']);

  grunt.registerTask('lint', 'Lint all Javascript files.', ['jshint']);

  grunt.registerTask('server', 'Start an Aurora development server.', ['clean', 'build', 'connect:server', 'watch']);

  grunt.registerTask('test', 'Run all tests.', ['build:templates', 'karma:unit']);
  grunt.registerTask('test:watch', 'Automatically run all tests when changes are made.', ['build:templates', 'karma:unit', 'watch:tests']);
};
<|endoftext|>


<commit_before>/*
 * Bristol
 * Copyright 2014-2016 Tom Shawver
 */

'use strict'

const request = require('request-promise')

/**
 * The Slack target posts to a Slack channel via POST to a webhook.
 * @param {Object} options Map of options for Slack
 * @param {string} options.webhook Slack webhook URL
 * @param {boolean} [options.format=false] Attempt to format the message
 * @param {boolean} [options.wrapBlock] Wrap log block in code/pre
 * @param {string} [options.icon_emoji] Slack emoji code for message icon, ex: :boom:
 * @param {string} [options.username] Username to display
 * @param {string} [options.channel] The channel to send to in Slack
 * @param {string} severity Unused
 * @param {Date} date Unused
 * @param {string} message The message to be sent to Slack
 */
module.exports = (options, severity, date, message) => {
  let text
  const nlIndex = message.indexOf('\n')
  const formatBlock = (block) => options.wrapBlock ? `\`\`\`${block}\`\`\`` : block
  // Perform formatting
  if (nlIndex > 0 && options.format) {
    // Message contains \n assume human formatter, split and format
    const str = message.substr(0, nlIndex)
    const block = message.slice(nlIndex + 1)
    text = `*${str}*\n${formatBlock(block)}`
  } else {
    // Send message as pre block
    text = formatBlock(message)
  }
  // Set options for request
  const opts = {
    uri: options.webhook,
    json: true,
    body: {
      icon_emoji: options.icon_emoji || undefined,
      username: options.username || undefined,
      channel: options.channel || undefined,
      text
    }
  }
  request.post(opts).catch((err) => {
    /* istanbul ignore next */
    console.error(`Error publishing log message to slack: ${err} - Message was: ${message}`)
  })
}
<commit_msg>feat(target-slack): cond-block indexOf check behind options.format<commit_after>/*
 * Bristol
 * Copyright 2014-2016 Tom Shawver
 */

'use strict'

const request = require('request-promise')

/**
 * The Slack target posts to a Slack channel via POST to a webhook.
 * @param {Object} options Map of options for Slack
 * @param {string} options.webhook Slack webhook URL
 * @param {boolean} [options.format=false] Attempt to format the message
 * @param {boolean} [options.wrapBlock] Wrap log block in code/pre
 * @param {string} [options.icon_emoji] Slack emoji code for message icon, ex: :boom:
 * @param {string} [options.username] Username to display
 * @param {string} [options.channel] The channel to send to in Slack
 * @param {string} severity Unused
 * @param {Date} date Unused
 * @param {string} message The message to be sent to Slack
 */
module.exports = (options, severity, date, message) => {
  let text
  const nlIndex = options.format ? message.indexOf('\n') : 0
  const formatBlock = (block) => options.wrapBlock ? `\`\`\`${block}\`\`\`` : block
  // Perform formatting
  if (nlIndex > 0) {
    // Message contains \n assume human formatter, split and format
    const str = message.substr(0, nlIndex)
    const block = message.slice(nlIndex + 1)
    text = `*${str}*\n${formatBlock(block)}`
  } else {
    // Send message as pre block
    text = formatBlock(message)
  }
  // Set options for request
  const opts = {
    uri: options.webhook,
    json: true,
    body: {
      icon_emoji: options.icon_emoji || undefined,
      username: options.username || undefined,
      channel: options.channel || undefined,
      text
    }
  }
  request.post(opts).catch((err) => {
    /* istanbul ignore next */
    console.error(`Error publishing log message to slack: ${err} - Message was: ${message}`)
  })
}
<|endoftext|>


<commit_before>"use strict"

module.exports = function( grunt ) {

  grunt.initConfig({

    copy: {
      src: {
        files: [
          { expand: true, cwd: "src/less", src: [ "*.css" ], dest: "tmp/css" },
          { expand: true, cwd: "src/images", src: [ "**" ], dest: "tmp/images" },
          { expand: true, cwd: "src", src: [ "*.html" ], dest: "tmp" }
        ]
      },
      tmp: {
        files: [
          { expand: true, cwd: "tmp", src: [ "*.html" ], dest: "dist" }
        ]
      }
    },

    connect: {
      options: {
        port: "8080",
        useAvailablePort: true,
        livereload: true,
        open: true
      },
      dev: {
        options: {
          base: "tmp/"
        }
      }
    },

    watch: {
      src: {
        files: [ "src/less/**/*.{css,less}", "src/images/**/*.{gif,png,jpg,jpeg}", "src/**/*.html" ],
        tasks: [ "dev:build" ],
        options: {
          livereload: true
        }
      }
    },

    less: {
      compile: {
        files: {
          "tmp/css/core.css": "src/less/core.less"
        }
      }
    },

    imagemin: {
      dist: {
        files: [
          { expand: true, cwd: "tmp/images", src: [ "**/*.{png,jpg,jpeg}" ], dest: "dist/images" }
        ]
      }
    },

    uncss: {
      dist: {
        files: {
          "tmp/css/core.css": [ "tmp/index.html" ]
        }
      }
    },

    htmlmin: {
      dist: {
        options: {
          removeComments: true
        },
        files: {
          "tmp/index.html": "tmp/index.html"
        }
      }
    },

    premailer: {
      options: {
        removeClasses: true
      },
      dist: {
        files: {
          "tmp/index.html": "tmp/index.html"
        }
      }
    }
  });

  grunt.registerTask( "default", "Compiles the distribution build", [
    "copy:src",
    "less:compile",
    "uncss:dist",
    "htmlmin:dist",
    "premailer:dist",
    "imagemin:dist",
    "copy:tmp"
  ]);

  grunt.registerTask( "dev:build", "Compiles the development build", [
    "copy:src",
    "less:compile",
    "copy:tmp"
  ]);

  grunt.registerTask( "dev", "Compiles the development environment", [
    "dev:build",
    "connect:dev",
    "watch:src"
  ]);

  grunt.loadNpmTasks( "grunt-contrib-copy" );
  grunt.loadNpmTasks( "grunt-contrib-connect" );
  grunt.loadNpmTasks( "grunt-contrib-watch" );
  grunt.loadNpmTasks( "grunt-contrib-imagemin" );
  grunt.loadNpmTasks( "grunt-uncss" );
  grunt.loadNpmTasks( "grunt-contrib-htmlmin" );
  grunt.loadNpmTasks( "grunt-premailer" );
  grunt.loadNpmTasks( "grunt-contrib-less" );

};
<commit_msg>Fix 'use strict' from function.<commit_after>module.exports = function( grunt ) {
  'use strict';

  grunt.initConfig({

    copy: {
      src: {
        files: [
          { expand: true, cwd: "src/less", src: [ "*.css" ], dest: "tmp/css" },
          { expand: true, cwd: "src/images", src: [ "**" ], dest: "tmp/images" },
          { expand: true, cwd: "src", src: [ "*.html" ], dest: "tmp" }
        ]
      },
      tmp: {
        files: [
          { expand: true, cwd: "tmp", src: [ "*.html" ], dest: "dist" }
        ]
      }
    },

    connect: {
      options: {
        port: "8080",
        useAvailablePort: true,
        livereload: true,
        open: true
      },
      dev: {
        options: {
          base: "tmp/"
        }
      }
    },

    watch: {
      src: {
        files: [ "src/less/**/*.{css,less}", "src/images/**/*.{gif,png,jpg,jpeg}", "src/**/*.html" ],
        tasks: [ "dev:build" ],
        options: {
          livereload: true
        }
      }
    },

    less: {
      compile: {
        files: {
          "tmp/css/core.css": "src/less/core.less"
        }
      }
    },

    imagemin: {
      dist: {
        files: [
          { expand: true, cwd: "tmp/images", src: [ "**/*.{png,jpg,jpeg}" ], dest: "dist/images" }
        ]
      }
    },

    uncss: {
      dist: {
        files: {
          "tmp/css/core.css": [ "tmp/index.html" ]
        }
      }
    },

    htmlmin: {
      dist: {
        options: {
          removeComments: true
        },
        files: {
          "tmp/index.html": "tmp/index.html"
        }
      }
    },

    premailer: {
      options: {
        removeClasses: true
      },
      dist: {
        files: {
          "tmp/index.html": "tmp/index.html"
        }
      }
    }
  });

  grunt.registerTask( "default", "Compiles the distribution build", [
    "copy:src",
    "less:compile",
    "uncss:dist",
    "htmlmin:dist",
    "premailer:dist",
    "imagemin:dist",
    "copy:tmp"
  ]);

  grunt.registerTask( "dev:build", "Compiles the development build", [
    "copy:src",
    "less:compile",
    "copy:tmp"
  ]);

  grunt.registerTask( "dev", "Compiles the development environment", [
    "dev:build",
    "connect:dev",
    "watch:src"
  ]);

  grunt.loadNpmTasks( "grunt-contrib-copy" );
  grunt.loadNpmTasks( "grunt-contrib-connect" );
  grunt.loadNpmTasks( "grunt-contrib-watch" );
  grunt.loadNpmTasks( "grunt-contrib-imagemin" );
  grunt.loadNpmTasks( "grunt-uncss" );
  grunt.loadNpmTasks( "grunt-contrib-htmlmin" );
  grunt.loadNpmTasks( "grunt-premailer" );
  grunt.loadNpmTasks( "grunt-contrib-less" );

};
<|endoftext|>


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

var Benchmark = require("benchmark"),
    sprintf = require("sprintf").sprintf;

var Digraph = require("..").Digraph;

var NODE_SIZES = [10, 100, 1000],
    EDGE_DENSITY = 0.2,
    KEY_SIZE = 10;

function runBenchmark(name, fn) {
  var options = {};
  options.onComplete = function(bench) {
    var target = bench.target,
        hz = target.hz,
        stats = target.stats,
        rme = stats.rme,
        samples = stats.sample.length,
        msg = sprintf("    %25s: %13s ops/sec \xb1 %s%% (%3d run(s) sampled)",
                      target.name,
                      Benchmark.formatNumber(hz.toFixed(2)),
                      rme.toFixed(2),
                      samples);
    console.log(msg);
  };
  options.onError = function(bench) {
    console.error("    " + bench.target.error);
  };
  new Benchmark(name, fn, options).run();
}

function keys(count) {
  var ks = [],
      k;
  for (var i = 0; i < count; ++i) {
    k = "";
    for (var j = 0; j < KEY_SIZE; ++j) {
      k += String.fromCharCode(97 + Math.floor(Math.random() * 26));
    }
    ks.push(k);
  }
  return ks;
}

function buildGraph(numNodes, edgeDensity) {
  var g = new Digraph(),
      numEdges = numNodes * numNodes * edgeDensity,
      ks = keys(numNodes);

  ks.forEach(function(k) { g.set(k); });

  for (var i = 0; i < numEdges; ++i) {
    var v, w;
    do {
      v = ks[Math.floor(Math.random() * ks.length)];
      w = ks[Math.floor(Math.random() * ks.length)];
    } while (g.hasEdge(v, w));
    g.setEdge(v, w);
  }
  return g;
}

runBenchmark("constructor", function () { new Digraph(); });

NODE_SIZES.forEach(function(size) {
  var g = buildGraph(size, EDGE_DENSITY),
      nodeIds = g.nodeIds(),
      node = nodeIds[Math.floor(Math.random() * nodeIds.length)],
      edges = g.edges(),
      edge = edges[Math.floor(Math.random() * edges.length)];

  runBenchmark("set(" + size + "," + EDGE_DENSITY + ")", function() {
    g.set("key", "label");
  });

  runBenchmark("get(" + size + "," + EDGE_DENSITY + ")", function() {
    g.get(node);
  });

  runBenchmark("setDelete(" + size + "," + EDGE_DENSITY + ")", function() {
    g.set("key");
    g.delete("key");
  });

  runBenchmark("setEdge(" + size + "," + EDGE_DENSITY + ")", function() {
    g.setEdge("from", "to", "label");
  });

  runBenchmark("getEdge(" + size + "," + EDGE_DENSITY + ")", function() {
    g.getEdge(edge.v, edge.w);
  });

  runBenchmark("setDeleteEdge(" + size + "," + EDGE_DENSITY + ")", function() {
    g.setEdge("from", "to", "label");
    g.deleteEdge("from", "to");
  });

  runBenchmark("copy(" + size + "," + EDGE_DENSITY + ")", function() {
    g.copy();
  });
});
<commit_msg>Some benchmark refactoring and more benchmark tests<commit_after>#!/usr/bin/env node

var Benchmark = require("benchmark"),
    sprintf = require("sprintf").sprintf;

var Digraph = require("..").Digraph;

var NODE_SIZES = [100],
    EDGE_DENSITY = 0.2,
    KEY_SIZE = 10;

function runBenchmark(name, fn) {
  var options = {};
  options.onComplete = function(bench) {
    var target = bench.target,
        hz = target.hz,
        stats = target.stats,
        rme = stats.rme,
        samples = stats.sample.length,
        msg = sprintf("    %25s: %13s ops/sec \xb1 %s%% (%3d run(s) sampled)",
                      target.name,
                      Benchmark.formatNumber(hz.toFixed(2)),
                      rme.toFixed(2),
                      samples);
    console.log(msg);
  };
  options.onError = function(bench) {
    console.error("    " + bench.target.error);
  };
  new Benchmark(name, fn, options).run();
}

function keys(count) {
  var ks = [],
      k;
  for (var i = 0; i < count; ++i) {
    k = "";
    for (var j = 0; j < KEY_SIZE; ++j) {
      k += String.fromCharCode(97 + Math.floor(Math.random() * 26));
    }
    ks.push(k);
  }
  return ks;
}

function buildGraph(numNodes, edgeDensity) {
  var g = new Digraph(),
      numEdges = numNodes * numNodes * edgeDensity,
      ks = keys(numNodes);

  ks.forEach(function(k) { g.set(k); });

  for (var i = 0; i < numEdges; ++i) {
    var v, w;
    do {
      v = ks[Math.floor(Math.random() * ks.length)];
      w = ks[Math.floor(Math.random() * ks.length)];
    } while (g.hasEdge(v, w));
    g.setEdge(v, w);
  }
  return g;
}

runBenchmark("constructor", function () { new Digraph(); });

NODE_SIZES.forEach(function(size) {
  var g = buildGraph(size, EDGE_DENSITY),
      nodeIds = g.nodeIds(),
      node = nodeIds[Math.floor(Math.random() * nodeIds.length)],
      edges = g.edges(),
      edge = edges[Math.floor(Math.random() * edges.length)],
      nameSuffix = "(" + size + "," + EDGE_DENSITY + ")";

  runBenchmark("set" + nameSuffix, function() {
    g.set("key", "label");
  });

  runBenchmark("get" + nameSuffix, function() {
    g.get(node);
  });

  runBenchmark("successors" + nameSuffix, function() {
    g.successors(node);
  });

  runBenchmark("predecessors" + nameSuffix, function() {
    g.predecessors(node);
  });

  runBenchmark("setDelete" + nameSuffix, function() {
    g.set("key");
    g.delete("key");
  });

  runBenchmark("setEdge" + nameSuffix, function() {
    g.setEdge("from", "to", "label");
  });

  runBenchmark("getEdge" + nameSuffix, function() {
    g.getEdge(edge.v, edge.w);
  });

  runBenchmark("outEdges" + nameSuffix, function() {
    g.outEdges(node);
  });

  runBenchmark("inEdges" + nameSuffix, function() {
    g.inEdges(node);
  });

  runBenchmark("setDeleteEdge" + nameSuffix, function() {
    g.setEdge("from", "to", "label");
    g.deleteEdge("from", "to");
  });

  runBenchmark("copy" + nameSuffix, function() {
    g.copy();
  });
});
<|endoftext|>


<commit_before>const NpmInstallPlugin = require("npm-install-webpack-plugin");
const detect = require("detect-port");
const webpack = require("webpack");
const commonPaths = require("./common-paths");

const config = {
  devtool: "eval-source-map",
  devServer: {
    port: 3002,
    open: true,
    host: "0.0.0.0",
    overlay: true,
    hot: true,
    useLocalIp: true,
    historyApiFallback: true
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "style-loader"
          },
          {
            loader: "css-loader",
            options: {
              importLoaders: 1
            }
          },
          {
            loader: "postcss-loader"
          }
        ]
      },
      {
        test: /\.jsx?$/,
        enforce: "pre",
        loader: "eslint-loader",
        options: {
          emitWarning: true
        }
      },
      {
        test: /.jsx?$/,
        use: {
          loader: "babel-loader"
        },
        exclude: /(node_modules|dist|build-utils|webpack.config.js)/
      }
    ]
  },
  plugins: [new NpmInstallPlugin(), new webpack.HotModuleReplacementPlugin()]
};

module.exports = config;
<commit_msg>Named Modules Plugin<commit_after>const NpmInstallPlugin = require("npm-install-webpack-plugin");
const detect = require("detect-port");
const webpack = require("webpack");
const commonPaths = require("./common-paths");

const config = {
  devtool: "eval-source-map",
  devServer: {
    port: 3002,
    open: true,
    host: "0.0.0.0",
    overlay: true,
    hot: true,
    useLocalIp: true,
    historyApiFallback: true
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "style-loader"
          },
          {
            loader: "css-loader",
            options: {
              importLoaders: 1
            }
          },
          {
            loader: "postcss-loader"
          }
        ]
      },
      {
        test: /\.jsx?$/,
        enforce: "pre",
        loader: "eslint-loader",
        options: {
          emitWarning: true
        }
      },
      {
        test: /.jsx?$/,
        use: {
          loader: "babel-loader"
        },
        exclude: /(node_modules|dist|build-utils|webpack.config.js)/
      }
    ]
  },
  plugins: [new NpmInstallPlugin(), new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin]
};

module.exports = config;
<|endoftext|>


<commit_before>function tcpServer(){
  var _tcpServer = chrome.sockets.tcpServer;
  this.option = {},
  this.socketId = 0,

  this.create = function(callback){
    _tcpServer.create(this.option, function(socketInfo){
      this.socketId = socketInfo.socketId;
      callback();
    }.bind(this));
  }.bind(this),

  this.update = function(){
    _tcpSever.update(this.socketId, newSocektOption, callback);
  }.bind(this),

  this.pause = function(isPaused, callback){
    _tcpServer.setPaused(this.socketId, isPaused, callback);
  }.bind(this),

  this.disconnect = function(callback){
    _tcpServer.disconnect(this.socketId, callback);
  }.bind(this),

  this.close = function(callback){
    _tcpServer.close(this.socketId, callback);
  }.bind(this),

  this.init = function(callback){
    this.create(callback);
  }.bind(this)
}
<commit_msg>add listen onAccept onAcceptError in tcpServer.js<commit_after>function tcpServer(){
  var _tcpServer = chrome.sockets.tcpServer;
  this.option = {},
  this.socketId = 0,

  this.create = function(callback){
    _tcpServer.create(this.option, function(socketInfo){
      this.socketId = socketInfo.socketId;
      callback();
    }.bind(this));
  }.bind(this),

  this.update = function(){
    _tcpSever.update(this.socketId, newSocektOption, callback);
  }.bind(this),

  this.pause = function(isPaused, callback){
    _tcpServer.setPaused(this.socketId, isPaused, callback);
  }.bind(this),

  this.disconnect = function(callback){
    _tcpServer.disconnect(this.socketId, callback);
  }.bind(this),

  this.close = function(callback){
    _tcpServer.close(this.socketId, callback);
  }.bind(this),

  this.init = function(callback){
    this.create(callback);
  }.bind(this),

  this.listen = function(address, port, callback){
    _tcpServer.listen(this.socketId, address, port, function(code){
      if(code < 0){
        this.error(code);
        return false;
      }else{
        _tcpServer.onAccept.addListener(function(info){
          if(info.socketId == this.socketId){
            this.accept(info);
          }
        }.bind(this));
        _tcpServer.onAcceptError.addListen(function(info){
          if(info.socketId == this.socketId){
            this.error(info.resultCode);
          }
        }.bind(this));
        callback();
      }
    }.bind(this));
  }.bind(this),

  this.error = function(code){
    console.log('An error occurred with code ' + code);
  },

  this.accept = function(info){
    console.log('New connection.');
  }

}
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict'
var Bluebird = require('bluebird')
var simpleFetch = require('./simple-fetch')
var fs = require('fs')
var TOML = require('./toml.js')
var getFic = require('./get-fic.js')
var ficToEpub = require('./fic-to-epub.js')
var Gauge = require('gauge')
var TrackerGroup = require('are-we-there-yet').TrackerGroup
var Tracker = require('are-we-there-yet').Tracker
var spinWith = require('./spin-with.js')
var TOML = require('./toml.js')
var filenameize = require('./filenameize.js')
var ms = require('mississippi')
var pipe = Bluebird.promisify(ms.pipe)
var argv = require('yargs')
  .usage('Usage: $0 <fic> [--xf_session=<sessionid>] [--xf_user=<userid>]')
  .demand(1, '<fic> - A fic metadata file to fetch a fic for. Typically ends in .fic.toml')
  .describe('xf_session', 'value of your xf_session variable')
  .describe('xf_user', 'value of your xf_session variable')
  .argv

main()

function main () {
  var cookie = argv.xf_session
  var user = argv.xf_user
  var fetchOpts = {cacheBreak: false}
  if (cookie) {
    if (!fetchOpts.headers) fetchOpts.headers = {}
    fetchOpts.headers.Cookie = 'xf_session=' + cookie
  }
  if (user) {
    if (!fetchOpts.headers) fetchOpts.headers = {}
    fetchOpts.headers.Cookie += '; xf_user=' + user
  }
  var fetchWithCache = simpleFetch(fetchOpts)
  var fetch = simpleFetch(fetchOpts)
  var gauge = new Gauge()
  var trackerGroup = new TrackerGroup()
  trackerGroup.on('change', function (name, completed) {
    gauge.show({completed: completed})
  })
  var trackers = argv._.map(function () { return trackerGroup.newItem(1) })
  var spin = spinWith(gauge)

  return Bluebird.each(argv._, fetchFic)

  function fetchFic (ficFile, ii) {
    var fic = TOML.parse(fs.readFileSync(ficFile, 'utf8'))
    fic.chapters.forEach(function (chapter, ii) {
      chapter.order = ii
    })

    var tracker = trackers[ii]
    gauge.show(fic.title + ': Fetching fic')
    var fetchWithOpts = function (url) {
      return spin(fetchWithCache(url)).tap(function () {
        tracker.completeWork(1)
      })
    }
    var filename = filenameize(fic.title) + '.epub'
    tracker.addWork(fic.chapters.length)

    return pipe(
      getFic(fetchWithOpts, fic.chapters, 1),
      ficToEpub(fic),
      fs.createWriteStream(filename)
    ).tap(function () {
      tracker.finish()
      gauge.hide()
      console.log(filename)
    })
  }
}
<commit_msg>Get rid of redundent module load<commit_after>#!/usr/bin/env node
'use strict'
var Bluebird = require('bluebird')
var simpleFetch = require('./simple-fetch')
var fs = require('fs')
var TOML = require('./toml.js')
var getFic = require('./get-fic.js')
var ficToEpub = require('./fic-to-epub.js')
var Gauge = require('gauge')
var TrackerGroup = require('are-we-there-yet').TrackerGroup
var Tracker = require('are-we-there-yet').Tracker
var spinWith = require('./spin-with.js')
var filenameize = require('./filenameize.js')
var ms = require('mississippi')
var pipe = Bluebird.promisify(ms.pipe)
var argv = require('yargs')
  .usage('Usage: $0 <fic> [--xf_session=<sessionid>] [--xf_user=<userid>]')
  .demand(1, '<fic> - A fic metadata file to fetch a fic for. Typically ends in .fic.toml')
  .describe('xf_session', 'value of your xf_session variable')
  .describe('xf_user', 'value of your xf_session variable')
  .argv

main()

function main () {
  var cookie = argv.xf_session
  var user = argv.xf_user
  var fetchOpts = {cacheBreak: false}
  if (cookie) {
    if (!fetchOpts.headers) fetchOpts.headers = {}
    fetchOpts.headers.Cookie = 'xf_session=' + cookie
  }
  if (user) {
    if (!fetchOpts.headers) fetchOpts.headers = {}
    fetchOpts.headers.Cookie += '; xf_user=' + user
  }
  var fetchWithCache = simpleFetch(fetchOpts)
  var fetch = simpleFetch(fetchOpts)
  var gauge = new Gauge()
  var trackerGroup = new TrackerGroup()
  trackerGroup.on('change', function (name, completed) {
    gauge.show({completed: completed})
  })
  var trackers = argv._.map(function () { return trackerGroup.newItem(1) })
  var spin = spinWith(gauge)

  return Bluebird.each(argv._, fetchFic)

  function fetchFic (ficFile, ii) {
    var fic = TOML.parse(fs.readFileSync(ficFile, 'utf8'))
    fic.chapters.forEach(function (chapter, ii) {
      chapter.order = ii
    })

    var tracker = trackers[ii]
    gauge.show(fic.title + ': Fetching fic')
    var fetchWithOpts = function (url) {
      return spin(fetchWithCache(url)).tap(function () {
        tracker.completeWork(1)
      })
    }
    var filename = filenameize(fic.title) + '.epub'
    tracker.addWork(fic.chapters.length)

    return pipe(
      getFic(fetchWithOpts, fic.chapters, 1),
      ficToEpub(fic),
      fs.createWriteStream(filename)
    ).tap(function () {
      tracker.finish()
      gauge.hide()
      console.log(filename)
    })
  }
}
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import PropTypes from 'prop-types';

import TableCell from '../_TableCell';

export default class Tbody extends Component {

	constructor(props) {

		super(props);

		this.contentRenderer = this::this.contentRenderer;

	}

	stringContentRenderer(data, template) {

		if (!data) {
			return template;
		}

		if (/\$\{.+\}/.test(template)) { // 配置的 renderer 中包含 ${...}，用数据替换
			let result = template;
			for (let key in data) {
				result = result.replace(new RegExp('\\$\\{' + key + '\\}', 'g'), data[key]);
			}
			return result;
		} else { // 直接显示字段
			return data[template];
		}

	}

	contentRenderer(renderer, colIndex) {

		const {rowIndex, data} = this.props;

		switch (typeof renderer) {
			case 'string':
				return this.stringContentRenderer(data, renderer);
			case 'function':
				return renderer(data, rowIndex, colIndex);
			default:
				return renderer;
		}

	}

	render() {

		const {columns} = this.props;

		return (

				{
					columns.map((col, colIndex) => {
						return <TableCell key={colIndex}
						                  className={col.className}
						                  style={col.style}
						                  data={this.contentRenderer(col.renderer, colIndex)}/>
					})
				}

		);

	}
};

Tbody.propTypes = {
	rowIndex: PropTypes.number,
	columns: PropTypes.array,
	data: PropTypes.object
};

Tbody.defaultProps = {
	rowIndex: 0,
	columns: [],
	data: {}
};<commit_msg>TableRow style bug fixed<commit_after>import React, {Component} from 'react';
import PropTypes from 'prop-types';

import TableCell from '../_TableCell';

export default class Tbody extends Component {

	constructor(props) {

		super(props);

		this.contentRenderer = this::this.contentRenderer;

	}

	stringContentRenderer(data, template) {

		if (!data) {
			return template;
		}

		if (/\$\{.+\}/.test(template)) { // 配置的 renderer 中包含 ${...}，用数据替换
			let result = template;
			for (let key in data) {
				result = result.replace(new RegExp('\\$\\{' + key + '\\}', 'g'), data[key]);
			}
			return result;
		} else { // 直接显示字段
			return data[template];
		}

	}

	contentRenderer(renderer, colIndex) {

		const {rowIndex, data} = this.props;

		switch (typeof renderer) {
			case 'string':
				return this.stringContentRenderer(data, renderer);
			case 'function':
				return renderer(data, rowIndex, colIndex);
			default:
				return renderer;
		}

	}

	render() {

		const {columns} = this.props;

		return (

				{
					columns.map((col, colIndex) => {
						return <TableCell key={colIndex}
						                  className={col.cellClassName}
						                  style={col.cellStyle}
						                  data={this.contentRenderer(col.renderer, colIndex)}/>
					})
				}

		);

	}
};

Tbody.propTypes = {
	rowIndex: PropTypes.number,
	columns: PropTypes.array,
	data: PropTypes.object
};

Tbody.defaultProps = {
	rowIndex: 0,
	columns: [],
	data: {}
};<|endoftext|>


<commit_before>module.exports = function(grunt) {
  'use strict';

  var PATH_ASSETS = 'src';
  var PATH_DEPLOY_ASSETS = 'public';

  // ==========================================================================
  // Project configuration
  // ==========================================================================
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    // clean build directory
    clean: [PATH_DEPLOY_ASSETS],

    copy: {
      main: {
        expand: true,
        cwd: PATH_ASSETS,
        src: '**',
        dest: PATH_DEPLOY_ASSETS
      }
    },

    requirejs: {
      compile: {
        options: {
          appDir: PATH_ASSETS,
          dir: PATH_DEPLOY_ASSETS,
          baseUrl: './js',
          //configuration file
          mainConfigFile: PATH_ASSETS + '/js/main.js',
          // optimize javascript files with uglifyjs
          optimize: 'uglify',
          // define dependencies
          modules: [
            {
              name: 'main'
            }
          ]
        }
      }
    },

    // js linting options
    jshint: {
      all: ['Gruntfile.js', PATH_ASSETS + '/js/main.js', PATH_ASSETS + '/js/app/**/*.js',
      '!' + PATH_ASSETS + '/js/app/templates.js']
    },

    concat: {
      css: {
        src: [PATH_ASSETS + '/css/*.css'],
        dest: PATH_DEPLOY_ASSETS + '/css/<%= pkg.name %>-<%= pkg.version %>.concat.css'
      }
    },

    cssmin: {
      my_target: {
        src: PATH_DEPLOY_ASSETS + '/css/<%= pkg.name %>-<%= pkg.version %>.concat.css',
        dest: PATH_DEPLOY_ASSETS + '/css/<%= pkg.name %>.min-<%= pkg.version %>.css'
      }
    },

    csslint: {
      lax: {
        rules: {
          'box-sizing': false,
          'adjoining-classes': false
        },
        src: [PATH_ASSETS + '/css/*.css', '!' + PATH_ASSETS + '/css/normalize.css']
      }
    },

    imagemin: {
      png: {
        options: {
          optimizationLevel: 7
        },
        files: [
          {
            expand: true,
            cwd: PATH_ASSETS + '/img',
            src: ['**/*.png'],
            dest: PATH_DEPLOY_ASSETS + '/img',
            ext: '.png'
          }
        ]
      },
      jpg: {
        options: {
          progressive: true
        },
        files: [
          {
            expand: true,
            cwd: PATH_ASSETS + '/img',
            src: ['**/*.jpg'],
            dest: PATH_DEPLOY_ASSETS + '/img',
            ext: '.jpg'
          }
        ]
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-css');
  grunt.loadNpmTasks('grunt-contrib-imagemin');

  // default build task
  grunt.registerTask('default', 'build:dev');

  //build tasks
  grunt.registerTask('build:prod', ['clean', 'jshint:all', 'csslint:lax', 'requirejs', 'concat', 'cssmin', 'imagemin']);
  grunt.registerTask('build:dev', ['clean', 'copy', 'jshint:all', 'csslint:lax', 'concat', 'cssmin']);
};
<commit_msg>Esteban. Improved RequireJS optimization config<commit_after>module.exports = function(grunt) {
  'use strict';

  var PATH_ASSETS = 'src';
  var PATH_DEPLOY_ASSETS = 'public';
  var PATH_GENERATED_JST = PATH_ASSETS + '/js/app/templates.js';

  // ==========================================================================
  // Project configuration
  // ==========================================================================
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    // clean build directory
    clean: [PATH_DEPLOY_ASSETS],

    copy: {
      main: {
        expand: true,
        cwd: PATH_ASSETS,
        src: '**',
        dest: PATH_DEPLOY_ASSETS
      }
    },

    requirejs: {
      compile: {
        options: {
          appDir: PATH_ASSETS,
          dir: PATH_DEPLOY_ASSETS,
          baseUrl: './js',
          mainConfigFile: PATH_ASSETS + '/js/main.js',
          optimize: 'uglify2',
          optimizeCss: 'none',
          modules: [
            {
              name: 'main'
            }
          ],
          skipDirOptimize: true
        }
      }
    },

    // js linting options
    jshint: {
      all: ['Gruntfile.js', PATH_ASSETS + '/js/main.js', PATH_ASSETS + '/js/app/**/*.js']
    },

    handlebars: {
      compile: {
        options: {
          namespace: 'JST',
          amd: true,
          processName: function(filename) {
            var pieces = filename.split('/');
            return pieces[pieces.length - 1];
          }
        },
        files: {
          PATH_GENERATED_JST: PATH_ASSETS + '/js/**/*.hbs'
        }
      }
    },

    concat: {
      css: {
        src: [PATH_ASSETS + '/css/*.css'],
        dest: PATH_DEPLOY_ASSETS + '/css/<%= pkg.name %>-<%= pkg.version %>.concat.css'
      }
    },

    cssmin: {
      my_target: {
        src: PATH_DEPLOY_ASSETS + '/css/<%= pkg.name %>-<%= pkg.version %>.concat.css',
        dest: PATH_DEPLOY_ASSETS + '/css/<%= pkg.name %>.min-<%= pkg.version %>.css'
      }
    },

    csslint: {
      lax: {
        rules: {
          'box-sizing': false,
          'adjoining-classes': false
        },
        src: [PATH_ASSETS + '/css/*.css', '!' + PATH_ASSETS + '/css/normalize.css']
      }
    },

    imagemin: {
      png: {
        options: {
          optimizationLevel: 7
        },
        files: [
          {
            expand: true,
            cwd: PATH_ASSETS + '/img',
            src: ['**/*.png'],
            dest: PATH_DEPLOY_ASSETS + '/img',
            ext: '.png'
          }
        ]
      },
      jpg: {
        options: {
          progressive: true
        },
        files: [
          {
            expand: true,
            cwd: PATH_ASSETS + '/img',
            src: ['**/*.jpg'],
            dest: PATH_DEPLOY_ASSETS + '/img',
            ext: '.jpg'
          }
        ]
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-css');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadNpmTasks('grunt-contrib-handlebars');

  // default build task
  grunt.registerTask('default', 'build:dev');

  //build tasks
  grunt.registerTask('build:prod', ['clean', 'jshint:all', 'handlebars', 'csslint:lax', 'requirejs', 'concat', 'cssmin', 'imagemin']);
  grunt.registerTask('build:dev', ['clean', 'handlebars', 'copy', 'jshint:all', 'csslint:lax', 'concat', 'cssmin']);
};
<|endoftext|>