<commit_before>/*
 * ------------------------------------------------------------------
	AJAX for using the Open Context API
 * ------------------------------------------------------------------
*/

function OpenContextAPI(settings) {
	/* Object for runing searches + displaying results from Open Context */
	this.name = "opencontext"; //object name, used for DOM-ID prefixes and object labeling
	this.root_dom_id = settings['api_start_url'];
	this.title = settings['title'];
	this.api_root = 'http://opencontext.org/';
	this.api_start_url = settings['api_start_url'];
	this.api_url = false;
	this.data = false;
	this.facets_dom_id = 'facets';
	this.filters_dom_id = 'filters';

	/* This is for a Lealet Map, which displays geospatial data from the search */
	this.map_dom_id = false;
	this.map = false;

	/* This builds HTML dom elements to fill with data, and creates an element for the map */
	this.start = function(){
		this.start_html();
		this.start_map();
		this.get_data();
	}

	this.start_map = function(){
		map = L.map(this.map_dom_id);
		this.bounds = new L.LatLngBounds();
		var osmTiles = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
			attribution: '© OpenStreetMap contributors'
		});
		var ESRISatelliteTiles = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
			attribution: '© ESRI.com '
		});
		var baseMaps = {
			"ESRI-Satellite": ESRISatelliteTiles,
			"OpenStreetMap": osmTiles,
		};
		map._layersMaxZoom = 20;
		var layerControl = L.control.layers(baseMaps).addTo(map);
		map.addLayer(osmTiles);
		map.oc_layer = false;
		map.render_region_layer = function(data){
			// this can get much more elaborate to add style
			// and callouts for map layers, but it's a first stab
			if (map.oc_layer != false) {
				map.removeLayer(map.oc_layer);
			}
			var region_layer = L.geoJson(data);
			map.fitBounds(region_layer.getBounds());
			region_layer.addTo(map);
			map.oc_layer = region_layer;
		}
		this.map = map;
	}
	this.get_data = function() {
		// calls the Open Context API to get data
		var url = this.get_api_url();
		if (url != false) {
			return $.ajax({
				type: "GET",
				url: url,
				dataType: "json",
				headers: {
					//added to get JSON data (content negotiation)
					Accept : "application/json; charset=utf-8"
				},
				context: this,
				success: this.get_dataDone, //do this when we get data w/o problems
				error: this.get_dataError //error message display
			});
		}
	}
	this.get_api_url = function(){
		// default to the api_start_url
		var url = this.api_start_url;
		if (this.api_url != false) {
			// we've got a requested url
			url = this.api_url;
		}
		else{
			// checking for a hashed url
			var hash_exists = window.location.hash;
			if (hash_exists){
				var hash = window.location.hash.substring(1);
				if (hash.indexOf(this.api_root) > -1) {
					url = hash;
				}
				else{
					url = this.api_root + hash;
				}
			}
		}
		return url;
	}
	this.get_dataDone = function(data){
		// function to display results of a request for data
		this.api_url = false; //set to false now that data is done.
		this.data = data;
		console.log(data);
		// show facets + facet values
		this.show_facets();
		// show filters on the data
		//this.show_filters();
		// now show the geojson data using the Leaflet Map
		this.map.render_region_layer(data);
	}
	this.show_facets = function(){
		var act_dom = this.get_facets_dom();
		if (act_dom != false) {
			var html = '';
			var data = this.data;
			html += '
Filter Records
';
			if ('oc-api:has-facets' in data) {
				// show some search facets
				for (var i = 0, length = data['oc-api:has-facets'].length; i < length; i++) {
					var facet = data['oc-api:has-facets'][i];
					var facet_html = '
'
					facet_html += '
';
					facet_html += '
' + facet.label + '
'
					//use another function to make facet search values
					facet_html += this.make_facet_values_html(facet);
					facet_html += '
';
					facet_html += '
';
					html += facet_html;
				}
			}
			act_dom.innerHTML = html;
		}
	}
	this.make_facet_values_html = function(facet){
		var value_list = [];
		var html_list = [];
		if ('oc-api:has-id-options' in facet) {
			var value_list = facet['oc-api:has-id-options'];
		}
		else{
			var value_list = [];
		}
		for (var i = 0, length = value_list.length; i < length; i++) {
			var val_item = value_list[i];
			var val_html = this.make_facet_val_link(val_item) + ' (' + val_item.count + ')';
			html_list.push(val_html);
		}
		var html = html_list.join(', ');
		return html;
	}
	this.make_facet_val_link = function(val_item){
		var html = '';
		html += val_item.label;
		html += '';
		return html;
	}
	this.show_filters = function(){
		// function to display filers as needed
		var act_dom = this.get_filters_dom();
		if (act_dom != false) {
			// we've got a dom place to add filters too
			var data = this.data;
			if ('oc-api:active-filters' in data) {
				// the data has filters
				html += '
';
				html += '
Filters on the data
';
				html += '
';
				for (var i = 0, length = data['oc-api:active-filters'].length; i < length; i++) {
					var filter = data['oc-api:active-filters'][i];
					html += this.make_filter_html(filter);
				}
				html += '
';
				html += '
';
				act_dom.innerHTML = html;
			}
		}
	}
	this.make_filter_html = function(filter){
		var html = '
';
		html += '';
		html += filter.label;
		html += '
';
		return html;
	}
	this.change = function(change_url){
		// this function is executed when a user clicks on a link
		// to add a filter or remove a filter
		this.change_frag_id(change_url);
		this.api_url = change_url;
		this.get_data();
	}
	this.change_frag_id = function(new_frag){
		new_frag = new_frag.replace(this.api_root, '');
		window.location.hash = new_frag;
	}
	this.get_dataError = function(){
		var act_dom = this.get_facets_dom();
		if (act_dom != false) {
			var html = [
			'
',
			'',
			'Failed to load valid data from Open Context.',
			'
'
			].join(' ');
			act_dom.innerHTML = html;
		}
	}
	this.get_facets_dom = function(){
		var act_dom = false;
		if (this.facets_dom_id != false) {
			if (document.getElementById(this.facets_dom_id)) {
				act_dom = document.getElementById(this.facets_dom_id);
			}
		}
		return act_dom;
	}
	this.get_filters_dom = function(){
		var act_dom = false;
		if (this.filters_dom_id != false) {
			if (document.getElementById(this.filters_dom_id)) {
				act_dom = document.getElementById(this.filters_dom_id);
			}
		}
		return act_dom;
	}
	this.start_html = function(){
		// builds the initial HTML for
		// map, facets, filters, and results
		var ok = false;
		var act_dom = false;
		if (document.getElementById(this.root_dom_id)) {
			act_dom = document.getElementById(this.root_dom_id);
		}
		if (act_dom != false) {
			this.map_dom_id = this.root_dom_id + '_map';
			this.facets_dom_id = this.root_dom_id + '_facets';
			this.filters_dom_id = this.root_dom_id + '_filters';
			var html = [
			'
',
				'
' + this.title + '
',
				'
',
				'Preparing map...',
				'
',
			'
',
			'
',
				'
',
					'
',
						'
',
							'Loading filters here...',
						'
',
					'
',
					'
',
					'
',
				'
',
			'
'
			].join('\n');
			act_dom.innerHTML = html;
			ok = true;
		}
		else{
			alert('Check your settings. Could not construct HTML in: ' + this.root_dom_id);
		}
		return ok;
	}
}
<commit_msg>Bug fix<commit_after>/*
 * ------------------------------------------------------------------
	AJAX for using the Open Context API
 * ------------------------------------------------------------------
*/

function OpenContextAPI(settings) {
	/* Object for runing searches + displaying results from Open Context */
	this.name = "opencontext"; //object name, used for DOM-ID prefixes and object labeling
	this.root_dom_id = settings['root_dom_id'];
	this.title = settings['title'];
	this.api_root = 'http://opencontext.org/';
	this.api_start_url = settings['api_start_url'];
	this.api_url = false;
	this.data = false;
	this.facets_dom_id = 'facets';
	this.filters_dom_id = 'filters';

	/* This is for a Lealet Map, which displays geospatial data from the search */
	this.map_dom_id = false;
	this.map = false;

	/* This builds HTML dom elements to fill with data, and creates an element for the map */
	this.start = function(){
		this.start_html();
		this.start_map();
		this.get_data();
	}

	this.start_map = function(){
		map = L.map(this.map_dom_id);
		this.bounds = new L.LatLngBounds();
		var osmTiles = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
			attribution: '© OpenStreetMap contributors'
		});
		var ESRISatelliteTiles = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
			attribution: '© ESRI.com '
		});
		var baseMaps = {
			"ESRI-Satellite": ESRISatelliteTiles,
			"OpenStreetMap": osmTiles,
		};
		map._layersMaxZoom = 20;
		var layerControl = L.control.layers(baseMaps).addTo(map);
		map.addLayer(osmTiles);
		map.oc_layer = false;
		map.render_region_layer = function(data){
			// this can get much more elaborate to add style
			// and callouts for map layers, but it's a first stab
			if (map.oc_layer != false) {
				map.removeLayer(map.oc_layer);
			}
			var region_layer = L.geoJson(data);
			map.fitBounds(region_layer.getBounds());
			region_layer.addTo(map);
			map.oc_layer = region_layer;
		}
		this.map = map;
	}
	this.get_data = function() {
		// calls the Open Context API to get data
		var url = this.get_api_url();
		if (url != false) {
			return $.ajax({
				type: "GET",
				url: url,
				dataType: "json",
				headers: {
					//added to get JSON data (content negotiation)
					Accept : "application/json; charset=utf-8"
				},
				context: this,
				success: this.get_dataDone, //do this when we get data w/o problems
				error: this.get_dataError //error message display
			});
		}
	}
	this.get_api_url = function(){
		// default to the api_start_url
		var url = this.api_start_url;
		if (this.api_url != false) {
			// we've got a requested url
			url = this.api_url;
		}
		else{
			// checking for a hashed url
			var hash_exists = window.location.hash;
			if (hash_exists){
				var hash = window.location.hash.substring(1);
				if (hash.indexOf(this.api_root) > -1) {
					url = hash;
				}
				else{
					url = this.api_root + hash;
				}
			}
		}
		return url;
	}
	this.get_dataDone = function(data){
		// function to display results of a request for data
		this.api_url = false; //set to false now that data is done.
		this.data = data;
		console.log(data);
		// show facets + facet values
		this.show_facets();
		// show filters on the data
		//this.show_filters();
		// now show the geojson data using the Leaflet Map
		this.map.render_region_layer(data);
	}
	this.show_facets = function(){
		var act_dom = this.get_facets_dom();
		if (act_dom != false) {
			var html = '';
			var data = this.data;
			html += '
Filter Records
';
			if ('oc-api:has-facets' in data) {
				// show some search facets
				for (var i = 0, length = data['oc-api:has-facets'].length; i < length; i++) {
					var facet = data['oc-api:has-facets'][i];
					var facet_html = '
'
					facet_html += '
';
					facet_html += '
' + facet.label + '
'
					//use another function to make facet search values
					facet_html += this.make_facet_values_html(facet);
					facet_html += '
';
					facet_html += '
';
					html += facet_html;
				}
			}
			act_dom.innerHTML = html;
		}
	}
	this.make_facet_values_html = function(facet){
		var value_list = [];
		var html_list = [];
		if ('oc-api:has-id-options' in facet) {
			var value_list = facet['oc-api:has-id-options'];
		}
		else{
			var value_list = [];
		}
		for (var i = 0, length = value_list.length; i < length; i++) {
			var val_item = value_list[i];
			var val_html = this.make_facet_val_link(val_item) + ' (' + val_item.count + ')';
			html_list.push(val_html);
		}
		var html = html_list.join(', ');
		return html;
	}
	this.make_facet_val_link = function(val_item){
		var html = '';
		html += val_item.label;
		html += '';
		return html;
	}
	this.show_filters = function(){
		// function to display filers as needed
		var act_dom = this.get_filters_dom();
		if (act_dom != false) {
			// we've got a dom place to add filters too
			var data = this.data;
			if ('oc-api:active-filters' in data) {
				// the data has filters
				html += '
';
				html += '
Filters on the data
';
				html += '
';
				for (var i = 0, length = data['oc-api:active-filters'].length; i < length; i++) {
					var filter = data['oc-api:active-filters'][i];
					html += this.make_filter_html(filter);
				}
				html += '
';
				html += '
';
				act_dom.innerHTML = html;
			}
		}
	}
	this.make_filter_html = function(filter){
		var html = '
';
		html += '';
		html += filter.label;
		html += '
';
		return html;
	}
	this.change = function(change_url){
		// this function is executed when a user clicks on a link
		// to add a filter or remove a filter
		this.change_frag_id(change_url);
		this.api_url = change_url;
		this.get_data();
	}
	this.change_frag_id = function(new_frag){
		new_frag = new_frag.replace(this.api_root, '');
		window.location.hash = new_frag;
	}
	this.get_dataError = function(){
		var act_dom = this.get_facets_dom();
		if (act_dom != false) {
			var html = [
			'
',
			'',
			'Failed to load valid data from Open Context.',
			'
'
			].join(' ');
			act_dom.innerHTML = html;
		}
	}
	this.get_facets_dom = function(){
		var act_dom = false;
		if (this.facets_dom_id != false) {
			if (document.getElementById(this.facets_dom_id)) {
				act_dom = document.getElementById(this.facets_dom_id);
			}
		}
		return act_dom;
	}
	this.get_filters_dom = function(){
		var act_dom = false;
		if (this.filters_dom_id != false) {
			if (document.getElementById(this.filters_dom_id)) {
				act_dom = document.getElementById(this.filters_dom_id);
			}
		}
		return act_dom;
	}
	this.start_html = function(){
		// builds the initial HTML for
		// map, facets, filters, and results
		var ok = false;
		var act_dom = false;
		if (document.getElementById(this.root_dom_id)) {
			act_dom = document.getElementById(this.root_dom_id);
		}
		if (act_dom != false) {
			this.map_dom_id = this.root_dom_id + '_map';
			this.facets_dom_id = this.root_dom_id + '_facets';
			this.filters_dom_id = this.root_dom_id + '_filters';
			var html = [
			'
',
				'
' + this.title + '
',
				'
',
				'Preparing map...',
				'
',
			'
',
			'
',
				'
',
					'
',
						'
',
							'Loading filters here...',
						'
',
					'
',
					'
',
					'
',
				'
',
			'
'
			].join('\n');
			act_dom.innerHTML = html;
			ok = true;
		}
		else{
			alert('Check your settings. Could not construct HTML in: ' + this.root_dom_id);
		}
		return ok;
	}
}
<|endoftext|>


