<commit_before>var settingsManager = new SettingsManager();

Array.prototype.unique = function() {
	var a = [];
	var l = this.length;
	for(var i=0; i<l; i++) {
		for(var j=i+1; j<l; j++) {
			if (this[i].url === this[j].url)
				j = ++i;
		}
		a.push(this[i]);
	}
	return a;
};

function openTab(urls, delay, windowId, tabPosition, closeTime) {
	var obj = {
			windowId: windowId,
			url: urls.shift().url,
			selected: false
	};

	if(tabPosition != null) {
		obj.index = tabPosition;
		tabPosition++;
	}

	chrome.tabs.create(obj, function(tab) {
		if(closeTime > 0) {
			window.setTimeout(function() {
				chrome.tabs.remove(tab.id);
			}, closeTime*1000);
		}
	});

	if(urls.length > 0) {
		window.setTimeout(function() {openTab(urls, delay, windowId, tabPosition, closeTime)}, delay*1000);
	}

}

function copyToClipboard( text ){
    var copyDiv = document.createElement("textarea");
    copyDiv.contentEditable = true;
    document.body.appendChild(copyDiv);
    copyDiv.innerHTML = text;
    copyDiv.unselectable = "off";
    copyDiv.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy", false, null);
    document.body.removeChild(copyDiv);
}

function pad(number, length) {
	var str = "" + number;
	while (str.length < length) {
		str = "0" + str;
	}

	return str;
}

function timeConverter(a){
	var year = a.getFullYear();
	var month = pad(a.getMonth()+1, 2)
	var day = pad(a.getDate(), 2);
	var hour = pad(a.getHours(),2);
	var min = pad(a.getMinutes(),2);
	var sec = pad(a.getSeconds(),2);
	var time = year+"-"+month+"-"+day+" "+hour+":"+min+":"+sec;
	return time;
}

function handleRequests(request, sender, callback){
	switch(request.message) {
	case "activate":
		if(request.setting.options.block) {
			request.urls = request.urls.unique();
		}

		if(request.urls.length === 0) {
			return;
		}

		if(request.setting.options.reverse) {
			request.urls.reverse();
		}

		switch(request.setting.action) {
		case "copy":
			var text = "";
			for (let i = 0; i < request.urls.length; i++) {
				switch(request.setting.options.copy) {
				case "0":
					text += request.urls[i].title+"\t"+request.urls[i].url+"\n";
					break;
				case "1":
					text += request.urls[i].url+"\n";
					break;
				case "2":
					text += request.urls[i].title+"\n";
					break;
				case "3":
					text += ''+request.urls[i].title+"\n";
					break;
				case "4":
					text += '
'+request.urls[i].title+"
\n";
					break;
				case "5":
					text += "["+request.urls[i].title+"]("+request.urls[i].url+")\n";
					break;
				}
			}

			if(request.setting.options.copy == 4) {
				text = "
\n"+text+"
\n"
			}

			copyToClipboard(text);
			break;
		case "bm":
			chrome.bookmarks.getTree(
				function(bookmarkTreeNodes) {
					// make assumption that bookmarkTreeNodes[0].children[1] refers to the "other bookmarks" folder
					// as different languages will not use the english name to refer to the folder
					chrome.bookmarks.create({"parentId": bookmarkTreeNodes[0].children[1].id, "title": "Linkclump "+timeConverter(new Date())},
						function(newFolder) {
							for (let j = 0; j < request.urls.length; j++) {
								chrome.bookmarks.create({"parentId": newFolder.id,
									"title": request.urls[j].title,
									"url": request.urls[j].url});
							}
						}
					);
				}
			);

			break;
		case "win":
			chrome.windows.getCurrent(function(currentWindow){

				chrome.windows.create({url: request.urls.shift().url, "focused" : !request.setting.options.unfocus}, function(window){
					if(request.urls.length > 0) {
						openTab(request.urls, request.setting.options.delay, window.id, null, 0);
					}
				});

				if(request.setting.options.unfocus) {
					chrome.windows.update(currentWindow.id, {"focused": true});
				}
			});
			break;
		case "tabs":
			chrome.tabs.get(sender.tab.id, function(tab) {
				chrome.windows.getCurrent(function(window){
					var tab_index = null;

					if(!request.setting.options.end) {
						tab_index = tab.index+1;
					}

					openTab(request.urls, request.setting.options.delay, window.id, tab_index, request.setting.options.close);
				})
			});
			break;
		}

		break;
	case "init":
		callback(settingsManager.load());
		break;
	case "update":
		settingsManager.save(request.settings);

		chrome.windows.getAll({
			populate: true
		}, function(windowList){
			windowList.forEach(function(window){
				window.tabs.forEach(function(tab){
					chrome.tabs.sendMessage(tab.id, {
						message: "update",
						settings: settingsManager.load()
					}, null);
				})
			})
		});

		break;
	}
}

chrome.extension.onMessage.addListener(handleRequests)

