<commit_before>var mainModule = angular.module('app', []).
	controller("forumCtrl", function forumCtrl($scope, $window, $timeout, $http){
		$scope.currentProject = null;
		$scope.currentThread = null;
		$scope.show = "login";
		$scope.newProjectName = "";
		$scope.newThreadSubject = "";
		$scope.newThreadMessage = "";
		$scope.newPost = "";

		$scope.openThreads = function(project){
			$scope.show = "threads";
			$scope.currentProject = project;
		}

		$scope.openPosts = function(thread){
			$scope.show = "posts";
			$scope.currentThread = thread;
		}

		$scope.createProject = function(){
			$scope.projects.push({id: $scope.projects.length, name: $scope.newProjectName, threads: []});
			$scope.newProjectName = "";
			$scope.show="projects";
		}

		$scope.createThread = function(){
			$scope.currentProject.threads.push({
				id: $scope.currentProject.threads.length,
				subject: $scope.newThreadSubject,
				posts: [{id: 0, userID: 0, message: $scope.newThreadMessage}]
			})
			$scope.newThreadSubject = "";
			$scope.newThreadMessage = "";
			$scope.show="threads";
		}

		$scope.sendPost = function(){
			$scope.currentThread.posts.push({
				id: $scope.currentThread.posts.length,
				userID: 2,
				message: $scope.newPost
			});

			$scope.newPost= "";
		}

		$scope.users = [
			{
				id: 0,
				firstName: "Michal",
				surname: "Paszkiewicz",
				imageURL: "http://www.gravatar.com/avatar/f8231ccab5f14c6499e32e17700399d9?d=wavatar",
				websiteURL: "http://www.michalpaszkiewicz.co.uk",
				experience: "8 years live guitar playing",
				skills: "Software",
				openToPublic: true
			},
			{
				id: 1,
				firstName: "Aaron",
				surname: "Dennis",
				imageURL: "https://avatars3.githubusercontent.com/u/9275082?v=3&amp",
				websiteURL: "https://aaronjden.github.io",
				experience: "Lots of good experience",
				skills: "Software",
				openToPublic: true
			},
			{
				id: 2,
				firstName: "Dave",
				surname: "Da rave",
				imageURL: "https://avatars2.githubusercontent.com/u/8076321?v=3&amp",
				websiteURL: "http://tametheboardgame.com/",
				experience: "40 years in the circus industry",
				skills: "Juggling",
				openToPublic: true
			}
		];

		$scope.getItemFromID = function(array, id)
		{
			for(var i = 0; i < array.length; i++){
				if(array[i].id == id){
					return array[i];
				}
			}
			return false;
		}

		$scope.getIndexFromID = function(array, id)
		{
			for(var i = 0; i < array.length; i++){
				if(array[i].id == id){
					return i;
				}
			}
			return false;
		}

		$scope.projects = [
			{
				id: 0,
				name: "Prince of Egypt",
				threads: [
					{
						id: 0,
						projectID: 0,
						subject: "when to do this",
						posts: [
							{
								id: 0,
								userID: 0,
								threadID: 0,
								projectID: 0,
								date: "2014",
								message: "hi"
							},
							{
								id: 1,
								userID: 2,
								threadID: 0,								threadID: 0,
								projectID: 0,
								date: "2014",
								message: "hi"
							}
						]
					},
					{
						id: 1,
						projectID: 0,
						subject: "stuff and things",
						posts: [
							{
								id: 2,
								userID: 1,
								threadID: 1,
								projectID: 0,
								date: "2014",
								message: "yo"
							},
							{
								id: 3,
								userID: 2,
								threadID: 1,
								projectID: 0,
								date: "2014",
								message: "kazaa"
							}
						]
					}
				]
			},
			{
				id: 1,
				name: "The Lion King",
				threads: [
					{
						id: 0,
						projectID: 0,
						subject: "when to do this",
						posts: [
							{
								id: 0,
								userID: 0,
								threadID: 0,
								projectID: 0,
								date: "2014",
								message: "hi"
							},
							{
								id: 1,
								userID: 2,
								threadID: 0,								threadID: 0,
								projectID: 0,
								date: "2014",
								message: "hi"
							}
						]
					},
					{
						id: 1,
						projectID: 0,
						subject: "stuff and things",
						posts: [
							{
								id: 2,
								userID: 1,
								threadID: 1,
								projectID: 0,
								date: "2014",
								message: "yo"
							},
							{
								id: 3,
								userID: 2,
								threadID: 1,
								projectID: 0,
								date: "2014",
								message: "kazaa"
							}
						]
					}
				]
			}
		];

		//todo: change this later to be assigned on login.
		$scope.currentUser = $scope.users[0];

	}).directive('selectOnClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('click', function () {
                this.select();
            });
        }
    };
});
<commit_msg>Update forum.js<commit_after>var mainModule = angular.module('app', []).
	controller("forumCtrl", function forumCtrl($scope, $window, $timeout, $http){
		$scope.currentProject = null;
		$scope.currentThread = null;
		$scope.show = "login";
		$scope.newProjectName = "";
		$scope.newThreadSubject = "";
		$scope.newThreadMessage = "";
		$scope.newPost = "";

		$scope.openThreads = function(project){
			$scope.show = "threads";
			$scope.currentProject = project;
		}

		$scope.openPosts = function(thread){
			$scope.show = "posts";
			$scope.currentThread = thread;
		}

		$scope.createProject = function(){
			$scope.projects.push({id: $scope.projects.length, name: $scope.newProjectName, threads: []});
			$scope.newProjectName = "";
			$scope.show="projects";
		}

		$scope.createThread = function(){
			$scope.currentProject.threads.push({
				id: $scope.currentProject.threads.length,
				subject: $scope.newThreadSubject,
				posts: [{id: 0, userID: 0, message: $scope.newThreadMessage}]
			})
			$scope.newThreadSubject = "";
			$scope.newThreadMessage = "";
			$scope.show="threads";
		}

		$scope.sendPost = function(){
			$scope.currentThread.posts.push({
				id: $scope.currentThread.posts.length,
				userID: 2,
				message: $scope.newPost
			});

			$scope.newPost= "";
		}

		$scope.users = [
			{
				id: 0,
				firstName: "Michal",
				surname: "Paszkiewicz",
				imageURL: "http://www.gravatar.com/avatar/f8231ccab5f14c6499e32e17700399d9?d=wavatar",
				websiteURL: "http://www.michalpaszkiewicz.co.uk",
				experience: "8 years live guitar playing",
				skills: "Software",
				openToPublic: true
			},
			{
				id: 1,
				firstName: "Aaron",
				surname: "Dennis",
				imageURL: "https://avatars3.githubusercontent.com/u/9275082?v=3&amp",
				websiteURL: "https://aaronjden.github.io",
				experience: "Lots of good experience",
				skills: "Software",
				openToPublic: true
			},
			{
				id: 2,
				firstName: "Dave",
				surname: "Da rave",
				imageURL: "https://avatars2.githubusercontent.com/u/8076321?v=3&amp",
				websiteURL: "http://tametheboardgame.com/",
				experience: "40 years in the circus industry",
				skills: "Juggling",
				openToPublic: true
			}
		];

		$scope.getItemFromID = function(array, id)
		{
			for(var i = 0; i < array.length; i++){
				if(array[i].id == id){
					return array[i];
				}
			}
			return false;
		}

		$scope.getIndexFromID = function(array, id)
		{
			for(var i = 0; i < array.length; i++){
				if(array[i].id == id){
					return i;
				}
			}
			return false;
		}

		$scope.projects = [
			{
				id: 0,
				name: "Prince of Egypt",
				threads: [
					{
						id: 0,
						projectID: 0,
						subject: "when to do this",
						posts: [
							{
								id: 0,
								userID: 0,
								threadID: 0,
								projectID: 0,
								date: "2014",
								message: "hi"
							},
							{
								id: 1,
								userID: 2,
								threadID: 0,								threadID: 0,
								projectID: 0,
								date: "2014",
								message: "hi"
							}
						]
					},
					{
						id: 1,
						projectID: 0,
						subject: "stuff and things",
						posts: [
							{
								id: 2,
								userID: 1,
								threadID: 1,
								projectID: 0,
								date: "2014",
								message: "yo"
							},
							{
								id: 3,
								userID: 2,
								threadID: 1,
								projectID: 0,
								date: "2014",
								message: "kazaa"
							}
						]
					}
				]
			},
			{
				id: 1,
				name: "The Lion King",
				threads: [
					{
						id: 0,
						projectID: 0,
						subject: "when to do this",
						posts: [
							{
								id: 0,
								userID: 0,
								threadID: 0,
								projectID: 0,
								date: "2014",
								message: "hi"
							},
							{
								id: 1,
								userID: 2,
								threadID: 0,								threadID: 0,
								projectID: 0,
								date: "2014",
								message: "hi"
							}
						]
					},
					{
						id: 1,
						projectID: 0,
						subject: "stuff and things",
						posts: [
							{
								id: 2,
								userID: 1,
								threadID: 1,
								projectID: 0,
								date: "2014",
								message: "yo"
							},
							{
								id: 3,
								userID: 2,
								threadID: 1,
								projectID: 0,
								date: "2014",
								message: "kazaa"
							}
						]
					}
				]
			}
		];

		//todo: change this later to be assigned on login.
		$scope.currentUser = $scope.users[0];
		$scope.loggedIn = false;
		$scope.loginFailed = false;

		$scope.login = function(){
			if(true){
				$scope.loginFailed = false;
				$scope.loggedIn = true;
				$scope.show = 'projects';
			}
			else{
				$scope.loginFailed = true;
			}
		}

	}).directive('selectOnClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('click', function () {
                this.select();
            });
        }
    };
});
<|endoftext|>