<commit_before>var express = require('express')
  , app = express()
  , http = require('http')
  , path = require('path')
  , engine = require('ejs-locals')
  , fs = require('fs')
  , flash = require('connect-flash')
  , async = require('async')
  , passport = require('passport')
  , environment = require('./environment.js')

module.exports = app;

if (fs.existsSync('./conf/envLocal.js')) {
  var configLocal = require('./conf/envLocal.js');

  // global variable
  conf = configLocal.getAppConfig();
}
else {
  console.log('Copy ./conf/envDefault.js to ./conf/envLocal.js.');
  throw new Error('Missing configuration file')
}

app.configure(function() {
  app.engine('ejs', engine);
  app.set('view engine', 'ejs');

  app.set('port', conf.port);
  app.set('views', path.normalize(__dirname + '/app/scripts/views'));

  app.enable("jsonp callback");

  app.use(express.favicon(path.normalize(__dirname + '/public/img/favicon.png')));

  app.use(express.logger('dev'));

  app.use(express.bodyParser({
    uploadDir: path.normalize(__dirname + '/tmp'),
    keepExtensions: true
  }))
  app.use(express.limit('50mb'));

  app.use(express.methodOverride());

  app.use(express.cookieParser(conf.secret));
  var RedisStore = require('connect-redis')(express);
  app.use(express.session({
    secret: conf.secret,
    store: new RedisStore,
    cookie: { secure: false, maxAge:86400000 }
  }));
  app.use(flash());

  app.use(passport.initialize());
  app.use(passport.session());

  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
  app.use(logErrors);
  app.use(clientErrorHandler);
  app.use(errorHandler);
  app.use(express.csrf());
});

function clientErrorHandler(err, req, res, next) {
  if (req.xhr) {
    res.send(500, { error: 'Whoops!' });
  } else {
    next(err);
  }
}

function errorHandler(err, req, res, next) {
  res.status(500);
  res.render('error', { error: err });
}

function logErrors(err, req, res, next) {
  console.error(err.stack);
  next(err);
}

var server = http.createServer(app)
  , pubsub = require('./pubsub').listen(server)
  , routes = require('./app/routes')(app)

environment.init(function(err, res) {
  server.listen(app.get('port'), function() {
    console.log("Express server listening on port " + app.get('port'));
    console.log("Server is running on " + (process.env.NODE_ENV || "development") + " mode")
  });
})
<commit_msg>Expires cookie after 1000 days.<commit_after>var express = require('express')
  , app = express()
  , http = require('http')
  , path = require('path')
  , engine = require('ejs-locals')
  , fs = require('fs')
  , flash = require('connect-flash')
  , async = require('async')
  , passport = require('passport')
  , environment = require('./environment.js')

module.exports = app;

if (fs.existsSync('./conf/envLocal.js')) {
  var configLocal = require('./conf/envLocal.js');

  // global variable
  conf = configLocal.getAppConfig();
}
else {
  console.log('Copy ./conf/envDefault.js to ./conf/envLocal.js.');
  throw new Error('Missing configuration file')
}

app.configure(function() {
  app.engine('ejs', engine);
  app.set('view engine', 'ejs');

  app.set('port', conf.port);
  app.set('views', path.normalize(__dirname + '/app/scripts/views'));

  app.enable("jsonp callback");

  app.use(express.favicon(path.normalize(__dirname + '/public/img/favicon.png')));

  app.use(express.logger('dev'));

  app.use(express.bodyParser({
    uploadDir: path.normalize(__dirname + '/tmp'),
    keepExtensions: true
  }))
  app.use(express.limit('50mb'));

  app.use(express.methodOverride());

  app.use(express.cookieParser(conf.secret));
  var RedisStore = require('connect-redis')(express);
  app.use(express.session({
    secret: conf.secret,
    store: new RedisStore,
    cookie: { secure: false, maxAge:86400000000 }
  }));
  app.use(flash());

  app.use(passport.initialize());
  app.use(passport.session());

  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
  app.use(logErrors);
  app.use(clientErrorHandler);
  app.use(errorHandler);
  app.use(express.csrf());
});

function clientErrorHandler(err, req, res, next) {
  if (req.xhr) {
    res.send(500, { error: 'Whoops!' });
  } else {
    next(err);
  }
}

function errorHandler(err, req, res, next) {
  res.status(500);
  res.render('error', { error: err });
}

function logErrors(err, req, res, next) {
  console.error(err.stack);
  next(err);
}

var server = http.createServer(app)
  , pubsub = require('./pubsub').listen(server)
  , routes = require('./app/routes')(app)

environment.init(function(err, res) {
  server.listen(app.get('port'), function() {
    console.log("Express server listening on port " + app.get('port'));
    console.log("Server is running on " + (process.env.NODE_ENV || "development") + " mode")
  });
})
<|endoftext|>


<commit_before>var argumentsRegExp = /\(([\s\S]*?)\)/;
var replaceRegExp = /[ ,\n\r\t]+/;

module.exports = function (fn) {
  var fnArguments = argumentsRegExp.exec(fn)[1].trim();
  if (0 === fnArguments.length) return [];
  return fnArguments.split(replaceRegExp);
};<commit_msg>Making sure there are arguments inside a function<commit_after>var argumentsRegExp = /\(([\s\S]*?)\)/;
var replaceRegExp = /[ ,\n\r\t]+/;

module.exports = function (fn) {
  var fnArguments = argumentsRegExp.exec(fn)
  if(!fnArguments || !fnArguments[1]){
    return null
  }
  fnArguments = fnArguments[1].trim();
  if (0 === fnArguments.length) return [];
  return fnArguments.split(replaceRegExp);
};
<|endoftext|>


<commit_before>/*
**  ComponentJS -- Component System for JavaScript <http://componentjs.com>
**  Copyright (c) 2009-2013 Ralf S. Engelschall <http://engelschall.com>
**
**  This Source Code Form is subject to the terms of the Mozilla Public
**  License, v. 2.0. If a copy of the MPL was not distributed with this
**  file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

(function () {

var pattern = /^[^<]*< ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), (.*) >/

var tokens =  function () { return {
        data: [],
        add: function (token) {
            this.data.push(token)
        },
        len: function () {
            return this.data.length
        },
        first: function (offs) {
            if (offs === undefined) {
                return this.data[0]
            }
            return this.data[offs]
        },
        consume: function (symbol) {
            if (symbol !== this.data[0]) {
                if (symbol === '}' && this.data[0] === undefined)
                    throw new Error('parse error: we are missing a closing }')
                else
                    throw new Error('parse error: could not consume token "' + symbol +'", actual token "' + this.data[0] + '"')
            }
            this.data = this.data.slice(1, this.data.length)
        },
        skip: function () {
            this.data = this.data.slice(1, this.data.length)
        }
    }
}

var tokenize = function (src) {
    var tkns = new tokens()
    var match
    while(src !== '') {
        match = src.match(/^(\s*)(["'][^"']*["']|[^\[\]()):{}\/,\s]+|[():{}\[\]\/,])(\s*)/)
        if (match === null)
            throw new Error('parse error: "' + src + '"')
        tkns.add(match[2])
        src = src.substr(match[0].length)
    }

    return tkns
}

var parseObject = function (param, params) {
    while (params.first() !== '}') {
        if (params.first() === ',')
            params.skip()
        if (params.first(2) === '{') {
            var obj = {}
            param[params.first()] = obj
            params.skip()
            params.skip()
            params.skip()
            parseObject(obj, params)
        }
        else {
            param[params.first()] = JSON.parse(params.first(2))
            params.skip()
            params.skip()
            params.skip()
        }
    }
}

var parseLog = function (lines) {
    var tuples = []
    for (var i = 0; i < lines.length; i++) {
        var line = lines[i]
        var matches = line.match(pattern)
        var params = tokenize(matches[7])
        params.skip()
        var param = {}
        parseObject(param, params)
        var newTuple = {
            time: parseInt(matches[1], 10),
            source: matches[2],
            sourceType: matches[3],
            origin: matches[4],
            originType: matches[5],
            operation: matches[6],
            parameters: param
        }
        tuples.push(newTuple)
    }
    return tuples
}

app.lib.tupleParser = {}
app.lib.tupleParser.parseLog = parseLog

})()<commit_msg>Tuples are now sorted according to their time right after importing<commit_after>/*
**  ComponentJS -- Component System for JavaScript <http://componentjs.com>
**  Copyright (c) 2009-2013 Ralf S. Engelschall <http://engelschall.com>
**
**  This Source Code Form is subject to the terms of the Mozilla Public
**  License, v. 2.0. If a copy of the MPL was not distributed with this
**  file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

(function () {

var pattern = /^[^<]*< ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), ([^,]*), (.*) >/

var tokens =  function () { return {
        data: [],
        add: function (token) {
            this.data.push(token)
        },
        len: function () {
            return this.data.length
        },
        first: function (offs) {
            if (offs === undefined) {
                return this.data[0]
            }
            return this.data[offs]
        },
        consume: function (symbol) {
            if (symbol !== this.data[0]) {
                if (symbol === '}' && this.data[0] === undefined)
                    throw new Error('parse error: we are missing a closing }')
                else
                    throw new Error('parse error: could not consume token "' + symbol +'", actual token "' + this.data[0] + '"')
            }
            this.data = this.data.slice(1, this.data.length)
        },
        skip: function () {
            this.data = this.data.slice(1, this.data.length)
        }
    }
}

var tokenize = function (src) {
    var tkns = new tokens()
    var match
    while(src !== '') {
        match = src.match(/^(\s*)(["'][^"']*["']|[^\[\]()):{}\/,\s]+|[():{}\[\]\/,])(\s*)/)
        if (match === null)
            throw new Error('parse error: "' + src + '"')
        tkns.add(match[2])
        src = src.substr(match[0].length)
    }

    return tkns
}

var parseObject = function (param, params) {
    while (params.first() !== '}') {
        if (params.first() === ',')
            params.skip()
        if (params.first(2) === '{') {
            var obj = {}
            param[params.first()] = obj
            params.skip()
            params.skip()
            params.skip()
            parseObject(obj, params)
        }
        else {
            param[params.first()] = JSON.parse(params.first(2))
            params.skip()
            params.skip()
            params.skip()
        }
    }
}

var parseLog = function (lines) {
    var tuples = []
    for (var i = 0; i < lines.length; i++) {
        var line = lines[i]
        var matches = line.match(pattern)
        var params = tokenize(matches[7])
        params.skip()
        var param = {}
        parseObject(param, params)
        var newTuple = {
            time: parseInt(matches[1], 10),
            source: matches[2],
            sourceType: matches[3],
            origin: matches[4],
            originType: matches[5],
            operation: matches[6],
            parameters: param
        }
        tuples.push(newTuple)
    }

    tuples.sort(function (a, b) { return b.time - a.time })

    return tuples
}

app.lib.tupleParser = {}
app.lib.tupleParser.parseLog = parseLog

})()<|endoftext|>


<commit_before>// opentype.js
// https://github.com/nodebox/opentype.js
// (c) 2015 Frederik De Bleser
// opentype.js may be freely distributed under the MIT license.

/* global ArrayBuffer, DataView, Uint8Array, XMLHttpRequest  */

