<commit_before>/*!
 * jquery.event.drag - v 2.2
 * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
 * Open Source MIT License - http://threedubmedia.com/code/license
 */
// Created: 2008-06-04
// Updated: 2012-05-21
// REQUIRES: jquery 1.7.x

module.exports = function( $ ){
  // add the jquery instance method
  $.fn.drag = function( str, arg, opts ){
  	// figure out the event type
  	var type = typeof str == "string" ? str : "",
  	// figure out the event handler...
  	fn = $.isFunction( str ) ? str : $.isFunction( arg ) ? arg : null;
  	// fix the event type
  	if ( type.indexOf("drag") !== 0 )
  		type = "drag"+ type;
  	// were options passed
  	opts = ( str == fn ? arg : opts ) || {};
  	// trigger or bind event handler
  	return fn ? this.bind( type, opts, fn ) : this.trigger( type );
  };

  // local refs (increase compression)
  var $event = $.event,
  $special = $event.special,
  // configure the drag special event
  drag = $special.drag = {

  	// these are the default settings
  	defaults: {
  		which: 1, // mouse button pressed to start drag sequence
  		distance: 0, // distance dragged before dragstart
  		not: ':input', // selector to suppress dragging on target elements
  		handle: null, // selector to match handle target elements
  		relative: false, // true to use "position", false to use "offset"
  		drop: true, // false to suppress drop events, true or selector to allow
  		click: false // false to suppress click events after dragend (no proxy)
  	},

  	// the key name for stored drag data
  	datakey: "dragdata",

  	// prevent bubbling for better performance
  	noBubble: true,

  	// count bound related events
  	add: function( obj ){
  		// read the interaction data
  		var data = $.data( this, drag.datakey ),
  		// read any passed options
  		opts = obj.data || {};
  		// count another realted event
  		data.related += 1;
  		// extend data options bound with this event
  		// don't iterate "opts" in case it is a node
  		$.each( drag.defaults, function( key, def ){
  			if ( opts[ key ] !== undefined )
  				data[ key ] = opts[ key ];
  		});
  	},

  	// forget unbound related events
  	remove: function(){
  		$.data( this, drag.datakey ).related -= 1;
  	},

  	// configure interaction, capture settings
  	setup: function(){
  		// check for related events
  		if ( $.data( this, drag.datakey ) )
  			return;
  		// initialize the drag data with copied defaults
  		var data = $.extend({ related:0 }, drag.defaults );
  		// store the interaction data
  		$.data( this, drag.datakey, data );
  		// bind the mousedown event, which starts drag interactions
  		$event.add( this, "touchstart mousedown", drag.init, data );
  		// prevent image dragging in IE...
  		if ( this.attachEvent )
  			this.attachEvent("ondragstart", drag.dontstart );
  	},

  	// destroy configured interaction
  	teardown: function(){
  		var data = $.data( this, drag.datakey ) || {};
  		// check for related events
  		if ( data.related )
  			return;
  		// remove the stored data
  		$.removeData( this, drag.datakey );
  		// remove the mousedown event
  		$event.remove( this, "touchstart mousedown", drag.init );
  		// enable text selection
  		drag.textselect( true );
  		// un-prevent image dragging in IE...
  		if ( this.detachEvent )
  			this.detachEvent("ondragstart", drag.dontstart );
  	},

  	// initialize the interaction
  	init: function( event ){
  		// sorry, only one touch at a time
  		if ( drag.touched )
  			return;
  		// the drag/drop interaction data
  		var dd = event.data, results;
  		// check the which directive
  		if ( event.which != 0 && dd.which > 0 && event.which != dd.which )
  			return;
  		// check for suppressed selector
  		if ( $( event.target ).is( dd.not ) )
  			return;
  		// check for handle selector
  		if ( dd.handle && !$( event.target ).closest( dd.handle, event.currentTarget ).length )
  			return;

  		drag.touched = event.type == 'touchstart' ? this : null;
  		dd.propagates = 1;
  		dd.mousedown = this;
  		dd.interactions = [ drag.interaction( this, dd ) ];
  		dd.target = event.target;
  		dd.pageX = event.pageX;
  		dd.pageY = event.pageY;
  		dd.dragging = null;
  		// handle draginit event...
  		results = drag.hijack( event, "draginit", dd );
  		// early cancel
  		if ( !dd.propagates )
  			return;
  		// flatten the result set
  		results = drag.flatten( results );
  		// insert new interaction elements
  		if ( results && results.length ){
  			dd.interactions = [];
  			$.each( results, function(){
  				dd.interactions.push( drag.interaction( this, dd ) );
  			});
  		}
  		// remember how many interactions are propagating
  		dd.propagates = dd.interactions.length;
  		// locate and init the drop targets
  		if ( dd.drop !== false && $special.drop )
  			$special.drop.handler( event, dd );
  		// disable text selection
  		drag.textselect( false );
  		// bind additional events...
  		if ( drag.touched )
  			$event.add( drag.touched, "touchmove touchend", drag.handler, dd );
  		else
  			$event.add( document, "mousemove mouseup", drag.handler, dd );
  		// helps prevent text selection or scrolling
  		if ( !drag.touched || dd.live )
  			return false;
  	},

  	// returns an interaction object
  	interaction: function( elem, dd ){
  		var offset = $( elem )[ dd.relative ? "position" : "offset" ]() || { top:0, left:0 };
  		return {
  			drag: elem,
  			callback: new drag.callback(),
  			droppable: [],
  			offset: offset
  		};
  	},

  	// handle drag-releatd DOM events
  	handler: function( event ){
  		// read the data before hijacking anything
  		var dd = event.data;
  		// handle various events
  		switch ( event.type ){
  			// mousemove, check distance, start dragging
  			case !dd.dragging && 'touchmove':
  				event.preventDefault();
  			case !dd.dragging && 'mousemove':
  				//  drag tolerance, x� + y� = distance�
  				if ( Math.pow(  event.pageX-dd.pageX, 2 ) + Math.pow(  event.pageY-dd.pageY, 2 ) < Math.pow( dd.distance, 2 ) )
  					break; // distance tolerance not reached
  				event.target = dd.target; // force target from "mousedown" event (fix distance issue)
  				drag.hijack( event, "dragstart", dd ); // trigger "dragstart"
  				if ( dd.propagates ) // "dragstart" not rejected
  					dd.dragging = true; // activate interaction
  			// mousemove, dragging
  			case 'touchmove':
  				event.preventDefault();
  			case 'mousemove':
  				if ( dd.dragging ){
  					// trigger "drag"
  					drag.hijack( event, "drag", dd );
  					if ( dd.propagates ){
  						// manage drop events
  						if ( dd.drop !== false && $special.drop )
  							$special.drop.handler( event, dd ); // "dropstart", "dropend"
  						break; // "drag" not rejected, stop
  					}
  					event.type = "mouseup"; // helps "drop" handler behave
  				}
  			// mouseup, stop dragging
  			case 'touchend':
  			case 'mouseup':
  			default:
  				if ( drag.touched )
  					$event.remove( drag.touched, "touchmove touchend", drag.handler ); // remove touch events
  				else
  					$event.remove( document, "mousemove mouseup", drag.handler ); // remove page events
  				if ( dd.dragging ){
  					if ( dd.drop !== false && $special.drop )
  						$special.drop.handler( event, dd ); // "drop"
  					drag.hijack( event, "dragend", dd ); // trigger "dragend"
  				}
  				drag.textselect( true ); // enable text selection
  				// if suppressing click events...
  				if ( dd.click === false && dd.dragging )
  					$.data( dd.mousedown, "suppress.click", new Date().getTime() + 5 );
  				dd.dragging = drag.touched = false; // deactivate element
  				break;
  		}
  	},

  	// re-use event object for custom events
  	hijack: function( event, type, dd, x, elem ){
  		// not configured
  		if ( !dd )
  			return;
  		// remember the original event and type
  		var orig = { event:event.originalEvent, type:event.type },
  		// is the event drag related or drog related?
  		mode = type.indexOf("drop") ? "drag" : "drop",
  		// iteration vars
  		result, i = x || 0, ia, $elems, callback,
  		len = !isNaN( x ) ? x : dd.interactions.length;
  		// modify the event type
  		event.type = type;
  		// remove the original event
  		event.originalEvent = null;
  		// initialize the results
  		dd.results = [];
  		// handle each interacted element
  		do if ( ia = dd.interactions[ i ] ){
  			// validate the interaction
  			if ( type !== "dragend" && ia.cancelled )
  				continue;
  			// set the dragdrop properties on the event object
  			callback = drag.properties( event, dd, ia );
  			// prepare for more results
  			ia.results = [];
  			// handle each element
  			$( elem || ia[ mode ] || dd.droppable ).each(function( p, subject ){
  				// identify drag or drop targets individually
  				callback.target = subject;
  				// force propagtion of the custom event
  				event.isPropagationStopped = function(){ return false; };
  				// handle the event
  				result = subject ? $event.dispatch.call( subject, event, callback ) : null;
  				// stop the drag interaction for this element
  				if ( result === false ){
  					if ( mode == "drag" ){
  						ia.cancelled = true;
  						dd.propagates -= 1;
  					}
  					if ( type == "drop" ){
  						ia[ mode ][p] = null;
  					}
  				}
  				// assign any dropinit elements
  				else if ( type == "dropinit" )
  					ia.droppable.push( drag.element( result ) || subject );
  				// accept a returned proxy element
  				if ( type == "dragstart" )
  					ia.proxy = $( drag.element( result ) || ia.drag )[0];
  				// remember this result
  				ia.results.push( result );
  				// forget the event result, for recycling
  				delete event.result;
  				// break on cancelled handler
  				if ( type !== "dropinit" )
  					return result;
  			});
  			// flatten the results
  			dd.results[ i ] = drag.flatten( ia.results );
  			// accept a set of valid drop targets
  			if ( type == "dropinit" )
  				ia.droppable = drag.flatten( ia.droppable );
  			// locate drop targets
  			if ( type == "dragstart" && !ia.cancelled )
  				callback.update();
  		}
  		while ( ++i < len )
  		// restore the original event & type
  		event.type = orig.type;
  		event.originalEvent = orig.event;
  		// return all handler results
  		return drag.flatten( dd.results );
  	},

  	// extend the callback object with drag/drop properties...
  	properties: function( event, dd, ia ){
  		var obj = ia.callback;
  		// elements
  		obj.drag = ia.drag;
  		obj.proxy = ia.proxy || ia.drag;
  		// starting mouse position
  		obj.startX = dd.pageX;
  		obj.startY = dd.pageY;
  		// current distance dragged
  		obj.deltaX = event.pageX - dd.pageX;
  		obj.deltaY = event.pageY - dd.pageY;
  		// original element position
  		obj.originalX = ia.offset.left;
  		obj.originalY = ia.offset.top;
  		// adjusted element position
  		obj.offsetX = obj.originalX + obj.deltaX;
  		obj.offsetY = obj.originalY + obj.deltaY;
  		// assign the drop targets information
  		obj.drop = drag.flatten( ( ia.drop || [] ).slice() );
  		obj.available = drag.flatten( ( ia.droppable || [] ).slice() );
  		return obj;
  	},

  	// determine is the argument is an element or jquery instance
  	element: function( arg ){
  		if ( arg && ( arg.jquery || arg.nodeType == 1 ) )
  			return arg;
  	},

  	// flatten nested jquery objects and arrays into a single dimension array
  	flatten: function( arr ){
  		return $.map( arr, function( member ){
  			return member && member.jquery ? $.makeArray( member ) :
  				member && member.length ? drag.flatten( member ) : member;
  		});
  	},

  	// toggles text selection attributes ON (true) or OFF (false)
  	textselect: function( bool ){
  		$( document )[ bool ? "unbind" : "bind" ]("selectstart", drag.dontstart )
  			.css("MozUserSelect", bool ? "" : "none" );
  		// .attr("unselectable", bool ? "off" : "on" )
  		document.unselectable = bool ? "off" : "on";
  	},

  	// suppress "selectstart" and "ondragstart" events
  	dontstart: function(){
  		return false;
  	},

  	// a callback instance contructor
  	callback: function(){}

  };

  // callback methods
  drag.callback.prototype = {
  	update: function(){
  		if ( $special.drop && this.available.length )
  			$.each( this.available, function( i ){
  				$special.drop.locate( this, i );
  			});
  	}
  };

  // patch $.event.$dispatch to allow suppressing clicks
  var $dispatch = $event.dispatch;
  $event.dispatch = function( event ){
  	if ( $.data( this, "suppress."+ event.type ) - new Date().getTime() > 0 ){
  		$.removeData( this, "suppress."+ event.type );
  		return;
  	}
  	return $dispatch.apply( this, arguments );
  };

  // event fix hooks for touch events...
  var touchHooks =
  $event.fixHooks.touchstart =
  $event.fixHooks.touchmove =
  $event.fixHooks.touchend =
  $event.fixHooks.touchcancel = {
  	props: "clientX clientY pageX pageY screenX screenY".split( " " ),
  	filter: function( event, orig ) {
  		if ( orig ){
  			var touched = ( orig.touches && orig.touches[0] )
  				|| ( orig.changedTouches && orig.changedTouches[0] )
  				|| null;
  			// iOS webkit: touchstart, touchmove, touchend
  			if ( touched )
  				$.each( touchHooks.props, function( i, prop ){
  					event[ prop ] = touched[ prop ];
  				});
  		}
  		return event;
  	}
  };

  // share the same special event configuration with related events...
  $special.draginit = $special.dragstart = $special.dragend = drag;
};
<commit_msg>slickgrid#7<commit_after>/*!
 * jquery.event.drag - v 2.2
 * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
 * Open Source MIT License - http://threedubmedia.com/code/license
 */
