<commit_before>// @ts-check
import { Mode1UpLit } from './Mode1UpLit.js';
/** @typedef {import('../BookReader.js').default} BookReader */
/** @typedef {import('./BookModel.js').BookModel} BookModel */
/** @typedef {import('./BookModel.js').PageIndex} PageIndex */

export class Mode1Up {
  /**
   * @param {BookReader} br
   * @param {BookModel} bookModel
   */
  constructor(br, bookModel) {
    this.br = br;
    this.book = bookModel;
    this.mode1UpLit = new Mode1UpLit(bookModel, br);

    /** @private */
    this.$el = $(this.mode1UpLit).addClass('br-mode-1up BRmode1up');

    this.everShown = false;
  }

  // TODO: Might not need this anymore? Might want to delete.
  /** @private */
  get $brContainer() { return this.br.refs.$brContainer; }

  /**
   * This is called when we switch to one page view
   */
  prepare() {
    const startLeaf = this.br.currentIndex();
    this.$brContainer
      .empty()
      .css({ overflow: 'hidden' })
      .append(this.$el);

    setTimeout(async () => {
      if (!this.everShown) {
        this.mode1UpLit.initFirstRender(startLeaf);
        this.everShown = true;
        await this.mode1UpLit.requestUpdate();
      }
      this.mode1UpLit.jumpToIndex(startLeaf);
    });
    this.br.updateBrClasses();
  }

  /**
   * BREAKING CHANGE: No longer supports pageX/pageY
   * @param {PageIndex} index
   * @param {number} [pageX] x position on the page (in pixels) to center on
   * @param {number} [pageY] y position on the page (in pixels) to center on
   * @param {boolean} [noAnimate]
   */
  jumpToIndex(index, pageX, pageY, noAnimate) {
    // Only smooth for small distances
    const distance = Math.abs(this.br.currentIndex() - index);
    const smooth = !noAnimate && distance <= 4;
    this.mode1UpLit.jumpToIndex(index, { smooth });
  }

  /**
   * @param {'in' | 'out'} direction
   */
  zoom(direction) {
    if (direction == 'in') this.mode1UpLit.zoomIn();
    else this.mode1UpLit.zoomOut();
  }

  /**
   * Resize the current one page view
   * Note this calls drawLeafs
   */
  resizePageView() {
    this.mode1UpLit.htmlDimensionsCacher.updateClientSizes();
    this.mode1UpLit.requestUpdate();
  }
}
<commit_msg>[Mode1UpLit] Make Mode1Up drag-scrollable again<commit_after>// @ts-check
import '../dragscrollable-br.js';
import { Mode1UpLit } from './Mode1UpLit.js';
/** @typedef {import('../BookReader.js').default} BookReader */
/** @typedef {import('./BookModel.js').BookModel} BookModel */
/** @typedef {import('./BookModel.js').PageIndex} PageIndex */

export class Mode1Up {
  /**
   * @param {BookReader} br
   * @param {BookModel} bookModel
   */
  constructor(br, bookModel) {
    this.br = br;
    this.book = bookModel;
    this.mode1UpLit = new Mode1UpLit(bookModel, br);

    /** @private */
    this.$el = $(this.mode1UpLit).addClass('br-mode-1up BRmode1up');

    this.everShown = false;
  }

  // TODO: Might not need this anymore? Might want to delete.
  /** @private */
  get $brContainer() { return this.br.refs.$brContainer; }

  /**
   * This is called when we switch to one page view
   */
  prepare() {
    const startLeaf = this.br.currentIndex();
    this.$brContainer
      .empty()
      .css({ overflow: 'hidden' })
      .append(this.$el);

    setTimeout(async () => {
      if (!this.everShown) {
        this.mode1UpLit.initFirstRender(startLeaf);
        this.everShown = true;
        await this.mode1UpLit.requestUpdate();
        $(this.mode1UpLit).dragscrollable({
          preventDefault: true,
          dragSelector: '.br-mode-1up__visible-world',
          // Only handle mouse events; let browser/HammerJS handle touch
          dragstart: 'mousedown',
          dragcontinue: 'mousemove',
          dragend: 'mouseup',
        });
      }
      this.mode1UpLit.jumpToIndex(startLeaf);
    });
    this.br.updateBrClasses();
  }

  /**
   * BREAKING CHANGE: No longer supports pageX/pageY
   * @param {PageIndex} index
   * @param {number} [pageX] x position on the page (in pixels) to center on
   * @param {number} [pageY] y position on the page (in pixels) to center on
   * @param {boolean} [noAnimate]
   */
  jumpToIndex(index, pageX, pageY, noAnimate) {
    // Only smooth for small distances
    const distance = Math.abs(this.br.currentIndex() - index);
    const smooth = !noAnimate && distance <= 4;
    this.mode1UpLit.jumpToIndex(index, { smooth });
  }

  /**
   * @param {'in' | 'out'} direction
   */
  zoom(direction) {
    if (direction == 'in') this.mode1UpLit.zoomIn();
    else this.mode1UpLit.zoomOut();
  }

  /**
   * Resize the current one page view
   * Note this calls drawLeafs
   */
  resizePageView() {
    this.mode1UpLit.htmlDimensionsCacher.updateClientSizes();
    this.mode1UpLit.requestUpdate();
  }
}
<|endoftext|>


<commit_before>//
//   Copyright 2009-2015 Ilkka Oksanen <iao@iki.fi>
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing,
//   software distributed under the License is distributed on an "AS
//   IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
//   express or implied.  See the License for the specific language
//   governing permissions and limitations under the License.
//

import Cookies from 'npm:js-cookie';
import Store from './base';
import { calcMsgHistorySize } from '../utils/msg-history-sizer';
import User from '../models/user';
import IndexArray from '../utils/index-array';

const UsersStore = Store.extend({
  users: IndexArray.create({ index: 'userId', factory: User }),
  isDirty: 0,
  userId: null,

  init() {
    try {
      // TODO: Should read this from initok request but that's too late
      this.userId = `m${JSON.parse(window.atob(Cookies.get('mas'))).userId}`;
    } catch (e) {
      this.userId = null;
    }

    this._super();
  },

  toJSON() {
    const data = {
      version: 4,
      users: {},
      userId: this.get('userId')
    };

    // Only persist users of recent messages
    window.stores.windows.get('windows').forEach(masWindow => {
      const sortedMessages = masWindow
        .get('messages')
        .sortBy('gid')
        .slice(-1 * calcMsgHistorySize());

      sortedMessages.forEach(message => {
        const userId = message.get('userId');

        if (userId) {
          data.users[userId] = true;
        }
      });
    });

    // Always save user itself
    data.users[this.get('userId')] = true;

    Object.keys(data.users).forEach(function(userId) {
      const user = this.get('users').getByIndex(userId);
      data.users[userId] = user.getProperties(['userId', 'name', 'nick', 'gravatar']);
    });

    return data;
  },

  fromJSON(data) {
    if (data.userId !== this.get('userId') || data.version !== 4) {
      return;
    }

    Object.keys(data.users).forEach(function(userId) {
      this.get('users').upsertModel(data.users[userId]);
    });

    this.incrementProperty('isDirty');
  },

  handleAddUsersServer(data) {
    Object.keys(data.mapping).forEach(function(userId) {
      const user = data.mapping[userId];
      user.userId = userId;

      this.get('users').upsertModel(user);
    });

    this.incrementProperty('isDirty');
  }
});

window.stores = window.stores || {};
window.stores.users = UsersStore.create();
<commit_msg>Fix context in loops<commit_after>//
//   Copyright 2009-2015 Ilkka Oksanen <iao@iki.fi>
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing,
//   software distributed under the License is distributed on an "AS
//   IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
//   express or implied.  See the License for the specific language
//   governing permissions and limitations under the License.
//

import Cookies from 'npm:js-cookie';
import Store from './base';
import { calcMsgHistorySize } from '../utils/msg-history-sizer';
import User from '../models/user';
import IndexArray from '../utils/index-array';

const UsersStore = Store.extend({
  users: IndexArray.create({ index: 'userId', factory: User }),
  isDirty: 0,
  userId: null,

  init() {
    try {
      // TODO: Should read this from initok request but that's too late
      this.userId = `m${JSON.parse(window.atob(Cookies.get('mas'))).userId}`;
    } catch (e) {
      this.userId = null;
    }

    this._super();
  },

  toJSON() {
    const data = {
      version: 4,
      users: {},
      userId: this.get('userId')
    };

    // Only persist users of recent messages
    window.stores.windows.get('windows').forEach(masWindow => {
      const sortedMessages = masWindow
        .get('messages')
        .sortBy('gid')
        .slice(-1 * calcMsgHistorySize());

      sortedMessages.forEach(message => {
        const userId = message.get('userId');

        if (userId) {
          data.users[userId] = true;
        }
      });
    });

    // Always save user itself
    data.users[this.get('userId')] = true;

    Object.keys(data.users).forEach(userId => {
      const user = this.get('users').getByIndex(userId);
      data.users[userId] = user.getProperties(['userId', 'name', 'nick', 'gravatar']);
    });

    return data;
  },

  fromJSON(data) {
    if (data.userId !== this.get('userId') || data.version !== 4) {
      return;
    }

    Object.keys(data.users).forEach(userId => {
      this.get('users').upsertModel(data.users[userId]);
    });

    this.incrementProperty('isDirty');
  },

  handleAddUsersServer(data) {
    Object.keys(data.mapping).forEach(userId => {
      const user = data.mapping[userId];
      user.userId = userId;

      this.get('users').upsertModel(user);
    });

    this.incrementProperty('isDirty');
  }
});

window.stores = window.stores || {};
window.stores.users = UsersStore.create();
<|endoftext|>