'use strict';

var inflate = require('tiny-inflate');

var encoding = require('./encoding');
var _font = require('./font');
var glyph = require('./glyph');
var parse = require('./parse');
var path = require('./path');

var cmap = require('./tables/cmap');
var cff = require('./tables/cff');
var fvar = require('./tables/fvar');
var glyf = require('./tables/glyf');
var gpos = require('./tables/gpos');
var head = require('./tables/head');
var hhea = require('./tables/hhea');
var hmtx = require('./tables/hmtx');
var kern = require('./tables/kern');
var ltag = require('./tables/ltag');
var loca = require('./tables/loca');
var maxp = require('./tables/maxp');
var _name = require('./tables/name');
var os2 = require('./tables/os2');
var post = require('./tables/post');

// File loaders /////////////////////////////////////////////////////////

// Convert a Node.js Buffer to an ArrayBuffer
function toArrayBuffer(buffer) {
    var arrayBuffer = new ArrayBuffer(buffer.length);
    var data = new Uint8Array(arrayBuffer);
    for (var i = 0; i < buffer.length; i += 1) {
        data[i] = buffer[i];
    }

    return arrayBuffer;
}

function loadFromFile(path, callback) {
    var fs = require('fs');
    fs.readFile(path, function(err, buffer) {
        if (err) {
            return callback(err.message);
        }

        callback(null, toArrayBuffer(buffer));
    });
}

function loadFromUrl(url, callback) {
    var request = new XMLHttpRequest();
    request.open('get', url, true);
    request.responseType = 'arraybuffer';
    request.onload = function() {
        if (request.status !== 200) {
            return callback('Font could not be loaded: ' + request.statusText);
        }

        return callback(null, request.response);
    };

    request.send();
}

// Table Directory Entries //////////////////////////////////////////////

function parseOpenTypeTableEntries(data, numTables) {
    var tableEntries = [];
    var p = 12;
    for (var i = 0; i < numTables; i += 1) {
        var tag = parse.getTag(data, p);
        var offset = parse.getULong(data, p + 8);
        tableEntries.push({tag: tag, offset: offset, compression: false});
        p += 16;
    }

    return tableEntries;
}

function parseWOFFTableEntries(data, numTables) {
    var tableEntries = [];
    var p = 44; // offset to the first table directory entry.
    for (var i = 0; i < numTables; i += 1) {
        var tag = parse.getTag(data, p);
        var offset = parse.getULong(data, p + 4);
        var compLength = parse.getULong(data, p + 8);
        var origLength = parse.getULong(data, p + 12);
        var compression;
        if (compLength < origLength) {
            compression = 'WOFF';
        } else {
            compression = false;
        }

        tableEntries.push({tag: tag, offset: offset, compression: compression,
            compressedLength: compLength, originalLength: origLength});
        p += 20;
    }

    return tableEntries;
}

function uncompressTable(data, tableEntry) {
    if (tableEntry.compression === 'WOFF') {
        var inBuffer = new Uint8Array(data.buffer, tableEntry.offset + 2, tableEntry.compressedLength - 2);
        var outBuffer = new Uint8Array(tableEntry.originalLength);
        inflate(inBuffer, outBuffer);
        if (outBuffer.byteLength !== tableEntry.originalLength) {
            throw new Error('Decompression error: ' + tableEntry.tag + ' decompressed length doesn\'t match recorded length');
        }

        var view = new DataView(outBuffer.buffer, 0);
        return {data: view, offset: 0};
    } else {
        return {data: data, offset: tableEntry.offset};
    }
}

// Public API ///////////////////////////////////////////////////////////

// Parse the OpenType file data (as an ArrayBuffer) and return a Font object.
// Throws an error if the font could not be parsed.
function parseBuffer(buffer) {
    var indexToLocFormat;
    var ltagTable;

    // OpenType fonts use big endian byte ordering.
    // We can't rely on typed array view types, because they operate with the endianness of the host computer.
    // Instead we use DataViews where we can specify endianness.

    var font = new _font.Font();
    var data = new DataView(buffer, 0);
    var numTables;
    var tableEntries = [];
    var signature = parse.getTag(data, 0);
    if (signature === String.fromCharCode(0, 1, 0, 0)) {
        font.outlinesFormat = 'truetype';
        numTables = parse.getUShort(data, 4);
        tableEntries = parseOpenTypeTableEntries(data, numTables);
    } else if (signature === 'OTTO') {
        font.outlinesFormat = 'cff';
        numTables = parse.getUShort(data, 4);
        tableEntries = parseOpenTypeTableEntries(data, numTables);
    } else if (signature === 'wOFF') {
        var flavor = parse.getTag(data, 4);
        if (flavor === String.fromCharCode(0, 1, 0, 0)) {
            font.outlinesFormat = 'truetype';
        } else if (flavor === 'OTTO') {
            font.outlinesFormat = 'cff';
        } else {
            throw new Error('Unsupported OpenType flavor ' + signature);
        }
        numTables = parse.getUShort(data, 12);
        tableEntries = parseWOFFTableEntries(data, numTables);
    } else {
        throw new Error('Unsupported OpenType signature ' + signature);
    }

    var cffTableEntry;
    var fvarTableEntry;
    var glyfTableEntry;
    var gposTableEntry;
    var hmtxTableEntry;
    var kernTableEntry;
    var locaTableEntry;
    var nameTableEntry;

    for (var i = 0; i < numTables; i += 1) {
        var tableEntry = tableEntries[i];
        var table;
        switch (tableEntry.tag) {
        case 'cmap':
            table = uncompressTable(data, tableEntry);
            font.tables.cmap = cmap.parse(table.data, table.offset);
            font.encoding = new encoding.CmapEncoding(font.tables.cmap);
            break;
        case 'fvar':
            fvarTableEntry = tableEntry;
            break;
        case 'head':
            table = uncompressTable(data, tableEntry);
            font.tables.head = head.parse(table.data, table.offset);
            font.unitsPerEm = font.tables.head.unitsPerEm;
            indexToLocFormat = font.tables.head.indexToLocFormat;
            break;
        case 'hhea':
            table = uncompressTable(data, tableEntry);
            font.tables.hhea = hhea.parse(table.data, table.offset);
            font.ascender = font.tables.hhea.ascender;
            font.descender = font.tables.hhea.descender;
            font.numberOfHMetrics = font.tables.hhea.numberOfHMetrics;
            break;
        case 'hmtx':
            hmtxTableEntry = tableEntry;
            break;
        case 'ltag':
            table = uncompressTable(data, tableEntry);
            ltagTable = ltag.parse(table.data, table.offset);
            break;
        case 'maxp':
            table = uncompressTable(data, tableEntry);
            font.tables.maxp = maxp.parse(table.data, table.offset);
            font.numGlyphs = font.tables.maxp.numGlyphs;
            break;
        case 'name':
            nameTableEntry = tableEntry;
            break;
        case 'OS/2':
            table = uncompressTable(data, tableEntry);
            font.tables.os2 = os2.parse(table.data, table.offset);
            break;
        case 'post':
            table = uncompressTable(data, tableEntry);
            font.tables.post = post.parse(table.data, table.offset);
            font.glyphNames = new encoding.GlyphNames(font.tables.post);
            break;
        case 'glyf':
            glyfTableEntry = tableEntry;
            break;
        case 'loca':
            locaTableEntry = tableEntry;
            break;
        case 'CFF ':
            cffTableEntry = tableEntry;
            break;
        case 'kern':
            kernTableEntry = tableEntry;
            break;
        case 'GPOS':
            gposTableEntry = tableEntry;
            break;
        }
    }

    var nameTable = uncompressTable(data, nameTableEntry);
    font.tables.name = _name.parse(nameTable.data, nameTable.offset, ltagTable);
    font.names = font.tables.name;

    if (glyfTableEntry && locaTableEntry) {
        var shortVersion = indexToLocFormat === 0;
        var locaTable = uncompressTable(data, locaTableEntry);
        var locaOffsets = loca.parse(locaTable.data, locaTable.offset, font.numGlyphs, shortVersion);
        var glyfTable = uncompressTable(data, glyfTableEntry);
        font.glyphs = glyf.parse(glyfTable.data, glyfTable.offset, locaOffsets, font);
    } else if (cffTableEntry) {
        var cffTable = uncompressTable(data, cffTableEntry);
        cff.parse(cffTable.data, cffTable.offset, font);
    } else {
        throw new Error('Font doesn\'t contain TrueType or CFF outlines.');
    }

    var hmtxTable = uncompressTable(data, hmtxTableEntry);
    hmtx.parse(hmtxTable.data, hmtxTable.offset, font.numberOfHMetrics, font.numGlyphs, font.glyphs);
    encoding.addGlyphNames(font);

    if (kernTableEntry) {
        var kernTable = uncompressTable(data, kernTableEntry);
        font.kerningPairs = kern.parse(kernTable.data, kernTable.offset);
    } else {
        font.kerningPairs = {};
    }

    if (gposTableEntry) {
        var gposTable = uncompressTable(data, gposTableEntry);
        gpos.parse(gposTable.data, gposTable.offset, font);
    }

    if (fvarTableEntry) {
        var fvarTable = uncompressTable(data, fvarTableEntry);
        font.tables.fvar = fvar.parse(fvarTable.data, fvarTable.offset, font.names);
    }

    return font;
}

// Asynchronously load the font from a URL or a filesystem. When done, call the callback
// with two arguments `(err, font)`. The `err` will be null on success,
// the `font` is a Font object.
//
// We use the node.js callback convention so that
// opentype.js can integrate with frameworks like async.js.
function load(url, callback) {
    var isNode = typeof window === 'undefined';
    var loadFn = isNode ? loadFromFile : loadFromUrl;
    loadFn(url, function(err, arrayBuffer) {
        if (err) {
            return callback(err);
        }

        var font = parseBuffer(arrayBuffer);
        return callback(null, font);
    });
}