<commit_before>//Main class that represents one simulation, including the tabs, home screen, play area, etc.
//Provides default initialization, such as polyfills as well.
define( function( require ) {
  'use strict';

  var Fort = require( 'FORT/Fort' );
  var Util = require( 'SCENERY/util/Util' );
  var NavigationBar = require( 'SCENERY_PHET/NavigationBar' );
  var HomeScreen = require( 'SCENERY_PHET/HomeScreen' );
  var Scene = require( 'SCENERY/Scene' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Layout = require( 'SCENERY_PHET/Layout' );

  //Default size to use, which will be scaled up and down isometrically
  var HEIGHT = Layout.simHeight;
  var WIDTH = Layout.simWidth;

  /**
   *
   * @param name
   * @param tabs
   * @param options optional parameters for starting tab and home values, so that developers can easily specify the startup scenario for quick development
   * @constructor
   */
  function Sim( name, tabs, options ) {
    var sim = this;

    //Default values are to show the home screen with the 1st tab selected
    options = options || {};
    var home = options.home || false;
    var tab = options.tab || 0;

    this.tabs = tabs;

    Util.polyfillRequestAnimationFrame();

    //This model represents where the simulation is, whether it is on the home screen or a tab, and which tab it is on or is highlighted in the home screen
    this.appModel = new Fort.Model( {home: home, tab: tab} );

    this.scene = new Scene( $( '.scene' ), {width: WIDTH, height: HEIGHT, allowDevicePixelRatioScaling: true} );
    this.scene.initializeStandaloneEvents(); // sets up listeners on the document with preventDefault(), and forwards those events to our scene
    this.scene.resizeOnWindowResize(); // the scene gets resized to the full screen size

    var homeScreen = new HomeScreen( name, tabs, this.appModel );
    var navigationBar = new NavigationBar( tabs, this.appModel ).mutate( {bottom: HEIGHT - 2} );//TODO: this padding amount is copied in NavigationBar

    //The root contains the home screen or the tabNode
    var root = new Node(); //root: homeScreen | tabNode

    //The tab container contains the tab itself, which will be swapped out based on which tab icon the user selected
    var tabContainer = new Node();//tabContainer: sceneForTab

    //The tabNode contains the tabContainer and the navigation bar
    var tabNode = new Node( {children: [navigationBar, tabContainer]} );
    this.scene.addChild( root );

    //When the user presses the home icon, then show the home screen, otherwise show the tabNode
    this.appModel.link( 'home', function( home ) { root.children = [home ? homeScreen : tabNode];} );

    function resize() {

      //TODO: This will have to change when sims are embedded on a page instead of taking up an entire page
      var width = $( window ).width();
      var height = $( window ).height();

      var scale = Math.min( width / WIDTH, height / HEIGHT );
      sim.scene.resetTransform();
      sim.scene.setScaleMagnitude( scale );

      //center vertically
      if ( scale === width / WIDTH ) {
        sim.scene.translate( 0, (height - HEIGHT * scale) / 2 / scale );
      }

      //center horizontally
      else if ( scale === height / HEIGHT ) {
        sim.scene.translate( (width - WIDTH * scale) / 2 / scale, 0 );
      }

      //Redraw if necessary, in case the animation loop hasn't started yet
      sim.scene.updateScene();
    }

    //Instantiate the tabs
    for ( var i = 0; i < tabs.length; i++ ) {
      tabs[i].instance = tabs[i].create();
    }

    //When the user presses a different tab, show it on the screen
    this.appModel.link( 'tab', function( tabIndex ) { tabContainer.children = [tabs[tabIndex].instance]; } );

    //Fit to the window and render the initial scene
    $( window ).resize( resize );
    resize();
  }

  Sim.prototype.start = function() {
    var sim = this;

    // place the rAF *before* the render() to assure as close to 60fps with the setTimeout fallback.
    //http://paulirish.com/2011/requestanimationframe-for-smart-animating/
    (function animationLoop() {
      requestAnimationFrame( animationLoop );

      //Update the tab, but not if the user is on the home screen
      if ( !sim.appModel.home ) {
        sim.tabs[sim.appModel.tab].instance.model.step();
      }
      sim.scene.updateScene();
    })();
  };

  return Sim;
} );<commit_msg>added docs<commit_after>//Main class that represents one simulation, including the tabs, home screen, play area, etc.
//Provides default initialization, such as polyfills as well.
//TODO: Handle simulations that have only one tab.  Perhaps just show the name at the left and the logo at the right, and omit home screen
define( function( require ) {
  'use strict';

  var Fort = require( 'FORT/Fort' );
  var Util = require( 'SCENERY/util/Util' );
  var NavigationBar = require( 'SCENERY_PHET/NavigationBar' );
  var HomeScreen = require( 'SCENERY_PHET/HomeScreen' );
  var Scene = require( 'SCENERY/Scene' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Layout = require( 'SCENERY_PHET/Layout' );

  //Default size to use, which will be scaled up and down isometrically
  var HEIGHT = Layout.simHeight;
  var WIDTH = Layout.simWidth;

  /**
   *
   * @param name
   * @param tabs
   * @param options optional parameters for starting tab and home values, so that developers can easily specify the startup scenario for quick development
   * @constructor
   */
  function Sim( name, tabs, options ) {
    var sim = this;

    //Default values are to show the home screen with the 1st tab selected
    options = options || {};
    var home = options.home || false;
    var tab = options.tab || 0;

    this.tabs = tabs;

    Util.polyfillRequestAnimationFrame();

    //This model represents where the simulation is, whether it is on the home screen or a tab, and which tab it is on or is highlighted in the home screen
    this.appModel = new Fort.Model( {home: home, tab: tab} );

    this.scene = new Scene( $( '.scene' ), {width: WIDTH, height: HEIGHT, allowDevicePixelRatioScaling: true} );
    this.scene.initializeStandaloneEvents(); // sets up listeners on the document with preventDefault(), and forwards those events to our scene
    this.scene.resizeOnWindowResize(); // the scene gets resized to the full screen size

    var homeScreen = new HomeScreen( name, tabs, this.appModel );
    var navigationBar = new NavigationBar( tabs, this.appModel ).mutate( {bottom: HEIGHT - 2} );//TODO: this padding amount is copied in NavigationBar

    //The root contains the home screen or the tabNode
    var root = new Node(); //root: homeScreen | tabNode

    //The tab container contains the tab itself, which will be swapped out based on which tab icon the user selected
    var tabContainer = new Node();//tabContainer: sceneForTab

    //The tabNode contains the tabContainer and the navigation bar
    var tabNode = new Node( {children: [navigationBar, tabContainer]} );
    this.scene.addChild( root );

    //When the user presses the home icon, then show the home screen, otherwise show the tabNode
    this.appModel.link( 'home', function( home ) { root.children = [home ? homeScreen : tabNode];} );

    function resize() {

      //TODO: This will have to change when sims are embedded on a page instead of taking up an entire page
      var width = $( window ).width();
      var height = $( window ).height();

      var scale = Math.min( width / WIDTH, height / HEIGHT );
      sim.scene.resetTransform();
      sim.scene.setScaleMagnitude( scale );

      //center vertically
      if ( scale === width / WIDTH ) {
        sim.scene.translate( 0, (height - HEIGHT * scale) / 2 / scale );
      }

      //center horizontally
      else if ( scale === height / HEIGHT ) {
        sim.scene.translate( (width - WIDTH * scale) / 2 / scale, 0 );
      }

      //Redraw if necessary, in case the animation loop hasn't started yet
      sim.scene.updateScene();
    }

    //Instantiate the tabs
    for ( var i = 0; i < tabs.length; i++ ) {
      tabs[i].instance = tabs[i].create();
    }

    //When the user presses a different tab, show it on the screen
    this.appModel.link( 'tab', function( tabIndex ) { tabContainer.children = [tabs[tabIndex].instance]; } );

    //Fit to the window and render the initial scene
    $( window ).resize( resize );
    resize();
  }

  Sim.prototype.start = function() {
    var sim = this;

    // place the rAF *before* the render() to assure as close to 60fps with the setTimeout fallback.
    //http://paulirish.com/2011/requestanimationframe-for-smart-animating/
    (function animationLoop() {
      requestAnimationFrame( animationLoop );

      //Update the tab, but not if the user is on the home screen
      if ( !sim.appModel.home ) {
        sim.tabs[sim.appModel.tab].instance.model.step();
      }
      sim.scene.updateScene();
    })();
  };

  return Sim;
} );<|endoftext|>


<commit_before>module.exports = function(data){
    var output = [];

    Object.keys(data).sort().forEach(function(filename){
        var error = data[filename];
        output.push('    ' + filename);
        if (error) {
            if (Array.isArray(error)) {
                output.push.apply(output, error.map(function(item){
                    return '        * ' + String(item.error.message || item.error).replace(/\n/g, '\n            ');
                }));
            } else {
                output.push('[ERROR] ' + error);
            }
        }
        output.push('');
    });

    return output.join('\n');
};
<commit_msg>better message output for default reporter<commit_after>module.exports = function(data){
    var output = [];

    Object.keys(data).sort().forEach(function(filename){
        var error = data[filename];
        output.push('    ' + filename);
        if (error) {
            if (Array.isArray(error)) {
                output.push.apply(output, error.map(function(item){
                    return '        * ' +
                        String(item.error.message || item.error)
                            .replace(/^[^\n]+/, item.message)
                            .replace(/\n/g, '\n            ');
                }));
            } else {
                output.push('[ERROR] ' + error);
            }
        }
        output.push('');
    });

    return output.join('\n');
};
<|endoftext|>


<commit_before>/**
 * MBP - Mobile boilerplate helper functions
 */

(function(document) {

	window.MBP = window.MBP || {};

	/**
	 * Fix for iPhone viewport scale bug
	 * http://www.blog.highub.com/mobile-2/a-fix-for-iphone-viewport-scale-bug/
	 */

	MBP.viewportmeta = document.querySelector && document.querySelector('meta[name="viewport"]');
	MBP.ua = navigator.userAgent;

	MBP.scaleFix = function() {
		if (MBP.viewportmeta && /iPhone|iPad|iPod/.test(MBP.ua) && !/Opera Mini/.test(MBP.ua)) {
			MBP.viewportmeta.content = 'width=device-width, minimum-scale=1.0, maximum-scale=1.0';
			document.addEventListener('gesturestart', MBP.gestureStart, false);
		}
	};

	MBP.gestureStart = function() {
		MBP.viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
	};

	/**
	 * Normalized hide address bar for iOS & Android
	 * (c) Scott Jehl, scottjehl.com
	 * MIT License
	 */

	// If we split this up into two functions we can reuse
	// this function if we aren't doing full page reloads.

	// If we cache this we don't need to re-calibrate everytime we call
	// the hide url bar
	MBP.BODY_SCROLL_TOP = false;

	// So we don't redefine this function everytime we
	// we call hideUrlBar
	MBP.getScrollTop = function() {
		var win = window;
		var doc = document;

		return win.pageYOffset || doc.compatMode === 'CSS1Compat' && doc.documentElement.scrollTop || doc.body.scrollTop || 0;
	};

	// It should be up to the mobile
	MBP.hideUrlBar = function() {
		var win = window;

		// if there is a hash, or MBP.BODY_SCROLL_TOP hasn't been set yet, wait till that happens
		if (!location.hash && MBP.BODY_SCROLL_TOP !== false) {
			win.scrollTo( 0, MBP.BODY_SCROLL_TOP === 1 ? 0 : 1 );
		}
	};

	MBP.hideUrlBarOnLoad = function() {
		var win = window;
		var doc = win.document;
		var bodycheck;

		// If there's a hash, or addEventListener is undefined, stop here
		if ( !location.hash && win.addEventListener ) {

			// scroll to 1
			window.scrollTo( 0, 1 );
			MBP.BODY_SCROLL_TOP = 1;

			// reset to 0 on bodyready, if needed
			bodycheck = setInterval(function() {
				if ( doc.body ) {
					clearInterval( bodycheck );
					MBP.BODY_SCROLL_TOP = MBP.getScrollTop();
					MBP.hideUrlBar();
				}
			}, 15 );

			win.addEventListener('load', function() {
				setTimeout(function() {
					// at load, if user hasn't scrolled more than 20 or so...
					if (MBP.getScrollTop() < 20) {
						// reset to hide addr bar at onload
						MBP.hideUrlBar();
					}
				}, 0);
			});
		}
	};

	/**
	 * Fast Buttons - read wiki below before using
	 * https://github.com/h5bp/mobile-boilerplate/wiki/JavaScript-Helper
	 */

	MBP.fastButton = function(element, handler, pressedClass) {
		this.handler = handler;
		// styling of .pressed is defined in the project's CSS files
		this.pressedClass = typeof pressedClass === 'undefined' ? 'pressed' : pressedClass;

		MBP.listenForGhostClicks();

		if (element.length && element.length > 1) {
			for (var singleElIdx in element) {
				this.addClickEvent(element[singleElIdx]);
			}
		} else {
			this.addClickEvent(element);
		}
	};

	MBP.fastButton.prototype.handleEvent = function(event) {
		event = event || window.event;

		switch (event.type) {
			case 'touchstart': this.onTouchStart(event); break;
			case 'touchmove': this.onTouchMove(event); break;
			case 'touchend': this.onClick(event); break;
			case 'click': this.onClick(event); break;
		}
	};

	MBP.fastButton.prototype.onTouchStart = function(event) {
		var element = event.target || event.srcElement;
		event.stopPropagation();
		element.addEventListener('touchend', this, false);
		document.body.addEventListener('touchmove', this, false);
		this.startX = event.touches[0].clientX;
		this.startY = event.touches[0].clientY;

		element.className+= ' ' + this.pressedClass;
	};

	MBP.fastButton.prototype.onTouchMove = function(event) {
		if (Math.abs(event.touches[0].clientX - this.startX) > 10 ||
			Math.abs(event.touches[0].clientY - this.startY) > 10) {
			this.reset(event);
		}
	};

	MBP.fastButton.prototype.onClick = function(event) {
		event = event || window.event;
		var element = event.target || event.srcElement;
		if (event.stopPropagation) {
			event.stopPropagation();
		}
		this.reset(event);
		this.handler.apply(event.currentTarget, [event]);
		if (event.type == 'touchend') {
			MBP.preventGhostClick(this.startX, this.startY);
		}
		var pattern = new RegExp(' ?' + this.pressedClass, 'gi');
		element.className = element.className.replace(pattern, '');
	};

	MBP.fastButton.prototype.reset = function(event) {
		var element = event.target || event.srcElement;
		rmEvt(element, 'touchend', this, false);
		rmEvt(document.body, 'touchmove', this, false);

		var pattern = new RegExp(' ?' + this.pressedClass, 'gi');
		element.className = element.className.replace(pattern, '');
	};

	MBP.fastButton.prototype.addClickEvent = function(element) {
		addEvt(element, 'touchstart', this, false);
		addEvt(element, 'click', this, false);
	};

	MBP.preventGhostClick = function(x, y) {
		MBP.coords.push(x, y);
		window.setTimeout(function() {
			MBP.coords.splice(0, 2);
		}, 2500);
	};

	MBP.ghostClickHandler = function(event) {
		if (!MBP.hadTouchEvent && MBP.dodgyAndroid) {
			// This is a bit of fun for Android 2.3...
			// If you change window.location via fastButton, a click event will fire
			// on the new page, as if the events are continuing from the previous page.
			// We pick that event up here, but MBP.coords is empty, because it's a new page,
			// so we don't prevent it. Here's we're assuming that click events on touch devices
			// that occur without a preceding touchStart are to be ignored.
			event.stopPropagation();
			event.preventDefault();
			return;
		}
		for (var i = 0, len = MBP.coords.length; i < len; i += 2) {
			var x = MBP.coords[i];
			var y = MBP.coords[i + 1];
			if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {
				event.stopPropagation();
				event.preventDefault();
			}
		}
	};

	// This bug only affects touch Android 2.3 devices, but a simple ontouchstart test creates a false positive on
	// some Blackberry devices. https://github.com/Modernizr/Modernizr/issues/372
	// The browser sniffing is to avoid the Blackberry case. Bah
	MBP.dodgyAndroid = ('ontouchstart' in window) && (navigator.userAgent.indexOf('Android 2.3') != -1);

	MBP.listenForGhostClicks = (function() {
		var alreadyRan = false;

		return function() {
			if(alreadyRan) {
				return;
			}

			if (document.addEventListener) {
				document.addEventListener('click', MBP.ghostClickHandler, true);
			}
			addEvt(document.documentElement, 'touchstart', function() {
				MBP.hadTouchEvent = true;
			}, false);

			alreadyRan = true;
		};
	})();

	MBP.coords = [];

	// fn arg can be an object or a function, thanks to handleEvent
	// read more about the explanation at: http://www.thecssninja.com/javascript/handleevent
	function addEvt(el, evt, fn, bubble) {
		if ('addEventListener' in el) {
			// BBOS6 doesn't support handleEvent, catch and polyfill
			try {
				el.addEventListener(evt, fn, bubble);
			} catch(e) {
				if (typeof fn == 'object' && fn.handleEvent) {
					el.addEventListener(evt, function(e){
						// Bind fn as this and set first arg as event object
						fn.handleEvent.call(fn,e);
					}, bubble);
				} else {
					throw e;
				}
			}
		} else if ('attachEvent' in el) {
			// check if the callback is an object and contains handleEvent
			if (typeof fn == 'object' && fn.handleEvent) {
				el.attachEvent('on' + evt, function(){
					// Bind fn as this
					fn.handleEvent.call(fn);
				});
			} else {
				el.attachEvent('on' + evt, fn);
			}
		}
	}

	function rmEvt(el, evt, fn, bubble) {
		if ('removeEventListener' in el) {
			// BBOS6 doesn't support handleEvent, catch and polyfill
			try {
				el.removeEventListener(evt, fn, bubble);
			} catch(e) {
				if (typeof fn == 'object' && fn.handleEvent) {
					el.removeEventListener(evt, function(e){
						// Bind fn as this and set first arg as event object
						fn.handleEvent.call(fn,e);
					}, bubble);
				} else {
					throw e;
				}
			}
		} else if ('detachEvent' in el) {
			// check if the callback is an object and contains handleEvent
			if (typeof fn == 'object' && fn.handleEvent) {
				el.detachEvent("on" + evt, function() {
					// Bind fn as this
					fn.handleEvent.call(fn);
				});
			} else {
				el.detachEvent('on' + evt, fn);
			}
		}
	}

	/**
	 * Autogrow
	 * http://googlecode.blogspot.com/2009/07/gmail-for-mobile-html5-series.html
	 */

	MBP.autogrow = function(element, lh) {
		function handler(e) {
			var newHeight = this.scrollHeight;
			var currentHeight = this.clientHeight;
			if (newHeight > currentHeight) {
				this.style.height = newHeight + 3 * textLineHeight + 'px';
			}
		}

		var setLineHeight = (lh) ? lh : 12;
		var textLineHeight = element.currentStyle ? element.currentStyle.lineHeight : getComputedStyle(element, null).lineHeight;

		textLineHeight = (textLineHeight.indexOf('px') == -1) ? setLineHeight : parseInt(textLineHeight, 10);

		element.style.overflow = 'hidden';
		element.addEventListener ? element.addEventListener('input', handler, false) : element.attachEvent('onpropertychange', handler);
	};

	/**
	 * Enable CSS active pseudo styles in Mobile Safari
	 * http://alxgbsn.co.uk/2011/10/17/enable-css-active-pseudo-styles-in-mobile-safari/
	 */

	MBP.enableActive = function() {
		document.addEventListener('touchstart', function() {}, false);
	};

	/**
	 * Prevent default scrolling on document window
	 */

	MBP.preventScrolling = function() {
		document.addEventListener('touchmove', function(e) {
			if (e.target.type === 'range') { return; }
			e.preventDefault();
		}, false);
	};

	/**
	 * Prevent iOS from zooming onfocus
	 * https://github.com/h5bp/mobile-boilerplate/pull/108
	 * Adapted from original jQuery code here: http://nerd.vasilis.nl/prevent-ios-from-zooming-onfocus/
	 */

	MBP.preventZoom = function() {
		var formFields = document.querySelectorAll('input, select, textarea');
		var contentString = 'width=device-width,initial-scale=1,maximum-scale=';
		var i = 0;
		var fieldLength = formFields.length;

		var setViewportOnFocus = function() {
			MBP.viewportmeta.content = contentString + '1';
		};

		var setViewportOnBlur = function() {
			MBP.viewportmeta.content = contentString + '10';
		};

		for (; i < fieldLength; i++) {
			formFields[i].onfocus = setViewportOnFocus;
			formFields[i].onblur = setViewportOnBlur;
		}
	};

	/**
	 * iOS Startup Image helper
	 */

	MBP.startupImage = function() {
		var portrait;
		var landscape;
		var pixelRatio;
		var head;
		var link1;
		var link2;

		pixelRatio = window.devicePixelRatio;
		head = document.getElementsByTagName('head')[0];

		if (navigator.platform === 'iPad') {
			portrait = pixelRatio === 2 ? 'img/startup/startup-tablet-portrait-retina.png' : 'img/startup/startup-tablet-portrait.png';
			landscape = pixelRatio === 2 ? 'img/startup/startup-tablet-landscape-retina.png' : 'img/startup/startup-tablet-landscape.png';

			link1 = document.createElement('link');
			link1.setAttribute('rel', 'apple-touch-startup-image');
			link1.setAttribute('media', 'screen and (orientation: portrait)');
			link1.setAttribute('href', portrait);
			head.appendChild(link1);

			link2 = document.createElement('link');
			link2.setAttribute('rel', 'apple-touch-startup-image');
			link2.setAttribute('media', 'screen and (orientation: landscape)');
			link2.setAttribute('href', landscape);
			head.appendChild(link2);
		} else {
			portrait = pixelRatio === 2 ? "img/startup/startup-retina.png" : "img/startup/startup.png";
			portrait = screen.height === 568 ? "img/startup/startup-retina-4in.png" : portrait;
			link1 = document.createElement('link');
			link1.setAttribute('rel', 'apple-touch-startup-image');
			link1.setAttribute('href', portrait);
			head.appendChild(link1);
		}

		//hack to fix letterboxed full screen web apps on 4" iPhone / iPod
		if (navigator.platform.match(/iPhone|iPod/i) && (screen.height === 568)) {
			if (MBP.viewportmeta) {
				MBP.viewportmeta.content = MBP.viewportmeta.content
					.replace(/\bwidth\s*=\s*320\b/, 'width=320.1')
					.replace(/\bwidth\s*=\s*device-width\b/, '');
			}
		}
	};
})(document);

/**
 * Sliding content
 */
(function ($) {

	'use strict';

	var Slider = $.extend(window.Slider || {}, {

		SlideContent: {

			element: $('.banner-main--feature')[0],

			isPointerEvents: window.navigator.msPointerEnabled,

			resetSlide: function () {
				var move = 'touchmove';
				var done = 'touchend';

				if (Slider.SlideContent.isPointerEvents) {
					$(Slider.SlideContent.element).css('-ms-touch-action', 'pan-y');

					move = 'MSPointerMove';
					done = 'MSPointerUp';
				}

				Slider.SlideContent.element.removeEventListener(move, Slider.SlideContent.onTouchMove, false);
				Slider.SlideContent.element.removeEventListener(done, Slider.SlideContent.onTouchEnd, false);

				Slider.SlideContent.startX = null;
				Slider.SlideContent.startY = null;
				Slider.SlideContent.dx = null;
			},

			onTouchStart: function (e) {
				var move = 'touchmove';
				var done = 'touchend';

				if (Slider.SlideContent.isPointerEvents) {
					$(Slider.SlideContent.element).css('-ms-touch-action', 'none');

					move = 'MSPointerMove';
					done = 'MSPointerUp';
				}

				Slider.SlideContent.element.addEventListener(move, Slider.SlideContent.onTouchMove, false);
				Slider.SlideContent.element.addEventListener(done, Slider.SlideContent.onTouchEnd, false);

				if (e.touches) {
					Slider.SlideContent.startX = e.touches[0].pageX;
					Slider.SlideContent.startY = e.touches[0].pageY;
				} else {
					Slider.SlideContent.startX = e.pageX;
					Slider.SlideContent.startY = e.pageY;
				}
				Slider.SlideContent.cwidth = Slider.SlideContent.element.offsetWidth;
			},

			onTouchMove: function (e) {
				if (e.touches) {
					Slider.SlideContent.dx = Slider.SlideContent.startX - e.touches[0].pageX;
					Slider.SlideContent.scrolling = Math.abs(Slider.SlideContent.dx) < Math.abs(Slider.SlideContent.startY - e.touches[0].pageY);
				} else {
					Slider.SlideContent.dx = Slider.SlideContent.startX - e.pageX;
					Slider.SlideContent.scrolling = Math.abs(Slider.SlideContent.dx) < Math.abs(Slider.SlideContent.startY - e.pageY);
				}

				if (!Slider.SlideContent.scrolling) {
					e.preventDefault();

					Slider.SlideContent.dx = (function () {
						return Slider.SlideContent.dx / Slider.SlideContent.cwidth;
					}());
				} else {
					Slider.SlideContent.resetSlide();
				}

			},

			onTouchEnd: function () {

				// Call next slide if possible
				if (Slider.SlideContent.dx !== null &&
						Slider.SlideContent.dx > 0.4) {
					var SliderIndexActive = window.location.hash.replace( /^\D+/g, '');
					var newSliderIndex = parseInt(SliderIndexActive)+parseInt(1);
					$('.slider-content').find('#slide-'+newSliderIndex).trigger('click');
				}

				// Call previous slide if possible
				if (Slider.SlideContent.dx !== null &&
						Slider.SlideContent.dx < -0.4) {
					var SliderIndexActive = window.location.hash.replace( /^\D+/g, '');
					var newSliderIndex = parseInt(SliderIndexActive)-parseInt(1);

					$('.slider-content').find('#slide-'+newSliderIndex).trigger('click');
				}

				// Finish the touch by undoing the touch session
				Slider.SlideContent.resetSlide();
			},

			// Initialize touch events
			init: function () {
				var touchEvent = 'touchstart';

				if (this.element.addEventListener) {

					// Detect Pointer Events
					if (Slider.SlideContent.isPointerEvents) {
						touchEvent = 'MSPointerDown';
						$(Slider.SlideContent.element).css('-ms-touch-action', 'pan-y');
					}

					this.element.addEventListener(touchEvent, Slider.SlideContent.onTouchStart, false);
				}
			}
		}
	});

	window.Slider = Slider;

}(jQuery));<commit_msg>remove unnecessary helpers<commit_after><|endoftext|>


<commit_before>$(function(){
  var $input = $('#input');
  var input = $input.get(0);
  $input.val('');
  var ime = false;
  input.focus();
  $input.blur(function(){input.focus();}).focusout(function(){input.focus();});
  setInterval(function(){$('#input:focus').length == 0 ? input.focus() : '';}, 100);
  var keyEventMap = {};
  var modes = {default: keyEventMap};
  var current_mode = 'default';
  var buffers = {'*scratch*' : new Buffer('#editor')};
  var current_buffer_title = '*scratch*';
  var buffer = buffers[current_buffer_title];

  var $d = $(document);
  var $footer = $('#footer');

  var past_input = null;
  var keyDown = null;
  var keyDownHit = false;

  prepareKeyEventMap();

  function invokeHandler(input){
    if(past_input){
      past_input = input = past_input + input;
      $footer.text(past_input);
    }
    var func = modes[current_mode][input];
    if(func){
      func({buffer:buffer});
      var pos = buffer.getCursorPosition();
      $footer.text('(' + pos.row+','+pos.column+')');
    } else {
      past_input = null;
      $footer.text('');
    }
  }

  $d.bind('compositionstart', function(e){
    ime = true;
    $input.css(buffer.$c.position());
    $input.css('z-index', '100');
  }).bind('compositionend', function(e){

    var timer = setInterval(function(){
      if(!ime){
        $input.val().split('').forEach(function(c){buffer.insertChar(c);});
        $input.val('');
        clearInterval(timer);
        $input.css('z-index', '1');
        var pos = buffer.getCursorPosition();
        $footer.text('(' + pos.row+','+pos.column+')');
      }
    },10);
    ime = false;
  });;

  $d.keypress(function(e){
    var mod = (e.altKey ? 'A' : '') + (e.shiftKey ? 'S' : '') + (e.metaKey ? 'M' : '') + (e.ctrlKey ? 'C' : '');
    if(!keyDownHit || mod){
      var char = String.fromCharCode(e.charCode);
      var input = null;
      if(mod.match(/(A|M|C){1,3}/)){
        input = mod + '-' + String.fromCharCode(keyDown).toLowerCase();
        keyDown = null;
      } else {
        input = mod ? mod + '-' + char : char;
      }
      if(input){
        // console.log('charCode: ' + e.charCode);
        // console.log('keyCode: ' + e.keyCode);
        // console.log('converted char: ' + char);
        // console.log('char: ' + e.char);
        // console.log('key: ' + e.key);
        // console.log('input: ' + input);
        // console.log('---');
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
        invokeHandler(input);
      }
    }
    keyDownHit = false;
  }).keydown(function(e){
    var mod = (e.altKey ? 'A' : '') + (e.shiftKey ? 'S' : '') + (e.metaKey ? 'M' : '') + (e.ctrlKey ? 'C' : '');
    keyDown = e.keyCode;

    var input = null;
    if(mod.match(/(A|M|C){1,3}/)){
      input = mod + '-' + String.fromCharCode(keyDown).toLowerCase();
      keyDown = null;
    } else {
      input = vkCodeMap[keyDown];
    }
    // console.log('keydown: ' + keyDown);

    if(input){
      e.preventDefault();
      e.stopPropagation();
      e.stopImmediatePropagation();
      if(past_input){
        input = past_input + input;
      }
      var func = modes[current_mode][input];
      if(func){
        func({buffer:buffer});
        var pos = buffer.getCursorPosition();
        $footer.text('(' + pos.row+','+pos.column+')');
      } else {

        keyDownHit = !!keyDown;
      }
    }
  });

  function prepareKeyEventMap(){
    prepareBasicKeyInputHandler();
    prepareCursorOperationHandler();
    prepareCombinationSequences();

    function prepareBasicKeyInputHandler(){
      for(var code=32;code <= 126; code++){
        var char = String.fromCharCode(code);
        // console.log(char);
        var handler = generateKeyInputHandler(char);
        keyEventMap[char] = handler;
        keyEventMap['S-' + char] = handler;
      }
      keyEventMap['C-m'] = keyEventMap['Enter'] = generateKeyInputHandler(buffer.lineDelimiter || '\n');
      keyEventMap['C-h'] = keyEventMap['Backspace'] = backspace;
      keyEventMap['C-d'] = keyEventMap['Del'] = deleteChar;
    }

    function prepareCombinationSequences(){
      setKeepSequenceHandler('C-x');
      setKeepSequenceHandler('C-c');
      keyEventMap['C-xk'] = reset;
    }

    function setKeepSequenceHandler(sequence){
      keyEventMap[sequence] = function(opt){
        past_input = sequence;
        $footer.text(past_input);
        // console.log(past_input);
      };
    }

    function generateKeyInputHandler(char){
      return function(opt){
        // console.log('#' + char + '#');
        var buffer = opt.buffer;
        buffer.insertChar(char);
      };
    }

    function reset(opt){
      var buffer = opt.buffer;
      buffer.reset();
    }

    function backspace(opt){
      var buffer = opt.buffer;
      buffer.backspace();
    }

    function deleteChar(opt){
      var buffer = opt.buffer;
      buffer.delete();
    }

    function prepareCursorOperationHandler(){
      keyEventMap['C-b'] = keyEventMap['Left'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorHorizontally(-1);
      };
      keyEventMap['C-f'] = keyEventMap['Right'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorHorizontally(+1);
      };
      keyEventMap['C-p'] = keyEventMap['Up'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorVertically(-1);
      };
      keyEventMap['C-n'] = keyEventMap['Down'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorVertically(+1);
      };
      keyEventMap['C-a'] = keyEventMap['Home'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorToBOL();
      };
      keyEventMap['C-e'] = keyEventMap['End'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorToEOL();
      };

    }

  }

});

function Buffer(selector){
  this.init.apply(this, arguments);
};

function generate_uuid(){
  return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4() +S4());
  function S4 () {
    return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
  }
}

Buffer.prototype.reset = function(){
  var uuid = this.uuid;
  var $e = this.$editor;
  $e.html('

');
  this.uuid = uuid;
  this.$c = $('#cursor_' + uuid);
  this.$BOF = $('#BOF_' + uuid);
  this.$EOF = $('#EOF_' + uuid);
  this.cursorX = -1;
  this.enabled = true;
};

Buffer.prototype.init = function(selector){
  this.$editor = $(selector);
  this.uuid = generate_uuid();
  this.reset();
};

Buffer.prototype.insertLineDelimiter = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  var next = $c.before('

\n
')
    .parent('div.line').removeClass('current')
    .after('

')
    .next('div.line')
    .append($('div.cursor, div.cursor ~ div.char, div.cursor'));
//    .append($c);
};

Buffer.prototype.insertChar = function(c){
  if(!this.enabled) return;
  // console.log(c);
  var $c = this.$c;
  this.cursorX = -1;
  if(c == (this.lineDelimiter || '\n')){
    this.insertLineDelimiter();
  } else {
    if(c == ' '){
      $c.before('

');
    } else {
      $c.before('

')
        .prev().text(c);
    }
  }
};
Buffer.prototype.backspace = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $prev = $c.prev('div.char.normal');
  if($prev.length == 0){
    var $line = $c.parent('div.line');
    var $preLine = $line.prev('div.line');
    if($preLine.length > 0){
      $('div.char.line_delimiter', $preLine).remove();
      $preLine.addClass('current');
      $preLine.append($c);
      $line.remove();
    }
  } else {
    $prev.remove();
  }
};

Buffer.prototype.delete = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $next = $c.next('div.char.normal');
  if($next.length == 0){
    var $line = $c.parent('div.line');
    var $nextLine = $line.next('div.line');
    if($nextLine.length > 0){
      $('div.char.line_delimiter', $line).remove();
      $line.append($nextLine.children());
      $nextLine.remove();
    }
  } else {
    $next.remove();
  }
};

Buffer.prototype.moveCursorToBOL = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $line = $c.parent('div.line');
  $('div.char.normal', $line).first().before($c);
};

Buffer.prototype.moveCursorToEOL = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $line = $c.parent('div.line');
  $('div.char.normal', $line).last().after($c);
};

Buffer.prototype.moveCursorHorizontally = function(n){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $line = $c.parent('div.line');
  if(n<0){
    var $prev = $c.prev('div.char');
    if($prev.length > 0){
      $c.prev().before($c);
    } else {
      var $preLine = $line.prev('div.line');
      if($preLine.length > 0){
        var $chars = $('div.char.normal', $preLine);
        if($chars.length > 0){
          $chars.last().after($c);
        } else {
          $preLine.prepend($c);
        }
        $line.removeClass('current');
        $preLine.addClass('current');
      }
    }
  } else if(n>0){
    var $next = $c.next('div.char.normal');
    if($next.length > 0){
      $c.next().after($c);
    } else {
      var $nextLine = $line.next('div.line');
      if($nextLine.length > 0){
        $nextLine.prepend($c);
        $line.removeClass('current');
        $nextLine.addClass('current');
      }
    }
  }
};

Buffer.prototype.moveCursorVertically = function(n){
  if(!this.enabled) return;
  var $c = this.$c;
  var $line = $c.parent('div.line');
  if(this.cursorX < 0){
    this.cursorX = $c.prevAll('div.char.normal').length;
  }
  // console.log(cursorX);
  var $targetLine = null;
      if(n<0){
        $targetLine = $line.prev('div.line');
      } else {
        $targetLine = $line.next('div.line');
      }
  if($targetLine.length > 0){
    var $targetLineChars = $('div.char.normal', $targetLine);
    if(this.cursorX == 0 || $targetLineChars.length == 0){
      $targetLine.prepend($c);
    } else {
      if($targetLineChars.length >= this.cursorX){
        $($targetLineChars.get(this.cursorX-1)).after($c);
      } else {
        $targetLineChars.last().after($c);
      }
    }
    $line.removeClass('current');
    $targetLine.addClass('current');
  }
};
Buffer.prototype.lineDelimiter = '\n';

var vkCodeMap = {
  8: 'Backspace',
  9: 'Tab',
  13: 'Enter',
  16: 'Shift',
  17: 'Control',
  18: 'Alt',
  20: 'CapsLock',
  27: 'Esc',
  32: ' ',
  33: 'PageUp',
  34: 'PageDown',
  35: 'End',
  36: 'Home',
  37: 'Left',
  38: 'Up',
  39: 'Right',
  40: 'Down',
  46: 'Del'
};

function keyMap(code){
  // console.log("code:" + code);
  var char = String.fromCharCode(code);
  if(32 <= code && code <= 126){
    ret = char;
  } else {
    ret = vkCodeMap[code];
  }
  return ret;
}
<commit_msg>Adds Buffer#getCursorPosition<commit_after>$(function(){
  var $input = $('#input');
  var input = $input.get(0);
  $input.val('');
  var ime = false;
  input.focus();
  $input.blur(function(){input.focus();}).focusout(function(){input.focus();});
  setInterval(function(){$('#input:focus').length == 0 ? input.focus() : '';}, 100);
  var keyEventMap = {};
  var modes = {default: keyEventMap};
  var current_mode = 'default';
  var buffers = {'*scratch*' : new Buffer('#editor')};
  var current_buffer_title = '*scratch*';
  var buffer = buffers[current_buffer_title];

  var $d = $(document);
  var $footer = $('#footer');

  var past_input = null;
  var keyDown = null;
  var keyDownHit = false;

  prepareKeyEventMap();

  function invokeHandler(input){
    if(past_input){
      past_input = input = past_input + input;
      $footer.text(past_input);
    }
    var func = modes[current_mode][input];
    if(func){
      func({buffer:buffer});
      var pos = buffer.getCursorPosition();
      $footer.text('(' + pos.row+','+pos.column+')');
    } else {
      past_input = null;
      $footer.text('');
    }
  }

  $d.bind('compositionstart', function(e){
    ime = true;
    $input.css(buffer.$c.position());
    $input.css('z-index', '100');
  }).bind('compositionend', function(e){

    var timer = setInterval(function(){
      if(!ime){
        $input.val().split('').forEach(function(c){buffer.insertChar(c);});
        $input.val('');
        clearInterval(timer);
        $input.css('z-index', '1');
        var pos = buffer.getCursorPosition();
        $footer.text('(' + pos.row+','+pos.column+')');
      }
    },10);
    ime = false;
  });;

  $d.keypress(function(e){
    var mod = (e.altKey ? 'A' : '') + (e.shiftKey ? 'S' : '') + (e.metaKey ? 'M' : '') + (e.ctrlKey ? 'C' : '');
    if(!keyDownHit || mod){
      var char = String.fromCharCode(e.charCode);
      var input = null;
      if(mod.match(/(A|M|C){1,3}/)){
        input = mod + '-' + String.fromCharCode(keyDown).toLowerCase();
        keyDown = null;
      } else {
        input = mod ? mod + '-' + char : char;
      }
      if(input){
        // console.log('charCode: ' + e.charCode);
        // console.log('keyCode: ' + e.keyCode);
        // console.log('converted char: ' + char);
        // console.log('char: ' + e.char);
        // console.log('key: ' + e.key);
        // console.log('input: ' + input);
        // console.log('---');
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
        invokeHandler(input);
      }
    }
    keyDownHit = false;
  }).keydown(function(e){
    var mod = (e.altKey ? 'A' : '') + (e.shiftKey ? 'S' : '') + (e.metaKey ? 'M' : '') + (e.ctrlKey ? 'C' : '');
    keyDown = e.keyCode;

    var input = null;
    if(mod.match(/(A|M|C){1,3}/)){
      input = mod + '-' + String.fromCharCode(keyDown).toLowerCase();
      keyDown = null;
    } else {
      input = vkCodeMap[keyDown];
    }
    // console.log('keydown: ' + keyDown);

    if(input){
      e.preventDefault();
      e.stopPropagation();
      e.stopImmediatePropagation();
      if(past_input){
        input = past_input + input;
      }
      var func = modes[current_mode][input];
      if(func){
        func({buffer:buffer});
        var pos = buffer.getCursorPosition();
        $footer.text('(' + pos.row+','+pos.column+')');
      } else {

        keyDownHit = !!keyDown;
      }
    }
  });

  function prepareKeyEventMap(){
    prepareBasicKeyInputHandler();
    prepareCursorOperationHandler();
    prepareCombinationSequences();

    function prepareBasicKeyInputHandler(){
      for(var code=32;code <= 126; code++){
        var char = String.fromCharCode(code);
        // console.log(char);
        var handler = generateKeyInputHandler(char);
        keyEventMap[char] = handler;
        keyEventMap['S-' + char] = handler;
      }
      keyEventMap['C-m'] = keyEventMap['Enter'] = generateKeyInputHandler(buffer.lineDelimiter || '\n');
      keyEventMap['C-h'] = keyEventMap['Backspace'] = backspace;
      keyEventMap['C-d'] = keyEventMap['Del'] = deleteChar;
    }

    function prepareCombinationSequences(){
      setKeepSequenceHandler('C-x');
      setKeepSequenceHandler('C-c');
      keyEventMap['C-xk'] = reset;
    }

    function setKeepSequenceHandler(sequence){
      keyEventMap[sequence] = function(opt){
        past_input = sequence;
        $footer.text(past_input);
        // console.log(past_input);
      };
    }

    function generateKeyInputHandler(char){
      return function(opt){
        // console.log('#' + char + '#');
        var buffer = opt.buffer;
        buffer.insertChar(char);
      };
    }

    function reset(opt){
      var buffer = opt.buffer;
      buffer.reset();
    }

    function backspace(opt){
      var buffer = opt.buffer;
      buffer.backspace();
    }

    function deleteChar(opt){
      var buffer = opt.buffer;
      buffer.delete();
    }

    function prepareCursorOperationHandler(){
      keyEventMap['C-b'] = keyEventMap['Left'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorHorizontally(-1);
      };
      keyEventMap['C-f'] = keyEventMap['Right'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorHorizontally(+1);
      };
      keyEventMap['C-p'] = keyEventMap['Up'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorVertically(-1);
      };
      keyEventMap['C-n'] = keyEventMap['Down'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorVertically(+1);
      };
      keyEventMap['C-a'] = keyEventMap['Home'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorToBOL();
      };
      keyEventMap['C-e'] = keyEventMap['End'] = function(opt){
        var buffer = opt.buffer;
        buffer.moveCursorToEOL();
      };

    }

  }

});

