<commit_before>#!/bin/env node

/* Add modules */
var express = require('express'),
	app = express(),
	fs = require('fs'),
	http = require('http'),
	jade = require('jade'),
	routes = require('./routes'),
	passport = require('passport'),
	user = require('./routes/user'),
	flash = require('connect-flash'),
	db = require('./config/database'),
	config = require('./config/config'),
	emailing = require('./config/email'),
	auth = require('./config/authentication'),
	MongoStore = require('connect-mongo')(express),
	expressValidator = require('express-validator');

/* Create a session store that is connected to the users */
var SessionStore = new MongoStore({ url: config.database_url });
/* Set app properties */
app.set('view engine', 'jade');
app.use(express.static(__dirname + "/public"));
app.use(express.json());
app.use(express.urlencoded());
app.use(expressValidator());
app.use(express.logger('dev'));
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
	secret: config.session_secret,
	store: SessionStore
}));
app.use(flash());
/* Set the view variables */
app.use(function(req, res, next) {
  res.locals.error = req.flash('error');
  res.locals.email = req.flash('email');
  res.locals.message = req.flash('message');
  res.locals.username = req.flash('username');
  next();
});
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);

/* Error handling */
app.use(function(err, req, res, next) {
    /* Check error information and respond accordingly */
    console.log("ERROR", "app error:", err);
    res.sendfile(__dirname + '/public/html/error.html');
    /* Send the error report to the admin */
    emailing.sendErrorReport(config.admin_name, config.admin_email, err);
});

/* Development only */
if ('development' == app.get('env')) {
	app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
}

/* Landingpage */
app.get('/', routes.index);

/* Login and registration */
app.get('/login', auth.checkLogin, user.login);
app.all('/signup', auth.checkLogin, user.signup);
app.get('/signup/:id', auth.checkLogin, user.verify);
app.all('/forgot', auth.checkLogin, user.forgotPassword);