<commit_before>(function () {
  app.views.Player = app.views.View.extend({

    name : 'player',

    className : 'player-view well',

    events: {
      'change .samples' : 'handleSampleChange',
      'click .play-button' : 'handlePlayPause',
      'click .hide-button' : 'handleHide'
    },

    initialize: function ( options ) {
      this.packageView = options.packageView;
      this.context = options.context;

      this.packageView.on( 'activate:demo', this.selectPackage, this );

      this.$el.data( 'hidden', true );
      this.render();

      this.currentSample = 'vox';
      this.$play = this.$el.find( '.play-button' );
      this.$module = this.$el.find( '.module' );
      this.$samples = this.$el.find( '.samples' );
    },

    selectPackage : function ( pkg ) {
      this.package = pkg;
      this.loadPackage();
    },

    // Package

    loadPackage : function () {
      var that = this;

      if ( this.$el.data('hidden') ) {
        this.showPlayer();
      }

      this.showLoading();

      require(['/packages/' + this.package.get( 'name' ) + '/script.js'], function ( module ) {
        that.module = new module( that.context );
        that.packageLoaded();
        that.module.connect( that.context.destination );
        that.createControlView( that.module );
      });
    },

    packageLoaded : function () {
      if ( this.source ) {
        this.source.connect( this.module.input );
      }
      this.hideLoading();
    },

    createControlView : function ( module ) {
      this.moduleControlView = new app.views.ModuleControl({
        module: this.module,
        context: this.context
      });
      this.$module.html( this.moduleControlView.$el );
    },

    // Sample

    loadSample : function ( sample ) {
      var that = this;

      this.showLoading();
      this.removeSample();

      this.source = this.context.createBufferSource();
      allen.getBuffer( 'samples/' + sample + '.mp3', function ( xhr ) {
        that.loadedSample( xhr.target.response );
      });
    },

    loadedSample : function ( buffer ) {
      this.source.buffer = this.context.createBuffer( buffer, false );
      if ( this.module ) {
        this.source.connect( this.module.input );
        this.source.noteOn( 0 );
      }
      this.hideLoading();
    },

    removeSample : function () {
      if ( this.source && this.source.disconnect ) {
        this.source.disconnect();
      }
      this.stopSample();
    },

    playSample : function () {
      this.loadSample( this.currentSample );
      this.$play.data( 'playing', true )
        .find('i')
          .removeClass( 'icon-play' )
          .addClass( 'icon-pause' );
    },

    stopSample : function () {
      this.$play.data( 'playing', false )
        .find('i')
          .addClass( 'icon-play' )
          .removeClass( 'icon-pause' );
      if ( this.source && this.source.noteOff ) {
        this.source.noteOff( 0 );
      }
    },

    showPlayer : function () {
      this.$el.animate({ 'margin-bottom' : '0px' });
      this.$el.data('hidden', false);
    },

    hidePlayer : function () {
      this.$el.animate({ 'margin-bottom' : '-150px' });
      this.$el.data('hidden', true);
    },

    // Loading GUI

    showLoading : function () {
      this.$el
        .find('.player-loading').show().end()
        .find('select, a').prop('disabled', true)
          .addClass('disabled');
    },

    hideLoading : function () {
      this.$el
        .find('.player-loading').hide().end()
        .find('select, a').prop('disabled', false)
          .removeClass('disabled');
    },

    // Event handlers

    handlePlayPause : function ( e ) {
      e.preventDefault();

      // Abort if button has class disabled
      if ( this.$play.hasClass('disabled') ) {
        return;
      }

      if ( this.$play.data( 'playing' ) ) {
        this.stopSample();
      } else {
        this.playSample();
      }
    },

    handleHide : function ( e ) {
      e.preventDefault();
      this.stopSample();
      this.hide();
    },

    handleSampleChange : function () {
      this.stopSample();
      this.currentSample = this.$samples.find(':selected').val();
    }

  });
})();
<commit_msg>Safely destroy moduleControlViews when creating new ones<commit_after>(function () {
  app.views.Player = app.views.View.extend({

    name : 'player',

    className : 'player-view well',

    events: {
      'change .samples' : 'handleSampleChange',
      'click .play-button' : 'handlePlayPause',
      'click .hide-button' : 'handleHide'
    },

    initialize: function ( options ) {
      this.packageView = options.packageView;
      this.context = options.context;

      this.packageView.on( 'activate:demo', this.selectPackage, this );

      this.$el.data( 'hidden', true );
      this.render();

      this.currentSample = 'vox';
      this.$play = this.$el.find( '.play-button' );
      this.$module = this.$el.find( '.module' );
      this.$samples = this.$el.find( '.samples' );
    },

    selectPackage : function ( pkg ) {
      this.package = pkg;
      this.loadPackage();
    },

    // Package

    loadPackage : function () {
      var that = this;

      if ( this.$el.data('hidden') ) {
        this.showPlayer();
      }

      this.showLoading();

      require(['/packages/' + this.package.get( 'name' ) + '/script.js'], function ( module ) {
        that.module = new module( that.context );
        that.packageLoaded();
        that.module.connect( that.context.destination );
        that.createControlView( that.module );
      });
    },

    packageLoaded : function () {
      if ( this.source ) {
        this.source.connect( this.module.input );
      }
      this.hideLoading();
    },

    createControlView : function ( module ) {

      // If a moduleControlView already exists,
      // remove it properly
      if ( this.moduleControlView ) {
        this.moduleControlView.remove();
      }

      this.moduleControlView = new app.views.ModuleControl({
        module: this.module,
        context: this.context
      });

      this.$module.html( this.moduleControlView.$el );
    },

    // Sample

    loadSample : function ( sample ) {
      var that = this;

      this.showLoading();
      this.removeSample();

      this.source = this.context.createBufferSource();
      allen.getBuffer( 'samples/' + sample + '.mp3', function ( xhr ) {
        that.loadedSample( xhr.target.response );
      });
    },

    loadedSample : function ( buffer ) {
      this.source.buffer = this.context.createBuffer( buffer, false );
      if ( this.module ) {
        this.source.connect( this.module.input );
        this.source.noteOn( 0 );
      }
      this.hideLoading();
    },

    removeSample : function () {
      if ( this.source && this.source.disconnect ) {
        this.source.disconnect();
      }
      this.stopSample();
    },

    playSample : function () {
      this.loadSample( this.currentSample );
      this.$play.data( 'playing', true )
        .find('i')
          .removeClass( 'icon-play' )
          .addClass( 'icon-pause' );
    },

    stopSample : function () {
      this.$play.data( 'playing', false )
        .find('i')
          .addClass( 'icon-play' )
          .removeClass( 'icon-pause' );
      if ( this.source && this.source.noteOff ) {
        this.source.noteOff( 0 );
      }
    },

    showPlayer : function () {
      this.$el.animate({ 'margin-bottom' : '0px' });
      this.$el.data('hidden', false);
    },

    hidePlayer : function () {
      this.$el.animate({ 'margin-bottom' : '-150px' });
      this.$el.data('hidden', true);
    },

    // Loading GUI

    showLoading : function () {
      this.$el
        .find('.player-loading').show().end()
        .find('select, a').prop('disabled', true)
          .addClass('disabled');
    },

    hideLoading : function () {
      this.$el
        .find('.player-loading').hide().end()
        .find('select, a').prop('disabled', false)
          .removeClass('disabled');
    },

    // Event handlers

    handlePlayPause : function ( e ) {
      e.preventDefault();

      // Abort if button has class disabled
      if ( this.$play.hasClass('disabled') ) {
        return;
      }

      if ( this.$play.data( 'playing' ) ) {
        this.stopSample();
      } else {
        this.playSample();
      }
    },

    handleHide : function ( e ) {
      e.preventDefault();
      this.stopSample();
      this.hide();
    },

    handleSampleChange : function () {
      this.stopSample();
      this.currentSample = this.$samples.find(':selected').val();
    }

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


<commit_before>var readJson = require('./readJson')
var Promise = require("bluebird")
var _ = require('lodash')

// get info.json
// for each list in file['info'],
	// check ['hash'] against the db's hash
		// if it matches, return.
		// else, request the file from ['path'],
			// delete the pervious data.
			// and store the new data in the database

var pathPrefix = '/data/'

function deleteItems(items) {
	// console.log('items to delete', items)
	// TODO: Delete items.
}

function storeItem(item) {
	console.log('storeItem', item)
	if (item.type === 'courses') {
		_.map(item.data.courses, function(course) {
			course.sourcePath = item.meta.path
			// window.server.courses.add(course).done(function(){console.log('a course has been added')})
		})
		window.server.courses.add.apply(window.server, item.data.courses).done(function() {
			console.log('courses have been added')
		})
	}
	if (item.type === 'areas') {
		item.data.info.sourcePath = item.meta.path
		return window.server.areas.add.apply(window.server, item.data.info).done(function(results) {
			console.log('an area has been added')
		})
	}
}

function cleanPriorData(item) {
	return new Promise(function(resolve, reject) {
		var path = item.meta.path
		var hash = item.meta.hash

		// Clear out old courses ...
		window.server.courses.query('sourcePath')
			.only(path)
			.execute()
			.done(deleteItems)

		// ... areas of study ...
		window.server.areas.query('sourcePath')
			.only(path)
			.execute()
			.done(deleteItems)

		// ... and the paths themselves.
		window.server.sources.query('path')
			.only(path)
			.execute()
			.done(function(results) {
				// console.log(results)
				// window.server.sources.remove.apply()
			})

		window.server.sources.add(item.meta).done()

		resolve(item)
	})
}

function getInfoFromDb(sourcePath) {
	// console.log('getItemFromDb', sourcePath)
	return new Promise(function(resolve, reject) {
		window.server.sources.query('path')
			.only(sourcePath)
			.execute()
			.done(function(data) {
				if (data.length > 0)
					resolve(data[0])
				else
					resolve()
			})
	})
}

function updateDatabase(itemType, infoFromJson) {
	infoFromJson.path = '/data/' + itemType + '/' + infoFromJson.path
	return getInfoFromDb(infoFromJson.path).then(function(infoFromDb) {
		if (_.contains(infoFromDb, 'hash') && infoFromJson.hash === infoFromDb.hash) {
			console.log('bypassed adding', infoFromDb.path)
			return;
		} else {
			console.log('have to add', infoFromJson.path)
			return readJson(infoFromJson.path)
				.then(function(data) {
					return { data: data, meta: infoFromJson, type: itemType }
				})
				.then(cleanPriorData)
				.then(storeItem)
				.catch(function(err) {
					console.error('adding error', err)
				})
				.done()
		}
	}).catch(function(err) {
		console.error('updataDatabase error', err)
	})
}

function loadDataFiles(info) {
	console.log('loadDataFiles', info)
	return new Promise.all(_.map(info.info, function(files) {
		return new Promise.all(_.map(files, function(file) {
			// console.log('loadDataFiles.Q.all', file)
			return updateDatabase(info.type, file)
		}))
	}))
}

function loadInfoFile(url) {
	console.log('loading', url)
	readJson(url)
		.then(loadDataFiles)
		.done()
}

function loadData() {
	var infoFiles = [
		'/data/areas/info.json',
		'/data/courses/info.json',
	]
	return new Promise.all(_.map(infoFiles, loadInfoFile))
}

module.exports = loadData
<commit_msg>loadData – Take 3<commit_after>var readJson = require('./readJson')
var Promise = require("bluebird")
var _ = require('lodash')

// get info.json
// for each list in file['info'],
	// check ['hash'] against the db's hash
		// if it matches, return.
		// else, request the file from ['path'],
			// delete the pervious data.
			// and store the new data in the database

var pathPrefix = '/data/'

function deleteItems(items) {
	// console.log('items to delete', items)
	// TODO: Delete items.
}

function storeItem(item) {
	if (item.type === 'courses') {
		_.map(item.data.courses, function(course) {
			course.sourcePath = item.meta.path
			// window.server.courses.add(course).done(function(){console.log('a course has been added')})
		})
		window.server.courses.add.apply(window.server, item.data.courses).done(function() {
			console.log('courses have been added')
		})
	}
	if (item.type === 'areas') {
		item.data.info.sourcePath = item.meta.path
		return window.server.areas.add(item.data.info).done(function(results) {
			console.log('an area has been added')
		})
	}
}

function cleanPriorData(item) {
	return new Promise(function(resolve, reject) {
		var path = item.meta.path
		var hash = item.meta.hash

		// Clear out old courses ...
		window.server.courses.query('sourcePath')
			.only(path)
			.execute()
			.done(deleteItems)

		// ... areas of study ...
		window.server.areas.query('sourcePath')
			.only(path)
			.execute()
			.done(deleteItems)

		// ... and the paths themselves.
		localStorage.removeItem(path)
		localStorage.setItem(path, hash)

		resolve(item)
	})
}

function getInfoFromDb(sourcePath) {
	// console.log('getItemFromDb', sourcePath)
	return new Promise(function(resolve, reject) {
		window.server.sources.query('path')
			.only(sourcePath)
			.execute()
			.done(function(data) {
				if (data.length > 0)
					resolve(data[0])
				else
					resolve()
			})
	})
}

function updateDatabase(itemType, infoFromServer) {
	infoFromServer.path = '/data/' + itemType + '/' + infoFromServer.path
	var oldHash = localStorage.getItem(infoFromServer.path)
	var newHash = infoFromServer.hash
	var itemPath = infoFromServer.path
	return new Promise(function(resolve, reject) {
		if (newHash !== oldHash) {
			console.log('have to add', itemPath)
			readJson(itemPath)
				.then(function(data) {return {data: data, meta: infoFromServer, type: itemType}})
				.then(cleanPriorData)
				.then(storeItem)
				.catch(function(err) {
					reject('adding error')
				})
				.done(function(){resolve('had to add ' + itemPath)})
		} else {
			resolve('bypassed adding ' + itemPath)
		}
	})
}

function loadDataFiles(info) {
	console.log('loadDataFiles', info)
	return new Promise.all(_.map(info.info, function(files) {
		return new Promise.all(_.map(files, function(file) {
			// console.log('loadDataFiles.Q.all', file)
			return updateDatabase(info.type, file)
		}))
	}))
}

function loadInfoFile(url) {
	console.log('loading', url)
	readJson(url)
		.then(loadDataFiles)
		.done()
}

function loadData() {
	var infoFiles = [
		'/data/areas/info.json',
		'/data/courses/info.json',
	]
	return new Promise.all(_.map(infoFiles, loadInfoFile))
}

module.exports = loadData
<|endoftext|>


<commit_before>
var formatter = require('./formatter');

var EtherTypes = {
  IPv4: 0x0800,
  ARP: 0x0806,
  RARP: 0x8035,
  VLAN: 0x8100,
  IPv6: 0x86DD,
  MPLSu: 0x8847,
  MPLSm: 0x8848,
  LLDP: 0x88cc
};

function lookup(value) {
  for(var prop
}

exports.MAC = function(v) {
  var addr = /(([0-9a-fA-F]{2})(-|:)){5}([0-9a-fA-F]{2})/;
  var octet = /[0-9a-fA-F]{2}/g;
  if(!addr.test(v)) throw "Invalid MAC Addr";
  var result = v.match(octet);
  this.addr = [];
  for(var i=0; i<result.length; ++i) {
    this.addr.push(parseInt(result[i], 16));
  }
}

exports.MAC.prototype.toString = function() {
  var result = [];
  for(var i=0; i<this.addr.length; ++i)
    result.push(this.addr[i].toString(16));
  return result.join(':');
}

exports.Ethernet = function(src, dst, ethertype) {
  this.src = new MAC(src);
  this.dst = new MAC(dst);
  if(ethertype) this.ethertype = ethertype;
}

exports.Ethernet.prototype.toFormatter = function(f) {
  f.begin('Ethernet');
  f.addPair('Src', this.src.toString());
  f.addPair('Dst', this.dst.toString());
  f.addTriple('Ethertype', lookup(this.ethertype), this.ethertype.toString(16));
  f.end();
}

exports.Ethernet.prototype.toString = function() {
  var f = new formatter.Formatter();
  this.toFormatter(f);
  var result = f.toString();
  delete f;
  return result;
}

var eth = new Ethernet('00:11:22:33:44:55', 'ff:ff:ff:ff:ff:ff', 0x8100);
console.log(eth.toString());

Ethernet.prototype.to_buffer = function(buf) {
  if(buf.remaining() < 14)
    throw new buf.Structural(14, buf.remaining());

  buf.write(this.src, 6);
  buf.write(this.dst, 6);
  buf.writeUInt16(this.ethertype);
}

Ethernet.prototype.from_buffer = function(buf) {
  if(buf.remaining() < 14)
    throw new buf.Structural(14, buf.remaining());

  buf.read(this.src, 6);
  buf.read(this.dst, 6);
  buf.readUInt16(this.ethertype);
}

<commit_msg>latest<commit_after>
var formatter = require('./formatter');

var EtherTypes = {
  IPv4: 0x0800,
  ARP: 0x0806,
  RARP: 0x8035,
  VLAN: 0x8100,
  IPv6: 0x86DD,
  MPLSu: 0x8847,
  MPLSm: 0x8848,
  LLDP: 0x88cc
};

function lookup(value) {
  for(var prop in EtherTypes) {
    if(EtherTypes[prop] == value)
      return prop;
  }
  return 'UNDEFINED';
}

exports.MAC = function(v) {
  var addr = /(([0-9a-fA-F]{2})(-|:)){5}([0-9a-fA-F]{2})/;
  var octet = /[0-9a-fA-F]{2}/g;
  if(!addr.test(v)) throw "Invalid MAC Addr";
  var result = v.match(octet);
  this.addr = [];
  for(var i=0; i<result.length; ++i) {
    this.addr.push(parseInt(result[i], 16));
  }
}

exports.MAC.prototype.toString = function() {
  var result = [];
  for(var i=0; i<this.addr.length; ++i)
    result.push(this.addr[i].toString(16));
  return result.join(':');
}

exports.Ethernet = function(src, dst, ethertype) {
  this.src = new exports.MAC(src);
  this.dst = new exports.MAC(dst);
  if(ethertype) this.ethertype = ethertype;
}

exports.Ethernet.prototype.toFormatter = function(f) {
  f.begin('Ethernet');
  f.addPair('Src', this.src.toString());
  f.addPair('Dst', this.dst.toString());
  f.addTriple('Ethertype', lookup(this.ethertype), this.ethertype.toString(16));
  f.end();
}

exports.Ethernet.prototype.toString = function() {
  var f = new formatter.Formatter();
  this.toFormatter(f);
  var result = f.toString();
  delete f;
  return result;
}

var eth = new exports.Ethernet('00:11:22:33:44:55', 'ff:ff:ff:ff:ff:ff', 0x8100);
console.log(eth.toString());

exports.Ethernet.prototype.to_buffer = function(buf) {
  if(buf.remaining() < 14)
    throw new buf.Structural(14, buf.remaining());

  buf.write(this.src, 6);
  buf.write(this.dst, 6);
  buf.writeUInt16(this.ethertype);
}

exports.Ethernet.prototype.from_buffer = function(buf) {
  if(buf.remaining() < 14)
    throw new buf.Structural(14, buf.remaining());

  buf.read(this.src, 6);
  buf.read(this.dst, 6);
  buf.readUInt16(this.ethertype);
}

<|endoftext|>


<commit_before>import React from 'react';
import {Link} from 'react-router';
import Page from '../components/Page';
import Calendar from '../components/Calendar';
import PostList from '../components/PostList';
import Button from '../components/Button';

class SubscribeUnsubscribeButton extends React.Component {
    render () {
        if (this.props.subscribed) {
            return <Button onClick={this.props.unsubscribe}>{"Me désinscrire de ce comité"}</Button>
        } else {
            return <Button onClick={this.props.subscribe}>{"M'inscrire à ce comité"}</Button>;
        }
    }
}

export default class ComityPage extends Page {
    constructor (props) {
        super(props);
        this.state = {
            comity: {
                members: []
            },
            events: [],
            posts: []
        };

        this.subscribe = this.subscribe.bind(this);
        this.unsubscribe = this.unsubscribe.bind(this);
    }
    getPageName () {
        return 'comity';
    }
    receiveData (data) {
        if (data.events) {
            data.events.forEach(function (event) {
                event.start = new Date(event.start);
                event.end = new Date(event.end);
            });
        }
        this.setState(data);
    }
    subscribe () {
        this.action('comity-subscribe', {
            comity: this.state.comity.id
        }).then(this.refreshPage, this.onError);
    }
    unsubscribe () {
        this.action('comity-unsubscribe', {
            comity: this.state.comity.id
        }).then(this.refreshPage, this.onError);
    }
    get isSubscribed () {
        const {members} = this.state.comity;
        if (!members) {
            return false;
        }
        const userId = this.context.currentUser.id;
        for (let index in members) {
            if (members[index].id == userId) {
                return true;
            }
        }
        return false;
    }
    renderSubscribeButton () {
        if (this.isSubscribed) {
            return <Button type="primary" size="sm" className="pull-right" onClick={this.unsubscribe}>{"Me désinscrire de ce comité"}</Button>;
        } else {
            return <Button type="primary" size="sm" className="pull-right" onClick={this.subscribe}>{"M'inscrire à ce comité"}</Button>;
        }
    }
    render () {
        const {comity, events, posts} = this.state;
        return (

{comity.name}

                			Ajouter un évènement

                		<Calendar events={events} />

Discussions

                				Ajouter une discussion

            			<PostList posts={posts} />

Membres

                            {this.renderSubscribeButton()}

                            {this.state.comity.members.map(function (member, index) {
                                return
{member.name}
;
                            })}

        );
    }
}
<commit_msg>remove unused component<commit_after>import React from 'react';
import {Link} from 'react-router';
import Page from '../components/Page';
import Calendar from '../components/Calendar';
import PostList from '../components/PostList';
import Button from '../components/Button';

export default class ComityPage extends Page {
    constructor (props) {
        super(props);
        this.state = {
            comity: {
                members: []
            },
            events: [],
            posts: []
        };

        this.subscribe = this.subscribe.bind(this);
        this.unsubscribe = this.unsubscribe.bind(this);
    }
    getPageName () {
        return 'comity';
    }
    receiveData (data) {
        if (data.events) {
            data.events.forEach(function (event) {
                event.start = new Date(event.start);
                event.end = new Date(event.end);
            });
        }
        this.setState(data);
    }
    subscribe () {
        this.action('comity-subscribe', {
            comity: this.state.comity.id
        }).then(this.refreshPage, this.onError);
    }
    unsubscribe () {
        this.action('comity-unsubscribe', {
            comity: this.state.comity.id
        }).then(this.refreshPage, this.onError);
    }
    get isSubscribed () {
        const {members} = this.state.comity;
        if (!members) {
            return false;
        }
        const userId = this.context.currentUser.id;
        for (let index in members) {
            if (members[index].id == userId) {
                return true;
            }
        }
        return false;
    }
    renderSubscribeButton () {
        if (this.isSubscribed) {
            return <Button type="primary" size="sm" className="pull-right" onClick={this.unsubscribe}>{"Me désinscrire de ce comité"}</Button>;
        } else {
            return <Button type="primary" size="sm" className="pull-right" onClick={this.subscribe}>{"M'inscrire à ce comité"}</Button>;
        }
    }
    render () {
        const {comity, events, posts} = this.state;
        return (

{comity.name}

                			Ajouter un évènement

                		<Calendar events={events} />

Discussions

                				Ajouter une discussion

            			<PostList posts={posts} />

Membres

                            {this.renderSubscribeButton()}

                            {this.state.comity.members.map(function (member, index) {
                                return
{member.name}
;
                            })}

        );
    }
}
<|endoftext|>


<commit_before>/**
 * Test run for scanner app
 * @type {*|exports|module.exports}
 */
var fs =  require('fs');
var Q = require('q');
var path = require('path');
//console.log("HEEEEYYY", process.env.OPENSHIFT_DATA_DIR + "nmap-7.00/nmap");
//TODO: Move to Core utils
var ajv = require('ajv')();
ajv.addSchema(require('../../schemas/nmap.json'), 'nmap');

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

//Data is chunked into 1024 targets, then 4 sets of 256 which each of is split into sets of 16
var nmap = require('libnmap');
//App.Store.kue.app.listen(8080);
App.Store.queue.process('418b3a196f9a8a9fb526e9be3f5e6b35', function(job, done){
    job.on('failed', function() {
        job.state('inactive').save();
    });

    var targets = job.data.targets;
    var total = targets.length;
    targets = App.util.chunk(targets, 256);
    var indx = 0;
    App.util.async.eachSeries(targets, function(midTargetBlock, targetsCB){
        //console.log(targetBlock);

        midTargetBlock = App.util.chunk(midTargetBlock, 16);
        console.log('Large Block');
        App.util.async.eachSeries(midTargetBlock, function(targetBlock, midTargetBlockCB){

            isItUp(targetBlock).then(function(report){
                //console.log(report);
                var targetblocksuccess = 0;
                for (var addr in report) {
                    job.progress(indx, total);
                    indx++;
                    //TODO: Add validation
                    App.Store.conn.targets.merge(addr, report[addr], function(err, res){
                        if(err){
                            done(new Error(err));
                            console.log('Error in Store Merge', err);
                            throw new Error(err);
                        } else targetblocksuccess++
                    });
                }

                console.log('targetblock success', targetblocksuccess);

            }).catch(function(err){
                console.log('Error in isITUp', err);
                done(new Error(err));
                midTargetBlockCB(err);
            }).done(function(){
                console.log('Done in isITUp');
                midTargetBlockCB();
            });
        }, function(err){
            if(!err) {
                targetsCB();
            }
        });

    },function(err){
        if(!err) done();
        else done(new Error(err));
    });
});

function isItUp(data) {
    var deferred = Q.defer();
    console.log("IsitUp?", data.length);
    var opts = {
        range: data,
        flags: ["Pn", "sL", "--disable-arp-ping"]
    };

    if(process.env.OPENSHIFT_DATA_DIR){

        opts.nmap = "."+ process.env.OPENSHIFT_REPO_DIR + "bin/nmap-openshift/nmap";
        fs.chmodSync(opts.nmap, 0775);
        console.log("OPTS", opts.nmap);
    }

    nmap.scan(opts, function (err, report) {
        if (err) deferred.reject(err);
        else deferred.resolve(report);

        //TODO: Add validation
        //var valid = ajv.validate('nmap', report[item]);

        //if (!valid) console.log(ajv.errorsText());

    });

    return deferred.promise;
}

module.exports = App;<commit_msg>nmap update<commit_after>/**
 * Test run for scanner app
 * @type {*|exports|module.exports}
 */
var fs =  require('fs');
var Q = require('q');
var path = require('path');
//console.log("HEEEEYYY", process.env.OPENSHIFT_DATA_DIR + "nmap-7.00/nmap");
//TODO: Move to Core utils
var ajv = require('ajv')();
ajv.addSchema(require('../../schemas/nmap.json'), 'nmap');

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

//Data is chunked into 1024 targets, then 4 sets of 256 which each of is split into sets of 16
var nmap = require('libnmap');
//App.Store.kue.app.listen(8080);
App.Store.queue.process('418b3a196f9a8a9fb526e9be3f5e6b35', function(job, done){
    job.on('failed', function() {
        job.state('inactive').save();
    });

    var targets = job.data.targets;
    var total = targets.length;
    targets = App.util.chunk(targets, 256);
    var indx = 0;
    App.util.async.eachSeries(targets, function(midTargetBlock, targetsCB){
        //console.log(targetBlock);

        midTargetBlock = App.util.chunk(midTargetBlock, 16);
        console.log('Large Block');
        App.util.async.eachSeries(midTargetBlock, function(targetBlock, midTargetBlockCB){

            isItUp(targetBlock).then(function(report){
                //console.log(report);
                var targetblocksuccess = 0;
                for (var addr in report) {
                    job.progress(indx, total);
                    indx++;
                    //TODO: Add validation
                    App.Store.conn.targets.merge(addr, report[addr], function(err, res){
                        if(err){
                            done(new Error(err));
                            console.log('Error in Store Merge', err);
                            throw new Error(err);
                        } else targetblocksuccess++
                    });
                }

                console.log('targetblock success', targetblocksuccess);

            }).catch(function(err){
                console.log('Error in isITUp', err);
                done(new Error(err));
                midTargetBlockCB(err);
            }).done(function(){
                console.log('Done in isITUp');
                midTargetBlockCB();
            });
        }, function(err){
            if(!err) {
                targetsCB();
            }
        });

    },function(err){
        if(!err) done();
        else done(new Error(err));
    });
});

function isItUp(data) {
    var deferred = Q.defer();
    console.log("IsitUp?", data.length);
    var opts = {
        range: data,
        flags: ["Pn", "sL", "--disable-arp-ping"]
    };

    if(process.env.OPENSHIFT_DATA_DIR){

        opts.nmap = "."+ process.env.OPENSHIFT_REPO_DIR + "bin/nmap-openshift/nmap";
        fs.chmodSync(process.env.OPENSHIFT_REPO_DIR + "bin/nmap-openshift/nmap", 0775);
        console.log("OPTS", opts.nmap);
    }

    nmap.scan(opts, function (err, report) {
        if (err) deferred.reject(err);
        else deferred.resolve(report);

        //TODO: Add validation
        //var valid = ajv.validate('nmap', report[item]);

        //if (!valid) console.log(ajv.errorsText());

    });

    return deferred.promise;
}

module.exports = App;<|endoftext|>


<commit_before>var ws = new WebSocket('wss://' + location.host + '/one2many');
var video;
var webRtcPeer; //gets assigned in presenter function

window.onload = function() {

  video = document.getElementById('video');

  document.getElementsByClassName('startBroadcast')[0].addEventListener('click', function() { presenter(); } );
  document.getElementsByClassName('joinBroadcast')[0].addEventListener('click', function() { viewer(); } );
  document.getElementsByClassName('endBroadcast')[0].addEventListener('click', function() { stop(); } );
}

window.onbeforeunload = function() {
  ws.close();
}

//This is where the signaling takes place. Look in server.js to see the other half
ws.onmessage = function(message) {
  var parsedMessage = JSON.parse(message.data);
  console.info('Received message: ' + message.data);

  var actions = {
    'presenterResponse': preseenterResponse(parsedMessage), //this has been called, there is a bug in the presenterFunction and this is the hotfix
    'viewerResponse': viewerResponse(parsedMessage),
    'stopCommunication': dispose(),
    'iceCandidate': webRtcPeer.addIceCandidate(parsedMessage.candidate),
  };

  actions[parsedMessage.id];
}

function presenterResponse(message) {
  if (message.response != 'accepted') {
    var errorMsg = message.message ? message.message : 'Unknown error';
    console.warn('Call not accepted for the following reason: ' + errorMsg);
    dispose();
  } else {
    webRtcPeer.processAnswer(message.sdpAnswer);
  }
}

function viewerResponse(message) {
  if (message.response != 'accepted') {
    var errorMsg = message.message ? message.message : 'Unknown error';
    console.warn('Call not accepted for the following reason: ' + errorMsg);
    dispose();
  } else {
    webRtcPeer.processAnswer(message.sdpAnswer);
  }
}

function presenter() {
  if (!webRtcPeer) {
    showSpinner(video);

    var options = {
      localVideo: video,
      onicecandidate : onIceCandidate
      }

    webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options, function(error) {
      if(error) return onError(error);

      this.generateOffer(onOfferPresenter);
    });
  }
}

function onOfferPresenter(error, offerSdp) {
    if (error) return onError(error);

  var message = {
    id : 'presenter',
    sdpOffer : offerSdp
  };
  sendMessage(message);
}

function viewer() {
  if (!webRtcPeer) {
    showSpinner(video);

    var options = {
      remoteVideo: video,
      onicecandidate : onIceCandidate
    }

    webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options, function(error) {
      if(error) return onError(error);

      this.generateOffer(onOfferViewer);
    });
  }
}

function onOfferViewer(error, offerSdp) {
  if (error) return onError(error)

  var message = {
    id : 'viewer',
    sdpOffer : offerSdp
  }
  sendMessage(message);
}

function onIceCandidate(candidate) {
     console.log('Local candidate' + JSON.stringify(candidate));

     var message = {
        id : 'onIceCandidate',
        candidate : candidate
     }
     sendMessage(message);
}

function stop() {
  if (webRtcPeer) {
    var message = {
        id : 'stop'
    }
    sendMessage(message);
    dispose();
  }
}

function dispose() {
  if (webRtcPeer) {
    webRtcPeer.dispose();
    webRtcPeer = null;
  }
  hideSpinner(video);
}

function sendMessage(message) {
  var jsonMessage = JSON.stringify(message);
  console.log('Sending message: ' + jsonMessage);
  ws.send(jsonMessage);
}

function showSpinner() {
  for (var i = 0; i < arguments.length; i++) {
    arguments[i].poster = '';
    arguments[i].style.background = 'center transparent url("./public/img/spinner.gif") no-repeat';
  }
}

function hideSpinner() {
  for (var i = 0; i < arguments.length; i++) {
    arguments[i].src = '';
    arguments[i].poster = './public/img/guitarist.jpg';
    arguments[i].style.background = '';
  }
}<commit_msg>(BUG) fix webRTC client code<commit_after>var ws = new WebSocket('wss://' + location.host + '/one2many');
var video;
var webRtcPeer; //gets assigned in presenter function

window.onload = function() {

  video = document.getElementById('video');

  document.getElementsByClassName('startBroadcast')[0].addEventListener('click', function() { presenter(); } );
  document.getElementsByClassName('joinBroadcast')[0].addEventListener('click', function() { viewer(); } );
  document.getElementsByClassName('endBroadcast')[0].addEventListener('click', function() { stop(); } );
}

window.onbeforeunload = function() {
  ws.close();
}

//This is where the signaling takes place. Look in server.js to see the other half
ws.onmessage = function(message) {
  var parsedMessage = JSON.parse(message.data);
  console.info('Received message: ' + message.data);

  switch (parsedMessage.id) {
  case 'presenterResponse':
    presenterResponse(parsedMessage);
    break;
  case 'viewerResponse':
    viewerResponse(parsedMessage);
    break;
  case 'stopCommunication':
    dispose();
    break;
  case 'iceCandidate':
    webRtcPeer.addIceCandidate(parsedMessage.candidate)
    break;
  default:
    console.error('Unrecognized message', parsedMessage);
  }
}

function presenterResponse(message) {
  if (message.response != 'accepted') {
    var errorMsg = message.message ? message.message : 'Unknown error';
    console.warn('Call not accepted for the following reason: ' + errorMsg);
    dispose();
  } else {
    webRtcPeer.processAnswer(message.sdpAnswer);
  }
}

function viewerResponse(message) {
  if (message.response != 'accepted') {
    var errorMsg = message.message ? message.message : 'Unknown error';
    console.warn('Call not accepted for the following reason: ' + errorMsg);
    dispose();
  } else {
    webRtcPeer.processAnswer(message.sdpAnswer);
  }
}

function presenter() {
  if (!webRtcPeer) {
    showSpinner(video);

    var options = {
      localVideo: video,
      onicecandidate : onIceCandidate
      }

    webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options, function(error) {
      if(error) return onError(error);

      this.generateOffer(onOfferPresenter);
    });
  }
}

function onOfferPresenter(error, offerSdp) {
    if (error) return onError(error);

  var message = {
    id : 'presenter',
    sdpOffer : offerSdp
  };
  sendMessage(message);
}

function viewer() {
  if (!webRtcPeer) {
    showSpinner(video);

    var options = {
      remoteVideo: video,
      onicecandidate : onIceCandidate
    }

    webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options, function(error) {
      if(error) return onError(error);

      this.generateOffer(onOfferViewer);
    });
  }
}

function onOfferViewer(error, offerSdp) {
  if (error) return onError(error)

  var message = {
    id : 'viewer',
    sdpOffer : offerSdp
  }
  sendMessage(message);
}

function onIceCandidate(candidate) {
     console.log('Local candidate' + JSON.stringify(candidate));

     var message = {
        id : 'onIceCandidate',
        candidate : candidate
     }
     sendMessage(message);
}

function stop() {
  if (webRtcPeer) {
    var message = {
        id : 'stop'
    }
    sendMessage(message);
    dispose();
  }
}

function dispose() {
  if (webRtcPeer) {
    webRtcPeer.dispose();
    webRtcPeer = null;
  }
  hideSpinner(video);
}

function sendMessage(message) {
  var jsonMessage = JSON.stringify(message);
  console.log('Sending message: ' + jsonMessage);
  ws.send(jsonMessage);
}

function showSpinner() {
  for (var i = 0; i < arguments.length; i++) {
    arguments[i].poster = '';
    arguments[i].style.background = 'center transparent url("./public/img/spinner.gif") no-repeat';
  }
}

function hideSpinner() {
  for (var i = 0; i < arguments.length; i++) {
    arguments[i].src = '';
    arguments[i].poster = './public/img/guitarist.jpg';
    arguments[i].style.background = '';
  }
}<|endoftext|>


<commit_before>var request = require('browser-request')
var config = require('../../config')

var constants = {
  SELECT_TAB: 'SELECT_TAB',
  DESELECT_TAB: 'DESELECT_TAB',
  FETCH_RESULTS: 'FETCH_RESULTS',
  SHOW_DETAIL: 'SHOW_DETAIL',
  HIDE_DETAIL: 'HIDE_DETAIL',
  SET_INFO: 'SET_INFO',
  SET_SEARCH: 'SET_SEARCH',
  REMOVE_INFO: 'REMOVE_INFO',
  UPLOAD_ERROR: 'UPLOAD_ERROR',
  UPLOAD_STARTED: 'UPLOAD_STARTED',
  UPLOAD_SUCCESS: 'UPLOAD_SUCCESS',
  UPLOAD_RESET: 'UPLOAD_RESET'
}

var host = config.host

function fetch () {
  return function (dx) {
    request({
      method: 'GET',
      url: host + '/api/results',
      json: true
    }, function (err, res, body) {
      if (err) {
        return dx({
          type: constants.FETCH_RESULTS,
          success: false
        })
      }
      return dx({
        type: constants.FETCH_RESULTS,
        success: true,
        entries: body
      })
    })
  }
}

function submit (data) {
  return function (dx) {
    setTimeout(function () {
      request({
        method: 'POST',
        url: host + '/api/submit',
        body: JSON.stringify(data),
        json: true,
        timeout: 10 * 60 * 1000
      }, function (req, res, body) {
        if (res.statusCode == 200) {
          fetch()(dx)
          dx({ type: 'UPLOAD_SUCCESS' })
          setTimeout(function () {
            dx({ type: 'UPLOAD_RESET' })
          }, 2000)
        }
        else dx({ type: 'UPLOAD_ERROR', message: res.response || 'failed to upload' })
      })
    }, 100)

  }
}

module.exports = {
  constants: constants,
  fetch: fetch,
  submit: submit
}<commit_msg>change error catching<commit_after>var request = require('browser-request')
var config = require('../../config')

var constants = {
  SELECT_TAB: 'SELECT_TAB',
  DESELECT_TAB: 'DESELECT_TAB',
  FETCH_RESULTS: 'FETCH_RESULTS',
  SHOW_DETAIL: 'SHOW_DETAIL',
  HIDE_DETAIL: 'HIDE_DETAIL',
  SET_INFO: 'SET_INFO',
  SET_SEARCH: 'SET_SEARCH',
  REMOVE_INFO: 'REMOVE_INFO',
  UPLOAD_ERROR: 'UPLOAD_ERROR',
  UPLOAD_STARTED: 'UPLOAD_STARTED',
  UPLOAD_SUCCESS: 'UPLOAD_SUCCESS',
  UPLOAD_RESET: 'UPLOAD_RESET'
}

var host = config.host

function fetch () {
  return function (dx) {
    request({
      method: 'GET',
      url: host + '/api/results',
      json: true
    }, function (err, res, body) {
      if (err) {
        return dx({
          type: constants.FETCH_RESULTS,
          success: false
        })
      }
      return dx({
        type: constants.FETCH_RESULTS,
        success: true,
        entries: body
      })
    })
  }
}

function submit (data) {
  return function (dx) {
    setTimeout(function () {
      request({
        method: 'POST',
        url: host + '/api/submit',
        body: JSON.stringify(data),
        json: true,
        timeout: 10 * 60 * 1000
      }, function (req, res, body) {
        if (res.statusCode != 500) {
          fetch()(dx)
          dx({ type: 'UPLOAD_SUCCESS' })
          setTimeout(function () {
            dx({ type: 'UPLOAD_RESET' })
          }, 2000)
        }
        else dx({ type: 'UPLOAD_ERROR', message: res.response || 'failed to upload' })
      })
    }, 100)

  }
}

module.exports = {
  constants: constants,
  fetch: fetch,
  submit: submit
}<|endoftext|>


<commit_before>import operation from 'models/transaction'

export const getModels = db => ({
  Operation: operation(db)
})

export default getModels
<commit_msg>Fix naming<commit_after>import transaction from 'models/transaction'

export const getModels = db => ({
  Transaction: transaction(db)
})

export default getModels
<|endoftext|>


<commit_before>_kiwi.view.Member = Backbone.View.extend({
    tagName: "li",
    initialize: function (options) {
        this.model.bind('change', this.render, this);
        this.render();
    },
    render: function () {
        var $this = this.$el,
            prefix_css_class = (this.model.get('modes') || []).join(' ');

        $this.attr('class', 'mode ' + prefix_css_class);
        $this.html('' + this.model.get("prefix") + '' + this.model.get("nick") + '');

        return this;
    }
});<commit_msg>Fix upstream issue #754<commit_after>_kiwi.view.Member = Backbone.View.extend({
    tagName: "li",
    initialize: function (options) {
        this.model.bind('change', this.render, this);
        this.render();
    },
    render: function () {
        var $this = this.$el,
            prefix_css_class = (this.model.get('modes') || []).join(' ');

        $this.attr('class', 'mode ' + prefix_css_class + ' member member-' + prefix_css_class);
        $this.html('' + this.model.get("prefix") + '' + this.model.get("nick") + '');

        return this;
    }
});<|endoftext|>


