<commit_before>var context = new AudioContext(),
    volume = context.createGain(),
    squareOscillators = {},
    sawtoothOscillators = {},
    analyser = context.createAnalyser(),
    dataArray = new Uint8Array(analyser.frequencyBinCount),
    canvas = document.getElementById('oscilloscope'),
    canvasCntxt = canvas.getContext('2d'),
    canvasHeight = 210,
    canvasWidth = 587;

//load and play a sample using Fetch API and web Audio API
var button = document.querySelector('#bling'),
    audioContext = new AudioContext(),
    audioBuffer,
    bufferSource;

//lower the output volume cause oscillators are loud
volume.gain.value = 0.5;

//route to output (context.destionation), speakers
volume.connect(context.destination);
//route output to analyser
volume.connect(analyser);

var keyboard = new QwertyHancock({
  id: 'keyboard',
  width: 600,
  height: 180,
  octaves: 2,
  startNote: 'A2'
});

keyboard.keyDown = function(note, frequency) {
  var squareOsc = context.createOscillator(),
      sawtoothOsc = context.createOscillator();

  squareOscillators[note] = squareOsc;
  sawtoothOscillators[note] = sawtoothOsc;

  squareOsc.connect(volume);
  sawtoothOsc.connect(volume);

  squareOsc.type = 'square';
  sawtoothOsc.type = 'sawtooth';

  squareOsc.frequency.value = frequency;
  squareOsc.detune.value = -10;

  sawtoothOsc.frequency.value = frequency;
  sawtoothOsc.detune.value = 5;

  squareOsc.start(context.currentTime);
  sawtoothOsc.start(context.currentTime);

};

keyboard.keyUp = function(note, frequency) {
  squareOscillators[note].stop(context.currentTime);
  squareOscillators[note].disconnect();

  sawtoothOscillators[note].stop(context.currentTime);
  sawtoothOscillators[note].disconnect();

};

var xWidth = canvasWidth / analyser.frequencyBinCount;

var draw = function() {
  requestAnimationFrame(function () {
    //reset canvas width to clear canvas after each frame
    canvas.width = canvasWidth;

    //analyze dataArray from output
    analyser.getByteTimeDomainData(dataArray);

    for(var i = 0; i < dataArray.length; i++) {
      var yPos = dataArray[i] / 256,
          xPos = i * xWidth;

      yPos = yPos * canvasHeight;
      canvasCntxt.lineTo(xPos,yPos);
    }
      canvasCntxt.strokeStyle = 'green';
      canvasCntxt.stroke();
      draw();
  });
};

draw();

//fetch the file and return an array buffer. Then do something with it.
fetch('/audio/Sandel-OpenCulture.mp3')
  .then(function(response) {
    return response.arrayBuffer();
  })
  .then(function(arrayBuffer) {
    //decode teh array buffer into something the audio api can read, ie AudioBuffer

    audioContext.decodeAudioData(arrayBuffer)
      .then(function(decodedBuffer) {
        //audio buffer is served up;
        console.log('decoded Buffer ', decodedBuffer);
        audioBuffer = decodedBuffer;
        //return audioBuffer;
      });
  });

var playSample = function() {
  //create new node to do stuff with the audio
  bufferSource = audioContext.createBufferSource();

  //point that at the returned decoded Audio buffer
  bufferSource.buffer = audioBuffer;

  //connect it to output (destination)
  bufferSource.connect(audioContext.destination);
  bufferSource.start(audioContext.currentTime);
};

//set eventlistener to the play button:
button.onclick = playSample;
<commit_msg>Replace somewhat hacky canvas clear with a proper method<commit_after>var context = new AudioContext(),
    volume = context.createGain(),
    squareOscillators = {},
    sawtoothOscillators = {},
    analyser = context.createAnalyser(),
    dataArray = new Uint8Array(analyser.frequencyBinCount),
    canvas = document.getElementById('oscilloscope'),
    canvasCntxt = canvas.getContext('2d'),
    canvasHeight = 210,
    canvasWidth = 587;

//load and play a sample using Fetch API and web Audio API
var button = document.querySelector('#bling'),
    audioContext = new AudioContext(),
    audioBuffer,
    bufferSource;

//lower the output volume cause oscillators are loud
volume.gain.value = 0.5;

//route to output (context.destionation), speakers
volume.connect(context.destination);
//route output to analyser
volume.connect(analyser);

var keyboard = new QwertyHancock({
  id: 'keyboard',
  width: 600,
  height: 180,
  octaves: 2,
  startNote: 'A2'
});

keyboard.keyDown = function(note, frequency) {
  var squareOsc = context.createOscillator(),
      sawtoothOsc = context.createOscillator();

  squareOscillators[note] = squareOsc;
  sawtoothOscillators[note] = sawtoothOsc;

  squareOsc.connect(volume);
  sawtoothOsc.connect(volume);

  squareOsc.type = 'square';
  sawtoothOsc.type = 'sawtooth';

  squareOsc.frequency.value = frequency;
  squareOsc.detune.value = -10;

  sawtoothOsc.frequency.value = frequency;
  sawtoothOsc.detune.value = 5;

  squareOsc.start(context.currentTime);
  sawtoothOsc.start(context.currentTime);

};

keyboard.keyUp = function(note, frequency) {
  squareOscillators[note].stop(context.currentTime);
  squareOscillators[note].disconnect();

  sawtoothOscillators[note].stop(context.currentTime);
  sawtoothOscillators[note].disconnect();

};

var xWidth = canvasWidth / analyser.frequencyBinCount;

var draw = function() {
  requestAnimationFrame(function () {
    //reset canvas width to clear canvas after each frame
    canvasCntxt.clearRect(0, 0, canvasWidth, canvasHeight);
    canvasCntxt.beginPath();

    //analyze dataArray from output
    analyser.getByteTimeDomainData(dataArray);

    for(var i = 0; i < dataArray.length; i++) {
      var yPos = dataArray[i] / 256,
          xPos = i * xWidth;

      yPos = yPos * canvasHeight;
      canvasCntxt.lineTo(xPos,yPos);
    }
      canvasCntxt.strokeStyle = 'green';
      canvasCntxt.stroke();
      draw();
  });
};

draw();

//fetch the file and return an array buffer. Then do something with it.
fetch('/audio/Sandel-OpenCulture.mp3')
  .then(function(response) {
    return response.arrayBuffer();
  })
  .then(function(arrayBuffer) {
    //decode teh array buffer into something the audio api can read, ie AudioBuffer

    audioContext.decodeAudioData(arrayBuffer)
      .then(function(decodedBuffer) {
        //audio buffer is served up;
        console.log('decoded Buffer ', decodedBuffer);
        audioBuffer = decodedBuffer;
        //return audioBuffer;
      });
  });

var playSample = function() {
  //create new node to do stuff with the audio
  bufferSource = audioContext.createBufferSource();

  //point that at the returned decoded Audio buffer
  bufferSource.buffer = audioBuffer;

  //make it louder
  volume.gain.value = .1;

  //connect it to output (destination)
  bufferSource.connect(audioContext.destination);
  bufferSource.start(audioContext.currentTime);
};

//set eventlistener to the play button:
button.onclick = playSample;
<|endoftext|>


<commit_before>

var app = angular.module('restApp',[])

app.controller('applicationController',['$scope',function($scope) {
    $scope.mapOptions = {
      center: {
         lat: 40.7903,
         lng: -73.9597
      },
      zoom: 10
    };

    $scope.map = new google.maps.Map(document.getElementById('map-canvas'),$scope.mapOptions);
    $scope.markers = [];
    $scope.koverseIsReady = KoverseApplication.EVENT_READY;

    Koverse.addEventListener($scope.koverseIsReady, function() {
      console.log("[Koverse] Ready1.");
      Koverse.getDataCollectionByName('violators',function(dataCollectionResponse) {
        $scope.dataCollection = dataCollectionResponse.dataCollection;
      });
    });

    Koverse.addEventListener($scope.koverseIsReady, function() {
      console.log("[Koverse] Ready2.");
      Koverse.performQuery("{$any: *}",[$scope.dataCollection],function(response) {
        $scope.records = response.records;
        _.each($scope.records,function(record) {
          var fields = record.fields;
          var latLng = new google.maps.LatLng(fields.Latitude,fields.Longitude)
          var marker = new google.maps.Marker({
            'position': latLng
          });
          console.log("[Koverse] Will push marker.");
          $scope.markers.push(marker);
        });
        $scope.mc = new MarkerClusterer($scope.map,$scope.markers);
      },1000,0,false);

    });

    google.maps.event.addDomListener(window, 'load');

    $scope.debug = function() {
      debugger;
    };
}]);

<commit_msg>Will load violators.<commit_after>

var app = angular.module('restApp',[])

app.controller('applicationController',['$scope',function($scope) {
    $scope.mapOptions = {
      center: {
         lat: 40.7903,
         lng: -73.9597
      },
      zoom: 10
    };

    $scope.map = new google.maps.Map(document.getElementById('map-canvas'),$scope.mapOptions);
    $scope.markers = [];
    $scope.koverseIsReady = KoverseApplication.EVENT_READY;
    $scope.dataCollection = null;

    // Koverse.addEventListener($scope.koverseIsReady, function() {
      // console.log("[Koverse] Ready1.");
      // Koverse.getDataCollectionByName('violators',function(dataCollectionResponse) {
      //   $scope.dataCollection = dataCollectionResponse.dataCollection;
      // });
    // });

    Koverse.addEventListener($scope.koverseIsReady, function() {
      console.log("[Koverse] Ready2.");

      Koverse.getDataCollectionByName('violators',function(dataCollectionResponse) {
        $scope.dataCollection = dataCollectionResponse.dataCollection;
        Koverse.performQuery("{$any: *}",[$scope.dataCollection.id],function(response) {
          $scope.records = response.records;
          //var record = $scope.records.pop();

          _.each($scope.records,function(record) {
            //var restaurant = record.fields.restaurant.pop()
            var fields = record.fields;
            var latLng = new google.maps.LatLng(fields.Latitude,fields.Longitude)
            var marker = new google.maps.Marker({
              'position': latLng
            });
            console.log("[Koverse] Will push marker.");
            $scope.markers.push(marker);
          });
          $scope.mc = new MarkerClusterer($scope.map,$scope.markers);
        },2,0,false);
      });

    });

    Koverse.addEventListener($scope.koverseIsReady, function() {
      console.log("[Koverse] Ready3.");
      $scope.mc = new MarkerClusterer($scope.map,$scope.markers);
    });

    $scope.mc = new MarkerClusterer($scope.map,$scope.markers);
    google.maps.event.addDomListener(window, 'load');

    $scope.debug = function() {
      debugger;
    };
}]);

<|endoftext|>


<commit_before>'use strict';

/* https://github.com/angular/protractor/blob/master/docs/toc.md */

describe('my app', function() {
  it('should add a todo', function() {
    browser.get('https://angularjs.org');

    element(by.model('todoList.todoText')).sendKeys('write first protractor test');
    element(by.css('[value="a1231ddd"]')).click();

    var todoList = element.all(by.repeater('todo in todoList.todos'));
    expect(todoList.count()).toEqual(3);
    expect(todoList.get(2).getText()).toEqual('write first protractor test');

    // You wrote your first test, cross it off the list
    todoList.get(2).element(by.css('input')).click();
    var completedAmount = element.all(by.css('.done-true'));
    expect(completedAmount.count()).toEqual(2);
  });
});
<commit_msg>Fixing broken test.<commit_after>'use strict';

/* https://github.com/angular/protractor/blob/master/docs/toc.md */

