<commit_before>// The Thing Is
// Configuration driven validation
// with the goal of a near-english syntax (for consumers)

// Usage:
//
// var whatYouExpect = 'number'  --  string (least useful)
// var whatYouExpect = ['present', 'number', {greaterThan:0}] -- array (tightest to write, preferred?)
// var whatYouExpect = ['present', 'integer', {greaterThan:0, lessThan:256}] -- combo v2, maintains order, groups comparisons that are chaotic
// var whatYouExpect = {present:true, number:true, greaterThan:0} -- object (verbose, unreliable order)
// var whatYouExpect = [{present:true}, {number:true}, {greaterThan:0}] -- array of objects (very verbose, reliable order)
//
// if (the(thing).is(whatYouExpect)) {
//   fuckYeah()
// }
//
// if (the(thing).isnt(whatYouExpect)) {
//   throwSomething()
// }

// Dependencies
var is = require('is-it')

// the -- function you care about
function the(thing) {
  the.past.push({ thing:thing })
  the.last = the.past[the.past.length-1 || 0]
  return comparisons
}

the.past = []
the.last = null

// is, isnt
var comparisons = {
  is: function(whatYouExpect) {

    var its = true
    var expectation = null

    // the(thing).is()
    // whatYouExpect is undefined or null -- so check mere presence of a thing
    if ( is.not.present(whatYouExpect) )
      its = is.present(the.last.thing)

    // 'present' -- single boolean check
    // the(thing).is('integer') // true/false
    // the(thing).is('borkborkbork') // throw
    else
      if ( is.string(whatYouExpect) )
        its = booleanCheck(whatYouExpect)

    // ['present', 'number'] -- array of boolean
    // the(thing).is(['present', 'integer'])
    else
      if ( is.array(whatYouExpect) )
        for (var i = 0; i < whatYouExpect.length && its == true; i++) {
          expectation = whatYouExpect[i]
          if (is.string(expectation))
            its = booleanCheck(expectation)
          else
            its = subjectCheck(expectation)

          if (!its)
            the.last.error = '' + the.last.thing + ' is not ' + whatYouExpect[i];
        }

    // {greaterThan:0} -- configuration object with single condition
    // {present:true, integer:true, greaterThan:0} -- unreliable due to unreliable hash key order
    // [{present:true}, {integer:true}, {greaterThan:0}] -- reliable, but verbose
    // ['present', 'integer', {greaterThanOrEqualTo:0}] -- preferred

    return its
  },
  isnt: function(whatYouExpect) {
    return !this.is(whatYouExpect)
  }
}

// simple yes/no type comparisons against an expectation
function booleanCheck(expectation) {
  if (is[expectation])
    return is[expectation](the.last.thing)
  else
    throw new TypeError("`"+expectation+"` isn't a valid comparison method.")
}

// TODO: compare the thing against a standard
function subjectCheck(expectation) {
  console.log('')
  // console.log('the:', the)
  // console.log('the.last', the.last)
  // console.log('is.VERSION:', is.VERSION)
  // console.log('expectation:', expectation)
  // console.log('is.plainObject(expectation):', is.plainObject(expectation) )
  // console.log('Object.keys(expectation):', Object.keys(expectation))

  var soFar = null
  var standard = null

  // being cute
  var notGood = false
  var soGood = true

  // only some of the checks on `is` are subject/standard checks:
  var standardized = ['equal', 'greaterThan', 'greaterThanOrEqualTo', 'lessThan', 'lessThanOrEqualTo', 'sameDate', 'futureDate', 'pastDate']

  the.last.error = []

  // loop through the keys in the object to
  if (is.plainObject(expectation))

    Object.keys(expectation).forEach(function(key){
      standard = expectation[key]
      console.log('key:', key)
      console.log('expecation[key]', expectation[key])
      console.log('is[key](the.last.thing, expectation[key]): ', is[key](the.last.thing, expectation[key]))

      // if there's no standard, and there's a value associated with it, then assume we're enforcing a particular state
      if ( !standardized.indexOf(key) ) {
        if (is.bool(standard))
          soFar = standard ? is[key](the.last.thing) : is.not[key](the.last.thing)
        else
          throw new Error('You\'re comparing a non-standardized attribute against a standard. `' + key + '` cannot be `' + standard + '`.')
      }

      // if ( expectation[key] )

      // if ( is[attribute](the.last.thing) )
      // the.last.error.push('' + the.last.thing + ' is not ' + attribute);
    })

  // throw new Error('not implemented')

  return !!the.last.error.length
}

module.exports = the
<commit_msg>got the check against the standard working decently enough.<commit_after>// The Thing Is
// Configuration driven validation
// with the goal of a near-english syntax (for consumers)

// Usage:
//
// var whatYouExpect = 'number'  --  string (least useful)
// var whatYouExpect = ['present', 'number', {greaterThan:0}] -- array (tightest to write, preferred?)
// var whatYouExpect = ['present', 'integer', {greaterThan:0, lessThan:256}] -- combo v2, maintains order, groups comparisons that are chaotic
// var whatYouExpect = {present:true, number:true, greaterThan:0} -- object (verbose, unreliable order)
// var whatYouExpect = [{present:true}, {number:true}, {greaterThan:0}] -- array of objects (very verbose, reliable order)
//
// if (the(thing).is(whatYouExpect)) {
//   fuckYeah()
// }
//
// if (the(thing).isnt(whatYouExpect)) {
//   throwSomething()
// }

// Dependencies
var is = require('is-it')

// the -- function you care about
function the(thing) {
  the.past.push({
    thing:  thing,
    errors: []
  })
  the.last = the.past[the.past.length-1 || 0]
  return comparisons
}

the.past = []
the.last = null

// is, isnt
var comparisons = {
  is: function(whatYouExpect) {

    var its = true
    var expectation = null

    // the(thing).is()
    // whatYouExpect is undefined or null -- so check mere presence of a thing
    if ( is.not.present(whatYouExpect) )
      its = is.present(the.last.thing)

    // 'present' -- single boolean check
    // the(thing).is('integer') // true/false
    // the(thing).is('borkborkbork') // throw
    else
      if ( is.string(whatYouExpect) )
        its = booleanCheck(whatYouExpect)

    // ['present', 'number'] -- array of boolean
    // the(thing).is(['present', 'integer'])
    else
      if ( is.array(whatYouExpect) )
        for (var i = 0; i < whatYouExpect.length && its == true; i++) {
          expectation = whatYouExpect[i]
          if (is.string(expectation))
            its = booleanCheck(expectation)
          else
            its = subjectCheck(expectation)

          if (!its)
            the.last.error = '' + the.last.thing + ' is not ' + whatYouExpect[i];
        }

    // {greaterThan:0} -- configuration object with single condition
    // {present:true, integer:true, greaterThan:0} -- unreliable due to unreliable hash key order
    // [{present:true}, {integer:true}, {greaterThan:0}] -- reliable, but verbose
    // ['present', 'integer', {greaterThanOrEqualTo:0}] -- preferred

    return its
  },
  isnt: function(whatYouExpect) {
    return !this.is(whatYouExpect)
  }
}

// simple yes/no type comparisons against an expectation
function booleanCheck(expectation) {
  if (is[expectation])
    return is[expectation](the.last.thing)
  else
    throw new TypeError("`"+expectation+"` isn't a valid comparison method.")
}

function subjectCheck(expectation) {
  var soFar = null
  var standard = null

  the.last.error = []

  // loop through the keys in the object to
  Object.keys(expectation).forEach(function(key, value){
    standard = expectation[key]
    if ( is[key](the.last.thing, standard) ) {
      the.last.error.push(['See, the thing is, ', the.last.thing, ' (', typeof the.last.thing, ') isn\'t ', key, ' ', value, '.'].join(''));
    }
  })

  return !!the.last.error.length
}

module.exports = the
<|endoftext|>


<commit_before>// The Thing Is
//
// Detailed Object Descriptions
// ...with a sort of _artistic_ quality of code
//
// Usage:
//
// var whatYouExpect = 'number'  --  string (least useful)
// var whatYouExpect = ['present', 'number', {greaterThan:0}] -- array (tightest to write, preferred?)
// var whatYouExpect = ['present', 'integer', {greaterThan:0, lessThan:256}] -- combo v2, maintains order, groups comparisons that are chaotic
// var whatYouExpect = [{present:true}, {number:true}, {greaterThan:0}] -- array of objects (very verbose, reliable order, overkill)
//
// if (the(thing).is(whatYouExpect)) {
//   ohYeah()
// }
//
// if (the(thing).isnt(whatYouExpect)) {
//   throwSomething()
// }

'use strict'

// Dependencies
var is = require('is-too')

// the -- function you care about
function the (thing) {
  the.path = []
  the.last = {
    thing: thing,
    wasnt: []
  }
  return {
    is: what,
    isnt: function (expected, thing) {
      return !this.is(expected, thing)
    }
  }
}

// will recursively see if the(thing).is(whatYouExpect)
function what (expected, thing) {

  thing = thing || the.last.thing

  // the(thing).is()
  // expected is undefined or null -- so check mere presence of a thing
  if ( is.not.present(expected) )
    return see('present', thing)

  // 'present' -- single boolean check
  // the(thing).is('integer') // true/false
  // the(thing).is('borkborkbork') // throw
  if ( is.string(expected) )
    return see(expected, thing)

  // ['present', 'number'] -- array of boolean comparisons
  // ['present', 'number', {greaterThan:0}, {lessThanorEqualTo:100}] -- separated objects
  // ['present', 'number', {greaterThan:0, lessThanorEqualTo:100}] -- combined object
  // { foo: ['present', { bar: ['present'] }] }
  // the(thing).is(['present', 'integer'])
  if ( is.array(expected) )
    return expected.every(function(expected){
      return what(expected, thing)
    })

  // { foo: ['bar'] } -- dictionary describing complex or deep objects
  // the(thing).is({
  //   name: ['present', 'string'],
  //   address: {
  //     street: 'string',
  //     city: 'string',
  //     state: 'string',
  //     zip: 'string'
  //   }
  // })
  if ( is.plainObject(expected) )
    if (is.plainObject(thing)) {

      // stash the path to branch the tree
      var pathStash = the.path.slice()

      var result = Object.keys(expected).every(function(key, i){
        var nexThing = thing[key]
        var nexPectation = expected[key]

        if (i > 0)
          the.path.pop()

        the.path.push(key)

        if ( is.present(nexPectation) && is.present(nexThing) )
          return what(nexPectation, nexThing)
        else
          return see('present', nexThing)
      })

      the.path = pathStash.slice();
      return result
    }
    else
      return Object.keys(expected).every(function(key, i, arr){
        var standard = expected[key];
        return see(key, thing, standard);
      })

  return false;

}

function see (expected, thing, standard) {
  var wasnt = {}
  var err = {}

  if ( is.not.string(expected) || is.not.present(is[expected]) )
    throw new TypeError('`' + expected + '` isn\'t a valid comparison method.')

  if ( is[expected](thing, standard) )
    return true

  if ( is.present(standard) )
    err[expected] = standard
  else
    err = expected

  if (the.path.length)
    wasnt[the.path.join('.')] = err
  else
    wasnt = err

  the.last.wasnt.push(wasnt)

  return false
}