<commit_before>Template.submit.events = {
  'click input[type=submit]': function(){
    if(!Meteor.user()) throw 'You must be logged in.';

    var title= $('#title').val();
    var url = $('#url').val();
    var body = $('#body').val();

    var postId = Posts.insert({
        headline: title
      , url: url
      , submitter: Meteor.user().username
      , submitted: new Date().getTime()
      , votes: 0
      , comments: 0
    });
    var post = Posts.findOne(postId);

    Meteor.call('voteForPost', post);

    Session.set('selected_post', post);
    Session.set('state', 'view_post');
  }
};

Template.submit.show = function(){
  return Session.equals('state', 'submit');
};
<commit_msg>added preventDefault to submit<commit_after>Template.submit.events = {
  'click input[type=submit]': function(event){
    event.preventDefault();
    if(!Meteor.user()) throw 'You must be logged in.';

    var title= $('#title').val();
    var url = $('#url').val();
    var body = $('#body').val();

    var postId = Posts.insert({
        headline: title
      , url: url
      , submitter: Meteor.user().username
      , submitted: new Date().getTime()
      , votes: 0
      , comments: 0
    });
    var post = Posts.findOne(postId);

    Meteor.call('voteForPost', post);

    Session.set('selected_post', post);
    Session.set('state', 'view_post');
  }
};

