<commit_before>//  Copyright 2002-2014, University of Colorado Boulder

/**
 * A physical-looking probe with a handle and a semicircular sensor region, used in simulations like Bending Light and
 * Beer's Law Lab to show how much light is being received. It is typically connected to a body with readouts with a
 * curved wire. The origin is in the center of the circular part of the sensor (which is not vertically symmetrical).
 *
 * This code was generalized from Bending Light, see https://github.com/phetsims/bending-light/issues/165
 *
 * TODO: This is under development and not ready for review or usage in simulations other than Bending Light.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chandrashekar Bemagoni (Actual Concepts)
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Shape = require( 'KITE/Shape' );
  var Path = require( 'SCENERY/nodes/Path' );
  var Vector2 = require( 'DOT/Vector2' );
  var LinearGradient = require( 'SCENERY/util/LinearGradient' );
  var RadialGradient = require( 'SCENERY/util/RadialGradient' );
  var Color = require( 'SCENERY/util/Color' );
  var Line = require( 'SCENERY/nodes/Line' );
  var Circle = require( 'SCENERY/nodes/Circle' );

  // Glass is one of the probe types, shows a shiny reflective interior in the central circle
  var glass = function( options ) {
    var GLASS_DEFAULTS = {
      centerColor: 'white',
      middleColor: '#E6F5FF', // light blue
      edgeColor: '#C2E7FF'    // slightly darker blue, like glass
    };
    options = _.extend( GLASS_DEFAULTS, options );
    return function( radius ) {
      return new Circle( radius, {
        fill: new RadialGradient( -radius * 0.15, -radius * 0.15, 0, -radius * 0.15, -radius * 0.20, radius * 0.60 )
          .addColorStop( 0, options.centerColor )
          .addColorStop( 0.4, options.middleColor ) // light blue
          .addColorStop( 1, options.edgeColor ) // slightly darker blue, like glass
      } );
    };
  };

  // Crosshairs cane be shown in the central circle
  var crosshairs = function( options ) {
    var CROSSHAIRS_DEFAULTS = {
      stroke: 'black',
      lineWidth: 3,

      // The amount of blank space visible at the intersection of the 2 crosshairs lines
      intersectionRadius: 8
    };
    options = _.extend( CROSSHAIRS_DEFAULTS, options );
    return function( radius ) {

      var lineOptions = { stroke: options.stroke, lineWidth: options.lineWidth };
      return new Node( {
        children: [
          new Line( -radius, 0, -options.intersectionRadius, 0, lineOptions ),
          new Line( +radius, 0, +options.intersectionRadius, 0, lineOptions ),
          new Line( 0, -radius, 0, -options.intersectionRadius, lineOptions ),
          new Line( 0, +radius, 0, +options.intersectionRadius, lineOptions ) ]
      } );
    };
  };

  // constants
  var DEFAULT_OPTIONS = {
    radius: 50,
    innerRadius: 35,
    handleWidth: 50,
    handleHeight: 30,
    handleCornerRadius: 30,
    lightAngle: 4.25, // in radians, the angle of the incoming light.  0 is from the right, PI/2 from the bottom,
                      // PI from the left, etc.  The default is from the upper-left
    color: '#008541', // darkish green

    // The circular part of the ProbeNode is called the sensor, where it receives light or has crosshairs, etc.
    // or null for an empty region
    sensorType: glass()
  };

  /**
   * Constructor for the ProbeNode
   * @param {Object} [options]
   * @constructor
   */
  function ProbeNode( options ) {

    options = _.extend( _.clone( DEFAULT_OPTIONS ), options );

    var color = new Color( options.color );

    // To improve readability
    var radius = options.radius;

    // the top of the handle, below the circle at the top of the sensor
    var handleBottom = radius + options.handleHeight;

    // The shape of the outer body, circular at top with a handle at the bottom
    var arcExtent = 0.8;
    var handleWidth = options.handleWidth;
    var innerRadius = Math.min( options.innerRadius, options.radius );
    var sensorShape = new Shape()

    // start in the bottom center
      .moveTo( 0, handleBottom )

      .lineTo( -handleWidth / 2, handleBottom )
      .lineTo( -handleWidth / 2, radius )

      // Top arc
      .ellipticalArc( 0, 0, radius, radius, 0, Math.PI * arcExtent, Math.PI * (1 - arcExtent), false )

      .lineTo( handleWidth / 2, radius )
      .lineTo( handleWidth / 2, handleBottom )

      .lineTo( 0, handleBottom )
      .moveTo( innerRadius, 0 )
      .arc( 0, 0, innerRadius, Math.PI * 2, 0, true )
      .close();

    // The light angle is variable so that you can create a probe node that is pointing up or to the side
    var lightAngle = options.lightAngle;
    var lightOrigin = Vector2.createPolar( radius / 2, lightAngle );
    var lightDestination = Vector2.createPolar( handleBottom, lightAngle + Math.PI );
    var gradientSource = lightOrigin;
    var gradientDestination = lightDestination;

    var outerShapePath = new Path( sensorShape, {
      stroke: new LinearGradient( gradientSource.x, gradientSource.y, gradientDestination.x, gradientDestination.y )
        .addColorStop( 0.0, color.colorUtilsBrightness( -0.1 ) ) // dark
        .addColorStop( 1.0, color.colorUtilsBrightness( -0.2 ) ), // darker
      fill: new LinearGradient( gradientSource.x, gradientSource.y, gradientDestination.x, gradientDestination.y )
        .addColorStop( 0.0, color.colorUtilsBrightness( +0.4 ) ) // light
        .addColorStop( 0.3, color.colorUtilsBrightness( +0.2 ) ) // medium light
        .addColorStop( 1.0, color.colorUtilsBrightness( -0.1 ) ), // less light
      lineWidth: 2
    } );

    // the front flat "surface" of the sensor, makes it look 3d by putting a shiny glare on the top edge
    var innerPath = new Path( sensorShape, {
      fill: options.color,
      lineWidth: 2,
      scale: new Vector2( 0.9, 0.93 ),
      centerX: outerShapePath.centerX,

      // Shift it down a bit to make the face look a bit more 3d
      y: 2
    } );

    var children = [];

    if ( options.sensorType ) {
      children.push( options.sensorType( radius ) );
    }

    children.push( outerShapePath, innerPath );

    Node.call( this, {
      children: children
    } );

    this.mutate( options );
  }

  return inherit( Node, ProbeNode, {},

    // statics
    {

      // @public {read-only}, make the defaults publicly available to clients in case they need to make
      // customizations, such as 0.9 x the default width
      DEFAULT_OPTIONS: DEFAULT_OPTIONS,

      // Sensor types
      // @public
      crosshairs: crosshairs,
      glass: glass
    } );
} );<commit_msg>Rounded out the probe node bottom corners, see #184<commit_after>//  Copyright 2002-2014, University of Colorado Boulder

/**
 * A physical-looking probe with a handle and a semicircular sensor region, used in simulations like Bending Light and
 * Beer's Law Lab to show how much light is being received. It is typically connected to a body with readouts with a
 * curved wire. The origin is in the center of the circular part of the sensor (which is not vertically symmetrical).
 *
 * This code was generalized from Bending Light, see https://github.com/phetsims/bending-light/issues/165
 *
 * TODO: This is under development and not ready for review or usage in simulations other than Bending Light.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chandrashekar Bemagoni (Actual Concepts)
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Shape = require( 'KITE/Shape' );
  var Path = require( 'SCENERY/nodes/Path' );
  var Vector2 = require( 'DOT/Vector2' );
  var LinearGradient = require( 'SCENERY/util/LinearGradient' );
  var RadialGradient = require( 'SCENERY/util/RadialGradient' );
  var Color = require( 'SCENERY/util/Color' );
  var Line = require( 'SCENERY/nodes/Line' );
  var Circle = require( 'SCENERY/nodes/Circle' );

  // Glass is one of the probe types, shows a shiny reflective interior in the central circle
  var glass = function( options ) {
    var GLASS_DEFAULTS = {
      centerColor: 'white',
      middleColor: '#E6F5FF', // light blue
      edgeColor: '#C2E7FF'    // slightly darker blue, like glass
    };
    options = _.extend( GLASS_DEFAULTS, options );
    return function( radius ) {
      return new Circle( radius, {
        fill: new RadialGradient( -radius * 0.15, -radius * 0.15, 0, -radius * 0.15, -radius * 0.20, radius * 0.60 )
          .addColorStop( 0, options.centerColor )
          .addColorStop( 0.4, options.middleColor ) // light blue
          .addColorStop( 1, options.edgeColor ) // slightly darker blue, like glass
      } );
    };
  };

  // Crosshairs cane be shown in the central circle
  var crosshairs = function( options ) {
    var CROSSHAIRS_DEFAULTS = {
      stroke: 'black',
      lineWidth: 3,

      // The amount of blank space visible at the intersection of the 2 crosshairs lines
      intersectionRadius: 8
    };
    options = _.extend( CROSSHAIRS_DEFAULTS, options );
    return function( radius ) {

      var lineOptions = { stroke: options.stroke, lineWidth: options.lineWidth };
      return new Node( {
        children: [
          new Line( -radius, 0, -options.intersectionRadius, 0, lineOptions ),
          new Line( +radius, 0, +options.intersectionRadius, 0, lineOptions ),
          new Line( 0, -radius, 0, -options.intersectionRadius, lineOptions ),
          new Line( 0, +radius, 0, +options.intersectionRadius, lineOptions ) ]
      } );
    };
  };

  // constants
  var DEFAULT_OPTIONS = {
    radius: 50,
    innerRadius: 35,
    handleWidth: 50,
    handleHeight: 30,
    handleCornerRadius: 10,
    lightAngle: 4.25, // in radians, the angle of the incoming light.  0 is from the right, PI/2 from the bottom,
                      // PI from the left, etc.  The default is from the upper-left
    color: '#008541', // darkish green

    // The circular part of the ProbeNode is called the sensor, where it receives light or has crosshairs, etc.
    // or null for an empty region
    sensorType: glass()
  };

  /**
   * Constructor for the ProbeNode
   * @param {Object} [options]
   * @constructor
   */
  function ProbeNode( options ) {

    options = _.extend( _.clone( DEFAULT_OPTIONS ), options );

    var color = new Color( options.color );

    // To improve readability
    var radius = options.radius;

    // the top of the handle, below the circle at the top of the sensor
    var handleBottom = radius + options.handleHeight;

    // The shape of the outer body, circular at top with a handle at the bottom
    var arcExtent = 0.8;
    var handleWidth = options.handleWidth;
    var innerRadius = Math.min( options.innerRadius, options.radius );
    var cornerRadius = options.handleCornerRadius;
    var sensorShape = new Shape()

    // start in the bottom center
      .moveTo( 0, handleBottom )

      .lineTo( -handleWidth / 2 + cornerRadius, handleBottom )
      .arc( -handleWidth / 2 + cornerRadius, handleBottom - cornerRadius, cornerRadius, Math.PI / 2, Math.PI, false )
      .lineTo( -handleWidth / 2, radius )

      // Top arc
      .ellipticalArc( 0, 0, radius, radius, 0, Math.PI * arcExtent, Math.PI * (1 - arcExtent), false )

      .lineTo( handleWidth / 2, radius )
      .lineTo( handleWidth / 2, handleBottom - cornerRadius )
      .arc( handleWidth / 2 - cornerRadius, handleBottom - cornerRadius, cornerRadius, 0, Math.PI / 2, false )

      .lineTo( 0, handleBottom )
      .moveTo( innerRadius, 0 )
      .arc( 0, 0, innerRadius, Math.PI * 2, 0, true )
      .close();

    // The light angle is variable so that you can create a probe node that is pointing up or to the side
    var lightAngle = options.lightAngle;
    var lightOrigin = Vector2.createPolar( radius / 2, lightAngle );
    var lightDestination = Vector2.createPolar( handleBottom, lightAngle + Math.PI );
    var gradientSource = lightOrigin;
    var gradientDestination = lightDestination;

    var outerShapePath = new Path( sensorShape, {
      stroke: new LinearGradient( gradientSource.x, gradientSource.y, gradientDestination.x, gradientDestination.y )
        .addColorStop( 0.0, color.colorUtilsBrightness( -0.1 ) ) // dark
        .addColorStop( 1.0, color.colorUtilsBrightness( -0.2 ) ), // darker
      fill: new LinearGradient( gradientSource.x, gradientSource.y, gradientDestination.x, gradientDestination.y )
        .addColorStop( 0.0, color.colorUtilsBrightness( +0.4 ) ) // light
        .addColorStop( 0.3, color.colorUtilsBrightness( +0.2 ) ) // medium light
        .addColorStop( 1.0, color.colorUtilsBrightness( -0.1 ) ), // less light
      lineWidth: 2
    } );

    // the front flat "surface" of the sensor, makes it look 3d by putting a shiny glare on the top edge
    var innerPath = new Path( sensorShape, {
      fill: options.color,
      lineWidth: 2,
      scale: new Vector2( 0.9, 0.93 ),
      centerX: outerShapePath.centerX,

      // Shift it down a bit to make the face look a bit more 3d
      y: 2
    } );

    var children = [];

    if ( options.sensorType ) {
      children.push( options.sensorType( radius ) );
    }

    children.push( outerShapePath, innerPath );

    Node.call( this, {
      children: children
    } );

    this.mutate( options );
  }

  return inherit( Node, ProbeNode, {},

    // statics
    {

      // @public {read-only}, make the defaults publicly available to clients in case they need to make
      // customizations, such as 0.9 x the default width
      DEFAULT_OPTIONS: DEFAULT_OPTIONS,

      // Sensor types
      // @public
      crosshairs: crosshairs,
      glass: glass
    } );
} );<|endoftext|>