if (!settingsManager.isInit()) {
	// initialize settings manager with defaults and to stop this appearing again
	settingsManager.init();

	// inject Linkclump into windows currently open to make it just work
	chrome.windows.getAll({ populate: true }, function(windows) {
		for (var i = 0; i < windows.length; ++i) {
			for (var j = 0; j < windows[i].tabs.length; ++j) {
				if (!/^https?:\/\//.test(windows[i].tabs[j].url)) continue;
				chrome.tabs.executeScript(windows[i].tabs[j].id, { file: "linkclump.js" });
			}
		}
	});

	// pop up window to show tour and options page
	chrome.windows.create({
		url: document.location.protocol + "//" + document.location.host + "/pages/options.html?init=true",
		width: 800,
		height: 850,
		left: screen.width / 2 - 800 / 2,
		top: screen.height / 2 - 700 / 2
	});
} else if (!settingsManager.isLatest()) {
	settingsManager.update();
}

<commit_msg>fix: cheome.tabs.create API change<commit_after>var settingsManager = new SettingsManager();

Array.prototype.unique = function() {
	var a = [];
	var l = this.length;
	for(var i=0; i<l; i++) {
		for(var j=i+1; j<l; j++) {
			if (this[i].url === this[j].url)
				j = ++i;
		}
		a.push(this[i]);
	}
	return a;
};

function openTab(urls, delay, windowId, tabPosition, closeTime) {
	var obj = {
			windowId: windowId,
			url: urls.shift().url,
			active: false
	};

	if(tabPosition != null) {
		obj.index = tabPosition;
		tabPosition++;
	}

	chrome.tabs.create(obj, function(tab) {
		if(closeTime > 0) {
			window.setTimeout(function() {
				chrome.tabs.remove(tab.id);
			}, closeTime*1000);
		}
	});

	if(urls.length > 0) {
		window.setTimeout(function() {openTab(urls, delay, windowId, tabPosition, closeTime)}, delay*1000);
	}

}

function copyToClipboard( text ){
    var copyDiv = document.createElement("textarea");
    copyDiv.contentEditable = true;
    document.body.appendChild(copyDiv);
    copyDiv.innerHTML = text;
    copyDiv.unselectable = "off";
    copyDiv.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy", false, null);
    document.body.removeChild(copyDiv);
}

function pad(number, length) {
	var str = "" + number;
	while (str.length < length) {
		str = "0" + str;
	}

	return str;
}

function timeConverter(a){
	var year = a.getFullYear();
	var month = pad(a.getMonth()+1, 2)
	var day = pad(a.getDate(), 2);
	var hour = pad(a.getHours(),2);
	var min = pad(a.getMinutes(),2);
	var sec = pad(a.getSeconds(),2);
	var time = year+"-"+month+"-"+day+" "+hour+":"+min+":"+sec;
	return time;
}

function handleRequests(request, sender, callback){
	switch(request.message) {
	case "activate":
		if(request.setting.options.block) {
			request.urls = request.urls.unique();
		}

		if(request.urls.length === 0) {
			return;
		}

		if(request.setting.options.reverse) {
			request.urls.reverse();
		}

		switch(request.setting.action) {
		case "copy":
			var text = "";
			for (let i = 0; i < request.urls.length; i++) {
				switch(request.setting.options.copy) {
				case "0":
					text += request.urls[i].title+"\t"+request.urls[i].url+"\n";
					break;
				case "1":
					text += request.urls[i].url+"\n";
					break;
				case "2":
					text += request.urls[i].title+"\n";
					break;
				case "3":
					text += ''+request.urls[i].title+"\n";
					break;
				case "4":
					text += '
'+request.urls[i].title+"
\n";
					break;
				case "5":
					text += "["+request.urls[i].title+"]("+request.urls[i].url+")\n";
					break;
				}
			}

			if(request.setting.options.copy == 4) {
				text = "
\n"+text+"
\n"
			}

			copyToClipboard(text);
			break;
		case "bm":
			chrome.bookmarks.getTree(
				function(bookmarkTreeNodes) {
					// make assumption that bookmarkTreeNodes[0].children[1] refers to the "other bookmarks" folder
					// as different languages will not use the english name to refer to the folder
					chrome.bookmarks.create({"parentId": bookmarkTreeNodes[0].children[1].id, "title": "Linkclump "+timeConverter(new Date())},
						function(newFolder) {
							for (let j = 0; j < request.urls.length; j++) {
								chrome.bookmarks.create({"parentId": newFolder.id,
									"title": request.urls[j].title,
									"url": request.urls[j].url});
							}
						}
					);
				}
			);

			break;
		case "win":
			chrome.windows.getCurrent(function(currentWindow){

				chrome.windows.create({url: request.urls.shift().url, "focused" : !request.setting.options.unfocus}, function(window){
					if(request.urls.length > 0) {
						openTab(request.urls, request.setting.options.delay, window.id, null, 0);
					}
				});

				if(request.setting.options.unfocus) {
					chrome.windows.update(currentWindow.id, {"focused": true});
				}
			});
			break;
		case "tabs":
			chrome.tabs.get(sender.tab.id, function(tab) {
				chrome.windows.getCurrent(function(window){
					var tab_index = null;

					if(!request.setting.options.end) {
						tab_index = tab.index+1;
					}

					openTab(request.urls, request.setting.options.delay, window.id, tab_index, request.setting.options.close);
				})
			});
			break;
		}

		break;
	case "init":
		callback(settingsManager.load());
		break;
	case "update":
		settingsManager.save(request.settings);

		chrome.windows.getAll({
			populate: true
		}, function(windowList){
			windowList.forEach(function(window){
				window.tabs.forEach(function(tab){
					chrome.tabs.sendMessage(tab.id, {
						message: "update",
						settings: settingsManager.load()
					}, null);
				})
			})
		});

		break;
	}
}

chrome.extension.onMessage.addListener(handleRequests)

if (!settingsManager.isInit()) {
	// initialize settings manager with defaults and to stop this appearing again
	settingsManager.init();

	// inject Linkclump into windows currently open to make it just work
	chrome.windows.getAll({ populate: true }, function(windows) {
		for (var i = 0; i < windows.length; ++i) {
			for (var j = 0; j < windows[i].tabs.length; ++j) {
				if (!/^https?:\/\//.test(windows[i].tabs[j].url)) continue;
				chrome.tabs.executeScript(windows[i].tabs[j].id, { file: "linkclump.js" });
			}
		}
	});

	// pop up window to show tour and options page
	chrome.windows.create({
		url: document.location.protocol + "//" + document.location.host + "/pages/options.html?init=true",
		width: 800,
		height: 850,
		left: screen.width / 2 - 800 / 2,
		top: screen.height / 2 - 700 / 2
	});
} else if (!settingsManager.isLatest()) {
	settingsManager.update();
}

<|endoftext|>


<commit_before>import path from 'path';
import url from 'url';
import {app, ipcMain, Menu, Tray} from 'electron';
import {autoUpdater} from 'electron-updater';

import devMenuTemplate from './menu/dev-menu-template';
import createWindow from './helpers/window';
import {checkAlert, checkInvasion} from './api';
import store from './helpers/config';

import env from './env';

const log = require('electron-log');
const makeDir = require('make-dir');
const got = require('got');
const AutoLaunch = require('auto-launch');
const osLocale = require('os-locale');
const ts = require('unix-timestamp');
const WorldState = require('warframe-worldstate-parser');
const unhandled = require('electron-unhandled');

unhandled();

require('electron-context-menu')();

const appAutoLauncher = new AutoLaunch({
	name: app.getName(),
	isHidden: true
});

let mainWindow;

if (env.name !== 'production') {
	const userDataPath = app.getPath('userData');
	app.setPath('userData', `${userDataPath} (${env.name})`);
}

makeDir.sync(app.getPath('userData'));
log.transports.file.file = app.getPath('userData') + '/log.log';
autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = 'debug';
log.info('App starting...');

const setApplicationMenu = () => {
	const menus = [];
	menus.push(devMenuTemplate);
	Menu.setApplicationMenu(Menu.buildFromTemplate(menus));
};

const updateLog = (msg, status) => {
	let d = new Date();
	const locale = osLocale.sync().replace('_', '-');
	d = d.toLocaleString(locale, {
		hour: 'numeric',
		minute: 'numeric',
		second: 'numeric'
	});
	let logLine = `[${d}] `;
	logLine += msg;
	mainWindow.webContents.send('log-data', logLine, status);
};

let interval;
let slowInterval;

const shouldQuit = app.makeSingleInstance(() => {
	if (mainWindow) {
		if (!mainWindow.isVisible()) {
			mainWindow.show();
		}
		mainWindow.focus();
	}
});

if (shouldQuit) {
	app.quit();
}

app.on('ready', () => {
	mainWindow = createWindow('main', {
		width: 1000,
		height: 600,
		show: false,
		backgroundColor: '#1b1e23',
		maximizable: false,
		fullscreenable: false,
		resizable: false,
		webPreferences: {
			devtools: false
		}
	});

	mainWindow.loadURL(url.format({
		pathname: path.join(__dirname, '/app.html'),
		protocol: 'file:',
		slashes: true
	}));

	if (env.name === 'development') {
		setApplicationMenu();
		mainWindow.openDevTools({mode: 'undocked'});
	} else {
		mainWindow.setMenu(null);
	}

	updateCheck();
	setInterval(() => {
		updateCheck();
	}, 86400000);

	const tray = new Tray(path.join(__dirname, '/icon.ico'));

	mainWindow.webContents.on('did-finish-load', async () => {
		updateLog(`Warframe Alerts v${app.getVersion()} Started`);
		mainWindow.webContents.send('filter-data', store.get('filters'));
		checkApi();
		setInterval(async () => {
			checkApi();
		}, 60000);
	});

	let autoStartEnabled;

	appAutoLauncher.isEnabled().then(isEnabled => {
		if (isEnabled) {
			autoStartEnabled = true;
		} else {
			autoStartEnabled = false;
		}

		const logUnmatched = store.get('app.logUnmatched', 'false');
		const contextMenu = Menu.buildFromTemplate([
			{
				label: `Warframe Alerts v${app.getVersion()}`,
				enabled: false
			},
			{
				label: 'Show', click() {
					mainWindow.show();
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Start with Windows', click() {
					if (autoStartEnabled === true) {
						appAutoLauncher.disable();
					} else {
						appAutoLauncher.enable();
					}
				},
				type: 'checkbox',
				checked: autoStartEnabled
			},
			{
				label: 'Log unmatched alerts', click() {
					store.set('app.logUnmatched', !logUnmatched);
				},
				type: 'checkbox',
				checked: logUnmatched
			},
			{
				type: 'separator'
			},
			{
				label: 'Quit', click() {
					app.isQuiting = true;
					app.quit();
					log.info('App quit');
				}
			}
		]);

		mainWindow.on('show', () => {
			tray.setHighlightMode('always');
		});

		tray.on('click', () => {
			contextMenu.items[1].checked = !contextMenu.items[1].checked;
		});
		tray.on('double-click', () => {
			mainWindow.show();
		});
		tray.setToolTip(app.getName());
		tray.setContextMenu(contextMenu);
		ipcMain.on('update-filter', async (event, arg) => {
			store.set(`${arg.config}.${arg.item}`, arg.value);
			checkApi();
		});
	}).catch(err => {
		log.error(err);
	});
});

app.on('window-all-closed', () => {
	clearInterval(interval);
	clearInterval(slowInterval);
	app.quit();
});

function updateCheck() {
	const lastUpdateCheck = store.get('app.lastUpdateCheck');
	const nowTs = ts.now() * 1000;
	let diff;
	if (typeof lastUpdateCheck !== 'undefined') {
		diff = nowTs - lastUpdateCheck;
	}
	if (diff >= 86400000 || typeof lastUpdateCheck === 'undefined') {
		autoUpdater.checkForUpdatesAndNotify().then(() => {
			store.set('app.lastUpdateCheck', nowTs);
		}).catch(err => {
			console.log(err);
		});
	}
}

async function checkApi() {
	const response = await got('http://content.warframe.com/dynamic/worldState.php');
	const ws = new WorldState(response.body);
	await checkAlert(ws);
	await checkInvasion(ws);
}
export default updateLog;
<commit_msg>Do not check api on filter update<commit_after>import path from 'path';
import url from 'url';
import {app, ipcMain, Menu, Tray} from 'electron';
import {autoUpdater} from 'electron-updater';

import devMenuTemplate from './menu/dev-menu-template';
import createWindow from './helpers/window';
import {checkAlert, checkInvasion} from './api';
import store from './helpers/config';

import env from './env';

const log = require('electron-log');
const makeDir = require('make-dir');
const got = require('got');
const AutoLaunch = require('auto-launch');
const osLocale = require('os-locale');
const ts = require('unix-timestamp');
const WorldState = require('warframe-worldstate-parser');
const unhandled = require('electron-unhandled');

unhandled();

require('electron-context-menu')();

const appAutoLauncher = new AutoLaunch({
	name: app.getName(),
	isHidden: true
});

let mainWindow;

if (env.name !== 'production') {
	const userDataPath = app.getPath('userData');
	app.setPath('userData', `${userDataPath} (${env.name})`);
}

makeDir.sync(app.getPath('userData'));
log.transports.file.file = app.getPath('userData') + '/log.log';
autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = 'debug';
log.info('App starting...');

const setApplicationMenu = () => {
	const menus = [];
	menus.push(devMenuTemplate);
	Menu.setApplicationMenu(Menu.buildFromTemplate(menus));
};

const updateLog = (msg, status) => {
	let d = new Date();
	const locale = osLocale.sync().replace('_', '-');
	d = d.toLocaleString(locale, {
		hour: 'numeric',
		minute: 'numeric',
		second: 'numeric'
	});
	let logLine = `[${d}] `;
	logLine += msg;
	mainWindow.webContents.send('log-data', logLine, status);
};

let interval;
let slowInterval;

const shouldQuit = app.makeSingleInstance(() => {
	if (mainWindow) {
		if (!mainWindow.isVisible()) {
			mainWindow.show();
		}
		mainWindow.focus();
	}
});

if (shouldQuit) {
	app.quit();
}

app.on('ready', () => {
	mainWindow = createWindow('main', {
		width: 1000,
		height: 600,
		show: false,
		backgroundColor: '#1b1e23',
		maximizable: false,
		fullscreenable: false,
		resizable: false,
		webPreferences: {
			devtools: false
		}
	});

	mainWindow.loadURL(url.format({
		pathname: path.join(__dirname, '/app.html'),
		protocol: 'file:',
		slashes: true
	}));

	if (env.name === 'development') {
		setApplicationMenu();
		mainWindow.openDevTools({mode: 'undocked'});
	} else {
		mainWindow.setMenu(null);
	}

	updateCheck();
	setInterval(() => {
		updateCheck();
	}, 86400000);

	const tray = new Tray(path.join(__dirname, '/icon.ico'));

	mainWindow.webContents.on('did-finish-load', async () => {
		updateLog(`Warframe Alerts v${app.getVersion()} Started`);
		mainWindow.webContents.send('filter-data', store.get('filters'));
		checkApi();
		setInterval(async () => {
			checkApi();
		}, 60000);
	});

	let autoStartEnabled;

	appAutoLauncher.isEnabled().then(isEnabled => {
		if (isEnabled) {
			autoStartEnabled = true;
		} else {
			autoStartEnabled = false;
		}

		const logUnmatched = store.get('app.logUnmatched', 'false');
		const contextMenu = Menu.buildFromTemplate([
			{
				label: `Warframe Alerts v${app.getVersion()}`,
				enabled: false
			},
			{
				label: 'Show', click() {
					mainWindow.show();
				}
			},
			{
				type: 'separator'
			},
			{
				label: 'Start with Windows', click() {
					if (autoStartEnabled === true) {
						appAutoLauncher.disable();
					} else {
						appAutoLauncher.enable();
					}
				},
				type: 'checkbox',
				checked: autoStartEnabled
			},
			{
				label: 'Log unmatched alerts', click() {
					store.set('app.logUnmatched', !logUnmatched);
				},
				type: 'checkbox',
				checked: logUnmatched
			},
			{
				type: 'separator'
			},
			{
				label: 'Quit', click() {
					app.isQuiting = true;
					app.quit();
					log.info('App quit');
				}
			}
		]);

		mainWindow.on('show', () => {
			tray.setHighlightMode('always');
		});

		tray.on('click', () => {
			contextMenu.items[1].checked = !contextMenu.items[1].checked;
		});
		tray.on('double-click', () => {
			mainWindow.show();
		});
		tray.setToolTip(app.getName());
		tray.setContextMenu(contextMenu);
		ipcMain.on('update-filter', async (event, arg) => {
			store.set(`${arg.config}.${arg.item}`, arg.value);
		});
	}).catch(err => {
		log.error(err);
	});
});

app.on('window-all-closed', () => {
	clearInterval(interval);
	clearInterval(slowInterval);
	app.quit();
});

function updateCheck() {
	const lastUpdateCheck = store.get('app.lastUpdateCheck');
	const nowTs = ts.now() * 1000;
	let diff;
	if (typeof lastUpdateCheck !== 'undefined') {
		diff = nowTs - lastUpdateCheck;
	}
	if (diff >= 86400000 || typeof lastUpdateCheck === 'undefined') {
		autoUpdater.checkForUpdatesAndNotify().then(() => {
			store.set('app.lastUpdateCheck', nowTs);
		}).catch(err => {
			console.log(err);
		});
	}
}

async function checkApi() {
	const response = await got('http://content.warframe.com/dynamic/worldState.php');
	const ws = new WorldState(response.body);
	await checkAlert(ws);
	await checkInvasion(ws);
}
export default updateLog;
<|endoftext|>


<commit_before>// Script blocking
chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    return {cancel: true};
  },
  {
    urls: [
      // O Estado de S. Paulo
      "*://*.estadao.com.br/paywall/*",

      // Folha de S.Paulo
      "*://paywall.folha.uol.com.br/*",
      "*://static.folha.uol.com.br/paywall/*",

      // O Globo
      "*://ogjs.infoglobo.com.br/*/js/controla-acesso-aux.js",

      // Gazeta do Povo
      "*://*.gazetadopovo.com.br/loader/v1/logan_full_toolbar.js*",

      // Correio Popular
      "*://correio.rac.com.br/includes/js/novo_cp/fivewall.js*",

      // O Estado do Maranhão
      "*://dashboard.tinypass.com/xbuilder/experience/load*",
      "http://assets.imirante.com/2.0/oestadoma/js/jquery.login.min.js",

      // Jornal de Novo Hamburgo
      "*://*.jornalnh.com.br/includes/js/paywall.js*",
      "*://blockv2.fivewall.com.br/*",

      // Diário de Santa Maria
      "*://www.rbsonline.com.br/cdn/scripts/SLoader.js",

      // New York Times
      "*://*.nyt.com/js/mtr.js",

      // Washington Post
      "*://*.washingtonpost.com/*pwapi/*.js*",
      "*://*.washingtonpost.com/*drawbridge/drawbridge.js?_*",

      // O Globo, Exame, Super Interessante e Veja
      "*://cdn.tinypass.com/api/tinypass.min.js",

      // UOL
-     "*://tm.jsuol.com.br/modules/content-gate.js"
    ],
    types: ["script"]
  },
  ["blocking"]
);