describe('my app', function() {
  it('should add a todo', function() {
    browser.get('https://angularjs.org');

    element(by.model('todoList.todoText')).sendKeys('write first protractor test');
    element(by.css('[value="add"]')).click();

    var todoList = element.all(by.repeater('todo in todoList.todos'));
    expect(todoList.count()).toEqual(3);
    expect(todoList.get(2).getText()).toEqual('write first protractor test');

    // You wrote your first test, cross it off the list
    todoList.get(2).element(by.css('input')).click();
    var completedAmount = element.all(by.css('.done-true'));
    expect(completedAmount.count()).toEqual(2);
  });
});
<|endoftext|>


<commit_before>define([
	'underscore'
	, 'marionette'
	, 'moment'
	, 'config'
	, 'models/expense'
	, 'views/list'
	, 'text!../../../templates/timesheet/list.tpl'
	, 'text!../../../templates/timesheet/list-item.tpl'
], function (_, Marionette, Moment, Config, ExpenseModel, ListView, CompositeViewTemplate, ItemViewTemplate) {
	var itemView = Marionette.ItemView.extend({
		template: ItemViewTemplate,
		tagName: 'tr'
	});

	var CompositeView = ListView.extend({
		template: CompositeViewTemplate,
		itemView: itemView,
		objectStore: 'timesheet'
		, serializeData: function() {
			var attrToView = _.clone(this.attributes) || {};

			// console.log(this.collection);
			// console.log(this.attributes);
			// console.log(attrToView);

			var modelStart;
			var configStart = Moment(Config.timesheet.startTime, 'HH:mm');
			var later = _.filter(this.collection.toJSON(), function(model) {
				modelStart = Moment(model.startTime, 'HH:mm');
				return Moment(modelStart).isAfter(configStart);
			});

			// Total Days Late to Work
			attrToView.totalLater = later.length;

			// Total Minutes After Start
			var totalMinutesLateByDay;
			var totalMinutesLaterAfterStart = Moment('00:00', 'HH:mm');
			console.log(totalMinutesLaterAfterStart);
			_.forEach(later, function(element, index, list) {
				totalMinutesLateByDay = Moment(element.startTime, 'HH:mm');
				totalMinutesLateByDay.subtract(configStart);
				totalMinutesLaterAfterStart.add(totalMinutesLateByDay);
			});
			attrToView.totalMinutesLaterAfterStart = totalMinutesLaterAfterStart.minutes();

			// // Total Extra Time
			// // Extra time before start
			// var daysWithExtraTimeBeforeStart = _.filter(this.collection.toJSON(), function(model) {
			// 	return model.startTime < officialStartTime;
			// });
			// var totalExtraTimeBeforeStart;
			// _.forEach(daysWithExtraTimeBeforeStart, function(element, index, list) {
			// 	console.log(element);
			// 	console.log(index);
			// 	console.log(list);

			// 	// TODO calculate extra time before start. Considering the folloow rule for each hour before:
			// 	// 0..20 min before: 0 min;
			// 	// 21..40 min before: 30 min;
			// 	// 41..60 min before: 1 hour;
			// });
			// // Extra time after end
			// var daysWithExtraTimeAfterEnd = _.filter(this.collection.toJSON(), function(model) {
			// 	return model.endTime > officialEndTime;
			// });
			// var totalExtraTimeAfterEnd;
			// _.forEach(daysWithExtraTimeAfterEnd, function(element, index, list) {
			// 	console.log(element);
			// 	console.log(index);
			// 	console.log(list);

			// 	// TODO calculate extra time after end. Considering the folloow rule for each hour after:
			// 	// 0..20 min before: 0 min;
			// 	// 21..40 min before: 30 min;
			// 	// 41..60 min before: 1 hour;
			// });

			// // Finally, the total of extra time!
			// var totalExtraTime = totalExtraTimeBeforeStart + totalExtraTimeAfterEnd;

			// // Total Leaving Early
			// var daysWithLeavingEarly = _.filter(this.collection.toJSON(), function(model) {
			// 	// TODO implement leaving early
			// 	// if total hours worked <= workload then must discount those hours!
			// 	return true;
			// });
			// var totalTimeLeavingEarly;
			// _.forEach(daysWithLeavingEarly, function(element, index, list) {
			// 	console.log(element);
			// 	console.log(index);
			// 	console.log(list);

			// 	// TODO implement it!
			// });

			// // Balance
			// var balance = totalExtraTime - totalTimeLeavingEarly;

			// // Status
			// // TODO implement it!
			// // until 8 days late to work and less than 45 minutes total minutes after: good else: bad

			// TODO filter by month
			attrToView.selectMonth = [
				{label: 'January', value: 0}
				, {label: 'February', value: 1}
				, {label: 'March', value: 2}
				, {label: 'April', value: 3}
				, {label: 'May', value: 4}
				, {label: 'June', value: 5}
				, {label: 'July', value: 6}
				, {label: 'August', value: 7}
				, {label: 'September', value: 8}
				, {label: 'October', value: 9}
				, {label: 'November', value: 10}
				, {label: 'December', value: 11}
			];

			return attrToView;
		}

	});

	return CompositeView;
});
<commit_msg>Timesheet<commit_after>define([
	'underscore'
	, 'marionette'
	, 'moment'
	, 'config'
	, 'models/expense'
	, 'views/list'
	, 'text!../../../templates/timesheet/list.tpl'
	, 'text!../../../templates/timesheet/list-item.tpl'
], function (_, Marionette, Moment, Config, ExpenseModel, ListView, CompositeViewTemplate, ItemViewTemplate) {
	var itemView = Marionette.ItemView.extend({
		template: ItemViewTemplate,
		tagName: 'tr'
	});

	var CompositeView = ListView.extend({
		template: CompositeViewTemplate,
		itemView: itemView,
		objectStore: 'timesheet'
		, serializeData: function() {
			var attrToView = _.clone(this.attributes) || {};

			// console.log(this.collection);
			// console.log(this.attributes);
			// console.log(attrToView);

			// Total Days Late to Work
			var modelStart;
			var configStart = Moment(Config.timesheet.startTime, 'HH:mm');
			var later = _.filter(this.collection.toJSON(), function(model) {
				modelStart = Moment(model.startTime, 'HH:mm');
				return Moment(modelStart).isAfter(configStart);
			});
			attrToView.totalLater = later.length;

			// Total Minutes After Start
			var totalMinutesLateByDay;
			var totalMinutesLaterAfterStart = Moment('00:00', 'HH:mm');
			_.forEach(later, function(element, index, list) {
				totalMinutesLateByDay = Moment(element.startTime, 'HH:mm');
				totalMinutesLateByDay.subtract(configStart);
				totalMinutesLaterAfterStart.add(totalMinutesLateByDay);
			});
			attrToView.totalMinutesLaterAfterStart = totalMinutesLaterAfterStart.minutes();

			// Total Extra Time
			// Extra time before start
			var daysWithExtraTimeBeforeStart = _.filter(this.collection.toJSON(), function(model) {
				modelStart = Moment(model.startTime, 'HH:mm');
				return Moment(modelStart).isBefore(configStart);
			});
			var minutes;
			var startTimeDay;
			var totalExtraTimeBeforeStart = Moment('00:00', 'HH:mm');;
			var officialStartTime = Moment(Config.timesheet.startTime, 'HH:mm');
			_.forEach(daysWithExtraTimeBeforeStart, function(element, index, list) {
				startTimeDay = Moment(element.startTime, 'HH:mm');
				officialStartTime.subtract(startTimeDay);

				// TODO iterate through hours

				if (officialStartTime.minutes() < 21)
					minutes = 0;
				else if (officialStartTime.minutes() < 41)
					minutes = 30;
				else
					minutes = 60;

				totalExtraTimeBeforeStart.add('minutes', minutes);

				// TODO calculate extra time before start. Considering the folloow rule for each hour before:
				// 0..20 min before: 0 min;
				// 21..40 min before: 30 min;
				// 41..60 min before: 1 hour;
			});

			// // Extra time after end
			// var daysWithExtraTimeAfterEnd = _.filter(this.collection.toJSON(), function(model) {
			// 	return model.endTime > officialEndTime;
			// });
			// var totalExtraTimeAfterEnd;
			// _.forEach(daysWithExtraTimeAfterEnd, function(element, index, list) {
			// 	console.log(element);
			// 	console.log(index);
			// 	console.log(list);

			// 	// TODO calculate extra time after end. Considering the folloow rule for each hour after:
			// 	// 0..20 min before: 0 min;
			// 	// 21..40 min before: 30 min;
			// 	// 41..60 min before: 1 hour;
			// });

			// // Finally, the total of extra time!
			// var totalExtraTime = totalExtraTimeBeforeStart + totalExtraTimeAfterEnd;

			// // Total Leaving Early
			// var daysWithLeavingEarly = _.filter(this.collection.toJSON(), function(model) {
			// 	// TODO implement leaving early
			// 	// if total hours worked <= workload then must discount those hours!
			// 	return true;
			// });
			// var totalTimeLeavingEarly;
			// _.forEach(daysWithLeavingEarly, function(element, index, list) {
			// 	console.log(element);
			// 	console.log(index);
			// 	console.log(list);

			// 	// TODO implement it!
			// });

			// // Balance
			// var balance = totalExtraTime - totalTimeLeavingEarly;

			// // Status
			// // TODO implement it!
			// // until 8 days late to work and less than 45 minutes total minutes after: good else: bad

			// TODO filter by month
			attrToView.selectMonth = [
				{label: 'January', value: 0}
				, {label: 'February', value: 1}
				, {label: 'March', value: 2}
				, {label: 'April', value: 3}
				, {label: 'May', value: 4}
				, {label: 'June', value: 5}
				, {label: 'July', value: 6}
				, {label: 'August', value: 7}
				, {label: 'September', value: 8}
				, {label: 'October', value: 9}
				, {label: 'November', value: 10}
				, {label: 'December', value: 11}
			];

			return attrToView;
		}

	});

	return CompositeView;
});
<|endoftext|>


<commit_before>/**
 * Issues a request to the retriever to get GC (Game Coordinator) data for a match
 * Calls back with an object containing the GC data
 * */
const moment = require('moment');
const utility = require('../util/utility');
const config = require('../config');
const queries = require('../store/queries');
const db = require('../store/db');
const redis = require('../store/redis');

const secret = config.RETRIEVER_SECRET;
const retrieverArr = utility.getRetrieverArr();
const { getData, redisCount } = utility;
const { insertMatch } = queries;

function getGcDataFromRetriever(match, cb) {
  // make array of retriever urls and use a random one on each retry
  let urls = retrieverArr.map(r => `http://${r}?key=${secret}&match_id=${match.match_id}`);
  if (config.NODE_ENV !== 'test' && match.allowBackup && (99 - (match.match_id % 100)) < config.BACKUP_RETRIEVER_PERCENT) {
    urls = [`https://api.stratz.com/api/v1/match?matchId=${match.match_id}`];
  }
  return getData({ url: urls, noRetry: match.noRetry }, (err, body, metadata) => {
    if (metadata && metadata.hostname === 'api.stratz.com') {
      // handle backup urls (don't save to DB since no party/buffs data)
      return cb(err, {
        match_id: Number(match.match_id),
        cluster: body.results[0].clusterId,
        replay_salt: body.results[0].replaySalt,
      });
    }
    if (err || !body || !body.match || !body.match.replay_salt || !body.match.players) {
      // non-retryable error
      return cb(new Error('invalid body or error'));
    }
    // Count retriever calls
    redisCount(redis, 'retriever');
    redis.zincrby('retrieverCounts', 1, metadata.hostname);
    redis.expireat('retrieverCounts', moment().startOf('hour').add(1, 'hour').format('X'));

    // Make requests for rank medal updates
    body.match.players.forEach((p) => {
      redis.lpush('mmrQueue', JSON.stringify({
        account_id: p.account_id,
      }));
    });

    // Persist parties and permanent buffs
    const players = body.match.players.map(p => ({
      player_slot: p.player_slot,
      party_id: Number(p.party_id),
      permanent_buffs: p.permanent_buffs,
      party_size: body.match.players
        .filter(matchPlayer => matchPlayer.party_id === p.party_id)
        .length,
    }));
    const matchToInsert = {
      match_id: match.match_id,
      pgroup: match.pgroup,
      players,
    };
    const gcdata = {
      match_id: Number(match.match_id),
      cluster: body.match.cluster,
      replay_salt: body.match.replay_salt,
      series_id: body.match.series_id,
      series_type: body.match.series_type,
    };
    return insertMatch(matchToInsert, {
      type: 'gcdata',
      skipParse: true,
    }, (err) => {
      if (err) {
        return cb(err);
      }
      // Persist GC data to database
      return queries.upsert(db, 'match_gcdata', gcdata, {
        match_id: body.match.match_id,
      }, (err) => {
        cb(err, gcdata);
      });
    });
  });
}