// Created: 2008-06-04
// Updated: 2012-05-21
// REQUIRES: jquery 1.7.x

;(function( $ ){

// add the jquery instance method
$.fn.drag = function( str, arg, opts ){
  // figure out the event type
  var type = typeof str == "string" ? str : "",
  // figure out the event handler...
  fn = $.isFunction( str ) ? str : $.isFunction( arg ) ? arg : null;
  // fix the event type
  if ( type.indexOf("drag") !== 0 )
    type = "drag"+ type;
  // were options passed
  opts = ( str == fn ? arg : opts ) || {};
  // trigger or bind event handler
  return fn ? this.bind( type, opts, fn ) : this.trigger( type );
};

// local refs (increase compression)
var $event = $.event,
$special = $event.special,
// configure the drag special event
drag = $special.drag = {

  // these are the default settings
  defaults: {
    which: 1, // mouse button pressed to start drag sequence
    distance: 0, // distance dragged before dragstart
    not: ':input', // selector to suppress dragging on target elements
    handle: null, // selector to match handle target elements
    relative: false, // true to use "position", false to use "offset"
    drop: true, // false to suppress drop events, true or selector to allow
    click: false // false to suppress click events after dragend (no proxy)
  },

  // the key name for stored drag data
  datakey: "dragdata",

  // prevent bubbling for better performance
  noBubble: true,

  // count bound related events
  add: function( obj ){
    // read the interaction data
    var data = $.data( this, drag.datakey ),
    // read any passed options
    opts = obj.data || {};
    // count another realted event
    data.related += 1;
    // extend data options bound with this event
    // don't iterate "opts" in case it is a node
    $.each( drag.defaults, function( key, def ){
      if ( opts[ key ] !== undefined )
        data[ key ] = opts[ key ];
    });
  },

  // forget unbound related events
  remove: function(){
    $.data( this, drag.datakey ).related -= 1;
  },

  // configure interaction, capture settings
  setup: function(){
    // check for related events
    if ( $.data( this, drag.datakey ) )
      return;
    // initialize the drag data with copied defaults
    var data = $.extend({ related:0 }, drag.defaults );
    // store the interaction data
    $.data( this, drag.datakey, data );
    // bind the mousedown event, which starts drag interactions
    $event.add( this, "touchstart mousedown", drag.init, data );
    // prevent image dragging in IE...
    if ( this.attachEvent )
      this.attachEvent("ondragstart", drag.dontstart );
  },

  // destroy configured interaction
  teardown: function(){
    var data = $.data( this, drag.datakey ) || {};
    // check for related events
    if ( data.related )
      return;
    // remove the stored data
    $.removeData( this, drag.datakey );
    // remove the mousedown event
    $event.remove( this, "touchstart mousedown", drag.init );
    // enable text selection
    drag.textselect( true );
    // un-prevent image dragging in IE...
    if ( this.detachEvent )
      this.detachEvent("ondragstart", drag.dontstart );
  },

  // initialize the interaction
  init: function( event ){
    // sorry, only one touch at a time
    if ( drag.touched )
      return;
    // the drag/drop interaction data
    var dd = event.data, results;
    // check the which directive
    if ( event.which != 0 && dd.which > 0 && event.which != dd.which )
      return;
    // check for suppressed selector
    if ( $( event.target ).is( dd.not ) )
      return;
    // check for handle selector
    if ( dd.handle && !$( event.target ).closest( dd.handle, event.currentTarget ).length )
      return;

    drag.touched = event.type == 'touchstart' ? this : null;
    dd.propagates = 1;
    dd.mousedown = this;
    dd.interactions = [ drag.interaction( this, dd ) ];
    dd.target = event.target;
    dd.pageX = event.pageX;
    dd.pageY = event.pageY;
    dd.dragging = null;
    // handle draginit event...
    results = drag.hijack( event, "draginit", dd );
    // early cancel
    if ( !dd.propagates )
      return;
    // flatten the result set
    results = drag.flatten( results );
    // insert new interaction elements
    if ( results && results.length ){
      dd.interactions = [];
      $.each( results, function(){
        dd.interactions.push( drag.interaction( this, dd ) );
      });
    }
    // remember how many interactions are propagating
    dd.propagates = dd.interactions.length;
    // locate and init the drop targets
    if ( dd.drop !== false && $special.drop )
      $special.drop.handler( event, dd );
    // disable text selection
    drag.textselect( false );
    // bind additional events...
    if ( drag.touched )
      $event.add( drag.touched, "touchmove touchend", drag.handler, dd );
    else
      $event.add( document, "mousemove mouseup", drag.handler, dd );
    // helps prevent text selection or scrolling
    if ( !drag.touched || dd.live )
      return false;
  },

  // returns an interaction object
  interaction: function( elem, dd ){
    var offset = $( elem )[ dd.relative ? "position" : "offset" ]() || { top:0, left:0 };
    return {
      drag: elem,
      callback: new drag.callback(),
      droppable: [],
      offset: offset
    };
  },

  // handle drag-releatd DOM events
  handler: function( event ){
    // read the data before hijacking anything
    var dd = event.data;
    // handle various events
    switch ( event.type ){
      // mousemove, check distance, start dragging
      case !dd.dragging && 'touchmove':
        event.preventDefault();
      case !dd.dragging && 'mousemove':
        //  drag tolerance, x≤ + y≤ = distance≤
        if ( Math.pow(  event.pageX-dd.pageX, 2 ) + Math.pow(  event.pageY-dd.pageY, 2 ) < Math.pow( dd.distance, 2 ) )
          break; // distance tolerance not reached
        event.target = dd.target; // force target from "mousedown" event (fix distance issue)
        drag.hijack( event, "dragstart", dd ); // trigger "dragstart"
        if ( dd.propagates ) // "dragstart" not rejected
          dd.dragging = true; // activate interaction
      // mousemove, dragging
      case 'touchmove':
        event.preventDefault();
      case 'mousemove':
        if ( dd.dragging ){
          // trigger "drag"
          drag.hijack( event, "drag", dd );
          if ( dd.propagates ){
            // manage drop events
            if ( dd.drop !== false && $special.drop )
              $special.drop.handler( event, dd ); // "dropstart", "dropend"
            break; // "drag" not rejected, stop
          }
          event.type = "mouseup"; // helps "drop" handler behave
        }
      // mouseup, stop dragging
      case 'touchend':
      case 'mouseup':
      default:
        if ( drag.touched )
          $event.remove( drag.touched, "touchmove touchend", drag.handler ); // remove touch events
        else
          $event.remove( document, "mousemove mouseup", drag.handler ); // remove page events
        if ( dd.dragging ){
          if ( dd.drop !== false && $special.drop )
            $special.drop.handler( event, dd ); // "drop"
          drag.hijack( event, "dragend", dd ); // trigger "dragend"
        }
        drag.textselect( true ); // enable text selection
        // if suppressing click events...
        if ( dd.click === false && dd.dragging )
          $.data( dd.mousedown, "suppress.click", new Date().getTime() + 5 );
        dd.dragging = drag.touched = false; // deactivate element
        break;
    }
  },

  // re-use event object for custom events
  hijack: function( event, type, dd, x, elem ){
    // not configured
    if ( !dd )
      return;
    // remember the original event and type
    var orig = { event:event.originalEvent, type:event.type },
    // is the event drag related or drog related?
    mode = type.indexOf("drop") ? "drag" : "drop",
    // iteration vars
    result, i = x || 0, ia, $elems, callback,
    len = !isNaN( x ) ? x : dd.interactions.length;
    // modify the event type
    event.type = type;
    // remove the original event
    event.originalEvent = null;
    // initialize the results
    dd.results = [];
    // handle each interacted element
    do if ( ia = dd.interactions[ i ] ){
      // validate the interaction
      if ( type !== "dragend" && ia.cancelled )
        continue;
      // set the dragdrop properties on the event object
      callback = drag.properties( event, dd, ia );
      // prepare for more results
      ia.results = [];
      // handle each element
      $( elem || ia[ mode ] || dd.droppable ).each(function( p, subject ){
        // identify drag or drop targets individually
        callback.target = subject;
        // force propagtion of the custom event
        event.isPropagationStopped = function(){ return false; };
        // handle the event
        result = subject ? $event.dispatch.call( subject, event, callback ) : null;
        // stop the drag interaction for this element
        if ( result === false ){
          if ( mode == "drag" ){
            ia.cancelled = true;
            dd.propagates -= 1;
          }
          if ( type == "drop" ){
            ia[ mode ][p] = null;
          }
        }
        // assign any dropinit elements
        else if ( type == "dropinit" )
          ia.droppable.push( drag.element( result ) || subject );
        // accept a returned proxy element
        if ( type == "dragstart" )
          ia.proxy = $( drag.element( result ) || ia.drag )[0];
        // remember this result
        ia.results.push( result );
        // forget the event result, for recycling
        delete event.result;
        // break on cancelled handler
        if ( type !== "dropinit" )
          return result;
      });
      // flatten the results
      dd.results[ i ] = drag.flatten( ia.results );
      // accept a set of valid drop targets
      if ( type == "dropinit" )
        ia.droppable = drag.flatten( ia.droppable );
      // locate drop targets
      if ( type == "dragstart" && !ia.cancelled )
        callback.update();
    }
    while ( ++i < len )
    // restore the original event & type
    event.type = orig.type;
    event.originalEvent = orig.event;
    // return all handler results
    return drag.flatten( dd.results );
  },

  // extend the callback object with drag/drop properties...
  properties: function( event, dd, ia ){
    var obj = ia.callback;
    // elements
    obj.drag = ia.drag;
    obj.proxy = ia.proxy || ia.drag;
    // starting mouse position
    obj.startX = dd.pageX;
    obj.startY = dd.pageY;
    // current distance dragged
    obj.deltaX = event.pageX - dd.pageX;
    obj.deltaY = event.pageY - dd.pageY;
    // original element position
    obj.originalX = ia.offset.left;
    obj.originalY = ia.offset.top;
    // adjusted element position
    obj.offsetX = obj.originalX + obj.deltaX;
    obj.offsetY = obj.originalY + obj.deltaY;
    // assign the drop targets information
    obj.drop = drag.flatten( ( ia.drop || [] ).slice() );
    obj.available = drag.flatten( ( ia.droppable || [] ).slice() );
    return obj;
  },

  // determine is the argument is an element or jquery instance
  element: function( arg ){
    if ( arg && ( arg.jquery || arg.nodeType == 1 ) )
      return arg;
  },

  // flatten nested jquery objects and arrays into a single dimension array
  flatten: function( arr ){
    return $.map( arr, function( member ){
      return member && member.jquery ? $.makeArray( member ) :
        member && member.length ? drag.flatten( member ) : member;
    });
  },

  // toggles text selection attributes ON (true) or OFF (false)
  textselect: function( bool ){
    $( document )[ bool ? "unbind" : "bind" ]("selectstart", drag.dontstart )
      .css("MozUserSelect", bool ? "" : "none" );
    // .attr("unselectable", bool ? "off" : "on" )
    document.unselectable = bool ? "off" : "on";
  },

  // suppress "selectstart" and "ondragstart" events
  dontstart: function(){
    return false;
  },

  // a callback instance contructor
  callback: function(){}

};

// callback methods
drag.callback.prototype = {
  update: function(){
    if ( $special.drop && this.available.length )
      $.each( this.available, function( i ){
        $special.drop.locate( this, i );
      });
  }
};

// patch $.event.$dispatch to allow suppressing clicks
var $dispatch = $event.dispatch;
$event.dispatch = function( event ){
  if ( $.data( this, "suppress."+ event.type ) - new Date().getTime() > 0 ){
    $.removeData( this, "suppress."+ event.type );
    return;
  }
  return $dispatch.apply( this, arguments );
};

// event fix hooks for touch events...
var touchHooks =
$event.fixHooks.touchstart =
$event.fixHooks.touchmove =
$event.fixHooks.touchend =
$event.fixHooks.touchcancel = {
  props: "clientX clientY pageX pageY screenX screenY".split( " " ),
  filter: function( event, orig ) {
    if ( orig ){
      var touched = ( orig.touches && orig.touches[0] )
        || ( orig.changedTouches && orig.changedTouches[0] )
        || null;
      // iOS webkit: touchstart, touchmove, touchend
      if ( touched )
        $.each( touchHooks.props, function( i, prop ){
          event[ prop ] = touched[ prop ];
        });
    }
    return event;
  }
};

// share the same special event configuration with related events...
$special.draginit = $special.dragstart = $special.dragend = drag;

})( jQuery );<|endoftext|>