Template.submit.show = function(){
  return Session.equals('state', 'submit');
};
<|endoftext|>


<commit_before>let test = require('ava'),
    webdriver = require('selenium-webdriver'),
    By = webdriver.By,
    chalk = require('chalk')

// This gives us access to send Chrome commands.
require('chromedriver')

// Webdriver's promise manager only made sense before Node had async/await support.
// Now it's a deprecated legacy feature, so we should use the simpler native Node support instead.
webdriver.promise.USE_PROMISE_MANAGER = false

console.log(
    chalk.bold.cyan('These tests assume that you have just run ../insertSqlBaseData.sql on your SQLServer instance')
)

// We use the beforeEach hook to put helpers on t.context and set up test scaffolding.
test.beforeEach(t => {
    t.context.driver = new webdriver.Builder()
        .forBrowser('chrome')
        .build()

    // This method is a helper so we don't have to keep repeating the hostname.
    // Passing the authentication through the querystring is a hack so we can
    // pass the information along via window.fetch.
    t.context.get = async pathname =>
        await t.context.driver.get(`http://localhost:3000${pathname}?user=erin&pass=erin`)

    // For debugging purposes.
    t.context.waitForever = async () => {
        console.log(chalk.red('Waiting forever so you can debug...'))
        await t.context.driver.wait(() => {})
    }

    t.context.$ = cssSelector => t.context.driver.findElement(By.css(cssSelector))
    t.context.$$ = cssSelector => t.context.driver.findElements(By.css(cssSelector))

    // This helper method is necessary because we don't know when React has finished rendering the page.
    // We will wait for it to be done, with a max timeout so the test does not hang if the rendering fails.
    let fiveSecondsMs = 5000
    t.context.waitUntilElementHasText = async ($elem, expectedText) =>
        await t.context.driver.wait(async () => {
            let text = await $elem.getText()
            return text === expectedText
        }, fiveSecondsMs, `Element did not have text '${expectedText}' within ${fiveSecondsMs} milliseconds`)

    // A helper function to combine waiting for an element to have rendered and then asserting on its contents.
    t.context.assertElementText = async (t, $elem, expectedText, message) => {
        try {
            await t.context.waitUntilElementHasText($elem, expectedText)
        } catch (e) {
            // If we got a TimeoutError because the element did not have the text we expected, just swallow it here
            // and let the assertion on blow up instead. That will produce a clearer error message.
            if (e.name !== 'TimeoutError') {
                throw e
            }
        }
        t.is(await $elem.getText(), expectedText, message)
    }

    t.context.assertElementNotPresent = async (t, cssSelector, message) => {
        try {
            await t.context.driver.wait(
                async () => {
                    try {
                        return !(await t.context.$(cssSelector))
                    } catch (e) {
                        if (e.name === 'NoSuchElementError') {
                            return true
                        }
                        throw e
                    }
                },
                fiveSecondsMs,
                `Element was still present after ${fiveSecondsMs} milliseconds`
            )
        } catch (e) {
            if (e.name === 'TimeoutError') {
                t.fail(`Element with css selector '${cssSelector}' was still present after ${fiveSecondsMs} milliseconds`)
            } else {
                throw e
            }
        }
        t.pass(message || 'Element was not present')
    }
})