module.exports = function getGcData(match, cb) {
  db.first().from('match_gcdata').where({
    match_id: match.match_id,
  }).asCallback((err, gcdata) => {
    if (err) {
      return cb(err);
    }
    if (gcdata && gcdata.replay_salt) {
      console.log('found cached replay url for %s', match.match_id);
      return cb(err, gcdata);
    }
    return getGcDataFromRetriever(match, cb);
  });
};
<commit_msg>Update getGcData.js<commit_after>/**
 * Issues a request to the retriever to get GC (Game Coordinator) data for a match
 * Calls back with an object containing the GC data
 * */
const moment = require('moment');
const utility = require('../util/utility');
const config = require('../config');
const queries = require('../store/queries');
const db = require('../store/db');
const redis = require('../store/redis');

const secret = config.RETRIEVER_SECRET;
const retrieverArr = utility.getRetrieverArr();
const { getData, redisCount } = utility;
const { insertMatch } = queries;

function getGcDataFromRetriever(match, cb) {
  // make array of retriever urls and use a random one on each retry
  let urls = retrieverArr.map(r => `http://${r}?key=${secret}&match_id=${match.match_id}`);
  if (config.NODE_ENV !== 'test' && match.allowBackup && (99 - (match.match_id % 100)) < config.BACKUP_RETRIEVER_PERCENT) {
    urls = [`https://api.stratz.com/api/v1/match?matchId=${match.match_id}`];
  }
  return getData({ url: urls, noRetry: match.noRetry }, (err, body, metadata) => {
    if (metadata && metadata.hostname === 'api.stratz.com') {
      // handle backup urls (don't save to DB since no party/buffs data)
      return cb(err, {
        match_id: Number(match.match_id),
        cluster: body.results[0].clusterId,
        replay_salt: body.results[0].replaySalt,
      });
    }
    if (err || !body || !body.match || !body.match.replay_salt || !body.match.players) {
      // non-retryable error
      return cb(new Error('invalid body or error'));
    }
    // Count retriever calls
    redisCount(redis, 'retriever');
    redis.zincrby('retrieverCounts', 1, metadata.hostname);
    redis.expireat('retrieverCounts', moment().startOf('hour').add(1, 'hour').format('X'));

    // Make requests for rank medal updates
    body.match.players.forEach((p) => {
      redis.lpush('mmrQueue', JSON.stringify({
        account_id: p.account_id,
      }));
    });

    // Persist parties and permanent buffs
    const players = body.match.players.map(p => ({
      player_slot: p.player_slot,
      party_id: Number(p.party_id),
      permanent_buffs: p.permanent_buffs,
      party_size: body.match.players
        .filter(matchPlayer => matchPlayer.party_id === p.party_id)
        .length,
    }));
    const matchToInsert = {
      match_id: match.match_id,
      pgroup: match.pgroup,
      players,
    };
    const gcdata = {
      match_id: Number(match.match_id),
      cluster: body.match.cluster,
      replay_salt: body.match.replay_salt,
      series_id: body.match.series_id,
      series_type: body.match.series_type,
    };
    return insertMatch(matchToInsert, {
      type: 'gcdata',
      skipParse: true,
    }, (err) => {
      if (err) {
        return cb(err);
      }
      // Persist GC data to database
      return queries.upsert(db, 'match_gcdata', gcdata, {
        match_id: body.match.match_id,
      }, (err) => {
        cb(err, gcdata);
      });
    });
  });
}

module.exports = function getGcData(match, cb) {
  const matchId = match.match_id;
  if (!matchId || Number.isNaN(Number(matchId)) || Number(matchId) <= 0) {
    return cb(new Error('invalid match_id'));
  }
  return db.first().from('match_gcdata').where({
    match_id: matchId,
  }).asCallback((err, gcdata) => {
    if (err) {
      return cb(err);
    }
    if (gcdata && gcdata.replay_salt) {
      console.log('found cached replay url for %s', matchId);
      return cb(err, gcdata);
    }
    return getGcDataFromRetriever(match, cb);
  });
};
<|endoftext|>


<commit_before>window.onload = async () => {
  await populateTable();
}

const populateTable = async () => {
  const table = document.getElementById('requests');

  const res = await fetch('/fetch-requests');

  if (res.status === HTTP_STATUS_CODES.UNAUTHORIZED) {
    alert(
        'We were not able to fetch your requests as you are not logged in, or have not registered');
  } else if (res.status === HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR) {
    alert(
        'We were not able to fetch your requests as there was an unexpected server error. Please try again.');
  }

  const requests = await res.json();

  /**
   * Create a ticket, with subject and details.
   * @param {string} subjectText The subject of the ticket
   * @param {string} detailsText The details of the ticket
   */
  const createTicket =
      (subjectText, detailsText) => {
        const ticket = document.createElement('div');
        const ticketBody = document.createElement('div');
        const subject = document.createElement('p');
        const details = document.createElement('h3');

        ticket.classList.add('card');
        ticketBody.classList.add('card-body');
        subject.classList.add('card-title');
        details.classList.add('card-text');

        ticket.appendChild(ticketBody);
        ticketBody.appendChild(subject);
        ticketBody.appendChild(details);

        subject.innerText = subjectText;
        detail.innerText = detailsText;

        return ticket;
      };

  /**
   * Create a row of the requests table, with date, start time, and end time.
   * @param {string} dateText The date of the request
   * @param {string} startText The start time of the request's delivery window - must be in ISO8601 format
   * @param {string} endText The end time of the request's delivery window - must be in ISO8601 format
   */
  const createRow =
      (dateText, startText, endText) => {
        const row = document.createElement('tr');

        const date = document.createElement('td');
        const start = document.createElement('td');
        const end = document.createElement('td');

        date.innerText = dateText;
        start.innerText = moment.utc(startText).local().format('hh:mmA');
        end.innerText = moment.utc(endText).local().format('hh:mmA');

        row.appendChild(date);
        row.appendChild(start);
        row.appendChild(end);

        return row;
      };

  for (let request of requests) {
    const row = createRow(request.date, request.start, request.end);
    const tickets = document.createElement('td');

    /* Iterate through the tickets for a request, and add them to this row. */
    for (let i = 0; i < request.subjects.length; i++) {
      const ticket = createTicket(request.subjects[i], request.details[i]);
      tickets.appendChild(ticket);
    }

    row.appendChild(tickets);

    table.appendChild(row);
  }
};
<commit_msg>fix typo in requests.js<commit_after>window.onload = async () => {
  await populateTable();
}

const populateTable = async () => {
  const table = document.getElementById('requests');

  const res = await fetch('/fetch-requests');

  if (res.status === HTTP_STATUS_CODES.UNAUTHORIZED) {
    alert(
        'We were not able to fetch your requests as you are not logged in, or have not registered');
  } else if (res.status === HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR) {
    alert(
        'We were not able to fetch your requests as there was an unexpected server error. Please try again.');
  }

  const requests = await res.json();

  /**
   * Create a ticket, with subject and details.
   * @param {string} subjectText The subject of the ticket
   * @param {string} detailsText The details of the ticket
   */
  const createTicket =
      (subjectText, detailsText) => {
        const ticket = document.createElement('div');
        const ticketBody = document.createElement('div');
        const subject = document.createElement('p');
        const details = document.createElement('h3');

        ticket.classList.add('card');
        ticketBody.classList.add('card-body');
        subject.classList.add('card-title');
        details.classList.add('card-text');

        ticket.appendChild(ticketBody);
        ticketBody.appendChild(subject);
        ticketBody.appendChild(details);

        subject.innerText = subjectText;
        details.innerText = detailsText;

        return ticket;
      };

  /**
   * Create a row of the requests table, with date, start time, and end time.
   * @param {string} dateText The date of the request
   * @param {string} startText The start time of the request's delivery window - must be in ISO8601 format
   * @param {string} endText The end time of the request's delivery window - must be in ISO8601 format
   */
  const createRow =
      (dateText, startText, endText) => {
        const row = document.createElement('tr');

        const date = document.createElement('td');
        const start = document.createElement('td');
        const end = document.createElement('td');

        date.innerText = dateText;
        start.innerText = moment.utc(startText).local().format('hh:mmA');
        end.innerText = moment.utc(endText).local().format('hh:mmA');

        row.appendChild(date);
        row.appendChild(start);
        row.appendChild(end);

        return row;
      };

  for (let request of requests) {
    const row = createRow(request.date, request.start, request.end);
    const tickets = document.createElement('td');

    /* Iterate through the tickets for a request, and add them to this row. */
    for (let i = 0; i < request.subjects.length; i++) {
      const ticket = createTicket(request.subjects[i], request.details[i]);
      tickets.appendChild(ticket);
    }

    row.appendChild(tickets);

    table.appendChild(row);
  }
};
<|endoftext|>


<commit_before>var expect = require('chai').expect;
var setup  = require(__dirname + '/lib/setup');

var objects = null;
var states  = null;
var onStateChanged = null;
var onObjectChanged = null;
var sendToID = 1;

function checkConnectionOfAdapter(cb, counter) {
    counter = counter || 0;
    console.log('Try check #' + counter);
    if (counter > 20) {
        cb && cb('Cannot check connection');
        return;
    }

    states.getState('system.adapter.nut.0.alive', function (err, state) {
        if (err) console.error(err);
        if (state && state.val) {
            cb && cb();
        } else {
            setTimeout(function () {
                checkConnectionOfAdapter(cb, counter + 1);
            }, 1000);
        }
    });
}

function checkValueOfState(id, value, cb, counter) {
    counter = counter || 0;
    if (counter > 20) {
        cb && cb('Cannot check value Of State ' + id);
        return;
    }

    states.getState(id, function (err, state) {
        if (err) console.error(err);
        if (value === null && !state) {
            cb && cb();
        } else
        if (state && (value === undefined || state.val === value)) {
            cb && cb();
        } else {
            setTimeout(function () {
                checkValueOfState(id, value, cb, counter + 1);
            }, 500);
        }
    });
}

function sendTo(target, command, message, callback) {
    onStateChanged = function (id, state) {
        if (id === 'messagebox.system.adapter.test.0') {
            callback(state.message);
        }
    };

    states.pushMessage('system.adapter.' + target, {
        command:    command,
        message:    message,
        from:       'system.adapter.test.0',
        callback: {
            message: message,
            id:      sendToID++,
            ack:     false,
            time:    (new Date()).getTime()
        }
    });
}