<commit_before>/***  HIMLE RIA SYSTEM
  **
  **  Copyright (C) 2008 HIMLE GROUP http://himle.sorsacode.com/
  **  Copyright (C) 2006-2007 Helmi Technologies Inc.
  **
  **  This program is free software; you can redistribute it and/or modify it under the terms
  **  of the GNU General Public License as published by the Free Software Foundation;
  **  either version 2 of the License, or (at your option) any later version.
  **  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  **  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  **  See the GNU General Public License for more details.
  **  You should have received a copy of the GNU General Public License along with this program;
  **  if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  ***/

/*** class: HImageView
  **
  ** HImageView is a control unit intended to display images on the screen
  ** through the HTML <IMG> tag. The HImageView class is a container to visualize
  ** images loaded via URL. It supports scaling via two class methods,
  ** scaleToFit and scaleToOriginal. If the image is unable to be loaded,
  ** a default blank image will be rendered.
  **
  ** vars: Instance variables
  **  type - '[HImageView]'
  **  value - URL pointing to the image that is currently shown.
  **
  ** Extends:
  **  <HControl>
  **
  ** See also:
  **  <HControl>
  ***/
HImageView = HControl.extend({

/** constructor: constructor
  *
  * Parameters:
  *   _rect - An <HRect> object that sets the position and dimensions of this control.
  *   _parentClass - The parent view that this control is to be inserted in.
  *   _options - (optional) All other parameters. See <HComponentDefaults>.
  **/
  constructor: function(_rect, _parentClass, _options) {

    if(this.isinherited) {
      this.base(_rect, _parentClass, _options);
    }
    else {
      this.isinherited = true;
      this.base(_rect, _parentClass, _options);
      this.isinherited = false;
    }

    if(!this.value) {
      // default to a blank image
      this.value = this.getThemeGfxPath() + "/blank.gif";
    }

    this.type = '[HImageView]';

    if(!this.isinherited) {
      this.draw();
    }
  },

  _makeElem: function(_parentId){
    this.elemId = ELEM.make(_parentId,'img');
    ELEM.setAttr(this.elemId,'src',this.value);
    ELEM.setAttr(this.elemId,'alt',this.label);
  },

  setValue: function(_value){
    this.base(_value);
    ELEM.setAttr(this.elemId,'src',_value);
  },

  setLabel: function(_label){
    this.base(_label);
    ELEM.setAttr(this.elemId,'alt',_label);
  },

/** method: scaleToFit
  *
  * Changes the size of the image element so that it fits in the rectangle of
  * the view.
  *
  * See also:
  *  <scaleToOriginal>
  **/
  scaleToFit: function() {
    ELEM.setStyle(this.elemId,'right','0px');
    ELEM.setStyle(this.elemId,'bottom','0px');
  },

/** method: scaleToOriginal
  *
  * Resizes the image element to its original dimesions. If the image is larger
  * than the rectangle of this view, clipping will occur.
  *
  * See also:
  *  <scaleToFit>
  **/
  scaleToOriginal: function() {
    ELEM.setStyle(this.elemId, 'right', 'auto');
    ELEM.setStyle(this.elemId, 'bottom', 'auto');
  }

});
<commit_msg>HImageView scaleToFit and scaleToOriginal now works properly<commit_after>/***  HIMLE RIA SYSTEM
  **
  **  Copyright (C) 2008 HIMLE GROUP http://himle.sorsacode.com/
  **  Copyright (C) 2006-2007 Helmi Technologies Inc.
  **
  **  This program is free software; you can redistribute it and/or modify it under the terms
  **  of the GNU General Public License as published by the Free Software Foundation;
  **  either version 2 of the License, or (at your option) any later version.
  **  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  **  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  **  See the GNU General Public License for more details.
  **  You should have received a copy of the GNU General Public License along with this program;
  **  if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  ***/

/*** class: HImageView
  **
  ** HImageView is a control unit intended to display images on the screen
  ** through the HTML <IMG> tag. The HImageView class is a container to visualize
  ** images loaded via URL. It supports scaling via two class methods,
  ** scaleToFit and scaleToOriginal. If the image is unable to be loaded,
  ** a default blank image will be rendered.
  **
  ** vars: Instance variables
  **  type - '[HImageView]'
  **  value - URL pointing to the image that is currently shown.
  **
  ** Extends:
  **  <HControl>
  **
  ** See also:
  **  <HControl>
  ***/
HImageView = HControl.extend({

/** constructor: constructor
  *
  * Parameters:
  *   _rect - An <HRect> object that sets the position and dimensions of this control.
  *   _parentClass - The parent view that this control is to be inserted in.
  *   _options - (optional) All other parameters. See <HComponentDefaults>.
  **/
  constructor: function(_rect, _parentClass, _options) {
    if(!_options) {
      _options={};
    }
    var _defaults = HClass.extend({
      scaleToFit: true
    });
    _options = new (_defaults.extend(_options))();
    if(this.isinherited) {
      this.base(_rect, _parentClass, _options);
    }
    else {
      this.isinherited = true;
      this.base(_rect, _parentClass, _options);
      this.isinherited = false;
    }
    if(!this.value) {
      // default to a blank image
      this.value = this.getThemeGfxPath() + "/blank.gif";
    }

    this.type = '[HImageView]';

    if(!this.isinherited) {
      this.draw();
    }
  },

  _makeScaleToFit: function(_parentId){
    this.elemId = ELEM.make(_parentId,'img');
    ELEM.setAttr(this.elemId,'src',this.value);
    ELEM.setAttr(this.elemId,'alt',this.label);
  },
  _makeScaleToOriginal: function(_parentId){
    this.elemId = ELEM.make(_parentId,'div');
    ELEM.setStyle(this.elemId,'background-image','url('+this.value+')');
  },
  _makeElem: function(_parentId){
    if(this.options.scaleToFit){
      this._makeScaleToFit(_parentId);
    }
    else {
      this._makeScaleToOriginal(_parentId);
    }
  },

  setValue: function(_value){
    this.base(_value);
    ELEM.setAttr(this.elemId,'src',_value);
  },

  setLabel: function(_label){
    this.base(_label);
    ELEM.setAttr(this.elemId,'alt',_label);
  },

/** method: scaleToFit
  *
  * Changes the size of the image element so that it fits in the rectangle of
  * the view.
  *
  * See also:
  *  <scaleToOriginal>
  **/
  scaleToFit: function() {
    if(!this.options.scaleToFit){
      ELEM.del(this.elemId);
      this._makeScaleToFit(this._getParentElemId());
      this.options.scaleToFit=true;
    }
  },

/** method: scaleToOriginal
  *
  * Resizes the image element to its original dimesions. If the image is larger
  * than the rectangle of this view, clipping will occur.
  *
  * See also:
  *  <scaleToFit>
  **/
  scaleToOriginal: function() {
    if(this.options.scaleToFit){
      ELEM.del(this.elemId);
      this._makeScaleToOriginal(this._getParentElemId());
      this.options.scaleToFit=false;
    }
  }

});
<|endoftext|>