module.exports = the
<commit_msg>Improved error handling to report _all_ errors.<commit_after>// The Thing Is
//
// Detailed Object Descriptions
// ...with a sort of _artistic_ quality of code
//
// Usage:
//
// var whatYouExpect = 'number'  --  string (least useful)
// var whatYouExpect = ['present', 'number', {greaterThan:0}] -- array (tightest to write, preferred?)
// var whatYouExpect = ['present', 'integer', {greaterThan:0, lessThan:256}] -- combo v2, maintains order, groups comparisons that are chaotic
// var whatYouExpect = [{present:true}, {number:true}, {greaterThan:0}] -- array of objects (very verbose, reliable order, overkill)
//
// if (the(thing).is(whatYouExpect)) {
//   ohYeah()
// }
//
// if (the(thing).isnt(whatYouExpect)) {
//   throwSomething()
// }

'use strict'

// Dependencies
var is = require('is-too')

// the -- function you care about
function the (thing) {
  the.path = []
  the.last = {
    thing: thing,
    error: []
  }
  return {
    is: what,
    isnt: function (expected, thing) {
      return !this.is(expected, thing)
    }
  }
}

// will recursively see if the(thing).is(whatYouExpect)
function what (expected, thing) {

  thing = thing || the.last.thing

  // the(thing).is()
  // expected is undefined or null -- so check mere presence of a thing
  if ( is.not.present(expected) )
    return see('present', thing)

  // 'present' -- single boolean check
  // the(thing).is('integer') // true/false
  // the(thing).is('borkborkbork') // throw
  if ( is.string(expected) )
    return see(expected, thing)

  // ['present', 'number'] -- array of boolean comparisons
  // ['present', 'number', {greaterThan:0}, {lessThanorEqualTo:100}] -- separated objects
  // ['present', 'number', {greaterThan:0, lessThanorEqualTo:100}] -- combined object
  // { foo: ['present', { bar: ['present'] }] }
  // the(thing).is(['present', 'integer'])
  if ( is.array(expected) )
    expected.forEach(function(expected){
      return what(expected, thing)
    })

  // { foo: ['bar'] } -- dictionary describing complex or deep objects
  // the(thing).is({
  //   name: ['present', 'string'],
  //   address: {
  //     street: 'string',
  //     city: 'string',
  //     state: 'string',
  //     zip: 'string'
  //   }
  // })
  if ( is.plainObject(expected) )
    if (is.plainObject(thing)) {

      // stash the path to branch the tree
      var pathStash = the.path.slice()

      Object.keys(expected).forEach(function(key, i){
        var nexThing = thing[key],
            nexPectation = expected[key]

        if (i > 0)
          the.path.pop()

        the.path.push(key)

        if ( is.present(nexPectation) && is.present(nexThing) )
          return what(nexPectation, nexThing)
        else
          return see('present', nexThing)
      })

      the.path = pathStash.slice();

    }
    else
      Object.keys(expected).forEach(function(key, i, arr){
        var standard = expected[key];
        return see(key, thing, standard);
      })

  return !the.last.error.length;

}

function see (expected, thing, standard) {

  var err = {},
      fail = {},
      failPath = the.path.join('.')

  if ( is.not.string(expected) || is.not.present(is[expected]) )
    throw new TypeError('`' + expected + '` isn\'t a valid comparison method.')

  // good to go, so go
  if ( is[expected](thing, standard) )
    return true

  // needs to be stored as an object
  if ( is.present(standard) )
    fail[expected] = standard // eg. {greaterThan:0}
  else
    fail = expected // eg. 'present'

  // needs to be stored as the value of the path
  if (the.path.length)
    err[failPath] = [fail] // eg. {'foo.bar': ['present']}
  else
    err = fail // eg. 'present'

  // need to group the fails for a key in the same array
  var isExisting = the.last.error.some(function something (last) {
    if (is.plainObject(last) && failPath in last) {
      last[failPath].push(fail)
      return true
    }
  })

  if (!isExisting)
    the.last.error.push(err)

  return false
}

module.exports = the
<|endoftext|>


<commit_before>
ToolbarEvent = {};
ToolbarEvent.api = new StumbleUponApi(config);

ToolbarEvent.handleRequest = function(request, sender, sendResponse) {
	console.log("ToolbarEvent.handleRequest", request);
	if (!ToolbarEvent[request.action])
		return false;
	ToolbarEvent[request.action](request, sender)
		.then(function(response) {
			console.log("ToolbarEvent.sendResponse", request, response);
			sendResponse(response);
			if (response.all) {
//				chrome.runtime.sendMessage(chrome.runtime.id, response);
				chrome.tabs.query({}, function(tabs) {
					tabs.forEach(function (tab) {
						chrome.tabs.sendMessage(tab.id, response);
					});
				});
			}
		});
	return true;
}

ToolbarEvent.sanity = function() {
	return ToolbarEvent.api.cache.get('user')
		.then(function(user) {
			if (!user.userid)
				return ToolbarEvent.ping();
			return user;
		})
}

ToolbarEvent.discover = function(request, sender) {
	return Page.getUrl(sender.tab.id)
	.then(function(url) {
		return ToolbarEvent.api.discover(url);
	})
	.then(function(url) {
		Page.note(sender.tab.id, url);
		return url;
	});
}