app.post('/login', passport.authenticate('local', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get(config.google.auth, passport.authenticate('google', { scope: config.google.gdata_scopes }));
app.get(config.google.callback, passport.authenticate('google', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get(config.twitter.auth, passport.authenticate('twitter'));
app.get(config.twitter.callback, passport.authenticate('twitter', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

/* Facebook Oauth2 bug appends #_=_ to the callback URL */
app.get(config.facebook.auth, passport.authenticate('facebook', { scope: ['email'] }));
app.get(config.facebook.callback, passport.authenticate('facebook', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get(config.linkedin.auth, passport.authenticate('linkedin', { scope: ['r_basicprofile', 'r_emailaddress'] }));
app.get(config.linkedin.callback, passport.authenticate('linkedin', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get(config.github.auth, passport.authenticate('github'));
app.get(config.github.callback, passport.authenticate('github', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get('/logout', user.logout);

/* Different tabs */
app.get('/chat', routes.chat);
app.get('/study', routes.study);
app.all('/coding', routes.coding);
app.get('/sumorobot', routes.sumorobot);
app.get('/dashboard', auth.ensureAuthenticated, routes.dashboard);

/* Profile pages */
app.get('/profile', auth.ensureAuthenticated, user.profile);
app.get('/:name', auth.ensureAuthenticated, user.detailed);
app.post('/profile/update', auth.ensureAuthenticated, user.profileUpdate);
app.post('/profile/password', auth.ensureAuthenticated, user.passwordUpdate);
app.get('/profile/remove/:name', auth.ensureAuthenticated, user.providerRemove);
app.get('/profile/mugshot/:provider', auth.ensureAuthenticated, user.mugshotUpdate);

/* Show all the users and providers and tasks */
db.User.find(function(err, users) {
	if (err) return new Error(err);
	else users.forEach(function(user) {
		console.log("INFO", "user name:", user.name);
	});
});
db.Provider.find(function(err, providers) {
	if (err) return new Error(err);
	else providers.forEach(function(provider) {
		console.log("INFO", "provider url:", provider.url);
	});
});
db.Task.find(function(err, tasks) {
	if (err) return new Error(err);
	else tasks.forEach(function(task) {
		console.log("INFO", "task:", task.name);
	});
});

/* Start the app and sockets */
var server = http.createServer(app).listen(config.port, function() {
	console.log("INFO", "express server listening on port:", config.port);
	var socket = require('./config/socket');
});

/* Export items for other modules */
exports.server = server;
exports.SessionStore = SessionStore;<commit_msg>app.js added cookie max age<commit_after>#!/bin/env node

/* Add modules */
var express = require('express'),
	app = express(),
	fs = require('fs'),
	http = require('http'),
	jade = require('jade'),
	routes = require('./routes'),
	passport = require('passport'),
	user = require('./routes/user'),
	flash = require('connect-flash'),
	db = require('./config/database'),
	config = require('./config/config'),
	emailing = require('./config/email'),
	auth = require('./config/authentication'),
	MongoStore = require('connect-mongo')(express),
	expressValidator = require('express-validator');

/* Create a session store that is connected to the users */
var SessionStore = new MongoStore({ url: config.database_url });
/* Set app properties */
app.set('view engine', 'jade');
app.use(express.static(__dirname + "/public"));
app.use(express.json());
app.use(express.urlencoded());
app.use(expressValidator());
app.use(express.logger('dev'));
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({
	store: SessionStore,
	secret: config.session_secret,
	cookie: { maxAge : 3600000 * 24 * 3 }, // 3 days
}));
app.use(flash());
/* Set the view variables */
app.use(function(req, res, next) {
  res.locals.error = req.flash('error');
  res.locals.email = req.flash('email');
  res.locals.message = req.flash('message');
  res.locals.username = req.flash('username');
  next();
});
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);

/* Error handling */
app.use(function(err, req, res, next) {
    /* Check error information and respond accordingly */
    console.log("ERROR", "app error:", err);
    res.sendfile(__dirname + '/public/html/error.html');
    /* Send the error report to the admin */
    emailing.sendErrorReport(config.admin_name, config.admin_email, err);
});

/* Development only */
if ('development' == app.get('env')) {
	app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
}

/* Landingpage */
app.get('/', routes.index);

/* Login and registration */
app.get('/login', auth.checkLogin, user.login);
app.all('/signup', auth.checkLogin, user.signup);
app.get('/signup/:id', auth.checkLogin, user.verify);
app.all('/forgot', auth.checkLogin, user.forgotPassword);

app.post('/login', passport.authenticate('local', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get(config.google.auth, passport.authenticate('google', { scope: config.google.gdata_scopes }));
app.get(config.google.callback, passport.authenticate('google', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get(config.twitter.auth, passport.authenticate('twitter'));
app.get(config.twitter.callback, passport.authenticate('twitter', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

/* Facebook Oauth2 bug appends #_=_ to the callback URL */
app.get(config.facebook.auth, passport.authenticate('facebook', { scope: ['email'] }));
app.get(config.facebook.callback, passport.authenticate('facebook', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get(config.linkedin.auth, passport.authenticate('linkedin', { scope: ['r_basicprofile', 'r_emailaddress'] }));
app.get(config.linkedin.callback, passport.authenticate('linkedin', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get(config.github.auth, passport.authenticate('github'));
app.get(config.github.callback, passport.authenticate('github', { successRedirect: '/profile', failureRedirect: '/login', failureFlash: true }));

app.get('/logout', user.logout);

/* Different tabs */
app.get('/chat', routes.chat);
app.get('/study', routes.study);
app.all('/coding', routes.coding);
app.get('/sumorobot', routes.sumorobot);
app.get('/dashboard', auth.ensureAuthenticated, routes.dashboard);

/* Profile pages */
app.get('/profile', auth.ensureAuthenticated, user.profile);
app.get('/:name', auth.ensureAuthenticated, user.detailed);
app.post('/profile/update', auth.ensureAuthenticated, user.profileUpdate);
app.post('/profile/password', auth.ensureAuthenticated, user.passwordUpdate);
app.get('/profile/remove/:name', auth.ensureAuthenticated, user.providerRemove);
app.get('/profile/mugshot/:provider', auth.ensureAuthenticated, user.mugshotUpdate);

/* Show all the users and providers and tasks */
db.User.find(function(err, users) {
	if (err) return new Error(err);
	else users.forEach(function(user) {
		console.log("INFO", "user name:", user.name);
	});
});
db.Provider.find(function(err, providers) {
	if (err) return new Error(err);
	else providers.forEach(function(provider) {
		console.log("INFO", "provider url:", provider.url);
	});
});
db.Task.find(function(err, tasks) {
	if (err) return new Error(err);
	else tasks.forEach(function(task) {
		console.log("INFO", "task:", task.name);
	});
});

/* Start the app and sockets */
var server = http.createServer(app).listen(config.port, function() {
	console.log("INFO", "express server listening on port:", config.port);
	var socket = require('./config/socket');
});

/* Export items for other modules */
exports.server = server;
exports.SessionStore = SessionStore;<|endoftext|>


<commit_before>import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Link } from 'react-router';

import { closeMessage } from '../../store/uiReducer';

import Alert from '../Alert/Alert';
import Loader from '../Loader';
import './Header.scss';

export const Header = ({ isFetching, message, closeMessage }) => {
  return (

        <Link to='/' className='brand-title navbar-brand'>Tiedonohjausjärjestelmä Alpha v0.1.4</Link>

      {isFetching &&
      <Loader />
      }
      {message.text !== '' &&
      <Alert
        message={message.text}
        style={(message.success ? 'alert-success' : 'alert-danger')}
        close={closeMessage}
      />
      }

  );
};

Header.propTypes = {
  closeMessage: React.propTypes.func,
  isFetching: React.PropTypes.bool,
  message: React.PropTypes.object
};

const mapStateToProps = (state) => {
  return {
    message: state.ui.message,
    isFetching: state.ui.isFetching || state.navigation.isFetching || state.selectedTOS.isFetching
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    closeMessage: bindActionCreators(closeMessage, dispatch)
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Header);
<commit_msg>Fix faulty propType<commit_after>import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Link } from 'react-router';

import { closeMessage } from '../../store/uiReducer';

import Alert from '../Alert/Alert';
import Loader from '../Loader';
import './Header.scss';

export const Header = ({ isFetching, message, closeMessage }) => {
  return (

        <Link to='/' className='brand-title navbar-brand'>Tiedonohjausjärjestelmä Alpha v0.1.4</Link>

      {isFetching &&
      <Loader />
      }
      {message.text !== '' &&
      <Alert
        message={message.text}
        style={(message.success ? 'alert-success' : 'alert-danger')}
        close={closeMessage}
      />
      }

  );
};

Header.propTypes = {
  closeMessage: React.PropTypes.func,
  isFetching: React.PropTypes.bool,
  message: React.PropTypes.object
};

const mapStateToProps = (state) => {
  return {
    message: state.ui.message,
    isFetching: state.ui.isFetching || state.navigation.isFetching || state.selectedTOS.isFetching
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    closeMessage: bindActionCreators(closeMessage, dispatch)
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Header);
<|endoftext|>


<commit_before>/*! SocialCount - v0.1.0 - 2012-07-24
* https://github.com/filamentgroup/SocialCount
* Copyright (c) 2012 zachleat; Licensed MIT */

(function( win, doc, $ ) {

	var $loadingIndicator,
		$count,
		cache = {};

	function featureTest( prop, unprefixedProp )
	{
		var style = doc.createElement('social').style,
			prefixes = 'webkit Moz o ms'.split(' ');

		if( unprefixedProp in style ) {
			return true;
		}
		for( var j = 0, k = prefixes.length; j < k; j++ ) {
			if( ( prefixes[ j ] + prop ) in style ) {
				return true;
			}
		}
		return false;
	}

	var SocialCount = {
		showCounts: true,
		minCount: 50,
		serviceUrl: '../service/index.php',
		initSelector: '.socialcount',
		jsClass: 'js',
		activeClass: 'active',
		noTransformsClass: 'no-transforms',
		showCountsClass: 'counts',
		countContentClass: 'count',
		minCountClass: 'minimum',
		thousandCharacter: 'K',
		millionCharacter: 'M',
		missingResultText: '-',
		classes: {
			facebook: '.facebook',
			twitter: '.twitter',
			googleplus: '.googleplus'
		},
		plugins: {
			init: [],
			bind: []
		},

		isCssAnimations: function()
		{
			return featureTest( 'AnimationName', 'animationName' );
		},
		isCssTransforms: function()
		{
			return featureTest( 'Transform', 'transform' );
		},
		init: function( $el ) {
			var map = SocialCount.classes,
				counts = {},
				url = $el.attr('data-url') || location.href,
				facebookAction = ( $el.attr('data-facebook-action' ) || 'like' ).toLowerCase(),
				classes = [ SocialCount.jsClass, facebookAction ],
				isSmall = $el.is( '.socialcount-small' ),
				$networkNode,
				$countNode,
				initPlugins = SocialCount.plugins.init;

			if( !SocialCount.isCssTransforms() ) {
				classes.push( SocialCount.noTransformsClass );
			}
			if( SocialCount.showCounts ) {
				classes.push( SocialCount.showCountsClass );
			}
			$el.addClass( classes.join(' ') );

			for( var j = 0, k = initPlugins.length; j < k; j++ ) {
				initPlugins[ j ].call( $el );
			}

			if( SocialCount.showCounts && !isSmall ) {
				for( var j in map ) {
					$networkNode = $el.find( map[ j ] );
					$countNode = $networkNode.find( '.' + SocialCount.countContentClass );

					if( $countNode.length ) {
						counts[ j ] = $countNode;
					} else {
						counts[ j ] = $count.clone();
						$networkNode.append( counts[ j ] );
					}
				}

				if( !cache[ url ] ) {
					cache[ url ] = SocialCount.fetch( url );
				}

				cache[ url ].done( function complete( data )
				{
					for( var j in data ) {
						if( data.hasOwnProperty( j ) ) {
							if( data[ j ] > SocialCount.minCount ) {
								counts[ j ].addClass( SocialCount.minCountClass )
									.html( SocialCount.normalizeCount( data[ j ] ) );
							}
						}
					}
				});
			}

			// Require querySelector or if Blackberry require OS >= 6
			if( 'querySelectorAll' in doc && !( win.blackberry && !win.WebKitPoint )) {
				SocialCount.bindEvents( $el, url, facebookAction, isSmall );
			}
		},
		fetch: function( url ) {
			return $.ajax({
				url: SocialCount.serviceUrl,
				data: {
					url: url
				},
				dataType: 'json'
			});
		},
		normalizeCount: function( count )
		{
			if( !count && count !== 0 ) {
				return SocialCount.missingResultText;
			}
			// > 1M
			if( count >= 1000000 ) {
				return Math.floor( count / 1000000 ) + SocialCount.millionCharacter;
			}
			// > 100K
			if( count >= 100000 ) {
				return Math.floor( count / 1000 ) + SocialCount.thousandCharacter;
			}
			if( count > 1000 ) {
				return ( count / 1000 ).toFixed(1).replace( /\.0/, '' ) + SocialCount.thousandCharacter;
			}
			return count;
		},
		bindEvents: function( $el, url, facebookAction, isSmall )
		{
			function removeLoader( $parent, $loading )
			{
				var $iframe = $parent.find('iframe');

				if( $iframe.length ) {
					$iframe.bind( 'load', function() {
						$loading.remove();
					});
				} else {
					$loading.remove();
				}
			}

			function bind( $a, html, jsUrl )
			{
				$a.one( 'click', function( event ) {
						$( this ).trigger( 'mouseover' );
						event.preventDefault();
					}).one( 'mouseover', function() {
						var $self = $( this ),
							$parent = $self.closest( 'li' ),
							$loading = $loadingIndicator.clone(),
							$content = $( html ),
							$button = $( '
' ).append( $content ),
							js,
							$iframe;

						$parent
							.addClass( SocialCount.activeClass )
							.append( $loading )
							.append( $button );

						if( jsUrl ) {
							js = doc.createElement( 'script' );
							js.src = jsUrl;

							// IE8 doesn't do script onload.
							if( js.attachEvent ) {
								js.attachEvent( 'onreadystatechange', function()
								{
									if( js.readyState === 'complete' ) {
										removeLoader( $parent, $loading );
									}
								});
							} else {
								$(js).bind( 'load', function() {
									removeLoader( $parent, $loading );
								});
							}

							doc.body.appendChild( js );
						} else if( $content.is( 'iframe' ) ) {
							removeLoader( $parent, $loading );
						}
					});
			}

			if( !isSmall ) {
				bind( $el.find( SocialCount.classes.facebook + ' a' ),
					'' );

				bind( $el.find( SocialCount.classes.twitter + ' a' ),
					'Tweet',
					'//platform.twitter.com/widgets.js' );

				bind( $el.find( SocialCount.classes.googleplus + ' a' ),
					'

',
					'//apis.google.com/js/plusone.js' );
			}

			var bindPlugins = SocialCount.plugins.bind;
			for( var j = 0, k = bindPlugins.length; j < k; j++ ) {
				bindPlugins[ j ].call( $el, bind, url, isSmall );
			}
		}
	};

	$(function() {
		// Thanks to http://codepen.io/ericmatthys/pen/FfcEL
		$loadingIndicator = $('
')
			.addClass('loading')
			.html( SocialCount.isCssAnimations() ? new Array(4).join('

') : 'Loading' );

		if( SocialCount.showCounts ) {
			$count = $('')
				.addClass( SocialCount.countContentClass )
				.html(' ');
		}

		$( SocialCount.initSelector ).each(function()
		{
			var $el = $(this);
			SocialCount.init($el);
		});
	});

	window.SocialCount = SocialCount;

}( window, window.document, jQuery ));<commit_msg>Use a deferred for loader removal.<commit_after>/*! SocialCount - v0.1.0 - 2012-07-24
* https://github.com/filamentgroup/SocialCount
* Copyright (c) 2012 zachleat; Licensed MIT */

(function( win, doc, $ ) {

	var $loadingIndicator,
		$count,
		cache = {};

	function featureTest( prop, unprefixedProp )
	{
		var style = doc.createElement('social').style,
			prefixes = 'webkit Moz o ms'.split(' ');

		if( unprefixedProp in style ) {
			return true;
		}
		for( var j = 0, k = prefixes.length; j < k; j++ ) {
			if( ( prefixes[ j ] + prop ) in style ) {
				return true;
			}
		}
		return false;
	}

	var SocialCount = {
		showCounts: true,
		minCount: 50,
		serviceUrl: '../service/index.php',
		initSelector: '.socialcount',
		jsClass: 'js',
		activeClass: 'active',
		noTransformsClass: 'no-transforms',
		showCountsClass: 'counts',
		countContentClass: 'count',
		minCountClass: 'minimum',
		thousandCharacter: 'K',
		millionCharacter: 'M',
		missingResultText: '-',
		classes: {
			facebook: '.facebook',
			twitter: '.twitter',
			googleplus: '.googleplus'
		},
		plugins: {
			init: [],
			bind: []
		},

		isCssAnimations: function()
		{
			return featureTest( 'AnimationName', 'animationName' );
		},
		isCssTransforms: function()
		{
			return featureTest( 'Transform', 'transform' );
		},
		init: function( $el ) {
			var map = SocialCount.classes,
				counts = {},
				url = $el.attr('data-url') || location.href,
				facebookAction = ( $el.attr('data-facebook-action' ) || 'like' ).toLowerCase(),
				classes = [ SocialCount.jsClass, facebookAction ],
				isSmall = $el.is( '.socialcount-small' ),
				$networkNode,
				$countNode,
				initPlugins = SocialCount.plugins.init;

			if( !SocialCount.isCssTransforms() ) {
				classes.push( SocialCount.noTransformsClass );
			}
			if( SocialCount.showCounts ) {
				classes.push( SocialCount.showCountsClass );
			}
			$el.addClass( classes.join(' ') );

			for( var j = 0, k = initPlugins.length; j < k; j++ ) {
				initPlugins[ j ].call( $el );
			}

			if( SocialCount.showCounts && !isSmall ) {
				for( var j in map ) {
					$networkNode = $el.find( map[ j ] );
					$countNode = $networkNode.find( '.' + SocialCount.countContentClass );

					if( $countNode.length ) {
						counts[ j ] = $countNode;
					} else {
						counts[ j ] = $count.clone();
						$networkNode.append( counts[ j ] );
					}
				}

				if( !cache[ url ] ) {
					cache[ url ] = SocialCount.fetch( url );
				}

				cache[ url ].done( function complete( data )
				{
					for( var j in data ) {
						if( data.hasOwnProperty( j ) ) {
							if( data[ j ] > SocialCount.minCount ) {
								counts[ j ].addClass( SocialCount.minCountClass )
									.html( SocialCount.normalizeCount( data[ j ] ) );
							}
						}
					}
				});
			}

			// Require querySelector or if Blackberry require OS >= 6
			if( 'querySelectorAll' in doc && !( win.blackberry && !win.WebKitPoint )) {
				SocialCount.bindEvents( $el, url, facebookAction, isSmall );
			}
		},
		fetch: function( url ) {
			return $.ajax({
				url: SocialCount.serviceUrl,
				data: {
					url: url
				},
				dataType: 'json'
			});
		},
		normalizeCount: function( count )
		{
			if( !count && count !== 0 ) {
				return SocialCount.missingResultText;
			}
			// > 1M
			if( count >= 1000000 ) {
				return Math.floor( count / 1000000 ) + SocialCount.millionCharacter;
			}
			// > 100K
			if( count >= 100000 ) {
				return Math.floor( count / 1000 ) + SocialCount.thousandCharacter;
			}
			if( count > 1000 ) {
				return ( count / 1000 ).toFixed(1).replace( /\.0/, '' ) + SocialCount.thousandCharacter;
			}
			return count;
		},
		bindEvents: function( $el, url, facebookAction, isSmall ) {
			function bind( $a, html, jsUrl ) {
				$a.one( 'click', function( event ) {
						$( this ).trigger( 'mouseover' );
						event.preventDefault();
					}).one( 'mouseover', function() {
						var $self = $( this ),
							$parent = $self.closest( 'li' ),
							$loading = $loadingIndicator.clone(),
							$content = $( html ),
							$button = $( '
' ).append( $content ),
							js,
							$iframe,
							deferred = $.Deferred();

						deferred.promise().always(function() {
							// Remove Loader
							var $iframe = $parent.find('iframe');

							if( $iframe.length ) {
								$iframe.bind( 'load', function() {
									$loading.remove();
								});
							} else {
								$loading.remove();
							}
						});

						$parent
							.addClass( SocialCount.activeClass )
							.append( $loading )
							.append( $button );

						if( jsUrl ) {
							js = doc.createElement( 'script' );
							js.src = jsUrl;

							// IE8 doesn't do script onload.
							if( js.attachEvent ) {
								js.attachEvent( 'onreadystatechange', function() {
									if( js.readyState === 'complete' ) {
										deferred.resolve();
									}
								});
							} else {
								$(js).bind( 'load', deferred.resolve );
							}

							doc.body.appendChild( js );
						} else if( $content.is( 'iframe' ) ) {
							deferred.resolve();
						}
					});
			}

			if( !isSmall ) {
				bind( $el.find( SocialCount.classes.facebook + ' a' ),
					'' );

				bind( $el.find( SocialCount.classes.twitter + ' a' ),
					'Tweet',
					'//platform.twitter.com/widgets.js' );

				bind( $el.find( SocialCount.classes.googleplus + ' a' ),
					'

',
					'//apis.google.com/js/plusone.js' );
			}

			var bindPlugins = SocialCount.plugins.bind;
			for( var j = 0, k = bindPlugins.length; j < k; j++ ) {
				bindPlugins[ j ].call( $el, bind, url, isSmall );
			}
		}
	};

	$(function() {
		// Thanks to http://codepen.io/ericmatthys/pen/FfcEL
		$loadingIndicator = $('
')
			.addClass('loading')
			.html( SocialCount.isCssAnimations() ? new Array(4).join('

') : 'Loading' );

		if( SocialCount.showCounts ) {
			$count = $('')
				.addClass( SocialCount.countContentClass )
				.html(' ');
		}

		$( SocialCount.initSelector ).each(function()
		{
			var $el = $(this);
			SocialCount.init($el);
		});
	});

	window.SocialCount = SocialCount;

}( window, window.document, jQuery ));<|endoftext|>


<commit_before>'use strict';

import { REQUEST_TIMEOUT } from '../lib/constants';
import { default as baseRequest } from 'request';
import { default as moment } from 'moment-timezone';
import cheerio from 'cheerio';
import { convertUnits } from '../lib/utils';
const request = baseRequest.defaults({timeout: REQUEST_TIMEOUT});

export const name = 'senamhi';

export function fetchData (source, cb) {
  request(source.url, (err, res, body) => {
    if (err || res.statusCode !== 200) {
      return cb(err || res);
    }

    // Wrap everything in a try/catch in case something goes wrong
    try {
      // Format the data
      const data = formatData(body);
      if (data === undefined) {
        return cb({message: 'Failure to parse data.'});
      }
      cb(null, data);
    } catch (e) {
      return cb({message: 'Unknown adapter error.'});
    }
  });
}

const formatData = function (results) {
  let measurements = [];
  const $ = cheerio.load(results);

  // We're looking for the script tag with the locations in it
  let scriptText;
  $('script').each((i, elem) => {
    if ($(elem).contents().get(0) && $(elem).contents().get(0).data.indexOf('var locations =') !== -1) {
      scriptText = $(elem).contents().get(0).data;
    }
  });

  // Exit if no matching script
  if (scriptText === undefined) {
    return undefined;
  }

  // Some magic to break down a string that represents a JS array into an array
  const locations = eval(/var locations = (.*)/.exec(scriptText)[1]); // eslint-disable-line no-eval

  // Loop over each location and create measurements
  // TODO, loop over all
  locations.forEach((l) => {
    // The HTML element stored in the JS ¯\_(ツ)_/¯
    const html = cheerio.load(l[4]);

    // Make sure we've got some valid html in here and not an error message
    if (!html('td', html('tr').eq(0)).eq(1).html()) {
      return;
    }

    // Location name
    const location = html('td', html('tr').eq(0)).eq(1).html().trim();

    // Convert DMS to decimal degrees for fun
    const coordsRe = /.*: (\d*)°(\d*)′(\d*\.?\d*)″ .*: (\d*)°(\d*)′(\d*\.?\d*)″/.exec(html('td', html('tr').eq(2)).eq(1).html().trim());
    const coordinates = {
      latitude: -1.0 * (Number(coordsRe[1]) + Number(coordsRe[2]) / 60.0 + Number(coordsRe[3]) / 3600.0).toFixed(6),
      longitude: -1.0 * (Number(coordsRe[4]) + Number(coordsRe[5]) / 60.0 + Number(coordsRe[6]) / 3600.0).toFixed(6)
    };

    // Create our base object
    const base = {
      location: location,
      coordinates: coordinates,
      city: 'Lima',
      attribution: [{'name': 'Peru Ministerio de Ambiente', 'url': 'http://www.senamhi.gob.pe/'}],
      averagingPeriod: {'value': 1, 'unit': 'hours'},
      unit: 'µg/m³'
    };

    // Filter out for <td> that match the format we want for the concentrations
    let ms = html('tr').filter((i, elem) => {
      return /^\d{2}\/\d{2}\/\d{4}$/.test(html('td', elem).first().text().trim());
    });

    // Loop over first 4 time rows to minimize number of inserts to database upstream
    ms.each((i, m) => {
      if (i >= 4) {
        return;
      }

      // Helper function to handle empty strings
      const getNumber = function (string) {
        if (string === '') {
          return NaN;
        }

        return Number(string);
      };

      // Build the datetime
      const dt = moment.tz(`${html('td', m).eq(0).text().trim()} ${html('td', m).eq(1).text().trim()}`, 'DD/MM/YYYY HH:mm', 'America/Lima');

      // pm25
      let pm25 = Object.assign({
        value: getNumber(html('td', m).eq(2).text().trim()),
        parameter: 'pm25',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(pm25);

      // pm10
      let pm10 = Object.assign({
        value: getNumber(html('td', m).eq(3).text().trim()),
        parameter: 'pm10',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(pm10);

      // so2
      let so2 = Object.assign({
        value: getNumber(html('td', m).eq(4).text().trim()),
        parameter: 'so2',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(so2);

      // no2
      let no2 = Object.assign({
        value: getNumber(html('td', m).eq(5).text().trim()),
        parameter: 'no2',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(no2);

      // o3
      let o3 = Object.assign({
        value: getNumber(html('td', m).eq(6).text().trim()),
        parameter: 'o3',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(o3);

      // co
      let co = Object.assign({
        value: getNumber(html('td', m).eq(7).text().trim().replace(',', '')),
        parameter: 'co',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(co);
    });
  });

  // Be kind, convert units
  measurements = convertUnits(measurements);

  return {name: 'unused', measurements: measurements};
};
<commit_msg>Update regex to improve the converts coordinates for senamhi adapter<commit_after>'use strict';

import { REQUEST_TIMEOUT } from '../lib/constants';
import { default as baseRequest } from 'request';
import { default as moment } from 'moment-timezone';
import cheerio from 'cheerio';
import { convertUnits } from '../lib/utils';
const request = baseRequest.defaults({timeout: REQUEST_TIMEOUT});

export const name = 'senamhi';

export function fetchData (source, cb) {
  request(source.url, (err, res, body) => {
    if (err || res.statusCode !== 200) {
      return cb(err || res);
    }

    // Wrap everything in a try/catch in case something goes wrong
    try {
      // Format the data
      const data = formatData(body);
      if (data === undefined) {
        return cb({message: 'Failure to parse data.'});
      }
      cb(null, data);
    } catch (e) {
      return cb({message: 'Unknown adapter error.'});
    }
  });
}

const formatData = function (results) {
  let measurements = [];
  const $ = cheerio.load(results);

  // We're looking for the script tag with the locations in it
  let scriptText;
  $('script').each((i, elem) => {
    if ($(elem).contents().get(0) && $(elem).contents().get(0).data.indexOf('var locations =') !== -1) {
      scriptText = $(elem).contents().get(0).data;
    }
  });

  // Exit if no matching script
  if (scriptText === undefined) {
    return undefined;
  }

  // Some magic to break down a string that represents a JS array into an array
  const locations = eval(/var locations = (.*)/.exec(scriptText)[1]); // eslint-disable-line no-eval

  // Loop over each location and create measurements
  // TODO, loop over all
  locations.forEach((l) => {
    // The HTML element stored in the JS ¯\_(ツ)_/¯
    const html = cheerio.load(l[4]);

    // Make sure we've got some valid html in here and not an error message
    if (!html('td', html('tr').eq(0)).eq(1).html()) {
      return;
    }

    // Location name
    const location = html('td', html('tr').eq(0)).eq(1).html().trim();

    // Convert DMS to decimal degrees for fun
    const coordsRe = /: (\d[0-9]*)°([0-9]*)′([0-9]*\.?[0-9]*)″ .*: (\d[0-9]*)°([0-9]*)′([0-9]*\.?[0-9]*)″/gmi.exec(html('td', html('tr').eq(2)).eq(1).html().trim());
    var coordinates = null;

    if (coordsRe && coordsRe.length > 5) {
      coordinates = {
        latitude: -1.0 * (Number(coordsRe[1]) + Number(coordsRe[2]) / 60.0 + Number(coordsRe[3]) / 3600.0).toFixed(6),
        longitude: -1.0 * (Number(coordsRe[4]) + Number(coordsRe[5]) / 60.0 + Number(coordsRe[6]) / 3600.0).toFixed(6)
      };
    }

    // Create our base object
    const base = {
      location: location,
      coordinates: coordinates,
      city: 'Lima',
      attribution: [{'name': 'Peru Ministerio de Ambiente', 'url': 'http://www.senamhi.gob.pe/'}],
      averagingPeriod: {'value': 1, 'unit': 'hours'},
      unit: 'µg/m³'
    };

    // Filter out for <td> that match the format we want for the concentrations
    let ms = html('tr').filter((i, elem) => {
      return /^\d{2}\/\d{2}\/\d{4}$/.test(html('td', elem).first().text().trim());
    });

    // Loop over first 4 time rows to minimize number of inserts to database upstream
    ms.each((i, m) => {
      if (i >= 4) {
        return;
      }

      // Helper function to handle empty strings
      const getNumber = function (string) {
        if (string === '') {
          return NaN;
        }

        return Number(string);
      };

      // Build the datetime
      const dt = moment.tz(`${html('td', m).eq(0).text().trim()} ${html('td', m).eq(1).text().trim()}`, 'DD/MM/YYYY HH:mm', 'America/Lima');

      // pm25
      let pm25 = Object.assign({
        value: getNumber(html('td', m).eq(2).text().trim()),
        parameter: 'pm25',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(pm25);

      // pm10
      let pm10 = Object.assign({
        value: getNumber(html('td', m).eq(3).text().trim()),
        parameter: 'pm10',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(pm10);

      // so2
      let so2 = Object.assign({
        value: getNumber(html('td', m).eq(4).text().trim()),
        parameter: 'so2',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(so2);

      // no2
      let no2 = Object.assign({
        value: getNumber(html('td', m).eq(5).text().trim()),
        parameter: 'no2',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(no2);

      // o3
      let o3 = Object.assign({
        value: getNumber(html('td', m).eq(6).text().trim()),
        parameter: 'o3',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(o3);

      // co
      let co = Object.assign({
        value: getNumber(html('td', m).eq(7).text().trim().replace(',', '')),
        parameter: 'co',
        date: {
          utc: dt.toDate(),
          local: dt.format()
        }
      }, base);
      measurements.push(co);
    });
  });

  // Be kind, convert units
  measurements = convertUnits(measurements.filter(i => i.value));

  return {name: 'unused', measurements: measurements};
};
<|endoftext|>


<commit_before>"use strict";

/*global module, require*/

/*
 This file is where all the mess and wiring goes.
 We should aim to reduce its size.
*/

var log2 = function(n) {
    return Math.log(n) / Math.LN2;

};
var zoomToLayer = function(l) {
    if (l.boundingbox()) {
	var x1 = l.boundingbox()[0],
	    y1 = l.boundingbox()[1],
	    x2 = l.boundingbox()[2],
	    y2 = l.boundingbox()[3];

	var boxSize = Math.max(
	    Math.abs(x1 - x2),
	    Math.abs(y1 - y2));

	var newZoom = Math.round(
	    log2(360 / boxSize) + 1.5);
	console.log("new zoom " + newZoom);
	console.log("new bounds " + [(y1 + y2) / 2, (x1 + x2) / 2]);

	map.setView(
	    leaflet.latLng(
		(y1 + y2) / 2,
		(x1 + x2) / 2),
	    newZoom);
    }
};

var projectPoint = function(x, y) {
    var point = map.latLngToLayerPoint(new leaflet.LatLng(y, x));
    this.stream.point(point.x, point.y);
};

var sortedByZ = function() {
    return layers.enabled().slice(0).sort(function(a, b){
	return a.options.zIndex - b.options.zIndex;
    });
};

var paintDisplayColumn = function() {
    var displayData = worksheet.displayData(time.current());
    colour.paintSVGElements(displayData, selection.current());

    colour.unpaintHTML(resultsTable.cells());
    if (worksheet.getSortProperties().properties.length > 0) {
	colour.paintHTMLSelection(displayData, resultsTable.column(worksheet.propertyIndex(
	    worksheet.getSortProperties().properties[0])));
    }
};

var startCoordinates = [0, 0],
    zoom = 2,
    d3 = require("d3"),
    dialogue = require("floating-dialogue"),
    geocoder = require("leaflet-control-geocoder"),
    leaflet = require("leaflet"),

    body = d3.select("body"),
    mapDiv = body.append("div").attr("id", "map"),

    toolbar = body.append("div").attr("id", "toolbar"),

    worksheetOpenClose = toolbar.append("span")
	.html("⊞"),
    worksheetContainer = dialogue(
	body.append("div").attr("id", "worksheet"))
	.resize()
	.close()
	.open(worksheetOpenClose)
	.drag(),

    errors = require("./errors.js")(body, toolbar),
    time = require("./time-control.js")(body, toolbar, 2013, 2024, 2014),
    loader = require("./loader.js"),
    sources = require("./sources.js")(errors),
    layers = require("./layers.js")(errors, sources),
    geometries = require("./geometries.js"),

    baseLayers = require("./base-layers.js")(errors),
    title = require("./title.js")(body),
    transform = d3.geo.transform({point: projectPoint});

require("leaflet-fancy-layer-control");
require("./lib/d3-plugins/geo/tile/tile.js");

var nationalHeatMap = leaflet.tileLayer('http://test-tiles.0d9303a4.cdn.memsites.com/Total%20Heat%20Density/Z{z}/{y}/{x}.png', {
    attribution: 'English National Heat Map,',
    minZoom: 2,
    maxZoom: 17
}),

    map = new leaflet.Map("map", {
	doubleClickZoom: false
    })
	.addLayer(baseLayers.default())
	.setView(startCoordinates, zoom);

map.on('layerremove', function(event){
    layers.remove(event.layer);
});

/* The map will make us an svg. It will automatically sort out its bounds for us. */
map._initPathRoot();

var overlay = d3.select(map.getPanes().overlayPane)
	.select("svg")
	.attr("id", "overlay"),

    selection = require("./selection.js")(overlay);

map.addControl(new geocoder({
    email: "research@cse.org.uk"
}));

var layerOpacity = leaflet.Control.Layers.Opacity(),
    layerOrder = leaflet.Control.Layers.Order(),
    layerDelete = leaflet.Control.Layers.Delete(map),
    layerSelect = require("./layer-select.js")(leaflet, zoomToLayer, layers, selection, getLayerObjects, function(layer, name, overlay) {
	return layers.get(name) !== undefined;
    }),

    layersControl = new leaflet.Control.Layers.Extensible(
	baseLayers.dict,
	{
	    "National Heat Map" : nationalHeatMap
	},
	{
	    hooks : [layerOpacity],
	    baseHooks : [],
	    overlayHooks : [layerOrder, layerDelete, layerSelect]
	});

layersControl.addTo(map);
layers.layerCreated(function(l){
    map.addLayer(l);
    layersControl.addOverlay(l, l.name());
});

var paint = require("./paint.js")(overlay, transform, sortedByZ);
layerOpacity.opacityChanged(paint.redrawAll);

layerOrder.orderChanged(function(){
    paint.redrawAll();
    paintDisplayColumn();
});

var worksheet = require("./worksheet.js")(
	worksheetContainer,
	layers,
	sources,
	errors),
    resultsTable = require("./results-table.js")(worksheetContainer.content()),
    colour = require("./colour.js"),
    calculationsDisplay = require("./calculations-display.js")(worksheetContainer.content());

sources.onSourceLoad(worksheet.addSource);

var getLayerObjects = function(layerName) {
    return d3.select("#map svg g#" + layerName)
	.selectAll("path");
};

layers.layerChanged(function(l){
    if (!l.enabled) {
	selection.deselect(getLayerObjects(l.name()));
    }
    paint.redrawAll();
});
layers.layerRemoved(function(l){
    selection.deselect(getLayerObjects(l.name()));
    paint.redrawAll();
});

paint.addClickHandler(selection.clickHandler);

map.on("viewreset", paint.redrawAll);

selection.addCallback(function(values, entering, leaving){
    colour.unpaint(leaving);
    worksheet.selectionChanged(values, entering, leaving);
});

var handlers = require("./file-handlers.js")(
    errors,
    geometries,
    layers,
    sources,
    function(layer) {
	zoomToLayer(layer);
	selection.select(getLayerObjects(layer.name()), false);
    },
    paint.redrawAll
);
require("./file-drop.js")(d3.select("body"), errors, handlers);

resultsTable.headerClicked(function(h){
    worksheet.sortProperty(h, d3.event.shiftKey);
});
resultsTable.rowClicked(function(head, row){
    var shape = d3.select("g#" + row[0] + " path#" + row[1]);
    selection.select(shape, d3.event.shiftKey);
});

time.onChange(worksheet.timeChanged);

worksheet.dataChanged(function(){
    resultsTable.info(worksheet.propertyNames(), worksheet.allData(time.current()), worksheet.getSortProperties());
    calculationsDisplay.update(worksheet.sources());
    paintDisplayColumn();
});

var wikiStore = require("./wiki-store.js")(
    errors,
    body,
    toolbar,
    layers,
    worksheet,
    selection,
    title,
    function findShapesByName(names) {
	return d3.selectAll("#map svg g path")
	    .filter(function(d, i) {
		return names.has(d.layer.name() + "/" + d.id);
	    });
    },
    paint.redrawAll
);

require("./query-string.js")(map, layersControl, baseLayers, wikiStore, title, errors);
<commit_msg>Fixed layer selection.<commit_after>"use strict";

/*global module, require*/

/*
 This file is where all the mess and wiring goes.
 We should aim to reduce its size.
*/

var log2 = function(n) {
    return Math.log(n) / Math.LN2;

};
var zoomToLayer = function(l) {
    if (l.boundingbox()) {
	var x1 = l.boundingbox()[0],
	    y1 = l.boundingbox()[1],
	    x2 = l.boundingbox()[2],
	    y2 = l.boundingbox()[3];

	var boxSize = Math.max(
	    Math.abs(x1 - x2),
	    Math.abs(y1 - y2));

	var newZoom = Math.round(
	    log2(360 / boxSize) + 1.5);
	console.log("new zoom " + newZoom);
	console.log("new bounds " + [(y1 + y2) / 2, (x1 + x2) / 2]);

	map.setView(
	    leaflet.latLng(
		(y1 + y2) / 2,
		(x1 + x2) / 2),
	    newZoom);
    }
};

var projectPoint = function(x, y) {
    var point = map.latLngToLayerPoint(new leaflet.LatLng(y, x));
    this.stream.point(point.x, point.y);
};

var sortedByZ = function() {
    return layers.enabled().slice(0).sort(function(a, b){
	return a.options.zIndex - b.options.zIndex;
    });
};

var paintDisplayColumn = function() {
    var displayData = worksheet.displayData(time.current());
    colour.paintSVGElements(displayData, selection.current());

    colour.unpaintHTML(resultsTable.cells());
    if (worksheet.getSortProperties().properties.length > 0) {
	colour.paintHTMLSelection(displayData, resultsTable.column(worksheet.propertyIndex(
	    worksheet.getSortProperties().properties[0])));
    }
};

var getLayerObjects = function(layerName) {
    return d3.select("#map svg g#" + layerName)
	.selectAll("path");
};

var startCoordinates = [0, 0],
    zoom = 2,
    d3 = require("d3"),
    dialogue = require("floating-dialogue"),
    geocoder = require("leaflet-control-geocoder"),
    leaflet = require("leaflet"),

    body = d3.select("body"),
    mapDiv = body.append("div").attr("id", "map"),

    toolbar = body.append("div").attr("id", "toolbar"),

    worksheetOpenClose = toolbar.append("span")
	.html("⊞"),
    worksheetContainer = dialogue(
	body.append("div").attr("id", "worksheet"))
	.resize()
	.close()
	.open(worksheetOpenClose)
	.drag(),

    errors = require("./errors.js")(body, toolbar),
    time = require("./time-control.js")(body, toolbar, 2013, 2024, 2014),
    loader = require("./loader.js"),
    sources = require("./sources.js")(errors),
    layers = require("./layers.js")(errors, sources),
    geometries = require("./geometries.js"),

    baseLayers = require("./base-layers.js")(errors),
    title = require("./title.js")(body),
    transform = d3.geo.transform({point: projectPoint});

require("leaflet-fancy-layer-control");
require("./lib/d3-plugins/geo/tile/tile.js");

var nationalHeatMap = leaflet.tileLayer('http://test-tiles.0d9303a4.cdn.memsites.com/Total%20Heat%20Density/Z{z}/{y}/{x}.png', {
    attribution: 'English National Heat Map,',
    minZoom: 2,
    maxZoom: 17
}),

    map = new leaflet.Map("map", {
	doubleClickZoom: false
    })
	.addLayer(baseLayers.default())
	.setView(startCoordinates, zoom);

map.on('layerremove', function(event){
    layers.remove(event.layer);
});

/* The map will make us an svg. It will automatically sort out its bounds for us. */
map._initPathRoot();

var overlay = d3.select(map.getPanes().overlayPane)
	.select("svg")
	.attr("id", "overlay"),

    selection = require("./selection.js")(overlay);

map.addControl(new geocoder({
    email: "research@cse.org.uk"
}));

var layerOpacity = leaflet.Control.Layers.Opacity(),
    layerOrder = leaflet.Control.Layers.Order(),
    layerDelete = leaflet.Control.Layers.Delete(map),
    layerSelect = require("./layer-select.js")(leaflet, zoomToLayer, layers, selection, getLayerObjects, function(layer, name, overlay) {
	return layers.get(name) !== undefined;
    }),

    layersControl = new leaflet.Control.Layers.Extensible(
	baseLayers.dict,
	{
	    "National Heat Map" : nationalHeatMap
	},
	{
	    hooks : [layerOpacity],
	    baseHooks : [],
	    overlayHooks : [layerOrder, layerDelete, layerSelect]
	});

layersControl.addTo(map);
layers.layerCreated(function(l){
    map.addLayer(l);
    layersControl.addOverlay(l, l.name());
});

var paint = require("./paint.js")(overlay, transform, sortedByZ);
layerOpacity.opacityChanged(paint.redrawAll);

layerOrder.orderChanged(function(){
    paint.redrawAll();
    paintDisplayColumn();
});

var worksheet = require("./worksheet.js")(
	worksheetContainer,
	layers,
	sources,
	errors),
    resultsTable = require("./results-table.js")(worksheetContainer.content()),
    colour = require("./colour.js"),
    calculationsDisplay = require("./calculations-display.js")(worksheetContainer.content());

sources.onSourceLoad(worksheet.addSource);

layers.layerChanged(function(l){
    if (!l.enabled) {
	selection.deselect(getLayerObjects(l.name()));
    }
    paint.redrawAll();
});
layers.layerRemoved(function(l){
    selection.deselect(getLayerObjects(l.name()));
    paint.redrawAll();
});

paint.addClickHandler(selection.clickHandler);

map.on("viewreset", paint.redrawAll);

selection.addCallback(function(values, entering, leaving){
    colour.unpaint(leaving);
    worksheet.selectionChanged(values, entering, leaving);
});

var handlers = require("./file-handlers.js")(
    errors,
    geometries,
    layers,
    sources,
    function(layer) {
	zoomToLayer(layer);
	selection.select(getLayerObjects(layer.name()), false);
    },
    paint.redrawAll
);
require("./file-drop.js")(d3.select("body"), errors, handlers);

resultsTable.headerClicked(function(h){
    worksheet.sortProperty(h, d3.event.shiftKey);
});
resultsTable.rowClicked(function(head, row){
    var shape = d3.select("g#" + row[0] + " path#" + row[1]);
    selection.select(shape, d3.event.shiftKey);
});

time.onChange(worksheet.timeChanged);

worksheet.dataChanged(function(){
    resultsTable.info(worksheet.propertyNames(), worksheet.allData(time.current()), worksheet.getSortProperties());
    calculationsDisplay.update(worksheet.sources());
    paintDisplayColumn();
});

var wikiStore = require("./wiki-store.js")(
    errors,
    body,
    toolbar,
    layers,
    worksheet,
    selection,
    title,
    function findShapesByName(names) {
	return d3.selectAll("#map svg g path")
	    .filter(function(d, i) {
		return names.has(d.layer.name() + "/" + d.id);
	    });
    },
    paint.redrawAll
);

require("./query-string.js")(map, layersControl, baseLayers, wikiStore, title, errors);
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var XHTML_NS = "http://www.w3.org/1999/xhtml";

exports.getDocumentHead = function(doc) {
    if (!doc)
        doc = document;
    return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement;
};

exports.createElement = function(tag, ns) {
    return document.createElementNS ?
           document.createElementNS(ns || XHTML_NS, tag) :
           document.createElement(tag);
};

exports.hasCssClass = function(el, name) {
    var classes = (el.className + "").split(/\s+/g);
    return classes.indexOf(name) !== -1;
};

/*
* Add a CSS class to the list of classes on the given node
*/
exports.addCssClass = function(el, name) {
    if (!exports.hasCssClass(el, name)) {
        el.className += " " + name;
    }
};

/*
* Remove a CSS class from the list of classes on the given node
*/
exports.removeCssClass = function(el, name) {
    var classes = el.className.split(/\s+/g);
    while (true) {
        var index = classes.indexOf(name);
        if (index == -1) {
            break;
        }
        classes.splice(index, 1);
    }
    el.className = classes.join(" ");
};

exports.toggleCssClass = function(el, name) {
    var classes = el.className.split(/\s+/g), add = true;
    while (true) {
        var index = classes.indexOf(name);
        if (index == -1) {
            break;
        }
        add = false;
        classes.splice(index, 1);
    }
    if (add)
        classes.push(name);

    el.className = classes.join(" ");
    return add;
};

/*
 * Add or remove a CSS class from the list of classes on the given node
 * depending on the value of <tt>include</tt>
 */
exports.setCssClass = function(node, className, include) {
    if (include) {
        exports.addCssClass(node, className);
    } else {
        exports.removeCssClass(node, className);
    }
};

exports.hasCssString = function(id, doc) {
    var index = 0, sheets;
    doc = doc || document;

    if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
        while (index < sheets.length)
            if (sheets[index++].owningElement.id === id) return true;
    } else if ((sheets = doc.getElementsByTagName("style"))) {
        while (index < sheets.length)
            if (sheets[index++].id === id) return true;
    }

    return false;
};

exports.importCssString = function importCssString(cssText, id, doc) {
    doc = doc || document;
    // If style is already imported return immediately.
    if (id && exports.hasCssString(id, doc))
        return null;

    var style;

    if (id)
        cssText += "\n/*# sourceURL=ace/css/" + id + " */";

    if (doc.createStyleSheet) {
        style = doc.createStyleSheet();
        style.cssText = cssText;
        if (id)
            style.owningElement.id = id;
    } else {
        style = exports.createElement("style");
        style.appendChild(doc.createTextNode(cssText));
        if (id)
            style.id = id;

        exports.getDocumentHead(doc).appendChild(style);
    }
};

exports.importCssStylsheet = function(uri, doc) {
    if (doc.createStyleSheet) {
        doc.createStyleSheet(uri);
    } else {
        var link = exports.createElement('link');
        link.rel = 'stylesheet';
        link.href = uri;

        exports.getDocumentHead(doc).appendChild(link);
    }
};

exports.getInnerWidth = function(element) {
    return (
        parseInt(exports.computedStyle(element, "paddingLeft"), 10) +
        parseInt(exports.computedStyle(element, "paddingRight"), 10) +
        element.clientWidth
    );
};

exports.getInnerHeight = function(element) {
    return (
        parseInt(exports.computedStyle(element, "paddingTop"), 10) +
        parseInt(exports.computedStyle(element, "paddingBottom"), 10) +
        element.clientHeight
    );
};

exports.scrollbarWidth = function(document) {
    var inner = exports.createElement("ace_inner");
    inner.style.width = "100%";
    inner.style.minWidth = "0px";
    inner.style.height = "200px";
    inner.style.display = "block";

    var outer = exports.createElement("ace_outer");
    var style = outer.style;

    style.position = "absolute";
    style.left = "-10000px";
    style.overflow = "hidden";
    style.width = "200px";
    style.minWidth = "0px";
    style.height = "150px";
    style.display = "block";

    outer.appendChild(inner);

    var body = document.documentElement;
    body.appendChild(outer);

    var noScrollbar = inner.offsetWidth;

    style.overflow = "scroll";
    var withScrollbar = inner.offsetWidth;

    if (noScrollbar == withScrollbar) {
        withScrollbar = outer.clientWidth;
    }

    body.removeChild(outer);

    return noScrollbar-withScrollbar;
};

if (typeof document == "undefined") {
    exports.importCssString = function() {};
    return;
}

if (window.pageYOffset !== undefined) {
    exports.getPageScrollTop = function() {
        return window.pageYOffset;
    };

    exports.getPageScrollLeft = function() {
        return window.pageXOffset;
    };
}
else {
    exports.getPageScrollTop = function() {
        return document.body.scrollTop;
    };

    exports.getPageScrollLeft = function() {
        return document.body.scrollLeft;
    };
}

if (window.getComputedStyle)
    exports.computedStyle = function(element, style) {
        if (style)
            return (window.getComputedStyle(element, "") || {})[style] || "";
        return window.getComputedStyle(element, "") || {};
    };
else
    exports.computedStyle = function(element, style) {
        if (style)
            return element.currentStyle[style];
        return element.currentStyle;
    };

/*
 * Optimized set innerHTML. This is faster than plain innerHTML if the element
 * already contains a lot of child elements.
 *
 * See http://blog.stevenlevithan.com/archives/faster-than-innerhtml for details
 */
exports.setInnerHtml = function(el, innerHtml) {
    var element = el.cloneNode(false);//document.createElement("div");
    element.innerHTML = innerHtml;
    el.parentNode.replaceChild(element, el);
    return element;
};

if ("textContent" in document.documentElement) {
    exports.setInnerText = function(el, innerText) {
        el.textContent = innerText;
    };

    exports.getInnerText = function(el) {
        return el.textContent;
    };
}
else {
    exports.setInnerText = function(el, innerText) {
        el.innerText = innerText;
    };

    exports.getInnerText = function(el) {
        return el.innerText;
    };
}

exports.getParentWindow = function(document) {
    return document.defaultView || document.parentWindow;
};

});
<commit_msg>add a helper for constructing dom nodes<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var XHTML_NS = "http://www.w3.org/1999/xhtml";

exports.buildDom = function buildDom(arr, parent, refs) {
    if (typeof arr == "string" && arr) {
        var txt = document.createTextNode(arr);
        if (parent)
            parent.appendChild(txt);
        return txt;
    }

    if (!Array.isArray(arr))
        return arr;
    if (typeof arr[0] != "string" || !arr[0]) {
        var els = [];
        for (var i = 0; i < arr.length; i++) {
            var ch = buildDom(arr[i], parent, refs);
            ch && els.push(ch);
        }
        return els;
    }

    var el = document.createElement(arr[0]);
    var options = arr[1];
    var childIndex = 1;
    if (options && typeof options == "object" && !Array.isArray(options))
        childIndex = 2;
    for (var i = childIndex; i < arr.length; i++)
        buildDom(arr[i], el, refs);
    if (childIndex == 2) {
        Object.keys(options).forEach(function(n) {
            var val = options[n];
            if (n === "class") {
                el.className = Array.isArray(val) ? val.join(" ") : val;
            } else if (typeof val == "function" || n == "value") {
                el[n] = val;
            } else if (n === "ref") {
                if (refs) refs[val] = el;
            } else if (val != null) {
                el.setAttribute(n, val);
            }
        });
    }
    if (parent)
        parent.appendChild(el);
    return el;
};

exports.getDocumentHead = function(doc) {
    if (!doc)
        doc = document;
    return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement;
};

exports.createElement = function(tag, ns) {
    return document.createElementNS ?
           document.createElementNS(ns || XHTML_NS, tag) :
           document.createElement(tag);
};

exports.hasCssClass = function(el, name) {
    var classes = (el.className + "").split(/\s+/g);
    return classes.indexOf(name) !== -1;
};

/*
* Add a CSS class to the list of classes on the given node
*/
exports.addCssClass = function(el, name) {
    if (!exports.hasCssClass(el, name)) {
        el.className += " " + name;
    }
};

/*
* Remove a CSS class from the list of classes on the given node
*/
exports.removeCssClass = function(el, name) {
    var classes = el.className.split(/\s+/g);
    while (true) {
        var index = classes.indexOf(name);
        if (index == -1) {
            break;
        }
        classes.splice(index, 1);
    }
    el.className = classes.join(" ");
};

exports.toggleCssClass = function(el, name) {
    var classes = el.className.split(/\s+/g), add = true;
    while (true) {
        var index = classes.indexOf(name);
        if (index == -1) {
            break;
        }
        add = false;
        classes.splice(index, 1);
    }
    if (add)
        classes.push(name);

    el.className = classes.join(" ");
    return add;
};

/*
 * Add or remove a CSS class from the list of classes on the given node
 * depending on the value of <tt>include</tt>
 */
exports.setCssClass = function(node, className, include) {
    if (include) {
        exports.addCssClass(node, className);
    } else {
        exports.removeCssClass(node, className);
    }
};

exports.hasCssString = function(id, doc) {
    var index = 0, sheets;
    doc = doc || document;

    if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
        while (index < sheets.length)
            if (sheets[index++].owningElement.id === id) return true;
    } else if ((sheets = doc.getElementsByTagName("style"))) {
        while (index < sheets.length)
            if (sheets[index++].id === id) return true;
    }

    return false;
};

exports.importCssString = function importCssString(cssText, id, doc) {
    doc = doc || document;
    // If style is already imported return immediately.
    if (id && exports.hasCssString(id, doc))
        return null;

    var style;

    if (id)
        cssText += "\n/*# sourceURL=ace/css/" + id + " */";

    if (doc.createStyleSheet) {
        style = doc.createStyleSheet();
        style.cssText = cssText;
        if (id)
            style.owningElement.id = id;
    } else {
        style = exports.createElement("style");
        style.appendChild(doc.createTextNode(cssText));
        if (id)
            style.id = id;

        exports.getDocumentHead(doc).appendChild(style);
    }
};

exports.importCssStylsheet = function(uri, doc) {
    if (doc.createStyleSheet) {
        doc.createStyleSheet(uri);
    } else {
        var link = exports.createElement('link');
        link.rel = 'stylesheet';
        link.href = uri;

        exports.getDocumentHead(doc).appendChild(link);
    }
};

exports.getInnerWidth = function(element) {
    return (
        parseInt(exports.computedStyle(element, "paddingLeft"), 10) +
        parseInt(exports.computedStyle(element, "paddingRight"), 10) +
        element.clientWidth
    );
};

exports.getInnerHeight = function(element) {
    return (
        parseInt(exports.computedStyle(element, "paddingTop"), 10) +
        parseInt(exports.computedStyle(element, "paddingBottom"), 10) +
        element.clientHeight
    );
};

exports.scrollbarWidth = function(document) {
    var inner = exports.createElement("ace_inner");
    inner.style.width = "100%";
    inner.style.minWidth = "0px";
    inner.style.height = "200px";
    inner.style.display = "block";

    var outer = exports.createElement("ace_outer");
    var style = outer.style;

    style.position = "absolute";
    style.left = "-10000px";
    style.overflow = "hidden";
    style.width = "200px";
    style.minWidth = "0px";
    style.height = "150px";
    style.display = "block";

    outer.appendChild(inner);

    var body = document.documentElement;
    body.appendChild(outer);

    var noScrollbar = inner.offsetWidth;

    style.overflow = "scroll";
    var withScrollbar = inner.offsetWidth;

    if (noScrollbar == withScrollbar) {
        withScrollbar = outer.clientWidth;
    }

    body.removeChild(outer);

    return noScrollbar-withScrollbar;
};

if (typeof document == "undefined") {
    exports.importCssString = function() {};
    return;
}

if (window.pageYOffset !== undefined) {
    exports.getPageScrollTop = function() {
        return window.pageYOffset;
    };

    exports.getPageScrollLeft = function() {
        return window.pageXOffset;
    };
}
else {
    exports.getPageScrollTop = function() {
        return document.body.scrollTop;
    };

    exports.getPageScrollLeft = function() {
        return document.body.scrollLeft;
    };
}

if (window.getComputedStyle)
    exports.computedStyle = function(element, style) {
        if (style)
            return (window.getComputedStyle(element, "") || {})[style] || "";
        return window.getComputedStyle(element, "") || {};
    };
else
    exports.computedStyle = function(element, style) {
        if (style)
            return element.currentStyle[style];
        return element.currentStyle;
    };

/*
 * Optimized set innerHTML. This is faster than plain innerHTML if the element
 * already contains a lot of child elements.
 *
 * See http://blog.stevenlevithan.com/archives/faster-than-innerhtml for details
 */
exports.setInnerHtml = function(el, innerHtml) {
    var element = el.cloneNode(false);//document.createElement("div");
    element.innerHTML = innerHtml;
    el.parentNode.replaceChild(element, el);
    return element;
};

if ("textContent" in document.documentElement) {
    exports.setInnerText = function(el, innerText) {
        el.textContent = innerText;
    };

    exports.getInnerText = function(el) {
        return el.textContent;
    };
}
else {
    exports.setInnerText = function(el, innerText) {
        el.innerText = innerText;
    };

    exports.getInnerText = function(el) {
        return el.innerText;
    };
}

exports.getParentWindow = function(document) {
    return document.defaultView || document.parentWindow;
};

});
<|endoftext|>


<commit_before>var tilelive = require("tilelive"),
    server = require("express")(),
    os = require('os'),
    port = 5044,
    application_prefix = ""; // Inserted at start of URL scheme, makes it easier to share to a port with other services. Blank or with trailing slash.

var mbtilesdirectory = "/usr/share/mapbox/export"; // relative or absolute directory containing .mbtiles files

// Make TileLive aware of the MBTiles and TileJSON tile formats.
require("mbtiles").registerProtocols(tilelive);
require("tilejson").registerProtocols(tilelive);

if (application_prefix !== "" && application_prefix[application_prefix.length - 1] !== "/") {
  console.log("Application Prefix must be empty or have a trailing slash: currently it is '" + application_prefix + "'.");
  process.exit(1);
}

tilelive.list(mbtilesdirectory, function(err, tileinfo) {
  if (err) throw err;

  var tilesets = toEntries(tileinfo);

  if (tilesets.length === 0) {
    console.log("No mbtiles sets found in directory '" + mbtilesdirectory + "'.");
    process.exit(1);
  }

  console.log("Found these tilesets:");
  tilesets.forEach(function(tileset) { console.log("  " + tileset.key + " - " + tileset.value); });
  console.log();

  console.log("Serving these endpoints:");
  tilesets.forEach(function(tileset) {
    var location = tileset.value,
        tileset_url = "/" + application_prefix + tileset.key,
        application_host = "http://" + os.hostname() + ":" + port + "/" + application_prefix;

    tilelive.info(location, function(err, tilejson) {
      console.log("  " + application_host + tilejson.id + ".json");

      // When client requests /mymbtiles.json, use TileJSON to return it.
      server.get("/" + application_prefix + tilejson.id + ".json", function(req, res) {
        tilejson.scheme = "xyz";
        tilejson.tiles = [ req.protocol + "://" + req.headers.host + "/" + application_prefix + tilejson.id + "/{z}/{x}/{y}.png" ];
        tilejson.grids = [ req.protocol + "://" + req.headers.host + "/" + application_prefix + tilejson.id + "/{z}/{x}/{y}.grid.json" ];

        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "X-Requested-With");
        res.type("application/json");

        if (!err) {
          res.send(tilejson);
        } else {
          res.send("TileJSON error: " + err + "\n");
        }

      });
    });

    // When client requests /mymbtiles/z/x/y.png, the MBTiles module serves the tile.
    tilelive.load(location, function(err, tilestore) {
      console.log("  " + application_host + tileset.key + "/{z}/{x}/{y}.png");
      server.get(tileset_url + "/:z/:x/:y.png", function(req, res) {
        tilestore.getTile(req.param("z"), req.param("x"), req.param("y"), function(err, tile) {

          if (!err) {
            res.contentType('image/png');
            res.send(tile);
          } else {
            res.send("Tile rendering error: " + err + "\n");
          }

        });
      });

      // When client requests /mymbtiles/z/xz/y.grid.json, MBTiles serves the UTFGrid (json).
      console.log("  " + application_host + tileset.key + "/{z}/{x}/{y}.grid.json");
      server.get(tileset_url + "/:z/:x/:y.grid.json", function(req, res) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "X-Requested-With");

        res.type("application/json");

        tilestore.getGrid(req.param("z"), req.param("x"), req.param("y"), function(err, tile) {
          if (!err) {
            res.send(tile);
          } else {
            res.send("Grid rendering error: " + err + "\n");
          }
        });
      });
    });
  });
});

server.listen(port);

function toEntries (map) {
  var entries = [];
  for (var key in map) entries.push({key: key, value: map[key]});
  return entries;
}
<commit_msg>CamelCaseStyle<commit_after>var tilelive = require("tilelive"),
    server = require("express")(),
    os = require('os'),
    port = 5044,
    applicationPrefix = ""; // Inserted at start of URL scheme, makes it easier to share to a port with other services. Blank or with trailing slash.

var mbtilesdirectory = "/usr/share/mapbox/export"; // relative or absolute directory containing .mbtiles files

// Make TileLive aware of the MBTiles and TileJSON tile formats.
require("mbtiles").registerProtocols(tilelive);
require("tilejson").registerProtocols(tilelive);

if (applicationPrefix !== "" && applicationPrefix[applicationPrefix.length - 1] !== "/") {
  console.log("Application Prefix must be empty or have a trailing slash: currently it is '" + applicationPrefix + "'.");
  process.exit(1);
}

tilelive.list(mbtilesdirectory, function(err, tileinfo) {
  if (err) throw err;

  var tilesets = toEntries(tileinfo);

  if (tilesets.length === 0) {
    console.log("No mbtiles sets found in directory '" + mbtilesdirectory + "'.");
    process.exit(1);
  }

  console.log("Found these tilesets:");
  tilesets.forEach(function(tileset) { console.log("  " + tileset.key + " - " + tileset.value); });
  console.log();

  console.log("Serving these endpoints:");
  tilesets.forEach(function(tileset) {
    var location = tileset.value,
        tilesetUrl = "/" + applicationPrefix + tileset.key,
        applicationHost = "http://" + os.hostname() + ":" + port + "/" + applicationPrefix;

    tilelive.info(location, function(err, tilejson) {
      console.log("  " + applicationHost + tilejson.id + ".json");

      // When client requests /mymbtiles.json, use TileJSON to return it.
      server.get("/" + applicationPrefix + tilejson.id + ".json", function(req, res) {
        tilejson.scheme = "xyz";
        tilejson.tiles = [ req.protocol + "://" + req.headers.host + "/" + applicationPrefix + tilejson.id + "/{z}/{x}/{y}.png" ];
        tilejson.grids = [ req.protocol + "://" + req.headers.host + "/" + applicationPrefix + tilejson.id + "/{z}/{x}/{y}.grid.json" ];

        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "X-Requested-With");
        res.type("application/json");

        if (!err) {
          res.send(tilejson);
        } else {
          res.send("TileJSON error: " + err + "\n");
        }

      });
    });

    // When client requests /mymbtiles/z/x/y.png, the MBTiles module serves the tile.
    tilelive.load(location, function(err, tilestore) {
      console.log("  " + applicationHost + tileset.key + "/{z}/{x}/{y}.png");
      server.get(tilesetUrl + "/:z/:x/:y.png", function(req, res) {
        tilestore.getTile(req.param("z"), req.param("x"), req.param("y"), function(err, tile) {

          if (!err) {
            res.contentType('image/png');
            res.send(tile);
          } else {
            res.send("Tile rendering error: " + err + "\n");
          }

        });
      });

      // When client requests /mymbtiles/z/xz/y.grid.json, MBTiles serves the UTFGrid (json).
      console.log("  " + applicationHost + tileset.key + "/{z}/{x}/{y}.grid.json");
      server.get(tilesetUrl + "/:z/:x/:y.grid.json", function(req, res) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "X-Requested-With");

        res.type("application/json");

        tilestore.getGrid(req.param("z"), req.param("x"), req.param("y"), function(err, tile) {
          if (!err) {
            res.send(tile);
          } else {
            res.send("Grid rendering error: " + err + "\n");
          }
        });
      });
    });
  });
});

server.listen(port);

function toEntries (map) {
  var entries = [];
  for (var key in map) entries.push({key: key, value: map[key]});
  return entries;
}
<|endoftext|>


<commit_before>import './Header.css';

import { Link, withRouter } from 'react-router-dom';
import React, { Component } from 'react';

import { Dropdown } from 'react-viewerbase';
import OHIFLogo from '../OHIFLogo/OHIFLogo.js';
import PropTypes from 'prop-types';
import { UserPreferencesModal } from 'react-viewerbase';
import { hotkeysManager } from './../../App.js';

class Header extends Component {
  static propTypes = {
    home: PropTypes.bool.isRequired,
    location: PropTypes.object.isRequired,
    children: PropTypes.node,
  };

  static defaultProps = {
    home: true,
    children: OHIFLogo(),
  };

  // onSave: data => {
  //   const contextName = window.store.getState().commandContext.context;
  //   const preferences = cloneDeep(window.store.getState().preferences);
  //   preferences[contextName] = data;
  //   dispatch(setUserPreferences(preferences));
  //   dispatch(setUserPreferencesModalOpen(false));
  //   OHIF.hotkeysUtil.setHotkeys(data.hotKeysData);
  // },
  // onResetToDefaults: () => {
  //   dispatch(setUserPreferences());
  //   dispatch(setUserPreferencesModalOpen(false));
  //   OHIF.hotkeysUtil.setHotkeys();
  // },

  constructor(props) {
    super(props);
    this.state = { isUserPreferencesOpen: false };

    const onClick = this.toggleUserPreferences.bind(this);

    this.options = [
      {
        title: 'Preferences ',
        icon: {
          name: 'user',
        },
        onClick: onClick,
      },
      {
        title: 'About',
        icon: {
          name: 'info',
        },
        link: 'http://ohif.org',
      },
    ];

    this.hotKeysData = hotkeysManager.hotkeyDefinitions;
  }

  toggleUserPreferences() {
    const isOpen = this.state.isUserPreferencesOpen;

    this.setState({
      isUserPreferencesOpen: !isOpen,
    });
  }

  onUserPreferencesSave({ windowLevelData, hotKeysData }) {
    console.log(windowLevelData);
    console.log(hotKeysData);

    // TODO: Update hotkeysManager
    // TODO: reset `this.hotKeysData`
  }

  render() {
    return (
      <div className={`entry-header ${this.props.home ? 'header-big' : ''}`}>

          {this.props.location && this.props.location.studyLink && (
            <Link
              to={this.props.location.studyLink}
              className="header-btn header-viewerLink"
            >
              Back to Viewer
            </Link>
          )}

          {this.props.children}

          {!this.props.home && (
            <Link
              className="header-btn header-studyListLinkSection"
              to={{
                pathname: '/',
                state: { studyLink: this.props.location.pathname },
              }}
            >
              Study list
            </Link>
          )}

          INVESTIGATIONAL USE ONLY
          <Dropdown title="Options" list={this.options} align="right" />
          <UserPreferencesModal
            isOpen={this.state.isUserPreferencesOpen}
            onCancel={this.toggleUserPreferences.bind(this)}
            onSave={this.toggleUserPreferences.bind(this)}
            onResetToDefaults={this.toggleUserPreferences.bind(this)}
            windowLevelData={{}}
            hotKeysData={this.hotKeysData}
          />

    );
  }
}

export default withRouter(Header);
<commit_msg>Hide our user preferences modal for now<commit_after>import './Header.css';

import { Link, withRouter } from 'react-router-dom';
import React, { Component } from 'react';

import { Dropdown } from 'react-viewerbase';
import OHIFLogo from '../OHIFLogo/OHIFLogo.js';
import PropTypes from 'prop-types';
// import { UserPreferencesModal } from 'react-viewerbase';
import { hotkeysManager } from './../../App.js';

class Header extends Component {
  static propTypes = {
    home: PropTypes.bool.isRequired,
    location: PropTypes.object.isRequired,
    children: PropTypes.node,
  };

  static defaultProps = {
    home: true,
    children: OHIFLogo(),
  };

  // onSave: data => {
  //   const contextName = window.store.getState().commandContext.context;
  //   const preferences = cloneDeep(window.store.getState().preferences);
  //   preferences[contextName] = data;
  //   dispatch(setUserPreferences(preferences));
  //   dispatch(setUserPreferencesModalOpen(false));
  //   OHIF.hotkeysUtil.setHotkeys(data.hotKeysData);
  // },
  // onResetToDefaults: () => {
  //   dispatch(setUserPreferences());
  //   dispatch(setUserPreferencesModalOpen(false));
  //   OHIF.hotkeysUtil.setHotkeys();
  // },

  constructor(props) {
    super(props);
    this.state = { isUserPreferencesOpen: false };

    const onClick = this.toggleUserPreferences.bind(this);

    this.options = [
      // {
      //   title: 'Preferences ',
      //   icon: {
      //     name: 'user',
      //   },
      //   onClick: onClick,
      // },
      {
        title: 'About',
        icon: {
          name: 'info',
        },
        link: 'http://ohif.org',
      },
    ];

    this.hotKeysData = hotkeysManager.hotkeyDefinitions;
  }

  toggleUserPreferences() {
    const isOpen = this.state.isUserPreferencesOpen;

    this.setState({
      isUserPreferencesOpen: !isOpen,
    });
  }

  onUserPreferencesSave({ windowLevelData, hotKeysData }) {
    console.log(windowLevelData);
    console.log(hotKeysData);

    // TODO: Update hotkeysManager
    // TODO: reset `this.hotKeysData`
  }

  render() {
    return (
      <div className={`entry-header ${this.props.home ? 'header-big' : ''}`}>

          {this.props.location && this.props.location.studyLink && (
            <Link
              to={this.props.location.studyLink}
              className="header-btn header-viewerLink"
            >
              Back to Viewer
            </Link>
          )}

          {this.props.children}

          {!this.props.home && (
            <Link
              className="header-btn header-studyListLinkSection"
              to={{
                pathname: '/',
                state: { studyLink: this.props.location.pathname },
              }}
            >
              Study list
            </Link>
          )}

          INVESTIGATIONAL USE ONLY
          <Dropdown title="Options" list={this.options} align="right" />
          {/* <UserPreferencesModal
            isOpen={this.state.isUserPreferencesOpen}
            onCancel={this.toggleUserPreferences.bind(this)}
            onSave={this.toggleUserPreferences.bind(this)}
            onResetToDefaults={this.toggleUserPreferences.bind(this)}
            windowLevelData={{}}
            hotKeysData={this.hotKeysData}
          /> */}

    );
  }
}

export default withRouter(Header);
<|endoftext|>


<commit_before>(function($) {

    "use strict";

    /* DROPDOWN CLASS DEFINITION */

    var toggle = '[data-toggle="dropdown"]';
    var share_selector = '.socialshare';
    var fb_iframe = '.socialshare.open[data-type="small-bubbles"] #share-options div.fb-like iframe';
    var $share_container;
    var packaged_html = '' +
    '
' +
    '    Share This' +
    '
' +
    '
' +
    '

' +
    '

' +
    '

' +
    '
' +
    '
' +
    '
'+
    '

';
    var type;
    var providers = {
        facebook: {
            id: 'facebook-jssdk',
            src: '//connect.facebook.net/en_US/all.js#xfbml=1&appId=255566051148260',
            selector: '.fb-like',
            'small-bubbles': {
                'data-send': 'false',
                'data-layout': 'button_count',
                'data-width': '105',
                'data-show-face': 'false'
            },
            'bubbles': {
                'data-send': 'false',
                'data-layout': 'box_count',
                'data-width': '12',
                'data-show-faces': 'false'
            },
            'small': {
                'data-send': 'false',
                'data-width': '85',
                'data-show-face': 'false'
            }
        },
        googleplus: {
            id: 'gplus-api',
            src: 'https://apis.google.com/js/plusone.js',
            selector: '.g-plusone',
            'small-bubbles': {
            },
            'bubbles': {
                'data-size': 'tall'
            },
            'small': {
                'data-size': 'small',
                'data-annotation': 'none'
            }
        },
        twitter: {
            id: 'twitter-wjs',
            src: '//platform.twitter.com/widgets.js',
            selector: '.twitter-share-button',
            'small-bubbles': {
                'data-via': 'firefox',
                'data-related': 'firefox'
            },
            'bubbles': {
                'data-via': 'firefox',
                'data-count': 'vertical',
                'data-related': 'firefox'
            },
            'small': {
                'data-via': 'firefox',
                'data-count': 'none',
                'data-related': 'firefox'
            }
        }
    };

    var clear_menus = function() {
        $(toggle).parent().removeClass('open');
        $(toggle).find(".share-button").attr("aria-expanded","false");
    };

    var Dropdown = function(element) {
        var $el = $(element).on('click.dropdown.data-api', this.toggle);
        $('html').on('click.dropdown.data-api', function() {
            $el.parent().removeClass('open');
        });
    };

    Dropdown.prototype = {
        constructor: Dropdown,
        scripts_loaded: false,

        toggle: function(e) {
            var $parent = $(this).parent();
            var isActive = $parent.hasClass('open');

            clear_menus();
            if (!isActive) {
                $(this).find(".share-button").attr("aria-expanded","true");
                $parent.toggleClass('open');
            }
            $share_container = $(fb_iframe).css('width',
                providers.facebook['small-bubbles']['data-width']);

            Dropdown.prototype.load_sharing();

            return false;
        },
        load_sharing: function() {
            if (!this.scripts_loaded) {
                for (var key in providers) {
                    this.load_script(providers[key].src, providers[key].id);
                }
                this.scripts_loaded = true;
            }
        },
        load_script: function(src, id) {
            var first_js = document.getElementsByTagName("script")[0];
            var js = document.getElementById(id);
            // If the script doesnt exist, create it.
            if (!js) {
                js = document.createElement("script");
                js.id = id;
                first_js.parentNode.insertBefore(js, first_js);
            }
            js.src = src;
        }
    };

    /* DROPDOWN PLUGIN DEFINITION */

    $.fn.dropdown = function(option) {
        return this.each(function() {
            var $this = $(this);
            var data = $this.data('dropdown');
            if (!data) {
                $this.data('dropdown', (data = new Dropdown(this)));
            }
            if (typeof option === 'string') {
                data[option].call($this);
            }
        });
    };

    $.fn.dropdown.Constructor = Dropdown;

    var set_twitter = function(property, value) {
        providers.twitter['small-bubbles'][property] = value;
        providers.twitter['bubbles'][property] = value;
    };

    $(function() {
        $('html').on('click.dropdown.data-api', clear_menus);
        $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle);
        $share_container = $(share_selector);
        var tweetby = $share_container.attr('data-tweet-at');
        if (tweetby) {
            set_twitter('data-via', tweetby);
        }
        var $meta_title = $('meta[property="og:title"]');
        if ($meta_title) {
            set_twitter('data-text', $meta_title.attr('content'));
        }
        var $meta_url = $('meta[property="og:url"]');
        if ($meta_url) {
            set_twitter('data-url', $meta_url.attr('content'));
        }
        $share_container.append(packaged_html);
        for (var key in providers) {
            $share_container.find(providers[key].selector)
                .attr(providers[key][$share_container.attr('data-type')]);
        }
        $share_container.find(".share-button").keypress(function(e) {
            if (e.which === 32) {
                $(this).trigger("click");
            }
        });
    });
})(window.jQuery);
<commit_msg>close widget with escape-key<commit_after>(function($) {

    "use strict";

    /* DROPDOWN CLASS DEFINITION */

    var toggle = '[data-toggle="dropdown"]';
    var share_selector = '.socialshare';
    var fb_iframe = '.socialshare.open[data-type="small-bubbles"] #share-options div.fb-like iframe';
    var $share_container;
    var packaged_html = '' +
    '
' +
    '    Share This' +
    '
' +
    '
' +
    '

' +
    '

' +
    '

' +
    '
' +
    '
' +
    '
'+
    '

';
    var type;
    var providers = {
        facebook: {
            id: 'facebook-jssdk',
            src: '//connect.facebook.net/en_US/all.js#xfbml=1&appId=255566051148260',
            selector: '.fb-like',
            'small-bubbles': {
                'data-send': 'false',
                'data-layout': 'button_count',
                'data-width': '105',
                'data-show-face': 'false'
            },
            'bubbles': {
                'data-send': 'false',
                'data-layout': 'box_count',
                'data-width': '12',
                'data-show-faces': 'false'
            },
            'small': {
                'data-send': 'false',
                'data-width': '85',
                'data-show-face': 'false'
            }
        },
        googleplus: {
            id: 'gplus-api',
            src: 'https://apis.google.com/js/plusone.js',
            selector: '.g-plusone',
            'small-bubbles': {
            },
            'bubbles': {
                'data-size': 'tall'
            },
            'small': {
                'data-size': 'small',
                'data-annotation': 'none'
            }
        },
        twitter: {
            id: 'twitter-wjs',
            src: '//platform.twitter.com/widgets.js',
            selector: '.twitter-share-button',
            'small-bubbles': {
                'data-via': 'firefox',
                'data-related': 'firefox'
            },
            'bubbles': {
                'data-via': 'firefox',
                'data-count': 'vertical',
                'data-related': 'firefox'
            },
            'small': {
                'data-via': 'firefox',
                'data-count': 'none',
                'data-related': 'firefox'
            }
        }
    };

    var clear_menus = function() {
        $(toggle).parent().removeClass('open');
        $(toggle).find(".share-button").attr("aria-expanded","false");
    };

    var Dropdown = function(element) {
        var $el = $(element).on('click.dropdown.data-api', this.toggle);
        $('html').on('click.dropdown.data-api', function() {
            $el.parent().removeClass('open');
        });
    };

    Dropdown.prototype = {
        constructor: Dropdown,
        scripts_loaded: false,

        toggle: function(e) {
            var $parent = $(this).parent();
            var isActive = $parent.hasClass('open');

            clear_menus();
            if (!isActive) {
                $(this).find(".share-button").attr("aria-expanded","true");
                $parent.toggleClass('open');
            }
            $share_container = $(fb_iframe).css('width',
                providers.facebook['small-bubbles']['data-width']);

            Dropdown.prototype.load_sharing();

            return false;
        },
        load_sharing: function() {
            if (!this.scripts_loaded) {
                for (var key in providers) {
                    this.load_script(providers[key].src, providers[key].id);
                }
                this.scripts_loaded = true;
            }
        },
        load_script: function(src, id) {
            var first_js = document.getElementsByTagName("script")[0];
            var js = document.getElementById(id);
            // If the script doesnt exist, create it.
            if (!js) {
                js = document.createElement("script");
                js.id = id;
                first_js.parentNode.insertBefore(js, first_js);
            }
            js.src = src;
        }
    };

    /* DROPDOWN PLUGIN DEFINITION */

    $.fn.dropdown = function(option) {
        return this.each(function() {
            var $this = $(this);
            var data = $this.data('dropdown');
            if (!data) {
                $this.data('dropdown', (data = new Dropdown(this)));
            }
            if (typeof option === 'string') {
                data[option].call($this);
            }
        });
    };

    $.fn.dropdown.Constructor = Dropdown;

    var set_twitter = function(property, value) {
        providers.twitter['small-bubbles'][property] = value;
        providers.twitter['bubbles'][property] = value;
    };

    $(function() {
        $('html').on('click.dropdown.data-api', clear_menus);
        $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle);
        $share_container = $(share_selector);
        var tweetby = $share_container.attr('data-tweet-at');
        if (tweetby) {
            set_twitter('data-via', tweetby);
        }
        var $meta_title = $('meta[property="og:title"]');
        if ($meta_title) {
            set_twitter('data-text', $meta_title.attr('content'));
        }
        var $meta_url = $('meta[property="og:url"]');
        if ($meta_url) {
            set_twitter('data-url', $meta_url.attr('content'));
        }
        $share_container.append(packaged_html);
        for (var key in providers) {
            $share_container.find(providers[key].selector)
                .attr(providers[key][$share_container.attr('data-type')]);
        }
        $share_container.find(".share-button").keypress(function(e) {
            if (e.which === 32) {
                $(this).trigger("click");
            }
        });
        $(document).keydown(function(e) {
	        if (e.which === 27 && $(".socialshare").hasClass("open")) {
	            $(".share-button").trigger("click");
	        }
	    });
    });
})(window.jQuery);
<|endoftext|>


<commit_before>var popup_function = function(rows, package_info){
    if (!document.getElementById('CompanyInfo')) {
	var content = "
"
	    + "

"
	    + "
"
	    + "×
"
	    + "

";
	document.body.innerHTML = content + document.body.innerHTML;
	var close = document.getElementById('CompanyInfoClose');

	close.addEventListener('click',function() {
	    document.getElementById('CompanyInfo').style.display = 'none';
	});
    } else {
	document.getElementById('CompanyInfo').style.display = 'block';
    }

    var htmlspecialchars = function(str){
	var span_dom = document.createElement('span');
	span_dom.innerText = str;
	str = span_dom.innerHTML;
	delete(span_dom);
	return str;
    };

    var info_dom = document.getElementById('CompanyInfo');
    info_dom.style.background = 'yellow';
    info_dom.style.color = 'black';
    document.getElementById('CompanyInfoMessage').innerHTML += '
'
	+ htmlspecialchars(rows[1]) + '. ' + htmlspecialchars(rows[2])
	+ '[' + htmlspecialchars(package_info.name) + ']'
	+ '
';
};

function onRequest(request, sender, sendResponse) {
    if (request.method== 'page') {
        // 顯示設定求職小幫手的 page action
        chrome.pageAction.show(sender.tab.id);
    }

    if (request.method == 'add_match') {
        chrome.tabs.executeScript(sender.tab.id, {code: "(" + popup_function + ')(' + JSON.stringify(request.rows) + ',' + JSON.stringify(request.package_info) + ')'});
    }

    // Return nothing to let the connection be cleaned up.
    sendResponse({});
};

// Listen for the content script to send a message to the background page.
chrome.extension.onRequest.addListener(onRequest);
<commit_msg>文字改為置左，並且最大高度只佔 20%，加上上下捲軸<commit_after>var popup_function = function(rows, package_info){
    if (!document.getElementById('CompanyInfo')) {
	var content = "
"
	    + "

"
	    + "
"
	    + "×
"
	    + "

";
	document.body.innerHTML = content + document.body.innerHTML;
	var close = document.getElementById('CompanyInfoClose');

	close.addEventListener('click',function() {
	    document.getElementById('CompanyInfo').style.display = 'none';
	});
    } else {
	document.getElementById('CompanyInfo').style.display = 'block';
    }

    var htmlspecialchars = function(str){
	var span_dom = document.createElement('span');
	span_dom.innerText = str;
	str = span_dom.innerHTML;
	delete(span_dom);
	return str;
    };

    var info_dom = document.getElementById('CompanyInfo');
    info_dom.style.background = 'yellow';
    info_dom.style.color = 'black';
    document.getElementById('CompanyInfoMessage').innerHTML += '
'
	+ htmlspecialchars(rows[1]) + '. ' + htmlspecialchars(rows[2])
	+ '[' + htmlspecialchars(package_info.name) + ']'
	+ '
';
};

function onRequest(request, sender, sendResponse) {
    if (request.method== 'page') {
        // 顯示設定求職小幫手的 page action
        chrome.pageAction.show(sender.tab.id);
    }

    if (request.method == 'add_match') {
        chrome.tabs.executeScript(sender.tab.id, {code: "(" + popup_function + ')(' + JSON.stringify(request.rows) + ',' + JSON.stringify(request.package_info) + ')'});
    }

    // Return nothing to let the connection be cleaned up.
    sendResponse({});
};

// Listen for the content script to send a message to the background page.
chrome.extension.onRequest.addListener(onRequest);
<|endoftext|>


<commit_before><commit_msg>Update tmp/bower_components/ace-builds/src-min-noconflict/worker-lua.js<commit_after><|endoftext|>


<commit_before>'use strict';

const express = require('express');
const app = express();

const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const SESS_SECRET = process.env.SESS_SECRET || 'DevPasswordYo';
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379'
app.use(session({
  secret: SESS_SECRET,
  resave: false,
  saveUninitialized: true,
  store: new RedisStore({
    url: REDIS_URL
  })
}));

const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));

const logger = require('./lib/logger');
app.use(logger);

const apiR = require('./routes/api');
app.use(apiR);

app.get('*', (req, res) => {
  res.redirect('https://www.google.com');
});

const mongoose = require('mongoose');
const localMongoPort = 27017;
const MONGO_PORT = process.env.MONGO_PORT || localMongoPort;
const MONGO_HOST = process.env.MONGO_HOST || 'localhost';
const MONGO_USER = process.env.MONGO_USER || '';
const MONGO_PASS = process.env.MONGO_PASS || '';
const MONGO_AUTH = MONGO_USER ? `${MONGO_USER}:${MONGO_PASS}@` : '';
const MONGO_URL = `mongodb://${MONGO_AUTH}${MONGO_HOST}:${MONGO_PORT}/thermostats`;
mongoose.connect(MONGO_URL);

const localPort = 3000;
const PORT = process.env.PORT || localPort;
mongoose.connection.on('open', err => {
  if (err) throw err;
  app.listen(PORT, () => {
    console.log(`Listening on port ${PORT}`); // eslint-disable-line no-console
  });
});
<commit_msg>Added static routes to public folder for eventual frontend portion<commit_after>'use strict';

const express = require('express');
const app = express();

const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const SESS_SECRET = process.env.SESS_SECRET || 'DevPasswordYo';
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379'
app.use(session({
  secret: SESS_SECRET,
  resave: false,
  saveUninitialized: true,
  store: new RedisStore({
    url: REDIS_URL
  })
}));

const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));

const logger = require('./lib/logger');
app.use(logger);

const apiR = require('./routes/api');
app.use(apiR);

const path = require('path');
app.use(express.static(path.join(__dirname, 'public')));

app.get('*', (req, res) => {
  res.redirect('https://www.google.com');
});

const mongoose = require('mongoose');
const localMongoPort = 27017;
const MONGO_PORT = process.env.MONGO_PORT || localMongoPort;
const MONGO_HOST = process.env.MONGO_HOST || 'localhost';
const MONGO_USER = process.env.MONGO_USER || '';
const MONGO_PASS = process.env.MONGO_PASS || '';
const MONGO_AUTH = MONGO_USER ? `${MONGO_USER}:${MONGO_PASS}@` : '';
const MONGO_URL = `mongodb://${MONGO_AUTH}${MONGO_HOST}:${MONGO_PORT}/thermostats`;
mongoose.connect(MONGO_URL);

const localPort = 3000;
const PORT = process.env.PORT || localPort;
mongoose.connection.on('open', err => {
  if (err) throw err;
  app.listen(PORT, () => {
    console.log(`Listening on port ${PORT}`); // eslint-disable-line no-console
  });
});
<|endoftext|>