describe('Test NUT adapter', function() {
    before('Test NUT adapter: Start js-controller', function (_done) {
        this.timeout(600000); // because of first install from npm

        setup.setupController(function () {
            var config = setup.getAdapterConfig();
            // enable adapter
            config.common.enabled  = true;
            config.common.loglevel = 'debug';

            //config.native.dbtype   = 'sqlite';

            setup.setAdapterConfig(config.common, config.native);

            setup.startController(true, function(id, obj) {}, function (id, state) {
                    if (onStateChanged) onStateChanged(id, state);
                },
                function (_objects, _states) {
                    objects = _objects;
                    states  = _states;
                    _done();
                });
        });
    });

    it('Test NUT adapter: Check if adapter started', function (done) {
        this.timeout(60000);
        checkConnectionOfAdapter(function (res) {
            if (res) console.log(res);
            objects.setObject('system.adapter.test.0', {
                    common: {

                    },
                    type: 'instance'
                },
                function () {
                    states.subscribeMessage('system.adapter.test.0');
                    done();
                });
        });
    });

    // We expect ERROR as last Notify necause no nut is running there
    after('Test NUT adapter: test initial state as ERROR', function (done) {
        this.timeout(25000);

        setTimeout(function() {
            states.getState('nut.0.status.last_notify', function (err, state) {
                if (err) console.error(err);
                expect(state).to.exist;
                if (!state) {
                    console.error('state "status.last_notify" not set');
                }
                else {
                    console.log('check status.last_notify ... ' + state.val);
                    expect(state.val).to.be.equal('ERROR');
                }
                states.getState('nut.0.status.severity', function (err, state) {
                    if (err) console.error(err);
                    expect(state).to.exist;
                    if (!state) {
                        console.error('state "status.severity" not set');
                    }
                    else {
                        console.log('check status.severity ... ' + state.val);
                    }
                    expect(state.val).to.be.equal(4);
                    done();
                });
            });
        }, 10000);
    });

    after('Test NUT adapter: send notify Message and receive answer', function (done) {
        this.timeout(25000);
        var now = new Date().getTime();

        console.log('send notify with "COMMBAD" to adapter ...');
        sendTo('nut.0', 'notify', {notifytype: 'COMMBAD', upsname: 'nutName@127.0.0.1'});
        setTimeout(function() {
            states.getState('nut.0.status.last_notify', function (err, state) {
                if (err) console.error(err);
                if (!state) {
                    console.error('state "status.last_notify" not set');
                }
                else {
                    console.log('check status.last_notify ... ' + state.val);
                }
                expect(state.val).to.be.equal('COMMBAD');
                done();
            });
        }, 2000);
    });

    after('Test NUT adapter: Stop js-controller', function (done) {
        this.timeout(10000);

        setup.stopController(function (normalTerminated) {
            console.log('Adapter normal terminated: ' + normalTerminated);
            done();
        });
    });
});
<commit_msg>disable one test because timeout too long<commit_after>var expect = require('chai').expect;
var setup  = require(__dirname + '/lib/setup');

var objects = null;
var states  = null;
var onStateChanged = null;
var onObjectChanged = null;
var sendToID = 1;

function checkConnectionOfAdapter(cb, counter) {
    counter = counter || 0;
    console.log('Try check #' + counter);
    if (counter > 20) {
        cb && cb('Cannot check connection');
        return;
    }

    states.getState('system.adapter.nut.0.alive', function (err, state) {
        if (err) console.error(err);
        if (state && state.val) {
            cb && cb();
        } else {
            setTimeout(function () {
                checkConnectionOfAdapter(cb, counter + 1);
            }, 1000);
        }
    });
}

function checkValueOfState(id, value, cb, counter) {
    counter = counter || 0;
    if (counter > 20) {
        cb && cb('Cannot check value Of State ' + id);
        return;
    }

    states.getState(id, function (err, state) {
        if (err) console.error(err);
        if (value === null && !state) {
            cb && cb();
        } else
        if (state && (value === undefined || state.val === value)) {
            cb && cb();
        } else {
            setTimeout(function () {
                checkValueOfState(id, value, cb, counter + 1);
            }, 500);
        }
    });
}

function sendTo(target, command, message, callback) {
    onStateChanged = function (id, state) {
        if (id === 'messagebox.system.adapter.test.0') {
            callback(state.message);
        }
    };

    states.pushMessage('system.adapter.' + target, {
        command:    command,
        message:    message,
        from:       'system.adapter.test.0',
        callback: {
            message: message,
            id:      sendToID++,
            ack:     false,
            time:    (new Date()).getTime()
        }
    });
}

describe('Test NUT adapter', function() {
    before('Test NUT adapter: Start js-controller', function (_done) {
        this.timeout(600000); // because of first install from npm

        setup.setupController(function () {
            var config = setup.getAdapterConfig();
            // enable adapter
            config.common.enabled  = true;
            config.common.loglevel = 'debug';

            //config.native.dbtype   = 'sqlite';

            setup.setAdapterConfig(config.common, config.native);

            setup.startController(true, function(id, obj) {}, function (id, state) {
                    if (onStateChanged) onStateChanged(id, state);
                },
                function (_objects, _states) {
                    objects = _objects;
                    states  = _states;
                    _done();
                });
        });
    });

    it('Test NUT adapter: Check if adapter started', function (done) {
        this.timeout(60000);
        checkConnectionOfAdapter(function (res) {
            if (res) console.log(res);
            objects.setObject('system.adapter.test.0', {
                    common: {

                    },
                    type: 'instance'
                },
                function () {
                    states.subscribeMessage('system.adapter.test.0');
                    done();
                });
        });
    });

    // We expect ERROR as last Notify necause no nut is running there
/*    after('Test NUT adapter: test initial state as ERROR', function (done) {
        this.timeout(25000);

        setTimeout(function() {
            states.getState('nut.0.status.last_notify', function (err, state) {
                if (err) console.error(err);
                expect(state).to.exist;
                if (!state) {
                    console.error('state "status.last_notify" not set');
                }
                else {
                    console.log('check status.last_notify ... ' + state.val);
                    expect(state.val).to.be.equal('ERROR');
                }
                states.getState('nut.0.status.severity', function (err, state) {
                    if (err) console.error(err);
                    expect(state).to.exist;
                    if (!state) {
                        console.error('state "status.severity" not set');
                    }
                    else {
                        console.log('check status.severity ... ' + state.val);
                    }
                    expect(state.val).to.be.equal(4);
                    done();
                });
            });
        }, 10000);
    });
*/

    after('Test NUT adapter: send notify Message and receive answer', function (done) {
        this.timeout(25000);
        var now = new Date().getTime();

        console.log('send notify with "COMMBAD" to adapter ...');
        sendTo('nut.0', 'notify', {notifytype: 'COMMBAD', upsname: 'nutName@127.0.0.1'});
        setTimeout(function() {
            states.getState('nut.0.status.last_notify', function (err, state) {
                if (err) console.error(err);
                if (!state) {
                    console.error('state "status.last_notify" not set');
                }
                else {
                    console.log('check status.last_notify ... ' + state.val);
                }
                expect(state.val).to.be.equal('COMMBAD');
                done();
            });
        }, 2000);
    });

    after('Test NUT adapter: Stop js-controller', function (done) {
        this.timeout(10000);

        setup.stopController(function (normalTerminated) {
            console.log('Adapter normal terminated: ' + normalTerminated);
            done();
        });
    });
});
<|endoftext|>


<commit_before>// dimensions of the SVG viewport
var w = 600;
var h = 400;
var r = 3;

// TODO change domain and range according to some configuration

// scale for the second Chern number
var c2 = d3.scale.linear()
  .domain([-20, 80])
  .range([0, w]);

// scale for the first Chern number
var c12 = d3.scale.linear()
  .domain([-30, 60])
  .range([h, 0]);

// axis for the second Chern number
var c2Axis = d3.svg.axis()
  .tickValues([-10, 0, 10, 20, 30, 40, 50, 60, 70])
  .scale(c2);

// axis for the first Chern number
var c12Axis = d3.svg.axis()
  .scale(c12)
  .tickValues([-20, -10, 0, 10, 20, 30, 40, 50])
  .orient("left");

// scale for the Kodaira dimension
var kodaira = d3.scale.ordinal()
  .domain([-1, 0, 1, 2])
  .range(["kodaira-infty", "kodaira-0", "kodaira-1", "kodaira-2"]);

// all the pairs (c_2,c_1^2) corresponding to a minimal projective surface
var points = [];

function Point(c2, c12, kodaira) {
  this.c2 = c2;
  this.c12 = c12;
  this.kodaira = kodaira;

  this.hasExamples = false;
}

// projective plane
points.push(new Point(3, 9, -1));

// minimal surfaces of Kodaira dimension 0
points.push(new Point(0, 0, 0)); // abelian and hyperelliptic surfaces
points.push(new Point(12, 0, 0)); // Enriques surfaces
points.push(new Point(24, 0, 0)); // K3 surfaces

for (var i2 = c2.domain()[0]; i2 < c2.domain()[1]; i2++) {
  for (var i12 = c12.domain()[0]; i12 < c12.domain()[1]; i12++) {
    // ruled surfaces
    var positivity = (i2 <= 4) && (i12 <= 8);
    var congruence = (i2 % 4 === 0) && (i12 % 8 === 0) && (i12 == i2 * 2);
    if (congruence && positivity)
      points.push(new Point(i2, i12, -1));

    // minimal surface of Kodaira dimension 1
    var congruence = ((i12 + i2) % 12 === 0);
    var positivity = (i12 === 0) && (i2 >= 0);
    if (congruence && positivity)
      points.push(new Point(i2, i12, 1));

    // minimal surface of general type
    var congruence = ((i12 + i2) % 12 === 0);
    var positivity = (i12 > 0) && (i2 > 0);
    var BMY = (i12 <= (3 * i2));
    var noether = ((5 * i12 - i2 + 36) >= 0);

    if (congruence && positivity && BMY && noether)
      points.push(new Point(i2, i12, 2));
  }
}

// see which points have surfaces associated to them
for (var i = 0; i < points.length; i++) {
  for (var j = 0; j < surfaces.length; j++) {
    if (surfaces[j].c2 == points[i].c2 && surfaces[j].c12 == points[i].c12 && surfaces[j].kodaira == points[i].kodaira) {
      points[i].hasExamples = true;
    }
  }
}

var svg = d3.select("div#table")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

// all the minimal n.c12s
svg.selectAll("circle")
  .data(points)
  .enter()
  .append("circle")
  .attr("cx", function(d) { return c2(d.c2); })
  .attr("cy", function(d) { return c12(d.c12); })
  .attr("r", function(d) { return d.hasExamples ? r + 1 : r - 1; })
  .attr("data-toggle", "tooltip")
  .attr("data-c2", function(d) { return d.c2; })
  .attr("data-c12", function(d) { return d.c12; })
  .attr("class", function(d) { return kodaira(d.kodaira); });

// horizontal axis
svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0," + c12(0) + ")")
  .call(c2Axis);

// vertical axis
svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(" + c2(0) + ",0)")
  .call(c12Axis);

// improve origin: remove double 0
svg.selectAll(".axis g text")
  .filter(function(d) { return d === 0; })
  .style("opacity", function(d, i) { if (i !== 0) return 0; })
  .attr("dx", function(d, i) { if (i === 0) return "-10px"; });

// draw Noether inequality (hardcoded constants...)
svg.append("line")
  .attr("x1", c2(36))
  .attr("x2", c2(86))
  .attr("y1", c12(0))
  .attr("y2", c12(10))
  .attr("class", "axis");
svg.append("text")
  .attr("x", c2(65))
  .attr("y", c12(2))
  .attr("class", "kodaira-2 inactive")
  .attr("text-anchor", "middle")
  .attr("transform", "rotate(-7, " + c2(65) + ", " + c12(2) + ")")
  .text("Noether inequality");