ToolbarEvent.mode = function(request, sender) {
	ToolbarEvent.api.cache.mset({ mode: config.mode = request.data.value || config.defaults.mode });
	ToolbarEvent.stumble(request, sender);
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.theme = function(request, sender) {
	ToolbarEvent.api.cache.mset({ theme: config.theme = request.data.value || config.defaults.theme });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.toggleHidden = function(request, sender) {
	ToolbarEvent.api.cache.mset({ hidden: config.hidden = !config.hidden });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.unhide = function(request, sender) {
	ToolbarEvent.api.cache.mset({ hidden: config.hidden = false });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.hide = function(request, sender) {
	ToolbarEvent.api.cache.mset({ hidden: config.hidden = true });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.repos = function(request, sender) {
	ToolbarEvent.api.cache.mset({ rpos: config.rpos = request.data.rpos });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent._buildResponse = function(change, all) {
	debug('ToolbarEvent._buildResponse', change);
	return Promise.resolve(Object.assign({all: all}, { config: config }, change));
}

ToolbarEvent.dislike = function(request, sender) {
	if ((request.url && request.url.userRating && request.url.userRating.type) == -1)
		return ToolbarEvent.unrate(request, sender);

	ToolbarEvent
		.sanity()
		.then(function() { return Page.getUrlId(sender.tab.id) })
		.then(function(urlid) {
			if (!urlid) {
				debug("Attempt to dislike url that doesn't exist", request);
				return Promise.resolve(request);
			}
			return ToolbarEvent.api.dislike(urlid)
				.then(function(response) {
					return Page.note(sender.tab.id, response.url);
				});
		})
		.catch(ToolbarEvent.error);

	request.url.userRating = { type: -1, subtype: 0 };
	return Promise.resolve(request);
}

ToolbarEvent.info = function(request, sender) {
	if (Page.getUrlId(sender.tab.id))
		chrome.tabs.create({ url: 'http://' + config.baseUrl + config.url.info.form({ urlid: Page.getUrlId(sender.tab.id) }) });
	Promise.resolve(request);
}

ToolbarEvent.unrate = function(request, sender) {
	ToolbarEvent
		.sanity()
		.then(function() { return Page.getUrlId(sender.tab.id) })
		.then(function(urlid) {
			if (!urlid) {
				debug("Attempt to unrate url that doesn't exist", request);
				return Promise.resolve(request);
			}
			return ToolbarEvent.api.unrate(urlid)
				.then(function(response) {
					return Page.note(sender.tab.id, response.url);
				});
		})
		.catch(ToolbarEvent.error);

	request.url.userRating = { type: 0, subtype: 0 };
	return Promise.resolve(request);
}

ToolbarEvent.like = function(request, sender) {
	if ((request.url && request.url.userRating && request.url.userRating.type) == 1)
		return ToolbarEvent.unrate(request, sender);

	ToolbarEvent
		.sanity()
		.then(function() { return Page.getUrlId(sender.tab.id) })
		.then(function(urlid) {
			return urlid || ToolbarEvent.discover(request, sender)
				.then(function(url) { return url.urlid; });
		})
		.then(function(urlid) {
			return ToolbarEvent.api.like(urlid)
				.then(function(response) {
					return Page.note(sender.tab.id, response.url);
				});
		})
		.catch(ToolbarEvent.error);

	request.url.userRating = { type: 1, subtype: 0 };
	return Promise.resolve(request);
}

ToolbarEvent.stumble = function(request, sender) {
	return ToolbarEvent.api
		._mode(config.mode || config.defaults.mode)
		.nextUrl()
		.then(function(url) {
			ToolbarEvent.api
				.nextUrl(true)
				.then(ToolbarEvent.preload);
			Page.note(sender.tab.id, url);
			ToolbarEvent.api.reportStumble([url.urlid]);
			request.url = url;
			console.log(url);
			chrome.tabs.update(sender.tab.id, { url: url.url });
			// Don't send URL now, wait for init call
			return ToolbarEvent._buildResponse({});
		})
		.catch(ToolbarEvent.error);
}

ToolbarEvent.error = function(e) {
	console.log(e)
	//ToolbarEvent.loginPage();
}

ToolbarEvent.loginPage = function() {
	ToolbarEvent.api._flush();
	chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
		chrome.tabs.update(tabs[0].id, {
			"url": 'https://' + config.baseUrl + '/login'
		});
	});
}
ToolbarEvent.needsLogin = function() {
	debug('Needs login', arguments);
}
ToolbarEvent.ping = function() {
	return ToolbarEvent.api
		.ping()
		.then(ToolbarEvent.api.getUser.bind(ToolbarEvent.api))
		.then(function(user) {
			debug('Login success for user', user.username);
			ToolbarEvent.api.nextUrl(true)
				.then(ToolbarEvent.preload)
				.catch(function(e) {warning('Expected to preload next url', e);});
		})
		.catch(ToolbarEvent.needsLogin);
}

ToolbarEvent.preload = function(url) {
	ToolbarEvent._prerender.href  = url.url;
	ToolbarEvent._prefetch.href   = url.url;
	ToolbarEvent._preload.href    = url.url;
	debug("Preload", url.url);
}

ToolbarEvent.getUrlFromPageCache = function(url) {
	console.log('GUFPC', Page.urlCache[url]);
	return ToolbarEvent._buildResponse({url: Page.urlCache[url]});
}

ToolbarEvent.urlChange = function(request, sender) {
	return new Promise(function(resolve, reject) {
		chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
			var url = (request && request.url && request.url.url) || (tabs[0] && tabs[0].url);
			console.log(url);
			if (url) {
				Page.urlChange(url, tabs[0].id)
					.then(function(url) {
						resolve(ToolbarEvent._buildResponse({url: url}));
					});
			} else {
				reject();
			}
		});
	});
	return p;
	return ToolbarEvent._buildResponse({});
	//return ToolbarEvent._buildResponse({url: Page.urlCache[request && request.url && request.url.url]});
	return Promise.resolve(request);
}

ToolbarEvent.init = function(request, sender) {
	request.config = config;
	return ToolbarEvent._buildResponse({ url: Page.lastUrl(sender.tab.id) });
	return Promise.resolve(request);
}

ToolbarEvent._init = function() {
	ToolbarEvent.api.cache.mget(config.persist)
		 .then(function (map) {
			 Object.assign(config, map);
		 });

	ToolbarEvent.ping();

	ToolbarEvent._prerender  = document.createElement('link');
	ToolbarEvent._prefetch   = document.createElement('link');
	ToolbarEvent._preload    = document.createElement('link');

	ToolbarEvent._prerender.rel  = 'prerender';
	ToolbarEvent._prefetch.rel   = 'prefetch';
	ToolbarEvent._preload.rel    = 'preload';

	document.body.appendChild(ToolbarEvent._prerender);
	document.body.appendChild(ToolbarEvent._prefetch);
	document.body.appendChild(ToolbarEvent._preload);

	chrome.runtime.onMessage.addListener(ToolbarEvent.handleRequest);
}

ToolbarEvent._init();
ToolbarEvent.api._flush();

<commit_msg>Peek expects an int<commit_after>
ToolbarEvent = {};
ToolbarEvent.api = new StumbleUponApi(config);

ToolbarEvent.handleRequest = function(request, sender, sendResponse) {
	console.log("ToolbarEvent.handleRequest", request);
	if (!ToolbarEvent[request.action])
		return false;
	ToolbarEvent[request.action](request, sender)
		.then(function(response) {
			console.log("ToolbarEvent.sendResponse", request, response);
			sendResponse(response);
			if (response.all) {
//				chrome.runtime.sendMessage(chrome.runtime.id, response);
				chrome.tabs.query({}, function(tabs) {
					tabs.forEach(function (tab) {
						chrome.tabs.sendMessage(tab.id, response);
					});
				});
			}
		});
	return true;
}

ToolbarEvent.sanity = function() {
	return ToolbarEvent.api.cache.get('user')
		.then(function(user) {
			if (!user.userid)
				return ToolbarEvent.ping();
			return user;
		})
}

ToolbarEvent.discover = function(request, sender) {
	return Page.getUrl(sender.tab.id)
	.then(function(url) {
		return ToolbarEvent.api.discover(url);
	})
	.then(function(url) {
		Page.note(sender.tab.id, url);
		return url;
	});
}

ToolbarEvent.mode = function(request, sender) {
	ToolbarEvent.api.cache.mset({ mode: config.mode = request.data.value || config.defaults.mode });
	ToolbarEvent.stumble(request, sender);
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.theme = function(request, sender) {
	ToolbarEvent.api.cache.mset({ theme: config.theme = request.data.value || config.defaults.theme });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.toggleHidden = function(request, sender) {
	ToolbarEvent.api.cache.mset({ hidden: config.hidden = !config.hidden });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.unhide = function(request, sender) {
	ToolbarEvent.api.cache.mset({ hidden: config.hidden = false });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.hide = function(request, sender) {
	ToolbarEvent.api.cache.mset({ hidden: config.hidden = true });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent.repos = function(request, sender) {
	ToolbarEvent.api.cache.mset({ rpos: config.rpos = request.data.rpos });
	return ToolbarEvent._buildResponse({}, true);
}

ToolbarEvent._buildResponse = function(change, all) {
	debug('ToolbarEvent._buildResponse', change);
	return Promise.resolve(Object.assign({all: all}, { config: config }, change));
}

ToolbarEvent.dislike = function(request, sender) {
	if ((request.url && request.url.userRating && request.url.userRating.type) == -1)
		return ToolbarEvent.unrate(request, sender);

	ToolbarEvent
		.sanity()
		.then(function() { return Page.getUrlId(sender.tab.id) })
		.then(function(urlid) {
			if (!urlid) {
				debug("Attempt to dislike url that doesn't exist", request);
				return Promise.resolve(request);
			}
			return ToolbarEvent.api.dislike(urlid)
				.then(function(response) {
					return Page.note(sender.tab.id, response.url);
				});
		})
		.catch(ToolbarEvent.error);

	request.url.userRating = { type: -1, subtype: 0 };
	return Promise.resolve(request);
}

ToolbarEvent.info = function(request, sender) {
	if (Page.getUrlId(sender.tab.id))
		chrome.tabs.create({ url: 'http://' + config.baseUrl + config.url.info.form({ urlid: Page.getUrlId(sender.tab.id) }) });
	Promise.resolve(request);
}

ToolbarEvent.unrate = function(request, sender) {
	ToolbarEvent
		.sanity()
		.then(function() { return Page.getUrlId(sender.tab.id) })
		.then(function(urlid) {
			if (!urlid) {
				debug("Attempt to unrate url that doesn't exist", request);
				return Promise.resolve(request);
			}
			return ToolbarEvent.api.unrate(urlid)
				.then(function(response) {
					return Page.note(sender.tab.id, response.url);
				});
		})
		.catch(ToolbarEvent.error);

	request.url.userRating = { type: 0, subtype: 0 };
	return Promise.resolve(request);
}

ToolbarEvent.like = function(request, sender) {
	if ((request.url && request.url.userRating && request.url.userRating.type) == 1)
		return ToolbarEvent.unrate(request, sender);

	ToolbarEvent
		.sanity()
		.then(function() { return Page.getUrlId(sender.tab.id) })
		.then(function(urlid) {
			return urlid || ToolbarEvent.discover(request, sender)
				.then(function(url) { return url.urlid; });
		})
		.then(function(urlid) {
			return ToolbarEvent.api.like(urlid)
				.then(function(response) {
					return Page.note(sender.tab.id, response.url);
				});
		})
		.catch(ToolbarEvent.error);

	request.url.userRating = { type: 1, subtype: 0 };
	return Promise.resolve(request);
}

ToolbarEvent.stumble = function(request, sender) {
	return ToolbarEvent.api
		._mode(config.mode || config.defaults.mode)
		.nextUrl()
		.then(function(url) {
			ToolbarEvent.api
				.nextUrl(1)
				.then(ToolbarEvent.preload);
			Page.note(sender.tab.id, url);
			ToolbarEvent.api.reportStumble([url.urlid]);
			request.url = url;
			console.log(url);
			chrome.tabs.update(sender.tab.id, { url: url.url });
			// Don't send URL now, wait for init call
			return ToolbarEvent._buildResponse({});
		})
		.catch(ToolbarEvent.error);
}

ToolbarEvent.error = function(e) {
	console.log(e)
	//ToolbarEvent.loginPage();
}

ToolbarEvent.loginPage = function() {
	ToolbarEvent.api._flush();
	chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
		chrome.tabs.update(tabs[0].id, {
			"url": 'https://' + config.baseUrl + '/login'
		});
	});
}
ToolbarEvent.needsLogin = function() {
	debug('Needs login', arguments);
}
ToolbarEvent.ping = function() {
	return ToolbarEvent.api
		.ping()
		.then(ToolbarEvent.api.getUser.bind(ToolbarEvent.api))
		.then(function(user) {
			debug('Login success for user', user.username);
			ToolbarEvent.api.nextUrl(1)
				.then(ToolbarEvent.preload)
				.catch(function(e) {warning('Expected to preload next url', e);});
		})
		.catch(ToolbarEvent.needsLogin);
}

ToolbarEvent.preload = function(url) {
	ToolbarEvent._prerender.href  = url.url;
	ToolbarEvent._prefetch.href   = url.url;
	ToolbarEvent._preload.href    = url.url;
	debug("Preload", url.url);
}

ToolbarEvent.getUrlFromPageCache = function(url) {
	console.log('GUFPC', Page.urlCache[url]);
	return ToolbarEvent._buildResponse({url: Page.urlCache[url]});
}

ToolbarEvent.urlChange = function(request, sender) {
	return new Promise(function(resolve, reject) {
		chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
			var url = (request && request.url && request.url.url) || (tabs[0] && tabs[0].url);
			console.log(url);
			if (url) {
				Page.urlChange(url, tabs[0].id)
					.then(function(url) {
						resolve(ToolbarEvent._buildResponse({url: url}));
					});
			} else {
				reject();
			}
		});
	});
	return p;
	return ToolbarEvent._buildResponse({});
	//return ToolbarEvent._buildResponse({url: Page.urlCache[request && request.url && request.url.url]});
	return Promise.resolve(request);
}

ToolbarEvent.init = function(request, sender) {
	request.config = config;
	return ToolbarEvent._buildResponse({ url: Page.lastUrl(sender.tab.id) });
	return Promise.resolve(request);
}

ToolbarEvent._init = function() {
	ToolbarEvent.api.cache.mget(config.persist)
		 .then(function (map) {
			 Object.assign(config, map);
		 });

	ToolbarEvent.ping();

	ToolbarEvent._prerender  = document.createElement('link');
	ToolbarEvent._prefetch   = document.createElement('link');
	ToolbarEvent._preload    = document.createElement('link');

	ToolbarEvent._prerender.rel  = 'prerender';
	ToolbarEvent._prefetch.rel   = 'prefetch';
	ToolbarEvent._preload.rel    = 'preload';

	document.body.appendChild(ToolbarEvent._prerender);
	document.body.appendChild(ToolbarEvent._prefetch);
	document.body.appendChild(ToolbarEvent._preload);

	chrome.runtime.onMessage.addListener(ToolbarEvent.handleRequest);
}

ToolbarEvent._init();
ToolbarEvent.api._flush();

<|endoftext|>


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

  $.widget("custom.contentsNav", {

    options: {
      rootPath: null
    },

    _create : function() {
      $(document).on('click', '.page-nav .page-nav-item .open-folder', $.proxy(this._onOpenFolderClick, this));
      this._resolvePaths(document);
    },

    _resolvePaths: function (container) {
      $(container).find('.page-nav-link').each($.proxy(function (index, link) {
        $(link).attr('href', this.options.rootPath + '/' + this._resolvePath(link));
      }, this));
    },

    _loadItems: function (path, pageId, callback) {
      $.ajax('/ajax/pagenav?pageId=' + pageId, {
        success: $.proxy(function (html) {
          callback(null, html);
        }, this),
        error: $.proxy(function (jqXHR, textStatus) {
          callback(textStatus);
        }, this)
      });
    },

    _resolvePath: function (link) {
      var slugs = [];

      $(link).parents('.page-nav-item').each(function (index, item) {
        slugs.unshift($(item).find('[data-slug]').attr('data-slug'));
      });

      return slugs.join('/');
    },

    _onOpenFolderClick: function (event) {
      event.preventDefault();
      var openLink = $(event.target);
      var item = openLink.closest('.page-nav-item');
      if (item.hasClass('open')) {
        item.addClass('closed').removeClass('open');
        return;
      }

      if (item.hasClass('closed')) {
        item.addClass('open').removeClass('closed');
        return;
      }

      item.addClass('loading');

      var path = openLink.attr('data-path');
      var pageId = openLink.attr('data-page-id');
      this._loadItems(path, pageId, $.proxy(function (err, html) {
        if (err) {
          console.error(err);
        } else {
          item.addClass('open')
            .removeClass('loading')
            .find('.child-pages')
            .html(html);
          this._resolvePaths(item);
        }
      }, this));
    }

  });

  $.widget("custom.casemHistoryTopic", {

    _create : function() {
      this.element.on('click', '> h3', $.proxy(this._onHeaderClick, this));
      this.element.find('.casem-history-topic-contents').hide();
      this.element.find('> h3').text('Näytä aikaisempi käsittely');
    },

    _onHeaderClick: function (event) {
      event.preventDefault();
      this.element.toggleClass('open');
      this.element.find('.casem-history-topic-contents').slideToggle();
    }

  });

  $.widget("custom.contactSearch", {

    _create : function() {
      this._page = 0;
      this._lastSearch = null;
      this.element.append($("<label>").text(this.element.attr("data-placeholder")).attr("for", this.element.attr("data-placeholder")));
      this.element.append($("<input>").addClass('contact-search form-control m-t-1').attr('placeholder', this.element.attr('data-placeholder')).attr("id", this.element.attr("data-placeholder")).attr("title", this.element.attr("data-placeholder")));
      this.element.append($("<div>").addClass('contact-search-results'));
      this.element.on('click', '.pages-container a.page-prev', $.proxy(this._onPagePrevClick, this));
      this.element.on('click', '.pages-container a.page-next', $.proxy(this._onPageNextClick, this));
      this.element.on("keyup", 'input.contact-search', $.proxy(this._onInputKeyUp, this));
      this._search();
    },

    _getSearch: function () {
      return $.trim(this.element.find('input.contact-search').val());
    },

    _search: function () {
      var search = this._getSearch();

      this._lastSearch = search;
      if (!this._searching) {
        this._searching = true;
        this.element.addClass('searching');
        this.element.find('.contact-search-results').empty();

        $.ajax({
          url : '/ajax/contactSearch/?page=' + this._page,
          data : {
            search: search
          },
          success : $.proxy(function(data) {
            this._searching = false;
            this.element
              .find('.contact-search-results')
              .html(data)
              .show();

            if (search !== this._getSearch()) {
              this._search();
            } else {
              this.element.removeClass('searching');
            }
          }, this)
        });
      }
    },

    _onInputKeyUp: function (event) {
      if (this._lastSearch !== this._getSearch()) {
        this._page = 0;
        this._search();
      }
    },

    _onPagePrevClick: function (event) {
      event.preventDefault();
      this._page = $(event.target).attr('data-page');
      this._search();
    },

    _onPageNextClick: function (event) {
      event.preventDefault();
      this._page = $(event.target).attr('data-page');
      this._search();
    }

  });

  $(document).ready(function () {
    $(document.body).contentsNav({
      rootPath: $('.rootPath').val()
    });

    $('.casem-history-topic').casemHistoryTopic();
    $('.kunta-api-contact-search').contactSearch();

    $("img.lazy").lazyload();

    $("button.open-info").click(function(event){
      event.preventDefault();
      var openLink = $(event.currentTarget);
      var item = openLink.children("span.arrow-icon");
      var content = openLink.siblings("div.accessibility-info-content");
      if (item.hasClass("open")) {
        item.addClass("closed").removeClass("open");
        content.addClass("hidden");
        return;
      }

      if (item.hasClass("closed")) {
        item.addClass("open").removeClass("closed");
        content.removeClass("hidden");
        return;
      }
    });

  });

}).call(this);<commit_msg>hound issue<commit_after>/* global $ */

(function () {
  'use strict';

  $.widget("custom.contentsNav", {

    options: {
      rootPath: null
    },

    _create : function() {
      $(document).on('click', '.page-nav .page-nav-item .open-folder', $.proxy(this._onOpenFolderClick, this));
      this._resolvePaths(document);
    },

    _resolvePaths: function (container) {
      $(container).find('.page-nav-link').each($.proxy(function (index, link) {
        $(link).attr('href', this.options.rootPath + '/' + this._resolvePath(link));
      }, this));
    },

    _loadItems: function (path, pageId, callback) {
      $.ajax('/ajax/pagenav?pageId=' + pageId, {
        success: $.proxy(function (html) {
          callback(null, html);
        }, this),
        error: $.proxy(function (jqXHR, textStatus) {
          callback(textStatus);
        }, this)
      });
    },

    _resolvePath: function (link) {
      var slugs = [];

      $(link).parents('.page-nav-item').each(function (index, item) {
        slugs.unshift($(item).find('[data-slug]').attr('data-slug'));
      });

      return slugs.join('/');
    },

    _onOpenFolderClick: function (event) {
      event.preventDefault();
      var openLink = $(event.target);
      var item = openLink.closest('.page-nav-item');
      if (item.hasClass('open')) {
        item.addClass('closed').removeClass('open');
        return;
      }

      if (item.hasClass('closed')) {
        item.addClass('open').removeClass('closed');
        return;
      }

      item.addClass('loading');

      var path = openLink.attr('data-path');
      var pageId = openLink.attr('data-page-id');
      this._loadItems(path, pageId, $.proxy(function (err, html) {
        if (err) {
          console.error(err);
        } else {
          item.addClass('open')
            .removeClass('loading')
            .find('.child-pages')
            .html(html);
          this._resolvePaths(item);
        }
      }, this));
    }

  });

  $.widget("custom.casemHistoryTopic", {

    _create : function() {
      this.element.on('click', '> h3', $.proxy(this._onHeaderClick, this));
      this.element.find('.casem-history-topic-contents').hide();
      this.element.find('> h3').text('Näytä aikaisempi käsittely');
    },

    _onHeaderClick: function (event) {
      event.preventDefault();
      this.element.toggleClass('open');
      this.element.find('.casem-history-topic-contents').slideToggle();
    }

  });

  $.widget("custom.contactSearch", {

    _create : function() {
      this._page = 0;
      this._lastSearch = null;
      this.element.append($("<label>").text(this.element.attr("data-placeholder")).attr("for", this.element.attr("data-placeholder")));
      this.element.append($("<input>").addClass('contact-search form-control m-t-1').attr('placeholder', this.element.attr('data-placeholder')).attr("id", this.element.attr("data-placeholder")).attr("title", this.element.attr("data-placeholder")));
      this.element.append($("<div>").addClass('contact-search-results'));
      this.element.on('click', '.pages-container a.page-prev', $.proxy(this._onPagePrevClick, this));
      this.element.on('click', '.pages-container a.page-next', $.proxy(this._onPageNextClick, this));
      this.element.on("keyup", 'input.contact-search', $.proxy(this._onInputKeyUp, this));
      this._search();
    },

    _getSearch: function () {
      return $.trim(this.element.find('input.contact-search').val());
    },

    _search: function () {
      var search = this._getSearch();

      this._lastSearch = search;
      if (!this._searching) {
        this._searching = true;
        this.element.addClass('searching');
        this.element.find('.contact-search-results').empty();

        $.ajax({
          url : '/ajax/contactSearch/?page=' + this._page,
          data : {
            search: search
          },
          success : $.proxy(function(data) {
            this._searching = false;
            this.element
              .find('.contact-search-results')
              .html(data)
              .show();

            if (search !== this._getSearch()) {
              this._search();
            } else {
              this.element.removeClass('searching');
            }
          }, this)
        });
      }
    },

    _onInputKeyUp: function (event) {
      if (this._lastSearch !== this._getSearch()) {
        this._page = 0;
        this._search();
      }
    },

    _onPagePrevClick: function (event) {
      event.preventDefault();
      this._page = $(event.target).attr('data-page');
      this._search();
    },

    _onPageNextClick: function (event) {
      event.preventDefault();
      this._page = $(event.target).attr('data-page');
      this._search();
    }

  });

  $(document).ready(function () {
    $(document.body).contentsNav({
      rootPath: $('.rootPath').val()
    });

    $('.casem-history-topic').casemHistoryTopic();
    $('.kunta-api-contact-search').contactSearch();

    $("img.lazy").lazyload();

    $("button.open-info").click(function(event){
      event.preventDefault();
      var openLink = $(event.currentTarget);
      var item = openLink.children("span.arrow-icon");
      var content = openLink.siblings("div.accessibility-info-content");
      if (item.hasClass("open")) {
        item.addClass("closed").removeClass("open");
        content.addClass("hidden");
        return;
      }

      if (item.hasClass("closed")) {
        item.addClass("open").removeClass("closed");
        content.removeClass("hidden");
        return;
      }
    });

  });

}).call(this);<|endoftext|>


<commit_before>/*

  Keyboard and mouse enabled horizontal screen
  scrolling plugin, with automatic realignment.

  Written in 2013 by Suraj N. Kurapati for
  Readably https://github.com/sunaku/readably
  and thus distributed under the ISC license.

  Requires: jQuery 1.2.6 or newer
  http://docs.jquery.com/Release:jQuery_1.2.6

  Optional: jquery-mousewheel 3.1.3 or newer
  https://github.com/brandonaaron/jquery-mousewheel

*/
$(function() {
  var $window   = $(window),
      $document = $(document),
      $screen   = $('html,body'),
      wheeling  = false;

  // Computes the width of a page (amount of content that fits on a screen).
  function boundary() {
    var display = $window.width(),
        content = $screen.width();
    //
    // midpoint of content width and midpoint of content and display widths:
    //
    // __________________
    // |xxxxxx          | <= content width
    // |xxxxxxxxxxxxxxxx| <= display width
    // |          A     | <= midpoint of content and display widths
    // |       B        | <= midpoint of content and above midpoint
    // |________________|
    //
    return Math.round((((display + content) / 2) + content) / 2);
  }

  // Scrolls the screen horizontally to the given location, which can be
  // an absolute pixel offset (number) or one of the following (string):
  //
  // 'left':  if not aligned, scroll to start of current page;
  //          otherwise, scroll to start of previous page
  //
  // 'right': scroll to start of next page
  //
  // 'align': if beyond half of current page, scroll to start of next page;
  //          otherwise, scroll to start of current page
  //
  // In either case, the screen will be left-aligned to a page boundary.
  //
  function horizoll(where, options) {
    if (

      // browser could not fit document vertically into window so don't
      // interfere with user's ability to scroll the document normally
      $document.height() > $window.height() ||

      // browser was able to fit document horizontally into window, so
      // scrolling is unnecessary: there's nothing here to be scrolled!
      $document.width() < $window.width()

    ) {
      return; // skip processing for the corner cases described above
    }

    var start = typeof where === 'number' ? where : $document.scrollLeft(),
        limit = boundary(),
        depth = start % limit,
        space = limit - depth;

    switch (where) {
      case 'left' : where = start - (depth > 0 ? depth : limit); break;
      case 'right': where = start + (depth > 0 ? space : limit); break;
      case 'align': if (depth >= space) { where = start + space; break; }
                    // else fall through
      default     : where = start - depth;
    }

    $screen.animate({ scrollLeft: where }, options);
  }

  // Aligns the screen to the nearest page boundary
  // while ensuring that any hash target is visible.
  function realign() {
    var target = $(':target');
    if (target.length) {
      horizoll(target.offset().left);
    }
    else {
      horizoll('align');
    }
  }

  // Tests whether the given event qualifies as a cause for scrolling.
  function qualify(event) {
    return !(
      // event originated from a form input field, so don't interfere:
      // the user is probably trying to enter text or scroll the field
      event.target.hasOwnProperty('form') ||

      // modifier was pressed along with keystroke, so don't interfere
      event.altKey || event.ctrlKey || event.metaKey || (
        // shift modifier was pressed along with a non-space-bar key
        event.shiftKey && (event.keyCode !== 32) // space bar
      )
    );
  }

  // traverse page boundaries using the keyboard
  $document.bind('keyup', function(event) {
    if (qualify(event)) {
      switch (event.keyCode) {
        case 33: // page up
        case 37: // left arrow
        case 38: // up arrow
          horizoll('left');
          break;

        case 34: // page down
        case 39: // right arrow
        case 40: // down arrow
          horizoll('right');
          break;

        case 32: // space bar
          horizoll(event.shiftKey ? 'left' : 'right');
          break;

        case 36: // home key
          horizoll(0);
          break;

        case 35: // end key
          horizoll($document.width());
          break;
      }
    }
  });

  // traverse page boundaries using the mouse wheel
  $document.bind('mousewheel', function(event, delta, deltaX, deltaY) {
    if (!wheeling && delta !== 0 && deltaX === 0 && qualify(event)) {
      wheeling = true;
      horizoll(deltaY > 0 ? 'left' : 'right', {
        complete: function() {
          wheeling = false;
        }
      });
    }
  });

  // automatically realign to nearest page boundary
  $window.bind('resize', realign);
  setTimeout(realign, 500);

});
<commit_msg>horizoll: reduce SLOC for corner case handling<commit_after>/*

  Keyboard and mouse enabled horizontal screen
  scrolling plugin, with automatic realignment.

  Written in 2013 by Suraj N. Kurapati for
  Readably https://github.com/sunaku/readably
  and thus distributed under the ISC license.

  Requires: jQuery 1.2.6 or newer
  http://docs.jquery.com/Release:jQuery_1.2.6

  Optional: jquery-mousewheel 3.1.3 or newer
  https://github.com/brandonaaron/jquery-mousewheel

*/
$(function() {
  var $window   = $(window),
      $document = $(document),
      $screen   = $('html,body'),
      wheeling  = false;

  // Computes the width of a page (amount of content that fits on a screen).
  function boundary() {
    var display = $window.width(),
        content = $screen.width();
    //
    // midpoint of content width and midpoint of content and display widths:
    //
    // __________________
    // |xxxxxx          | <= content width
    // |xxxxxxxxxxxxxxxx| <= display width
    // |          A     | <= midpoint of content and display widths
    // |       B        | <= midpoint of content and above midpoint
    // |________________|
    //
    return Math.round((((display + content) / 2) + content) / 2);
  }

  // Scrolls the screen horizontally to the given location, which can be
  // an absolute pixel offset (number) or one of the following (string):
  //
  // 'left':  if not aligned, scroll to start of current page;
  //          otherwise, scroll to start of previous page
  //
  // 'right': scroll to start of next page
  //
  // 'align': if beyond half of current page, scroll to start of next page;
  //          otherwise, scroll to start of current page
  //
  // In either case, the screen will be left-aligned to a page boundary.
  //
  function horizoll(where, options) {
    // browser could not fit document vertically into window so don't
    // interfere with user's ability to scroll the document normally
    if ($document.height() > $window.height()) return;

    // browser was able to fit document horizontally into window, so
    // scrolling is unnecessary: there's nothing here to be scrolled!
    if ($document.width() < $window.width()) return;

    var start = typeof where === 'number' ? where : $document.scrollLeft(),
        limit = boundary(),
        depth = start % limit,
        space = limit - depth;

    switch (where) {
      case 'left' : where = start - (depth > 0 ? depth : limit); break;
      case 'right': where = start + (depth > 0 ? space : limit); break;
      case 'align': if (depth >= space) { where = start + space; break; }
                    // else fall through
      default     : where = start - depth;
    }

    $screen.animate({ scrollLeft: where }, options);
  }

  // Aligns the screen to the nearest page boundary
  // while ensuring that any hash target is visible.
  function realign() {
    var target = $(':target');
    if (target.length) {
      horizoll(target.offset().left);
    }
    else {
      horizoll('align');
    }
  }

  // Tests whether the given event qualifies as a cause for scrolling.
  function qualify(event) {
    return !(
      // event originated from a form input field, so don't interfere:
      // the user is probably trying to enter text or scroll the field
      event.target.hasOwnProperty('form') ||

      // modifier was pressed along with keystroke, so don't interfere
      event.altKey || event.ctrlKey || event.metaKey || (
        // shift modifier was pressed along with a non-space-bar key
        event.shiftKey && (event.keyCode !== 32) // space bar
      )
    );
  }

  // traverse page boundaries using the keyboard
  $document.bind('keyup', function(event) {
    if (qualify(event)) {
      switch (event.keyCode) {
        case 33: // page up
        case 37: // left arrow
        case 38: // up arrow
          horizoll('left');
          break;

        case 34: // page down
        case 39: // right arrow
        case 40: // down arrow
          horizoll('right');
          break;

        case 32: // space bar
          horizoll(event.shiftKey ? 'left' : 'right');
          break;

        case 36: // home key
          horizoll(0);
          break;

        case 35: // end key
          horizoll($document.width());
          break;
      }
    }
  });

  // traverse page boundaries using the mouse wheel
  $document.bind('mousewheel', function(event, delta, deltaX, deltaY) {
    if (!wheeling && delta !== 0 && deltaX === 0 && qualify(event)) {
      wheeling = true;
      horizoll(deltaY > 0 ? 'left' : 'right', {
        complete: function() {
          wheeling = false;
        }
      });
    }
  });

  // automatically realign to nearest page boundary
  $window.bind('resize', realign);
  setTimeout(realign, 500);

});
<|endoftext|>


<commit_before>( function ( $, play){
	function Playlist(){
		this.config = null;
	};

	var PP = Playlist.prototype;

	var MP = play.main;

	PP.setup = function(){
		var This = this;
		return $.getJSON('/config.json').done(
        function(data){
          This.config = data;
          This.initialize();
        });
	};

	PP.initialize = function(){
		this.addClickHandlers();
	}

	PP.getPlaylists = function(){
		var This = this;
		$.getJSON(This.config.muzi_root + 'playlist/list').done( function(data){
			var html ='
';
			for(i in data){
				html += '

'+ data[i].name + '
';
			}
			html += '
';
			$(".data").html(html);
		});
	}

	PP.getSpecificPlaylist = function(id){
		var This = this;
		$.get(This.config.muzi_root + 'playlist/info/' + id).done(function(data){
			var html = '

'+data.name + '

by ' + data.username + '

' + '
';
			for(i in data.tracks){
				html += '

<div class="track-details"';
                html += data.tracks[i].title;
                html += '';
                html += data.tracks[i].artist;
                html += '

';
			}
			html += '
';
			$('.data').html(html);
		})
	}

	PP.addClickHandlers = function(){
		var This = this;
		$(".playlist-anchor").click(function(){
			This.getPlaylists();
		});
		$(".data").delegate("#playlists li", 'click', function(){
			This.getSpecificPlaylist($(this).attr('data-id'));
		});
		$('.data').delegate('.playlist_tracks li','click',function(e){
	      var trackId=this.getAttribute('mid');
	      datavalue = "";

	      $.getJSON(This.config.muzi_root+"track/info/" + trackId,function(data){
	        var url=data.file.split('/').map(function(x){return encodeURIComponent(x);}).join('/');
	        $.post('/play',{url:This.config.music_root+url,id:data.id},function(){
	          $.post(This.config.muzi_root+'track/log',{id:data.id});
	        }).fail( MP.to403 );
	      })
	      var liHandle = $(this);

	      $.get("/now", function(result){
	        if(result)
	        {
	          datavalue = "Added song to queue";
	          MP.showTooltip(liHandle, datavalue, "left");
	        }
	        else
	        {
	          datavalue = "Playing it right now";
	          MP.showTooltip(liHandle, datavalue, "left");
	        }
	      });

	      MP.removeTooltip($(this),"");
	    });

	}
	play.playlist = new Playlist();
	play.playlist.setup();

}(window.jQuery, window.Play));
<commit_msg>Fixed the playlist fetch json error<commit_after>( function ( $, play){
	function Playlist(){
		this.config = null;
	};

	var PP = Playlist.prototype;

	var MP = play.main;

	PP.setup = function(){
		var This = this;
		return $.getJSON('/config.json').done(
        function(data){
          This.config = data;
          This.initialize();
        });
	};

	PP.initialize = function(){
		this.addClickHandlers();
	}

	PP.getPlaylists = function(){
		var This = this;
		$.getJSON(This.config.muzi_root + 'playlist/list').done( function(data){
			var html ='
';
			for(i in data){
				html += '

'+ data[i].name + '
';
			}
			html += '
';
			$(".data").html(html);
		});
	}

	PP.getSpecificPlaylist = function(id){
		var This = this;
		$.getJSON(This.config.muzi_root + 'playlist/info/' + id).done(function(data){
			var html = '

'+data.name + '

by ' + data.username + '

' + '
';
			for(i in data.tracks){
				html += '

<div class="track-details"';
                html += data.tracks[i].title;
                html += '';
                html += data.tracks[i].artist;
                html += '

';
			}
			html += '
';
			$('.data').html(html);
		})
	}

	PP.addClickHandlers = function(){
		var This = this;
		$(".playlist-anchor").click(function(){
			This.getPlaylists();
		});
		$(".data").delegate("#playlists li", 'click', function(){
			This.getSpecificPlaylist($(this).attr('data-id'));
		});
		$('.data').delegate('.playlist_tracks li','click',function(e){
	      var trackId=this.getAttribute('mid');
	      datavalue = "";

	      $.getJSON(This.config.muzi_root+"track/info/" + trackId,function(data){
	        var url=data.file.split('/').map(function(x){return encodeURIComponent(x);}).join('/');
	        $.post('/play',{url:This.config.music_root+url,id:data.id},function(){
	          $.post(This.config.muzi_root+'track/log',{id:data.id});
	        }).fail( MP.to403 );
	      })
	      var liHandle = $(this);

	      $.get("/now", function(result){
	        if(result)
	        {
	          datavalue = "Added song to queue";
	          MP.showTooltip(liHandle, datavalue, "left");
	        }
	        else
	        {
	          datavalue = "Playing it right now";
	          MP.showTooltip(liHandle, datavalue, "left");
	        }
	      });

	      MP.removeTooltip($(this),"");
	    });

	}
	play.playlist = new Playlist();
	play.playlist.setup();

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


<commit_before>/* globals assert, qq, before, beforeEach, afterEach */
var $fixture;

(function() {
    "use strict";

    qq.override(assert, function(super_) {
        var expected = -1,
            hit = 0,
            done;

        function checkIfDone() {
            if (expected >= 0) {
                if (hit === expected) {
                    done();
                }
                else if (hit > expected) {
                    assert.ok(false, "Too many assertions!");
                }
            }
        }

        return {
            expect: function(assertsExpected, doneCallback) {
                expected = assertsExpected;
                done = doneCallback;
            },

            reset: function() {
                expected = -1;
                hit = 0;
            },

            ok: function() {
                hit++;
                super_.ok.apply(this, arguments);
                checkIfDone();
            },

            equal: function() {
                hit++;
                super_.equal.apply(this, arguments);
                checkIfDone();
            },

            deepEqual: function() {
                hit++;
                super_.deepEqual.apply(this, arguments);
                checkIfDone();
            }
        };
    });

    before(function() {
        // "Turn off" the before unload handler since this may cause the tests to stall when run in a browser
        qq.FineUploaderBasic.prototype._preventLeaveInProgress = function() {};
        qq.s3.FineUploaderBasic.prototype._preventLeaveInProgress = function() {};
        qq.azure.FineUploaderBasic.prototype._preventLeaveInProgress = function() {};
    });

    beforeEach(function() {
        assert.reset();
        $fixture = $("

");
        $fixture.appendTo("body");
        return $fixture;
    });

    afterEach(function () {
        $fixture.empty();
        return $fixture.remove();
    });

    // `Error.captureStackTrace` may not be supported on all UAs.  Assert.js expects it to be.
    Error.captureStackTrace = Error.captureStackTrace || function() {};
}());
<commit_msg>test(karma-runner.js): Don't count assert method hit if it throws an exception<commit_after>/* globals assert, qq, before, beforeEach, afterEach */
var $fixture;

(function() {
    "use strict";

    qq.override(assert, function(super_) {
        var expected = -1,
            hit = 0,
            done;

        function checkIfDone() {
            if (expected >= 0) {
                if (hit === expected) {
                    done();
                }
                else if (hit > expected) {
                    assert.ok(false, "Too many assertions!");
                }
            }
        }

        return {
            expect: function(assertsExpected, doneCallback) {
                expected = assertsExpected;
                done = doneCallback;
            },

            reset: function() {
                expected = -1;
                hit = 0;
            },

            ok: function() {
                super_.ok.apply(this, arguments);
                hit++;
                checkIfDone();
            },

            equal: function() {
                super_.equal.apply(this, arguments);
                hit++;
                checkIfDone();
            },

            deepEqual: function() {
                super_.deepEqual.apply(this, arguments);
                hit++;
                checkIfDone();
            }
        };
    });

    before(function() {
        // "Turn off" the before unload handler since this may cause the tests to stall when run in a browser
        qq.FineUploaderBasic.prototype._preventLeaveInProgress = function() {};
        qq.s3.FineUploaderBasic.prototype._preventLeaveInProgress = function() {};
        qq.azure.FineUploaderBasic.prototype._preventLeaveInProgress = function() {};
    });

    beforeEach(function() {
        assert.reset();
        $fixture = $("

");
        $fixture.appendTo("body");
        return $fixture;
    });

    afterEach(function () {
        $fixture.empty();
        return $fixture.remove();
    });

    // `Error.captureStackTrace` may not be supported on all UAs.  Assert.js expects it to be.
    Error.captureStackTrace = Error.captureStackTrace || function() {};
}());
<|endoftext|>


<commit_before>jQuery.fn.versionSelector = function(versions, sizes) {
    $(this).each(function() {
        new jQuery.versionSelector(this, versions, sizes);
    })
}

jQuery.versionSelector = function(element, versions, sizes) {
    var _this = this,
        guid = 0;

    this.init = function() {
        this.selects = [];
        this.inputs = [];
        this.unknownSize = false;

        this.gemVersions = [];
        for (var i=0, l = versions.length; i < l; i++) {
            switch (versions[i].name.toLowerCase()) {
                case 'ruby':
                    this.rubyVersions = versions[i];
                    break;
                case 'rails':
                    this.railsVersions = versions[i];
                    break;
                default:
                    this.gemVersions.push(versions[i]);
            }
        };
    }

    this.bindEvents = function() {
        $('.preset', element).click(this.presetClick);
        $('#download, #browse').click(this.downloadClick);
    }

    this.downloadClick = function() {
        if (_this.unknownSize) $('.build-message').show()
    }

    this.presetClick = function() {
        if ($(this).hasClass('preset_ruby')) {
            _this.setHrefs([
                [_this.railsVersions.href, _this.railsVersions.versions[0]],
                [_this.rubyVersions.href, _this.rubyVersions.versions[0]]
            ]);
            _this.close();
        } else if ($(this).hasClass('preset_rails')) {
            _this.setHrefs([
                [_this.railsVersions.href, _this.railsVersions.versions[0]]
            ]);
            _this.close();
        } else {
            _this.open();
        }

        $('.preset_selected', element).removeClass('preset_selected');
        $(this).addClass('preset_selected');
    }

    this.close = function() {
        if (this.$form) {
            this.$form.slideUp('slow');
        }
    }

    this.open = function() {
        if (!this.$form) {
            this.render();
        }
        this.$form.slideDown('slow');
        this.rebuildHrefs();
    }

    this.render = function() {
        if (this.$form) return;
        var div = document.createElement('div'),
            item,
            col1 = document.createElement('div'),
            col2 = document.createElement('div'),
            h3 = document.createElement('h3'),
            clear = document.createElement('div');
        div.className = 'packages';
        div.style.display = 'none';
        col1.className = 'column';
        col2.className = 'column';
        clear.className = 'clear';
        h3.innerHTML = 'Gems';

        item = this.renderItem(this.selects, this.inputs, this.railsVersions, true);
        div.appendChild(item);
        item = this.renderItem(this.selects, this.inputs, this.rubyVersions, true)
        div.appendChild(item);
        div.appendChild(h3);
        div.appendChild(col1);
        div.appendChild(col2);
        div.appendChild(clear);

        for (var i=0, l = this.gemVersions.length; i < l; i++) {
            item = this.renderItem(this.selects, this.inputs, this.gemVersions[i]);
            var target = i < l / 2 ? col1 : col2;
            target.appendChild(item);
        };
        this.element.appendChild(div);
        this.$form = $(div);
        this.bindRendered();
    }

    this.bindRendered = function() {
        $(this.selects).each(function() {
            $(this).change(function() {_this.rebuildHrefs()});
        })
        $(this.inputs).each(function() {
            $(this).click(function() {_this.rebuildHrefs()});
        })
    }

    this.renderItem = function(selects, inputs, version, checked) {
        var p = document.createElement('p'),
            id = guid++, select, input, option, versions = version.versions;
        p.innerHTML =
            '<input type="checkbox" id="item_' + id + '" />'
            + '' + version.name + ' ';
        if (versions.length > 1) {
            p.innerHTML += '<select id="item_select_' + id + '"></select>';
            select = p.getElementsByTagName('select')[0];
            for (var i=0, l = versions.length; i < l; i++) {
                option = document.createElement('option');
                option.value = versions[i];
                option.innerHTML = versions[i];
                select.appendChild(option);
            };
        } else {
            p.innerHTML += '<input type="hidden" value="' + versions[0] + '"> ' + versions[0];
            select = p.getElementsByTagName('input')[1];
        }
        $(select).data('href', version.href);
        input = p.getElementsByTagName('input')[0];
        if (checked) input.checked = input.defaultChecked = true;
        inputs.push(input);
        selects.push(select);
        return p;
    }

    this.rebuildHrefs = function() {
        var items = [], select;
        for (var i=0, l = this.inputs.length; i < l; i++) {
            if(this.inputs[i].checked) {
                select = this.selects[i];
                items.push([$(select).data('href'), select.value]);
            }
        };
        this.setHrefs(items);
    }

    this.setHrefs = function(items) {
        var parts = [], item, path;
        for (var i=0, l = items.length; i < l; i++) {
            item = items[i]
            parts[parts.length] = item[0].replace(/[_-]/g, '') + '-' + item[1].replace(/[_-]/g, '');
        };
        path = parts.join('_');
        if (parts.length) {
            $('#download').attr('href', '/doc/' + path + '/rdoc.zip');
            $('#browse').attr('href', '/doc/' + path + '/');
            this.unknownSize = !this.sizes[path];
        } else {
            $('#download').attr('href', '#');
            $('#browse').attr('href', '#');
            this.unknownSize = false;
        }
        $('#size').html('Zip, ' + (this.sizes[path] || 'unknown size'));
    }

    this.element = element;
    this.sizes = sizes;
    this.init();
    this.bindEvents();

    if (location.hash.indexOf('custom') != -1) {
        $('.preset:eq(2)', element).click();
    }
}
<commit_msg>Path building<commit_after>jQuery.fn.versionSelector = function(versions, sizes) {
    $(this).each(function() {
        new jQuery.versionSelector(this, versions, sizes);
    })
}

jQuery.versionSelector = function(element, versions, sizes) {
    var _this = this,
        guid = 0;

    this.init = function() {
        this.selects = [];
        this.inputs = [];
        this.unknownSize = false;

        this.gemVersions = [];
        for (var i=0, l = versions.length; i < l; i++) {
            switch (versions[i].name.toLowerCase()) {
                case 'ruby':
                    this.rubyVersions = versions[i];
                    break;
                case 'rails':
                    this.railsVersions = versions[i];
                    break;
                default:
                    this.gemVersions.push(versions[i]);
            }
        };
    }

    this.bindEvents = function() {
        $('.preset', element).click(this.presetClick);
        $('#download, #browse').click(this.downloadClick);
    }

    this.downloadClick = function() {
        if (_this.unknownSize) $('.build-message').show()
    }

    this.presetClick = function() {
        if ($(this).hasClass('preset_ruby')) {
            _this.setHrefs([
                [_this.railsVersions.href, _this.railsVersions.versions[0]],
                [_this.rubyVersions.href, _this.rubyVersions.versions[0]]
            ]);
            _this.close();
        } else if ($(this).hasClass('preset_rails')) {
            _this.setHrefs([
                [_this.railsVersions.href, _this.railsVersions.versions[0]]
            ]);
            _this.close();
        } else {
            _this.open();
        }

        $('.preset_selected', element).removeClass('preset_selected');
        $(this).addClass('preset_selected');
    }

    this.close = function() {
        if (this.$form) {
            this.$form.slideUp('slow');
        }
    }

    this.open = function() {
        if (!this.$form) {
            this.render();
        }
        this.$form.slideDown('slow');
        this.rebuildHrefs();
    }

    this.render = function() {
        if (this.$form) return;
        var div = document.createElement('div'),
            item,
            col1 = document.createElement('div'),
            col2 = document.createElement('div'),
            h3 = document.createElement('h3'),
            clear = document.createElement('div');
        div.className = 'packages';
        div.style.display = 'none';
        col1.className = 'column';
        col2.className = 'column';
        clear.className = 'clear';
        h3.innerHTML = 'Gems';

        item = this.renderItem(this.selects, this.inputs, this.railsVersions, true);
        div.appendChild(item);
        item = this.renderItem(this.selects, this.inputs, this.rubyVersions, true)
        div.appendChild(item);
        div.appendChild(h3);
        div.appendChild(col1);
        div.appendChild(col2);
        div.appendChild(clear);

        for (var i=0, l = this.gemVersions.length; i < l; i++) {
            item = this.renderItem(this.selects, this.inputs, this.gemVersions[i]);
            var target = i < l / 2 ? col1 : col2;
            target.appendChild(item);
        };
        this.element.appendChild(div);
        this.$form = $(div);
        this.bindRendered();
    }

    this.bindRendered = function() {
        $(this.selects).each(function() {
            $(this).change(function() {_this.rebuildHrefs()});
        })
        $(this.inputs).each(function() {
            $(this).click(function() {_this.rebuildHrefs()});
        })
    }

    this.renderItem = function(selects, inputs, version, checked) {
        var p = document.createElement('p'),
            id = guid++, select, input, option, versions = version.versions;
        p.innerHTML =
            '<input type="checkbox" id="item_' + id + '" />'
            + '' + version.name + ' ';
        if (versions.length > 1) {
            p.innerHTML += '<select id="item_select_' + id + '"></select>';
            select = p.getElementsByTagName('select')[0];
            for (var i=0, l = versions.length; i < l; i++) {
                option = document.createElement('option');
                option.value = versions[i];
                option.innerHTML = versions[i];
                select.appendChild(option);
            };
        } else {
            p.innerHTML += '<input type="hidden" value="' + versions[0] + '"> ' + versions[0];
            select = p.getElementsByTagName('input')[1];
        }
        $(select).data('href', version.href);
        input = p.getElementsByTagName('input')[0];
        if (checked) input.checked = input.defaultChecked = true;
        inputs.push(input);
        selects.push(select);
        return p;
    }

    this.rebuildHrefs = function() {
        var items = [], select;
        for (var i=0, l = this.inputs.length; i < l; i++) {
            if(this.inputs[i].checked) {
                select = this.selects[i];
                items.push([$(select).data('href'), select.value]);
            }
        };
        this.setHrefs(items);
    }

    this.setHrefs = function(items) {
        var parts = [], item, path;
        for (var i=0, l = items.length; i < l; i++) {
            item = items[i]
            parts[parts.length] = item[0].replace(/[_-]/g, '') + '-' + item[1].replace(/[_-]/g, '');
        };
        path = parts.sort().join('_');
        if (parts.length) {
            $('#download').attr('href', '/doc/' + path + '/rdoc.zip');
            $('#browse').attr('href', '/doc/' + path + '/');
            this.unknownSize = !this.sizes[path];
        } else {
            $('#download').attr('href', '#');
            $('#browse').attr('href', '#');
            this.unknownSize = false;
        }
        $('#size').html('Zip, ' + (this.sizes[path] || 'unknown size'));
    }

    this.element = element;
    this.sizes = sizes;
    this.init();
    this.bindEvents();

    if (location.hash.indexOf('custom') != -1) {
        $('.preset:eq(2)', element).click();
    }
}
<|endoftext|>


<commit_before>const { resolve } = require('path')

// Determine which version of Angular we're running the tests for. (--ng 1.6)
// If none is specified, default to running tests for Angular 1.6.
const args = process.argv.slice(2)
const index = args.indexOf('--ng')
const ngVersion = index > -1 ? args[index + 1] : '1.x'
const ngConfig = require(`./karma.config.angular-${ngVersion}.js`)

// Config
module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['mocha'],
    files: ngConfig.files,
    exclude: [],

    preprocessors: {
      '../src/index.js': ['webpack', 'sourcemap'],
      '../test/**/index.js': ['webpack', 'sourcemap']
    },

    webpack: {
      mode: 'production',
      target: 'node',
      externals: {
        angular: 'angular'
      },
      module: {
        rules: [{
          test: /\.js$/,
          include: resolve('src'),
          exclude: /node_modules/,
          enforce: 'post',
          loader: 'istanbul-instrumenter-loader',
          options: {
            esModules: true
          }
        }]
      },
      devtool: 'inline-source-map'
    },
    webpackMiddleware: {
      stats: 'minimal'
    },

    reporters: ['progress', 'coverage'],

    coverageReporter: ngConfig.coverageReporter,

    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['ChromeHeadless'],
    singleRun: true,
    concurrency: Infinity
  })
}
<commit_msg>Fix sandboxing issue in Travis<commit_after>const { resolve } = require('path')

// Determine which version of Angular we're running the tests for. (--ng 1.6)
// If none is specified, default to running tests for Angular 1.6.
const args = process.argv.slice(2)
const index = args.indexOf('--ng')
const ngVersion = index > -1 ? args[index + 1] : '1.x'
const ngConfig = require(`./karma.config.angular-${ngVersion}.js`)

// Config
module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['mocha'],
    files: ngConfig.files,
    exclude: [],

    preprocessors: {
      '../src/index.js': ['webpack', 'sourcemap'],
      '../test/**/index.js': ['webpack', 'sourcemap']
    },

    webpack: {
      mode: 'production',
      target: 'node',
      externals: {
        angular: 'angular'
      },
      module: {
        rules: [{
          test: /\.js$/,
          include: resolve('src'),
          exclude: /node_modules/,
          enforce: 'post',
          loader: 'istanbul-instrumenter-loader',
          options: {
            esModules: true
          }
        }]
      },
      devtool: 'inline-source-map'
    },
    webpackMiddleware: {
      stats: 'minimal'
    },

    reporters: ['progress', 'coverage'],

    coverageReporter: ngConfig.coverageReporter,

    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    singleRun: true,
    browsers: ['ChromeHeadlessNoSandbox'],
    customLaunchers: {
      ChromeHeadlessNoSandbox: {
        base: 'ChromeHeadless',
        flags: ['--no-sandbox']
      }
    },
    concurrency: Infinity
  })
}
<|endoftext|>