// Syncronously load the font from a URL or file.
// When done, return the font object or throw an error.
function loadSync(url) {
    var fs = require('fs');
    var buffer = fs.readFileSync(url);
    return parseBuffer(toArrayBuffer(buffer));
}

exports._parse = parse;
exports.Font = _font.Font;
exports.Glyph = glyph.Glyph;
exports.Path = path.Path;
exports.parse = parseBuffer;
exports.load = load;
exports.loadSync = loadSync;
<commit_msg>Fix code style issue.<commit_after>// opentype.js
// https://github.com/nodebox/opentype.js
// (c) 2015 Frederik De Bleser
// opentype.js may be freely distributed under the MIT license.

/* global ArrayBuffer, DataView, Uint8Array, XMLHttpRequest  */

'use strict';

var inflate = require('tiny-inflate');

var encoding = require('./encoding');
var _font = require('./font');
var glyph = require('./glyph');
var parse = require('./parse');
var path = require('./path');

var cmap = require('./tables/cmap');
var cff = require('./tables/cff');
var fvar = require('./tables/fvar');
var glyf = require('./tables/glyf');
var gpos = require('./tables/gpos');
var head = require('./tables/head');
var hhea = require('./tables/hhea');
var hmtx = require('./tables/hmtx');
var kern = require('./tables/kern');
var ltag = require('./tables/ltag');
var loca = require('./tables/loca');
var maxp = require('./tables/maxp');
var _name = require('./tables/name');
var os2 = require('./tables/os2');
var post = require('./tables/post');

// File loaders /////////////////////////////////////////////////////////

// Convert a Node.js Buffer to an ArrayBuffer
function toArrayBuffer(buffer) {
    var arrayBuffer = new ArrayBuffer(buffer.length);
    var data = new Uint8Array(arrayBuffer);
    for (var i = 0; i < buffer.length; i += 1) {
        data[i] = buffer[i];
    }

    return arrayBuffer;
}

function loadFromFile(path, callback) {
    var fs = require('fs');
    fs.readFile(path, function(err, buffer) {
        if (err) {
            return callback(err.message);
        }

        callback(null, toArrayBuffer(buffer));
    });
}

function loadFromUrl(url, callback) {
    var request = new XMLHttpRequest();
    request.open('get', url, true);
    request.responseType = 'arraybuffer';
    request.onload = function() {
        if (request.status !== 200) {
            return callback('Font could not be loaded: ' + request.statusText);
        }

        return callback(null, request.response);
    };

    request.send();
}

// Table Directory Entries //////////////////////////////////////////////

function parseOpenTypeTableEntries(data, numTables) {
    var tableEntries = [];
    var p = 12;
    for (var i = 0; i < numTables; i += 1) {
        var tag = parse.getTag(data, p);
        var offset = parse.getULong(data, p + 8);
        tableEntries.push({tag: tag, offset: offset, compression: false});
        p += 16;
    }

    return tableEntries;
}

function parseWOFFTableEntries(data, numTables) {
    var tableEntries = [];
    var p = 44; // offset to the first table directory entry.
    for (var i = 0; i < numTables; i += 1) {
        var tag = parse.getTag(data, p);
        var offset = parse.getULong(data, p + 4);
        var compLength = parse.getULong(data, p + 8);
        var origLength = parse.getULong(data, p + 12);
        var compression;
        if (compLength < origLength) {
            compression = 'WOFF';
        } else {
            compression = false;
        }

        tableEntries.push({tag: tag, offset: offset, compression: compression,
            compressedLength: compLength, originalLength: origLength});
        p += 20;
    }

    return tableEntries;
}

function uncompressTable(data, tableEntry) {
    if (tableEntry.compression === 'WOFF') {
        var inBuffer = new Uint8Array(data.buffer, tableEntry.offset + 2, tableEntry.compressedLength - 2);
        var outBuffer = new Uint8Array(tableEntry.originalLength);
        inflate(inBuffer, outBuffer);
        if (outBuffer.byteLength !== tableEntry.originalLength) {
            throw new Error('Decompression error: ' + tableEntry.tag + ' decompressed length doesn\'t match recorded length');
        }

        var view = new DataView(outBuffer.buffer, 0);
        return {data: view, offset: 0};
    } else {
        return {data: data, offset: tableEntry.offset};
    }
}

// Public API ///////////////////////////////////////////////////////////

// Parse the OpenType file data (as an ArrayBuffer) and return a Font object.
// Throws an error if the font could not be parsed.
function parseBuffer(buffer) {
    var indexToLocFormat;
    var ltagTable;

    // OpenType fonts use big endian byte ordering.
    // We can't rely on typed array view types, because they operate with the endianness of the host computer.
    // Instead we use DataViews where we can specify endianness.

    var font = new _font.Font();
    var data = new DataView(buffer, 0);
    var numTables;
    var tableEntries = [];
    var signature = parse.getTag(data, 0);
    if (signature === String.fromCharCode(0, 1, 0, 0)) {
        font.outlinesFormat = 'truetype';
        numTables = parse.getUShort(data, 4);
        tableEntries = parseOpenTypeTableEntries(data, numTables);
    } else if (signature === 'OTTO') {
        font.outlinesFormat = 'cff';
        numTables = parse.getUShort(data, 4);
        tableEntries = parseOpenTypeTableEntries(data, numTables);
    } else if (signature === 'wOFF') {
        var flavor = parse.getTag(data, 4);
        if (flavor === String.fromCharCode(0, 1, 0, 0)) {
            font.outlinesFormat = 'truetype';
        } else if (flavor === 'OTTO') {
            font.outlinesFormat = 'cff';
        } else {
            throw new Error('Unsupported OpenType flavor ' + signature);
        }

        numTables = parse.getUShort(data, 12);
        tableEntries = parseWOFFTableEntries(data, numTables);
    } else {
        throw new Error('Unsupported OpenType signature ' + signature);
    }

    var cffTableEntry;
    var fvarTableEntry;
    var glyfTableEntry;
    var gposTableEntry;
    var hmtxTableEntry;
    var kernTableEntry;
    var locaTableEntry;
    var nameTableEntry;

    for (var i = 0; i < numTables; i += 1) {
        var tableEntry = tableEntries[i];
        var table;
        switch (tableEntry.tag) {
        case 'cmap':
            table = uncompressTable(data, tableEntry);
            font.tables.cmap = cmap.parse(table.data, table.offset);
            font.encoding = new encoding.CmapEncoding(font.tables.cmap);
            break;
        case 'fvar':
            fvarTableEntry = tableEntry;
            break;
        case 'head':
            table = uncompressTable(data, tableEntry);
            font.tables.head = head.parse(table.data, table.offset);
            font.unitsPerEm = font.tables.head.unitsPerEm;
            indexToLocFormat = font.tables.head.indexToLocFormat;
            break;
        case 'hhea':
            table = uncompressTable(data, tableEntry);
            font.tables.hhea = hhea.parse(table.data, table.offset);
            font.ascender = font.tables.hhea.ascender;
            font.descender = font.tables.hhea.descender;
            font.numberOfHMetrics = font.tables.hhea.numberOfHMetrics;
            break;
        case 'hmtx':
            hmtxTableEntry = tableEntry;
            break;
        case 'ltag':
            table = uncompressTable(data, tableEntry);
            ltagTable = ltag.parse(table.data, table.offset);
            break;
        case 'maxp':
            table = uncompressTable(data, tableEntry);
            font.tables.maxp = maxp.parse(table.data, table.offset);
            font.numGlyphs = font.tables.maxp.numGlyphs;
            break;
        case 'name':
            nameTableEntry = tableEntry;
            break;
        case 'OS/2':
            table = uncompressTable(data, tableEntry);
            font.tables.os2 = os2.parse(table.data, table.offset);
            break;
        case 'post':
            table = uncompressTable(data, tableEntry);
            font.tables.post = post.parse(table.data, table.offset);
            font.glyphNames = new encoding.GlyphNames(font.tables.post);
            break;
        case 'glyf':
            glyfTableEntry = tableEntry;
            break;
        case 'loca':
            locaTableEntry = tableEntry;
            break;
        case 'CFF ':
            cffTableEntry = tableEntry;
            break;
        case 'kern':
            kernTableEntry = tableEntry;
            break;
        case 'GPOS':
            gposTableEntry = tableEntry;
            break;
        }
    }

    var nameTable = uncompressTable(data, nameTableEntry);
    font.tables.name = _name.parse(nameTable.data, nameTable.offset, ltagTable);
    font.names = font.tables.name;

    if (glyfTableEntry && locaTableEntry) {
        var shortVersion = indexToLocFormat === 0;
        var locaTable = uncompressTable(data, locaTableEntry);
        var locaOffsets = loca.parse(locaTable.data, locaTable.offset, font.numGlyphs, shortVersion);
        var glyfTable = uncompressTable(data, glyfTableEntry);
        font.glyphs = glyf.parse(glyfTable.data, glyfTable.offset, locaOffsets, font);
    } else if (cffTableEntry) {
        var cffTable = uncompressTable(data, cffTableEntry);
        cff.parse(cffTable.data, cffTable.offset, font);
    } else {
        throw new Error('Font doesn\'t contain TrueType or CFF outlines.');
    }

    var hmtxTable = uncompressTable(data, hmtxTableEntry);
    hmtx.parse(hmtxTable.data, hmtxTable.offset, font.numberOfHMetrics, font.numGlyphs, font.glyphs);
    encoding.addGlyphNames(font);

    if (kernTableEntry) {
        var kernTable = uncompressTable(data, kernTableEntry);
        font.kerningPairs = kern.parse(kernTable.data, kernTable.offset);
    } else {
        font.kerningPairs = {};
    }

    if (gposTableEntry) {
        var gposTable = uncompressTable(data, gposTableEntry);
        gpos.parse(gposTable.data, gposTable.offset, font);
    }

    if (fvarTableEntry) {
        var fvarTable = uncompressTable(data, fvarTableEntry);
        font.tables.fvar = fvar.parse(fvarTable.data, fvarTable.offset, font.names);
    }

    return font;
}

// Asynchronously load the font from a URL or a filesystem. When done, call the callback
// with two arguments `(err, font)`. The `err` will be null on success,
// the `font` is a Font object.
//
// We use the node.js callback convention so that
// opentype.js can integrate with frameworks like async.js.
function load(url, callback) {
    var isNode = typeof window === 'undefined';
    var loadFn = isNode ? loadFromFile : loadFromUrl;
    loadFn(url, function(err, arrayBuffer) {
        if (err) {
            return callback(err);
        }

        var font = parseBuffer(arrayBuffer);
        return callback(null, font);
    });
}

// Syncronously load the font from a URL or file.
// When done, return the font object or throw an error.
function loadSync(url) {
    var fs = require('fs');
    var buffer = fs.readFileSync(url);
    return parseBuffer(toArrayBuffer(buffer));
}

exports._parse = parse;
exports.Font = _font.Font;
exports.Glyph = glyph.Glyph;
exports.Path = path.Path;
exports.parse = parseBuffer;
exports.load = load;
exports.loadSync = loadSync;
<|endoftext|>


<commit_before><commit_msg>Implement prefix dropdown for qname block<commit_after><|endoftext|>


<commit_before>$ = require("jquery");
s_ = require("./../spatie-front.js");
var GoogleMapsLoader = require('google-maps');