// draw the BMY inequality (hardcoded constants...)
svg.append("line")
  .attr("x1", c2(0))
  .attr("x2", c2(20))
  .attr("y1", c12(0))
  .attr("y2", c12(60))
  .attr("class", "axis");
svg.append("text")
  .attr("x", c2(10))
  .attr("y", c12(35))
  .attr("class", "kodaira-2 inactive")
  .attr("text-anchor", "middle")
  .attr("transform", "rotate(-66, " + c2(10) + ", " + c12(35) + ")")
  .text("Bogomolov-Miyaoka-Yau inequality");

// draw the Debarre inequality (hardcoded constants...)
svg.append("line")
  .attr("x1", c2(0))
  .attr("x2", c2(30))
  .attr("y1", c12(0))
  .attr("y2", c12(60))
  .attr("class", "axis");
$("body").append("
Debarre inequality
");

// assign click event to points
d3.selectAll("circle").on("click", clickedPoint);

function clickedPoint(point) {
  // only act when the clicked node is active (i.e. has the correct Kodaira dimension)
  if (!d3.select(this).classed("inactive")) {
    // make all nodes inactive
    d3.selectAll("circle").classed("active", false);

    // make this node active
    d3.select(this).classed("active", true);

    // remove candidates
    clearCandidates();

    // reset the Hodge diamond
    setInactive();

    // add the coordinates to the legend in the fieldset
    $("fieldset#candidates legend").html("Candidates
for $\\mathrm{c}_2=" + point.c2 + "$, $\\mathrm{c}_1^2=" + point.c12 + "$");
    MathJax.Hub.Queue(["Typeset", MathJax.Hub]);

    // look for surfaces with the correct invariants
    for (var i = 0; i < surfaces.length; i++) {
      if (surfaces[i].c2 == point.c2 && surfaces[i].c12 == point.c12 && surfaces[i].kodaira == point.kodaira)
        addCandidateSurface(surfaces[i]);
    }

    // check whether we have found surfaces, otherwise display a message
    if ($("fieldset#candidates ol li").length === 0) {
      $("fieldset#candidates").prepend("
No surfaces known with these invariants, sorry.");
    } else if ($("fieldset#candidates ol li").length === 1) {
      $("fieldset#candidates ol li a").click();
    }

    MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
  }
}

<commit_msg>Improve #11<commit_after>// dimensions of the SVG viewport
var w = 600;
var h = 400;
var r = 3;

// TODO change domain and range according to some configuration

// scale for the second Chern number
var c2 = d3.scale.linear()
  .domain([-20, 80])
  .range([0, w]);

// scale for the first Chern number
var c12 = d3.scale.linear()
  .domain([-30, 60])
  .range([h, 0]);

// axis for the second Chern number
var c2Axis = d3.svg.axis()
  .tickValues([-10, 0, 10, 20, 30, 40, 50, 60, 70])
  .scale(c2);

// axis for the first Chern number
var c12Axis = d3.svg.axis()
  .scale(c12)
  .tickValues([-20, -10, 0, 10, 20, 30, 40, 50])
  .orient("left");

// scale for the Kodaira dimension
var kodaira = d3.scale.ordinal()
  .domain([-1, 0, 1, 2])
  .range(["kodaira-infty", "kodaira-0", "kodaira-1", "kodaira-2"]);

// all the pairs (c_2,c_1^2) corresponding to a minimal projective surface
var points = [];

function Point(c2, c12, kodaira) {
  this.c2 = c2;
  this.c12 = c12;
  this.kodaira = kodaira;

  this.hasExamples = false;
}

// projective plane
points.push(new Point(3, 9, -1));

// minimal surfaces of Kodaira dimension 0
points.push(new Point(0, 0, 0)); // abelian and hyperelliptic surfaces
points.push(new Point(12, 0, 0)); // Enriques surfaces
points.push(new Point(24, 0, 0)); // K3 surfaces

for (var i2 = c2.domain()[0]; i2 < c2.domain()[1]; i2++) {
  for (var i12 = c12.domain()[0]; i12 < c12.domain()[1]; i12++) {
    // ruled surfaces
    var positivity = (i2 <= 4) && (i12 <= 8);
    var congruence = (i2 % 4 === 0) && (i12 % 8 === 0) && (i12 == i2 * 2);
    if (congruence && positivity)
      points.push(new Point(i2, i12, -1));

    // minimal surface of Kodaira dimension 1
    var congruence = ((i12 + i2) % 12 === 0);
    var positivity = (i12 === 0) && (i2 >= 0);
    if (congruence && positivity)
      points.push(new Point(i2, i12, 1));

    // minimal surface of general type
    var congruence = ((i12 + i2) % 12 === 0);
    var positivity = (i12 > 0) && (i2 > 0);
    var BMY = (i12 <= (3 * i2));
    var noether = ((5 * i12 - i2 + 36) >= 0);

    if (congruence && positivity && BMY && noether)
      points.push(new Point(i2, i12, 2));
  }
}

// see which points have surfaces associated to them
for (var i = 0; i < points.length; i++) {
  for (var j = 0; j < surfaces.length; j++) {
    if (surfaces[j].c2 == points[i].c2 && surfaces[j].c12 == points[i].c12 && surfaces[j].kodaira == points[i].kodaira) {
      points[i].hasExamples = true;
    }
  }
}

var svg = d3.select("div#table")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

// all the minimal n.c12s
svg.selectAll("circle")
  .data(points)
  .enter()
  .append("circle")
  .attr("cx", function(d) { return c2(d.c2); })
  .attr("cy", function(d) { return c12(d.c12); })
  .attr("r", function(d) { return d.hasExamples ? r + 1 : r - 1; })
  .attr("data-toggle", "tooltip")
  .attr("data-c2", function(d) { return d.c2; })
  .attr("data-c12", function(d) { return d.c12; })
  .attr("class", function(d) { return kodaira(d.kodaira); });

// horizontal axis
svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0," + c12(0) + ")")
  .call(c2Axis);

// vertical axis
svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(" + c2(0) + ",0)")
  .call(c12Axis);

// improve origin: remove double 0
svg.selectAll(".axis g text")
  .filter(function(d) { return d === 0; })
  .style("opacity", function(d, i) { if (i !== 0) return 0; })
  .attr("dx", function(d, i) { if (i === 0) return "-10px"; });

// draw Noether inequality (hardcoded constants...)
svg.append("line")
  .attr("x1", c2(36))
  .attr("x2", c2(86))
  .attr("y1", c12(0))
  .attr("y2", c12(10))
  .attr("class", "axis");
svg.append("text")
  .attr("x", c2(65))
  .attr("y", c12(2))
  .attr("class", "kodaira-2 inactive")
  .attr("text-anchor", "middle")
  .attr("transform", "rotate(-7, " + c2(65) + ", " + c12(2) + ")")
  .text("Noether inequality");

// draw the BMY inequality (hardcoded constants...)
svg.append("line")
  .attr("x1", c2(0))
  .attr("x2", c2(20))
  .attr("y1", c12(0))
  .attr("y2", c12(60))
  .attr("class", "axis");
svg.append("text")
  .attr("x", c2(10))
  .attr("y", c12(35))
  .attr("class", "kodaira-2 inactive")
  .attr("text-anchor", "middle")
  .attr("transform", "rotate(-66, " + c2(10) + ", " + c12(35) + ")")
  .text("Bogomolov-Miyaoka-Yau inequality");

// draw the Debarre inequality (hardcoded constants...)
svg.append("line")
  .attr("x1", c2(0))
  .attr("x2", c2(30))
  .attr("y1", c12(0))
  .attr("y2", c12(60))
  .attr("class", "axis");
$("body").append("
Debarre inequality
");

// assign click event to points
d3.selectAll("circle").on("click", clickedPoint);

function clickedPoint(point) {
  // only act when the clicked node is active (i.e. has the correct Kodaira dimension)
  if (!d3.select(this).classed("inactive")) {
    // make all nodes inactive
    d3.selectAll("circle").classed("active", false);

    // make this node active
    d3.select(this).classed("active", true);

    // remove candidates
    clearCandidates();

    // reset the Hodge diamond
    setInactive();

    // add the coordinates to the legend in the fieldset
    $("fieldset#candidates legend").html("Candidates
for $\\mathrm{c}_2=" + point.c2 + "$, $\\mathrm{c}_1^2=" + point.c12 + "$");
    MathJax.Hub.Queue(["Typeset", MathJax.Hub]);

    // look for surfaces with the correct invariants
    for (var i = 0; i < surfaces.length; i++) {
      if (surfaces[i].c2 == point.c2 && surfaces[i].c12 == point.c12 && surfaces[i].kodaira == point.kodaira)
        addCandidateSurface(surfaces[i]);
    }

    // check whether we have found surfaces, otherwise display a message
    if ($("fieldset#candidates ol li").length === 0) {
      $("fieldset#candidates").prepend("
No surfaces known with these invariants, sorry.");
    } else if ($("fieldset#candidates ol li").length === 1) {
      $("fieldset#candidates ol li a").click();
      $("fieldset#candidates ol li").addClass("active");
    }

    MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
  }
}

<|endoftext|>


<commit_before>const webpack = require('webpack')

const logger = require('../helpers/logger')
const log = logger('app:electron')
const warn = logger('app:electron', 'red')
const { spawn } = require('../helpers/spawn')
const appPaths = require('../app-paths')
const nodePackager = require('../helpers/node-packager')
const getPackageJson = require('../helpers/get-package-json')
const getPackage = require('../helpers/get-package')

class ElectronRunner {
  constructor () {
    this.pid = 0
    this.watcher = null
  }

  init () {}

  async run (quasarConfig, argv) {
    const url = quasarConfig.getBuildConfig().build.APP_URL

    if (this.pid) {
      if (this.url !== url) {
        await this.stop()
      }
      else {
        return
      }
    }

    this.url = url

    const compiler = webpack(quasarConfig.getWebpackConfig().main)

    return new Promise(resolve => {
      log(`Building main Electron process...`)
      this.watcher = compiler.watch({}, async (err, stats) => {
        if (err) {
          console.log(err)
          return
        }

        log(`Webpack built Electron main process`)
        log()
        process.stdout.write(stats.toString({
          colors: true,
          modules: false,
          children: false,
          chunks: false,
          chunkModules: false
        }) + '\n')
        log()

        if (stats.hasErrors()) {
          warn(`⚠  Electron main build failed with errors`)
          return
        }

        await this.__stopElectron()
        this.__startElectron(argv._)

        resolve()
      })
    })
  }

  build (quasarConfig) {
    const cfg = quasarConfig.getBuildConfig()

    return new Promise(resolve => {
      spawn(
        nodePackager,
        [ 'install', '--production' ].concat(cfg.electron.unPackagedInstallParams),
        { cwd: cfg.build.distDir },
        code => {
          if (code) {
            warn(`⚠  [FAIL] ${nodePackager} failed installing dependencies`)
            process.exit(1)
          }
          resolve()
        }
      )
    }).then(() => {
      return new Promise(async resolve => {
        if (typeof cfg.electron.beforePackaging === 'function') {
          log('Running beforePackaging()')
          log()

          const result = cfg.electron.beforePackaging({
            appPaths,
            unpackagedDir: cfg.build.distDir
          })

          if (result && result.then) {
            await result
          }

          log()
          log('[SUCCESS] Done running beforePackaging()')
        }
        resolve()
      })
    }).then(() => {
      const bundlerName = cfg.electron.bundler
      const bundlerConfig = cfg.electron[bundlerName]
      const bundler = require('./bundler').getBundler(bundlerName)
      const pkgName = `electron-${bundlerName}`

      return new Promise((resolve, reject) => {
        log(`Bundling app with electron-${bundlerName}...`)
        log()

        const bundlePromise = bundlerName === 'packager'
          ? bundler({
            ...bundlerConfig,
            electronVersion: getPackageJson('electron').version
          })
          : bundler.build(bundlerConfig)

        bundlePromise
          .then(() => {
            log()
            log(`[SUCCESS] ${pkgName} built the app`)
            log()
            resolve()
          })
          .catch(err => {
            log()
            warn(`⚠  [FAIL] ${pkgName} could not build`)
            log()
            console.error(err + '\n')
            reject()
          })
      })
    })
  }

  stop () {
    return new Promise(resolve => {
      const finalize = () => {
        this.__stopElectron().then(resolve)
      }

      if (this.watcher) {
        this.watcher.close(finalize)
        this.watcher = null
        return
      }

      finalize()
    })
  }

  __startElectron (extraParams) {
    log(`Booting up Electron process...`)
    this.pid = spawn(
      getPackage('electron'),
      [
        '--inspect=5858',
        appPaths.resolve.app('.quasar/electron/electron-main.js')
      ].concat(extraParams),
      { cwd: appPaths.appDir },
      code => {
        if (code) {
          warn()
          warn(`⚠  Electron process ended with error code: ${code}`)
          warn()
          process.exit(1)
        }

        if (this.killPromise) {
          this.killPromise()
          this.killPromise = null
        }
        else { // else it wasn't killed by us
          warn()
          warn('Electron process was killed. Exiting...')
          warn()
          process.exit(0)
        }
      }
    )
  }

  __stopElectron () {
    const pid = this.pid

    if (!pid) {
      return Promise.resolve()
    }

    log('Shutting down Electron process...')
    this.pid = 0
    return new Promise(resolve => {
      this.killPromise = resolve
      process.kill(pid)
    })
  }
}

module.exports = new ElectronRunner()
<commit_msg>fix(app): [Windows] Electron process terminated after changing main-process code #5949<commit_after>const webpack = require('webpack')

const logger = require('../helpers/logger')
const log = logger('app:electron')
const warn = logger('app:electron', 'red')
const { spawn } = require('../helpers/spawn')
const appPaths = require('../app-paths')
const nodePackager = require('../helpers/node-packager')
const getPackageJson = require('../helpers/get-package-json')
const getPackage = require('../helpers/get-package')

class ElectronRunner {
  constructor () {
    this.pid = 0
    this.watcher = null
  }

  init () {}

  async run (quasarConfig, argv) {
    const url = quasarConfig.getBuildConfig().build.APP_URL

    if (this.pid) {
      if (this.url !== url) {
        await this.stop()
      }
      else {
        return
      }
    }

    this.url = url

    const compiler = webpack(quasarConfig.getWebpackConfig().main)

    return new Promise(resolve => {
      log(`Building main Electron process...`)
      this.watcher = compiler.watch({}, async (err, stats) => {
        if (err) {
          console.log(err)
          return
        }

        log(`Webpack built Electron main process`)
        log()
        process.stdout.write(stats.toString({
          colors: true,
          modules: false,
          children: false,
          chunks: false,
          chunkModules: false
        }) + '\n')
        log()

        if (stats.hasErrors()) {
          warn(`⚠  Electron main build failed with errors`)
          return
        }

        await this.__stopElectron()
        this.__startElectron(argv._)

        resolve()
      })
    })
  }

  build (quasarConfig) {
    const cfg = quasarConfig.getBuildConfig()

    return new Promise(resolve => {
      spawn(
        nodePackager,
        [ 'install', '--production' ].concat(cfg.electron.unPackagedInstallParams),
        { cwd: cfg.build.distDir },
        code => {
          if (code) {
            warn(`⚠  [FAIL] ${nodePackager} failed installing dependencies`)
            process.exit(1)
          }
          resolve()
        }
      )
    }).then(() => {
      return new Promise(async resolve => {
        if (typeof cfg.electron.beforePackaging === 'function') {
          log('Running beforePackaging()')
          log()

          const result = cfg.electron.beforePackaging({
            appPaths,
            unpackagedDir: cfg.build.distDir
          })

          if (result && result.then) {
            await result
          }

          log()
          log('[SUCCESS] Done running beforePackaging()')
        }
        resolve()
      })
    }).then(() => {
      const bundlerName = cfg.electron.bundler
      const bundlerConfig = cfg.electron[bundlerName]
      const bundler = require('./bundler').getBundler(bundlerName)
      const pkgName = `electron-${bundlerName}`

      return new Promise((resolve, reject) => {
        log(`Bundling app with electron-${bundlerName}...`)
        log()

        const bundlePromise = bundlerName === 'packager'
          ? bundler({
            ...bundlerConfig,
            electronVersion: getPackageJson('electron').version
          })
          : bundler.build(bundlerConfig)

        bundlePromise
          .then(() => {
            log()
            log(`[SUCCESS] ${pkgName} built the app`)
            log()
            resolve()
          })
          .catch(err => {
            log()
            warn(`⚠  [FAIL] ${pkgName} could not build`)
            log()
            console.error(err + '\n')
            reject()
          })
      })
    })
  }

  stop () {
    return new Promise(resolve => {
      const finalize = () => {
        this.__stopElectron().then(resolve)
      }

      if (this.watcher) {
        this.watcher.close(finalize)
        this.watcher = null
        return
      }

      finalize()
    })
  }

  __startElectron (extraParams) {
    log(`Booting up Electron process...`)
    this.pid = spawn(
      getPackage('electron'),
      [
        '--inspect=5858',
        appPaths.resolve.app('.quasar/electron/electron-main.js')
      ].concat(extraParams),
      { cwd: appPaths.appDir },
      code => {
        if (this.killPromise) {
          this.killPromise()
          this.killPromise = null
        }
        else if (code) {
          warn()
          warn(`⚠  Electron process ended with error code: ${code}`)
          warn()
          process.exit(1)
        }
        else { // else it wasn't killed by us
          warn()
          warn('Electron process was killed. Exiting...')
          warn()
          process.exit(0)
        }
      }
    )
  }

  __stopElectron () {
    const pid = this.pid

    if (!pid) {
      return Promise.resolve()
    }

    log('Shutting down Electron process...')
    this.pid = 0
    return new Promise(resolve => {
      this.killPromise = resolve
      process.kill(pid)
    })
  }
}

module.exports = new ElectronRunner()
<|endoftext|>


<commit_before>/*!
 * mustache.js - Logic-less {{mustache}} templates with JavaScript
 * http://github.com/janl/mustache.js
 */

/*global define: false*/

(function (root, factory) {
  if (typeof exports === "object" && exports) {
    module.exports = factory; // CommonJS
  } else if (typeof define === "function" && define.amd) {
    define(factory); // AMD
  } else {
    root.Mustache = factory; // <script>
  }
}(this, (function () {

  var exports = {};

  exports.name = "mustache.js";
  exports.version = "0.7.2";
  exports.tags = ["{{", "}}"];

  exports.Scanner = Scanner;
  exports.Context = Context;
  exports.Writer = Writer;

  var whiteRe = /\s*/;
  var spaceRe = /\s+/;
  var nonSpaceRe = /\S/;
  var eqRe = /\s*=/;
  var curlyRe = /\s*\}/;
  var tagRe = /#|\^|\/|>|\{|&|=|!/;

  // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
  // See https://github.com/janl/mustache.js/issues/189
  function testRe(re, string) {
    return RegExp.prototype.test.call(re, string);
  }

  function isWhitespace(string) {
    return !testRe(nonSpaceRe, string);
  }

  var isArray = Array.isArray || function (obj) {
    return Object.prototype.toString.call(obj) === "[object Array]";
  };

  function escapeRe(string) {
    return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
  }

  var entityMap = {
    "&": "&",
    "<": "<",
    ">": ">",
    '"': '"',
    "'": ''',
    "/": '/'
  };

  function escapeHtml(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
      return entityMap[s];
    });
  }

  // Export the escaping function so that the user may override it.
  // See https://github.com/janl/mustache.js/issues/244
  exports.escape = escapeHtml;

  function Scanner(string) {
    this.string = string;
    this.tail = string;
    this.pos = 0;
  }

  /**
   * Returns `true` if the tail is empty (end of string).
   */
  Scanner.prototype.eos = function () {
    return this.tail === "";
  };

  /**
   * Tries to match the given regular expression at the current position.
   * Returns the matched text if it can match, the empty string otherwise.
   */
  Scanner.prototype.scan = function (re) {
    var match = this.tail.match(re);

    if (match && match.index === 0) {
      this.tail = this.tail.substring(match[0].length);
      this.pos += match[0].length;
      return match[0];
    }

    return "";
  };

  /**
   * Skips all text until the given regular expression can be matched. Returns
   * the skipped string, which is the entire tail if no match can be made.
   */
  Scanner.prototype.scanUntil = function (re) {
    var match, pos = this.tail.search(re);

    switch (pos) {
    case -1:
      match = this.tail;
      this.pos += this.tail.length;
      this.tail = "";
      break;
    case 0:
      match = "";
      break;
    default:
      match = this.tail.substring(0, pos);
      this.tail = this.tail.substring(pos);
      this.pos += pos;
    }

    return match;
  };

  function Context(view, parent) {
    this.view = view;
    this.parent = parent;
    this.clearCache();
  }

  Context.make = function (view) {
    return (view instanceof Context) ? view : new Context(view);
  };

  Context.prototype.clearCache = function () {
    this._cache = {};
  };

  Context.prototype.push = function (view) {
    return new Context(view, this);
  };

  Context.prototype.lookup = function (name) {
    var value = this._cache[name];

    if (!value) {
      if (name === ".") {
        value = this.view;
      } else {
        var context = this;

        while (context) {
          if (name.indexOf(".") > 0) {
            var names = name.split("."), i = 0;

            value = context.view;

            while (value && i < names.length) {
              value = value[names[i++]];
            }
          } else {
            value = context.view[name];
          }

          if (value != null) break;

          context = context.parent;
        }
      }

      this._cache[name] = value;
    }

    if (typeof value === 'function') value = value.call(this.view);

    return value;
  };

  function Writer() {
    this.clearCache();
  }

  Writer.prototype.clearCache = function () {
    this._cache = {};
    this._partialCache = {};
  };

  Writer.prototype.compile = function (template, tags) {
    var fn = this._cache[template];

    if (!fn) {
      var tokens = exports.parse(template, tags);
      fn = this._cache[template] = this.compileTokens(tokens, template);
    }

    return fn;
  };

  Writer.prototype.compilePartial = function (name, template, tags) {
    var fn = this.compile(template, tags);
    this._partialCache[name] = fn;
    return fn;
  };

  Writer.prototype.compileTokens = function (tokens, template) {
    var fn = compileTokens(tokens);
    var self = this;

    return function (view, partials) {
      if (partials) {
        if (typeof partials === "function") {
          self._loadPartial = partials;
        } else {
          for (var name in partials) {
            self.compilePartial(name, partials[name]);
          }
        }
      }

      return fn(self, Context.make(view), template);
    };
  };

  Writer.prototype.render = function (template, view, partials) {
    return this.compile(template)(view, partials);
  };

  Writer.prototype._section = function (token, context, template, callback) {
    var name = token[1];
    var value = context.lookup(name);

    switch (typeof value) {
    case "object":
      if (isArray(value)) {
        var buffer = '';

        for (var i = 0, len = value.length; i < len; ++i) {
          buffer += callback(this, context.push(value[i]));
        }

        return buffer;
      }

      return value ? callback(this, context.push(value)) : "";
    case "function":
      var text = template == null ? null : template.slice(token[3], token[5]);
      var self = this;
      var scopedRender = function (template) {
        return self.render(template, context);
      };

      var result = value.call(context.view, text, scopedRender);
      return result == null ? '' : result;
    default:
      if (value) {
        return callback(this, context);
      }
    }

    return '';
  };

  Writer.prototype._inverted = function (token, context, callback) {
    var value = context.lookup(token[1]);

    // Use JavaScript's definition of falsy. Include empty arrays.
    // See https://github.com/janl/mustache.js/issues/186
    if (!value || (isArray(value) && value.length === 0)) {
      return callback(this, context);
    }

    return '';
  };

  Writer.prototype._partial = function (token, context) {
    var name = token[1];

    if (!(name in this._partialCache) && this._loadPartial) {
      this.compilePartial(name, this._loadPartial(name));
    }

    var fn = this._partialCache[name];

    return fn ? fn(context) : '';
  };

  Writer.prototype._name = function (token, context) {
    var value = context.lookup(token[1]);
    return value == null ? '' : value;
  };

  Writer.prototype._escaped = function (token, context) {
    return exports.escape(this._name(token, context));
  };

  /**
   * Low-level function that compiles the given `tokens` into a function
   * that accepts three arguments: a Writer, a Context, and the template.
   */
  function compileTokens(tokens) {
    var subRenders = {};

    function subRender(i, tokens, template) {
      if (!subRenders[i]) {
        var fn = compileTokens(tokens);
        subRenders[i] = function (writer, context) {
          return fn(writer, context, template);
        };
      }

      return subRenders[i];
    }

    return function (writer, context, template) {
      var buffer = '';

      var token;
      for (var i = 0, len = tokens.length; i < len; ++i) {
        token = tokens[i];
        switch (token[0]) {
        case "#":
          buffer += writer._section(token, context, template, subRender(i, token[4], template));
          break;
        case "^":
          buffer += writer._inverted(token, context, subRender(i, token[4], template));
          break;
        case ">":
          buffer += writer._partial(token, context);
          break;
        case "&":
          buffer += writer._name(token, context);
          break;
        case "name":
          buffer += writer._escaped(token, context);
          break;
        case "text":
          buffer += token[1];
          break;
        }
      }

      return buffer;
    };
  }

  /**
   * Forms the given array of `tokens` into a nested tree structure where
   * tokens that represent a section have two additional items: 1) an array of
   * all tokens that appear in that section and 2) the index in the original
   * template that represents the end of that section.
   */
  function nestTokens(tokens) {
    var tree = [];
    var collector = tree;
    var sections = [];

    var token;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      switch (token[0]) {
      case '#':
      case '^':
        sections.push(token);
        collector.push(token);
        collector = token[4] = [];
        break;
      case '/':
        var section = sections.pop();
        section[5] = token[2];
        collector = sections.length > 0 ? sections[sections.length - 1][4] : tree;
        break;
      default:
        collector.push(token);
      }
    }

    return tree;
  }

  /**
   * Combines the values of consecutive text tokens in the given `tokens` array
   * to a single token.
   */
  function squashTokens(tokens) {
    var squashedTokens = [];

    var token, lastToken;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
        lastToken[1] += token[1];
        lastToken[3] = token[3];
      } else {
        lastToken = token;
        squashedTokens.push(token);
      }
    }

    return squashedTokens;
  }

  function escapeTags(tags) {
    return [
      new RegExp(escapeRe(tags[0]) + "\\s*"),
      new RegExp("\\s*" + escapeRe(tags[1]))
    ];
  }

  /**
   * Breaks up the given `template` string into a tree of token objects. If
   * `tags` is given here it must be an array with two string values: the
   * opening and closing tags used in the template (e.g. ["<%", "%>"]). Of
   * course, the default is to use mustaches (i.e. Mustache.tags).
   */
  exports.parse = function (template, tags) {
    template = template || '';
    tags = tags || exports.tags;

    if (typeof tags === 'string') tags = tags.split(spaceRe);
    if (tags.length !== 2) {
      throw new Error('Invalid tags: ' + tags.join(', '));
    }

    var tagRes = escapeTags(tags);
    var scanner = new Scanner(template);

    var sections = [];     // Stack to hold section tokens
    var tokens = [];       // Buffer to hold the tokens
    var spaces = [];       // Indices of whitespace tokens on the current line
    var hasTag = false;    // Is there a {{tag}} on the current line?
    var nonSpace = false;  // Is there a non-space char on the current line?

    // Strips all whitespace tokens array for the current line
    // if there was a {{#tag}} on it and otherwise only space.
    function stripSpace() {
      if (hasTag && !nonSpace) {
        while (spaces.length) {
          tokens.splice(spaces.pop(), 1);
        }
      } else {
        spaces = [];
      }

      hasTag = false;
      nonSpace = false;
    }

    var start, type, value, chr;
    while (!scanner.eos()) {
      start = scanner.pos;
      value = scanner.scanUntil(tagRes[0]);

      if (value) {
        for (var i = 0, len = value.length; i < len; ++i) {
          chr = value.charAt(i);

          if (isWhitespace(chr)) {
            spaces.push(tokens.length);
          } else {
            nonSpace = true;
          }

          tokens.push(["text", chr, start, start + 1]);
          start += 1;

          if (chr === "\n") {
            stripSpace(); // Check for whitespace on the current line.
          }
        }
      }

      start = scanner.pos;

      // Match the opening tag.
      if (!scanner.scan(tagRes[0])) {
        break;
      }

      hasTag = true;
      type = scanner.scan(tagRe) || "name";

      // Skip any whitespace between tag and value.
      scanner.scan(whiteRe);

      // Extract the tag value.
      if (type === "=") {
        value = scanner.scanUntil(eqRe);
        scanner.scan(eqRe);
        scanner.scanUntil(tagRes[1]);
      } else if (type === "{") {
        var closeRe = new RegExp("\\s*" + escapeRe("}" + tags[1]));
        value = scanner.scanUntil(closeRe);
        scanner.scan(curlyRe);
        scanner.scanUntil(tagRes[1]);
        type = "&";
      } else {
        value = scanner.scanUntil(tagRes[1]);
      }

      // Match the closing tag.
      if (!scanner.scan(tagRes[1])) {
        throw new Error('Unclosed tag at ' + scanner.pos);
      }

      // Check section nesting.
      if (type === '/') {
        if (sections.length === 0) {
          throw new Error('Unopened section "' + value + '" at ' + start);
        }

        var section = sections.pop();

        if (section[1] !== value) {
          throw new Error('Unclosed section "' + section[1] + '" at ' + start);
        }
      }

      var token = [type, value, start, scanner.pos];
      tokens.push(token);

      if (type === '#' || type === '^') {
        sections.push(token);
      } else if (type === "name" || type === "{" || type === "&") {
        nonSpace = true;
      } else if (type === "=") {
        // Set the tags for the next time around.
        tags = value.split(spaceRe);

        if (tags.length !== 2) {
          throw new Error('Invalid tags at ' + start + ': ' + tags.join(', '));
        }

        tagRes = escapeTags(tags);
      }
    }

    // Make sure there are no open sections when we're done.
    var section = sections.pop();
    if (section) {
      throw new Error('Unclosed section "' + section[1] + '" at ' + scanner.pos);
    }

    return nestTokens(squashTokens(tokens));
  };

  // The high-level clearCache, compile, compilePartial, and render functions
  // use this default writer.
  var _writer = new Writer();

  /**
   * Clears all cached templates and partials in the default writer.
   */
  exports.clearCache = function () {
    return _writer.clearCache();
  };

  /**
   * Compiles the given `template` to a reusable function using the default
   * writer.
   */
  exports.compile = function (template, tags) {
    return _writer.compile(template, tags);
  };

  /**
   * Compiles the partial with the given `name` and `template` to a reusable
   * function using the default writer.
   */
  exports.compilePartial = function (name, template, tags) {
    return _writer.compilePartial(name, template, tags);
  };

  /**
   * Compiles the given array of tokens (the output of a parse) to a reusable
   * function using the default writer.
   */
  exports.compileTokens = function (tokens, template) {
    return _writer.compileTokens(tokens, template);
  };

  /**
   * Renders the `template` with the given `view` and `partials` using the
   * default writer.
   */
  exports.render = function (template, view, partials) {
    return _writer.render(template, view, partials);
  };

  // This is here for backwards compatibility with 0.4.x.
  exports.to_html = function (template, view, partials, send) {
    var result = exports.render(template, view, partials);

    if (typeof send === "function") {
      send(result);
    } else {
      return result;
    }
  };

  return exports;

}())));
<commit_msg>Inline rendering functions<commit_after>/*!
 * mustache.js - Logic-less {{mustache}} templates with JavaScript
 * http://github.com/janl/mustache.js
 */

/*global define: false*/

(function (root, factory) {
  if (typeof exports === "object" && exports) {
    module.exports = factory; // CommonJS
  } else if (typeof define === "function" && define.amd) {
    define(factory); // AMD
  } else {
    root.Mustache = factory; // <script>
  }
}(this, (function () {

  var exports = {};

  exports.name = "mustache.js";
  exports.version = "0.7.2";
  exports.tags = ["{{", "}}"];

  exports.Scanner = Scanner;
  exports.Context = Context;
  exports.Writer = Writer;

  var whiteRe = /\s*/;
  var spaceRe = /\s+/;
  var nonSpaceRe = /\S/;
  var eqRe = /\s*=/;
  var curlyRe = /\s*\}/;
  var tagRe = /#|\^|\/|>|\{|&|=|!/;

  // Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
  // See https://github.com/janl/mustache.js/issues/189
  function testRe(re, string) {
    return RegExp.prototype.test.call(re, string);
  }

  function isWhitespace(string) {
    return !testRe(nonSpaceRe, string);
  }

  var isArray = Array.isArray || function (obj) {
    return Object.prototype.toString.call(obj) === "[object Array]";
  };

  function escapeRe(string) {
    return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
  }

  var entityMap = {
    "&": "&",
    "<": "<",
    ">": ">",
    '"': '"',
    "'": ''',
    "/": '/'
  };

  function escapeHtml(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
      return entityMap[s];
    });
  }

  // Export the escaping function so that the user may override it.
  // See https://github.com/janl/mustache.js/issues/244
  exports.escape = escapeHtml;

  function Scanner(string) {
    this.string = string;
    this.tail = string;
    this.pos = 0;
  }

  /**
   * Returns `true` if the tail is empty (end of string).
   */
  Scanner.prototype.eos = function () {
    return this.tail === "";
  };

  /**
   * Tries to match the given regular expression at the current position.
   * Returns the matched text if it can match, the empty string otherwise.
   */
  Scanner.prototype.scan = function (re) {
    var match = this.tail.match(re);

    if (match && match.index === 0) {
      this.tail = this.tail.substring(match[0].length);
      this.pos += match[0].length;
      return match[0];
    }

    return "";
  };

  /**
   * Skips all text until the given regular expression can be matched. Returns
   * the skipped string, which is the entire tail if no match can be made.
   */
  Scanner.prototype.scanUntil = function (re) {
    var match, pos = this.tail.search(re);

    switch (pos) {
    case -1:
      match = this.tail;
      this.pos += this.tail.length;
      this.tail = "";
      break;
    case 0:
      match = "";
      break;
    default:
      match = this.tail.substring(0, pos);
      this.tail = this.tail.substring(pos);
      this.pos += pos;
    }

    return match;
  };

  function Context(view, parent) {
    this.view = view;
    this.parent = parent;
    this.clearCache();
  }

  Context.make = function (view) {
    return (view instanceof Context) ? view : new Context(view);
  };

  Context.prototype.clearCache = function () {
    this._cache = {};
  };

  Context.prototype.push = function (view) {
    return new Context(view, this);
  };

  Context.prototype.lookup = function (name) {
    var value = this._cache[name];

    if (!value) {
      if (name === ".") {
        value = this.view;
      } else {
        var context = this;

        while (context) {
          if (name.indexOf(".") > 0) {
            var names = name.split("."), i = 0;

            value = context.view;

            while (value && i < names.length) {
              value = value[names[i++]];
            }
          } else {
            value = context.view[name];
          }

          if (value != null) break;

          context = context.parent;
        }
      }

      this._cache[name] = value;
    }

    if (typeof value === 'function') value = value.call(this.view);

    return value;
  };

  function Writer() {
    this.clearCache();
  }

  Writer.prototype.clearCache = function () {
    this._cache = {};
    this._partialCache = {};
  };

  Writer.prototype.compile = function (template, tags) {
    var fn = this._cache[template];

    if (!fn) {
      var tokens = exports.parse(template, tags);
      fn = this._cache[template] = this.compileTokens(tokens, template);
    }

    return fn;
  };

  Writer.prototype.compilePartial = function (name, template, tags) {
    var fn = this.compile(template, tags);
    this._partialCache[name] = fn;
    return fn;
  };

  Writer.prototype.getPartial = function (name) {
    if (!(name in this._partialCache) && this._loadPartial) {
      this.compilePartial(name, this._loadPartial(name));
    }

    return this._partialCache[name];
  };

  Writer.prototype.compileTokens = function (tokens, template) {
    var self = this;
    return function (view, partials) {
      if (partials) {
        if (typeof partials === 'function') {
          self._loadPartial = partials;
        } else {
          for (var name in partials) {
            self.compilePartial(name, partials[name]);
          }
        }
      }

      return renderTokens(tokens, self, Context.make(view), template);
    };
  };

  Writer.prototype.render = function (template, view, partials) {
    return this.compile(template)(view, partials);
  };

  /**
   * Low-level function that renders the given `tokens` using the given `writer`
   * and `context`. The `template` string is only needed for templates that use
   * higher-order sections to extract the portion of the original template that
   * was contained in that section.
   */
  function renderTokens(tokens, writer, context, template) {
    var buffer = '';

    var token, tokenValue, value;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      tokenValue = token[1];

      switch (token[0]) {
      case '#':
        value = context.lookup(tokenValue);

        if (typeof value === 'object') {
          if (isArray(value)) {
            for (var j = 0, jlen = value.length; j < jlen; ++j) {
              buffer += renderTokens(token[4], writer, context.push(value[j]), template);
            }
          } else if (value) {
            buffer += renderTokens(token[4], writer, context.push(value), template);
          }
        } else if (typeof value === 'function') {
          var text = template == null ? null : template.slice(token[3], token[5]);
          var result = value.call(context.view, text, function (template) {
            return writer.render(template, context);
          });
          if (result != null) buffer += result;
        } else if (value) {
          buffer += renderTokens(token[4], writer, context, template);
        }

        break;
      case '^':
        value = context.lookup(tokenValue);

        // Use JavaScript's definition of falsy. Include empty arrays.
        // See https://github.com/janl/mustache.js/issues/186
        if (!value || (isArray(value) && value.length === 0)) {
          buffer += renderTokens(token[4], writer, context, template);
        }

        break;
      case '>':
        value = writer.getPartial(tokenValue);
        if (typeof value === 'function') buffer += value(context);
        break;
      case '&':
        value = context.lookup(tokenValue);
        if (value != null) buffer += value;
        break;
      case 'name':
        value = context.lookup(tokenValue);
        if (value != null) buffer += exports.escape(value);
        break;
      case 'text':
        buffer += tokenValue;
        break;
      }
    }

    return buffer;
  }

  /**
   * Forms the given array of `tokens` into a nested tree structure where
   * tokens that represent a section have two additional items: 1) an array of
   * all tokens that appear in that section and 2) the index in the original
   * template that represents the end of that section.
   */
  function nestTokens(tokens) {
    var tree = [];
    var collector = tree;
    var sections = [];

    var token;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      switch (token[0]) {
      case '#':
      case '^':
        sections.push(token);
        collector.push(token);
        collector = token[4] = [];
        break;
      case '/':
        var section = sections.pop();
        section[5] = token[2];
        collector = sections.length > 0 ? sections[sections.length - 1][4] : tree;
        break;
      default:
        collector.push(token);
      }
    }

    return tree;
  }

  /**
   * Combines the values of consecutive text tokens in the given `tokens` array
   * to a single token.
   */
  function squashTokens(tokens) {
    var squashedTokens = [];

    var token, lastToken;
    for (var i = 0, len = tokens.length; i < len; ++i) {
      token = tokens[i];
      if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
        lastToken[1] += token[1];
        lastToken[3] = token[3];
      } else {
        lastToken = token;
        squashedTokens.push(token);
      }
    }

    return squashedTokens;
  }

  function escapeTags(tags) {
    return [
      new RegExp(escapeRe(tags[0]) + "\\s*"),
      new RegExp("\\s*" + escapeRe(tags[1]))
    ];
  }

  /**
   * Breaks up the given `template` string into a tree of token objects. If
   * `tags` is given here it must be an array with two string values: the
   * opening and closing tags used in the template (e.g. ["<%", "%>"]). Of
   * course, the default is to use mustaches (i.e. Mustache.tags).
   */
  exports.parse = function (template, tags) {
    template = template || '';
    tags = tags || exports.tags;

    if (typeof tags === 'string') tags = tags.split(spaceRe);
    if (tags.length !== 2) {
      throw new Error('Invalid tags: ' + tags.join(', '));
    }

    var tagRes = escapeTags(tags);
    var scanner = new Scanner(template);

    var sections = [];     // Stack to hold section tokens
    var tokens = [];       // Buffer to hold the tokens
    var spaces = [];       // Indices of whitespace tokens on the current line
    var hasTag = false;    // Is there a {{tag}} on the current line?
    var nonSpace = false;  // Is there a non-space char on the current line?

    // Strips all whitespace tokens array for the current line
    // if there was a {{#tag}} on it and otherwise only space.
    function stripSpace() {
      if (hasTag && !nonSpace) {
        while (spaces.length) {
          tokens.splice(spaces.pop(), 1);
        }
      } else {
        spaces = [];
      }

      hasTag = false;
      nonSpace = false;
    }

    var start, type, value, chr;
    while (!scanner.eos()) {
      start = scanner.pos;
      value = scanner.scanUntil(tagRes[0]);

      if (value) {
        for (var i = 0, len = value.length; i < len; ++i) {
          chr = value.charAt(i);

          if (isWhitespace(chr)) {
            spaces.push(tokens.length);
          } else {
            nonSpace = true;
          }

          tokens.push(["text", chr, start, start + 1]);
          start += 1;

          if (chr === "\n") {
            stripSpace(); // Check for whitespace on the current line.
          }
        }
      }

      start = scanner.pos;

      // Match the opening tag.
      if (!scanner.scan(tagRes[0])) {
        break;
      }

      hasTag = true;
      type = scanner.scan(tagRe) || "name";

      // Skip any whitespace between tag and value.
      scanner.scan(whiteRe);

      // Extract the tag value.
      if (type === "=") {
        value = scanner.scanUntil(eqRe);
        scanner.scan(eqRe);
        scanner.scanUntil(tagRes[1]);
      } else if (type === "{") {
        var closeRe = new RegExp("\\s*" + escapeRe("}" + tags[1]));
        value = scanner.scanUntil(closeRe);
        scanner.scan(curlyRe);
        scanner.scanUntil(tagRes[1]);
        type = "&";
      } else {
        value = scanner.scanUntil(tagRes[1]);
      }

      // Match the closing tag.
      if (!scanner.scan(tagRes[1])) {
        throw new Error('Unclosed tag at ' + scanner.pos);
      }

      // Check section nesting.
      if (type === '/') {
        if (sections.length === 0) {
          throw new Error('Unopened section "' + value + '" at ' + start);
        }

        var section = sections.pop();

        if (section[1] !== value) {
          throw new Error('Unclosed section "' + section[1] + '" at ' + start);
        }
      }

      var token = [type, value, start, scanner.pos];
      tokens.push(token);

      if (type === '#' || type === '^') {
        sections.push(token);
      } else if (type === "name" || type === "{" || type === "&") {
        nonSpace = true;
      } else if (type === "=") {
        // Set the tags for the next time around.
        tags = value.split(spaceRe);

        if (tags.length !== 2) {
          throw new Error('Invalid tags at ' + start + ': ' + tags.join(', '));
        }

        tagRes = escapeTags(tags);
      }
    }

    // Make sure there are no open sections when we're done.
    var section = sections.pop();
    if (section) {
      throw new Error('Unclosed section "' + section[1] + '" at ' + scanner.pos);
    }

    return nestTokens(squashTokens(tokens));
  };

  // All Mustache.* functions use this writer.
  var _writer = new Writer();

  /**
   * Clears all cached templates and partials in the default writer.
   */
  exports.clearCache = function () {
    return _writer.clearCache();
  };

  /**
   * Compiles the given `template` to a reusable function using the default
   * writer.
   */
  exports.compile = function (template, tags) {
    return _writer.compile(template, tags);
  };

  /**
   * Compiles the partial with the given `name` and `template` to a reusable
   * function using the default writer.
   */
  exports.compilePartial = function (name, template, tags) {
    return _writer.compilePartial(name, template, tags);
  };

  /**
   * Compiles the given array of tokens (the output of a parse) to a reusable
   * function using the default writer.
   */
  exports.compileTokens = function (tokens, template) {
    return _writer.compileTokens(tokens, template);
  };

  /**
   * Renders the `template` with the given `view` and `partials` using the
   * default writer.
   */
  exports.render = function (template, view, partials) {
    return _writer.render(template, view, partials);
  };

  // This is here for backwards compatibility with 0.4.x.
  exports.to_html = function (template, view, partials, send) {
    var result = exports.render(template, view, partials);

    if (typeof send === "function") {
      send(result);
    } else {
      return result;
    }
  };

  return exports;

}())));
<|endoftext|>