<commit_before>'use strict';

/* Services */

// Demonstrate how to register services
// In this case it is a simple value service.
app.
  value('version', '0.1').
  factory('socket', function () {
    var socket = io.connect();
    return socket;
  });
<commit_msg>removed 'version' service provided with the seed<commit_after>'use strict';

/* Services */

// Demonstrate how to register services
// In this case it is a simple value service.
app.factory('socket', function () {
  var socket = io.connect();
  return socket;
});
<|endoftext|>


<commit_before>function makeData() {
  "use strict";
  return d3.csv("../../examples/data/hygxyzTruncated.csv");
}

function run(div, data, Plottable) {
  "use strict";
  d3.csv("../../examples/data/hygxyzTruncated.csv", function(d) {
  var svg = div.append("svg").attr("height", 500);
  var xScale = new Plottable.Scale.Linear();
  var yScale = new Plottable.Scale.Linear();
  var rScale = new Plottable.Scale.Linear();

  var xAxis = new Plottable.Axis.Numeric(xScale, "bottom");
  var yAxis = new Plottable.Axis.Numeric(yScale, "left");
  var scatterRenderer = new Plottable.Plot.Scatter(d, xScale, yScale)
    .project("x", "X", xScale)
    .project("y", function(d) {return Math.abs(d.Y)}, yScale)
    .project("r", function(d) {return Math.abs(d.Mag)});

  var titleLabel = new Plottable.Component.TitleLabel("Absolute Value of Visual Magnitudes of Stars");
  var subtitleLabel = new Plottable.Component.Label("Data from The HYG Database at The Astronomy Nexus");
  var titleTable = new Plottable.Component.Table([
                                                  [titleLabel],
                                                  [subtitleLabel]
                                                  ]).xAlign("center");

  var yAxisLabel = new Plottable.Component.AxisLabel("Absolute Value of Y Coordinate of the Star", "vertical-left");
  var xAxisLabel = new Plottable.Component.AxisLabel("X Coordinate of the Star");
  var plotTable = new Plottable.Component.Table([
                                                 [yAxisLabel, yAxis, scatterRenderer],
                                                 [null, null, xAxis],
                                                 [null, null, xAxisLabel]
                                                 ]);

  new Plottable.Component.Table([
                                 [titleTable],
                                 [plotTable]
                                 ]).renderTo(svg);
  });
}<commit_msg>Use modifiedLog scale, changed paramters<commit_after>function makeData() {
  "use strict";
  return d3.csv("../../examples/data/hygxyzTruncated.csv");
}