<commit_before>// Copyright 2019, University of Colorado Boulder

/**
 * Stopwatch is the model for the stopwatch. It is responsible for time, location, and visibility.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const BooleanProperty = require( 'AXON/BooleanProperty' );
  const merge = require( 'PHET_CORE/merge' );
  const NumberProperty = require( 'AXON/NumberProperty' );
  const PhetioObject = require( 'TANDEM/PhetioObject' );
  const ReferenceIO = require( 'TANDEM/types/ReferenceIO' );
  const sceneryPhet = require( 'SCENERY_PHET/sceneryPhet' );
  const Tandem = require( 'TANDEM/Tandem' );
  const Vector2 = require( 'DOT/Vector2' );
  const Vector2Property = require( 'DOT/Vector2Property' );

  class Stopwatch extends PhetioObject {

    /**
     * @param {Object} [options]
     */
    constructor( options ) {

      options = merge( {
        position: Vector2.ZERO,
        isVisible: false,
        timePropertyOptions: {},

        // phet-io
        tandem: Tandem.REQUIRED,
        phetioType: ReferenceIO
      }, options );

      super( options );

      // @public - position of the stopwatch, in view coordinates
      this.positionProperty = new Vector2Property( options.position, {
        tandem: options.tandem.createTandem( 'positionProperty' )
      } );

      // @public - whether the stopwatch is visible
      this.isVisibleProperty = new BooleanProperty( options.isVisible, {
        tandem: options.tandem.createTandem( 'isVisibleProperty' )
      } );

      // @public - whether the stopwatch is running
      this.isRunningProperty = new BooleanProperty( false, {
        tandem: options.tandem.createTandem( 'isRunningProperty' )
      } );

      assert && assert( !options.timePropertyOptions.hasOwnProperty( 'tandem' ), 'Time property provides its own tandem' );

      // @public (read-only) time displayed on the stopwatch
      this.timeProperty = new NumberProperty( 0, merge( {
        units: 's',
        isValidValue: value => ( value >= 0 ),
        tandem: options.tandem.createTandem( 'timeProperty' ),
        phetioReadOnly: true,
        phetioHighFrequency: true
      }, options.timePropertyOptions ) );

      // When the stopwatch visibility changes, stop it and reset its value.
      const visibilityListener = () => {
        this.isRunningProperty.value = false;
        this.timeProperty.value = 0;
      };
      this.isVisibleProperty.link( visibilityListener );

      // @private
      this.disposeStopwatch = () => {
        this.isVisibleProperty.unlink( visibilityListener );
      };
    }

    /**
     * @public
     */
    dispose() {
      this.disposeStopwatch();
      this.positionProperty.dispose();
      this.isVisibleProperty.dispose();
      this.isRunningProperty.dispose();
      this.timeProperty.dispose();
      super.dispose();
    }

    /**
     * Resets the stopwatch.
     * @public
     */
    reset() {
      this.positionProperty.reset();
      this.isVisibleProperty.reset();
      this.isRunningProperty.reset();
      this.timeProperty.reset();
    }

    /**
     * Steps the stopwatch.
     * @param {number} dt - time delta, in the units appropriate for the corresponding model
     * @public
     */
    step( dt ) {
      assert && assert( typeof dt === 'number' && dt > 0, `invalid dt: ${dt}` );

      if ( this.isRunningProperty.value ) {
        this.timeProperty.value += dt;
      }
    }
  }

  return sceneryPhet.register( 'Stopwatch', Stopwatch );
} );<commit_msg>fix Stopwatch.dispose #170<commit_after>// Copyright 2019, University of Colorado Boulder

/**
 * Stopwatch is the model for the stopwatch. It is responsible for time, location, and visibility.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const BooleanProperty = require( 'AXON/BooleanProperty' );
  const merge = require( 'PHET_CORE/merge' );
  const NumberProperty = require( 'AXON/NumberProperty' );
  const PhetioObject = require( 'TANDEM/PhetioObject' );
  const ReferenceIO = require( 'TANDEM/types/ReferenceIO' );
  const sceneryPhet = require( 'SCENERY_PHET/sceneryPhet' );
  const Tandem = require( 'TANDEM/Tandem' );
  const Vector2 = require( 'DOT/Vector2' );
  const Vector2Property = require( 'DOT/Vector2Property' );

  class Stopwatch extends PhetioObject {

    /**
     * @param {Object} [options]
     */
    constructor( options ) {

      options = merge( {
        position: Vector2.ZERO,
        isVisible: false,
        timePropertyOptions: {},

        // phet-io
        tandem: Tandem.REQUIRED,
        phetioType: ReferenceIO
      }, options );

      super( options );

      // @public - position of the stopwatch, in view coordinates
      this.positionProperty = new Vector2Property( options.position, {
        tandem: options.tandem.createTandem( 'positionProperty' )
      } );

      // @public - whether the stopwatch is visible
      this.isVisibleProperty = new BooleanProperty( options.isVisible, {
        tandem: options.tandem.createTandem( 'isVisibleProperty' )
      } );

      // @public - whether the stopwatch is running
      this.isRunningProperty = new BooleanProperty( false, {
        tandem: options.tandem.createTandem( 'isRunningProperty' )
      } );

      assert && assert( !options.timePropertyOptions.hasOwnProperty( 'tandem' ), 'Time property provides its own tandem' );

      // @public (read-only) time displayed on the stopwatch
      this.timeProperty = new NumberProperty( 0, merge( {
        units: 's',
        isValidValue: value => ( value >= 0 ),
        tandem: options.tandem.createTandem( 'timeProperty' ),
        phetioReadOnly: true,
        phetioHighFrequency: true
      }, options.timePropertyOptions ) );

      // When the stopwatch visibility changes, stop it and reset its value.
      const visibilityListener = () => {
        this.isRunningProperty.value = false;
        this.timeProperty.value = 0;
      };
      this.isVisibleProperty.link( visibilityListener );

      // @private
      this.disposeStopwatch = () => {
        this.isVisibleProperty.unlink( visibilityListener );
        this.positionProperty.dispose();
        this.isVisibleProperty.dispose();
        this.isRunningProperty.dispose();
        this.timeProperty.dispose();
      };
    }

    /**
     * @public
     */
    dispose() {
      this.disposeStopwatch();
      super.dispose();
    }

    /**
     * Resets the stopwatch.
     * @public
     */
    reset() {
      this.positionProperty.reset();
      this.isVisibleProperty.reset();
      this.isRunningProperty.reset();
      this.timeProperty.reset();
    }

    /**
     * Steps the stopwatch.
     * @param {number} dt - time delta, in the units appropriate for the corresponding model
     * @public
     */
    step( dt ) {
      assert && assert( typeof dt === 'number' && dt > 0, `invalid dt: ${dt}` );

      if ( this.isRunningProperty.value ) {
        this.timeProperty.value += dt;
      }
    }
  }

  return sceneryPhet.register( 'Stopwatch', Stopwatch );
} );<|endoftext|>


<commit_before>
// Is app installed?
if ((window.navigator.hasOwnProperty('standalone') && window.navigator.standalone)) {
    /*
		If you are using framework7 you must Initialize your app here so
    	var myApp = new Framework7(); get rid of /* And The Text Inside
    	it except for var myApp = new Framework7(); and also remove this */

    */
}
else {
    document.body.setAttribute('class', 'install');
}

/*
	Add All Of This To Your JS Files At The Very Top And If You Are
	Using Framework7
	Get Rid Of This Default Initialization And Add The One Below Which
	I Already Setup For You.
*/

// Framework7 Initialize Code below Get Rid Of The
// var myApp = new Framework7();
// Already In Your my-app.js file and replace it with this one below
/*
// Initialize your app
if ((window.navigator.hasOwnProperty('standalone') && window.navigator.standalone)) {
    	var myApp = new Framework7();
}
else {
    document.body.setAttribute('class', 'install');
}*/<commit_msg>Fixed<commit_after>
// Is app installed?
if ((window.navigator.hasOwnProperty('standalone') && window.navigator.standalone)) {
    /*
		If you are using framework7 you must Initialize your app here so
    	var myApp = new Framework7(); get rid of /* And The Text Inside
    	it except for var myApp = new Framework7(); and also remove this */

    */
}
else {
    document.body.setAttribute('class', 'install');
}

/*
	Add All Of This To Your JS Files At The Very Top And If You Are
	Using Framework7
	Get Rid Of This Default Initialization And Add The One Below Which
	I Already Setup For You.
*/

// Framework7 Initialize Code below Get Rid Of The
// var myApp = new Framework7();
// Already In Your my-app.js file and replace it with this one below
/*
// Initialize your app
if ((window.navigator.hasOwnProperty('standalone') && window.navigator.standalone)) {
    	var myApp = new Framework7();
}
else {
    document.body.setAttribute('class', 'install');
}

*/<|endoftext|>


<commit_before>/**
 * Created by Mariandi on 11/03/2014.
 */
/*global angular*/
'use strict';