<commit_before>/*
The MIT License (MIT)
Copyright (c) 2014 Microsoft Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

//SCRIPT START

var Constants = {
    MediaTypes: {
        Any: "*/*",
        ImageJpeg: "image/jpeg",
        ImagePng: "image/png",
        Javascript: "application/x-javascript",
        Json: "application/json",
        OctetStream: "application/octet-stream",
        QueryJson: "application/query+json",
        SQL: "application/sql",
        TextHtml: "text/html",
        TextPlain: "text/plain",
        Xml: "application/xml"
    },

    HttpMethods: {
        Get: "GET",
        Post: "POST",
        Put: "PUT",
        Delete: "DELETE",
        Head: "HEAD",
        Options: "OPTIONS"
    },

    HttpHeaders: {
        Authorization: "authorization",
        ETag: "etag",
        MethodOverride: "X-HTTP-Method",
        Slug: "Slug",
        ContentType: "Content-Type",
        LastModified: "Last-Modified",
        ContentEncoding: "Content-Encoding",
        CharacterSet: "CharacterSet",
        UserAgent: "User-Agent",
        IfModifiedSince: "If-Modified-Since",
        IfMatch: "If-Match",
        IfNoneMatch: "If-None-Match",
        ContentLength: "Content-Length",
        AcceptEncoding: "Accept-Encoding",
        KeepAlive: "Keep-Alive",
        CacheControl: "Cache-Control",
        TransferEncoding: "Transfer-Encoding",
        ContentLanguage: "Content-Language",
        ContentLocation: "Content-Location",
        ContentMd5: "Content-Md5",
        ContentRange: "Content-Range",
        Accept: "Accept",
        AcceptCharset: "Accept-Charset",
        AcceptLanguage: "Accept-Language",
        IfRange: "If-Range",
        IfUnmodifiedSince: "If-Unmodified-Since",
        MaxForwards: "Max-Forwards",
        ProxyAuthorization: "Proxy-Authorization",
        AcceptRanges: "Accept-Ranges",
        ProxyAuthenticate: "Proxy-Authenticate",
        RetryAfter: "Retry-After",
        SetCookie: "Set-Cookie",
        WwwAuthenticate: "Www-Authenticate",
        Origin: "Origin",
        Host: "Host",
        AccessControlAllowOrigin: "Access-Control-Allow-Origin",
        AccessControlAllowHeaders: "Access-Control-Allow-Headers",
        KeyValueEncodingFormat: "application/x-www-form-urlencoded",
        WrapAssertionFormat: "wrap_assertion_format",
        WrapAssertion: "wrap_assertion",
        WrapScope: "wrap_scope",
        SimpleToken: "SWT",
        HttpDate: "date",
        Prefer: "Prefer",
        Location: "Location",
        Referer: "referer",

        // Query
        Query: "x-ms-documentdb-query",
        IsQuery: "x-ms-documentdb-isquery",

        // Our custom DocumentDB headers
        Continuation: "x-ms-continuation",
        PageSize: "x-ms-max-item-count",

        // Request sender generated. Simply echoed by backend.
        ActivityId: "x-ms-activity-id",
        PreTriggerInclude: "x-ms-documentdb-pre-trigger-include",
        PreTriggerExclude: "x-ms-documentdb-pre-trigger-exclude",
        PostTriggerInclude: "x-ms-documentdb-post-trigger-include",
        PostTriggerExclude: "x-ms-documentdb-post-trigger-exclude",
        IndexingDirective: "x-ms-indexing-directive",
        SessionToken: "x-ms-session-token",
        ConsistencyLevel: "x-ms-consistency-level",
        XDate: "x-ms-date",
        CollectionPartitionInfo: "x-ms-collection-partition-info",
        CollectionServiceInfo: "x-ms-collection-service-info",
        RetryAfterInMilliseconds: "x-ms-retry-after-ms",
        IsFeedUnfiltered: "x-ms-is-feed-unfiltered",
        ResourceTokenExpiry: "x-ms-documentdb-expiry-seconds",
        EnableScanInQuery: "x-ms-documentdb-query-enable-scan",
        EmitVerboseTracesInQuery: "x-ms-documentdb-query-emit-traces",
        // Version headers and values
        Version: "x-ms-version",

        //Quota Info
        MaxEntityCount: "x-ms-root-entity-max-count",
        CurrentEntityCount: "x-ms-root-entity-current-count",
        CollectionQuotaInMb: "x-ms-collection-quota-mb",
        CollectionCurrentUsageInMb: "x-ms-collection-usage-mb",
        MaxMediaStorageUsageInMB: "x-ms-max-media-storage-usage-mb",
        CurrentMediaStorageUsageInMB: "x-ms-media-storage-usage-mb",
        RequestCharge: "x-ms-request-charge",

        // Offer header
        OfferType: "x-ms-offer-type",

        // Index progress headers
        IndexTransformationProgress: "x-ms-documentdb-collection-index-transformation-progress",
        LazyIndexingProgress: "x-ms-documentdb-collection-lazy-indexing-progress",

        // Upsert header
        IsUpsert: "x-ms-documentdb-is-upsert"
    },

    CurrentVersion: "2015-08-06",

    UserAgent: "documentdb-nodejs-sdk-1.4.0",

    DefaultPrecisions: {
        DefaultNumberHashPrecision: 3,
        DefaultNumberRangePrecision: -1,
        DefaultStringHashPrecision: 3,
        DefaultStringRangePrecision: -1
    },

    ConsistentHashRing: {
        DefaultVirtualNodesPerCollection: 128
    },

    RegularExpressions: {
        TrimLeftSlashes: new RegExp("^[/]+"),
        TrimRightSlashes: new RegExp("[/]+$")
    }
};

//SCRIPT END

if (typeof exports !== "undefined") {
    module.exports = Constants;
}<commit_msg>Bump version to 1.5<commit_after>/*
The MIT License (MIT)
Copyright (c) 2014 Microsoft Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

//SCRIPT START

var Constants = {
    MediaTypes: {
        Any: "*/*",
        ImageJpeg: "image/jpeg",
        ImagePng: "image/png",
        Javascript: "application/x-javascript",
        Json: "application/json",
        OctetStream: "application/octet-stream",
        QueryJson: "application/query+json",
        SQL: "application/sql",
        TextHtml: "text/html",
        TextPlain: "text/plain",
        Xml: "application/xml"
    },

    HttpMethods: {
        Get: "GET",
        Post: "POST",
        Put: "PUT",
        Delete: "DELETE",
        Head: "HEAD",
        Options: "OPTIONS"
    },

    HttpHeaders: {
        Authorization: "authorization",
        ETag: "etag",
        MethodOverride: "X-HTTP-Method",
        Slug: "Slug",
        ContentType: "Content-Type",
        LastModified: "Last-Modified",
        ContentEncoding: "Content-Encoding",
        CharacterSet: "CharacterSet",
        UserAgent: "User-Agent",
        IfModifiedSince: "If-Modified-Since",
        IfMatch: "If-Match",
        IfNoneMatch: "If-None-Match",
        ContentLength: "Content-Length",
        AcceptEncoding: "Accept-Encoding",
        KeepAlive: "Keep-Alive",
        CacheControl: "Cache-Control",
        TransferEncoding: "Transfer-Encoding",
        ContentLanguage: "Content-Language",
        ContentLocation: "Content-Location",
        ContentMd5: "Content-Md5",
        ContentRange: "Content-Range",
        Accept: "Accept",
        AcceptCharset: "Accept-Charset",
        AcceptLanguage: "Accept-Language",
        IfRange: "If-Range",
        IfUnmodifiedSince: "If-Unmodified-Since",
        MaxForwards: "Max-Forwards",
        ProxyAuthorization: "Proxy-Authorization",
        AcceptRanges: "Accept-Ranges",
        ProxyAuthenticate: "Proxy-Authenticate",
        RetryAfter: "Retry-After",
        SetCookie: "Set-Cookie",
        WwwAuthenticate: "Www-Authenticate",
        Origin: "Origin",
        Host: "Host",
        AccessControlAllowOrigin: "Access-Control-Allow-Origin",
        AccessControlAllowHeaders: "Access-Control-Allow-Headers",
        KeyValueEncodingFormat: "application/x-www-form-urlencoded",
        WrapAssertionFormat: "wrap_assertion_format",
        WrapAssertion: "wrap_assertion",
        WrapScope: "wrap_scope",
        SimpleToken: "SWT",
        HttpDate: "date",
        Prefer: "Prefer",
        Location: "Location",
        Referer: "referer",

        // Query
        Query: "x-ms-documentdb-query",
        IsQuery: "x-ms-documentdb-isquery",

        // Our custom DocumentDB headers
        Continuation: "x-ms-continuation",
        PageSize: "x-ms-max-item-count",

        // Request sender generated. Simply echoed by backend.
        ActivityId: "x-ms-activity-id",
        PreTriggerInclude: "x-ms-documentdb-pre-trigger-include",
        PreTriggerExclude: "x-ms-documentdb-pre-trigger-exclude",
        PostTriggerInclude: "x-ms-documentdb-post-trigger-include",
        PostTriggerExclude: "x-ms-documentdb-post-trigger-exclude",
        IndexingDirective: "x-ms-indexing-directive",
        SessionToken: "x-ms-session-token",
        ConsistencyLevel: "x-ms-consistency-level",
        XDate: "x-ms-date",
        CollectionPartitionInfo: "x-ms-collection-partition-info",
        CollectionServiceInfo: "x-ms-collection-service-info",
        RetryAfterInMilliseconds: "x-ms-retry-after-ms",
        IsFeedUnfiltered: "x-ms-is-feed-unfiltered",
        ResourceTokenExpiry: "x-ms-documentdb-expiry-seconds",
        EnableScanInQuery: "x-ms-documentdb-query-enable-scan",
        EmitVerboseTracesInQuery: "x-ms-documentdb-query-emit-traces",
        // Version headers and values
        Version: "x-ms-version",

        //Quota Info
        MaxEntityCount: "x-ms-root-entity-max-count",
        CurrentEntityCount: "x-ms-root-entity-current-count",
        CollectionQuotaInMb: "x-ms-collection-quota-mb",
        CollectionCurrentUsageInMb: "x-ms-collection-usage-mb",
        MaxMediaStorageUsageInMB: "x-ms-max-media-storage-usage-mb",
        CurrentMediaStorageUsageInMB: "x-ms-media-storage-usage-mb",
        RequestCharge: "x-ms-request-charge",

        // Offer header
        OfferType: "x-ms-offer-type",

        // Index progress headers
        IndexTransformationProgress: "x-ms-documentdb-collection-index-transformation-progress",
        LazyIndexingProgress: "x-ms-documentdb-collection-lazy-indexing-progress",

        // Upsert header
        IsUpsert: "x-ms-documentdb-is-upsert"
    },

    CurrentVersion: "2015-08-06",

    UserAgent: "documentdb-nodejs-sdk-1.5.0",

    DefaultPrecisions: {
        DefaultNumberHashPrecision: 3,
        DefaultNumberRangePrecision: -1,
        DefaultStringHashPrecision: 3,
        DefaultStringRangePrecision: -1
    },

    ConsistentHashRing: {
        DefaultVirtualNodesPerCollection: 128
    },

    RegularExpressions: {
        TrimLeftSlashes: new RegExp("^[/]+"),
        TrimRightSlashes: new RegExp("[/]+$")
    }
};

//SCRIPT END

if (typeof exports !== "undefined") {
    module.exports = Constants;
}<|endoftext|>


<commit_before>Ext.namespace("Gemma");

/**
 *
 * @class Gemma.MGEDCombo
 * @extends Ext.form.ComboBox
 */