// Shut down the browser when we are done.
test.afterEach.always(async t => {
    if (t.context.driver) {
        await t.context.driver.quit()
    }
})

test('Home Page', async t => {
    // We can use t.plan() to indicate how many assertions we plan to make.
    // This provides safety in case there's a silent failure and the test
    // looks like it exited successfully, when in fact it just died. I've
    // seen people get bit by that a done with frameworks like Mocha which
    // do not offer test planning.
    t.plan(6)

    let {assertElementText, assertElementNotPresent, $, $$} = t.context

    await t.context.get('/')

    // Use a CSS selector to find an element that we care about on the page.
    let [$reportsPending, $draftReports, $orgReports, $upcomingEngagements] = await $$('.home-tile h1')

    await assertElementText(t, $reportsPending, '0')
    await assertElementText(t, $draftReports, '0')
    await assertElementText(t, $orgReports, '2')
    await assertElementText(t, $upcomingEngagements, '0')

    await $('.persistent-tour-launcher').click()
    let $hopscotchTitle = await $('.hopscotch-title')
    await assertElementText(
        t, $hopscotchTitle, 'Welcome', 'Clicking the hopscotch launch button starts the hopscotch tour'
    )

    await $('.hopscotch-next').click()

    await t.context.driver.findElement(By.linkText('My reports')).click()
    await assertElementNotPresent(t, '.hopscotch-title', 'Navigating to a new page clears the hopscotch tour')
})
<commit_msg>putting in warning when the backend is broken<commit_after>let test = require('ava'),
    webdriver = require('selenium-webdriver'),
    By = webdriver.By,
    chalk = require('chalk')