// XHR blocking
WHITELIST = [
  'http://paywall.folha.uol.com.br/status.php'
];
chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    if (WHITELIST.indexOf(details.url) !== -1)
      return {cancel: false};
    else
      return {cancel: true};
  },
  {
    urls: [
      // Folha de S.Paulo
      "*://paywall.folha.uol.com.br/*",
      "*://static.folha.uol.com.br/paywall/*",

      // Diário Catarinense
      "http://dc.clicrbs.com.br/jornal-2015/jsp/paywall.jspx*",

      // Jornal de Santa Catarina
      "http://jornaldesantacatarina.clicrbs.com.br/jornal/jsp/paywall*",

      // Tinypass (O Globo, Exame e outros)
      "*://cdn.tinypass.com/api/tinypass.min.js"
    ],
    types: ["xmlhttprequest"]
  },
  ["blocking"]
);

// Cookie blocking
chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    chrome.cookies.remove({
      'url': 'http://jota.info/*',
      'name': 'articles'
    });
  },
  {
    urls: [
      // JOTA
      "http://jota.info/*"
    ],
    types: ["main_frame"]
  }
);

chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    console.log(details);
    removeCookies('https://gauchazh.clicrbs.com.br');
    removeCookies('https://www.ft.com');
  },
  {
    urls: [
      // Financial Times
      "*://*.ft.com/*",

      // Zero Hora
      "*://*.clicrbs.com.br/*"
    ]
  }
);

function removeCookies(url) {
  chrome.cookies.getAll({}, function(cookies) {
    cookies.forEach(function(cookie, index, array) {
      chrome.cookies.remove({
        'url': url,
        'name': cookie.name
      });
    });
  });
}

chrome.webRequest.onHeadersReceived.addListener(
  // Block cookies from being set
  function (details) {
    details.responseHeaders.forEach(function(responseHeader) {
      if (responseHeader.name.toLowerCase() == "set-cookie") {
        responseHeader.value = '';
      }
    });
    return {
      responseHeaders: details.responseHeaders
    };
  },
  {
    urls: [
      // Financial Times
      "*://*.ft.com/*",

      // Zero Hora
      "*://*.clicrbs.com.br/*"
    ]
  },
  ['blocking', 'responseHeaders']
);

chrome.webRequest.onBeforeSendHeaders.addListener(
  function(details) {
    injectHeader('Cookie', '', details.requestHeaders);
    return {requestHeaders: details.requestHeaders};
  },
  {
    urls: [
      // Jornal Nexo
      '*://api.nexojornal.com.br/*'
    ],
    types: ['xmlhttprequest']
  },
  ['blocking', 'requestHeaders']
);

// Referer injection
chrome.webRequest.onBeforeSendHeaders.addListener(
  function(details) {
    injectHeader(
      'Referer',
      'https://www.google.com.br/',
      details.requestHeaders
    );

    return {requestHeaders: details.requestHeaders};
  },
  {
    urls: [
      // Financial Times
      "*://www.ft.com/*"
    ],
    types: ["xmlhttprequest", "main_frame"]
  },
  ["blocking", "requestHeaders"]
);

function injectHeader(name, value, requestHeaders) {
  /**
   * @param {string} name - Name of the header to be inserted
   * @param {string} value - Value of the header to be inserted
   * @param {Object[]} requestHeaders - Provided by webRequest
   *   listeners in callback arg `details.requestHeader`
   * @param {string} requestHeaders[].name
   * @param {string} requestHeaders[].value
   */
  var headerIndex = requestHeaders.findIndex(
    x => x.name.toLowerCase() == name.toLowerCase());

  var newHeader = {name: name, value: value};
  if (headerIndex == -1)
    requestHeaders.push(newHeader);
  else
    requestHeaders[headerIndex] = newHeader;
}
<commit_msg>Corrige erro Chrome<commit_after>// Script blocking
chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    return {cancel: true};
  },
  {
    urls: [
      // O Estado de S. Paulo
      "*://*.estadao.com.br/paywall/*",

      // Folha de S.Paulo
      "*://paywall.folha.uol.com.br/*",
      "*://static.folha.uol.com.br/paywall/*",

      // O Globo
      "*://ogjs.infoglobo.com.br/*/js/controla-acesso-aux.js",

      // Gazeta do Povo
      "*://*.gazetadopovo.com.br/loader/v1/logan_full_toolbar.js*",

      // Correio Popular
      "*://correio.rac.com.br/includes/js/novo_cp/fivewall.js*",

      // O Estado do Maranhão
      "*://dashboard.tinypass.com/xbuilder/experience/load*",
      "http://assets.imirante.com/2.0/oestadoma/js/jquery.login.min.js",

      // Jornal de Novo Hamburgo
      "*://*.jornalnh.com.br/includes/js/paywall.js*",
      "*://blockv2.fivewall.com.br/*",

      // Diário de Santa Maria
      "*://www.rbsonline.com.br/cdn/scripts/SLoader.js",

      // New York Times
      "*://*.nyt.com/js/mtr.js",

      // Washington Post
      "*://*.washingtonpost.com/*pwapi/*.js*",
      "*://*.washingtonpost.com/*drawbridge/drawbridge.js?_*",

      // O Globo, Exame, Super Interessante e Veja
      "*://cdn.tinypass.com/api/tinypass.min.js",

      // UOL
      "*://tm.jsuol.com.br/modules/content-gate.js"
    ],
    types: ["script"]
  },
  ["blocking"]
);

// XHR blocking
WHITELIST = [
  'http://paywall.folha.uol.com.br/status.php'
];
chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    if (WHITELIST.indexOf(details.url) !== -1)
      return {cancel: false};
    else
      return {cancel: true};
  },
  {
    urls: [
      // Folha de S.Paulo
      "*://paywall.folha.uol.com.br/*",
      "*://static.folha.uol.com.br/paywall/*",

      // Diário Catarinense
      "http://dc.clicrbs.com.br/jornal-2015/jsp/paywall.jspx*",

      // Jornal de Santa Catarina
      "http://jornaldesantacatarina.clicrbs.com.br/jornal/jsp/paywall*",

      // Tinypass (O Globo, Exame e outros)
      "*://cdn.tinypass.com/api/tinypass.min.js"
    ],
    types: ["xmlhttprequest"]
  },
  ["blocking"]
);

// Cookie blocking
chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    chrome.cookies.remove({
      'url': 'http://jota.info/*',
      'name': 'articles'
    });
  },
  {
    urls: [
      // JOTA
      "http://jota.info/*"
    ],
    types: ["main_frame"]
  }
);

chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    console.log(details);
    removeCookies('https://gauchazh.clicrbs.com.br');
    removeCookies('https://www.ft.com');
  },
  {
    urls: [
      // Financial Times
      "*://*.ft.com/*",

      // Zero Hora
      "*://*.clicrbs.com.br/*"
    ]
  }
);

function removeCookies(url) {
  chrome.cookies.getAll({}, function(cookies) {
    cookies.forEach(function(cookie, index, array) {
      chrome.cookies.remove({
        'url': url,
        'name': cookie.name
      });
    });
  });
}

chrome.webRequest.onHeadersReceived.addListener(
  // Block cookies from being set
  function (details) {
    details.responseHeaders.forEach(function(responseHeader) {
      if (responseHeader.name.toLowerCase() == "set-cookie") {
        responseHeader.value = '';
      }
    });
    return {
      responseHeaders: details.responseHeaders
    };
  },
  {
    urls: [
      // Financial Times
      "*://*.ft.com/*",

      // Zero Hora
      "*://*.clicrbs.com.br/*"
    ]
  },
  ['blocking', 'responseHeaders']
);

chrome.webRequest.onBeforeSendHeaders.addListener(
  function(details) {
    injectHeader('Cookie', '', details.requestHeaders);
    return {requestHeaders: details.requestHeaders};
  },
  {
    urls: [
      // Jornal Nexo
      '*://api.nexojornal.com.br/*'
    ],
    types: ['xmlhttprequest']
  },
  ['blocking', 'requestHeaders']
);

// Referer injection
chrome.webRequest.onBeforeSendHeaders.addListener(
  function(details) {
    injectHeader(
      'Referer',
      'https://www.google.com.br/',
      details.requestHeaders
    );

    return {requestHeaders: details.requestHeaders};
  },
  {
    urls: [
      // Financial Times
      "*://www.ft.com/*"
    ],
    types: ["xmlhttprequest", "main_frame"]
  },
  ["blocking", "requestHeaders"]
);