<commit_before>var passwordMenuId;

function contextFunction(info, tab) {
	chrome.tabs.sendRequest(tab.id, {}, function(response){
		selectedElement = response.dom_element;
		console.log(selectedElement);
	});
};

chrome.extension.onConnect.addListener(function(port) {
	console.assert(port.name === "passhalf");
	port.onMessage.addListener(handleMessages);
});

function handleMessages(msg) {
	if(msg.password == true) {
		passwordMenuId = chrome.contextMenus.create(
			{"title": "Setup a half-life password",
			 "contexts": ["all"],
			 "onclick": contextFunction});
		console.log(msg.passId + " " + msg.formId);
	} else if(passwordMenuId) {
		chrome.contextMenus.remove(passwordMenuId);
		passwordMenuId = null;
	}
}

<commit_msg>Correctly getting information in context function<commit_after>// Declarations
var passwordMenuId, formId, passId;

function contextFunction(info, tab) {
	console.log(formId + " " + passId);
};

function handleMessages(msg) {
	if(msg.password == true) {
		passwordMenuId = chrome.contextMenus.create(
			{"title": "Setup a half-life password",
			 "contexts": ["all"],
			 "onclick": contextFunction});
		formId = msg.formId;
		passId = msg.passId;
		//console.log(msg.passId + " " + msg.formId);
	} else if(passwordMenuId) {
		chrome.contextMenus.remove(passwordMenuId);
		passwordMenuId = null;
	}
}

// Scripting
chrome.extension.onConnect.addListener(function(port) {
	console.assert(port.name === "passhalf");
	port.onMessage.addListener(handleMessages);
});

<|endoftext|>