// Object
s_.map = {
    element : $('[data-map]'),
    readConfiguration : function(){
        this.lat = this.element.data('map-lat');
        this.lng = this.element.data('map-lng');
        this.lng = this.element.data('map-zoom');
        this.options = this.element.data('map-options');
        this.locations = this.element.data('map-locations');
    },
    renderMap : function(google){
        this.options.center = new google.maps.LatLng(this.lat , this.lng);
        this.map = new google.maps.Map( this.element[0] , this.options);
    },
    renderLocations : function(google){
        this.locations.map(function(){
            var markerIcon = this.icon;
            var markerLatLng = new google.maps.LatLng(this.lat,this.lng);

            var markerImage = new google.maps.MarkerImage( markerIcon.image, null, null, null, new google.maps.Size( markerIcon.width, markerIcon.height ));
            var marker = new google.maps.Marker({
                position: markerLatLng,
                map: this.map,
                flat: true,
                title: this.title,
                icon: markerImage
            });

            if(this.url!='') {
                google.maps.event.addListener(marker, 'click', function () {
                    window.location.href = this.url;
                });
            }
        });
    },
    init : function(){
        GoogleMapsLoader.load(function(google) {
            this.readConfiguration();
            this.renderMap(google);
            this.renderLocations(google);
        });
    }
};

module.exports = s_.map;<commit_msg>interface.map<commit_after>$ = require("jquery");
s_ = require("./../spatie-front.js");
var GoogleMapsLoader = require('google-maps');

// Object
s_.map = {
    element: $('[data-map]'),
    readConfiguration: function () {
        this.lat = this.element.data('map-lat');
        this.lng = this.element.data('map-lng');
        this.options = this.element.data('map-options');
        this.locations = this.element.data('map-locations');
    },
    renderMap: function (google) {
        this.options.center = new google.maps.LatLng(this.lat, this.lng);
        if (typeof this.options.mapTypeId === 'string') { //Load data from HTML: every prop is number, boolean or string. No custom objects
            this.options.mapTypeId = eval(this.options.mapTypeId);
        }

        this.map = new google.maps.Map(this.element[0], this.options);
    },
    renderLocations: function (google) {

        var map = this.map;

        this.locations.map(function (location) {
            var markerIcon = location.icon;
            var markerLatLng = new google.maps.LatLng(location.lat, location.lng);
            var markerImage = new google.maps.MarkerImage(markerIcon.image, null, null, null, new google.maps.Size(markerIcon.width, markerIcon.height));
            var marker = new google.maps.Marker({
                position: markerLatLng,
                map: map,
                flat: true,
                title: location.title,
                icon: markerImage
            });

            if (location.url != '') {
                google.maps.event.addListener(marker, 'click', function () {
                    window.location.href = location.url;
                });
            }
        });
    },
    init: function (element) {
        this.element = element;
        var map = this;
        GoogleMapsLoader.load(function (google) {
            map.readConfiguration();
            map.renderMap(google);
            map.renderLocations(google);
        });
    }
};

module.exports = s_.map;<|endoftext|>


<commit_before>const about = {
    bindings: {},
    controller: function () {
        let ctrl = this;

        ctrl.imageUrl = "/images/winterPineTrees.jpg";
        ctrl.title = "ABOUT US";

        ctrl.$onInit = function () {};
    },
    template:   `
        <parallax-jumbotron image-url="$ctrl.imageUrl" title="$ctrl.title"></parallax-jumbotron>

Hi I'm just a test div

          Seitan tattooed occupy kinfolk raw denim brunch, vinyl photo booth pork belly. Austin vegan before they sold out edison bulb next level cronut unicorn ugh. Tousled XOXO gochujang edison bulb thundercats disrupt. Chillwave cloud bread everyday carry venmo distillery. Poutine yr schlitz artisan. Try-hard truffaut craft beer raclette blog marfa keffiyeh kombucha poutine YOLO retro celiac hell of banh mi. Man braid bushwick ramps meh hoodie. Gluten-free art party gentrify hot chicken. Activated charcoal intelligentsia ennui meditation. Single-origin coffee blue bottle XOXO, helvetica fixie four loko jean shorts small batch. Taxidermy brooklyn man bun kitsch franzen vaporware.

    `
};

angular.module('RowdyMermaid-site.about')
    .component('about', about);

about.$inject = [];
<commit_msg>added parallax jumbotron to about page #51<commit_after>const about = {
    bindings: {},
    controller: function () {
        let ctrl = this;

        ctrl.imageUrl = "/images/winterPineTrees.jpg";
        ctrl.title = "ABOUT US";

        ctrl.$onInit = function () {};
    },
    template:   `
        <parallax-jumbotron image-url="$ctrl.imageUrl" title="$ctrl.title"></parallax-jumbotron>

          Seitan tattooed occupy kinfolk raw denim brunch, vinyl photo booth pork belly. Austin vegan before they sold out edison bulb next level cronut unicorn ugh. Tousled XOXO gochujang edison bulb thundercats disrupt. Chillwave cloud bread everyday carry venmo distillery. Poutine yr schlitz artisan. Try-hard truffaut craft beer raclette blog marfa keffiyeh kombucha poutine YOLO retro celiac hell of banh mi. Man braid bushwick ramps meh hoodie. Gluten-free art party gentrify hot chicken. Activated charcoal intelligentsia ennui meditation. Single-origin coffee blue bottle XOXO, helvetica fixie four loko jean shorts small batch. Taxidermy brooklyn man bun kitsch franzen vaporware.

    `
};

angular.module('RowdyMermaid-site.about')
    .component('about', about);

about.$inject = [];
<|endoftext|>


<commit_before>(function(angular){
    'use strict';

    var app = angular.module('timtec.discussion', [
        'header',
        'discussion',
        'djangular',
        'django',
    ]);
})(angular);
<commit_msg>usa app djangular para o discussion<commit_after>(function(angular){
    'use strict';

    var app = angular.module('timtec.discussion', [
        'header',
        'discussion',
        'djangular',
    ]);
})(angular);
<|endoftext|>


<commit_before>import { Log } from '../infrastructure';
import { Command } from '../command';
import { Shortcut } from '../shortcut';
import { CellEditor } from './edit.cell.editor';
import { getFactory as valueFactory } from '../services/value';
import { getFactory as labelFactory } from '../services/label';
import { parseFactory } from '../services';
import { View } from '../view';

export class EditCellView extends View {
	constructor(model, table, commandManager) {
		super();

		this.model = model;
		this.table = table;

		this.editor = CellEditor.empty;
		this.commandManager = commandManager;

		this.shortcut = model.action().shortcut;
		const commands = this.commands;
		this.shortcutOff = this.shortcut.register(commandManager, commands);

		this.enter = commands.get('enter');
		this.commit = commands.get('commit');
		this.cancel = commands.get('cancel');
		this.reset = commands.get('reset');

		this.using(model.navigationChanged.watch(e => {
			if (e.hasChanges('cell')) {
				const oldCell = e.changes.cell.oldValue;
				if (oldCell && oldCell.column.editorOptions.trigger === 'focus') {
					if (this.commit.canExecute(oldCell)) {
						this.commit.execute(oldCell);
					}
				}

				const newCell = e.changes.cell.newValue;
				if (newCell && newCell.column.editorOptions.trigger === 'focus') {
					if (this.enter.canExecute(newCell)) {
						this.enter.execute(newCell);
					}
				}
			}
		}));
	}

	get commands() {
		const model = this.model;
		const table = this.table;
		const commands = {
			enter: new Command({
				shortcut: this.shortcutFactory('enter'),
				canExecute: cell => {
					// TODO: source should be set up from outside
					const source = cell ? 'mouse' : 'keyboard';
					if (source === 'keyboard' && Shortcut.isControl(this.shortcut.keyCode)) {
						return false;
					}

					cell = cell || model.navigation().cell;
					return cell
						&& cell.column.canEdit
						&& (cell.column.class === 'control' || model.edit().mode === 'cell')
						&& model.edit().state === 'view'
						&& model.edit().enter.canExecute(this.contextFactory(cell));
				},
				execute: (cell, e) => {
					Log.info('cell.edit', 'edit mode');
					if (e) {
						e.stopImmediatePropagation();
					}

					// TODO: source should be set up from outside
					const source = cell ? 'mouse' : 'keyboard';
					cell = cell || model.navigation().cell;
					if (cell && model.edit().enter.execute(this.contextFactory(cell, cell.value, cell.label)) !== false) {
						this.editor = new CellEditor(cell);
						if (source === 'keyboard' && Shortcut.isPrintable(this.shortcut.keyCode)) {
							const parse = parseFactory(cell.column.type);
							const value = Shortcut.stringify(this.shortcut.keyCode);
							const typedValue = parse(value);
							if (typedValue !== null) {
								this.value = typedValue;
							}
						}

						model.edit({ state: 'edit' });
						cell.mode('edit');
						return true;
					}

					return false;
				}
			}),
			commit: new Command({
				shortcut: this.shortcutFactory('commit'),
				// TODO: add validation support
				canExecute: cell => {
					cell = cell || this.editor.cell;
					return cell
						&& cell === this.editor.cell
						&& cell.column.canEdit
						&& (cell.column.class === 'control' || model.edit().mode === 'cell')
						&& model.edit().state === 'edit'
						&& model.edit().commit.canExecute(this.contextFactory(cell));
				},
				execute: (cell, e, timeout) => {
					Log.info('cell.edit', 'commit');
					if (e) {
						e.stopImmediatePropagation();
					}

					cell = cell || this.editor.cell;
					if (cell && model.edit().commit.execute(this.contextFactory(cell, this.value, this.label, this.tag)) !== false) {
						this.editor.commit();
						this.editor = CellEditor.empty;
						model.edit({ state: 'view' });

						const toggleMode = () => {
							cell.mode('view');
							table.view.focus();
						};

						if (timeout) {
							setTimeout(toggleMode, timeout);
						}
						else {
							toggleMode();
						}
						return true;
					}

					return false;
				}
			}),
			cancel: new Command({
				shortcut: this.shortcutFactory('cancel'),
				canExecute: cell => {
					cell = cell || this.editor.cell;
					return cell
						&& cell.column.canEdit
						&& (cell.column.class === 'control' || model.edit().mode === 'cell')
						&& model.edit().state === 'edit'
						&& model.edit().cancel.canExecute(this.contextFactory(cell, this.value, this.label));
				},
				execute: (cell, e, timeout) => {
					Log.info('cell.edit', 'cancel');
					if (e) {
						e.stopImmediatePropagation();
					}

					cell = cell || this.editor.cell;
					if (cell && model.edit().cancel.execute(this.contextFactory(cell, cell.value, cell.label)) !== false) {
						this.editor.reset();
						this.editor = CellEditor.empty;

						model.edit({ state: 'view' });
						const toggleMode = () => {
							cell.mode('view');
							table.view.focus();
						};

						if (timeout) {
							setTimeout(toggleMode, timeout);
						}
						else {
							toggleMode();
						}

						return true;
					}

					return false;
				}
			}),
			reset: new Command({
				canExecute: cell => {
					cell = cell || this.editor.cell;
					return cell
						&& cell.column.canEdit
						&& (cell.column.class === 'control' || model.edit().mode === 'cell')
						&& model.edit().state === 'edit'
						&& model.edit().reset.canExecute(this.contextFactory(cell, this.value, this.label));
				},
				execute: (cell, e) => {
					Log.info('cell.edit', 'reset');
					if (e) {
						e.stopImmediatePropagation();
					}

					cell = cell || this.editor.cell;
					if (cell && model.edit().reset.execute(this.contextFactory(cell, this.value, this.label)) !== false) {
						this.editor.reset();
						return true;
					}

					return false;
				}
			})
		};

		return new Map(
			Object.entries(commands)
		);
	}

	contextFactory(cell, value, label, tag) {
		return {
			column: cell.column,
			row: cell.row,
			columnIndex: cell.columnIndex,
			rowIndex: cell.rowIndex,
			oldValue: cell.value,
			newValue: arguments.length >= 2 ? value : cell.value,
			oldLabel: cell.label,
			newLabel: arguments.length >= 3 ? label : cell.label,
			unit: 'cell',
			tag: tag,
			valueFactory: valueFactory,
			labelFactory: labelFactory
		};
	}

	get fetch() {
		return this.editor.fetch;
	}