// This gives us access to send Chrome commands.
require('chromedriver')

// Webdriver's promise manager only made sense before Node had async/await support.
// Now it's a deprecated legacy feature, so we should use the simpler native Node support instead.
webdriver.promise.USE_PROMISE_MANAGER = false

console.log(
    chalk.bold.cyan('These tests assume that you have just run ../insertSqlBaseData.sql on your SQLServer instance')
)

// We use the beforeEach hook to put helpers on t.context and set up test scaffolding.
test.beforeEach(t => {
    t.context.driver = new webdriver.Builder()
        .forBrowser('chrome')
        .build()

    // This method is a helper so we don't have to keep repeating the hostname.
    // Passing the authentication through the querystring is a hack so we can
    // pass the information along via window.fetch.
    t.context.get = async pathname => {
        await t.context.driver.get(`http://localhost:3000${pathname}?user=erin&pass=erin`)
        let $notFoundHeader = await t.context.$('.not-found-text')
        try {
            let halfSecondMs = 500
            await t.context.waitUntilElementHasText($notFoundHeader, 'There was an error processing this request. Please contact an administrator.', halfSecondMs)
            throw new Error('The API returned a 500.')
        } catch (e) {
            if (e.name !== 'TimeoutError') {
                throw e
            }
        }
    }

    // For debugging purposes.
    t.context.waitForever = async () => {
        console.log(chalk.red('Waiting forever so you can debug...'))
        await t.context.driver.wait(() => {})
    }

    t.context.$ = cssSelector => t.context.driver.findElement(By.css(cssSelector))
    t.context.$$ = cssSelector => t.context.driver.findElements(By.css(cssSelector))

    // This helper method is necessary because we don't know when React has finished rendering the page.
    // We will wait for it to be done, with a max timeout so the test does not hang if the rendering fails.
    let fiveSecondsMs = 5000
    t.context.waitUntilElementHasText = async ($elem, expectedText, timeoutMs) => {
        let waitTimeoutMs = timeoutMs || fiveSecondsMs
        await t.context.driver.wait(async () => {
            let text = await $elem.getText()
            return text === expectedText
        }, waitTimeoutMs, `Element did not have text '${expectedText}' within ${waitTimeoutMs} milliseconds`)
    }

    // A helper function to combine waiting for an element to have rendered and then asserting on its contents.
    t.context.assertElementText = async (t, $elem, expectedText, message) => {
        try {
            await t.context.waitUntilElementHasText($elem, expectedText)
        } catch (e) {
            // If we got a TimeoutError because the element did not have the text we expected, just swallow it here
            // and let the assertion on blow up instead. That will produce a clearer error message.
            if (e.name !== 'TimeoutError') {
                throw e
            }
        }
        t.is(await $elem.getText(), expectedText, message)
    }

    t.context.assertElementNotPresent = async (t, cssSelector, message) => {
        try {
            await t.context.driver.wait(
                async () => {
                    try {
                        return !(await t.context.$(cssSelector))
                    } catch (e) {
                        if (e.name === 'NoSuchElementError') {
                            return true
                        }
                        throw e
                    }
                },
                fiveSecondsMs,
                `Element was still present after ${fiveSecondsMs} milliseconds`
            )
        } catch (e) {
            if (e.name === 'TimeoutError') {
                t.fail(`Element with css selector '${cssSelector}' was still present after ${fiveSecondsMs} milliseconds`)
            } else {
                throw e
            }
        }
        t.pass(message || 'Element was not present')
    }
})