function injectHeader(name, value, requestHeaders) {
  /**
   * @param {string} name - Name of the header to be inserted
   * @param {string} value - Value of the header to be inserted
   * @param {Object[]} requestHeaders - Provided by webRequest
   *   listeners in callback arg `details.requestHeader`
   * @param {string} requestHeaders[].name
   * @param {string} requestHeaders[].value
   */
  var headerIndex = requestHeaders.findIndex(
    x => x.name.toLowerCase() == name.toLowerCase());

  var newHeader = {name: name, value: value};
  if (headerIndex == -1)
    requestHeaders.push(newHeader);
  else
    requestHeaders[headerIndex] = newHeader;
}
<|endoftext|>


<commit_before>// Copyright 2014 Globo.com Player authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var _ = require('underscore');
var Moment = require('moment');

var extend = function(protoProps, staticProps) {
  var parent = this;
  var child;

  if (protoProps && _.has(protoProps, 'constructor')) {
    child = protoProps.constructor;
  } else {
    child = function(){ return parent.apply(this, arguments); };
  }

  _.extend(child, parent, staticProps);

  var Surrogate = function(){ this.constructor = child; };
  Surrogate.prototype = parent.prototype;
  child.prototype = new Surrogate();

  if (protoProps) _.extend(child.prototype, protoProps);

  child.__super__ = parent.prototype;

  return child;
};

var zeroPad = function(number, size) {
  return (new Array(size + 1 - number.toString().length)).join('0') + number;
};

var formatTime = function(time, showMillis) {
  var duration = Moment.duration(time * 1000);
  var str = duration.minutes() + ':' + zeroPad(duration.seconds(), 2);
  if (duration.hours())
    str = duration.hours() + ':' + str;
  if (showMillis)
    str += '.' + duration.milliseconds();
  return str;
};

module.exports = {
  extend: extend,
  zeroPad: zeroPad,
  formatTime: formatTime
};
<commit_msg>utils: add super method implementation to call methods from "superclass"<commit_after>// Copyright 2014 Globo.com Player authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var _ = require('underscore');
var Moment = require('moment');

var extend = function(protoProps, staticProps) {
  var parent = this;
  var child;

  if (protoProps && _.has(protoProps, 'constructor')) {
    child = protoProps.constructor;
  } else {
    child = function(){ return parent.apply(this, arguments); };
  }

  _.extend(child, parent, staticProps);

  var Surrogate = function(){ this.constructor = child; };
  Surrogate.prototype = parent.prototype;
  child.prototype = new Surrogate();

  if (protoProps) _.extend(child.prototype, protoProps);

  child.__super__ = parent.prototype;

  child.prototype.super = function(name, params) {
    if (child.__super__[name])
      return child.__super__[name].call(this, params);
    if (child.__super__.super)
      child.__super__.super(name, params);
  };

  return child;
};

var zeroPad = function(number, size) {
  return (new Array(size + 1 - number.toString().length)).join('0') + number;
};

var formatTime = function(time, showMillis) {
  var duration = Moment.duration(time * 1000);
  var str = duration.minutes() + ':' + zeroPad(duration.seconds(), 2);
  if (duration.hours())
    str = duration.hours() + ':' + str;
  if (showMillis)
    str += '.' + duration.milliseconds();
  return str;
};

module.exports = {
  extend: extend,
  zeroPad: zeroPad,
  formatTime: formatTime
};
<|endoftext|>


<commit_before>const jwt = require('jsonwebtoken');
const api = require('../api');
const permissionsHelper = require('./permissions');

const rolesDisplayName = {
	teacher: 'Lehrer',
	student: 'Schüler',
	administrator: 'Administrator',
	superhero: 'Schul-Cloud Admin',
	demo: 'Demo',
	demoTeacher: 'Demo',
	demoStudent: 'Demo',
	helpdesk: 'Helpdesk',
	betaTeacher: 'Beta',
	expert: 'Experte',
};

const isJWT = req => (req && req.cookies && req.cookies.jwt);

const isAuthenticated = (req) => {
	if (!isJWT(req)) {
		return Promise.resolve(false);
	}

	return api(req).post('/authentication', {
		json: {
			strategy: 'jwt',
			accessToken: req.cookies.jwt,
		},
	}).then(() => true).catch(() => false);
};

const populateCurrentUser = (req, res) => {
	let payload = {};
	if (isJWT(req)) {
		// eslint-disable-next-line prefer-destructuring
		payload = (jwt.decode(req.cookies.jwt, { complete: true }) || {}).payload;
		res.locals.currentPayload = payload;
	}

	// separates users in two groups for AB testing
	function setTestGroup(user) {
		if (process.env.SW_ENABLED) {
			const lChar = user._id.substr(user._id.length - 1);
			const group = parseInt(lChar, 16) % 2 ? 1 : 0;
			user.testGroup = group;
		} else {
			user.testGroup = 0;
		}
	}

	if (payload && payload.userId) {
		return api(req).get(`/users/${payload.userId}`, {
			qs: {
				$populate: ['roles'],
			},
		}).then((data) => {
			res.locals.currentUser = data;
			setTestGroup(res.locals.currentUser);
			res.locals.currentRole = rolesDisplayName[data.roles[0].name];
			res.locals.roleNames = data.roles.map(r => rolesDisplayName[r.name]);
			return api(req).get(`/schools/${res.locals.currentUser.schoolId}`, {
				qs: {
					$populate: ['federalState'],
				},
			}).then((data2) => {
				res.locals.currentSchool = res.locals.currentUser.schoolId;
				res.locals.currentSchoolData = data2;
				res.locals.currentSchoolData.isExpertSchool = data2.purpose === 'expert';
				return data2;
			});
		}).catch((e) => {
			if (e.error.message === 'jwt expired' || e.error.className === 'not-found') {
				res.clearCookie('jwt');
			}
		});
	}

	return Promise.resolve();
};

const checkConsent = (req, res) => {
	if (
		((res.locals.currentUser || {}).preferences || {}).firstLogin	// do not exist if 3. system login
		|| req.path.startsWith('/login/success')
		|| req.baseUrl.startsWith('/firstLogin')) {
		return Promise.resolve();
	}
	// eslint-disable-next-line prefer-promise-reject-errors
	return Promise.reject('firstLogin was not completed, redirecting...');
};

const restrictSidebar = (req, res) => {
	res.locals.sidebarItems = res.locals.sidebarItems.filter((item) => {
		if (!item.permission) return true;

		const hasRequiredPermission = permissionsHelper.userHasPermission(res.locals.currentUser, item.permission);
		const hasExcludedPermission = permissionsHelper.userHasPermission(res.locals.currentUser,
			item.excludedPermission);
		return hasRequiredPermission && !hasExcludedPermission;
		// excludedPermission is used to prevent the case that an Admin has both: Verwaltung and Administration
	});
};

const authChecker = (req, res, next) => {
	isAuthenticated(req)
		.then((isAuthenticated2) => {
			const redirectUrl = `/login?challenge=${req.query.challenge}`;
			if (isAuthenticated2) {
				// fetch user profile
				populateCurrentUser(req, res)
					.then(() => checkConsent(req, res))
					.then(() => restrictSidebar(req, res))
					.then(() => {
						next();
						return null;
					})
					.catch((err) => {
						if (err === 'firstLogin was not completed, redirecting...') {
							// print message?
							res.redirect('/firstLogin');
						} else {
							res.redirect(redirectUrl);
						}
					});
			} else {
				res.redirect(redirectUrl);
			}
		});
};

const cookieDomain = (res) => {
	if (res.locals.domain && process.env.NODE_ENV === 'production') {
		return { domain: res.locals.domain };
	}
	return {};
};

module.exports = {
	isJWT,
	authChecker,
	isAuthenticated,
	restrictSidebar,
	populateCurrentUser,
	cookieDomain,
};
<commit_msg>fix invalid signature of jwt<commit_after>const jwt = require('jsonwebtoken');
const api = require('../api');
const permissionsHelper = require('./permissions');

const rolesDisplayName = {
	teacher: 'Lehrer',
	student: 'Schüler',
	administrator: 'Administrator',
	superhero: 'Schul-Cloud Admin',
	demo: 'Demo',
	demoTeacher: 'Demo',
	demoStudent: 'Demo',
	helpdesk: 'Helpdesk',
	betaTeacher: 'Beta',
	expert: 'Experte',
};

const isJWT = req => (req && req.cookies && req.cookies.jwt);

const cookieDomain = (res) => {
	if (res.locals.domain && process.env.NODE_ENV === 'production') {
		return { domain: res.locals.domain };
	}
	return {};
};

const isAuthenticated = (req) => {
	if (!isJWT(req)) {
		return Promise.resolve(false);
	}

	return api(req).post('/authentication', {
		json: {
			strategy: 'jwt',
			accessToken: req.cookies.jwt,
		},
	}).then(() => true).catch(() => false);
};

const populateCurrentUser = (req, res) => {
	let payload = {};
	if (isJWT(req)) {
		// eslint-disable-next-line prefer-destructuring
		payload = (jwt.decode(req.cookies.jwt, { complete: true }) || {}).payload;
		res.locals.currentPayload = payload;
	}

	// separates users in two groups for AB testing
	function setTestGroup(user) {
		if (process.env.SW_ENABLED) {
			const lChar = user._id.substr(user._id.length - 1);
			const group = parseInt(lChar, 16) % 2 ? 1 : 0;
			user.testGroup = group;
		} else {
			user.testGroup = 0;
		}
	}

	if (payload && payload.userId) {
		return api(req).get(`/users/${payload.userId}`, {
			qs: {
				$populate: ['roles'],
			},
		}).then((data) => {
			res.locals.currentUser = data;
			setTestGroup(res.locals.currentUser);
			res.locals.currentRole = rolesDisplayName[data.roles[0].name];
			res.locals.roleNames = data.roles.map(r => rolesDisplayName[r.name]);
			return api(req).get(`/schools/${res.locals.currentUser.schoolId}`, {
				qs: {
					$populate: ['federalState'],
				},
			}).then((data2) => {
				res.locals.currentSchool = res.locals.currentUser.schoolId;
				res.locals.currentSchoolData = data2;
				res.locals.currentSchoolData.isExpertSchool = data2.purpose === 'expert';
				return data2;
			});
		}).catch((e) => {
			// 401 for invalid jwt, not-found for deleted user
			if (e.statusCode === 401 || e.error.className === 'not-found') {
				res.clearCookie('jwt', cookieDomain(res));
			}
		});
	}

	return Promise.resolve();
};

const checkConsent = (req, res) => {
	if (
		((res.locals.currentUser || {}).preferences || {}).firstLogin	// do not exist if 3. system login
		|| req.path.startsWith('/login/success')
		|| req.baseUrl.startsWith('/firstLogin')) {
		return Promise.resolve();
	}
	// eslint-disable-next-line prefer-promise-reject-errors
	return Promise.reject('firstLogin was not completed, redirecting...');
};