	get value() {
		return this.editor.value;
	}

	set value(value) {
		this.editor.value = value;
	}

	get label() {
		return this.editor.label;
	}

	set label(label) {
		this.editor.label = label;
	}

	get column() {
		return this.editor.column;
	}

	canEdit(cell) {
		if (cell) {
			return cell.column.canEdit && this.model.edit().mode === 'cell';
		}

		return false;
	}

	get options() {
		return this.editor.options;
	}

	shortcutFactory(type) {
		const model = this.model;
		const edit = model.edit;
		return () => {
			const shortcuts = edit()[type + 'Shortcuts'];
			const cell = this.editor.cell;
			if (cell) {
				const type = cell.column && cell.column.editor ? cell.column.editor : cell.column.type;
				if (shortcuts.hasOwnProperty(type)) {
					return shortcuts[type];
				}
			}

			return shortcuts['$default'];
		};
	}

	dispose() {
		super.dispose();

		this.editor.reset();
		this.shortcutOff();
	}
}<commit_msg>added timeout to cancel and commit<commit_after>import {Log} from '../infrastructure';
import {Command} from '../command';
import {Shortcut} from '../shortcut';
import {CellEditor} from './edit.cell.editor';
import {getFactory as valueFactory} from '../services/value';
import {getFactory as labelFactory} from '../services/label';
import {parseFactory} from '../services';
import {View} from '../view';

export class EditCellView extends View {
	constructor(model, table, commandManager) {
		super();

		this.model = model;
		this.table = table;

		this.editor = CellEditor.empty;
		this.commandManager = commandManager;

		this.shortcut = model.action().shortcut;
		const commands = this.commands;
		this.shortcutOff = this.shortcut.register(commandManager, commands);

		this.enter = commands.get('enter');
		this.commit = commands.get('commit');
		this.cancel = commands.get('cancel');
		this.reset = commands.get('reset');

		this.using(model.navigationChanged.watch(e => {
			if (e.hasChanges('cell')) {
				const oldCell = e.changes.cell.oldValue;
				if (oldCell && oldCell.column.editorOptions.trigger === 'focus') {
					if (this.commit.canExecute(oldCell)) {
						this.commit.execute(oldCell);
					}
				}

				const newCell = e.changes.cell.newValue;
				if (newCell && newCell.column.editorOptions.trigger === 'focus') {
					if (this.enter.canExecute(newCell)) {
						this.enter.execute(newCell);
					}
				}
			}
		}));
	}

	get commands() {
		const model = this.model;
		const table = this.table;
		const commands = {
			enter: new Command({
				shortcut: this.shortcutFactory('enter'),
				canExecute: cell => {
					// TODO: source should be set up from outside
					const source = cell ? 'mouse' : 'keyboard';
					if (source === 'keyboard' && Shortcut.isControl(this.shortcut.keyCode)) {
						return false;
					}

					cell = cell || model.navigation().cell;
					return cell
						&& cell.column.canEdit
						&& (cell.column.class === 'control' || model.edit().mode === 'cell')
						&& model.edit().state === 'view'
						&& model.edit().enter.canExecute(this.contextFactory(cell));
				},
				execute: (cell, e) => {
					Log.info('cell.edit', 'edit mode');
					if (e) {
						e.stopImmediatePropagation();
					}

					// TODO: source should be set up from outside
					const source = cell ? 'mouse' : 'keyboard';
					cell = cell || model.navigation().cell;
					if (cell && model.edit().enter.execute(this.contextFactory(cell, cell.value, cell.label)) !== false) {
						this.editor = new CellEditor(cell);
						if (source === 'keyboard' && Shortcut.isPrintable(this.shortcut.keyCode)) {
							const parse = parseFactory(cell.column.type);
							const value = Shortcut.stringify(this.shortcut.keyCode);
							const typedValue = parse(value);
							if (typedValue !== null) {
								this.value = typedValue;
							}
						}

						model.edit({ state: 'edit' });
						cell.mode('edit');
						return true;
					}

					return false;
				}
			}),
			commit: new Command({
				shortcut: this.shortcutFactory('commit'),
				// TODO: add validation support
				canExecute: cell => {
					cell = cell || this.editor.cell;
					return cell
						&& cell === this.editor.cell
						&& cell.column.canEdit
						&& (cell.column.class === 'control' || model.edit().mode === 'cell')
						&& model.edit().state === 'edit'
						&& model.edit().commit.canExecute(this.contextFactory(cell));
				},
				execute: (cell, e, timeout) => {
					Log.info('cell.edit', 'commit');
					if (e) {
						e.stopImmediatePropagation();
					}

					cell = cell || this.editor.cell;
					if (cell && model.edit().commit.execute(this.contextFactory(cell, this.value, this.label, this.tag)) !== false) {
						this.editor.commit();
						this.editor = CellEditor.empty;
						model.edit({ state: 'view' });

						const toggleMode = () => {
							cell.mode('view');
							table.view.focus();
						};

						if (timeout) {
							setTimeout(toggleMode, timeout);
						}
						else {
							toggleMode();
						}
						return true;
					}

					return false;
				}
			}),
			cancel: new Command({
				shortcut: this.shortcutFactory('cancel'),
				canExecute: cell => {
					cell = cell || this.editor.cell;
					return cell
						&& cell.column.canEdit
						&& (cell.column.class === 'control' || model.edit().mode === 'cell')
						&& model.edit().state === 'edit'
						&& model.edit().cancel.canExecute(this.contextFactory(cell, this.value, this.label));
				},
				execute: (cell, e, timeout) => {
					Log.info('cell.edit', 'cancel');
					if (e) {
						e.stopImmediatePropagation();
					}

					cell = cell || this.editor.cell;
					if (cell && model.edit().cancel.execute(this.contextFactory(cell, cell.value, cell.label)) !== false) {
						this.editor.reset();
						this.editor = CellEditor.empty;

						model.edit({ state: 'view' });
						const toggleMode = () => {
							cell.mode('view');
							table.view.focus();
						};

						if (timeout) {
							setTimeout(toggleMode, timeout);
						}
						else {
							toggleMode();
						}

						return true;
					}

					return false;
				}
			}),
			reset: new Command({
				canExecute: cell => {
					cell = cell || this.editor.cell;
					return cell
						&& cell.column.canEdit
						&& (cell.column.class === 'control' || model.edit().mode === 'cell')
						&& model.edit().state === 'edit'
						&& model.edit().reset.canExecute(this.contextFactory(cell, this.value, this.label));
				},
				execute: (cell, e) => {
					Log.info('cell.edit', 'reset');
					if (e) {
						e.stopImmediatePropagation();
					}

					cell = cell || this.editor.cell;
					if (cell && model.edit().reset.execute(this.contextFactory(cell, this.value, this.label)) !== false) {
						this.editor.reset();
						return true;
					}

					return false;
				}
			})
		};

		return new Map(
			Object.entries(commands)
		);
	}

	contextFactory(cell, value, label, tag) {
		return {
			column: cell.column,
			row: cell.row,
			columnIndex: cell.columnIndex,
			rowIndex: cell.rowIndex,
			oldValue: cell.value,
			newValue: arguments.length >= 2 ? value : cell.value,
			oldLabel: cell.label,
			newLabel: arguments.length >= 3 ? label : cell.label,
			unit: 'cell',
			tag: tag,
			valueFactory: valueFactory,
			labelFactory: labelFactory
		};
	}

	get fetch() {
		return this.editor.fetch;
	}

	get value() {
		return this.editor.value;
	}

	set value(value) {
		this.editor.value = value;
	}

	get label() {
		return this.editor.label;
	}

	set label(label) {
		this.editor.label = label;
	}

	get column() {
		return this.editor.column;
	}

	canEdit(cell) {
		if (cell) {
			return cell.column.canEdit && this.model.edit().mode === 'cell';
		}

		return false;
	}

	get options() {
		return this.editor.options;
	}

	shortcutFactory(type) {
		const model = this.model;
		const edit = model.edit;
		return () => {
			const shortcuts = edit()[type + 'Shortcuts'];
			const cell = this.editor.cell;
			if (cell) {
				const type = cell.column && cell.column.editor ? cell.column.editor : cell.column.type;
				if (shortcuts.hasOwnProperty(type)) {
					return shortcuts[type];
				}
			}

			return shortcuts['$default'];
		};
	}

	dispose() {
		super.dispose();

		this.editor.reset();
		this.shortcutOff();
	}
}<|endoftext|>


<commit_before>/**
 * This module adds GDPR consentManagement support to prebid.js.  It interacts with
 * supported CMPs (Consent Management Platforms) to grab the user's consent information
 * and make it available for any GDPR supported adapters to read/pass this information to
 * their system.
 */
import * as utils from 'src/utils';
import { config } from 'src/config';
import { gdprDataHandler } from 'src/adaptermanager';
import includes from 'core-js/library/fn/array/includes';
import strIncludes from 'core-js/library/fn/string/includes';

const DEFAULT_CMP = 'iab';
const DEFAULT_CONSENT_TIMEOUT = 10000;
const DEFAULT_ALLOW_AUCTION_WO_CONSENT = true;

export let userCMP;
export let consentTimeout;
export let allowAuction;

let consentData;

let context;
let args;
let nextFn;
let bidsBackHandler;

let timer;
let haveExited;

// add new CMPs here, with their dedicated lookup function
const cmpCallMap = {
  'iab': lookupIabConsent
};

/**
 * This function handles interacting with an IAB compliant CMP to obtain the consent information of the user.
 * Given the async nature of the CMP's API, we pass in acting success/error callback functions to exit this function
 * based on the appropriate result.
 * @param {function(string)} cmpSuccess acts as a success callback when CMP returns a value; pass along consentObject (string) from CMP
 * @param {function(string)} cmpError acts as an error callback while interacting with CMP; pass along an error message (string)
 * @param {[objects]} adUnits used in the safeframe workflow to know what sizes to include in the $sf.ext.register call
 */