Gemma.MGEDCombo = Ext.extend(Ext.form.ComboBox, {

			editable : true,
			mode : 'local',
			selectOnFocus : true,
			triggerAction : 'all',
			typeAhead : true,
			forceSelection : true,
			displayField : 'term',

			record : Ext.data.Record.create([{
						name : "uri"
					}, {
						name : "term"
					}, {
						name : "comment"
					}]),

			getTerm : function() {
				return this.selectedTerm;
			},

			initComponent : function() {
				if (this.termKey) {
					this.dwrMethod = MgedOntologyService.getMgedTermsByKey;
					this.dwrParams = [this.termKey];
				} else {
					this.dwrMethod = MgedOntologyService.getUsefulMgedTerms;
					this.dwrParams = [];
				}

				this.store = new Ext.data.Store({
							proxy : new Ext.data.DWRProxy(this.dwrMethod),
							reader : new Ext.data.ListRangeReader({
										id : "uri"
									}, this.record),
							remoteSort : false,
							sortInfo : {
								field : "term"
							}
						});

				Gemma.MGEDCombo.superclass.initComponent.call(this);

				// this.tpl = new Ext.XTemplate('<tpl for=".">{term}
</tpl>');
				// this.tpl.compile();

				this.on("select", function(combo, record, index) {
							this.selectedTerm = record.data;
						});

				this.store.load({
							params : this.dwrParams
						});
			}
		});
<commit_msg>fix for 1927 - select on blur<commit_after>Ext.namespace("Gemma");

/**
 * Dropdown menu of MGED categories to use in annotations
 *
 * @class Gemma.MGEDCombo
 * @extends Ext.form.ComboBox
 * @version $Id$
 */
Gemma.MGEDCombo = Ext.extend(Ext.form.ComboBox, {

			editable : true,
			mode : 'local',
			selectOnFocus : true,
			triggerAction : 'all',
			typeAhead : true,
			forceSelection : true,
			displayField : 'term',

			record : Ext.data.Record.create([{
						name : "uri"
					}, {
						name : "term"
					}, {
						name : "comment"
					}]),

			getTerm : function() {
				return this.selectedTerm;
			},

			initComponent : function() {
				if (this.termKey) {
					this.dwrMethod = MgedOntologyService.getMgedTermsByKey;
					this.dwrParams = [this.termKey];
				} else {
					this.dwrMethod = MgedOntologyService.getUsefulMgedTerms;
					this.dwrParams = [];
				}

				this.store = new Ext.data.Store({
							proxy : new Ext.data.DWRProxy(this.dwrMethod),
							reader : new Ext.data.ListRangeReader({
										id : "uri"
									}, this.record),
							remoteSort : false,
							sortInfo : {
								field : "term"
							}
						});

				Gemma.MGEDCombo.superclass.initComponent.call(this);

				// so that tabbing away still results in a 'select'. I wish there was a better way to do this.
				this.on("change", function(combo) {
							if (this.getValue()) {
								var ix = this.getStore().find("term", this.getValue());
								var rec = this.getStore().getAt(ix);
								this.select(ix, true);
								this.fireEvent('select', this, rec, ix);
							}
						});

				this.on("select", function(combo, record, index) {
							this.selectedTerm = record.data;
						});

				this.store.load({
							params : this.dwrParams
						});
			}
		});
<|endoftext|>


<commit_before>describe('Preprocessor', function () {
  var
    H = humblevis;

  it('defines preprocessor', function () {
    expect(H.Preprocessor).toBeDefined();
  });

  it('creates a preprocessor', function () {
    expect(new H.Preprocessor()).toBeDefined();
  });

  it('gets private data from options', function () {
    var
      data = [[],[]],
      options = { data : data },
      preprocessor = new H.Preprocessor(options);

    expect(preprocessor.getData()).toBe(data);
  });

  it('sets new private data', function () {

    var
      data = [[],[]],
      options = { data : [[], []] },
      preprocessor = new H.Preprocessor(options);

    expect(preprocessor.getData()).not.toBe(data);
    preprocessor.setData(data);
    expect(preprocessor.getData()).toBe(data);
  });

  describe('Validation', function () {

    var
      preprocessor;

    beforeEach(function () {
      preprocessor = new H.Preprocessor();
    });
    afterEach(function () {
      preprocessor = null;
    });

    it('expects array data', function () {
      expect(function () { preprocessor.setData({}); })
        .toThrow(new Error("Array expected."));
    });

    it('expects at least two dimensions', function () {
      var
        e = new Error('Data must contain at least two dimensions.');
      expect(function () { preprocessor.setData([]); }).toThrow(e);
      expect(function () { preprocessor.setData([[]]); }).toThrow(e);
    });

    it('expects each dimension to be an array', function () {
      expect(function () { preprocessor.setData([[], {}]); })
        .toThrow(new Error('Data dimensions must be arrays.'));
    });

    it('expects each dimension to have the same number of points', function () {
      expect(function () { preprocessor.setData([[], [1]]); })
        .toThrow(new Error('Data dimensions must contain the same number of points.'));
    });
  });
});
<commit_msg>Added check for data validation through options / construction.<commit_after>describe('Preprocessor', function () {
  var
    H = humblevis;

  it('defines preprocessor', function () {
    expect(H.Preprocessor).toBeDefined();
  });

  it('creates a preprocessor', function () {
    expect(new H.Preprocessor()).toBeDefined();
  });

  it('gets private data from options', function () {
    var
      data = [[],[]],
      options = { data : data },
      preprocessor = new H.Preprocessor(options);

    expect(preprocessor.getData()).toBe(data);
  });

  it('sets new private data', function () {

    var
      data = [[],[]],
      options = { data : [[], []] },
      preprocessor = new H.Preprocessor(options);

    expect(preprocessor.getData()).not.toBe(data);
    preprocessor.setData(data);
    expect(preprocessor.getData()).toBe(data);
  });

  describe('Validation', function () {

    var
      preprocessor;

    beforeEach(function () {
      preprocessor = new H.Preprocessor();
    });
    afterEach(function () {
      preprocessor = null;
    });

    it('expects array data', function () {
      expect(function () { preprocessor.setData({}); })
        .toThrow(new Error("Array expected."));
    });

    it('expects at least two dimensions', function () {
      var
        e = new Error('Data must contain at least two dimensions.');
      expect(function () { preprocessor.setData([]); }).toThrow(e);
      expect(function () { preprocessor.setData([[]]); }).toThrow(e);
    });

    it('expects each dimension to be an array', function () {
      expect(function () { preprocessor.setData([[], {}]); })
        .toThrow(new Error('Data dimensions must be arrays.'));
    });

    it('expects each dimension to have the same number of points', function () {
      expect(function () { preprocessor.setData([[], [1]]); })
        .toThrow(new Error('Data dimensions must contain the same number of points.'));
    });

    it('validates options data', function () {
      var
        options = { data : {} };
      expect(function () { new H.Preprocessor(options); })
        .toThrow(new Error("Array expected."));
    });
  });
});
<|endoftext|>


<commit_before>// Globals
var curtab = ''

// Code for initialising the view
$(document).ready(function() {
  $("#base").attr("src","img/Riddler.png");

  // Prepare action when text submitted
  $("#query").on("submit", function(e) {
    e.preventDefault();
    // Prepare to loop through output lines, updating them
    solsubmit = $("#solution").val();
    update_log('You> ' + solsubmit);
    // Reset input field
    $("#solution").val('');
    // Prepare form
    //dataform = $("#query").serialize();
    if (curtab) {
      dataform = {};
      dataform['riddle'] = curtab;
      dataform['solution'] = solsubmit;
      // Submit solution
      $.ajax({
        url: '/query',
        type: 'post',
        dataType: 'json',
        data: dataform,
        success: function(data) {
          // Display response
          update_log(data['msg']);
          // Update visible tablets
          hide_tabs(data['lstat']);
          // Complete if finished
          if ( (data['lstat'] & 15) == 15) $("#base").attr("src","img/Winner.png");
        }
      });
    }
    else {
      update_log('Skeleton> Please have a tablet open before submitting a solution.');
    }
  });

  // Handle text bar when empty / focussed / etc.
  $("#solution").focus( function(e) {
    if ($(this).is(".empty")) {
      // Remove this class, and empty the field
      $(this).val('').removeClass('empty');
    }
  });
  $("#solution").blur( function(e) {
    if ($(this).val() == '' && $(this).not(".empty")) {
      $(this).val('Enter solutions here...').addClass('empty');
    }
  });

  // Load text into tablets and show/hide solved tabs
  load_riddles();
  hide_tabs(lstat);

  // Handle clicks on tablets
  $(".tablet").click( function(e) {
    //update_log($(this).attr('id') + ' clicked.');
    tab = '#' + $(this).attr('id') + 'tab';
    // As a precaution, close any open tab
    if (curtab) {
      $(curtab).hide();
    }
    $(tab).show();
    curtab = tab;
  });

  // Handled tablet closeicons
  $(".closeicon").click( function(e) {
    $(curtab).hide();
    curtab = '';
  });
});

function update_log(newval) {
  new_text = newval;
  old_text = '';
  for (i=0; i<10; i++) {
    old_text = $("#record_"+i).text();
    $("#record_"+i).text(new_text);
    new_text = old_text;
  }
}

function load_riddles() {
  $.ajax({
    url: "getriddle",
    type: 'get',
    dataType: 'json',
    success: function(data) {
      // Fill each tabspan with their content -- response keys are span ids
      $(".tabspan").each( function() {
        $(this).html(data[$(this).attr('id')]);
      });
    }
  });
}

function hide_tabs(lst) {
  // Cyan
  if ( (lst & 8) == 8 ) $('#cyan').hide();
  else $('#cyan').show();
  // Violet
  if ( (lst & 4) == 4 ) $('#violet').hide();
  else $('#violet').show();
  // Purple
  if ( (lst & 2) == 2 ) $('#purple').hide();
  else $('#purple').show();
  // Red
  if ( (lst & 1) == 1 ) $('#red').hide();
  else $('#red').show();
}
<commit_msg>Update to show correct state on refresh<commit_after>// Globals
var curtab = ''

// Code for initialising the view
$(document).ready(function() {
  // Check if already complete, load background if not
  if ( ( lstat & 15 ) != 15 ) $("#base").attr("src","img/Riddler.png");
  else {
    $("#base").attr("src","img/Winner.png");
    $("#record_0").text("You're done, feel free to leave, and good luck!");
    $("#record_1").text('');
  }

  // Prepare action when text submitted
  $("#query").on("submit", function(e) {
    e.preventDefault();
    // Prepare to loop through output lines, updating them
    solsubmit = $("#solution").val();
    update_log('You> ' + solsubmit);
    // Reset input field
    $("#solution").val('');
    // Prepare form
    //dataform = $("#query").serialize();
    if (curtab) {
      dataform = {};
      dataform['riddle'] = curtab;
      dataform['solution'] = solsubmit;
      // Submit solution
      $.ajax({
        url: '/query',
        type: 'post',
        dataType: 'json',
        data: dataform,
        success: function(data) {
          // Display response
          update_log(data['msg']);
          // Update visible tablets
          hide_tabs(data['lstat']);
          // Complete if finished
          if ( (data['lstat'] & 15) == 15) $("#base").attr("src","img/Winner.png");
        }
      });
    }
    else {
      update_log('Skeleton> Please have a tablet open before submitting a solution.');
    }
  });

  // Handle text bar when empty / focussed / etc.
  $("#solution").focus( function(e) {
    if ($(this).is(".empty")) {
      // Remove this class, and empty the field
      $(this).val('').removeClass('empty');
    }
  });
  $("#solution").blur( function(e) {
    if ($(this).val() == '' && $(this).not(".empty")) {
      $(this).val('Enter solutions here...').addClass('empty');
    }
  });

  // Load text into tablets and show/hide solved tabs
  load_riddles();
  hide_tabs(lstat);

  // Handle clicks on tablets
  $(".tablet").click( function(e) {
    //update_log($(this).attr('id') + ' clicked.');
    tab = '#' + $(this).attr('id') + 'tab';
    // As a precaution, close any open tab
    if (curtab) {
      $(curtab).hide();
    }
    $(tab).show();
    curtab = tab;
  });

  // Handled tablet closeicons
  $(".closeicon").click( function(e) {
    $(curtab).hide();
    curtab = '';
  });
});