function run(div, data, Plottable) {
  "use strict";
  d3.csv("../../examples/data/hygxyzTruncated.csv", function(d) {
  var svg = div.append("svg").attr("height", 500);
  var xScale = new Plottable.Scale.Linear();
  var yScale = new Plottable.Scale.ModifiedLog();
  var rScale = new Plottable.Scale.Linear();

  var xAxis = new Plottable.Axis.Numeric(xScale, "bottom");
  var yAxis = new Plottable.Axis.Numeric(yScale, "left");
  var scatterRenderer = new Plottable.Plot.Scatter(d, xScale, yScale)
    .project("x", "Distance", xScale)
    .project("y", function(d) {return Math.abs(d.Mag)}, yScale)
    .project("r", function(d) {return Math.abs(d.AbsMag)});

  var titleLabel = new Plottable.Component.TitleLabel("Absolute Value of Absolute Visual Magnitudes of Stars");
  var subtitleLabel = new Plottable.Component.Label("Data from The HYG Database at The Astronomy Nexus");
  var titleTable = new Plottable.Component.Table([
                                                  [titleLabel],
                                                  [subtitleLabel]
                                                  ]).xAlign("center");

  var yAxisLabel = new Plottable.Component.AxisLabel("Absolute Value of Apparent Visual Magnitude", "vertical-left");
  var xAxisLabel = new Plottable.Component.AxisLabel("Distance in parsecs");
  var plotTable = new Plottable.Component.Table([
                                                 [yAxisLabel, yAxis, scatterRenderer],
                                                 [null, null, xAxis],
                                                 [null, null, xAxisLabel]
                                                 ]);

  new Plottable.Component.Table([
                                 [titleTable],
                                 [plotTable]
                                 ]).renderTo(svg);
  });
}<|endoftext|>