function lookupIabConsent(cmpSuccess, cmpError, adUnits) {
  function handleCmpResponseCallbacks() {
    const cmpResponse = {};

    function afterEach() {
      if (cmpResponse.getConsentData && cmpResponse.getVendorConsents) {
        cmpSuccess(cmpResponse);
      }
    }

    return {
      consentDataCallback: function(consentResponse) {
        cmpResponse.getConsentData = consentResponse;
        afterEach();
      },
      vendorConsentsCallback: function(consentResponse) {
        cmpResponse.getVendorConsents = consentResponse;
        afterEach();
      }
    }
  }
  let callbackHandler = handleCmpResponseCallbacks();
  let cmpCallbacks = {};

  // to collect the consent information from the user, we perform two calls to the CMP in parallel:
  // first to collect the user's consent choices represented in an encoded string (via getConsentData)
  // second to collect the user's full unparsed consent information (via getVendorConsents)

  // the following code also determines where the CMP is located and uses the proper workflow to communicate with it:
  // check to see if CMP is found on the same window level as prebid and call it directly if so
  // check to see if prebid is in a safeframe (with CMP support)
  // else assume prebid may be inside an iframe and use the IAB CMP locator code to see if CMP's located in a higher parent window. this works in cross domain iframes
  // if the CMP is not found, the iframe function will call the cmpError exit callback to abort the rest of the CMP workflow
  if (utils.isFn(window.__cmp)) {
    window.__cmp('getConsentData', null, callbackHandler.consentDataCallback);
    window.__cmp('getVendorConsents', null, callbackHandler.vendorConsentsCallback);
  } else if (inASafeFrame() && typeof window.$sf.ext.cmp === 'function') {
    callCmpWhileInSafeFrame('getConsentData', callbackHandler.consentDataCallback);
    callCmpWhileInSafeFrame('getVendorConsents', callbackHandler.vendorConsentsCallback);
  } else {
    // find the CMP frame
    let f = window;
    let cmpFrame;
    while (!cmpFrame) {
      try {
        if (f.frames['__cmpLocator']) cmpFrame = f;
      } catch (e) {}
      if (f === window.top) break;
      f = f.parent;
    }

    callCmpWhileInIframe('getConsentData', cmpFrame, callbackHandler.consentDataCallback);
    callCmpWhileInIframe('getVendorConsents', cmpFrame, callbackHandler.vendorConsentsCallback);
  }

  function inASafeFrame() {
    return !!(window.$sf && window.$sf.ext);
  }

  function callCmpWhileInSafeFrame(commandName, callback) {
    function sfCallback(msgName, data) {
      if (msgName === 'cmpReturn') {
        let responseObj = (commandName === 'getConsentData') ? data.vendorConsentData : data.vendorConsents;
        callback(responseObj);
      }
    }

    // find sizes from adUnits object
    let width = 1;
    let height = 1;
    if (Array.isArray(adUnits) && adUnits.length > 0) {
      let sizes = utils.getAdUnitSizes(adUnits[0]);
      width = sizes[0][0];
      height = sizes[0][1];
    }

    window.$sf.ext.register(width, height, sfCallback);
    window.$sf.ext.cmp(commandName);
  }

  function callCmpWhileInIframe(commandName, cmpFrame, moduleCallback) {
    /* Setup up a __cmp function to do the postMessage and stash the callback.
      This function behaves (from the caller's perspective identicially to the in-frame __cmp call */
    window.__cmp = function(cmd, arg, callback) {
      if (!cmpFrame) {
        removePostMessageListener();

        let errmsg = 'CMP not found';
        return cmpError(errmsg);
      }
      let callId = Math.random() + '';
      let msg = {__cmpCall: {
        command: cmd,
        parameter: arg,
        callId: callId
      }};
      cmpCallbacks[callId] = callback;
      cmpFrame.postMessage(msg, '*');
    }

    /** when we get the return message, call the stashed callback */
    window.addEventListener('message', readPostMessageResponse, false);

    // call CMP
    window.__cmp(commandName, null, cmpIframeCallback);

    function readPostMessageResponse(event) {
      let json = (typeof event.data === 'string' && strIncludes(event.data, 'cmpReturn')) ? JSON.parse(event.data) : event.data;
      if (json.__cmpReturn && json.__cmpReturn.callId) {
        let i = json.__cmpReturn;
        // TODO - clean up this logic (move listeners?); we have duplicate messages responses because 2 eventlisteners are active from the 2 cmp requests running in parallel
        if (typeof cmpCallbacks[i.callId] !== 'undefined') {
          cmpCallbacks[i.callId](i.returnValue, i.success);
          delete cmpCallbacks[i.callId];
        }
      }
    }

    function removePostMessageListener() {
      window.removeEventListener('message', readPostMessageResponse, false);
    }

    function cmpIframeCallback(consentObject) {
      removePostMessageListener();
      moduleCallback(consentObject);
    }
  }
}

/**
 * If consentManagement module is enabled (ie included in setConfig), this hook function will attempt to fetch the
 * user's encoded consent string from the supported CMP.  Once obtained, the module will store this
 * data as part of a gdprConsent object which gets transferred to adaptermanager's gdprDataHandler object.
 * This information is later added into the bidRequest object for any supported adapters to read/pass along to their system.
 * @param {object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids.
 * @param {function} fn required; The next function in the chain, used by hook.js
 */
export function requestBidsHook(reqBidsConfigObj, fn) {
  context = this;
  args = arguments;
  nextFn = fn;
  haveExited = false;
  let adUnits = reqBidsConfigObj.adUnits || $$PREBID_GLOBAL$$.adUnits;
  bidsBackHandler = reqBidsConfigObj.bidsBackHandler;

  // in case we already have consent (eg during bid refresh)
  if (consentData) {
    return exitModule();
  }

  if (!includes(Object.keys(cmpCallMap), userCMP)) {
    utils.logWarn(`CMP framework (${userCMP}) is not a supported framework.  Aborting consentManagement module and resuming auction.`);
    return nextFn.apply(context, args);
  }

  cmpCallMap[userCMP].call(this, processCmpData, cmpFailed, adUnits);

  // only let this code run if module is still active (ie if the callbacks used by CMPs haven't already finished)
  if (!haveExited) {
    if (consentTimeout === 0) {
      processCmpData(undefined);
    } else {
      timer = setTimeout(cmpTimedOut, consentTimeout);
    }
  }
}

/**
 * This function checks the consent data provided by CMP to ensure it's in an expected state.
 * If it's bad, we exit the module depending on config settings.
 * If it's good, then we store the value and exits the module.
 * @param {object} consentObject required; object returned by CMP that contains user's consent choices
 */
function processCmpData(consentObject) {
  if (
    !utils.isPlainObject(consentObject) ||
    (!utils.isPlainObject(consentObject.getVendorConsents) || Object.keys(consentObject.getVendorConsents).length === 0) ||
    (!utils.isPlainObject(consentObject.getConsentData) || Object.keys(consentObject.getConsentData).length === 0)) {
    cmpFailed(`CMP returned unexpected value during lookup process; returned value was (${consentObject}).`);
  } else {
    clearTimeout(timer);
    storeConsentData(consentObject);

    exitModule();
  }
}

/**
 * General timeout callback when interacting with CMP takes too long.
 */
function cmpTimedOut() {
  cmpFailed('CMP workflow exceeded timeout threshold.');
}

/**
 * This function contains the controlled steps to perform when there's a problem with CMP.
 * @param {string} errMsg required; should be a short descriptive message for why the failure/issue happened.
*/
function cmpFailed(errMsg) {
  clearTimeout(timer);

  // still set the consentData to undefined when there is a problem as per config options
  if (allowAuction) {
    storeConsentData(undefined);
  }
  exitModule(errMsg);
}

/**
 * Stores CMP data locally in module and then invokes gdprDataHandler.setConsentData() to make information available in adaptermanger.js for later in the auction
 * @param {object} cmpConsentObject required; an object representing user's consent choices (can be undefined in certain use-cases for this function only)
 */
function storeConsentData(cmpConsentObject) {
  consentData = {
    consentString: (cmpConsentObject) ? cmpConsentObject.getConsentData.consentData : undefined,
    vendorData: (cmpConsentObject) ? cmpConsentObject.getVendorConsents : undefined,
    gdprApplies: (cmpConsentObject) ? cmpConsentObject.getConsentData.gdprApplies : undefined
  };
  gdprDataHandler.setConsentData(consentData);
}

/**
 * This function handles the exit logic for the module.
 * There are several paths in the module's logic to call this function and we only allow 1 of the 3 potential exits to happen before suppressing others.
 *
 * We prevent multiple exits to avoid conflicting messages in the console depending on certain scenarios.
 * One scenario could be auction was canceled due to timeout with CMP being reached.
 * While the timeout is the accepted exit and runs first, the CMP's callback still tries to process the user's data (which normally leads to a good exit).
 * In this case, the good exit will be suppressed since we already decided to cancel the auction.
 *
 * Three exit paths are:
 * 1. good exit where auction runs (CMP data is processed normally).
 * 2. bad exit but auction still continues (warning message is logged, CMP data is undefined and still passed along).
 * 3. bad exit with auction canceled (error message is logged).
 * @param {string} errMsg optional; only to be used when there was a 'bad' exit.  String is a descriptive message for the failure/issue encountered.
 */
function exitModule(errMsg) {
  if (haveExited === false) {
    haveExited = true;

    if (errMsg) {
      if (allowAuction) {
        utils.logWarn(errMsg + ' Resuming auction without consent data as per consentManagement config.');
        nextFn.apply(context, args);
      } else {
        utils.logError(errMsg + ' Canceling auction as per consentManagement config.');
        if (typeof bidsBackHandler === 'function') {
          bidsBackHandler();
        } else {
          utils.logError('Error executing bidsBackHandler');
        }
      }
    } else {
      nextFn.apply(context, args);
    }
  }
}

/**
 * Simply resets the module's consentData variable back to undefined, mainly for testing purposes
 */
export function resetConsentData() {
  consentData = undefined;
  gdprDataHandler.setConsentData(null);
}

/**
 * A configuration function that initializes some module variables, as well as add a hook into the requestBids function
 * @param {object} config required; consentManagement module config settings; cmp (string), timeout (int), allowAuctionWithoutConsent (boolean)
 */