function update_log(newval) {
  new_text = newval;
  old_text = '';
  for (i=0; i<10; i++) {
    old_text = $("#record_"+i).text();
    $("#record_"+i).text(new_text);
    new_text = old_text;
  }
}

function load_riddles() {
  $.ajax({
    url: "getriddle",
    type: 'get',
    dataType: 'json',
    success: function(data) {
      // Fill each tabspan with their content -- response keys are span ids
      $(".tabspan").each( function() {
        $(this).html(data[$(this).attr('id')]);
      });
    }
  });
}

function hide_tabs(lst) {
  // Cyan
  if ( (lst & 8) == 8 ) $('#cyan').hide();
  else $('#cyan').show();
  // Violet
  if ( (lst & 4) == 4 ) $('#violet').hide();
  else $('#violet').show();
  // Purple
  if ( (lst & 2) == 2 ) $('#purple').hide();
  else $('#purple').show();
  // Red
  if ( (lst & 1) == 1 ) $('#red').hide();
  else $('#red').show();
}
<|endoftext|>


<commit_before>//! moment.js locale configuration
//! locale : Arabic (Kuwait) [ar-kw]
//! author : Nusret Parlak: https://github.com/nusretparlak

;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../moment')) :
   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

var arKw = moment.defineLocale('ar-kw', {
    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
    weekdaysParseExact : true,
    longDateFormat : {
        LT : 'HH:mm',
        LTS : 'HH:mm:ss',
        L : 'DD/MM/YYYY',
        LL : 'D MMMM YYYY',
        LLL : 'D MMMM YYYY HH:mm',
        LLLL : 'dddd D MMMM YYYY HH:mm'
    },
    calendar : {
        sameDay: '[اليوم على الساعة] LT',
        nextDay: '[غدا على الساعة] LT',
        nextWeek: 'dddd [على الساعة] LT',
        lastDay: '[أمس على الساعة] LT',
        lastWeek: 'dddd [على الساعة] LT',
        sameElse: 'L'
    },
    relativeTime : {
        future : 'في %s',
        past : 'منذ %s',
        s : 'ثوان',
        m : 'دقيقة',
        mm : '%d دقائق',
        h : 'ساعة',
        hh : '%d ساعات',
        d : 'يوم',
        dd : '%d أيام',
        M : 'شهر',
        MM : '%d أشهر',
        y : 'سنة',
        yy : '%d سنوات'
    },
    week : {
        dow : 7, // Sunday is the first day of the week.
        doy : 12  // The week that contains Jan 1st is the first week of the year.
    }
});

return arKw;

})));
<commit_msg>Day of week updated.<commit_after>//! moment.js locale configuration
//! locale : Arabic (Kuwait) [ar-kw]
//! author : Nusret Parlak: https://github.com/nusretparlak

;(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined'
       && typeof require === 'function' ? factory(require('../moment')) :
   typeof define === 'function' && define.amd ? define(['../moment'], factory) :
   factory(global.moment)
}(this, (function (moment) { 'use strict';

var arKw = moment.defineLocale('ar-kw', {
    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
    weekdaysParseExact : true,
    longDateFormat : {
        LT : 'HH:mm',
        LTS : 'HH:mm:ss',
        L : 'DD/MM/YYYY',
        LL : 'D MMMM YYYY',
        LLL : 'D MMMM YYYY HH:mm',
        LLLL : 'dddd D MMMM YYYY HH:mm'
    },
    calendar : {
        sameDay: '[اليوم على الساعة] LT',
        nextDay: '[غدا على الساعة] LT',
        nextWeek: 'dddd [على الساعة] LT',
        lastDay: '[أمس على الساعة] LT',
        lastWeek: 'dddd [على الساعة] LT',
        sameElse: 'L'
    },
    relativeTime : {
        future : 'في %s',
        past : 'منذ %s',
        s : 'ثوان',
        m : 'دقيقة',
        mm : '%d دقائق',
        h : 'ساعة',
        hh : '%d ساعات',
        d : 'يوم',
        dd : '%d أيام',
        M : 'شهر',
        MM : '%d أشهر',
        y : 'سنة',
        yy : '%d سنوات'
    },
    week : {
        dow : 0, // Sunday is the first day of the week.
        doy : 12  // The week that contains Jan 1st is the first week of the year.
    }
});

return arKw;

})));
<|endoftext|>


<commit_before>// https://git.io/vH4Ek
var supports_video_autoplay = function(callback) {

    var v = document.createElement("video");
    v.paused = true;
    var p = "play" in v && v.play();

    typeof callback === "function" && callback(!v.paused || "Promise" in window && p instanceof Promise);

};

var supports_mp4_in_img = function(callback) {

    var image = new Image();

    image.onload = function() {
        var isSupported = image.width > 0 && image.height > 0;
        callback(isSupported);
    };

    image.onerror = function() {
        callback(false);
    };
    image.src = 'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAAs1tZGF0AAACrgYF//+q3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0OCByMjYwMSBhMGNkN2QzIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNSAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1oZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0xIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MSBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aHJlYWRzPTEgbG9va2FoZWFkX3RocmVhZHM9MSBzbGljZWRfdGhyZWFkcz0wIG5yPTAgZGVjaW1hdGU9MSBpbnRlcmxhY2VkPTAgYmx1cmF5X2NvbXBhdD0wIGNvbnN0cmFpbmVkX2ludHJhPTAgYmZyYW1lcz0zIGJfcHlyYW1pZD0yIGJfYWRhcHQ9MSBiX2JpYXM9MCBkaXJlY3Q9MSB3ZWlnaHRiPTEgb3Blbl9nb3A9MCB3ZWlnaHRwPTIga2V5aW50PTI1MCBrZXlpbnRfbWluPTEwIHNjZW5lY3V0PTQwIGludHJhX3JlZnJlc2g9MCByY19sb29rYWhlYWQ9NDAgcmM9Y3JmIG1idHJlZT0xIGNyZj0yMy4wIHFjb21wPTAuNjAgcXBtaW49MCBxcG1heD02OSBxcHN0ZXA9NCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAD2WIhAA3//728P4FNjuZQQAAAu5tb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAAZAABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACGHRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAEAAAAAAAAAZAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAgAAAAIAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAGQAAAAAAAEAAAAAAZBtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAACgAAAAEAFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAE7bWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAAA+3N0YmwAAACXc3RzZAAAAAAAAAABAAAAh2F2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAgACAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAxYXZjQwFkAAr/4QAYZ2QACqzZX4iIhAAAAwAEAAADAFA8SJZYAQAGaOvjyyLAAAAAGHN0dHMAAAAAAAAAAQAAAAEAAAQAAAAAHHN0c2MAAAAAAAAAAQAAAAEAAAABAAAAAQAAABRzdHN6AAAAAAAAAsUAAAABAAAAFHN0Y28AAAAAAAAAAQAAADAAAABidWR0YQAAAFptZXRhAAAAAAAAACFoZGxyAAAAAAAAAABtZGlyYXBwbAAAAAAAAAAAAAAAAC1pbHN0AAAAJal0b28AAAAdZGF0YQAAAAEAAAAATGF2ZjU2LjQwLjEwMQ==';
}

supports_video_autoplay(function(supportsAutoplay) {
    supports_mp4_in_img(function(supportsMP4InImg) {
        if (supportsMP4InImg) {
            var videos = document.querySelectorAll('[data-gif]');

            [].forEach.call(videos, function(video) {
                var img = new Image();
                img.src = video.querySelector('source').src;
                img.setAttribute('alt', "");
                if (img.decode) {
                    img.decode().then(function() { video.parentNode.replaceChild(img, video); });
                } else {
                    img.onload = function() {
                        video.parentNode.replaceChild(img, video);
                    }
                }

            });
        } else {
            var saveData = navigator.connection && navigator.connection.saveData;
            if (supportsAutoplay && 'IntersectionObserver' in window && !saveData) {
                var videos = document.querySelectorAll('[data-gif]');

                observer = new IntersectionObserver(entries => {
                    entries.forEach(entry => {
                        var video = entry.target;
                        if (entry.intersectionRatio > 0) {
                            // video is in the viewport - start it
                            video.setAttribute('autoplay', true);
                            video.setAttribute('loop', true);
                        } else {
                            // video is outside the viewport - pause it
                            video.removeAttribute('autoplay');
                            video.removeAttribute('loop');
                        }
                    });
                });

                [].forEach.call(videos, function(video) {
                    video.removeAttribute('controls');

                    observer.observe(video);
                });
            } else {
                // no video autoplay support :(
            }
        }
    });

});<commit_msg>correct autplay feature test<commit_after>// https://git.io/vH4Ek
var supports_video_autoplay = function(callback) {

    var v = document.createElement("video");
    v.paused = true;
    var p = false;
    try {
        p = "play" in v && v.play();
    } catch {

    }
    typeof callback === "function" && callback(!v.paused || "Promise" in window && p instanceof Promise);

};

var supports_mp4_in_img = function(callback) {

    var image = new Image();

    image.onload = function() {
        var isSupported = image.width > 0 && image.height > 0;
        callback(isSupported);
    };

    image.onerror = function() {
        callback(false);
    };
    image.src = 'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAAAs1tZGF0AAACrgYF//+q3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0OCByMjYwMSBhMGNkN2QzIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNSAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1oZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0xIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MSBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aHJlYWRzPTEgbG9va2FoZWFkX3RocmVhZHM9MSBzbGljZWRfdGhyZWFkcz0wIG5yPTAgZGVjaW1hdGU9MSBpbnRlcmxhY2VkPTAgYmx1cmF5X2NvbXBhdD0wIGNvbnN0cmFpbmVkX2ludHJhPTAgYmZyYW1lcz0zIGJfcHlyYW1pZD0yIGJfYWRhcHQ9MSBiX2JpYXM9MCBkaXJlY3Q9MSB3ZWlnaHRiPTEgb3Blbl9nb3A9MCB3ZWlnaHRwPTIga2V5aW50PTI1MCBrZXlpbnRfbWluPTEwIHNjZW5lY3V0PTQwIGludHJhX3JlZnJlc2g9MCByY19sb29rYWhlYWQ9NDAgcmM9Y3JmIG1idHJlZT0xIGNyZj0yMy4wIHFjb21wPTAuNjAgcXBtaW49MCBxcG1heD02OSBxcHN0ZXA9NCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAD2WIhAA3//728P4FNjuZQQAAAu5tb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAAZAABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACGHRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAEAAAAAAAAAZAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAgAAAAIAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAGQAAAAAAAEAAAAAAZBtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAACgAAAAEAFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAE7bWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAAA+3N0YmwAAACXc3RzZAAAAAAAAAABAAAAh2F2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAgACAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAxYXZjQwFkAAr/4QAYZ2QACqzZX4iIhAAAAwAEAAADAFA8SJZYAQAGaOvjyyLAAAAAGHN0dHMAAAAAAAAAAQAAAAEAAAQAAAAAHHN0c2MAAAAAAAAAAQAAAAEAAAABAAAAAQAAABRzdHN6AAAAAAAAAsUAAAABAAAAFHN0Y28AAAAAAAAAAQAAADAAAABidWR0YQAAAFptZXRhAAAAAAAAACFoZGxyAAAAAAAAAABtZGlyYXBwbAAAAAAAAAAAAAAAAC1pbHN0AAAAJal0b28AAAAdZGF0YQAAAAEAAAAATGF2ZjU2LjQwLjEwMQ==';
}