<commit_before>/**
 * Settings configuration for jsSART
 */

var jsSART = {

  // Conditions
  // --------------------------------
  'CONDITIONS': {
    // Total number of trials a participant will see during experiment
    'NUM_TRIALS': [484, 560, 646, 731, 810],
    // Number of trials before being shown real-time post-block questions
    'TRIALS_PER_BLOCK': [225, 82],
    // Practice blocks conditions
    'PRACTICE': ['num_trials', 'time_duration']
  },

  // Stimuli
  // --------------------------------
  'STIMULI': {
    // Possible stimuli values
    'VALUES': _.range(1, 10),  // 1--9
    // No-go value
    'NO_GO_VALUE': 3,
    // Font sizes
    // NOTE: approx. 48px, 72px, 94px, 100px and 120px
    'FONT_SIZES': ["12mm", "17.4mm", "22.717mm", "24.17mm", "29mm"],
    // Second level quasi-random counter range
    'QUASI_RANDOM_RANGE': _.range(4),  // 0-3
    // Allow keys 1--9 and numpad 1--9
    'ALLOW_KEYCODES': [32, 13],
    // Pace of PASAT trial presentation
    // NOTE: first number for stimlus (in milliseconds), second for fixation
    'DISPLAY_TIMINGS': [250, 900]
  },

  // Practice block stimuli
  // --------------------------------
  'PRACTICE': {
    // Duration of time to show trial feedback for block 1
    'FEEDBACK_DELAY_MS': 350,
    // Maximum proportion of trials a participant can get wrong in block 2
    'MAX_ERROR_RATE': 0.10,
    // Maximum number of times a participant can attempt block 2
    // (before skipping experiment)
    'MAX_ATTEMPTS': 3
  },

  // Evaluation questions
  // --------------------------------
  'QUESTIONS': {
    // Baseline and post-experiment evaluation of valence and arousal
    'AROUSAL': [
      {
        question: "Right now, I am feeling:",
        likert_scale: 'EMOTIONS'
      },
      {
        question: "Right now, my mind and body are:",
        likert_scale: "ENERGY"
      },
    ],
    // Real-time evaluation during the experiment (between blocks)
    'REAL_TIME': [
      {
        question: "How much mental effort is this task currently requiring?",
        likert_scale: 'NONE_ALOT'
      },
      {
        question: "How much discomfort or distress is this task currently causing?",
        likert_scale: "NONE_ALOT"
      },
    ],
    // Self-report anticipated effort, discomfort, etc
    'ANTICIPATION': [
      {
        question: "In light of your experience so far, how much do you anticipate enjoying this task?",
         likert_scale: "NONE_ALOT"
      },
      {
        question: "In light of your experience so far, how well do you anticipate performing during this task?",
        likert_scale: "BELOW_ABOVE_AVG"
      },
      {
        question: "In light of your experience so far, how much mental effort do you expect will be required to complete this task?",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "In light of your experience so far, how much discomfort or distress do you expect to experience during this task?",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "In light of your experience so far, how much mental fatigue do you expect to have while completing this task?",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "In light of your experience so far, how motivated are you to perform to the best of your ability on this task?",
        likert_scale: "NOT_EXTREMELY"
      },
    ],
    // Post-experiment retrospective evaluation
    'RETROSPECTIVE': [
      {
        question: "Considering the sustained attention task in its entirety: What was the total amount of mental effort it required?",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "Considering the sustained attention task in its entirety: What was the total amount of discomfort or distress it caused? ",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "How well did you perform on the sustained attention task?",
        likert_scale: "BELOW_ABOVE_AVG"
      },
      {
        question: "How willing would you be to do another sustained attention task right now?",
        likert_scale: "WILLINGNESS"
      },
      {
        question: "How satisfied are you with your performance on the sustained attention task?",
        likert_scale: "SATISFACTION"
      },
      {
        question: "Considering the sustained attention task in its entirety: I feel that I tried as hard as I could have to do my best.",
        likert_scale: "TRUTH"
      },
    ]
  },

  // Re-useable Likert scale labels
  // --------------------------------
  'LIKERT': {
    'NONE_ALOT': ["1
None", "2", "3", "4", "5", "6", "7
A Lot"],
    'BELOW_ABOVE_AVG': [
      "1
Significantly
Below Average", "2", "3", "4
Average",
      "5", "6", "7
Significantly
Above Average"
    ],
    'EMOTIONS': [
      "1
Very Negative/
Unpleasant
Emotions", "2", "3", "4",
      "5", "6", "7
Very Positive/
Pleasant
Emotions"
    ],
    'ENERGY': [
      "1
Deactivated
and Have Very
Little Energy", "2", "3", "4",
      "5", "6", "7
Activated and
Have a Great
Deal of Energy"
    ],
    'NOT_EXTREMELY': [
      "1
Not
at all", "2", "3", "4", "5", "6", "7
Extremely"
    ],
    'SATISFACTION': [
      "1
Not at all
satisfied", "2", "3", "4", "5", "6",
      "7
Completely
satisfied"
    ],
    'WILLINGNESS': [
      "1
Not at all
willing", "2", "3", "4", "5", "6",
      "7
Definitely
willing"
    ],
    'TRUTH': [
      "1
Not at all
true", "2", "3", "4", "5", "6",
      "7
Very true"
    ],
  }
};
<commit_msg>Add mental fatigue to retrospective questions<commit_after>/**
 * Settings configuration for jsSART
 */

var jsSART = {

  // Conditions
  // --------------------------------
  'CONDITIONS': {
    // Total number of trials a participant will see during experiment
    'NUM_TRIALS': [484, 560, 646, 731, 810],
    // Number of trials before being shown real-time post-block questions
    'TRIALS_PER_BLOCK': [225, 82],
    // Practice blocks conditions
    'PRACTICE': ['num_trials', 'time_duration']
  },

  // Stimuli
  // --------------------------------
  'STIMULI': {
    // Possible stimuli values
    'VALUES': _.range(1, 10),  // 1--9
    // No-go value
    'NO_GO_VALUE': 3,
    // Font sizes
    // NOTE: approx. 48px, 72px, 94px, 100px and 120px
    'FONT_SIZES': ["12mm", "17.4mm", "22.717mm", "24.17mm", "29mm"],
    // Second level quasi-random counter range
    'QUASI_RANDOM_RANGE': _.range(4),  // 0-3
    // Allow keys 1--9 and numpad 1--9
    'ALLOW_KEYCODES': [32, 13],
    // Pace of PASAT trial presentation
    // NOTE: first number for stimlus (in milliseconds), second for fixation
    'DISPLAY_TIMINGS': [250, 900]
  },

  // Practice block stimuli
  // --------------------------------
  'PRACTICE': {
    // Duration of time to show trial feedback for block 1
    'FEEDBACK_DELAY_MS': 350,
    // Maximum proportion of trials a participant can get wrong in block 2
    'MAX_ERROR_RATE': 0.10,
    // Maximum number of times a participant can attempt block 2
    // (before skipping experiment)
    'MAX_ATTEMPTS': 3
  },

  // Evaluation questions
  // --------------------------------
  'QUESTIONS': {
    // Baseline and post-experiment evaluation of valence and arousal
    'AROUSAL': [
      {
        question: "Right now, I am feeling:",
        likert_scale: 'EMOTIONS'
      },
      {
        question: "Right now, my mind and body are:",
        likert_scale: "ENERGY"
      },
    ],
    // Real-time evaluation during the experiment (between blocks)
    'REAL_TIME': [
      {
        question: "How much mental effort is this task currently requiring?",
        likert_scale: 'NONE_ALOT'
      },
      {
        question: "How much discomfort or distress is this task currently causing?",
        likert_scale: "NONE_ALOT"
      },
    ],
    // Self-report anticipated effort, discomfort, etc
    'ANTICIPATION': [
      {
        question: "In light of your experience so far, how much do you anticipate enjoying this task?",
         likert_scale: "NONE_ALOT"
      },
      {
        question: "In light of your experience so far, how well do you anticipate performing during this task?",
        likert_scale: "BELOW_ABOVE_AVG"
      },
      {
        question: "In light of your experience so far, how much mental effort do you expect will be required to complete this task?",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "In light of your experience so far, how much discomfort or distress do you expect to experience during this task?",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "In light of your experience so far, how much mental fatigue do you expect to have while completing this task?",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "In light of your experience so far, how motivated are you to perform to the best of your ability on this task?",
        likert_scale: "NOT_EXTREMELY"
      },
    ],
    // Post-experiment retrospective evaluation
    'RETROSPECTIVE': [
      {
        question: "Considering the sustained attention task in its entirety: What was the total amount of mental effort it required?",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "Considering the sustained attention task in its entirety: What was the total amount of discomfort or distress it caused? ",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "How well did you perform on the sustained attention task?",
        likert_scale: "BELOW_ABOVE_AVG"
      },
      {
        question: "How willing would you be to do another sustained attention task right now?",
        likert_scale: "WILLINGNESS"
      },
      {
        question: "Considering the sustained attention task in its entirety: How much mental fatigue did you experience?",
        likert_scale: "NONE_ALOT"
      },
      {
        question: "How satisfied are you with your performance on the sustained attention task?",
        likert_scale: "SATISFACTION"
      },
      {
        question: "Considering the sustained attention task in its entirety: I feel that I tried as hard as I could have to do my best.",
        likert_scale: "TRUTH"
      },
    ]
  },

  // Re-useable Likert scale labels
  // --------------------------------
  'LIKERT': {
    'NONE_ALOT': ["1
None", "2", "3", "4", "5", "6", "7
A Lot"],
    'BELOW_ABOVE_AVG': [
      "1
Significantly
Below Average", "2", "3", "4
Average",
      "5", "6", "7
Significantly
Above Average"
    ],
    'EMOTIONS': [
      "1
Very Negative/
Unpleasant
Emotions", "2", "3", "4",
      "5", "6", "7
Very Positive/
Pleasant
Emotions"
    ],
    'ENERGY': [
      "1
Deactivated
and Have Very
Little Energy", "2", "3", "4",
      "5", "6", "7
Activated and
Have a Great
Deal of Energy"
    ],
    'NOT_EXTREMELY': [
      "1
Not
at all", "2", "3", "4", "5", "6", "7
Extremely"
    ],
    'SATISFACTION': [
      "1
Not at all
satisfied", "2", "3", "4", "5", "6",
      "7
Completely
satisfied"
    ],
    'WILLINGNESS': [
      "1
Not at all
willing", "2", "3", "4", "5", "6",
      "7
Definitely
willing"
    ],
    'TRUTH': [
      "1
Not at all
true", "2", "3", "4", "5", "6",
      "7
Very true"
    ],
  }
};
<|endoftext|>


<commit_before>(function (mw, $) {
	"use strict";

	mw.PluginManager.add('currentTimeLabel', mw.KBaseComponent.extend({

		defaultConfig: {
			"parent": "controlsContainer",
			"order": 21,
			"displayImportance": "high"
		},

		updateEnabled: true,

		setup: function () {
			var _this = this;
			if ( this.embedPlayer.isMobileSkin() ){
				this.getComponent().data("width",0.1);
			}
			this.bindTimeUpdate();
			this.bind('externalTimeUpdate', function (e, newTime) {
				if (newTime != undefined) {
					_this.updateUI(newTime);
				}
			});
			//will stop listening to native timeupdate events
			this.bind('detachTimeUpdate', function () {
				_this.unbind('timeupdate');
			});
			//will re-listen to native timeupdate events
			this.bind('reattachTimeUpdate', function () {
				_this.bindTimeUpdate();
			});
			// Bind to Ad events
			this.bind('AdSupport_AdUpdatePlayhead', function (e, currentTime) {
				if (_this.getPlayer().isInSequence()) {
					_this.updateUI(currentTime);
				}
			});
			this.bind('AdSupport_EndAdPlayback', function () {
				_this.updateUI(_this.getCurrentTime());
			});
			this.bind('seeked', function () {
				_this.updateUI(_this.getCurrentTime());
			});
			this.bind("freezeTimeIndicators", function (e, state) {
				if (state === true) {
					_this.updateEnabled = false;
				} else {
					_this.updateEnabled = true;
				}
			});
		},
		bindTimeUpdate: function () {
			var _this = this;
			this.bind('timeupdate', function () {
				if (!_this.getPlayer().isInSequence()) {
					_this.updateUI(_this.getCurrentTime());
				}
			});
		},
		updateUI: function (time) {
			if (this.updateEnabled) {
				this.getComponent().text(mw.seconds2npt(time));
			}
		},
		getCurrentTime: function () {
			var ct = this.getPlayer().getPlayerElementTime() - this.getPlayer().startOffset;
			if (ct < 0) {
				ct = 0;
			}
			return parseFloat(ct);
		},
		getComponent: function () {
			if (!this.$el) {
				this.$el = $('<div />')
					.addClass("timers" + this.getCssClass())
					.text('0:00');
			}
			return this.$el;
		},
		show: function () {
			this.getComponent().css('display', 'inline').removeData('forceHide');
		}
	}));

})(window.mw, window.jQuery);<commit_msg>zero the current time when changing media<commit_after>(function (mw, $) {
	"use strict";

	mw.PluginManager.add('currentTimeLabel', mw.KBaseComponent.extend({

		defaultConfig: {
			"parent": "controlsContainer",
			"order": 21,
			"displayImportance": "high"
		},

		updateEnabled: true,

		setup: function () {
			var _this = this;
			if ( this.embedPlayer.isMobileSkin() ){
				this.getComponent().data("width",0.1);
			}
			this.bindTimeUpdate();
			this.bind('externalTimeUpdate', function (e, newTime) {
				if (newTime != undefined) {
					_this.updateUI(newTime);
				}
			});
			// zero the current time when changing media
			this.bind('onChangeMediaDone', function () {
				_this.updateUI(0);
			});
			//will stop listening to native timeupdate events
			this.bind('detachTimeUpdate', function () {
				_this.unbind('timeupdate');
			});
			//will re-listen to native timeupdate events
			this.bind('reattachTimeUpdate', function () {
				_this.bindTimeUpdate();
			});
			// Bind to Ad events
			this.bind('AdSupport_AdUpdatePlayhead', function (e, currentTime) {
				if (_this.getPlayer().isInSequence()) {
					_this.updateUI(currentTime);
				}
			});
			this.bind('AdSupport_EndAdPlayback', function () {
				_this.updateUI(_this.getCurrentTime());
			});
			this.bind('seeked', function () {
				_this.updateUI(_this.getCurrentTime());
			});
			this.bind("freezeTimeIndicators", function (e, state) {
				if (state === true) {
					_this.updateEnabled = false;
				} else {
					_this.updateEnabled = true;
				}
			});
		},
		bindTimeUpdate: function () {
			var _this = this;
			this.bind('timeupdate', function () {
				if (!_this.getPlayer().isInSequence()) {
					_this.updateUI(_this.getCurrentTime());
				}
			});
		},
		updateUI: function (time) {
			if (this.updateEnabled) {
				this.getComponent().text(mw.seconds2npt(time));
			}
		},
		getCurrentTime: function () {
			var ct = this.getPlayer().getPlayerElementTime() - this.getPlayer().startOffset;
			if (ct < 0) {
				ct = 0;
			}
			return parseFloat(ct);
		},
		getComponent: function () {
			if (!this.$el) {
				this.$el = $('<div />')
					.addClass("timers" + this.getCssClass())
					.text('0:00');
			}
			return this.$el;
		},
		show: function () {
			this.getComponent().css('display', 'inline').removeData('forceHide');
		}
	}));

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