const restrictSidebar = (req, res) => {
	res.locals.sidebarItems = res.locals.sidebarItems.filter((item) => {
		if (!item.permission) return true;

		const hasRequiredPermission = permissionsHelper.userHasPermission(res.locals.currentUser, item.permission);
		const hasExcludedPermission = permissionsHelper.userHasPermission(res.locals.currentUser,
			item.excludedPermission);
		return hasRequiredPermission && !hasExcludedPermission;
		// excludedPermission is used to prevent the case that an Admin has both: Verwaltung and Administration
	});
};

const authChecker = (req, res, next) => {
	isAuthenticated(req)
		.then((isAuthenticated2) => {
			const redirectUrl = `/login?challenge=${req.query.challenge}`;
			if (isAuthenticated2) {
				// fetch user profile
				populateCurrentUser(req, res)
					.then(() => checkConsent(req, res))
					.then(() => restrictSidebar(req, res))
					.then(() => {
						next();
						return null;
					})
					.catch((err) => {
						if (err === 'firstLogin was not completed, redirecting...') {
							// print message?
							res.redirect('/firstLogin');
						} else {
							res.redirect(redirectUrl);
						}
					});
			} else {
				res.redirect(redirectUrl);
			}
		});
};

module.exports = {
	isJWT,
	cookieDomain,
	authChecker,
	isAuthenticated,
	restrictSidebar,
	populateCurrentUser,
};
<|endoftext|>


<commit_before>'use strict';

var db = require('mano').db

  , user = db.User.prototype
  , reqRadio;

exports['step-guide'] = { class: { 'step-active': true } };

require('./_inventory');