supports_video_autoplay(function(supportsAutoplay) {
    supports_mp4_in_img(function(supportsMP4InImg) {
        if (supportsMP4InImg) {
            var videos = document.querySelectorAll('[data-gif]');

            [].forEach.call(videos, function(video) {
                var img = new Image();
                img.src = video.querySelector('source').src;
                img.setAttribute('alt', "");
                if (img.decode) {
                    img.decode().then(function() { video.parentNode.replaceChild(img, video); });
                } else {
                    img.onload = function() {
                        video.parentNode.replaceChild(img, video);
                    }
                }

            });
        } else {
            var saveData = navigator.connection && navigator.connection.saveData;
            if (supportsAutoplay && 'IntersectionObserver' in window && !saveData) {
                var videos = document.querySelectorAll('[data-gif]');

                observer = new IntersectionObserver(entries => {
                    entries.forEach(entry => {
                        var video = entry.target;
                        if (entry.intersectionRatio > 0) {
                            // video is in the viewport - start it
                            video.setAttribute('autoplay', true);
                            video.setAttribute('loop', true);
                        } else {
                            // video is outside the viewport - pause it
                            video.removeAttribute('autoplay');
                            video.removeAttribute('loop');
                        }
                    });
                });

                [].forEach.call(videos, function(video) {
                    video.removeAttribute('controls');

                    observer.observe(video);
                });
            } else {
                // no video autoplay support :(
            }
        }
    });

});<|endoftext|>


<commit_before>// ==ClosureCompiler==
// @output_file_name default.js
// @compilation_level ADVANCED_OPTIMIZATIONS
// @js_externs var kintExpandOnLoad
// @js_externs var kint
// ==/ClosureCompiler==

if ( typeof kint === 'undefined' ) {
	if ( typeof kintExpandOnLoad === 'undefined' ) {
		kintExpandOnLoad = {};
	}

	kint = {
		visiblePluses : [],
		currentPlus   : -1,

		selectText : function( element ) {
			var selection = window.getSelection(),
				range = document.createRange();

			range.selectNodeContents(element);
			selection.removeAllRanges();
			selection.addRange(range);
		},

		addClass : function( ele, className ) {
			if ( typeof className === 'undefined' ) {
				className = 'kint-minus';
			}

			kint.removeClass(ele, className).className += (" " + className);
		},

		removeClass : function( ele, className ) {
			if ( typeof className === 'undefined' ) {
				className = 'kint-minus';
			}

			ele.className = ele.className.replace(
				new RegExp('(\\s|^)' + className + '(\\s|$)'), ' '
			);
			return ele;
		},

		next : function( element ) {
			do {
				element = element.nextElementSibling;
			} while ( element.nodeName.toLowerCase() !== 'dd' );

			return element;
		},

		toggleChildren : function( element, hide ) {
			var parent = kint.next(element),
				nodes = parent.getElementsByClassName('kint-parent'),
				i = nodes.length;

			if ( typeof hide === 'undefined' ) {
				hide = parent.style.display === 'inline';
			}

			while ( i-- ) {
				kint.toggle(nodes[i], hide);
			}
			kint.toggle(element, hide);
		},

		toggle : function( element, hide ) {
			var parent, plus;
			parent = kint.next(element);
			plus = element.getElementsByClassName('_kint-collapse')[0];

			if ( typeof hide === 'undefined' ) {
				hide = parent.style.display === 'inline';
			}

			if ( hide ) {
				parent.style.display = 'none';
				if ( plus ) kint.removeClass(plus);
			} else {
				parent.style.display = 'inline';
				if ( plus ) kint.addClass(plus);
			}

			if ( parent.childNodes.length === 1 ) {
				parent = parent.childNodes[0].childNodes[0]; // reuse var cause I can

				if ( kint.hasClass(parent, 'kint-parent') ) {
					kint.toggle(parent, hide)
				}
			} else if ( kint.currentPlus !== -1 ) {
				kint.fetchVisiblePluses();
			}
		},

		toggleAll : function( element ) {
			var elements = document.getElementsByClassName('kint-parent'),
				i = elements.length,
				visible = kint.next(element.parentNode).style.display === 'inline';

			while ( i-- ) {
				kint.toggle(elements[i], visible);
			}
		},

		toggleTrace : function( target ) {
			var lis, el = target, index = 0;

			kint.removeClass(target.parentNode.getElementsByClassName('kint-active-tab')[0], 'kint-active-tab');
			kint.addClass(target, 'kint-active-tab');

			// take the index of clicked title tab and make the same n-th content tab visible
			while ( el = el.previousSibling ) el.nodeType === 1 && index++;
			lis = target.parentNode.nextSibling.childNodes;
			for ( var i = 0; i < lis.length; i++ ) {
				if ( i === index ) {
					lis[i].style.display = 'block';

					if ( lis[i].childNodes.length === 1 ) {
						el = lis[i].childNodes[0].childNodes[0];

						if ( kint.hasClass(el, 'kint-parent') ) {
							kint.toggle(el, false)
						}
					}
				} else {
					lis[i].style.display = 'none';
				}
			}

			if ( kint.currentPlus !== -1 ) {
				kint.fetchVisiblePluses();
			}
		},

		hasClass : function( target, className ) {
			var r = new RegExp('\\b' + className + '\\b');
			return r.test(target.className);
		},

		fetchVisiblePluses : function() {
			kint.visiblePluses = [];
			Array.prototype.slice.call(document.querySelectorAll('.kint-plus, .kint-tabs>li:not(.kint-active-tab)'), 0)
				.forEach(
				function( el ) {
					if ( el.offsetWidth !== 0 || el.offsetHeight !== 0 ) {
						kint.visiblePluses.push(el)
					}
				}
			);
		}
	};

	window.addEventListener("click", function( e ) {
		var target = e.target;

		var nodeName = target.nodeName.toLowerCase();

		if ( nodeName === 'dfn' ) {
			kint.selectText(target);
			target = target.parentNode;
		} else if ( nodeName === 'var' ) { // stupid workaround for misc elements
			target = target.parentNode;    // to not stop event from further propagating
			nodeName = target.nodeName.toLowerCase()
		}

		if ( nodeName === 'li' && target.parentNode.className === 'kint-tabs' && target.className !== 'kint-active-tab' ) {
			kint.toggleTrace(target);
			return false;
		}

		if ( kint.hasClass(target, '_kint-collapse') ) {
			setTimeout(function() {
				var timer = parseInt(target.kintTimer, 10);
				if ( timer > 0 ) {
					target.kintTimer--;
				} else {
					kint.toggleChildren(target.parentNode); //

				}
			}, 300);
			e.stopPropagation();
			return false;
		} else if ( kint.hasClass(target, 'kint-parent') ) {
			kint.toggle(target);
			return false;
		} else if ( kint.hasClass(target, 'kint-ide-link') ) {
			e.preventDefault();
			var ajax = new XMLHttpRequest(); // add ajax call to contact editor but prevent link default action
			ajax.open('GET', target.href);
			ajax.send(null);
			return false;
		}
	}, false);

	window.addEventListener("dblclick", function( e ) {
		var target = e.target;
		if ( kint.hasClass(target, '_kint-collapse') ) {
			target.kintTimer = 2;
			kint.toggleAll(target);
			e.stopPropagation();
		}
	}, false);

	window.addEventListener("load", function( e ) {
		for ( var selector in kintExpandOnLoad ) {
			Array.prototype.slice.call(document.querySelectorAll('.' + selector + '>dl>dt'), 0)
				.forEach(
				function( el ) {
					kint.toggleChildren(el);
				}
			);
		}
	}, false);

	window.onkeydown = function( e ) {
		var keyCode = e.keyCode;
		var shiftKey = e.shiftKey;
		var i = kint.currentPlus;
		var focusedClass = 'kint-focused';

		var cleanup = function( i ) {
			var prevElement = document.querySelector('.' + focusedClass);
			prevElement && kint.removeClass(prevElement, focusedClass);

			if ( i !== -1 ) {
				var el = kint.visiblePluses[i];
				kint.addClass(el, focusedClass);

				var offsetTop = function( el ) {
					return el.offsetTop + ( el.offsetParent ? offsetTop(el.offsetParent) : 0 );
				};

				var top = offsetTop(el) - (window.innerHeight / 2 );
				window.scrollTo(0, top);
			}

			kint.currentPlus = i;
		};

		var moveCursor = function( up ) {
			// todo make the first VISIBLE plus active

			if ( up ) {
				if ( --i < 0 ) {
					i = kint.visiblePluses.length - 1;
				}
			} else {
				if ( ++i >= kint.visiblePluses.length ) {
					i = 0;
				}
			}

			cleanup(i);
			return false;
		};

		if ( keyCode === 68 ) { // 'd' : toggles navigation on/off
			if ( i === -1 ) {
				kint.fetchVisiblePluses();
				return moveCursor(false);
			} else {
				cleanup(-1);
				return false;
			}
		} else {
			if ( i === -1 ) return;
			if ( keyCode === 9 ) { // TAB : moves up/down depending on shift key
				return moveCursor(shiftKey);
			} else if ( keyCode === 38 ) { // ARROW UP : moves up
				return moveCursor(true);
			} else if ( keyCode === 40 ) { // ARROW DOWN : down
				return moveCursor(false);
			} else {
				if ( i === -1 ) {
					return;
				}
			}
		}

		var kintNode = kint.visiblePluses[i];
		if ( kintNode.nodeName.toLowerCase() === 'li' ) { // we're on a trace tab
			if ( keyCode === 32 || keyCode === 13 ) { // SPACE/ENTER
				kint.toggleTrace(kintNode);
				return moveCursor(true);
			} else if ( keyCode === 39 ) { // arrows
				return moveCursor(false);
			} else if ( keyCode === 37 ) {
				return moveCursor(true);
			}
		}

		kintNode = kintNode.parentNode; // simple dump
		if ( keyCode === 32 || keyCode === 13 ) { // SPACE/ENTER : toggles
			kint.toggle(kintNode);
			return false;
		} else if ( keyCode === 39 || keyCode === 37 ) { // ARROW LEFT/RIGHT : respectively hides/shows and traverses
			var visible = kint.next(kintNode).style.display === 'inline';
			var hide = keyCode === 37;

			if ( visible ) {
				kint.toggleChildren(kintNode, hide); // expand/collapse all children if immediate ones are showing
			} else {
				if ( hide ) { // LEFT
					// traverse to parent and THEN hide
					do {kintNode = kintNode.parentNode} while ( kintNode && kintNode.nodeName.toLowerCase() !== 'dd' );

					if ( kintNode ) {
						kintNode = kintNode.previousElementSibling;

						i = -1;
						var parentPlus = kintNode.querySelector('.kint-plus');
						while ( parentPlus !== kint.visiblePluses[++i] ) {}
						cleanup(i)
					} else { // we are at root
						kintNode = kint.visiblePluses[i].parentNode;
					}
				}
				kint.toggle(kintNode, hide);
			}
			return false;
		}
	};
}