// Shut down the browser when we are done.
test.afterEach.always(async t => {
    if (t.context.driver) {
        await t.context.driver.quit()
    }
})

test('Home Page', async t => {
    // We can use t.plan() to indicate how many assertions we plan to make.
    // This provides safety in case there's a silent failure and the test
    // looks like it exited successfully, when in fact it just died. I've
    // seen people get bit by that a done with frameworks like Mocha which
    // do not offer test planning.
    t.plan(6)

    let {assertElementText, assertElementNotPresent, $, $$} = t.context

    await t.context.get('/')

    // Use a CSS selector to find an element that we care about on the page.
    let [$reportsPending, $draftReports, $orgReports, $upcomingEngagements] = await $$('.home-tile h1')

    await assertElementText(t, $reportsPending, '0')
    await assertElementText(t, $draftReports, '0')
    await assertElementText(t, $orgReports, '2')
    await assertElementText(t, $upcomingEngagements, '0')

    await $('.persistent-tour-launcher').click()
    let $hopscotchTitle = await $('.hopscotch-title')
    await assertElementText(
        t, $hopscotchTitle, 'Welcome', 'Clicking the hopscotch launch button starts the hopscotch tour'
    )

    await $('.hopscotch-next').click()

    await t.context.driver.findElement(By.linkText('My reports')).click()
    await assertElementNotPresent(t, '.hopscotch-title', 'Navigating to a new page clears the hopscotch tour')
})
<|endoftext|>


<commit_before>var raf         = require('raf');

var WindowImpl  = require('./WindowImpl');
var Context     = require('pex-context/Context');
var WindowEvent       = require('./WindowEvent');
var WebGLDebugUtils   = require('webgl-debug');

var WebGLContextNames = [
    'experimental-webgl2',
    'webgl2',
    'experimental-webgl',
    'webgl'
];

var DefaultWebGLContextOptions = {
    alpha                           : false,
    depth                           : true,
    stencil                         : false,
    antialias                       : true,
    premultipliedAlpha              : true,
    preserveDrawingBuffer           : false,
    preferLowPowerToHighPerformance : false,
    failIfMajorPerformanceCaveat    : false
};

var isiOS9 = function() {
    var deviceAgent = navigator.userAgent.toLowerCase();
    return /(iphone|ipod|ipad).* os 9_/.test(deviceAgent);
};

function getWebGLContext(canvas, contextOptions) {
    var gl = null;
    for(var i=0; i<WebGLContextNames.length; i++) {
        try {
            gl = canvas.getContext(WebGLContextNames[i], contextOptions);
            if (gl) {
                break;
            }
        }
        catch (err) {
        }
    }
    return gl;
}

function setCanvasSize(canvas,width,height,pixelRatio){
    pixelRatio = pixelRatio === undefined ? 1 : pixelRatio;

    canvas.width  = width * pixelRatio;
    canvas.height = height * pixelRatio;
    canvas.style.width  = width  + 'px';
    canvas.style.height = height + 'px';
}

function WindowImplBrowser(){
    WindowImpl.call(this);
    this.canvas = null;
}

WindowImplBrowser.prototype = Object.create(WindowImpl.prototype);
WindowImplBrowser.prototype.constructor = WindowImplBrowser;

WindowImplBrowser.prototype.setSize = function(width,height,pixelRatio){
    pixelRatio = pixelRatio === undefined ? this.pixelRatio : pixelRatio;

    setCanvasSize(this.canvas, width, height, pixelRatio);
    this.width  = width * pixelRatio;
    this.height = height * pixelRatio;
    this.pixelRatio = pixelRatio;
};

WindowImplBrowser.prototype.setFullScreen = function(enable){
    var isDocumentFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;

    if((enable && this.fullScreen && isDocumentFullScreen) ||
        (!enable && !this.fullScreen && !isDocumentFullScreen)){
        return;
    }

    if(enable){
        var canvas = this.canvas;
        this.fullScreen = true;

        if(canvas.requestFullScreen){
            canvas.requestFullScreen();
        }
        else if(canvas.webkitRequestFullScreen){
            canvas.webkitRequestFullScreen();
        }
        else if(canvas.mozRequestFullScreen){
            canvas.mozRequestFullScreen();
        }
    }
    else {
        this.fullScreen = false;

        if(document.exitFullscreen){
            document.exitFullscreen();
        }
        else if(document.webkitExitFullscreen){
            document.webkitExitFullscreen();
        }
        else if(document.mozCancelFullScreen){
            document.mozCancelFullScreen();
        }
    }
};