exports.step = function () {
	h1("1. Individual registration guide for companies");

	form(
		{ class: 'user-guide' },
		div({ class: 'section-primary' }, h2("Questions"),
			hr(),
			ul({ class: 'form-elements' },
				['businessActivity',
					'isOwner',
					'inventory',
					'surfaceArea', 'members',
					'companyType',
					'isShoppingGallery'],
				function (name) {
					if (name === 'inventory') {
						div({ class: 'dbjs-input-component' },
							label({ for: 'input-' + name }, user.getDescriptor(name).label, ":"),
							div({ class: 'input' },
								input({ control: { id: 'input-' + name }, dbjs: user.getObservable(name) })));
						div({ class: 'user-guide-inventory-button' },
							a({ href: '#inventory' },
								span({ class: 'fa fa-calculator user-guide-inventory-icon' }, "Calculator"),
								span({ class: 'user-guide-inventory-label' }, "Calculate the amount")));
					} else if (name === 'isShoppingGallery') {
						li(div({ class: 'dbjs-input-component' },
							label(
								{ for: 'input-' + name },
								"Is shopping gallery?"
							),
							div({ class: 'input' },
								input({ control: { id: 'input-' + name }, dbjs: user.getObservable(name),
									type: 'checkbox' }))));
					} else {
						li(div({ class: 'dbjs-input-component' },
							label(
								{ for: 'input-' + name },
								user.getDescriptor(name).label,
								":"
							),
							div({ class: 'input' },
								input({ control: { id: 'input-' + name }, dbjs: user.getObservable(name) }))));
					}
				})),
		div(
			{ class: 'section-primary' },
			h2("Registrations"),
			hr(),
			p("Lorem ipsum dolor sit amet, consectetur adipiscing elit." +
				" Etiam vestibulum dui mi, nec ultrices diam ultricies id. " +
				" Etiam vestibulum dui mi, nec ultrices diam ultricies id. "),
			ul(li(label({ class: 'input-aside' },
				input({ dbjs: user._isARequested, type: 'checkbox', control: { class: 'readonly' } }), " ",
				span(user.getDescriptor('isARequested').label))),
				li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
					span(user.getDescriptor('isBRequested').label))),
				li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
					span(user.getDescriptor('isARequested').label)))),
			div(
				{ class: 'section-primary-wrapper' },
				h2("Optional Registrations"),
				hr(),
				ul(li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested, type: 'checkbox', control: { class: 'readonly' } }),
					" ",
					span(user.getDescriptor('isARequested').label))),
					li(label({ class: 'input-aside' },
						input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
						span(user.getDescriptor('isBRequested').label))))
			)
		),

		div({ class: 'section-primary' }, h2("Requirements"),
			hr(),
			p("Lorem ipsum dolor sit amet, consectetur adipiscing elit." +
				" Etiam vestibulum dui mi, nec ultrices diam ultricies id. "),
			ul({ class: 'user-guide-requirements-list' },
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
					" Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum " +
					"dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet," +
					" consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet: ",
					ul(li(reqRadio = input({ dbjs: user._isType, type: 'radio',
						renderOption: function (labelTxt) {
							var data = {};
							data.dom = li(label({ class: 'input-aside' },
								span(data.input = input()),
								span(labelTxt)));
							return data;
						}  }), " "))),
				li(
					"Please choose x docs in the list: ",
					ul(
						li(label({ class: 'input-aside' },
							input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
							span(user.getDescriptor('isBRequested').label))),
						li(label({ class: 'input-aside' },
							input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
							span(user.getDescriptor('isBRequested').label))),
						li(
							label({ class: 'input-aside' }, input({ dbjs: user._isBRequested,
								type: 'checkbox',
								control: { class: 'readonly' },
								value: 'checked' }),
								" ",
								span(user.getDescriptor('isBRequested').label))
						),
						li(label({ class: 'input-aside' },
							input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
							span(user.getDescriptor('isARequested').label))),
						li(label({ class: 'input-aside' },
							input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
							span(user.getDescriptor('isBRequested').label)))
					)
				))),
		div({ class: 'section-primary' }, h2("Costs"),
			hr(),
			div(
				{ class: 'free-form' },
				p("LoLorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat aliquet massa," +
					" quis vulputate diam. Morbi non dolor ac tellus finibus commodo. Donec convallis" +
					" tortor felis, et sodales quam vulputate ac."),
				ul(
					li(
						p("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
						ul(
							li("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
							li("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
						)
					),
					li("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
					li("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
				),
				ol(
					li(
						p("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
						ol(
							li("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
							li("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
						)
					),
					li("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
				),
				p("LoLorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat aliquet massa," +
					" quis vulputate diam. Morbi non dolor ac tellus finibus commodo. Donec convallis" +
					" tortor felis, et sodales quam vulputate ac.")
			),
			p("Lorem ipsum dolor sit amet, consectetur adipiscing elit." +
				" Etiam vestibulum dui mi, nec ultrices diam ultricies id. "),
			ul({ class: 'user-guide-costs-list' },
				li(span("Registration fee"), " ",
					span("$50'000")),
				li(span("Stamp duty for registration"), " ",
					span("$10'000")),
				li(span("Filing fees for memorandum"), " ",
					span("$45'000")),
				li({ class: 'user-guide-total-costs' },
					span("Total Costs:"), " ",
					span("$105'000")),
				li(span("Filing fees for memorandum"), " ",
					span("$45'000")),
					small("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")),
			p(
				a({ class: 'button-resource-link', href: 'costs-print/' },
					span({ class: 'fa fa-print' }), " ",
					"Print costs list"
					)
			)
			),
		p({ class: 'user-next-step-button' },
			button({ type: 'submit' },
				"Save and continue"))
	);
	reqRadio._dbjsInput.listItems[0].appendChild(
		div({ class: 'disabler-range' }, // add 'disabler-active' class to disable ul
			ul(
				li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
					span(user.getDescriptor('isBRequested').label))),
				li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested,
						type: 'checkbox', value: 'checked' }), " ",
					span(user.getDescriptor('isBRequested').label)))
			),
			div({ class: 'disabler' }))
	);
};
<commit_msg>Added autocomplet element in user guide. #459<commit_after>'use strict';

var db = require('mano').db

  , user = db.User.prototype
  , reqRadio;

exports['step-guide'] = { class: { 'step-active': true } };

require('./_inventory');

exports.step = function () {
	h1("1. Individual registration guide for companies");

	form(
		{ class: 'user-guide' },
		div({ class: 'section-primary' }, h2("Questions"),
			hr(),
			ul({ class: 'form-elements' },
				['businessActivity',
					'isOwner',
					'inventory',
					'surfaceArea', 'members',
					'companyType',
					'isShoppingGallery',
					'autocomplet'],
				function (name) {
					if (name === 'inventory') {
						div({ class: 'dbjs-input-component' },
							label({ for: 'input-' + name }, user.getDescriptor(name).label, ":"),
							div({ class: 'input' },
								input({ control: { id: 'input-' + name }, dbjs: user.getObservable(name) })));
						div({ class: 'user-guide-inventory-button' },
							a({ href: '#inventory' },
								span({ class: 'fa fa-calculator user-guide-inventory-icon' }, "Calculator"),
								span({ class: 'user-guide-inventory-label' }, "Calculate the amount")));
					} else if (name === 'isShoppingGallery') {
						li(div({ class: 'dbjs-input-component' },
							label(
								{ for: 'input-' + name },
								"Is shopping gallery?"
							),
							div({ class: 'input' },
								input({ control: { id: 'input-' + name }, dbjs: user.getObservable(name),
									type: 'checkbox' }))));
					} else if (name === 'autocomplet') {
						li(div({ class: 'dbjs-input-component' },
								label('Autocomplet input:'),
								div({ class: 'input' },
									input({ list: 'datalist', type: 'text', placeholder: 'Start typing' })),
								datalist({ id: 'datalist' },
									option('Adam'),
									option('Alan'),
									option('Frank'),
									option('Viene'),
									option('Bita'))));
					} else {
						li(div({ class: 'dbjs-input-component' },
							label(
								{ for: 'input-' + name },
								user.getDescriptor(name).label,
								":"
							),
							div({ class: 'input' },
								input({ control: { id: 'input-' + name }, dbjs: user.getObservable(name) }))));
					}
				})),
		div(
			{ class: 'section-primary' },
			h2("Registrations"),
			hr(),
			p("Lorem ipsum dolor sit amet, consectetur adipiscing elit." +
				" Etiam vestibulum dui mi, nec ultrices diam ultricies id. " +
				" Etiam vestibulum dui mi, nec ultrices diam ultricies id. "),
			ul(li(label({ class: 'input-aside' },
				input({ dbjs: user._isARequested, type: 'checkbox', control: { class: 'readonly' } }), " ",
				span(user.getDescriptor('isARequested').label))),
				li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
					span(user.getDescriptor('isBRequested').label))),
				li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
					span(user.getDescriptor('isARequested').label)))),
			div(
				{ class: 'section-primary-wrapper' },
				h2("Optional Registrations"),
				hr(),
				ul(li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested, type: 'checkbox', control: { class: 'readonly' } }),
					" ",
					span(user.getDescriptor('isARequested').label))),
					li(label({ class: 'input-aside' },
						input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
						span(user.getDescriptor('isBRequested').label))))
			)
		),

		div({ class: 'section-primary' }, h2("Requirements"),
			hr(),
			p("Lorem ipsum dolor sit amet, consectetur adipiscing elit." +
				" Etiam vestibulum dui mi, nec ultrices diam ultricies id. "),
			ul({ class: 'user-guide-requirements-list' },
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
					" Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum " +
					"dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet," +
					" consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
				li("Lorem ipsum dolor sit amet: ",
					ul(li(reqRadio = input({ dbjs: user._isType, type: 'radio',
						renderOption: function (labelTxt) {
							var data = {};
							data.dom = li(label({ class: 'input-aside' },
								span(data.input = input()),
								span(labelTxt)));
							return data;
						}  }), " "))),
				li(
					"Please choose x docs in the list: ",
					ul(
						li(label({ class: 'input-aside' },
							input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
							span(user.getDescriptor('isBRequested').label))),
						li(label({ class: 'input-aside' },
							input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
							span(user.getDescriptor('isBRequested').label))),
						li(
							label({ class: 'input-aside' }, input({ dbjs: user._isBRequested,
								type: 'checkbox',
								control: { class: 'readonly' },
								value: 'checked' }),
								" ",
								span(user.getDescriptor('isBRequested').label))
						),
						li(label({ class: 'input-aside' },
							input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
							span(user.getDescriptor('isARequested').label))),
						li(label({ class: 'input-aside' },
							input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
							span(user.getDescriptor('isBRequested').label)))
					)
				))),
		div({ class: 'section-primary' }, h2("Costs"),
			hr(),
			div(
				{ class: 'free-form' },
				p("LoLorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat aliquet massa," +
					" quis vulputate diam. Morbi non dolor ac tellus finibus commodo. Donec convallis" +
					" tortor felis, et sodales quam vulputate ac."),
				ul(
					li(
						p("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
						ul(
							li("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
							li("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
						)
					),
					li("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
					li("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
				),
				ol(
					li(
						p("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
						ol(
							li("Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
							li("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
						)
					),
					li("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
				),
				p("LoLorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat aliquet massa," +
					" quis vulputate diam. Morbi non dolor ac tellus finibus commodo. Donec convallis" +
					" tortor felis, et sodales quam vulputate ac.")
			),
			p("Lorem ipsum dolor sit amet, consectetur adipiscing elit." +
				" Etiam vestibulum dui mi, nec ultrices diam ultricies id. "),
			ul({ class: 'user-guide-costs-list' },
				li(span("Registration fee"), " ",
					span("$50'000")),
				li(span("Stamp duty for registration"), " ",
					span("$10'000")),
				li(span("Filing fees for memorandum"), " ",
					span("$45'000")),
				li({ class: 'user-guide-total-costs' },
					span("Total Costs:"), " ",
					span("$105'000")),
				li(span("Filing fees for memorandum"), " ",
					span("$45'000")),
					small("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")),
			p(
				a({ class: 'button-resource-link', href: 'costs-print/' },
					span({ class: 'fa fa-print' }), " ",
					"Print costs list"
					)
			)
			),
		p({ class: 'user-next-step-button' },
			button({ type: 'submit' },
				"Save and continue"))
	);
	reqRadio._dbjsInput.listItems[0].appendChild(
		div({ class: 'disabler-range' }, // add 'disabler-active' class to disable ul
			ul(
				li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested, type: 'checkbox' }), " ",
					span(user.getDescriptor('isBRequested').label))),
				li(label({ class: 'input-aside' },
					input({ dbjs: user._isARequested,
						type: 'checkbox', value: 'checked' }), " ",
					span(user.getDescriptor('isBRequested').label)))
			),
			div({ class: 'disabler' }))
	);
};
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var varargs = require('varargs');

var schemaContents = fs.readFileSync(__dirname + '/oce.proto', 'utf8').toString();
var proto = require('protocol-buffers')(schemaContents);
var obj = require('protobuf-schema').parse(schemaContents);

var BufferList = require('bl');

var argumentHintParser = require('./arguments');
var getResponseArray = require('./response');

var response = proto.NetOCE_Response;
var request = proto.NetOCE_Request;

// extract the message type enum
var ENUM = obj.messages.filter(function(msg) {
  return msg.name === 'NetOCE_Value';
})[0].enums[0].values;

module.exports = createClient;
createClient.request =  proto.NetOCE_Request;
createClient.response =  proto.NetOCE_Response;

createClient.encodeRequest = encode;

var phase = 0, decode_message_length = 0;
function decode(buffer) {

  if (phase === 0) {
    if (buffer.length < 4) {
      return false;
    }

    decode_message_length = buffer.readUInt32LE(0);
    buffer.consume(4);
    phase = 1;
  }

  if (buffer.length && buffer.length >= decode_message_length) {

    var result = response.decode(buffer.slice(0, decode_message_length));
    buffer.consume(decode_message_length);
    decode_message_length = 0;
    phase = 0;

    return result;
  }

  return false
}

function encode(obj) {
  var messageLength = request.encodingLength(obj);
  var outgoingLength = messageLength + 4;
  var buf = new Buffer(outgoingLength);
  request.encode(obj, buf.slice(4));
  buf.writeUInt32LE(messageLength, 0);

  return buf;
}

var buffer = new BufferList();
function processOceOutput(data) {

  // Work around protocol-buffers and typed arrays.
  if (data.byteLength) {
    data = new Buffer(new Uint8Array(data));
  }
  buffer.append(data);

  var result = [];
  while(true) {

    var obj = decode(buffer);
    if (!obj) {
      break;
    }
    result.push(obj);
  }
  return result;
}

function createClient(stream, cb) {
  var seq = 1;

  stream.once('data', function(first) {
    var r = processOceOutput(first)[0];
    if (!r) {
      return cb(new Error('could not get methods from net-oce'))
    }
    var queue = {};
    stream.done = function() {
      return !Object.keys(queue).length;
    };

    stream.on('data', function(data) {
      var responses = processOceOutput(data);

      responses.forEach(function(res) {
        var fn = queue[res.seq];
        delete queue[res.seq];
        getResponseArray(res, fn);
      });
    });

    var methods = {};

    r.value.forEach(function(op) {
      var id = op.operation.id;

      var genfn = methods[op.operation.name] = function(a, fn) {
        var args;

        if (Array.isArray(a)) {
          args = a;
        } else {
          args = varargs(arguments);
          fn = args.pop();
        }

        var obj = {
          method : id,
          seq: seq++,
          argument: argumentHintParser(op.operation.arguments, args, ENUM)
        };

        if (fn._shapeId) {
          obj.shape_id = fn._shapeId;
        }

        queue[obj.seq] = fn;

        stream.write(encode(obj));
      };

      var parts = op.operation.arguments.replace(/ /g, '').split(',');
      var infinite = parts[parts.length-1].indexOf('..') > -1;
      genfn.argc = (infinite) ? Infinity : parts.length;
    });

    cb(null, methods);
  });

  stream.write(encode({ method: 0, seq: seq++ }));

  return stream;
}
<commit_msg>extract shape_id from 'this' instead<commit_after>var path = require('path');
var fs = require('fs');
var varargs = require('varargs');

var schemaContents = fs.readFileSync(__dirname + '/oce.proto', 'utf8').toString();
var proto = require('protocol-buffers')(schemaContents);
var obj = require('protobuf-schema').parse(schemaContents);

var BufferList = require('bl');

var argumentHintParser = require('./arguments');
var getResponseArray = require('./response');

var response = proto.NetOCE_Response;
var request = proto.NetOCE_Request;

// extract the message type enum
var ENUM = obj.messages.filter(function(msg) {
  return msg.name === 'NetOCE_Value';
})[0].enums[0].values;

module.exports = createClient;
createClient.request =  proto.NetOCE_Request;
createClient.response =  proto.NetOCE_Response;

createClient.encodeRequest = encode;

var phase = 0, decode_message_length = 0;
function decode(buffer) {

  if (phase === 0) {
    if (buffer.length < 4) {
      return false;
    }

    decode_message_length = buffer.readUInt32LE(0);
    buffer.consume(4);
    phase = 1;
  }

  if (buffer.length && buffer.length >= decode_message_length) {

    var result = response.decode(buffer.slice(0, decode_message_length));
    buffer.consume(decode_message_length);
    decode_message_length = 0;
    phase = 0;

    return result;
  }

  return false
}

function encode(obj) {
  var messageLength = request.encodingLength(obj);
  var outgoingLength = messageLength + 4;
  var buf = new Buffer(outgoingLength);
  request.encode(obj, buf.slice(4));
  buf.writeUInt32LE(messageLength, 0);

  return buf;
}

var buffer = new BufferList();
function processOceOutput(data) {

  // Work around protocol-buffers and typed arrays.
  if (data.byteLength) {
    data = new Buffer(new Uint8Array(data));
  }
  buffer.append(data);

  var result = [];
  while(true) {

    var obj = decode(buffer);
    if (!obj) {
      break;
    }
    result.push(obj);
  }
  return result;
}

function createClient(stream, cb) {
  var seq = 1;

  stream.once('data', function(first) {
    var r = processOceOutput(first)[0];
    if (!r) {
      return cb(new Error('could not get methods from net-oce'))
    }
    var queue = {};
    stream.done = function() {
      return !Object.keys(queue).length;
    };

    stream.on('data', function(data) {
      var responses = processOceOutput(data);

      responses.forEach(function(res) {
        var fn = queue[res.seq];
        delete queue[res.seq];
        getResponseArray(res, fn);
      });
    });

    var methods = {};

    r.value.forEach(function(op) {
      var id = op.operation.id;

      var genfn = methods[op.operation.name] = function(a, fn) {
        var args;

        if (Array.isArray(a)) {
          args = a;
        } else {
          args = varargs(arguments);
          fn = args.pop();
        }

        var obj = {
          method : id,
          seq: seq++,
          argument: argumentHintParser(op.operation.arguments, args, ENUM)
        };

        // Allow callers to scope this to a Shape object
        if (typeof this.id === 'number') {
          obj.shape_id = this.id;
        }

        queue[obj.seq] = fn;

        stream.write(encode(obj));
      };

      var parts = op.operation.arguments.replace(/ /g, '').split(',');
      var infinite = parts[parts.length-1].indexOf('..') > -1;
      genfn.argc = (infinite) ? Infinity : parts.length;
    });

    cb(null, methods);
  });

  stream.write(encode({ method: 0, seq: seq++ }));

  return stream;
}
<|endoftext|>


<commit_before>// hammer JS for touch support
var Hammer = require('hammerjs');
Hammer = typeof(Hammer) === 'function' ? Hammer : window.Hammer;

// Get the chart variable
var Chart = require('chart.js');
Chart = typeof(Chart) === 'function' ? Chart : window.Chart;
var helpers = Chart.helpers;

// Take the zoom namespace of Chart
var zoomNS = Chart.Zoom = Chart.Zoom || {};

// Where we store functions to handle different scale types
var zoomFunctions = zoomNS.zoomFunctions = zoomNS.zoomFunctions || {};
var panFunctions = zoomNS.panFunctions = zoomNS.panFunctions || {};

// Default options if none are provided
var defaultOptions = zoomNS.defaults = {
	pan: {
		enabled: true,
		mode: 'xy',
		threshold: 10,
	},
	zoom: {
		enabled: true,
		mode: 'xy',
	}
};

function directionEnabled(mode, dir) {
	if (mode === undefined) {
		return true;
	} else if (typeof mode === 'string') {
		return mode.indexOf(dir) !== -1;
	}

	return false;
}

function zoomIndexScale(scale, zoom, center) {

}

function zoomTimeScale(scale, zoom, center) {
	var options = scale.options;
	var range = scale.right - scale.left;
	var newDiff = range * (zoom - 1);

	// Assumes time scale is always X axis
	var min_percent = (center.x - scale.left) / range;
	var max_percent = 1 - min_percent;

	var minDelta = newDiff * min_percent;
	var maxDelta = newDiff * max_percent;

	options.time.min = scale.getValueForPixel(scale.getPixelForValue(scale.firstTick) + minDelta);
	options.time.max = scale.getValueForPixel(scale.getPixelForValue(scale.lastTick) - maxDelta);
}

function zoomNumericalScale(scale, zoom, center) {
	var range = scale.max - scale.min;
	var newDiff = range * (zoom - 1);

	var cursorPixel = scale.isHorizontal() ? center.x : center.y;
	var min_percent = (scale.getValueForPixel(cursorPixel) - scale.min) / range;
	var max_percent = 1 - min_percent;

	var minDelta = newDiff * min_percent;
	var maxDelta = newDiff * max_percent;

	scale.options.ticks.min = scale.min + minDelta;
	scale.options.ticks.max = scale.max - maxDelta;
}

function zoomScale(scale, zoom, center) {
	var fn = zoomFunctions[scale.options.type];
	if (fn) {
		fn(scale, zoom, center);
	}
}

function doZoom(chartInstance, zoom, center) {
	var ca = chartInstance.chartArea;
	if (!center) {
		center = {
			x: (ca.left + ca.right) / 2,
			y: (ca.top + ca.bottom) / 2,
		};
	}

	var zoomOptions = chartInstance.options.zoom;

	if (zoomOptions && helpers.getValueOrDefault(zoomOptions.enabled, defaultOptions.zoom.enabled)) {
		// Do the zoom here
		var zoomMode = helpers.getValueOrDefault(chartInstance.options.zoom.mode, defaultOptions.zoom.mode);

		helpers.each(chartInstance.scales, function(scale, id) {
			if (scale.isHorizontal() && directionEnabled(zoomMode, 'x')) {
				zoomScale(scale, zoom, center);
			} else if (directionEnabled(zoomMode, 'y')) {
				// Do Y zoom
				zoomScale(scale, zoom, center);
			}
		});

		chartInstance.update(0);
	}
}

function panIndexScale(scale, delta) {
	/*var options = scale.options;
	var labels = scale.chart.data.labels;
	var lastLabelIndex = labels.length - 1;

	var minIndex = Math.max(0, Math.round(scale.getValueForPixel(scale.getPixelForValue(null, scale.minIndex, null, true) - delta)));
	var maxIndex = Math.min(lastLabelIndex, Math.round(scale.getValueForPixel(scale.getPixelForValue(null, scale.maxIndex, null, true) - delta)))
	options.ticks.min = labels[minIndex];
	options.ticks.max = labels[maxIndex];*/
}

function panTimeScale(scale, delta) {
	var options = scale.options;
	options.time.min = scale.getValueForPixel(scale.getPixelForValue(scale.firstTick) - delta);
	options.time.max = scale.getValueForPixel(scale.getPixelForValue(scale.lastTick) - delta);
}

function panNumericalScale(scale, delta) {
	var tickOpts = scale.options.ticks;
	var start = scale.start,
		end = scale.end;

	if (tickOpts.reverse) {
		tickOpts.max = scale.getValueForPixel(scale.getPixelForValue(start) - delta);
		tickOpts.min = scale.getValueForPixel(scale.getPixelForValue(end) - delta);
	} else {
		tickOpts.min = scale.getValueForPixel(scale.getPixelForValue(start) - delta);
		tickOpts.max = scale.getValueForPixel(scale.getPixelForValue(end) - delta);
	}
}

function panScale(scale, delta) {
	var fn = panFunctions[scale.options.type];
	if (fn) {
		fn(scale, delta);
	}
}

function doPan(chartInstance, deltaX, deltaY) {
	var panOptions = chartInstance.options.pan;
	if (panOptions && helpers.getValueOrDefault(panOptions.enabled, defaultOptions.pan.enabled)) {
		var panMode = helpers.getValueOrDefault(chartInstance.options.pan.mode, defaultOptions.pan.mode);

		helpers.each(chartInstance.scales, function(scale, id) {
			if (scale.isHorizontal() && directionEnabled(panMode, 'x') && deltaX !== 0) {
				panScale(scale, deltaX);
			} else if (directionEnabled(panMode, 'y') && deltaY !== 0) {
				panScale(scale, deltaY);
			}
		});

		chartInstance.update(0);
	}
}

function positionInChartArea(chartInstance, position) {
	return 	(position.x >= chartInstance.chartArea.left && position.x <= chartInstance.chartArea.right) &&
			(position.y >= chartInstance.chartArea.top && position.y <= chartInstance.chartArea.bottom);
}

// Store these for later
zoomNS.zoomFunctions.category = zoomIndexScale;
zoomNS.zoomFunctions.time = zoomTimeScale;
zoomNS.zoomFunctions.linear = zoomNumericalScale;
zoomNS.zoomFunctions.logarithmic = zoomNumericalScale;
zoomNS.panFunctions.category = panIndexScale;
zoomNS.panFunctions.time = panTimeScale;
zoomNS.panFunctions.linear = panNumericalScale;
zoomNS.panFunctions.logarithmic = panNumericalScale;

// Chartjs Zoom Plugin
var zoomPlugin = {
	beforeInit: function(chartInstance) {
		var node = chartInstance.chart.ctx.canvas;
		var options = chartInstance.options;
		var panThreshold = helpers.getValueOrDefault(options.pan ? options.pan.threshold : undefined, zoomNS.defaults.pan.threshold);

		var wheelHandler = function(e) {
			var rect = e.target.getBoundingClientRect();
			var offsetX = e.clientX - rect.left;
			var offsetY = e.clientY - rect.top;

			var center = {
				x : offsetX,
				y : offsetY
			};

			if (e.deltaY < 0) {
				doZoom(chartInstance, 1.1, center);
			} else {
				doZoom(chartInstance, 0.909, center);
			}
		};
		chartInstance._wheelHandler = wheelHandler;

		node.addEventListener('wheel', wheelHandler);

		if (Hammer) {
			var mc = new Hammer.Manager(node);
			mc.add(new Hammer.Pinch());
			mc.add(new Hammer.Pan({
				threshold: panThreshold
			}));

			// Hammer reports the total scaling. We need the incremental amount
			var currentPinchScaling;
			var handlePinch = function handlePinch(e) {
				var diff = 1 / (currentPinchScaling) * e.scale;
				doZoom(chartInstance, diff, e.center);

				// Keep track of overall scale
				currentPinchScaling = e.scale;
			};

			mc.on('pinchstart', function(e) {
				currentPinchScaling = 1; // reset tracker
			});
			mc.on('pinch', handlePinch);
			mc.on('pinchend', function(e) {
				handlePinch(e);
				currentPinchScaling = null; // reset
			});

			var currentDeltaX = null, currentDeltaY = null;
			var handlePan = function handlePan(e) {
				if (currentDeltaX !== null && currentDeltaY !== null) {
					var deltaX = e.deltaX - currentDeltaX;
					var deltaY = e.deltaY - currentDeltaY;
					currentDeltaX = e.deltaX;
					currentDeltaY = e.deltaY;

					doPan(chartInstance, deltaX, deltaY);
				}
			};

			mc.on('panstart', function(e) {
				currentDeltaX = 0;
				currentDeltaY = 0;
				handlePan(e);
			});
			mc.on('panmove', handlePan);
			mc.on('panend', function(e) {
				currentDeltaX = null;
				currentDeltaY = null;
			});
			chartInstance._mc = mc;
		}
	},

	beforeDatasetsDraw: function(chartInstance) {
		var ctx = chartInstance.chart.ctx;
		var chartArea = chartInstance.chartArea;
		ctx.save();
		ctx.beginPath();
		ctx.rect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
		ctx.clip();
	},

	afterDatasetsDraw: function(chartInstance) {
		chartInstance.chart.ctx.restore();
	},

	destroy: function(chartInstance) {
		var node = chartInstance.chart.ctx.canvas;
		node.removeEventListener('wheel', chartInstance._wheelHandler);

		var mc = chartInstance._mc;
		if (mc) {
			mc.remove('pinchstart');
			mc.remove('pinch');
			mc.remove('pinchend');
			mc.remove('panstart');
			mc.remove('pan');
			mc.remove('panend');
		}
	}
};

Chart.pluginService.register(zoomPlugin);
<commit_msg>Only pan deltaY on vertical scale<commit_after>// hammer JS for touch support
var Hammer = require('hammerjs');
Hammer = typeof(Hammer) === 'function' ? Hammer : window.Hammer;

// Get the chart variable
var Chart = require('chart.js');
Chart = typeof(Chart) === 'function' ? Chart : window.Chart;
var helpers = Chart.helpers;

// Take the zoom namespace of Chart
var zoomNS = Chart.Zoom = Chart.Zoom || {};

// Where we store functions to handle different scale types
var zoomFunctions = zoomNS.zoomFunctions = zoomNS.zoomFunctions || {};
var panFunctions = zoomNS.panFunctions = zoomNS.panFunctions || {};

// Default options if none are provided
var defaultOptions = zoomNS.defaults = {
	pan: {
		enabled: true,
		mode: 'xy',
		threshold: 10,
	},
	zoom: {
		enabled: true,
		mode: 'xy',
	}
};

function directionEnabled(mode, dir) {
	if (mode === undefined) {
		return true;
	} else if (typeof mode === 'string') {
		return mode.indexOf(dir) !== -1;
	}

	return false;
}

function zoomIndexScale(scale, zoom, center) {

}

function zoomTimeScale(scale, zoom, center) {
	var options = scale.options;
	var range = scale.right - scale.left;
	var newDiff = range * (zoom - 1);

	// Assumes time scale is always X axis
	var min_percent = (center.x - scale.left) / range;
	var max_percent = 1 - min_percent;

	var minDelta = newDiff * min_percent;
	var maxDelta = newDiff * max_percent;

	options.time.min = scale.getValueForPixel(scale.getPixelForValue(scale.firstTick) + minDelta);
	options.time.max = scale.getValueForPixel(scale.getPixelForValue(scale.lastTick) - maxDelta);
}

function zoomNumericalScale(scale, zoom, center) {
	var range = scale.max - scale.min;
	var newDiff = range * (zoom - 1);

	var cursorPixel = scale.isHorizontal() ? center.x : center.y;
	var min_percent = (scale.getValueForPixel(cursorPixel) - scale.min) / range;
	var max_percent = 1 - min_percent;

	var minDelta = newDiff * min_percent;
	var maxDelta = newDiff * max_percent;

	scale.options.ticks.min = scale.min + minDelta;
	scale.options.ticks.max = scale.max - maxDelta;
}

function zoomScale(scale, zoom, center) {
	var fn = zoomFunctions[scale.options.type];
	if (fn) {
		fn(scale, zoom, center);
	}
}

function doZoom(chartInstance, zoom, center) {
	var ca = chartInstance.chartArea;
	if (!center) {
		center = {
			x: (ca.left + ca.right) / 2,
			y: (ca.top + ca.bottom) / 2,
		};
	}

	var zoomOptions = chartInstance.options.zoom;

	if (zoomOptions && helpers.getValueOrDefault(zoomOptions.enabled, defaultOptions.zoom.enabled)) {
		// Do the zoom here
		var zoomMode = helpers.getValueOrDefault(chartInstance.options.zoom.mode, defaultOptions.zoom.mode);

		helpers.each(chartInstance.scales, function(scale, id) {
			if (scale.isHorizontal() && directionEnabled(zoomMode, 'x')) {
				zoomScale(scale, zoom, center);
			} else if (directionEnabled(zoomMode, 'y')) {
				// Do Y zoom
				zoomScale(scale, zoom, center);
			}
		});

		chartInstance.update(0);
	}
}

function panIndexScale(scale, delta) {
	/*var options = scale.options;
	var labels = scale.chart.data.labels;
	var lastLabelIndex = labels.length - 1;

	var minIndex = Math.max(0, Math.round(scale.getValueForPixel(scale.getPixelForValue(null, scale.minIndex, null, true) - delta)));
	var maxIndex = Math.min(lastLabelIndex, Math.round(scale.getValueForPixel(scale.getPixelForValue(null, scale.maxIndex, null, true) - delta)))
	options.ticks.min = labels[minIndex];
	options.ticks.max = labels[maxIndex];*/
}

function panTimeScale(scale, delta) {
	var options = scale.options;
	options.time.min = scale.getValueForPixel(scale.getPixelForValue(scale.firstTick) - delta);
	options.time.max = scale.getValueForPixel(scale.getPixelForValue(scale.lastTick) - delta);
}

function panNumericalScale(scale, delta) {
	var tickOpts = scale.options.ticks;
	var start = scale.start,
		end = scale.end;

	if (tickOpts.reverse) {
		tickOpts.max = scale.getValueForPixel(scale.getPixelForValue(start) - delta);
		tickOpts.min = scale.getValueForPixel(scale.getPixelForValue(end) - delta);
	} else {
		tickOpts.min = scale.getValueForPixel(scale.getPixelForValue(start) - delta);
		tickOpts.max = scale.getValueForPixel(scale.getPixelForValue(end) - delta);
	}
}

function panScale(scale, delta) {
	var fn = panFunctions[scale.options.type];
	if (fn) {
		fn(scale, delta);
	}
}

function doPan(chartInstance, deltaX, deltaY) {
	var panOptions = chartInstance.options.pan;
	if (panOptions && helpers.getValueOrDefault(panOptions.enabled, defaultOptions.pan.enabled)) {
		var panMode = helpers.getValueOrDefault(chartInstance.options.pan.mode, defaultOptions.pan.mode);

		helpers.each(chartInstance.scales, function(scale, id) {
			if (scale.isHorizontal() && directionEnabled(panMode, 'x') && deltaX !== 0) {
				panScale(scale, deltaX);
			} else if (!scale.isHorizontal() && directionEnabled(panMode, 'y') && deltaY !== 0) {
				panScale(scale, deltaY);
			}
		});

		chartInstance.update(0);
	}
}

function positionInChartArea(chartInstance, position) {
	return 	(position.x >= chartInstance.chartArea.left && position.x <= chartInstance.chartArea.right) &&
			(position.y >= chartInstance.chartArea.top && position.y <= chartInstance.chartArea.bottom);
}

// Store these for later
zoomNS.zoomFunctions.category = zoomIndexScale;
zoomNS.zoomFunctions.time = zoomTimeScale;
zoomNS.zoomFunctions.linear = zoomNumericalScale;
zoomNS.zoomFunctions.logarithmic = zoomNumericalScale;
zoomNS.panFunctions.category = panIndexScale;
zoomNS.panFunctions.time = panTimeScale;
zoomNS.panFunctions.linear = panNumericalScale;
zoomNS.panFunctions.logarithmic = panNumericalScale;

// Chartjs Zoom Plugin
var zoomPlugin = {
	beforeInit: function(chartInstance) {
		var node = chartInstance.chart.ctx.canvas;
		var options = chartInstance.options;
		var panThreshold = helpers.getValueOrDefault(options.pan ? options.pan.threshold : undefined, zoomNS.defaults.pan.threshold);

		var wheelHandler = function(e) {
			var rect = e.target.getBoundingClientRect();
			var offsetX = e.clientX - rect.left;
			var offsetY = e.clientY - rect.top;

			var center = {
				x : offsetX,
				y : offsetY
			};

			if (e.deltaY < 0) {
				doZoom(chartInstance, 1.1, center);
			} else {
				doZoom(chartInstance, 0.909, center);
			}
		};
		chartInstance._wheelHandler = wheelHandler;

		node.addEventListener('wheel', wheelHandler);

		if (Hammer) {
			var mc = new Hammer.Manager(node);
			mc.add(new Hammer.Pinch());
			mc.add(new Hammer.Pan({
				threshold: panThreshold
			}));

			// Hammer reports the total scaling. We need the incremental amount
			var currentPinchScaling;
			var handlePinch = function handlePinch(e) {
				var diff = 1 / (currentPinchScaling) * e.scale;
				doZoom(chartInstance, diff, e.center);

				// Keep track of overall scale
				currentPinchScaling = e.scale;
			};

			mc.on('pinchstart', function(e) {
				currentPinchScaling = 1; // reset tracker
			});
			mc.on('pinch', handlePinch);
			mc.on('pinchend', function(e) {
				handlePinch(e);
				currentPinchScaling = null; // reset
			});

			var currentDeltaX = null, currentDeltaY = null;
			var handlePan = function handlePan(e) {
				if (currentDeltaX !== null && currentDeltaY !== null) {
					var deltaX = e.deltaX - currentDeltaX;
					var deltaY = e.deltaY - currentDeltaY;
					currentDeltaX = e.deltaX;
					currentDeltaY = e.deltaY;

					doPan(chartInstance, deltaX, deltaY);
				}
			};

			mc.on('panstart', function(e) {
				currentDeltaX = 0;
				currentDeltaY = 0;
				handlePan(e);
			});
			mc.on('panmove', handlePan);
			mc.on('panend', function(e) {
				currentDeltaX = null;
				currentDeltaY = null;
			});
			chartInstance._mc = mc;
		}
	},

	beforeDatasetsDraw: function(chartInstance) {
		var ctx = chartInstance.chart.ctx;
		var chartArea = chartInstance.chartArea;
		ctx.save();
		ctx.beginPath();
		ctx.rect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
		ctx.clip();
	},

	afterDatasetsDraw: function(chartInstance) {
		chartInstance.chart.ctx.restore();
	},

	destroy: function(chartInstance) {
		var node = chartInstance.chart.ctx.canvas;
		node.removeEventListener('wheel', chartInstance._wheelHandler);

		var mc = chartInstance._mc;
		if (mc) {
			mc.remove('pinchstart');
			mc.remove('pinch');
			mc.remove('pinchend');
			mc.remove('panstart');
			mc.remove('pan');
			mc.remove('panend');
		}
	}
};

Chart.pluginService.register(zoomPlugin);
<|endoftext|>


<commit_before>#!/usr/bin/node

'use strict'

const { resolve } = require('path')
const convert = require('../convert.js')
const argv = require('minimist')(process.argv.slice(2))
const selectSyntax = require('./select-syntax.js')
const init = require('./init.js')
const path = require('path')
const installAirline = require('./install-airline.js')
const installLightline = require('./install-lightline.js')
const projectPath = resolve('.')

const updateNotifier = require('update-notifier')
const pkg = require('../../package.json')

updateNotifier({
  pkg,
  updateCheckInterval: 1000 * 60 * 60 * 24 // 1 day
}).notify()

const command = argv._[0]

if (!command || command === 'help') {
  showHelp()
} else if (command === 'render') {
  convert(projectPath)
} else if (command === 'add-syntax') {
  selectSyntax(projectPath)
} else if (command === 'init') {
  init(path.resolve(argv._[1] || '.'), argv.y)
} else if (command === 'add-airline') {
  installAirline(projectPath)
} else if (command === 'add-lightline') {
  installLightline(projectPath)
} else {
  console.log('Command not found')
  showHelp()
}

function showHelp () {
  console.log(`
  Usage: estilo [command]

  Commands:

    init                Initialize an estilo project in current folder
    render              Render all the colorschemes and themes
    add-syntax          Opens dialog for adding more syntax templates
    add-airline         Opens dialog for adding a new Airline style
    add-lightline       Opens dialog for adding a new Lightline style
    help                Show this help
`)
}

<commit_msg>fix(): fix interpreter error Closes #23<commit_after>#!/usr/bin/env node

'use strict'

const { resolve } = require('path')
const convert = require('../convert.js')
const argv = require('minimist')(process.argv.slice(2))
const selectSyntax = require('./select-syntax.js')
const init = require('./init.js')
const path = require('path')
const installAirline = require('./install-airline.js')
const installLightline = require('./install-lightline.js')
const projectPath = resolve('.')

const updateNotifier = require('update-notifier')
const pkg = require('../../package.json')

updateNotifier({
  pkg,
  updateCheckInterval: 1000 * 60 * 60 * 24 // 1 day
}).notify()

const command = argv._[0]

if (!command || command === 'help') {
  showHelp()
} else if (command === 'render') {
  convert(projectPath)
} else if (command === 'add-syntax') {
  selectSyntax(projectPath)
} else if (command === 'init') {
  init(path.resolve(argv._[1] || '.'), argv.y)
} else if (command === 'add-airline') {
  installAirline(projectPath)
} else if (command === 'add-lightline') {
  installLightline(projectPath)
} else {
  console.log('Command not found')
  showHelp()
}

function showHelp () {
  console.log(`
  Usage: estilo [command]

  Commands:

    init                Initialize an estilo project in current folder
    render              Render all the colorschemes and themes
    add-syntax          Opens dialog for adding more syntax templates
    add-airline         Opens dialog for adding a new Airline style
    add-lightline       Opens dialog for adding a new Lightline style
    help                Show this help
`)
}

<|endoftext|>