// debug purposes only, removed in minified source
function clg( i ) {
	if ( !window.console )return;
	var l = arguments.length, o = 0;
	while ( o < l )console.log(arguments[o++])
}
<commit_msg>fixed https://github.com/raveren/kint/issues/36 and refractored keydown js handler to not recreate functions on each keydown (slight front end performance increase)<commit_after>// ==ClosureCompiler==
// @output_file_name default.js
// @compilation_level ADVANCED_OPTIMIZATIONS
// @js_externs var kintExpandOnLoad
// @js_externs var kint
// ==/ClosureCompiler==

if ( typeof kint === 'undefined' ) {
	if ( typeof kintExpandOnLoad === 'undefined' ) {
		kintExpandOnLoad = {};
	}

	kint = {
		visiblePluses : [],
		currentPlus   : -1,

		selectText : function( element ) {
			var selection = window.getSelection(),
				range = document.createRange();

			range.selectNodeContents(element);
			selection.removeAllRanges();
			selection.addRange(range);
		},

		addClass : function( ele, className ) {
			if ( typeof className === 'undefined' ) {
				className = 'kint-minus';
			}

			kint.removeClass(ele, className).className += (" " + className);
		},

		removeClass : function( ele, className ) {
			if ( typeof className === 'undefined' ) {
				className = 'kint-minus';
			}

			ele.className = ele.className.replace(
				new RegExp('(\\s|^)' + className + '(\\s|$)'), ' '
			);
			return ele;
		},

		next : function( element ) {
			do {
				element = element.nextElementSibling;
			} while ( element.nodeName.toLowerCase() !== 'dd' );

			return element;
		},

		toggleChildren : function( element, hide ) {
			var parent = kint.next(element),
				nodes = parent.getElementsByClassName('kint-parent'),
				i = nodes.length;

			if ( typeof hide === 'undefined' ) {
				hide = parent.style.display === 'inline';
			}

			while ( i-- ) {
				kint.toggle(nodes[i], hide);
			}
			kint.toggle(element, hide);
		},

		toggle : function( element, hide ) {
			var parent, plus;
			parent = kint.next(element);
			plus = element.getElementsByClassName('_kint-collapse')[0];

			if ( typeof hide === 'undefined' ) {
				hide = parent.style.display === 'inline';
			}

			if ( hide ) {
				parent.style.display = 'none';
				if ( plus ) kint.removeClass(plus);
			} else {
				parent.style.display = 'inline';
				if ( plus ) kint.addClass(plus);
			}

			if ( parent.childNodes.length === 1 ) {
				parent = parent.childNodes[0].childNodes[0]; // reuse var cause I can

				if ( kint.hasClass(parent, 'kint-parent') ) {
					kint.toggle(parent, hide)
				}
			} else if ( kint.currentPlus !== -1 ) {
				kint.fetchVisiblePluses();
			}
		},

		toggleAll : function( element ) {
			var elements = document.getElementsByClassName('kint-parent'),
				i = elements.length,
				visible = kint.next(element.parentNode).style.display === 'inline';

			while ( i-- ) {
				kint.toggle(elements[i], visible);
			}
		},

		toggleTrace : function( target ) {
			var lis, el = target, index = 0;

			kint.removeClass(target.parentNode.getElementsByClassName('kint-active-tab')[0], 'kint-active-tab');
			kint.addClass(target, 'kint-active-tab');

			// take the index of clicked title tab and make the same n-th content tab visible
			while ( el = el.previousSibling ) el.nodeType === 1 && index++;
			lis = target.parentNode.nextSibling.childNodes;
			for ( var i = 0; i < lis.length; i++ ) {
				if ( i === index ) {
					lis[i].style.display = 'block';

					if ( lis[i].childNodes.length === 1 ) {
						el = lis[i].childNodes[0].childNodes[0];

						if ( kint.hasClass(el, 'kint-parent') ) {
							kint.toggle(el, false)
						}
					}
				} else {
					lis[i].style.display = 'none';
				}
			}

			if ( kint.currentPlus !== -1 ) {
				kint.fetchVisiblePluses();
			}
		},

		hasClass : function( target, className ) {
			var r = new RegExp('\\b' + className + '\\b');
			return r.test(target.className);
		},

		fetchVisiblePluses : function() {
			kint.visiblePluses = [];
			Array.prototype.slice.call(document.querySelectorAll('.kint-plus, .kint-tabs>li:not(.kint-active-tab)'), 0)
				.forEach(
				function( el ) {
					if ( el.offsetWidth !== 0 || el.offsetHeight !== 0 ) {
						kint.visiblePluses.push(el)
					}
				}
			);
		},

		keyCallBacks : {
			cleanup : function( i ) {
				var focusedClass = 'kint-focused';
				var prevElement = document.querySelector('.' + focusedClass);
				prevElement && kint.removeClass(prevElement, focusedClass);

				if ( i !== -1 ) {
					var el = kint.visiblePluses[i];
					kint.addClass(el, focusedClass);

					var offsetTop = function( el ) {
						return el.offsetTop + ( el.offsetParent ? offsetTop(el.offsetParent) : 0 );
					};

					var top = offsetTop(el) - (window.innerHeight / 2 );
					window.scrollTo(0, top);
				}

				kint.currentPlus = i;
			},

			moveCursor : function( up, i ) {
				// todo make the first VISIBLE plus active

				if ( up ) {
					if ( --i < 0 ) {
						i = kint.visiblePluses.length - 1;
					}
				} else {
					if ( ++i >= kint.visiblePluses.length ) {
						i = 0;
					}
				}

				kint.keyCallBacks.cleanup(i);
				return false;
			}
		}
	};

	window.addEventListener("click", function( e ) {
		var target = e.target;

		var nodeName = target.nodeName.toLowerCase();

		if ( nodeName === 'dfn' ) {
			kint.selectText(target);
			target = target.parentNode;
		} else if ( nodeName === 'var' ) { // stupid workaround for misc elements
			target = target.parentNode;    // to not stop event from further propagating
			nodeName = target.nodeName.toLowerCase()
		}

		if ( nodeName === 'li' && target.parentNode.className === 'kint-tabs' && target.className !== 'kint-active-tab' ) {
			kint.toggleTrace(target);
			return false;
		}

		if ( kint.hasClass(target, '_kint-collapse') ) {
			setTimeout(function() {
				var timer = parseInt(target.kintTimer, 10);
				if ( timer > 0 ) {
					target.kintTimer--;
				} else {
					kint.toggleChildren(target.parentNode); //

				}
			}, 300);
			e.stopPropagation();
			return false;
		} else if ( kint.hasClass(target, 'kint-parent') ) {
			kint.toggle(target);
			return false;
		} else if ( kint.hasClass(target, 'kint-ide-link') ) {
			e.preventDefault();
			var ajax = new XMLHttpRequest(); // add ajax call to contact editor but prevent link default action
			ajax.open('GET', target.href);
			ajax.send(null);
			return false;
		}
	}, false);

	window.addEventListener("dblclick", function( e ) {
		var target = e.target;
		if ( kint.hasClass(target, '_kint-collapse') ) {
			target.kintTimer = 2;
			kint.toggleAll(target);
			e.stopPropagation();
		}
	}, false);

	window.addEventListener("load", function( e ) {
		for ( var selector in kintExpandOnLoad ) {
			Array.prototype.slice.call(document.querySelectorAll('.' + selector + '>dl>dt'), 0)
				.forEach(
				function( el ) {
					kint.toggleChildren(el);
				}
			);
		}
	}, false);

	window.onkeydown = function( e ) {
		if ( e.altKey ) return;

		var keyCode = e.keyCode;
		var shiftKey = e.shiftKey;
		var i = kint.currentPlus;

		if ( keyCode === 68 ) { // 'd' : toggles navigation on/off
			if ( i === -1 ) {
				kint.fetchVisiblePluses();
				return kint.keyCallBacks.moveCursor(false, i);
			} else {
				kint.keyCallBacks.cleanup(-1);
				return false;
			}
		} else {
			if ( i === -1 ) return;

			if ( keyCode === 9 ) { // TAB : moves up/down depending on shift key
				return kint.keyCallBacks.moveCursor(shiftKey, i);
			} else if ( keyCode === 38 ) { // ARROW UP : moves up
				return kint.keyCallBacks.moveCursor(true, i);
			} else if ( keyCode === 40 ) { // ARROW DOWN : down
				return kint.keyCallBacks.moveCursor(false, i);
			} else {
				if ( i === -1 ) {
					return;
				}
			}
		}

		var kintNode = kint.visiblePluses[i];
		if ( kintNode.nodeName.toLowerCase() === 'li' ) { // we're on a trace tab
			if ( keyCode === 32 || keyCode === 13 ) { // SPACE/ENTER
				kint.toggleTrace(kintNode);
				return kint.keyCallBacks.moveCursor(true, i);
			} else if ( keyCode === 39 ) { // arrows
				return kint.keyCallBacks.moveCursor(false, i);
			} else if ( keyCode === 37 ) {
				return kint.keyCallBacks.moveCursor(true, i);
			}
		}

		kintNode = kintNode.parentNode; // simple dump
		if ( keyCode === 32 || keyCode === 13 ) { // SPACE/ENTER : toggles
			kint.toggle(kintNode);
			return false;
		} else if ( keyCode === 39 || keyCode === 37 ) { // ARROW LEFT/RIGHT : respectively hides/shows and traverses
			var visible = kint.next(kintNode).style.display === 'inline';
			var hide = keyCode === 37;

			if ( visible ) {
				kint.toggleChildren(kintNode, hide); // expand/collapse all children if immediate ones are showing
			} else {
				if ( hide ) { // LEFT
					// traverse to parent and THEN hide
					do {kintNode = kintNode.parentNode} while ( kintNode && kintNode.nodeName.toLowerCase() !== 'dd' );

					if ( kintNode ) {
						kintNode = kintNode.previousElementSibling;

						i = -1;
						var parentPlus = kintNode.querySelector('.kint-plus');
						while ( parentPlus !== kint.visiblePluses[++i] ) {}
						kint.keyCallBacks.cleanup(i)
					} else { // we are at root
						kintNode = kint.visiblePluses[i].parentNode;
					}
				}
				kint.toggle(kintNode, hide);
			}
			return false;
		}
	};
}

// debug purposes only, removed in minified source
function clg( i ) {
	if ( !window.console )return;
	var l = arguments.length, o = 0;
	while ( o < l )console.log(arguments[o++])
}
<|endoftext|>