angular.module('defina-se-backoffice-ui')
    .directive("anguvideo", ['$sce','$rootScope', function ($sce,$rootScope) {
        return {
            restrict: 'EA',
            scope: {
                source: '=ngModel',
                width: '@',
                height: '@'
            },
            replace: true,
            template: '
' +
                            '' +
                      '
',
            link: function (scope, element, attrs) {

              var player;
              function onPlayerStateChange(event) {
                if (!event.data) {
                  $rootScope.$broadcast("anguvideo:finishVideo");
                }
              }
              (function onYouTubeIframeAPIReady() {
                player = new YT.Player('playerYV', {
                  events: {
                    'onStateChange': onPlayerStateChange
                  }
                });
              }());
                var origin = location.origin;
                var embedFriendlyUrl = "",
                    urlSections,
                    index;

                var youtubeParams = (attrs.hideControls ? '?autoplay=0&showinfo=0&controls=0&enablejsapi=1&origin='+origin : '?autoplay=1&enablejsapi=1&origin='+origin);

                scope.$watch('source', function (newVal) {
                    if (newVal) {
                        /*
                        * Need to convert the urls into a friendly url that can be embedded and be used in the available online players the services have provided
                        * for youtube: src="//www.youtube.com/embed/{{video_id}}"
                        * for vimeo: src="http://player.vimeo.com/video/{{video_id}}
                        */

                        if (newVal.indexOf("vimeo") >= 0) { // Displaying a vimeo video
                            if (newVal.indexOf("player.vimeo") >= 0) {
                                embedFriendlyUrl = newVal;
                            } else {
                                embedFriendlyUrl = newVal.replace("https:", "http:");
                                urlSections = embedFriendlyUrl.split(".com/");
                                embedFriendlyUrl = embedFriendlyUrl.replace("vimeo", "player.vimeo");
                                embedFriendlyUrl = embedFriendlyUrl.replace("/" + urlSections[urlSections.length - 1], "/video/" + urlSections[urlSections.length - 1] + "");
                                embedFriendlyUrl += '?autoplay=1&api=1&player_id=playerYV';
                            }

                            $(function() {
                                  var iframe = $('#playerYV')[0];
                                  var player = $f(iframe);
                                  // When the player is ready, add listeners for pause, finish, and playProgress
                                  player.addEvent('ready', function() {
                                      player.addEvent('finish', onFinish);
                                  });

                                  function onFinish(id) {
                                      $rootScope.$broadcast("anguvideo:finishVideo");
                                  }
                            });

                        } else if (newVal.indexOf("youtu.be") >= 0) {

                            index = newVal.indexOf(".be/");

                            embedFriendlyUrl = newVal.slice(index + 4, newVal.length);
                            embedFriendlyUrl = "http://www.youtube.com/embed/" + embedFriendlyUrl + youtubeParams;

                        } else if (newVal.indexOf("youtube.com") >= 0) { // displaying a youtube video

                            if (newVal.indexOf("embed") >= 0) {
                                embedFriendlyUrl = newVal + youtubeParams;
                            } else {
                                embedFriendlyUrl = newVal.replace("/watch?v=", "/embed/") + youtubeParams;
                            }

                        }

                        scope.url = $sce.trustAsResourceUrl(embedFriendlyUrl);
                        //console.log("done",  scope.url, embedFriendlyUrl);

                    }
                });
            }
        };
    }]);
<commit_msg>update<commit_after>/**
 * Created by Mariandi on 11/03/2014.
 */
/*global angular*/
'use strict';

angular.module('anguvideo',[])
    .directive("anguvideo", ['$sce','$rootScope', function ($sce,$rootScope) {
        return {
            restrict: 'EA',
            scope: {
                source: '=ngModel',
                width: '@',
                height: '@'
            },
            replace: true,
            template: '
' +
                            '' +
                      '
',
            link: function (scope, element, attrs) {

              var player;
              function onPlayerStateChange(event) {
                if (!event.data) {
                  $rootScope.$broadcast("anguvideo:finishVideo");
                }
              }
              (function onYouTubeIframeAPIReady() {
                player = new YT.Player('playerYV', {
                  events: {
                    'onStateChange': onPlayerStateChange
                  }
                });
              }());
                var origin = location.origin;
                var embedFriendlyUrl = "",
                    urlSections,
                    index;

                var youtubeParams = (attrs.hideControls ? '?autoplay=0&showinfo=0&controls=0&enablejsapi=1&origin='+origin : '?autoplay=1&enablejsapi=1&origin='+origin);

                scope.$watch('source', function (newVal) {
                    if (newVal) {
                        /*
                        * Need to convert the urls into a friendly url that can be embedded and be used in the available online players the services have provided
                        * for youtube: src="//www.youtube.com/embed/{{video_id}}"
                        * for vimeo: src="http://player.vimeo.com/video/{{video_id}}
                        */

                        if (newVal.indexOf("vimeo") >= 0) { // Displaying a vimeo video
                            if (newVal.indexOf("player.vimeo") >= 0) {
                                embedFriendlyUrl = newVal;
                            } else {
                                embedFriendlyUrl = newVal.replace("https:", "http:");
                                urlSections = embedFriendlyUrl.split(".com/");
                                embedFriendlyUrl = embedFriendlyUrl.replace("vimeo", "player.vimeo");
                                embedFriendlyUrl = embedFriendlyUrl.replace("/" + urlSections[urlSections.length - 1], "/video/" + urlSections[urlSections.length - 1] + "");
                                embedFriendlyUrl += '?autoplay=1&api=1&player_id=playerYV';
                            }

                            $(function() {
                                  var iframe = $('#playerYV')[0];
                                  var player = $f(iframe);
                                  // When the player is ready, add listeners for pause, finish, and playProgress
                                  player.addEvent('ready', function() {
                                      player.addEvent('finish', onFinish);
                                  });

                                  function onFinish(id) {
                                      $rootScope.$broadcast("anguvideo:finishVideo");
                                  }
                            });

                        } else if (newVal.indexOf("youtu.be") >= 0) {

                            index = newVal.indexOf(".be/");

                            embedFriendlyUrl = newVal.slice(index + 4, newVal.length);
                            embedFriendlyUrl = "http://www.youtube.com/embed/" + embedFriendlyUrl + youtubeParams;

                        } else if (newVal.indexOf("youtube.com") >= 0) { // displaying a youtube video

                            if (newVal.indexOf("embed") >= 0) {
                                embedFriendlyUrl = newVal + youtubeParams;
                            } else {
                                embedFriendlyUrl = newVal.replace("/watch?v=", "/embed/") + youtubeParams;
                            }

                        }

                        scope.url = $sce.trustAsResourceUrl(embedFriendlyUrl);
                        //console.log("done",  scope.url, embedFriendlyUrl);

                    }
                });
            }
        };
    }]);
<|endoftext|>