function Buffer(selector){
  this.init.apply(this, arguments);
};

function generate_uuid(){
  return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4() +S4());
  function S4 () {
    return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
  }
}

Buffer.prototype.reset = function(){
  var uuid = this.uuid;
  var $e = this.$editor;
  $e.html('

');
  this.uuid = uuid;
  this.$c = $('#cursor_' + uuid);
  this.$BOF = $('#BOF_' + uuid);
  this.$EOF = $('#EOF_' + uuid);
  this.cursorX = -1;
  this.enabled = true;
};

Buffer.prototype.init = function(selector){
  this.$editor = $(selector);
  this.uuid = generate_uuid();
  this.reset();
};

Buffer.prototype.insertLineDelimiter = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  var next = $c.before('

\n
')
    .parent('div.line').removeClass('current')
    .after('

')
    .next('div.line')
    .append($('div.cursor, div.cursor ~ div.char, div.cursor'));
//    .append($c);
};

Buffer.prototype.insertChar = function(c){
  if(!this.enabled) return;
  // console.log(c);
  var $c = this.$c;
  this.cursorX = -1;
  if(c == (this.lineDelimiter || '\n')){
    this.insertLineDelimiter();
  } else {
    if(c == ' '){
      $c.before('

');
    } else {
      $c.before('

')
        .prev().text(c);
    }
  }
};
Buffer.prototype.backspace = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $prev = $c.prev('div.char.normal');
  if($prev.length == 0){
    var $line = $c.parent('div.line');
    var $preLine = $line.prev('div.line');
    if($preLine.length > 0){
      $('div.char.line_delimiter', $preLine).remove();
      $preLine.addClass('current');
      $preLine.append($c);
      $line.remove();
    }
  } else {
    $prev.remove();
  }
};

Buffer.prototype.delete = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $next = $c.next('div.char.normal');
  if($next.length == 0){
    var $line = $c.parent('div.line');
    var $nextLine = $line.next('div.line');
    if($nextLine.length > 0){
      $('div.char.line_delimiter', $line).remove();
      $line.append($nextLine.children());
      $nextLine.remove();
    }
  } else {
    $next.remove();
  }
};

Buffer.prototype.moveCursorToBOL = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $line = $c.parent('div.line');
  $('div.char.normal', $line).first().before($c);
};

Buffer.prototype.moveCursorToEOL = function(){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $line = $c.parent('div.line');
  $('div.char.normal', $line).last().after($c);
};

Buffer.prototype.moveCursorHorizontally = function(n){
  if(!this.enabled) return;
  var $c = this.$c;
  this.cursorX = -1;
  var $line = $c.parent('div.line');
  if(n<0){
    var $prev = $c.prev('div.char');
    if($prev.length > 0){
      $c.prev().before($c);
    } else {
      var $preLine = $line.prev('div.line');
      if($preLine.length > 0){
        var $chars = $('div.char.normal', $preLine);
        if($chars.length > 0){
          $chars.last().after($c);
        } else {
          $preLine.prepend($c);
        }
        $line.removeClass('current');
        $preLine.addClass('current');
      }
    }
  } else if(n>0){
    var $next = $c.next('div.char.normal');
    if($next.length > 0){
      $c.next().after($c);
    } else {
      var $nextLine = $line.next('div.line');
      if($nextLine.length > 0){
        $nextLine.prepend($c);
        $line.removeClass('current');
        $nextLine.addClass('current');
      }
    }
  }
};

Buffer.prototype.moveCursorVertically = function(n){
  if(!this.enabled) return;
  var $c = this.$c;
  var $line = $c.parent('div.line');
  if(this.cursorX < 0){
    this.cursorX = $c.prevAll('div.char.normal').length;
  }
  // console.log(cursorX);
  var $targetLine = null;
      if(n<0){
        $targetLine = $line.prev('div.line');
      } else {
        $targetLine = $line.next('div.line');
      }
  if($targetLine.length > 0){
    var $targetLineChars = $('div.char.normal', $targetLine);
    if(this.cursorX == 0 || $targetLineChars.length == 0){
      $targetLine.prepend($c);
    } else {
      if($targetLineChars.length >= this.cursorX){
        $($targetLineChars.get(this.cursorX-1)).after($c);
      } else {
        $targetLineChars.last().after($c);
      }
    }
    $line.removeClass('current');
    $targetLine.addClass('current');
  }
};
Buffer.prototype.lineDelimiter = '\n';

Buffer.prototype.getCursorPosition = function(){
  var $c = this.$c;
  var column = $c.prevAll('div.char.normal').length;
  var row = $c.parent('div.line').prevAll('div.line').length + 1;
  return {row: row, column: column};
};

var vkCodeMap = {
  8: 'Backspace',
  9: 'Tab',
  13: 'Enter',
  16: 'Shift',
  17: 'Control',
  18: 'Alt',
  20: 'CapsLock',
  27: 'Esc',
  32: ' ',
  33: 'PageUp',
  34: 'PageDown',
  35: 'End',
  36: 'Home',
  37: 'Left',
  38: 'Up',
  39: 'Right',
  40: 'Down',
  46: 'Del'
};

function keyMap(code){
  // console.log("code:" + code);
  var char = String.fromCharCode(code);
  if(32 <= code && code <= 126){
    ret = char;
  } else {
    ret = vkCodeMap[code];
  }
  return ret;
}
<|endoftext|>


<commit_before>;(function($B){

eval($B.InjectBuiltins())

// class of traceback objects
var $TracebackDict = {__class__:$B.$type,
    __name__:'traceback'
}
$TracebackDict.__getattribute__ = function(self, attr){
    if(self.stack.length==0){alert('no stack', attr)}
    var last_frame = $B.last(self.stack)
    if(last_frame==undefined){alert('last frame undef ');console.log(self.stack, Object.keys(self.stack))}
    var line_info = last_frame[1].$line_info

    switch(attr){
        case 'tb_frame':
            return frame(self.stack)
        case 'tb_lineno':
            if(line_info===undefined){return -1}
            else{return parseInt(line_info.split(',')[0])}
        case 'tb_lasti':
            if(line_info===undefined){return '<unknown>'}
            else{
                var info = line_info.split(',')
                var src = $B.$py_src[info[1]]
                if(src!==undefined){
                    return src.split('\n')[parseInt(info[0]-1)].trim()
                }else{return '<unknown>'}
            }
        case 'tb_next':
            if(self.stack.length==1){return None}
            else{return traceback(self.stack.slice(0, self.stack.length-1))}
        default:
            return $TracebackDict[attr]
    }
}

$TracebackDict.__mro__ = [$TracebackDict, _b_.object.$dict]

$TracebackDict.__str__ = function(self){return '<traceback object>'}

function traceback(stack) {
  return {__class__ : $TracebackDict,
      stack : stack
  }
}

traceback.__class__ = $B.$factory
traceback.$dict = $TracebackDict
$TracebackDict.$factory = traceback

// class of frame objects
var $FrameDict = {__class__:$B.$type,
    __name__:'frame'
}

$FrameDict.__getattr__ = function(self, attr){
    // Used for f_back to avoid computing it when the frame object
    // is initialised
    if(attr=='f_back'){
        if(self.$pos>0){
            return frame(self.$stack, self.$pos-1)
        }
    }
}

$FrameDict.__mro__ = [$FrameDict, _b_.object.$dict]

function to_dict(obj){
    var res = _b_.dict()
    var setitem=_b_.dict.$dict.__setitem__
    for(var attr in obj){
        if(attr.charAt(0)=='$'){continue}
        setitem(res, attr, obj[attr])
    }
    return res
}

function frame(stack, pos){
    var mod_name = stack[2]
    var fs = stack
    var res = {__class__:$FrameDict,
        f_builtins : {}, // XXX fix me
        $stack: stack,
    }
    if(pos===undefined){pos = fs.length-1}
    res.$pos = pos
    if(fs.length){
        var _frame = fs[pos]
        var locals_id = _frame[0]
        try{
            res.f_locals = $B.obj_dict(_frame[1])
        }catch(err){
            console.log('err '+err)
            throw err
        }
        res.f_globals = $B.obj_dict(_frame[3])
        if($B.debug>0){
            if(_frame[1].$line_info === undefined){res.f_lineno=-1}
            else{res.f_lineno = parseInt(_frame[1].$line_info.split(',')[0])}
        }else{
            res.f_lineno = -1
        }
        //if(pos!==undefined && pos>1){res.f_back = frame(stack, pos-1)}
        //else{res.f_back = None}
        res.f_code = {__class__:$B.$CodeDict,
            co_code:None, // XXX fix me
            co_name: locals_id, // idem
            co_filename: _frame[3].__name__ // idem
        }
        if(res.f_code.co_filename===undefined){console.log(_frame[0],_frame[1],_frame[2],_frame[3]);alert('no cofilename')}
    }
    return res
}

frame.__class__ = $B.$factory
frame.$dict = $FrameDict
$FrameDict.$factory = frame
$B._frame=frame

// built-in exceptions

var $BaseExceptionDict = {__class__:$B.$type,
    __bases__ : [_b_.object],
    __module__:'builtins',
    __name__:'BaseException'
}

$BaseExceptionDict.__init__ = function(self){
    self.args = _b_.tuple([arguments[1]])
}

$BaseExceptionDict.__repr__ = function(self){
    return self.__class__.__name__+repr(self.args)
}

$BaseExceptionDict.__str__ = function(self){
    return _b_.str(self.args[0])
}

$BaseExceptionDict.__mro__ = [$BaseExceptionDict,_b_.object.$dict]

$BaseExceptionDict.__new__ = function(cls){
    var err = _b_.BaseException()
    err.__name__ = cls.$dict.__name__
    err.__class__ = cls.$dict
    return err
}

$BaseExceptionDict.__getattr__ = function(self, attr){
    if(attr=='info'){
        var name = self.__class__.__name__
        if(name=='SyntaxError' || name=='IndentationError'){
            return 'File "'+self.args[1]+'", line '+self.args[2]+'\n    '+
                self.args[4]

        }

        var info = 'Traceback (most recent call last):'

        if(self.$js_exc!==undefined){
            for(var attr in self.$js_exc){
                if(attr==='message') continue
                try{info += '\n    '+attr+' : '+self.$js_exc[attr]}
                catch(_err){}
            }
            info+='\n'
        }
        for(var i=0;i<self.$stack.length;i++){
            var frame = self.$stack[i]
            if(frame[1].$line_info===undefined){continue}
            var line_info = frame[1].$line_info.split(',')
            var lines = $B.$py_src[line_info[1]].split('\n')
            info += '\n  module '+line_info[1]+' line '+line_info[0]
            var line = lines[parseInt(line_info[0])-1]
            if(line) line=line.replace(/^[ ]+/g, '')
            if(line===undefined){console.log('line undef...',line_info,$B.$py_src[line_info[1]])}
            info += '\n    '+line
        }
        return info

    }else if(attr=='traceback'){
        // Return traceback object
        return traceback(self.$stack)
    }else{
        throw AttributeError(self.__class__.__name__+
            "has no attribute '"+attr+"'")
    }
}

$BaseExceptionDict.with_traceback = function(self, tb){
    self.traceback = tb
    return self
}

$B.set_func_names($BaseExceptionDict)

var BaseException = function (){
    var err = Error()
    err.__name__ = 'BaseException'
    //err.$js_exc = js_exc

    err.args = _b_.tuple(Array.prototype.slice.call(arguments))
    err.$message = arguments[0]
    err.__class__ = $BaseExceptionDict
    err.$py_error = true
    err.$stack = $B.frames_stack.slice()
    $B.current_exception = err
    return err
}

BaseException.__class__ = $B.$factory
BaseException.$dict = $BaseExceptionDict
$BaseExceptionDict.$factory = BaseException

_b_.BaseException = BaseException

$B.exception = function(js_exc){
    // thrown by eval(), exec() or by a function
    // js_exc is the Javascript exception, which can be raised by the
    // code generated by Python - in this case it has attribute $py_error set -
    // or by the Javascript interpreter (ReferenceError for instance)

    if(!js_exc.$py_error){
        // Print complete Javascript traceback in console
        //console.log(js_exc)

        if($B.debug>0 && js_exc.info===undefined){
            var _frame = $B.last($B.frames_stack)
            if(_frame===undefined){_frame=$B.pmframe} // use post-mortem frame
            if(_frame && _frame[1].$line_info!==undefined){
                var line_info = _frame[1].$line_info.split(',')
                var mod_name = line_info[1]
                var module = $B.modules[mod_name]
                if(module){
                    if(module.caller!==undefined){
                        // for list comprehension and the likes, replace
                        // by the line in the enclosing module
                        var mod_name = line_info[1]
                    }
                    var lib_module = mod_name
                    var line_num = parseInt(line_info[0])
                    if($B.$py_src[mod_name]===undefined){
                        console.log('pas de py_src pour '+mod_name)
                    }
                    var lines = $B.$py_src[mod_name].split('\n'),
                        msg = js_exc.message.toString()
                    // For some weird reason, nothing can be added to js_exc.message
                    // so we have to create another attribute with the complete
                    // error message including line in source code
                    msg += "\n  module '"+lib_module+"' line "+line_num
                    msg += '\n'+lines[line_num-1]
                    js_exc.msg = msg
                    js_exc.info_in_msg = true
                }
            }else{
                console.log('error ', js_exc)
            }
        }
        var exc = Error()
        exc.__name__ = 'Internal Javascript error: '+(js_exc.__name__ || js_exc.name)
        exc.__class__ = _b_.Exception.$dict
        exc.$js_exc = js_exc
        if(js_exc.name=='ReferenceError'){
            exc.__name__='NameError'
            exc.__class__=_b_.NameError.$dict
            js_exc.message = js_exc.message.replace('$$','')
        }else if(js_exc.name=="InternalError"){
            exc.__name__='RuntimeError'
            exc.__class__=_b_.RuntimeError.$dict
        }
        exc.$message = js_exc.msg || '<'+js_exc+'>'
        exc.args = _b_.tuple([exc.$message])
        exc.info = ''
        exc.$py_error = true
        exc.$stack = $B.frames_stack.slice()
    }else{
        var exc = js_exc
    }
    $B.current_exception = exc
    return exc
}

$B.is_exc=function(exc,exc_list){
    // used in try/except to check if an exception is an instance of
    // one of the classes in exc_list
    if(exc.__class__===undefined) exc = $B.exception(exc)

    var exc_class = exc.__class__.$factory
    for(var i=0;i<exc_list.length;i++){
        if(issubclass(exc_class,exc_list[i])) return true
    }
    return false
}

$B.clear_exc = function(){
    $B.current_exception = null
}

function $make_exc(names,parent){
    // create a class for exception called "name"
    var _str=[], pos=0
    for(var i=0;i<names.length;i++){
        var name = names[i]
        $B.bound['__builtins__'][name] = true
        var $exc = (BaseException+'').replace(/BaseException/g,name)
        // class dictionary
        _str[pos++]='var $'+name+'Dict={__class__:$B.$type,__name__:"'+name+'"}'
        _str[pos++]='$'+name+'Dict.__bases__ = [parent]'
        _str[pos++]='$'+name+'Dict.__module__ = "builtins"'
        _str[pos++]='$'+name+'Dict.__mro__=[$'+name+'Dict].concat(parent.$dict.__mro__)'
        // class constructor
        _str[pos++]='_b_.'+name+'='+$exc
        _str[pos++]='_b_.'+name+'.__class__=$B.$factory'
        _str[pos++]='$'+name+'Dict.$factory=_b_.'+name
        _str[pos++]='_b_.'+name+'.$dict=$'+name+'Dict'
    }
    eval(_str.join(';'))
}

$make_exc(['SystemExit','KeyboardInterrupt','GeneratorExit','Exception'],BaseException)
$make_exc(['StopIteration','ArithmeticError','AssertionError','AttributeError',
    'BufferError','EOFError','ImportError','LookupError','MemoryError',
    'NameError','OSError','ReferenceError','RuntimeError','SyntaxError',
    'SystemError','TypeError','ValueError','Warning'],_b_.Exception)
$make_exc(['FloatingPointError','OverflowError','ZeroDivisionError'],
    _b_.ArithmeticError)
$make_exc(['IndexError','KeyError'],_b_.LookupError)
$make_exc(['UnboundLocalError'],_b_.NameError)
$make_exc(['BlockingIOError','ChildProcessError','ConnectionError',
    'FileExistsError','FileNotFoundError','InterruptedError',
    'IsADirectoryError','NotADirectoryError','PermissionError',
    'ProcessLookupError','TimeoutError'],_b_.OSError)
$make_exc(['BrokenPipeError','ConnectionAbortedError','ConnectionRefusedError',
    'ConnectionResetError'],_b_.ConnectionError)
$make_exc(['NotImplementedError'],_b_.RuntimeError)
$make_exc(['IndentationError'],_b_.SyntaxError)
$make_exc(['TabError'],_b_.IndentationError)
$make_exc(['UnicodeError'],_b_.ValueError)
$make_exc(['UnicodeDecodeError','UnicodeEncodeError','UnicodeTranslateError'],
    _b_.UnicodeError)
$make_exc(['DeprecationWarning','PendingDeprecationWarning','RuntimeWarning',
    'SyntaxWarning','UserWarning','FutureWarning','ImportWarning',
    'UnicodeWarning','BytesWarning','ResourceWarning'],_b_.Warning)

$make_exc(['EnvironmentError','IOError','VMSError','WindowsError'],_b_.OSError)

$B.$NameError = function(name){
    // Used if a name is not found in the bound names
    // It is converted into
    // $globals[name] !== undefined ? $globals[name] : __BRYTHON__.$NameError(name)
    throw _b_.NameError(name)
}
$B.$TypeError = function(msg){
    throw _b_.TypeError(msg)
}

})(__BRYTHON__)<commit_msg>Fix bug with argument "args" of exception classes and instances<commit_after>;(function($B){

eval($B.InjectBuiltins())

// class of traceback objects
var $TracebackDict = {__class__:$B.$type,
    __name__:'traceback'
}
$TracebackDict.__getattribute__ = function(self, attr){
    if(self.stack.length==0){alert('no stack', attr)}
    var last_frame = $B.last(self.stack)
    if(last_frame==undefined){alert('last frame undef ');console.log(self.stack, Object.keys(self.stack))}
    var line_info = last_frame[1].$line_info

    switch(attr){
        case 'tb_frame':
            return frame(self.stack)
        case 'tb_lineno':
            if(line_info===undefined){return -1}
            else{return parseInt(line_info.split(',')[0])}
        case 'tb_lasti':
            if(line_info===undefined){return '<unknown>'}
            else{
                var info = line_info.split(',')
                var src = $B.$py_src[info[1]]
                if(src!==undefined){
                    return src.split('\n')[parseInt(info[0]-1)].trim()
                }else{return '<unknown>'}
            }
        case 'tb_next':
            if(self.stack.length==1){return None}
            else{return traceback(self.stack.slice(0, self.stack.length-1))}
        default:
            return $TracebackDict[attr]
    }
}

$TracebackDict.__mro__ = [$TracebackDict, _b_.object.$dict]

$TracebackDict.__str__ = function(self){return '<traceback object>'}

function traceback(stack) {
  return {__class__ : $TracebackDict,
      stack : stack
  }
}

traceback.__class__ = $B.$factory
traceback.$dict = $TracebackDict
$TracebackDict.$factory = traceback

// class of frame objects
var $FrameDict = {__class__:$B.$type,
    __name__:'frame'
}

$FrameDict.__getattr__ = function(self, attr){
    // Used for f_back to avoid computing it when the frame object
    // is initialised
    if(attr=='f_back'){
        if(self.$pos>0){
            return frame(self.$stack, self.$pos-1)
        }
    }
}

$FrameDict.__mro__ = [$FrameDict, _b_.object.$dict]

function to_dict(obj){
    var res = _b_.dict()
    var setitem=_b_.dict.$dict.__setitem__
    for(var attr in obj){
        if(attr.charAt(0)=='$'){continue}
        setitem(res, attr, obj[attr])
    }
    return res
}

function frame(stack, pos){
    var mod_name = stack[2]
    var fs = stack
    var res = {__class__:$FrameDict,
        f_builtins : {}, // XXX fix me
        $stack: stack,
    }
    if(pos===undefined){pos = fs.length-1}
    res.$pos = pos
    if(fs.length){
        var _frame = fs[pos]
        var locals_id = _frame[0]
        try{
            res.f_locals = $B.obj_dict(_frame[1])
        }catch(err){
            console.log('err '+err)
            throw err
        }
        res.f_globals = $B.obj_dict(_frame[3])
        if($B.debug>0){
            if(_frame[1].$line_info === undefined){res.f_lineno=-1}
            else{res.f_lineno = parseInt(_frame[1].$line_info.split(',')[0])}
        }else{
            res.f_lineno = -1
        }
        //if(pos!==undefined && pos>1){res.f_back = frame(stack, pos-1)}
        //else{res.f_back = None}
        res.f_code = {__class__:$B.$CodeDict,
            co_code:None, // XXX fix me
            co_name: locals_id, // idem
            co_filename: _frame[3].__name__ // idem
        }
        if(res.f_code.co_filename===undefined){console.log(_frame[0],_frame[1],_frame[2],_frame[3]);alert('no cofilename')}
    }
    return res
}

frame.__class__ = $B.$factory
frame.$dict = $FrameDict
$FrameDict.$factory = frame
$B._frame=frame

// built-in exceptions

var $BaseExceptionDict = {__class__:$B.$type,
    __bases__ : [_b_.object],
    __module__:'builtins',
    __name__:'BaseException',
    args: []
}

$BaseExceptionDict.__init__ = function(self){
    var args = arguments[1] === undefined ? [] : [arguments[1]]
    self.args = _b_.tuple(args)
}

$BaseExceptionDict.__repr__ = function(self){
    return self.__class__.__name__+repr(self.args)
}

$BaseExceptionDict.__str__ = function(self){
    return _b_.str(self.args[0])
}

$BaseExceptionDict.__mro__ = [$BaseExceptionDict,_b_.object.$dict]

$BaseExceptionDict.__new__ = function(cls){
    var err = _b_.BaseException()
    err.__name__ = cls.$dict.__name__
    err.__class__ = cls.$dict
    return err
}

$BaseExceptionDict.__getattr__ = function(self, attr){
    if(attr=='info'){
        var name = self.__class__.__name__
        if(name=='SyntaxError' || name=='IndentationError'){
            return 'File "'+self.args[1]+'", line '+self.args[2]+'\n    '+
                self.args[4]

        }

        var info = 'Traceback (most recent call last):'

        if(self.$js_exc!==undefined){
            for(var attr in self.$js_exc){
                if(attr==='message') continue
                try{info += '\n    '+attr+' : '+self.$js_exc[attr]}
                catch(_err){}
            }
            info+='\n'
        }
        for(var i=0;i<self.$stack.length;i++){
            var frame = self.$stack[i]
            if(frame[1].$line_info===undefined){continue}
            var line_info = frame[1].$line_info.split(',')
            var lines = $B.$py_src[line_info[1]].split('\n')
            info += '\n  module '+line_info[1]+' line '+line_info[0]
            var line = lines[parseInt(line_info[0])-1]
            if(line) line=line.replace(/^[ ]+/g, '')
            if(line===undefined){console.log('line undef...',line_info,$B.$py_src[line_info[1]])}
            info += '\n    '+line
        }
        return info

    }else if(attr=='traceback'){
        // Return traceback object
        return traceback(self.$stack)
    }else{
        throw AttributeError(self.__class__.__name__+
            "has no attribute '"+attr+"'")
    }
}

$BaseExceptionDict.with_traceback = function(self, tb){
    self.traceback = tb
    return self
}

$B.set_func_names($BaseExceptionDict)

var BaseException = function (){
    var err = Error()
    err.__name__ = 'BaseException'
    //err.$js_exc = js_exc

    err.args = _b_.tuple(Array.prototype.slice.call(arguments))
    err.$message = arguments[0]
    err.__class__ = $BaseExceptionDict
    err.$py_error = true
    err.$stack = $B.frames_stack.slice()
    $B.current_exception = err
    return err
}

BaseException.__class__ = $B.$factory
BaseException.$dict = $BaseExceptionDict
$BaseExceptionDict.$factory = BaseException

_b_.BaseException = BaseException

$B.exception = function(js_exc){
    // thrown by eval(), exec() or by a function
    // js_exc is the Javascript exception, which can be raised by the
    // code generated by Python - in this case it has attribute $py_error set -
    // or by the Javascript interpreter (ReferenceError for instance)

    if(!js_exc.$py_error){
        // Print complete Javascript traceback in console
        //console.log(js_exc)

        if($B.debug>0 && js_exc.info===undefined){
            var _frame = $B.last($B.frames_stack)
            if(_frame===undefined){_frame=$B.pmframe} // use post-mortem frame
            if(_frame && _frame[1].$line_info!==undefined){
                var line_info = _frame[1].$line_info.split(',')
                var mod_name = line_info[1]
                var module = $B.modules[mod_name]
                if(module){
                    if(module.caller!==undefined){
                        // for list comprehension and the likes, replace
                        // by the line in the enclosing module
                        var mod_name = line_info[1]
                    }
                    var lib_module = mod_name
                    var line_num = parseInt(line_info[0])
                    if($B.$py_src[mod_name]===undefined){
                        console.log('pas de py_src pour '+mod_name)
                        console.log(js_exc)
                    }
                    var lines = $B.$py_src[mod_name].split('\n'),
                        msg = js_exc.message.toString()
                    // For some weird reason, nothing can be added to js_exc.message
                    // so we have to create another attribute with the complete
                    // error message including line in source code
                    msg += "\n  module '"+lib_module+"' line "+line_num
                    msg += '\n'+lines[line_num-1]
                    js_exc.msg = msg
                    js_exc.info_in_msg = true
                }
            }else{
                console.log('error ', js_exc)
            }
        }
        var exc = Error()
        exc.__name__ = 'Internal Javascript error: '+(js_exc.__name__ || js_exc.name)
        exc.__class__ = _b_.Exception.$dict
        exc.$js_exc = js_exc
        if(js_exc.name=='ReferenceError'){
            exc.__name__='NameError'
            exc.__class__=_b_.NameError.$dict
            js_exc.message = js_exc.message.replace('$$','')
        }else if(js_exc.name=="InternalError"){
            exc.__name__='RuntimeError'
            exc.__class__=_b_.RuntimeError.$dict
        }
        exc.$message = js_exc.msg || '<'+js_exc+'>'
        exc.args = _b_.tuple([exc.$message])
        exc.info = ''
        exc.$py_error = true
        exc.$stack = $B.frames_stack.slice()
    }else{
        var exc = js_exc
    }
    $B.current_exception = exc
    return exc
}

$B.is_exc=function(exc,exc_list){
    // used in try/except to check if an exception is an instance of
    // one of the classes in exc_list
    if(exc.__class__===undefined) exc = $B.exception(exc)

    var exc_class = exc.__class__.$factory
    for(var i=0;i<exc_list.length;i++){
        if(issubclass(exc_class,exc_list[i])) return true
    }
    return false
}

$B.clear_exc = function(){
    $B.current_exception = null
}

function $make_exc(names,parent){
    // create a class for exception called "name"
    var _str=[], pos=0
    for(var i=0;i<names.length;i++){
        var name = names[i]
        $B.bound['__builtins__'][name] = true
        var $exc = (BaseException+'').replace(/BaseException/g,name)
        // class dictionary
        _str[pos++]='var $'+name+'Dict={__class__:$B.$type,__name__:"'+name+'"}'
        _str[pos++]='$'+name+'Dict.__bases__ = [parent]'
        _str[pos++]='$'+name+'Dict.__module__ = "builtins"'
        _str[pos++]='$'+name+'Dict.__mro__=[$'+name+'Dict].concat(parent.$dict.__mro__)'
        // class constructor
        _str[pos++]='_b_.'+name+'='+$exc
        _str[pos++]='_b_.'+name+'.__class__=$B.$factory'
        _str[pos++]='$'+name+'Dict.$factory=_b_.'+name
        _str[pos++]='_b_.'+name+'.$dict=$'+name+'Dict'
    }
    eval(_str.join(';'))
}

$make_exc(['SystemExit','KeyboardInterrupt','GeneratorExit','Exception'],BaseException)
$make_exc(['StopIteration','ArithmeticError','AssertionError','AttributeError',
    'BufferError','EOFError','ImportError','LookupError','MemoryError',
    'NameError','OSError','ReferenceError','RuntimeError','SyntaxError',
    'SystemError','TypeError','ValueError','Warning'],_b_.Exception)
$make_exc(['FloatingPointError','OverflowError','ZeroDivisionError'],
    _b_.ArithmeticError)
$make_exc(['IndexError','KeyError'],_b_.LookupError)
$make_exc(['UnboundLocalError'],_b_.NameError)
$make_exc(['BlockingIOError','ChildProcessError','ConnectionError',
    'FileExistsError','FileNotFoundError','InterruptedError',
    'IsADirectoryError','NotADirectoryError','PermissionError',
    'ProcessLookupError','TimeoutError'],_b_.OSError)
$make_exc(['BrokenPipeError','ConnectionAbortedError','ConnectionRefusedError',
    'ConnectionResetError'],_b_.ConnectionError)
$make_exc(['NotImplementedError'],_b_.RuntimeError)
$make_exc(['IndentationError'],_b_.SyntaxError)
$make_exc(['TabError'],_b_.IndentationError)
$make_exc(['UnicodeError'],_b_.ValueError)
$make_exc(['UnicodeDecodeError','UnicodeEncodeError','UnicodeTranslateError'],
    _b_.UnicodeError)
$make_exc(['DeprecationWarning','PendingDeprecationWarning','RuntimeWarning',
    'SyntaxWarning','UserWarning','FutureWarning','ImportWarning',
    'UnicodeWarning','BytesWarning','ResourceWarning'],_b_.Warning)

$make_exc(['EnvironmentError','IOError','VMSError','WindowsError'],_b_.OSError)

$B.$NameError = function(name){
    // Used if a name is not found in the bound names
    // It is converted into
    // $globals[name] !== undefined ? $globals[name] : __BRYTHON__.$NameError(name)
    throw _b_.NameError(name)
}
$B.$TypeError = function(msg){
    throw _b_.TypeError(msg)
}

})(__BRYTHON__)<|endoftext|>


<commit_before>var api = {
  backend: 'http://localhost:3000',

  ajax: function(config, cb) {
    $.ajax(config).done(function(data, textStatus, jqxhr) {
      cb(null, data);
    }).fail(function(jqxhr, status, error) {
      cb({jqxher: jqxhr, status: status, error: error});
    });
  },

  register: function register(credentials, callback) {
    this.ajax({
      method: 'POST',
      url: this.backend + '/signup',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(credentials),
      dataType: 'json'
    }, callback);
  },

  login: function login(credentials, callback) {
    this.ajax({
      method: 'POST',
      url: this.backend + '/login',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(credentials),
      dataType: 'json'
    }, callback);
  },

  logout: function logout(callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/logout',
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  changePass: function changePass(credentials, callback) {
    this.ajax({
      method: 'POST',
      url: this.backend + '/changePassword',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(credentials),
      dataType: 'json'
    }, callback);
  },

  getAllPosts: function getAllPosts(callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/posts',
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  getLoggedUserPosts: function getLoggedUserPosts(callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/posts/user',
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  getUserPosts: function getUserPosts(id, callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/posts/user/' + id,
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  getSinglePost: function getSinglePost(id, callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/posts/article/' + id,
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  newPost: function newPost(content, callback) {
    this.ajax({
      method: 'POST',
      url: this.backend + '/posts/user',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(content),
      dataType: 'json'
    }, callback);
  },

  deletePost: function deletePost(id, callback) {
    this.ajax({
      method: 'DELETE',
      url: this.backend + '/posts/article/' + id
    }, callback);
  },

  updatePost: function updatePost(id, content, callback) {
    this.ajax({
      method: 'PATCH',
      url: this.backend + '/posts/article/' + id,
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(content),
      dataType: 'json'
    }, callback);
  }
};

var switchView = function switchView(view) {
  $('#main-page').hide();
  $('#view-all').hide();
  $('#view-one').hide();
  $('#create').hide();
  $('#update-view').hide();

  if(view === 'view-all') {
    console.log('switched to view all');
    $('#view-all').show();
  } else if (view === 'view-one') {
    console.log('switched to view one');
    $('#view-one').show();
  } else if (view === 'create') {
    console.log('switched to create');
    $('#create').show();
  } else if (view === 'update-view') {
    $('#update-view').show();
  } else {
    console.log('switched to view main');
    $('#main-page').show();
  }
};

var form2object = function(form) {
  var data = {};
  $(form).children().each(function(index, element) {
    var type = $(this).attr('type');
    if ($(this).attr('name') && type !== 'submit' && type !== 'hidden') {
      data[$(this).attr('name')] = $(this).val();
    }
  });
  console.log("Form output:");
  console.log(data);
  return data;
};

var allPostTemplate = Handlebars.compile($('#template-view-all').html());
var onePostTemplate = Handlebars.compile($('#template-view-one').html());

var serverData;
var callback = function callback(error, data) {
  if (error) {
    console.error(error);
    return;
  }
  serverData = data;
  console.log(serverData);
};

var onePostCallback = function onePostCallback(error, data) {
  if(error) {
    console.error(err);
    return;
  }
  var html = onePostTemplate(data);
  $('#view-one').html(html);

  $('#delete').on('click', function() {
    api.deletePost(data._id, callback);
    switchView('view-all');
    api.getUserPosts(data.userID, function(err, data) {
      if(err) {
        console.error(err);
        return;
      }
      var html = allPostTemplate(data);
      $('#view-all').html(html);
    });

  });

  $('#update').on('click', function() {
    var oldTitle = data.title;
    var oldBody = data.body;
    var oldID = data._id;
    $('#update-title').val(oldTitle);
    $('#update-body').val(oldBody);
    $('#update-ID').val(oldID);
    $('#update-view').show();
  });
};

Handlebars.registerHelper('xbbcodeParse', function(input) {
  var result = XBBCODE.process({
      text: input,
      removeMisalignedTags: false,
      addInLineBreaks: true
  });
  console.log("Errors: " + result.error);
  console.dir(result.errorQueue);
  return result.html;
});
<commit_msg>Added to the hadlebars helper, removes anything resembling HTML from the body of a post before parsing the bbcode.<commit_after>var api = {
  backend: 'http://localhost:3000',

  ajax: function(config, cb) {
    $.ajax(config).done(function(data, textStatus, jqxhr) {
      cb(null, data);
    }).fail(function(jqxhr, status, error) {
      cb({jqxher: jqxhr, status: status, error: error});
    });
  },

  register: function register(credentials, callback) {
    this.ajax({
      method: 'POST',
      url: this.backend + '/signup',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(credentials),
      dataType: 'json'
    }, callback);
  },

  login: function login(credentials, callback) {
    this.ajax({
      method: 'POST',
      url: this.backend + '/login',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(credentials),
      dataType: 'json'
    }, callback);
  },

  logout: function logout(callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/logout',
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  changePass: function changePass(credentials, callback) {
    this.ajax({
      method: 'POST',
      url: this.backend + '/changePassword',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(credentials),
      dataType: 'json'
    }, callback);
  },

  getAllPosts: function getAllPosts(callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/posts',
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  getLoggedUserPosts: function getLoggedUserPosts(callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/posts/user',
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  getUserPosts: function getUserPosts(id, callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/posts/user/' + id,
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  getSinglePost: function getSinglePost(id, callback) {
    this.ajax({
      method: 'GET',
      url: this.backend + '/posts/article/' + id,
      contentType: 'application/json; charset=utf-8'
    }, callback);
  },

  newPost: function newPost(content, callback) {
    this.ajax({
      method: 'POST',
      url: this.backend + '/posts/user',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(content),
      dataType: 'json'
    }, callback);
  },

  deletePost: function deletePost(id, callback) {
    this.ajax({
      method: 'DELETE',
      url: this.backend + '/posts/article/' + id
    }, callback);
  },

  updatePost: function updatePost(id, content, callback) {
    this.ajax({
      method: 'PATCH',
      url: this.backend + '/posts/article/' + id,
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(content),
      dataType: 'json'
    }, callback);
  }
};

var switchView = function switchView(view) {
  $('#main-page').hide();
  $('#view-all').hide();
  $('#view-one').hide();
  $('#create').hide();
  $('#update-view').hide();

  if(view === 'view-all') {
    console.log('switched to view all');
    $('#view-all').show();
  } else if (view === 'view-one') {
    console.log('switched to view one');
    $('#view-one').show();
  } else if (view === 'create') {
    console.log('switched to create');
    $('#create').show();
  } else if (view === 'update-view') {
    $('#update-view').show();
  } else {
    console.log('switched to view main');
    $('#main-page').show();
  }
};

var form2object = function(form) {
  var data = {};
  $(form).children().each(function(index, element) {
    var type = $(this).attr('type');
    if ($(this).attr('name') && type !== 'submit' && type !== 'hidden') {
      data[$(this).attr('name')] = $(this).val();
    }
  });
  console.log("Form output:");
  console.log(data);
  return data;
};

var allPostTemplate = Handlebars.compile($('#template-view-all').html());
var onePostTemplate = Handlebars.compile($('#template-view-one').html());

var serverData;
var callback = function callback(error, data) {
  if (error) {
    console.error(error);
    return;
  }
  serverData = data;
  console.log(serverData);
};

var onePostCallback = function onePostCallback(error, data) {
  if(error) {
    console.error(err);
    return;
  }
  var html = onePostTemplate(data);
  $('#view-one').html(html);

  $('#delete').on('click', function() {
    api.deletePost(data._id, callback);
    switchView('view-all');
    api.getUserPosts(data.userID, function(err, data) {
      if(err) {
        console.error(err);
        return;
      }
      var html = allPostTemplate(data);
      $('#view-all').html(html);
    });

  });

  $('#update').on('click', function() {
    var oldTitle = data.title;
    var oldBody = data.body;
    var oldID = data._id;
    $('#update-title').val(oldTitle);
    $('#update-body').val(oldBody);
    $('#update-ID').val(oldID);
    $('#update-view').show();
  });
};

Handlebars.registerHelper('xbbcodeParse', function(input) {
  var noHTMLinput = input.replace(/<(?:.|\n)*?>/gm, '');

  var result = XBBCODE.process({
      text: noHTMLinput,
      removeMisalignedTags: false,
      addInLineBreaks: true
  });
  console.log("Errors: " + result.error);
  console.dir(result.errorQueue);
  return result.html;
});
<|endoftext|>


<commit_before>if (typeof iD === 'undefined') iD = {};

iD.Util = {};

iD.Util._id = 0;

iD.Util.id = function() {
    return iD.Util._id++;
};

iD.Util.friendlyName = function(entity) {
    // summary:		Rough-and-ready function to return a human-friendly name
    //				for the object. Really just a placeholder for something better.
    // returns:		A string such as 'river' or 'Fred's House'.
    if (_.isEmpty(entity.tags)) { return ''; }

    var mainkeys = ['highway','amenity','railway','waterway'];
    var n = _.compact([entity.tags.name, entity.tags.ref]);

    if (!n.length) {
        var k = _.find(mainkeys, function(m) {
            return !!entity.tags[m];
        });
        if (k) n.push(entity.tags[k]);
    }

    return n.length === 0 ? 'unknown' : n.join('; ');
};

// TODO: don't use a cache here?
iD.Util._presets = {};
iD.Util.presets = function(type, callback) {
    if (iD.Util._presets[type]) return callback(iD.Util._presets[type]);
    $.ajax({
        url: 'presets/' + type + '.json',
        dataType: "json",
        error: function() {
            if (typeof console !== 'undefined') console.error(arguments);
        },
        success: function(resp) {
            iD.Util._presets[type] = resp;
            return callback(resp);
        }
    });
};

iD.Util.tileKey = function(coord) {
    return coord.z + ',' + coord.x + ',' + coord.y;
};
<commit_msg>Remove more underscore dep<commit_after>if (typeof iD === 'undefined') iD = {};

iD.Util = {};

iD.Util._id = 0;

iD.Util.id = function() {
    return iD.Util._id++;
};

iD.Util.friendlyName = function(entity) {
    // summary:		Rough-and-ready function to return a human-friendly name
    //				for the object. Really just a placeholder for something better.
    // returns:		A string such as 'river' or 'Fred's House'.
    if (!Object.keys(entity.tags).length) { return ''; }

    var mainkeys = ['highway','amenity','railway','waterway'];
    var n = [];

    if (entity.tags.name) n.push(entity.tags.name);
    if (entity.tags.ref) n.push(entity.tags.ref);

    if (!n.length) {
        for (var k in entity.tags) {
            if (mainkeys[k]) {
                n.push(entity.tags[k]);
                break;
            }
        }
    }

    return n.length === 0 ? 'unknown' : n.join('; ');
};

// TODO: don't use a cache here?
iD.Util._presets = {};
iD.Util.presets = function(type, callback) {
    if (iD.Util._presets[type]) return callback(iD.Util._presets[type]);
    $.ajax({
        url: 'presets/' + type + '.json',
        dataType: "json",
        error: function() {
            if (typeof console !== 'undefined') console.error(arguments);
        },
        success: function(resp) {
            iD.Util._presets[type] = resp;
            return callback(resp);
        }
    });
};

iD.Util.tileKey = function(coord) {
    return coord.z + ',' + coord.x + ',' + coord.y;
};
<|endoftext|>