export function setConfig(config) {
  if (utils.isStr(config.cmpApi)) {
    userCMP = config.cmpApi;
  } else {
    userCMP = DEFAULT_CMP;
    utils.logInfo(`consentManagement config did not specify cmp.  Using system default setting (${DEFAULT_CMP}).`);
  }

  if (utils.isNumber(config.timeout)) {
    consentTimeout = config.timeout;
  } else {
    consentTimeout = DEFAULT_CONSENT_TIMEOUT;
    utils.logInfo(`consentManagement config did not specify timeout.  Using system default setting (${DEFAULT_CONSENT_TIMEOUT}).`);
  }

  if (typeof config.allowAuctionWithoutConsent === 'boolean') {
    allowAuction = config.allowAuctionWithoutConsent;
  } else {
    allowAuction = DEFAULT_ALLOW_AUCTION_WO_CONSENT;
    utils.logInfo(`consentManagement config did not specify allowAuctionWithoutConsent.  Using system default setting (${DEFAULT_ALLOW_AUCTION_WO_CONSENT}).`);
  }

  $$PREBID_GLOBAL$$.requestBids.addHook(requestBidsHook, 50);
}
config.getConfig('consentManagement', config => setConfig(config.consentManagement));
<commit_msg>fix issue with GDPR module in concurrent auctions (#2612)<commit_after>/**
 * This module adds GDPR consentManagement support to prebid.js.  It interacts with
 * supported CMPs (Consent Management Platforms) to grab the user's consent information
 * and make it available for any GDPR supported adapters to read/pass this information to
 * their system.
 */
import * as utils from 'src/utils';
import { config } from 'src/config';
import { gdprDataHandler } from 'src/adaptermanager';
import includes from 'core-js/library/fn/array/includes';
import strIncludes from 'core-js/library/fn/string/includes';

const DEFAULT_CMP = 'iab';
const DEFAULT_CONSENT_TIMEOUT = 10000;
const DEFAULT_ALLOW_AUCTION_WO_CONSENT = true;

export let userCMP;
export let consentTimeout;
export let allowAuction;

let consentData;

// add new CMPs here, with their dedicated lookup function
const cmpCallMap = {
  'iab': lookupIabConsent
};

/**
 * This function handles interacting with an IAB compliant CMP to obtain the consent information of the user.
 * Given the async nature of the CMP's API, we pass in acting success/error callback functions to exit this function
 * based on the appropriate result.
 * @param {function(string)} cmpSuccess acts as a success callback when CMP returns a value; pass along consentObject (string) from CMP
 * @param {function(string)} cmpError acts as an error callback while interacting with CMP; pass along an error message (string)
 * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function)
 */
function lookupIabConsent(cmpSuccess, cmpError, hookConfig) {
  function handleCmpResponseCallbacks() {
    const cmpResponse = {};

    function afterEach() {
      if (cmpResponse.getConsentData && cmpResponse.getVendorConsents) {
        cmpSuccess(cmpResponse, hookConfig);
      }
    }

    return {
      consentDataCallback: function(consentResponse) {
        cmpResponse.getConsentData = consentResponse;
        afterEach();
      },
      vendorConsentsCallback: function(consentResponse) {
        cmpResponse.getVendorConsents = consentResponse;
        afterEach();
      }
    }
  }
  let callbackHandler = handleCmpResponseCallbacks();
  let cmpCallbacks = {};

  // to collect the consent information from the user, we perform two calls to the CMP in parallel:
  // first to collect the user's consent choices represented in an encoded string (via getConsentData)
  // second to collect the user's full unparsed consent information (via getVendorConsents)

  // the following code also determines where the CMP is located and uses the proper workflow to communicate with it:
  // check to see if CMP is found on the same window level as prebid and call it directly if so
  // check to see if prebid is in a safeframe (with CMP support)
  // else assume prebid may be inside an iframe and use the IAB CMP locator code to see if CMP's located in a higher parent window. this works in cross domain iframes
  // if the CMP is not found, the iframe function will call the cmpError exit callback to abort the rest of the CMP workflow
  if (utils.isFn(window.__cmp)) {
    window.__cmp('getConsentData', null, callbackHandler.consentDataCallback);
    window.__cmp('getVendorConsents', null, callbackHandler.vendorConsentsCallback);
  } else if (inASafeFrame() && typeof window.$sf.ext.cmp === 'function') {
    callCmpWhileInSafeFrame('getConsentData', callbackHandler.consentDataCallback);
    callCmpWhileInSafeFrame('getVendorConsents', callbackHandler.vendorConsentsCallback);
  } else {
    // find the CMP frame
    let f = window;
    let cmpFrame;
    while (!cmpFrame) {
      try {
        if (f.frames['__cmpLocator']) cmpFrame = f;
      } catch (e) {}
      if (f === window.top) break;
      f = f.parent;
    }

    callCmpWhileInIframe('getConsentData', cmpFrame, callbackHandler.consentDataCallback);
    callCmpWhileInIframe('getVendorConsents', cmpFrame, callbackHandler.vendorConsentsCallback);
  }

  function inASafeFrame() {
    return !!(window.$sf && window.$sf.ext);
  }

  function callCmpWhileInSafeFrame(commandName, callback) {
    function sfCallback(msgName, data) {
      if (msgName === 'cmpReturn') {
        let responseObj = (commandName === 'getConsentData') ? data.vendorConsentData : data.vendorConsents;
        callback(responseObj);
      }
    }

    // find sizes from adUnits object
    let adUnits = hookConfig.adUnits;
    let width = 1;
    let height = 1;
    if (Array.isArray(adUnits) && adUnits.length > 0) {
      let sizes = utils.getAdUnitSizes(adUnits[0]);
      width = sizes[0][0];
      height = sizes[0][1];
    }

    window.$sf.ext.register(width, height, sfCallback);
    window.$sf.ext.cmp(commandName);
  }

  function callCmpWhileInIframe(commandName, cmpFrame, moduleCallback) {
    /* Setup up a __cmp function to do the postMessage and stash the callback.
      This function behaves (from the caller's perspective identicially to the in-frame __cmp call */
    window.__cmp = function(cmd, arg, callback) {
      if (!cmpFrame) {
        removePostMessageListener();

        let errmsg = 'CMP not found';
        return cmpError(errmsg, hookConfig);
      }
      let callId = Math.random() + '';
      let msg = {__cmpCall: {
        command: cmd,
        parameter: arg,
        callId: callId
      }};
      cmpCallbacks[callId] = callback;
      cmpFrame.postMessage(msg, '*');
    }

    /** when we get the return message, call the stashed callback */
    window.addEventListener('message', readPostMessageResponse, false);

    // call CMP
    window.__cmp(commandName, null, cmpIframeCallback);

    function readPostMessageResponse(event) {
      let json = (typeof event.data === 'string' && strIncludes(event.data, 'cmpReturn')) ? JSON.parse(event.data) : event.data;
      if (json.__cmpReturn && json.__cmpReturn.callId) {
        let i = json.__cmpReturn;
        // TODO - clean up this logic (move listeners?); we have duplicate messages responses because 2 eventlisteners are active from the 2 cmp requests running in parallel
        if (typeof cmpCallbacks[i.callId] !== 'undefined') {
          cmpCallbacks[i.callId](i.returnValue, i.success);
          delete cmpCallbacks[i.callId];
        }
      }
    }

    function removePostMessageListener() {
      window.removeEventListener('message', readPostMessageResponse, false);
    }

    function cmpIframeCallback(consentObject) {
      removePostMessageListener();
      moduleCallback(consentObject);
    }
  }
}

/**
 * If consentManagement module is enabled (ie included in setConfig), this hook function will attempt to fetch the
 * user's encoded consent string from the supported CMP.  Once obtained, the module will store this
 * data as part of a gdprConsent object which gets transferred to adaptermanager's gdprDataHandler object.
 * This information is later added into the bidRequest object for any supported adapters to read/pass along to their system.
 * @param {object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids.
 * @param {function} fn required; The next function in the chain, used by hook.js
 */
export function requestBidsHook(reqBidsConfigObj, fn) {
  // preserves all module related variables for the current auction instance (used primiarily for concurrent auctions)
  const hookConfig = {
    context: this,
    args: arguments,
    nextFn: fn,
    adUnits: reqBidsConfigObj.adUnits || $$PREBID_GLOBAL$$.adUnits,
    bidsBackHandler: reqBidsConfigObj.bidsBackHandler,
    haveExited: false,
    timer: null
  };

  // in case we already have consent (eg during bid refresh)
  if (consentData) {
    return exitModule(null, hookConfig);
  }

  if (!includes(Object.keys(cmpCallMap), userCMP)) {
    utils.logWarn(`CMP framework (${userCMP}) is not a supported framework.  Aborting consentManagement module and resuming auction.`);
    return hookConfig.nextFn.apply(hookConfig.context, hookConfig.args);
  }

  cmpCallMap[userCMP].call(this, processCmpData, cmpFailed, hookConfig);

  // only let this code run if module is still active (ie if the callbacks used by CMPs haven't already finished)
  if (!hookConfig.haveExited) {
    if (consentTimeout === 0) {
      processCmpData(undefined, hookConfig);
    } else {
      hookConfig.timer = setTimeout(cmpTimedOut.bind(null, hookConfig), consentTimeout);
    }
  }
}

/**
 * This function checks the consent data provided by CMP to ensure it's in an expected state.
 * If it's bad, we exit the module depending on config settings.
 * If it's good, then we store the value and exits the module.
 * @param {object} consentObject required; object returned by CMP that contains user's consent choices
 * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function)
 */
function processCmpData(consentObject, hookConfig) {
  if (
    !utils.isPlainObject(consentObject) ||
    (!utils.isPlainObject(consentObject.getVendorConsents) || Object.keys(consentObject.getVendorConsents).length === 0) ||
    (!utils.isPlainObject(consentObject.getConsentData) || Object.keys(consentObject.getConsentData).length === 0)) {
    cmpFailed(`CMP returned unexpected value during lookup process; returned value was (${consentObject}).`, hookConfig);
  } else {
    clearTimeout(hookConfig.timer);
    storeConsentData(consentObject);

    exitModule(null, hookConfig);
  }
}

/**
 * General timeout callback when interacting with CMP takes too long.
 */
function cmpTimedOut(hookConfig) {
  cmpFailed('CMP workflow exceeded timeout threshold.', hookConfig);
}

/**
 * This function contains the controlled steps to perform when there's a problem with CMP.
 * @param {string} errMsg required; should be a short descriptive message for why the failure/issue happened.
 * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function)
*/
function cmpFailed(errMsg, hookConfig) {
  clearTimeout(hookConfig.timer);

  // still set the consentData to undefined when there is a problem as per config options
  if (allowAuction) {
    storeConsentData(undefined);
  }
  exitModule(errMsg, hookConfig);
}

/**
 * Stores CMP data locally in module and then invokes gdprDataHandler.setConsentData() to make information available in adaptermanger.js for later in the auction
 * @param {object} cmpConsentObject required; an object representing user's consent choices (can be undefined in certain use-cases for this function only)
 */
function storeConsentData(cmpConsentObject) {
  consentData = {
    consentString: (cmpConsentObject) ? cmpConsentObject.getConsentData.consentData : undefined,
    vendorData: (cmpConsentObject) ? cmpConsentObject.getVendorConsents : undefined,
    gdprApplies: (cmpConsentObject) ? cmpConsentObject.getConsentData.gdprApplies : undefined
  };
  gdprDataHandler.setConsentData(consentData);
}

/**
 * This function handles the exit logic for the module.
 * There are several paths in the module's logic to call this function and we only allow 1 of the 3 potential exits to happen before suppressing others.
 *
 * We prevent multiple exits to avoid conflicting messages in the console depending on certain scenarios.
 * One scenario could be auction was canceled due to timeout with CMP being reached.
 * While the timeout is the accepted exit and runs first, the CMP's callback still tries to process the user's data (which normally leads to a good exit).
 * In this case, the good exit will be suppressed since we already decided to cancel the auction.
 *
 * Three exit paths are:
 * 1. good exit where auction runs (CMP data is processed normally).
 * 2. bad exit but auction still continues (warning message is logged, CMP data is undefined and still passed along).
 * 3. bad exit with auction canceled (error message is logged).
 * @param {string} errMsg optional; only to be used when there was a 'bad' exit.  String is a descriptive message for the failure/issue encountered.
 * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function)
 */
function exitModule(errMsg, hookConfig) {
  if (hookConfig.haveExited === false) {
    hookConfig.haveExited = true;

    let context = hookConfig.context;
    let args = hookConfig.args;
    let nextFn = hookConfig.nextFn;

    if (errMsg) {
      if (allowAuction) {
        utils.logWarn(errMsg + ' Resuming auction without consent data as per consentManagement config.');
        nextFn.apply(context, args);
      } else {
        utils.logError(errMsg + ' Canceling auction as per consentManagement config.');
        if (typeof hookConfig.bidsBackHandler === 'function') {
          hookConfig.bidsBackHandler();
        } else {
          utils.logError('Error executing bidsBackHandler');
        }
      }
    } else {
      nextFn.apply(context, args);
    }
  }
}

/**
 * Simply resets the module's consentData variable back to undefined, mainly for testing purposes
 */
export function resetConsentData() {
  consentData = undefined;
  gdprDataHandler.setConsentData(null);
}

/**
 * A configuration function that initializes some module variables, as well as add a hook into the requestBids function
 * @param {object} config required; consentManagement module config settings; cmp (string), timeout (int), allowAuctionWithoutConsent (boolean)
 */
export function setConfig(config) {
  if (utils.isStr(config.cmpApi)) {
    userCMP = config.cmpApi;
  } else {
    userCMP = DEFAULT_CMP;
    utils.logInfo(`consentManagement config did not specify cmp.  Using system default setting (${DEFAULT_CMP}).`);
  }

  if (utils.isNumber(config.timeout)) {
    consentTimeout = config.timeout;
  } else {
    consentTimeout = DEFAULT_CONSENT_TIMEOUT;
    utils.logInfo(`consentManagement config did not specify timeout.  Using system default setting (${DEFAULT_CONSENT_TIMEOUT}).`);
  }

  if (typeof config.allowAuctionWithoutConsent === 'boolean') {
    allowAuction = config.allowAuctionWithoutConsent;
  } else {
    allowAuction = DEFAULT_ALLOW_AUCTION_WO_CONSENT;
    utils.logInfo(`consentManagement config did not specify allowAuctionWithoutConsent.  Using system default setting (${DEFAULT_ALLOW_AUCTION_WO_CONSENT}).`);
  }

  $$PREBID_GLOBAL$$.requestBids.addHook(requestBidsHook, 50);
}
config.getConfig('consentManagement', config => setConfig(config.consentManagement));
<|endoftext|>


<commit_before>'use strict';

var Textfield = require('./Textfield');

/**
 * @constructor
 */
var Number = Textfield.extend('Number', {

    template: '<input type="text">',

    initialize: function(grid) {
        this.localizer = grid.localization.get('number');
    }

});

module.exports = Number;
<commit_msg>removed unneeded template from Number prototype<commit_after>'use strict';

var Textfield = require('./Textfield');

/**
 * @constructor
 */
var Number = Textfield.extend('Number', {

    initialize: function(grid) {
        this.localizer = grid.localization.get('number');
    }

});

module.exports = Number;
<|endoftext|>