WindowImplBrowser.create = function(windowPex,settings){
    var canvas  = settings.canvas || document.createElement('canvas');

    var width, height;
    var pixelRatio = settings.pixelRatio || 1;
    if(settings.fullScreen){
        width = isiOS9 ? document.documentElement.clientWidth : window.innerWidth;
        height = isiOS9 ? document.documentElement.clientHeight : window.innerHeight;
    }
    else {
        width  = settings.width;
        height = settings.height;
    }

    var impl = new WindowImplBrowser();
    impl.canvas = canvas;
    impl.setSize(width,height,pixelRatio);

    var mouse = windowPex._mouse;

    impl.canvas.addEventListener('mousedown', function(e) {
        mouse.handleMouseDown({
            x        : e.offsetX * pixelRatio,
            y        : e.offsetY * pixelRatio,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    impl.canvas.addEventListener('mouseup', function(e) {
        mouse.handleMouseUp({
            x        : e.offsetX * pixelRatio,
            y        : e.offsetY * pixelRatio,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    impl.canvas.addEventListener('mousemove', function(e) {
        mouse.handleMouseMove({
            x        : e.offsetX * pixelRatio,
            y        : e.offsetY * pixelRatio,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    var lastTouch = null;
    impl.canvas.addEventListener('touchstart', function(e) {
        var touches = Array.prototype.slice.call(e.touches).map(function(touch) {
            touch.x = touch.clientX * pixelRatio;
            touch.y = touch.clientY * pixelRatio;
            return touch;
        })
        lastTouch = touches[0];
        mouse.handleMouseDown({
            x        : touches[0].x,
            y        : touches[0].y,
            altKey   : false,
            shiftKey : false,
            ctrlKey  : false,
            metaKey  : false,
            touches  : touches
        });
        e.preventDefault();
        e.stopPropagation();
        return false;
    })

    impl.canvas.addEventListener('touchend', function(e) {
        var touches = Array.prototype.slice.call(e.touches).map(function(touch) {
            touch.x = touch.clientX * pixelRatio;
            touch.y = touch.clientY * pixelRatio;
            return touch;
        })
        mouse.handleMouseUp({
            x        : lastTouch.x,
            y        : lastTouch.y,
            altKey   : false,
            shiftKey : false,
            ctrlKey  : false,
            metaKey  : false,
            touches  : touches
        });
        lastTouch = null;
        e.preventDefault();
        e.stopPropagation();
        return false;
    })

    impl.canvas.addEventListener('touchmove', function(e) {
        var touches = Array.prototype.slice.call(e.touches).map(function(touch) {
            touch.x = touch.clientX * pixelRatio;
            touch.y = touch.clientY * pixelRatio;
            return touch;
        })
        mouse.handleMouseMove({
            x        : touches[0].x,
            y        : touches[0].y,
            altKey   : false,
            shiftKey : false,
            ctrlKey  : false,
            metaKey  : false,
            touches  : touches
        });
        e.preventDefault();
        e.stopPropagation();
        return false;
    })

    var mouseWheelEvent = /Firefox/i.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel';
    //FIXME: horizontal scroll in the browser? What is .detail?
    window.addEventListener(mouseWheelEvent, function(e) {
        var dx = 0;
        var dy = e.wheelDelta / 10 || -e.detail / 10;
        mouse.handleMouseScroll({
            dx       : dx,
            dy       : dy,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    var keyboard = windowPex._keyboard;

    window.addEventListener('keydown', function(e) {
        keyboard.handleKeyDown({
            str      : '',
            keyCode  : e.keyCode,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    window.addEventListener('keypress', function(e) {
        keyboard.handleKeyPress({
            str      : String.fromCharCode(e.charCode),
            keyCode  : e.keyCode,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    window.addEventListener('keyup', function(e) {
        keyboard.handleKeyUp({
            str      : '',
            keyCode  : e.keyCode,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    window.addEventListener('resize', function(e) {
        e.width = isiOS9 ? document.documentElement.clientWidth : window.innerWidth;
        e.height = isiOS9 ? document.documentElement.clientHeight : window.innerHeight;
        if(settings.fullScreen) {
            impl.setSize(e.width, e.height, settings.pixelRatio);
        }

        impl.dispatchEvent(new WindowEvent(WindowEvent.WINDOW_RESIZE, e));
    });

    function drawLoop(now){
        windowPex._time._update(now);
        if (settings.debug) {
            try {
                windowPex.draw();
                raf(drawLoop);
            }
            catch(e) {
                console.log(e);
                console.log(e.stack);
            }
        }
        else {
            windowPex.draw()
            raf(drawLoop);
        }
    }

    function go(){
        if (!settings.canvas) {
            //we careted new canvas, so we need to add it to the DOM
            document.body.appendChild(canvas);
        }

        impl.width    = width * pixelRatio;
        impl.height   = height * pixelRatio;
        impl.pixelRatio = pixelRatio;

        if (settings.type == '2d') {
            windowPex._ctx = canvas.getContext('2d');
        }
        else {
            var options = Object.assign({}, DefaultWebGLContextOptions, settings);

            var gl = getWebGLContext(canvas,options);
            if(gl === null){
                throw new Error('WindowImplBrowser: No WebGL context is available.');
            }

            if (settings.debug) {
                function throwOnGLError(err, funcName, args) {
                    throw new Error('WindowImplBrowser ' + WebGLDebugUtils.glEnumToString(err) + " was caused by call to " + funcName);
                };
                gl = WebGLDebugUtils.makeDebugContext(gl, throwOnGLError);
            }

            windowPex._ctx = new Context(gl);
        }

        setTimeout(function() {
            impl.dispatchEvent(new WindowEvent(WindowEvent.WINDOW_READY, {}));
            drawLoop(0);
        }, 1)
    }

    if(!canvas.parentNode){
        //Window already loaded, or script inside body
        if (document.body) {
            go();
        }
        //Wait for window to load
        else {
            window.addEventListener('load',function(){
                go();
            },false);
        }
    }
    else{
        //Canvas element node already attached, ready to go
        go();
    }

    return impl;
};

module.exports = WindowImplBrowser;
<commit_msg>Disable webgl2 context creation<commit_after>var raf         = require('raf');

var WindowImpl  = require('./WindowImpl');
var Context     = require('pex-context/Context');
var WindowEvent       = require('./WindowEvent');
var WebGLDebugUtils   = require('webgl-debug');

var WebGLContextNames = [
    'experimental-webgl',
    'webgl'
];

var DefaultWebGLContextOptions = {
    alpha                           : false,
    depth                           : true,
    stencil                         : false,
    antialias                       : true,
    premultipliedAlpha              : true,
    preserveDrawingBuffer           : false,
    preferLowPowerToHighPerformance : false,
    failIfMajorPerformanceCaveat    : false
};

var isiOS9 = function() {
    var deviceAgent = navigator.userAgent.toLowerCase();
    return /(iphone|ipod|ipad).* os 9_/.test(deviceAgent);
};

function getWebGLContext(canvas, contextOptions) {
    var gl = null;
    for(var i=0; i<WebGLContextNames.length; i++) {
        try {
            gl = canvas.getContext(WebGLContextNames[i], contextOptions);
            if (gl) {
                break;
            }
        }
        catch (err) {
        }
    }
    return gl;
}

function setCanvasSize(canvas,width,height,pixelRatio){
    pixelRatio = pixelRatio === undefined ? 1 : pixelRatio;

    canvas.width  = width * pixelRatio;
    canvas.height = height * pixelRatio;
    canvas.style.width  = width  + 'px';
    canvas.style.height = height + 'px';
}

function WindowImplBrowser(){
    WindowImpl.call(this);
    this.canvas = null;
}

WindowImplBrowser.prototype = Object.create(WindowImpl.prototype);
WindowImplBrowser.prototype.constructor = WindowImplBrowser;

WindowImplBrowser.prototype.setSize = function(width,height,pixelRatio){
    pixelRatio = pixelRatio === undefined ? this.pixelRatio : pixelRatio;

    setCanvasSize(this.canvas, width, height, pixelRatio);
    this.width  = width * pixelRatio;
    this.height = height * pixelRatio;
    this.pixelRatio = pixelRatio;
};

WindowImplBrowser.prototype.setFullScreen = function(enable){
    var isDocumentFullScreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;

    if((enable && this.fullScreen && isDocumentFullScreen) ||
        (!enable && !this.fullScreen && !isDocumentFullScreen)){
        return;
    }

    if(enable){
        var canvas = this.canvas;
        this.fullScreen = true;

        if(canvas.requestFullScreen){
            canvas.requestFullScreen();
        }
        else if(canvas.webkitRequestFullScreen){
            canvas.webkitRequestFullScreen();
        }
        else if(canvas.mozRequestFullScreen){
            canvas.mozRequestFullScreen();
        }
    }
    else {
        this.fullScreen = false;

        if(document.exitFullscreen){
            document.exitFullscreen();
        }
        else if(document.webkitExitFullscreen){
            document.webkitExitFullscreen();
        }
        else if(document.mozCancelFullScreen){
            document.mozCancelFullScreen();
        }
    }
};

WindowImplBrowser.create = function(windowPex,settings){
    var canvas  = settings.canvas || document.createElement('canvas');

    var width, height;
    var pixelRatio = settings.pixelRatio || 1;
    if(settings.fullScreen){
        width = isiOS9 ? document.documentElement.clientWidth : window.innerWidth;
        height = isiOS9 ? document.documentElement.clientHeight : window.innerHeight;
    }
    else {
        width  = settings.width;
        height = settings.height;
    }

    var impl = new WindowImplBrowser();
    impl.canvas = canvas;
    impl.setSize(width,height,pixelRatio);

    var mouse = windowPex._mouse;

    impl.canvas.addEventListener('mousedown', function(e) {
        mouse.handleMouseDown({
            x        : e.offsetX * pixelRatio,
            y        : e.offsetY * pixelRatio,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    impl.canvas.addEventListener('mouseup', function(e) {
        mouse.handleMouseUp({
            x        : e.offsetX * pixelRatio,
            y        : e.offsetY * pixelRatio,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    impl.canvas.addEventListener('mousemove', function(e) {
        mouse.handleMouseMove({
            x        : e.offsetX * pixelRatio,
            y        : e.offsetY * pixelRatio,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    var lastTouch = null;
    impl.canvas.addEventListener('touchstart', function(e) {
        var touches = Array.prototype.slice.call(e.touches).map(function(touch) {
            touch.x = touch.clientX * pixelRatio;
            touch.y = touch.clientY * pixelRatio;
            return touch;
        })
        lastTouch = touches[0];
        mouse.handleMouseDown({
            x        : touches[0].x,
            y        : touches[0].y,
            altKey   : false,
            shiftKey : false,
            ctrlKey  : false,
            metaKey  : false,
            touches  : touches
        });
        e.preventDefault();
        e.stopPropagation();
        return false;
    })

    impl.canvas.addEventListener('touchend', function(e) {
        var touches = Array.prototype.slice.call(e.touches).map(function(touch) {
            touch.x = touch.clientX * pixelRatio;
            touch.y = touch.clientY * pixelRatio;
            return touch;
        })
        mouse.handleMouseUp({
            x        : lastTouch.x,
            y        : lastTouch.y,
            altKey   : false,
            shiftKey : false,
            ctrlKey  : false,
            metaKey  : false,
            touches  : touches
        });
        lastTouch = null;
        e.preventDefault();
        e.stopPropagation();
        return false;
    })

    impl.canvas.addEventListener('touchmove', function(e) {
        var touches = Array.prototype.slice.call(e.touches).map(function(touch) {
            touch.x = touch.clientX * pixelRatio;
            touch.y = touch.clientY * pixelRatio;
            return touch;
        })
        mouse.handleMouseMove({
            x        : touches[0].x,
            y        : touches[0].y,
            altKey   : false,
            shiftKey : false,
            ctrlKey  : false,
            metaKey  : false,
            touches  : touches
        });
        e.preventDefault();
        e.stopPropagation();
        return false;
    })

    var mouseWheelEvent = /Firefox/i.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel';
    //FIXME: horizontal scroll in the browser? What is .detail?
    window.addEventListener(mouseWheelEvent, function(e) {
        var dx = 0;
        var dy = e.wheelDelta / 10 || -e.detail / 10;
        mouse.handleMouseScroll({
            dx       : dx,
            dy       : dy,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    var keyboard = windowPex._keyboard;

    window.addEventListener('keydown', function(e) {
        keyboard.handleKeyDown({
            str      : '',
            keyCode  : e.keyCode,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    window.addEventListener('keypress', function(e) {
        keyboard.handleKeyPress({
            str      : String.fromCharCode(e.charCode),
            keyCode  : e.keyCode,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    window.addEventListener('keyup', function(e) {
        keyboard.handleKeyUp({
            str      : '',
            keyCode  : e.keyCode,
            altKey   : e.altKey,
            shiftKey : e.shiftKey,
            ctrlKey  : e.ctrlKey,
            metaKey  : e.metaKey
        });
    });

    window.addEventListener('resize', function(e) {
        e.width = isiOS9 ? document.documentElement.clientWidth : window.innerWidth;
        e.height = isiOS9 ? document.documentElement.clientHeight : window.innerHeight;
        if(settings.fullScreen) {
            impl.setSize(e.width, e.height, settings.pixelRatio);
        }

        impl.dispatchEvent(new WindowEvent(WindowEvent.WINDOW_RESIZE, e));
    });

    function drawLoop(now){
        windowPex._time._update(now);
        if (settings.debug) {
            try {
                windowPex.draw();
                raf(drawLoop);
            }
            catch(e) {
                console.log(e);
                console.log(e.stack);
            }
        }
        else {
            windowPex.draw()
            raf(drawLoop);
        }
    }

    function go(){
        if (!settings.canvas) {
            //we careted new canvas, so we need to add it to the DOM
            document.body.appendChild(canvas);
        }

        impl.width    = width * pixelRatio;
        impl.height   = height * pixelRatio;
        impl.pixelRatio = pixelRatio;

        if (settings.type == '2d') {
            windowPex._ctx = canvas.getContext('2d');
        }
        else {
            var options = Object.assign({}, DefaultWebGLContextOptions, settings);

            var gl = getWebGLContext(canvas,options);
            if(gl === null){
                throw new Error('WindowImplBrowser: No WebGL context is available.');
            }

            if (settings.debug) {
                function throwOnGLError(err, funcName, args) {
                    throw new Error('WindowImplBrowser ' + WebGLDebugUtils.glEnumToString(err) + " was caused by call to " + funcName);
                };
                gl = WebGLDebugUtils.makeDebugContext(gl, throwOnGLError);
            }

            windowPex._ctx = new Context(gl);
        }

        setTimeout(function() {
            impl.dispatchEvent(new WindowEvent(WindowEvent.WINDOW_READY, {}));
            drawLoop(0);
        }, 1)
    }

    if(!canvas.parentNode){
        //Window already loaded, or script inside body
        if (document.body) {
            go();
        }
        //Wait for window to load
        else {
            window.addEventListener('load',function(){
                go();
            },false);
        }
    }
    else{
        //Canvas element node already attached, ready to go
        go();
    }

    return impl;
};

module.exports = WindowImplBrowser;
<|endoftext|>