<commit_before>'use strict';
define(
    [
        'app/config',
        'three',
        'stats',
        'app/InputHandler',
        'app/classes/Debug',
        'app/classes/Camera',
        'app/classes/GameObjectManager',
        'app/classes/Planet',
        'app/classes/Star',
        'app/classes/SpaceShip',
        'app/classes/Grid'
    ],
    function(config, THREE, Stats, InputHandler, Debug, Camera, GameObjectManager, Planet, Star, SpaceShip, Grid) {
        let stats = new Stats();
        stats.showPanel(0);
        document.body.appendChild(stats.dom);

        let renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(config.canvasWidth, config.canvasHeight);
        document.getElementById('game').appendChild(renderer.domElement);

        config.maxAnisotropy = renderer.getMaxAnisotropy();

        let scene = new THREE.Scene();

        // Create camera
        let camera = new Camera(
            scene,
            renderer,
            config.camera.fov,
            config.canvasWidth / config.canvasHeight,
            0.1,
            1000,
            new THREE.Vector3(25, 50, 50)
        );

        scene.add(new THREE.AmbientLight( 0x101010 ));

        // Add objects
        GameObjectManager.add([
            new Grid(scene, 'grid', new THREE.Vector3(0, 0, 0), 750, 750, 60, true),

            new Planet(scene, 'redPlanet',     3.301,   20, new THREE.Vector3( 0, 18, 0), true, 0xff3333),
            new Planet(scene, 'homePlanet',   48.690,  100, new THREE.Vector3(25, 0,  0), true, 0x33ff33),

            new Star(  scene, 'sol',        1.9984E8, 1400, new THREE.Vector3( 0,  0, 0),       0xffff00),

            new SpaceShip(scene, 'player', 40.0, new THREE.Vector3(0, 0, -50))
        ]);

        // Give objects a speed so they won't
        // just plunge back into the sun
        GameObjectManager.get('redPlanet').velocity.setX(0.2);
        GameObjectManager.get('redPlanet').velocity.setZ(0.3);

        GameObjectManager.get('homePlanet').velocity.setY(0.03);
        GameObjectManager.get('homePlanet').velocity.setZ(0.3);

        GameObjectManager.get('player').velocity.setX(.2);
        GameObjectManager.get('player').velocity.setZ(0);

        // Inititiate
        let lastFrameTime    = 0;
        let lastDeltaTValues = [];
        let smoothDeltaT     = 0;

        function update(currentFrameTime) {
            stats.begin();
            Debug.clear();

            let deltaT = currentFrameTime - lastFrameTime;
            lastFrameTime = currentFrameTime;

            // Ugly hack to prevent "jumps" when the tab lost focus
            if(deltaT > 32) deltaT = 1000/60;

            // Smooth deltaT
            while(lastDeltaTValues.length >= config.framesToSmoothDeltaT) {
                lastDeltaTValues.splice(0, 1);
            }
            lastDeltaTValues.push(deltaT);
            smoothDeltaT = lastDeltaTValues.reduce(function(prev, cur) { return prev + cur;}) / lastDeltaTValues.length;

            // Update controls
            camera.controls.update();

            // Handle user input
            InputHandler.checkInput(camera);

            // Update all the objects' positions
            GameObjectManager.updatePositions(deltaT, smoothDeltaT);

            // Update all the objects
            GameObjectManager.update(deltaT, smoothDeltaT);

            // Render the scene
            renderer.render(scene, camera.camera);

            stats.end();
            requestAnimationFrame(update);
        }

        requestAnimationFrame(update);
    }
);<commit_msg>Added fog (fixes #7)<commit_after>'use strict';
define(
    [
        'app/config',
        'three',
        'stats',
        'app/InputHandler',
        'app/classes/Debug',
        'app/classes/Camera',
        'app/classes/GameObjectManager',
        'app/classes/Planet',
        'app/classes/Star',
        'app/classes/SpaceShip',
        'app/classes/Grid'
    ],
    function(config, THREE, Stats, InputHandler, Debug, Camera, GameObjectManager, Planet, Star, SpaceShip, Grid) {
        let stats = new Stats();
        stats.showPanel(0);
        document.body.appendChild(stats.dom);

        let renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(config.canvasWidth, config.canvasHeight);
        document.getElementById('game').appendChild(renderer.domElement);

        config.maxAnisotropy = renderer.getMaxAnisotropy();

        let scene = new THREE.Scene();
        scene.fog = new THREE.Fog(0x000000, 100, 300);

        // Create camera
        let camera = new Camera(
            scene,
            renderer,
            config.camera.fov,
            config.canvasWidth / config.canvasHeight,
            0.1,
            1000,
            new THREE.Vector3(25, 50, 50)
        );

        scene.add(new THREE.AmbientLight( 0x101010 ));

        // Add objects
        GameObjectManager.add([
            new Grid(scene, 'grid', new THREE.Vector3(0, 0, 0), 750, 750, 60, true),

            new Planet(scene, 'redPlanet',     3.301,   20, new THREE.Vector3( 0, 18, 0), true, 0xff3333),
            new Planet(scene, 'homePlanet',   48.690,  100, new THREE.Vector3(25, 0,  0), true, 0x33ff33),

            new Star(  scene, 'sol',        1.9984E8, 1400, new THREE.Vector3( 0,  0, 0),       0xffff00),

            new SpaceShip(scene, 'player', 40.0, new THREE.Vector3(0, 0, -50))
        ]);

        // Give objects a speed so they won't
        // just plunge back into the sun
        GameObjectManager.get('redPlanet').velocity.setX(0.2);
        GameObjectManager.get('redPlanet').velocity.setZ(0.3);

        GameObjectManager.get('homePlanet').velocity.setY(0.03);
        GameObjectManager.get('homePlanet').velocity.setZ(0.3);

        GameObjectManager.get('player').velocity.setX(.2);
        GameObjectManager.get('player').velocity.setZ(0);

        // Inititiate
        let lastFrameTime    = 0;
        let lastDeltaTValues = [];
        let smoothDeltaT     = 0;

        function update(currentFrameTime) {
            stats.begin();
            Debug.clear();

            let deltaT = currentFrameTime - lastFrameTime;
            lastFrameTime = currentFrameTime;

            // Ugly hack to prevent "jumps" when the tab lost focus
            if(deltaT > 32) deltaT = 1000/60;

            // Smooth deltaT
            while(lastDeltaTValues.length >= config.framesToSmoothDeltaT) {
                lastDeltaTValues.splice(0, 1);
            }
            lastDeltaTValues.push(deltaT);
            smoothDeltaT = lastDeltaTValues.reduce(function(prev, cur) { return prev + cur;}) / lastDeltaTValues.length;

            // Update controls
            camera.controls.update();

            // Handle user input
            InputHandler.checkInput(camera);

            // Update all the objects' positions
            GameObjectManager.updatePositions(deltaT, smoothDeltaT);

            // Update all the objects
            GameObjectManager.update(deltaT, smoothDeltaT);

            // Render the scene
            renderer.render(scene, camera.camera);

            stats.end();
            requestAnimationFrame(update);
        }

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


<commit_before>function DebtProto() {
	this.snowball = 0;
	this.getMinPayment = function() {
	    if(this.minpaymenttype === 'percent') {
			return Math.max(Math.round(this.balance*this.minpayment), 1);
	    } else {
			return this.minpayment;
	    }
	};
	this.getPayment = function() {
		if(this.onlymin) {
			return this.getMinPayment();
		} else {
			return this.payment;
		}
	};
	this.update = function() {
	    this.balance = this.balance * (1 + this.rate / 12) - this.getPayment();
	    this.balance = Math.round(this.balance);

	    if(this.balance < this.payment) {
			if(this.getminpaymenttype === 'dollar' && this.balance < this.minpayment) {
		    	this.minpayment = this.balance;
			}
			this.snowball = this.payment - this.balance;
			this.payment = this.balance;
	    }

	    if(this.balance <= 0) {
			this.balance = 0;
			this.minpayment = 0;
			this.snowball = this.payment;
			this.payment = 0;
	    }
	};
}

function Debt(name, balance, rate, payment, onlymin, minpayment, minpaymenttype) {
	this.name = name;
	this.balance = balance;
	this.rate = rate;
	this.payment = payment;
	this.onlymin = onlymin;
	this.minpayment = minpayment;
	this.minpaymenttype = minpaymenttype;
	$.extend( this, new DebtProto() );
}

function avalanche(debts, method) {
    var snowballs = debts.reduce(function(p, c) {return p + c.snowball;}, 0);

    if(snowballs > 0) {
        var toSnowball = debts.filter(function(debt) {return debt.snowball == 0;});

        debts.forEach(function(debt) {debt.snowball = 0;});

        if(toSnowball.length > 0) {
            var avalanche = method(toSnowball);
            avalanche.payment = avalanche.payment + snowballs;
		    avalanche.onlymin = false;
        }
    }
}

function sumBalances(debts) {
    return debts.reduce(function(p, c){return p + c.balance;}, 0);
}

function sumMinpayments(debts) {
    return debts.reduce(function(p, c) {return p + c.getMinPayment();}, 0);
}

function sumPayments(debts) {
    return debts.reduce(function(p, c) {return p + c.getPayment();}, 0);
}

function totalAccounts(debts) {
    return debts.reduce(function(p, c){return p + Math.min(c.balance, 1);}, 0);
}

function lowestBalance(debts){
    return debts.reduce(function(p, c) {
        if(p == null) {return c;}
        else if(p.balance > c.balance) {return c;}
        else if(p.balance === c.balance) {
			if(p.rate < c.rate) {return c;}
			else{return p;}
		}
		else {return p;}
    });
}

function highestRate(debts) {
    return debts.reduce(function(p, c) {
        if(p == null) {return c;}
        else if(p.rate < c.rate) {return c;}
		else if(p.rate === c.rate) {
			if(p.balance > c.balance) {return c;}
			else {return p;}
		}
        else{return p;}
    });
}

function usingMethod(debts, method) {
	var numOpen = totalAccounts(debts);

	var results = {
			balances: [['year', 'balance', 'minimum payment'],
				  [0, sumBalances(debts), sumMinpayments(debts)]],
			accounts: [['year','interest'],
				   [0, numOpen]],
			totalPaid: 0,
			months: 0
	};

	var month = 1;

	for(var balance = sumBalances(debts); balance > 0; balance = sumBalances(debts)) {
        debts.forEach(function(debt) {debt.update();});

		if(month % 12 === 0) {
			results.balances.push([month / 12, balance, sumMinpayments(debts)]);

		}

		var nowNumOpen = totalAccounts(debts);

		if(nowNumOpen !== numOpen) {
			results.interests.push([month / 12, nowNumOpen]);
			numOpen = nowNumOpen;
		}

		results.totalPaid = results.totalPaid + sumPayments(debts);

		if(typeof method !== 'undefined') {
			avalanche(debts, method);
		}

        month++;

        if(month > 500) {
            break;
        }
    }

	results.months = month;

	return results;
}

function getResults(debts) {
	var highest = JSON.parse(JSON.stringify(debts));
	highest.forEach(function(debt) {$.extend(debt, new DebtProto() );});

	var lowest = JSON.parse(JSON.stringify(debts));
	lowest.forEach(function(debt) {$.extend(debt, new DebtProto() );});

	var just = JSON.parse(JSON.stringify(debts));
	just.forEach(function(debt) {$.extend(debt, new DebtProto() );});

	var results = {
		highestRate: usingMethod(highest, highestRate),
		lowestBalance: usingMethod(lowest, lowestBalance),
		justPayments: usingMethod(just)
	};
    return results;
}

function getTimeString(months) {
	var years = Math.floor(months / 12);
	var m = months - years * 12;

	return years + " years " + m + " months";
}

function generateRow(debt) {
	var nameString = "<input type='text' name='name' value='" + debt.name + "' required />";
        var balanceString = "$<input type='number' name='balance' min='0' value='" + debt.balance + "' required />";
        var rateString = "<input type='number' name='rate' min='0' max='100' step='0.01' value='" + debt.rate * 100 + "' required />%";
        var paymentString = "$<input type='number' name='payment' min='0' value='" + debt.payment + "' required />";
	var onlyminString = "<input type='checkbox' name='onlymin' value='true' " + (debt.onlymin ? "checked " : "") +"/> Minimum";
        var minpaymentString = "<input type='number' name='minpayment' min='0' value='";

	if(debt.minpaymenttype === 'percent') {
	    minpaymentString = minpaymentString + debt.minpayment * 100;
	} else {
	    minpaymentString = minpaymentString + debt.minpayment;
	}

	minpaymentString = minpaymentString + "' required />";

        var minpaymenttypeString = "<select name='minpaymenttype'><option value='dollar'"
            + (debt.minpaymenttype === 'dollar' ? ' selected' : '')
            + ">dollar</option><option value='percent'"
            + (debt.minpaymenttype === 'percent' ? ' selected' : '')
            + ">percent</option></select>";

        var row = '
' + nameString + '	'
            + balanceString  + '	'
            + rateString + '	'
            + paymentString + onlyminString + '	'
            + minpaymentString + '	'
            + minpaymenttypeString + '
';

	return row;
}

function make(divString, results) {
	$('#' + divString + '-total-paid').append('$' + results.totalPaid + " in " + getTimeString(results.months));

    c3.generate({
        bindto: '#' + divString + '-balance-chart',
        data:{x: 'year', rows:results.balances, type:'spline'},
        axis:{x: {label: {text: 'year', position: 'outer-center'}},
              y: {label: {text: 'dollars', position: 'outer-middle'}}}
    });

    c3.generate({
        bindto: '#' + divString + '-interest-chart',
        data:{x: 'year', rows:results.accounts, type:'area-step'},
        axis:{x: {label: {text: 'year', position: 'outer-center'}},
              y: {label: {text: 'number of debts', position: 'outer-middle'}}}
    });
}

$(document).ready(function() {
	$("#addRowButton").click(function() {
		var row = generateRow(new Debt('', 0, 0, 0, 0, 'dollar'));
		$('#debt-table tbody').append(row);
	});

	$("#removeRowButton").click(function() {
		$('#debt-table tbody tr').last().remove();
	});

	var debts;

	if(hasKey('name') && hasKey('balance') && hasKey('rate') && hasKey('payment') && hasKey('minpayment')) {
		debts = getObjectArray();
		debts.forEach(function(debt) {
			$.extend( debt, new DebtProto() );
			debt.rate = debt.rate / 100;
			debt.balance = parseInt(debt.balance);
			debt.payment = parseInt(debt.payment);
			if(debt.minpaymenttype === 'percent') {
				debt.minpayment = debt.minpayment / 100;
			} else {
				debt.minpayment = parseInt(debt.minpayment);
			}
		});
	} else {
		debts = new Array();

		var house = new Debt('mortgage', 150000, 0.03, 750, true, 750, 'dollar');
		var car = new Debt('car loan', 20000, 0.1, 250, true, 250, 'dollar');
		var creditcard1 = new Debt('credit card 1', 5000, 0.20, 100, false, 0.04, 'percent');
		var creditcard2 = new Debt('credit card 2', 100, 0.01, 100, true, 0.04, 'percent');
		debts = [house, car, creditcard1, creditcard2];
	}

    for(var i = 0; i < debts.length; i++) {
        var debt = debts[i];

        $('#debt-table').append(generateRow(debt));
    }

    var results = getResults(debts);

	make('highest-rate', results.highestRate);
	make('lowest-balance', results.lowestBalance);
	make('just-payments', results.justPayments);
});<commit_msg>again...<commit_after>function DebtProto() {
	this.snowball = 0;
	this.getMinPayment = function() {
	    if(this.minpaymenttype === 'percent') {
			return Math.max(Math.round(this.balance*this.minpayment), 1);
	    } else {
			return this.minpayment;
	    }
	};
	this.getPayment = function() {
		if(this.onlymin) {
			return this.getMinPayment();
		} else {
			return this.payment;
		}
	};
	this.update = function() {
	    this.balance = this.balance * (1 + this.rate / 12) - this.getPayment();
	    this.balance = Math.round(this.balance);

	    if(this.balance < this.payment) {
			if(this.getminpaymenttype === 'dollar' && this.balance < this.minpayment) {
		    	this.minpayment = this.balance;
			}
			this.snowball = this.payment - this.balance;
			this.payment = this.balance;
	    }

	    if(this.balance <= 0) {
			this.balance = 0;
			this.minpayment = 0;
			this.snowball = this.payment;
			this.payment = 0;
	    }
	};
}

function Debt(name, balance, rate, payment, onlymin, minpayment, minpaymenttype) {
	this.name = name;
	this.balance = balance;
	this.rate = rate;
	this.payment = payment;
	this.onlymin = onlymin;
	this.minpayment = minpayment;
	this.minpaymenttype = minpaymenttype;
	$.extend( this, new DebtProto() );
}

function avalanche(debts, method) {
    var snowballs = debts.reduce(function(p, c) {return p + c.snowball;}, 0);

    if(snowballs > 0) {
        var toSnowball = debts.filter(function(debt) {return debt.snowball == 0;});

        debts.forEach(function(debt) {debt.snowball = 0;});

        if(toSnowball.length > 0) {
            var avalanche = method(toSnowball);
            avalanche.payment = avalanche.payment + snowballs;
		    avalanche.onlymin = false;
        }
    }
}

function sumBalances(debts) {
    return debts.reduce(function(p, c){return p + c.balance;}, 0);
}

function sumMinpayments(debts) {
    return debts.reduce(function(p, c) {return p + c.getMinPayment();}, 0);
}

function sumPayments(debts) {
    return debts.reduce(function(p, c) {return p + c.getPayment();}, 0);
}

function totalAccounts(debts) {
    return debts.reduce(function(p, c){return p + Math.min(c.balance, 1);}, 0);
}

function lowestBalance(debts){
    return debts.reduce(function(p, c) {
        if(p == null) {return c;}
        else if(p.balance > c.balance) {return c;}
        else if(p.balance === c.balance) {
			if(p.rate < c.rate) {return c;}
			else{return p;}
		}
		else {return p;}
    });
}

function highestRate(debts) {
    return debts.reduce(function(p, c) {
        if(p == null) {return c;}
        else if(p.rate < c.rate) {return c;}
		else if(p.rate === c.rate) {
			if(p.balance > c.balance) {return c;}
			else {return p;}
		}
        else{return p;}
    });
}

function usingMethod(debts, method) {
	var numOpen = totalAccounts(debts);

	var results = {
			balances: [['year', 'balance', 'minimum payment'],
				  [0, sumBalances(debts), sumMinpayments(debts)]],
			accounts: [['year','interest'],
				   [0, numOpen]],
			totalPaid: 0,
			months: 0
	};

	var month = 1;

	for(var balance = sumBalances(debts); balance > 0; balance = sumBalances(debts)) {
        debts.forEach(function(debt) {debt.update();});

		if(month % 12 === 0) {
			results.balances.push([month / 12, balance, sumMinpayments(debts)]);

		}

		var nowNumOpen = totalAccounts(debts);

		if(nowNumOpen !== numOpen) {
			results.accounts.push([month / 12, nowNumOpen]);
			numOpen = nowNumOpen;
		}

		results.totalPaid = results.totalPaid + sumPayments(debts);

		if(typeof method !== 'undefined') {
			avalanche(debts, method);
		}

        month++;

        if(month > 500) {
            break;
        }
    }

	results.months = month;

	return results;
}

function getResults(debts) {
	var highest = JSON.parse(JSON.stringify(debts));
	highest.forEach(function(debt) {$.extend(debt, new DebtProto() );});

	var lowest = JSON.parse(JSON.stringify(debts));
	lowest.forEach(function(debt) {$.extend(debt, new DebtProto() );});

	var just = JSON.parse(JSON.stringify(debts));
	just.forEach(function(debt) {$.extend(debt, new DebtProto() );});

	var results = {
		highestRate: usingMethod(highest, highestRate),
		lowestBalance: usingMethod(lowest, lowestBalance),
		justPayments: usingMethod(just)
	};
    return results;
}

function getTimeString(months) {
	var years = Math.floor(months / 12);
	var m = months - years * 12;

	return years + " years " + m + " months";
}

function generateRow(debt) {
	var nameString = "<input type='text' name='name' value='" + debt.name + "' required />";
        var balanceString = "$<input type='number' name='balance' min='0' value='" + debt.balance + "' required />";
        var rateString = "<input type='number' name='rate' min='0' max='100' step='0.01' value='" + debt.rate * 100 + "' required />%";
        var paymentString = "$<input type='number' name='payment' min='0' value='" + debt.payment + "' required />";
	var onlyminString = "<input type='checkbox' name='onlymin' value='true' " + (debt.onlymin ? "checked " : "") +"/> Minimum";
        var minpaymentString = "<input type='number' name='minpayment' min='0' value='";

	if(debt.minpaymenttype === 'percent') {
	    minpaymentString = minpaymentString + debt.minpayment * 100;
	} else {
	    minpaymentString = minpaymentString + debt.minpayment;
	}

	minpaymentString = minpaymentString + "' required />";

        var minpaymenttypeString = "<select name='minpaymenttype'><option value='dollar'"
            + (debt.minpaymenttype === 'dollar' ? ' selected' : '')
            + ">dollar</option><option value='percent'"
            + (debt.minpaymenttype === 'percent' ? ' selected' : '')
            + ">percent</option></select>";

        var row = '
' + nameString + '	'
            + balanceString  + '	'
            + rateString + '	'
            + paymentString + onlyminString + '	'
            + minpaymentString + '	'
            + minpaymenttypeString + '
';

	return row;
}

function make(divString, results) {
	$('#' + divString + '-total-paid').append('$' + results.totalPaid + " in " + getTimeString(results.months));

    c3.generate({
        bindto: '#' + divString + '-balance-chart',
        data:{x: 'year', rows:results.balances, type:'spline'},
        axis:{x: {label: {text: 'year', position: 'outer-center'}},
              y: {label: {text: 'dollars', position: 'outer-middle'}}}
    });

    c3.generate({
        bindto: '#' + divString + '-interest-chart',
        data:{x: 'year', rows:results.accounts, type:'area-step'},
        axis:{x: {label: {text: 'year', position: 'outer-center'}},
              y: {label: {text: 'number of debts', position: 'outer-middle'}}}
    });
}

$(document).ready(function() {
	$("#addRowButton").click(function() {
		var row = generateRow(new Debt('', 0, 0, 0, 0, 'dollar'));
		$('#debt-table tbody').append(row);
	});

	$("#removeRowButton").click(function() {
		$('#debt-table tbody tr').last().remove();
	});

	var debts;

	if(hasKey('name') && hasKey('balance') && hasKey('rate') && hasKey('payment') && hasKey('minpayment')) {
		debts = getObjectArray();
		debts.forEach(function(debt) {
			$.extend( debt, new DebtProto() );
			debt.rate = debt.rate / 100;
			debt.balance = parseInt(debt.balance);
			debt.payment = parseInt(debt.payment);
			if(debt.minpaymenttype === 'percent') {
				debt.minpayment = debt.minpayment / 100;
			} else {
				debt.minpayment = parseInt(debt.minpayment);
			}
		});
	} else {
		debts = new Array();

		var house = new Debt('mortgage', 150000, 0.03, 750, true, 750, 'dollar');
		var car = new Debt('car loan', 20000, 0.1, 250, true, 250, 'dollar');
		var creditcard1 = new Debt('credit card 1', 5000, 0.20, 100, false, 0.04, 'percent');
		var creditcard2 = new Debt('credit card 2', 100, 0.01, 100, true, 0.04, 'percent');
		debts = [house, car, creditcard1, creditcard2];
	}

    for(var i = 0; i < debts.length; i++) {
        var debt = debts[i];

        $('#debt-table').append(generateRow(debt));
    }

    var results = getResults(debts);

	make('highest-rate', results.highestRate);
	make('lowest-balance', results.lowestBalance);
	make('just-payments', results.justPayments);
});<|endoftext|>


<commit_before>// Para implementar agregar: onkeypress="return validaPatron(event, 'patron')"
function validaPatron(e, patron) {
    // Patron de entrada, en este caso solo aceptaria numeros o numeros y punto.
    // patron =[0-9]; patron =[0-9-.];
    tecla = (document.all) ? e.keyCode : e.which;
    // Tecla de retroceso para borrar, siempre la permite
    if (tecla==8) {
        return true;
    }
    patron = new RegExp(patron);
    tecla_final = String.fromCharCode(tecla);
    return patron.test(tecla_final);
}<commit_msg>fix permite tab, delete y enter<commit_after>// Para implementar agregar: onkeypress="return validaPatron(event, 'patron')"
function validaPatron(e, patron) {
    // Patron de entrada, en este caso solo aceptaria numeros o numeros y punto.
    // patron =[0-9]; patron =[0-9-.];
    tecla = (document.all) ? e.keyCode : e.which;
    // Teclas de retroceso para borrar, tab, enter, delete, siempre la permite
    if (tecla==8 || tecla==13) {
        return true;
    } else if (e.keyCode==9 || e.keyCode==46) {
        return true;
    }
    patron = new RegExp(patron);
    tecla_final = String.fromCharCode(tecla);
    return patron.test(tecla_final);
}<|endoftext|>


<commit_before>var TLDS = TLDS || [];
if (typeof require != 'undefined') {
	TLDS = require('./tlds').TLDS;
}

function loadValidTLDS() {
	var tldsArray = [];

	TLDS.forEach(function(tld){
		tldsArray.push('\\.' + tld + '(?!\\w)');
	});

	return tldsArray.join('|');
}

var validLinkMarkDownRegEx = new RegExp(loadValidTLDS() + '|^https?:\\/\\/', "i");

var _ = _ || null;
if ((typeof require != 'undefined') && !_) {
	var _ = require('underscore');
}

var Markdown = function(raw, options) {
	var options = options || {};
	if (!raw) {
		return '';
	}
	if (!options.dont_escape) {
		raw = _.escape(raw);
	}
	var code_blocks = {};
	var block_count = 0;
	var quote_tag = options.use_blockquote ? 'span class="blockquote"' : 'q';
	var end_quote_tag = options.use_blockquote ? '/span' : '/q';
	var bench = +new Date();
	var link_last_offset = bold_last_offset = italic_last_offset = strike_last_offset = underline_last_offset = 0;
	var test = 0;
	var total = 0;
	var link_was_inside_tag = bold_in_url = italic_in_url = strike_in_url = underline_in_url = false;
	var val = raw.replace(/\&\#x2F;/g, '/'). // not sure why underscore replaces these...docs don't even claim that it does
		replace(/\[([^\]]*?)\]\(([\s\S]*?)\)/g, function(full_match, text, link) {
			if (text === 'code') {
				return full_match;
			}

			if(!validLinkMarkDownRegEx.test(link)) {
				return full_match;
			}

			return "" + text + "";

		}).
		replace(Markdown.global_url_regex, function(
			full_match,
			maybe_email1,
			maybe_email2,
			link,
			proto_and_slashes,
			protocol,
			junk,
			junkpoint5,
			junk1,
			junk2,
			junk3,
			junk4,
			junk5,
			junk6,
			last_char,
			offset,
			full_str
	) {
			if(!validLinkMarkDownRegEx.test(link)) {
				return full_match;
			}

			var sub_bench = +new Date();
			var start = full_str.substr(link_last_offset, offset - link_last_offset);
			link_last_offset = offset;
			if (start.match(/.*\($/)) {
				return full_match;
			}
			var inside_tag = link_was_inside_tag ? (start.match(/.*>[^<]*$/) ? false : true) : start.match(/.*<[^>]*$/);
			if (inside_tag) {
				link_was_inside_tag = true;
				return full_match;
			}
			link_was_inside_tag = false;
			var inside_post_tag = start.match(/.*(\{\{-\{\{)(?![\s\S]*\}\}-\}\})[\s\S]*$/);
			if (inside_post_tag) {
				return full_match;
			}
			var lead_match = full_str.substring(0, offset);
			var lead_str = lead_match + full_match;
			var link_matches = lead_str.replace(/\{\{\-\{\{/g, '<').replace(/\}\}-\}\}/g, '>').match(/^[\s\S]*([\s\S]*?)$/);
			if (link_matches) {
				var link_match = link_matches[1];
				if (!link_match.match(/<\/a>/) || link_match.match(/<\/a>$/)) {
					return full_match;
				}
			}
			//console.warn("nomatch:", +new Date() - sub_bench);
			return "" +
					(maybe_email2 ? maybe_email2 : '') +
					link + "" + last_char;
		}).
		replace(/\[code\]([\s\S]*?)(\[\/code\]|$)/gi, function(full_match, text) {
			var code;
			try {
				code = unescape(text);
			}
			catch(error) {
				code = text.replace(/(\%\w\w)/g, function(fm, esc) {
					return unescape(esc);
				});
			}
			code_blocks['code_' + block_count] = code;
			var to_return = '[code_' + block_count + ']';
			block_count++;
			return to_return;
		}).
		replace(/\|([^\n]*)\|(\s|\n|$)/g, function(full_match, text) {
			var cols = text.split(/\|/);
			if (!cols.length) {
				return text;
			}
			var percent = (100 / cols.length).toFixed(0);
			return "

" +
					cols.join("	") +
				"

";
		}).
		replace(/<\/table>
/, '').
		replace(/((^|\n)\* [^\*\n]*)+/g, function(full_match, junk, start) {
			var parts = full_match.split(/\n/);
			if (parts[0].length === 0) {
				parts.shift();
			}
			return start + "

" +
				parts.map(function(part) { return part.replace(/^\* /, ''); }).
					join("

") +
				"

";
		}).
		replace(/\*\*(\S[^\*\*]*?\S)\*\*/g, function(full_match, text, offset, full_str) {
			total++;
			if (Markdown.is_in_url(full_match, text, offset, full_str, bold_in_url, bold_last_offset)) {
				bold_last_offset = offset;
				bold_in_url = true;
				return full_match;
			}
			bold_last_offset = offset;
			bold_in_url = false;
			return "" + text + "";
		}).
		replace(/\*(\S[^\*]*?\S)\*/g, function(full_match, text, offset, full_str) {
			if (Markdown.is_in_url(full_match, text, offset, full_str, italic_in_url, italic_last_offset)) {
				italic_last_offset = offset;
				italic_in_url = true;
				return full_match;
			}
			italic_last_offset = offset;
			italic_in_url = false;
			return "" + text + "";
		}).
		replace(/__(\S[^__]*?\S)__/g, function(full_match, text, offset, full_str) {
			if (Markdown.is_in_url(full_match, text, offset, full_str, underline_in_url, underline_last_offset)) {
				underline_last_offset = offset;
				underline_in_url = true;
				return full_match;
			}
			underline_last_offset = offset;
			underline_in_url = false;
			return "" + text + "";
		}).
		replace(/~~(\S[^~~]*?\S)~~/g, function(full_match, text, offset, full_str) {
			if (Markdown.is_in_url(full_match, text, offset, full_str, strike_in_url, strike_last_offset)) {
				strike_last_offset = offset;
				strike_in_url = true;
				return full_match;
			}
			strike_last_offset = offset;
			strike_in_url = false;
			return "" + text + "";
		}).
		replace(/\{\{\[\[-([^\{\{\[\[]*?)-\]\]\}\}/g, function(full_match, text, offset, full_str) {
			return "" + text + "";
		}).
		replace(/(^|\n)> ([^\n]*)/g, function(full_match, start, text) {
			return start + "<" + quote_tag + ">" + text + "<" + end_quote_tag + ">";
		}).
		replace(/\[code_(\w+)\]/g, function(full_match, which) {
			return "
" + code_blocks['code_' + which] + "
";
		}).
		replace(/mailto:<a href=/g, function(full_match, which) {
			return "[^<]*$/) : start.match(/.*<[^>]*$/);
	if (inside_tag) { return true; }
	var last_str = /([A-Za-z0-9\!\#\$\%\&\'\*\+\-\/\=\?\%\_\`\{\|\}\~\.\:]+)$/g.exec(start);
	if (last_str) {
		var potential_url = last_str[0] + text;
		if (potential_url.match(Markdown.url_regex)) {
			return true;
		}
	}
	return false;
};

var Markdown_Is_Valid_Link = function(link) {
	return validLinkMarkDownRegEx.test(link);
}

Markdown.tld_url_regex = validLinkMarkDownRegEx;
Markdown.url_regex = /^((ftp|https?):\/\/)?[-\w]+\.([-\w]+\.)*(\d+\.\d+\.\d+|[-A-Za-z]+)(:\d+)?($|(\/\S?(\/\S)*\/?)|(\#\S?)|(\?\S?))/i;
Markdown.global_url_regex = /(([a-zA-Z0-9\!\#\$\%\&\'\*\+\-\/\=\?\%\_\`\{\|\}\~\.]+@)?)(((ftp|https?):\/\/)?[-\w]+\.([-\w]+\.)*(\d+\.\d+\.\d+|[-A-Za-z]+)(:\d+)?(((\/([A-Za-z0-9-\._~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=])*)+)\??([A-Za-z0-9-\._~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\%])*)?)([^A-Za-z]|$)/gi;

var Markdown_For_Search = function(raw, options) {
	options = options || {};
	if (!raw) { return ''; }
	if (!options.dont_escape) {
		raw = _.escape(raw);
	}
	return raw.replace(/\{\{\[\[-([^\{\{\[\[]*?)-\]\]\}\}/g, function(full_match, text) {
		return "" + text + "";
	});
};

var Remove_Markdown = function(raw, options) {
	options = options || {};
	return (options.dont_escape ? raw : _.escape(raw)).
		replace(/\&\#x2F;/g, '/'). // not sure why underscore replaces these...docs don't even claim that it does
		replace(/\[code\]/g, '').
		replace(/\[\/code\]/g,'').
		replace(/\|([^\n]*)\|/g, function(full_match, text) {
			var cols = text.split(/\|/);
			if (!cols.length) {
				return text;
			}
			return cols.join('\t');
		}).
		replace(/\*\*(\S[^\*\*]*?\S)\*\*/g, function(full_match, text) {
			return text;
		}).
		// replace(/\`(.*?)\`/g, function(full_match, text) {
		// 	return text;
		// }).
		replace(/\*(\S[^\*]*?\S)\*/g, function(full_match, text) {
			return text;
		}).
		replace(/__(\S[^__]*?\S)__/g, function(full_match, text) {
			return text;
		}).
		replace(/~~(\S[^~~]*?\S)~~/g, function(full_match, text) {
			return text;
		}).
		replace(/(^|\n)> ([^\n]*)/g, function(full_match, start, text) {
			return start + " " + text + " ";
		}).
		replace(/\[([^\]]*?)\]\(([\s\S]*?)\)/g, function(full_match, text, link) {
			return text;
		});
};

if (typeof exports == 'object') {
	exports.Markdown = Markdown;
	exports.Remove_Markdown = Remove_Markdown;
	exports.Markdown_For_Search = Markdown_For_Search;
	exports.Markdown_Is_Valid_Link = Markdown_Is_Valid_Link;
}
<commit_msg>Preventing unescaped code blocks from rendering  open and close brackets.<commit_after>var TLDS = TLDS || [];
if (typeof require != 'undefined') {
	TLDS = require('./tlds').TLDS;
}

function loadValidTLDS() {
	var tldsArray = [];

	TLDS.forEach(function(tld){
		tldsArray.push('\\.' + tld + '(?!\\w)');
	});

	return tldsArray.join('|');
}

var validLinkMarkDownRegEx = new RegExp(loadValidTLDS() + '|^https?:\\/\\/', "i");

var _ = _ || null;
if ((typeof require != 'undefined') && !_) {
	var _ = require('underscore');
}

var Markdown = function(raw, options) {
	var options = options || {};
	if (!raw) {
		return '';
	}
	if (!options.dont_escape) {
		raw = _.escape(raw);
	}
	var code_blocks = {};
	var block_count = 0;
	var quote_tag = options.use_blockquote ? 'span class="blockquote"' : 'q';
	var end_quote_tag = options.use_blockquote ? '/span' : '/q';
	var bench = +new Date();
	var link_last_offset = bold_last_offset = italic_last_offset = strike_last_offset = underline_last_offset = 0;
	var test = 0;
	var total = 0;
	var link_was_inside_tag = bold_in_url = italic_in_url = strike_in_url = underline_in_url = false;
	var val = raw.replace(/\&\#x2F;/g, '/'). // not sure why underscore replaces these...docs don't even claim that it does
		replace(/\[([^\]]*?)\]\(([\s\S]*?)\)/g, function(full_match, text, link) {
			if (text === 'code') {
				return full_match;
			}

			if(!validLinkMarkDownRegEx.test(link)) {
				return full_match;
			}

			return "" + text + "";

		}).
		replace(Markdown.global_url_regex, function(
			full_match,
			maybe_email1,
			maybe_email2,
			link,
			proto_and_slashes,
			protocol,
			junk,
			junkpoint5,
			junk1,
			junk2,
			junk3,
			junk4,
			junk5,
			junk6,
			last_char,
			offset,
			full_str
	) {
			if(!validLinkMarkDownRegEx.test(link)) {
				return full_match;
			}

			var sub_bench = +new Date();
			var start = full_str.substr(link_last_offset, offset - link_last_offset);
			link_last_offset = offset;
			if (start.match(/.*\($/)) {
				return full_match;
			}
			var inside_tag = link_was_inside_tag ? (start.match(/.*>[^<]*$/) ? false : true) : start.match(/.*<[^>]*$/);
			if (inside_tag) {
				link_was_inside_tag = true;
				return full_match;
			}
			link_was_inside_tag = false;
			var inside_post_tag = start.match(/.*(\{\{-\{\{)(?![\s\S]*\}\}-\}\})[\s\S]*$/);
			if (inside_post_tag) {
				return full_match;
			}
			var lead_match = full_str.substring(0, offset);
			var lead_str = lead_match + full_match;
			var link_matches = lead_str.replace(/\{\{\-\{\{/g, '<').replace(/\}\}-\}\}/g, '>').match(/^[\s\S]*([\s\S]*?)$/);
			if (link_matches) {
				var link_match = link_matches[1];
				if (!link_match.match(/<\/a>/) || link_match.match(/<\/a>$/)) {
					return full_match;
				}
			}
			//console.warn("nomatch:", +new Date() - sub_bench);
			return "" +
					(maybe_email2 ? maybe_email2 : '') +
					link + "" + last_char;
		}).
		replace(/\[code\]([\s\S]*?)(\[\/code\]|$)/gi, function(full_match, text) {
			var code;
			try {
				code = unescape(text);
				code = code.replace(/</g, '<').replace(/>/g, '>');
			}
			catch(error) {
				code = text.replace(/(\%\w\w)/g, function(fm, esc) {
					return unescape(esc);
				});
			}
			code_blocks['code_' + block_count] = code;
			var to_return = '[code_' + block_count + ']';
			block_count++;
			return to_return;
		}).
		replace(/\|([^\n]*)\|(\s|\n|$)/g, function(full_match, text) {
			var cols = text.split(/\|/);
			if (!cols.length) {
				return text;
			}
			var percent = (100 / cols.length).toFixed(0);
			return "

" +
					cols.join("	") +
				"

";
		}).
		replace(/<\/table>
/, '').
		replace(/((^|\n)\* [^\*\n]*)+/g, function(full_match, junk, start) {
			var parts = full_match.split(/\n/);
			if (parts[0].length === 0) {
				parts.shift();
			}
			return start + "

" +
				parts.map(function(part) { return part.replace(/^\* /, ''); }).
					join("

") +
				"

";
		}).
		replace(/\*\*(\S[^\*\*]*?\S)\*\*/g, function(full_match, text, offset, full_str) {
			total++;
			if (Markdown.is_in_url(full_match, text, offset, full_str, bold_in_url, bold_last_offset)) {
				bold_last_offset = offset;
				bold_in_url = true;
				return full_match;
			}
			bold_last_offset = offset;
			bold_in_url = false;
			return "" + text + "";
		}).
		replace(/\*(\S[^\*]*?\S)\*/g, function(full_match, text, offset, full_str) {
			if (Markdown.is_in_url(full_match, text, offset, full_str, italic_in_url, italic_last_offset)) {
				italic_last_offset = offset;
				italic_in_url = true;
				return full_match;
			}
			italic_last_offset = offset;
			italic_in_url = false;
			return "" + text + "";
		}).
		replace(/__(\S[^__]*?\S)__/g, function(full_match, text, offset, full_str) {
			if (Markdown.is_in_url(full_match, text, offset, full_str, underline_in_url, underline_last_offset)) {
				underline_last_offset = offset;
				underline_in_url = true;
				return full_match;
			}
			underline_last_offset = offset;
			underline_in_url = false;
			return "" + text + "";
		}).
		replace(/~~(\S[^~~]*?\S)~~/g, function(full_match, text, offset, full_str) {
			if (Markdown.is_in_url(full_match, text, offset, full_str, strike_in_url, strike_last_offset)) {
				strike_last_offset = offset;
				strike_in_url = true;
				return full_match;
			}
			strike_last_offset = offset;
			strike_in_url = false;
			return "" + text + "";
		}).
		replace(/\{\{\[\[-([^\{\{\[\[]*?)-\]\]\}\}/g, function(full_match, text, offset, full_str) {
			return "" + text + "";
		}).
		replace(/(^|\n)> ([^\n]*)/g, function(full_match, start, text) {
			return start + "<" + quote_tag + ">" + text + "<" + end_quote_tag + ">";
		}).
		replace(/\[code_(\w+)\]/g, function(full_match, which) {
			return "
" + code_blocks['code_' + which] + "
";
		}).
		replace(/mailto:<a href=/g, function(full_match, which) {
			return "[^<]*$/) : start.match(/.*<[^>]*$/);
	if (inside_tag) { return true; }
	var last_str = /([A-Za-z0-9\!\#\$\%\&\'\*\+\-\/\=\?\%\_\`\{\|\}\~\.\:]+)$/g.exec(start);
	if (last_str) {
		var potential_url = last_str[0] + text;
		if (potential_url.match(Markdown.url_regex)) {
			return true;
		}
	}
	return false;
};

var Markdown_Is_Valid_Link = function(link) {
	return validLinkMarkDownRegEx.test(link);
}

Markdown.tld_url_regex = validLinkMarkDownRegEx;
Markdown.url_regex = /^((ftp|https?):\/\/)?[-\w]+\.([-\w]+\.)*(\d+\.\d+\.\d+|[-A-Za-z]+)(:\d+)?($|(\/\S?(\/\S)*\/?)|(\#\S?)|(\?\S?))/i;
Markdown.global_url_regex = /(([a-zA-Z0-9\!\#\$\%\&\'\*\+\-\/\=\?\%\_\`\{\|\}\~\.]+@)?)(((ftp|https?):\/\/)?[-\w]+\.([-\w]+\.)*(\d+\.\d+\.\d+|[-A-Za-z]+)(:\d+)?(((\/([A-Za-z0-9-\._~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=])*)+)\??([A-Za-z0-9-\._~:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\%])*)?)([^A-Za-z]|$)/gi;

var Markdown_For_Search = function(raw, options) {
	options = options || {};
	if (!raw) { return ''; }
	if (!options.dont_escape) {
		raw = _.escape(raw);
	}
	return raw.replace(/\{\{\[\[-([^\{\{\[\[]*?)-\]\]\}\}/g, function(full_match, text) {
		return "" + text + "";
	});
};

var Remove_Markdown = function(raw, options) {
	options = options || {};
	return (options.dont_escape ? raw : _.escape(raw)).
		replace(/\&\#x2F;/g, '/'). // not sure why underscore replaces these...docs don't even claim that it does
		replace(/\[code\]/g, '').
		replace(/\[\/code\]/g,'').
		replace(/\|([^\n]*)\|/g, function(full_match, text) {
			var cols = text.split(/\|/);
			if (!cols.length) {
				return text;
			}
			return cols.join('\t');
		}).
		replace(/\*\*(\S[^\*\*]*?\S)\*\*/g, function(full_match, text) {
			return text;
		}).
		// replace(/\`(.*?)\`/g, function(full_match, text) {
		// 	return text;
		// }).
		replace(/\*(\S[^\*]*?\S)\*/g, function(full_match, text) {
			return text;
		}).
		replace(/__(\S[^__]*?\S)__/g, function(full_match, text) {
			return text;
		}).
		replace(/~~(\S[^~~]*?\S)~~/g, function(full_match, text) {
			return text;
		}).
		replace(/(^|\n)> ([^\n]*)/g, function(full_match, start, text) {
			return start + " " + text + " ";
		}).
		replace(/\[([^\]]*?)\]\(([\s\S]*?)\)/g, function(full_match, text, link) {
			return text;
		});
};

if (typeof exports == 'object') {
	exports.Markdown = Markdown;
	exports.Remove_Markdown = Remove_Markdown;
	exports.Markdown_For_Search = Markdown_For_Search;
	exports.Markdown_Is_Valid_Link = Markdown_Is_Valid_Link;
}
<|endoftext|>


<commit_before>var global = window || GLOBAL;

/****************************************************************************************
 * Function signatures have been intentionally left out of the comments describing what *
 * each function does so that you can have practice looking up documentation. Please    *
 * Reference the documentation at [ https://lodash.com/docs/4.17.4 ] You should have    *
 * documentation up in a browser window at all times when working on projects!          *
 ****************************************************************************************/

global.bruhdash = {

  // returns the first element of an array
  first: function () {

  },

  // returns the last element of an array
  last: function () {

  },

  // returns the index of the first matching element from left to right
  indexOf: function () {

  },

  // returns the index of the first matching element from right to left
  lastIndexof: function () {

  },

  // returns an array with all elements except for the last element
  initial: function () {

  },

  // returns an array with all falsey values removed
  compact: function() {

  },

  // creates a slice of an array from the start index up to but not including the end index
  slice: function () {

  },

  // returns a slice of array with n elements dropped from the beignning
  drop: function(){

  },

  // returns a slice of array with n elements dropped from the end
  dropRight: function() {

  },

  // creates a slice of an array with n elements taken from the beginning
  take: function () {

  },

  // creates a slice of an array with n elements taken from the end
  takeRight: function () {

  },

  // fills elements of array with specified value from the start index
  // up to but not including the end index
  fill: function() {

  },

  // removes all given values from an array
  pull: function () {

  },

  // removes elements of an array corresponding to the given indices
  pullAt: function () {

  },

  // creates an array excluding all the specified values
  without: function() {

  },

  // returns an array with specified values excluded
  difference: function() {

  },

  /*******************
   *  STRETCH GOALS! *
   *******************/

  // creates an array of grouped elements
  zip: function () {

  },

  // creates an array of grouped elements in their pre-zip configuration
  unzip: function () {

  },

  // creates an array of elements into groups of length of specified size
  chunk: function(){

  },

  // iterates over elements of a collection and invokes iteratee for each element
  // Note: this should work for arrays and objects
  forEach: function() {

  },

  // creates an array of values by running each element in collection thru the iteratee
  // Note: this should work for arrays and objects
  map: function() {

  },

  /*************************
   *  SUPER STRETCH GOALS!  *
   *************************/

  // iterates over elements of a collection and returns all elements that the predicate returns truthy for
  // Note: this should work for arrays and objects
  filter: function() {

  },

  // Reduces the collection to a value which is the accumulated result of running each element
  // in the collection through an iteratee
  // Note: this should work for arrays and objects
  reduce: function() {

  }
};
<commit_msg>camelcase<commit_after>var global = window || GLOBAL;

/****************************************************************************************
 * Function signatures have been intentionally left out of the comments describing what *
 * each function does so that you can have practice looking up documentation. Please    *
 * Reference the documentation at [ https://lodash.com/docs/4.17.4 ] You should have    *
 * documentation up in a browser window at all times when working on projects!          *
 ****************************************************************************************/

global.bruhdash = {

  // returns the first element of an array
  first: function () {

  },

  // returns the last element of an array
  last: function () {

  },

  // returns the index of the first matching element from left to right
  indexOf: function () {

  },

  // returns the index of the first matching element from right to left
  lastIndexOf: function () {

  },

  // returns an array with all elements except for the last element
  initial: function () {

  },

  // returns an array with all falsey values removed
  compact: function() {

  },

  // creates a slice of an array from the start index up to but not including the end index
  slice: function () {

  },

  // returns a slice of array with n elements dropped from the beignning
  drop: function(){

  },

  // returns a slice of array with n elements dropped from the end
  dropRight: function() {

  },

  // creates a slice of an array with n elements taken from the beginning
  take: function () {

  },

  // creates a slice of an array with n elements taken from the end
  takeRight: function () {

  },

  // fills elements of array with specified value from the start index
  // up to but not including the end index
  fill: function() {

  },

  // removes all given values from an array
  pull: function () {

  },

  // removes elements of an array corresponding to the given indices
  pullAt: function () {

  },

  // creates an array excluding all the specified values
  without: function() {

  },

  // returns an array with specified values excluded
  difference: function() {

  },

  /*******************
   *  STRETCH GOALS! *
   *******************/

  // creates an array of grouped elements
  zip: function () {

  },

  // creates an array of grouped elements in their pre-zip configuration
  unzip: function () {

  },

  // creates an array of elements into groups of length of specified size
  chunk: function(){

  },

  // iterates over elements of a collection and invokes iteratee for each element
  // Note: this should work for arrays and objects
  forEach: function() {

  },

  // creates an array of values by running each element in collection thru the iteratee
  // Note: this should work for arrays and objects
  map: function() {

  },

  /*************************
   *  SUPER STRETCH GOALS!  *
   *************************/

  // iterates over elements of a collection and returns all elements that the predicate returns truthy for
  // Note: this should work for arrays and objects
  filter: function() {

  },

  // Reduces the collection to a value which is the accumulated result of running each element
  // in the collection through an iteratee
  // Note: this should work for arrays and objects
  reduce: function() {

  }
};
<|endoftext|>


<commit_before>define(function(require, exports, module) {
    main.consumes = [
        "c9", "Previewer", "fs", "dialog.error", "commands", "tabManager",
        "layout", "settings"
    ];
    main.provides = ["preview.markdown"];
    return main;

    // @todo possible improvements: http://benweet.github.io/stackedit/#

    function main(options, imports, register) {
        var Previewer = imports.Previewer;
        var c9 = imports.c9;
        var fs = imports.fs;
        var commands = imports.commands;
        var layout = imports.layout;
        var settings = imports.settings;
        var tabManager = imports.tabManager;
        var showError = imports["dialog.error"].show;
        var dirname = require("path").dirname;

        /***** Initialization *****/

        var plugin = new Previewer("Ajax.org", main.consumes, {
            caption: "Markdown",
            index: 200,
            selector: function(path) {
                return path && path.match(/(?:\.md|\.markdown)$/i);
            }
        });
        var emit = plugin.getEmitter();

        var BGCOLOR = {
            "flat-light": "rgb(250,250,250)",
            "light": "rgba(255, 255, 255, 0.88)",
            "light-gray": "rgba(255, 255, 255, 0.88)",
            "dark": "rgba(255, 255, 255, 0.88)",
            "dark-gray": "rgba(255, 255, 255, 0.88)"
        };

        var counter = 0;
        var HTMLURL, previewOrigin;

        /***** Methods *****/

        function getPreviewUrl(fn) {
            if (options.local && document.baseURI.substr(0, 5) == "file:")
                return setTimeout(getPreviewUrl.bind(null, fn), 100);
            else if (HTMLURL)
                return fn(HTMLURL);

            HTMLURL = (options.staticPrefix
                ? (options.local ? dirname(document.baseURI) + "/static" : options.staticPrefix)
                    + options.htmlPath
                : "/static/plugins/c9.ide.preview/previewers/markdown.html")
                    + "?host=" + (options.local ? "local" : location.origin);

            if (HTMLURL.charAt(0) == "/")
                HTMLURL = location.protocol + "//" + location.host + HTMLURL;

            previewOrigin = HTMLURL.match(/^(?:[^\/]|\/\/)*/)[0];

            fn(HTMLURL);
        }

        // function cleanIframeSrc(src) {
        //     return src
        //         .replace(/\?host=.*?(?:\&|$)/, "")
        //         .replace(/[\?\&]$/, "");
        // }

        /***** Lifecycle *****/

        plugin.on("load", function(){

        });
        plugin.on("documentLoad", function(e) {
            var doc = e.doc;
            var session = doc.getSession();
            var tab = doc.tab;
            var editor = e.editor;

            if (session.iframe) {
                session.editor = editor;
                editor.container.appendChild(session.iframe);
                return;
            }

            var iframe = document.createElement("iframe");

            iframe.setAttribute("nwfaketop", true);
            iframe.setAttribute("nwdisable", true);

            iframe.style.width = "100%";
            iframe.style.height = "100%";
            iframe.style.border = 0;

            function setTheme(e) {
                iframe.style.backgroundColor = BGCOLOR[e.theme];
            }
            layout.on("themeChange", setTheme, doc);
            setTheme({ theme: settings.get("user/general/@skin") });

            if (options.local) {
                iframe.addEventListener("load", function(){
                    // @todo to do this correctly stack needs to allow switching previewer
                    // plugin.activeSession.add(iframe.contentWindow.location.href);

                    iframe.contentWindow.opener = window;
                    if (iframe.contentWindow.start)
                        iframe.contentWindow.start(window);
                });
            }

            var onMessage = function(e) {
                if (c9.hosted && e.origin !== previewOrigin)
                    return;

                if (e.data.id != session.id)
                    return;

                if (e.data.message == "exec") {
                    commands.exec(e.data.command);
                }
                else if (e.data.message == "focus") {
                    tabManager.focusTab(tab);
                }
                else if (e.data.message == "stream.document") {
                    session.source = e.source;

                    if (session.previewTab) {
                        var doc = session.previewTab.document;

                        session.source.postMessage({
                            type: "document",
                            content: doc.value
                        }, "*");

                        if (!doc.hasValue())
                            doc.once("setValue", function(){
                                emit("update", { previewDocument: doc });
                            });
                    }
                    else {
                        fs.readFile(session.path, function(err, data) {
                            if (err)
                                return showError(err.message);

                            session.source.postMessage({
                                type: "document",
                                content: data
                            }, "*");
                        });
                    }

                    session.source.postMessage({
                        type: "keys",
                        keys: commands.getExceptionBindings()
                    }, "*");

                    tab.classList.remove("loading");
                }
            };
            window.addEventListener("message", onMessage, false);

            // Set iframe
            session.iframe = iframe;
            session.id = "markdown" + counter++;

            session.destroy = function(){
                delete session.editor;
                delete session.iframe;

                window.removeEventListener("message", onMessage, false);
            }

            // Load the markup renderer
            getPreviewUrl(function(url) {
                iframe.src = url + "&id=" + session.id;
            });

            session.editor = editor;
            editor.container.appendChild(session.iframe);
        });
        plugin.on("documentUnload", function(e) {
            var doc = e.doc;
            var session = doc.getSession();
            var iframe = session.iframe;

            iframe.parentNode.removeChild(iframe);

            doc.tab.classList.remove("loading");
        });
        plugin.on("documentActivate", function(e) {
            var session = e.doc.getSession();

            session.iframe.style.display = "block";
            session.editor.setLocation(session.path);
            session.editor.setButtonStyle("Markdown", "page_white.png");
        });
        plugin.on("documentDeactivate", function(e) {
            var session = e.doc.getSession();
            session.iframe.style.display = "none";
        });
        plugin.on("navigate", function(e) {
            var tab = plugin.activeDocument.tab;
            var iframe = plugin.activeSession.iframe;
            var editor = plugin.activeSession.editor;

            tab.classList.add("loading");

            tab.title =
            tab.tooltip = "[M] " + e.url;
            editor.setLocation(e.url);

            iframe.src = iframe.src;
        });
        plugin.on("update", function(e) {
            var session = plugin.activeSession;
            if (!session.source) return; // Renderer is not loaded yet

            session.source.postMessage({
                type: "document",
                content: e.previewDocument.value
            }, "*");
        });
        plugin.on("reload", function(){
            var iframe = plugin.activeSession.iframe;
            var tab = plugin.activeDocument.tab;
            tab.classList.add("loading");
            iframe.src = iframe.src;
        });
        plugin.on("popout", function(){
            var src = plugin.activeSession.iframe.src;
            window.open(src);
        });
        plugin.on("enable", function(){

        });
        plugin.on("disable", function(){

        });
        plugin.on("unload", function(){
        });

        /***** Register and define API *****/

        /**
         * Previewer for markdown content.
         **/
        plugin.freezePublicAPI({
        });

        register(null, {
            "preview.markdown": plugin
        });
    }
});<commit_msg>Doc based fixes<commit_after>define(function(require, exports, module) {
    main.consumes = [
        "c9", "Previewer", "fs", "dialog.error", "commands", "tabManager",
        "layout", "settings"
    ];
    main.provides = ["preview.markdown"];
    return main;

    // @todo possible improvements: http://benweet.github.io/stackedit/#

    function main(options, imports, register) {
        var Previewer = imports.Previewer;
        var c9 = imports.c9;
        var fs = imports.fs;
        var commands = imports.commands;
        var layout = imports.layout;
        var settings = imports.settings;
        var tabManager = imports.tabManager;
        var showError = imports["dialog.error"].show;
        var dirname = require("path").dirname;

        /***** Initialization *****/

        var plugin = new Previewer("Ajax.org", main.consumes, {
            caption: "Markdown",
            index: 200,
            selector: function(path) {
                return path && path.match(/(?:\.md|\.markdown)$/i);
            }
        });
        var emit = plugin.getEmitter();

        var BGCOLOR = {
            "flat-light": "rgb(250,250,250)",
            "light": "rgba(255, 255, 255, 0.88)",
            "light-gray": "rgba(255, 255, 255, 0.88)",
            "dark": "rgba(255, 255, 255, 0.88)",
            "dark-gray": "rgba(255, 255, 255, 0.88)"
        };

        var counter = 0;
        var HTMLURL, previewOrigin;

        /***** Methods *****/

        function getPreviewUrl(fn) {
            if (options.local && document.baseURI.substr(0, 5) == "file:")
                return setTimeout(getPreviewUrl.bind(null, fn), 100);
            else if (HTMLURL)
                return fn(HTMLURL);

            HTMLURL = (options.staticPrefix
                ? (options.local ? dirname(document.baseURI) + "/static" : options.staticPrefix)
                    + options.htmlPath
                : "/static/plugins/c9.ide.preview/previewers/markdown.html")
                    + "?host=" + (options.local ? "local" : location.origin);

            if (HTMLURL.charAt(0) == "/")
                HTMLURL = location.protocol + "//" + location.host + HTMLURL;

            previewOrigin = HTMLURL.match(/^(?:[^\/]|\/\/)*/)[0];

            fn(HTMLURL);
        }

        // function cleanIframeSrc(src) {
        //     return src
        //         .replace(/\?host=.*?(?:\&|$)/, "")
        //         .replace(/[\?\&]$/, "");
        // }

        /***** Lifecycle *****/

        plugin.on("load", function(){

        });
        plugin.on("sessionStart", function(e) {
            var doc = e.doc;
            var session = e.session;
            var tab = e.tab;
            var editor = e.editor;

            if (session.iframe) {
                session.editor = editor;
                editor.container.appendChild(session.iframe);
                return;
            }

            var iframe = document.createElement("iframe");

            iframe.setAttribute("nwfaketop", true);
            iframe.setAttribute("nwdisable", true);

            iframe.style.width = "100%";
            iframe.style.height = "100%";
            iframe.style.border = 0;

            function setTheme(e) {
                iframe.style.backgroundColor = BGCOLOR[e.theme];
            }
            layout.on("themeChange", setTheme, doc);
            setTheme({ theme: settings.get("user/general/@skin") });

            if (options.local) {
                iframe.addEventListener("load", function(){
                    // @todo to do this correctly stack needs to allow switching previewer
                    // plugin.activeSession.add(iframe.contentWindow.location.href);

                    iframe.contentWindow.opener = window;
                    if (iframe.contentWindow.start)
                        iframe.contentWindow.start(window);
                });
            }

            var onMessage = function(e) {
                if (c9.hosted && e.origin !== previewOrigin)
                    return;

                if (e.data.id != session.id)
                    return;

                if (e.data.message == "exec") {
                    commands.exec(e.data.command);
                }
                else if (e.data.message == "focus") {
                    tabManager.focusTab(tab);
                }
                else if (e.data.message == "stream.document") {
                    session.source = e.source;

                    if (session.previewTab) {
                        var doc = session.previewTab.document;

                        session.source.postMessage({
                            type: "document",
                            content: doc.value
                        }, "*");

                        if (!doc.hasValue())
                            doc.once("setValue", function(){
                                emit("update", { previewDocument: doc });
                            });
                    }
                    else {
                        fs.readFile(session.path, function(err, data) {
                            if (err)
                                return showError(err.message);

                            session.source.postMessage({
                                type: "document",
                                content: data
                            }, "*");
                        });
                    }

                    session.source.postMessage({
                        type: "keys",
                        keys: commands.getExceptionBindings()
                    }, "*");

                    tab.classList.remove("loading");
                }
            };
            window.addEventListener("message", onMessage, false);

            // Set iframe
            session.iframe = iframe;
            session.id = "markdown" + counter++;

            session.destroy = function(){
                delete session.editor;
                delete session.iframe;

                window.removeEventListener("message", onMessage, false);
            }

            // Load the markup renderer
            getPreviewUrl(function(url) {
                iframe.src = url + "&id=" + session.id;
            });

            session.editor = editor;
            editor.container.appendChild(session.iframe);
        });
        plugin.on("sessionEnd", function(e) {
            var tab = e.tab;
            var session = e.session;
            var iframe = session.iframe;

            iframe.parentNode.removeChild(iframe);

            tab.classList.remove("loading");
        });
        plugin.on("sessionActivate", function(e) {
            var session = e.session;

            session.iframe.style.display = "block";
            session.editor.setLocation(session.path);
            session.editor.setButtonStyle("Markdown", "page_white.png");
        });
        plugin.on("sessionDeactivate", function(e) {
            var session = e.session;
            session.iframe.style.display = "none";
        });
        plugin.on("navigate", function(e) {
            var tab = plugin.activeDocument.tab;
            var iframe = plugin.activeSession.iframe;
            var editor = plugin.activeSession.editor;

            tab.classList.add("loading");

            tab.title =
            tab.tooltip = "[M] " + e.url;
            editor.setLocation(e.url);

            iframe.src = iframe.src;
        });
        plugin.on("update", function(e) {
            var session = plugin.activeSession;
            if (!session.source) return; // Renderer is not loaded yet

            session.source.postMessage({
                type: "document",
                content: e.previewDocument.value
            }, "*");
        });
        plugin.on("reload", function(){
            var iframe = plugin.activeSession.iframe;
            var tab = plugin.activeDocument.tab;
            tab.classList.add("loading");
            iframe.src = iframe.src;
        });
        plugin.on("popout", function(){
            var src = plugin.activeSession.iframe.src;
            window.open(src);
        });
        plugin.on("enable", function(){

        });
        plugin.on("disable", function(){

        });
        plugin.on("unload", function(){
        });

        /***** Register and define API *****/

        /**
         * Previewer for markdown content.
         **/
        plugin.freezePublicAPI({
        });

        register(null, {
            "preview.markdown": plugin
        });
    }
});<|endoftext|>


<commit_before>const app     = require('express')();
const admin   = require('express')();
const http    = require('http');
const server  = http.createServer(app);
const io      = require('socket.io')(server);
const PORT    = 8080;

app.get('/', function(request, response) {
  console.log(app.mountpath);
  response.send('GET homepage request');
});

admin.get('/', function (req, res) {
  console.log(admin.mountpath);
  res.send('Admin Homepage');
})

app.use('/admin', admin); // mount the sub app

io.on('connection', function(){ /* … */ });

server.listen(PORT, function(){
    console.log("Server listening on: http://localhost:%s", PORT);
});

<commit_msg>Remove Build Folder<commit_after><|endoftext|>