<commit_before>function KzedProjection() {}
KzedProjection.prototype = {
		fromLatLngToPoint: function(latLng) {
			var x = (latLng.lng() * config.tileWidth)|0;
			var y = (latLng.lat() * config.tileHeight)|0;

			return new google.maps.Point(x, y);
		},
		fromPointToLatLng: function(point) {
			var lng = point.x / config.tileWidth;
			var lat = point.y / config.tileHeight;
			return new google.maps.LatLng(lat, lng);
		},
		fromWorldToLatLng: function(x, y, z)
		{
			var dx = +x;
			var dy = +y - 127;
			var dz = +z;
			var px = dx + dz;
			var py = dx - dz - dy;

			var lng = -px / config.tileWidth / 2 + 0.5;
			var lat = py / config.tileHeight / 2;

			return new google.maps.LatLng(lat, lng);
		}
};

function KzedMapType() {}
KzedMapType.prototype = {
	__proto__: new DynMapType(),
	constructor: KzedMapType,
	projection: new KzedProjection(),
	tileSize: new google.maps.Size(128, 128),
	minZoom: 0,
	maxZoom: 3,
	prefix: null,
	getTile: function(coord, zoom, doc) {
		var tileDebugText = null;
		var tileSize = 128;
		var tileName;
		var imgSize;
		var offset = {x: 0, y: 0};

		var debugred;
		var debugblue;

		if (zoom == 0) {
			// Most zoomed out tiles.

			tileSize = 128;
			imgSize = tileSize;
			tileName = 'z' + this.prefix + '_' + (-coord.x * tileSize*2) + '_' + (coord.y * tileSize*2);
		} else {
			// Other zoom levels.
			tileSize = 128;

			// Helper functions.
			var floor = Math.floor;
			var div = function(x,y){return floor(x/y);}
			var mod = function(x,y){return ((x%y)+y)%y;};

			// Split the image up in ... segments (1*1 for zoom 1, 2*2 for zoom 2, 4*4 for zoom 3, etc).
			var segments = Math.pow(2,zoom-1);
			imgSize = segments*tileSize;

			// Calculate the location relative to the world of this segment.
			var mapcoord = {x: div(coord.x,segments)*tileSize, y: div(coord.y,segments)*tileSize};
			// Calculate the location relative to the image of this segment.
			offset = {x: mod(coord.x,segments)*-tileSize, y: mod(coord.y,segments)*-tileSize};

			// The next couple of lines are somewhat of a hack, but makes it faster to render zoomed in tiles:
			/*tileSize = imgSize;

			if (offset.x == 0 && offset.y == 0) {
				tileName = this.prefix + '_' + (-mapcoord.x) + '_' + mapcoord.y;
			}
			offset = {x: 0, y: 0};*/
			// The next line is not:
			tileName = this.prefix + '_' + (-mapcoord.x) + '_' + mapcoord.y;
		}
		var img;
		var tile = $('<div/>')
			.addClass('tile')
			.css({
				overflow: 'hidden',
				width: tileSize + 'px',
				height: tileSize + 'px'
			});
		if (tileDebugText) {
			$('<span/>')
				.text(tileDebugText)
				.css({
					position: 'absolute',
					color: 'red'
				})
				.appendTo(tile);
		}
		if (tileName) {
			img = $('<img/>')
				.attr('src', this.dynmap.getTileUrl(tileName))
				.error(function() { img.hide(); })
				.css({
					width: imgSize + 'px',
					height: imgSize + 'px',
					borderStyle: 'none',
					marginLeft: offset.x + 'px',
					marginTop: offset.y + 'px'
				})
				.appendTo(tile);
			this.dynmap.registerTile(this, tileName, img);
		} else {
			this.dynmap.unregisterTile(this, tileName);
		}
		return tile.get(0);
	},
};

DefaultMapType.prototype = new KzedMapType();
DefaultMapType.prototype.constructor = DefaultMapType;
function DefaultMapType(){}
DefaultMapType.prototype.prefix = 't';

CaveMapType.prototype = new KzedMapType();
CaveMapType.prototype.constructor = CaveMapType;
function CaveMapType(){}
CaveMapType.prototype.prefix = 'ct';

<commit_msg>Better way of handling inheriting in javascript.<commit_after>function KzedProjection() {}
KzedProjection.prototype = {
		fromLatLngToPoint: function(latLng) {
			var x = (latLng.lng() * config.tileWidth)|0;
			var y = (latLng.lat() * config.tileHeight)|0;

			return new google.maps.Point(x, y);
		},
		fromPointToLatLng: function(point) {
			var lng = point.x / config.tileWidth;
			var lat = point.y / config.tileHeight;
			return new google.maps.LatLng(lat, lng);
		},
		fromWorldToLatLng: function(x, y, z)
		{
			var dx = +x;
			var dy = +y - 127;
			var dz = +z;
			var px = dx + dz;
			var py = dx - dz - dy;

			var lng = -px / config.tileWidth / 2 + 0.5;
			var lat = py / config.tileHeight / 2;

			return new google.maps.LatLng(lat, lng);
		}
};

function KzedMapType() {}
KzedMapType.prototype = $.extend(new DynMapType(), {
	constructor: KzedMapType,
	projection: new KzedProjection(),
	tileSize: new google.maps.Size(128, 128),
	minZoom: 0,
	maxZoom: 3,
	prefix: null,
	getTile: function(coord, zoom, doc) {
		var tileDebugText = null;
		var tileSize = 128;
		var tileName;
		var imgSize;
		var offset = {x: 0, y: 0};

		var debugred;
		var debugblue;

		if (zoom == 0) {
			// Most zoomed out tiles.

			tileSize = 128;
			imgSize = tileSize;
			tileName = 'z' + this.prefix + '_' + (-coord.x * tileSize*2) + '_' + (coord.y * tileSize*2);
		} else {
			// Other zoom levels.
			tileSize = 128;

			// Helper functions.
			var floor = Math.floor;
			var div = function(x,y){return floor(x/y);}
			var mod = function(x,y){return ((x%y)+y)%y;};

			// Split the image up in ... segments (1*1 for zoom 1, 2*2 for zoom 2, 4*4 for zoom 3, etc).
			var segments = Math.pow(2,zoom-1);
			imgSize = segments*tileSize;

			// Calculate the location relative to the world of this segment.
			var mapcoord = {x: div(coord.x,segments)*tileSize, y: div(coord.y,segments)*tileSize};
			// Calculate the location relative to the image of this segment.
			offset = {x: mod(coord.x,segments)*-tileSize, y: mod(coord.y,segments)*-tileSize};

			// The next couple of lines are somewhat of a hack, but makes it faster to render zoomed in tiles:
			/*tileSize = imgSize;

			if (offset.x == 0 && offset.y == 0) {
				tileName = this.prefix + '_' + (-mapcoord.x) + '_' + mapcoord.y;
			}
			offset = {x: 0, y: 0};*/
			// The next line is not:
			tileName = this.prefix + '_' + (-mapcoord.x) + '_' + mapcoord.y;
		}
		var img;
		var tile = $('<div/>')
			.addClass('tile')
			.css({
				overflow: 'hidden',
				width: tileSize + 'px',
				height: tileSize + 'px'
			});
		if (tileDebugText) {
			$('<span/>')
				.text(tileDebugText)
				.css({
					position: 'absolute',
					color: 'red'
				})
				.appendTo(tile);
		}
		if (tileName) {
			img = $('<img/>')
				.attr('src', this.dynmap.getTileUrl(tileName))
				.error(function() { img.hide(); })
				.css({
					width: imgSize + 'px',
					height: imgSize + 'px',
					borderStyle: 'none',
					marginLeft: offset.x + 'px',
					marginTop: offset.y + 'px'
				})
				.appendTo(tile);
			this.dynmap.registerTile(this, tileName, img);
		} else {
			this.dynmap.unregisterTile(this, tileName);
		}
		return tile.get(0);
	},
});

function DefaultMapType(){}
DefaultMapType.prototype = $.extend(new KzedMapType(), {
	prefix: 't'
});

function CaveMapType(){}
CaveMapType.prototype = $.extend(new KzedMapType(), {
	prefix: 'ct'
});

<|endoftext|>


<commit_before>/*! Featherbox 0.4 | github.com/adamaveray/featherbox | Adam Averay | MIT */
;(function($){
	var $window	= $(window),
		$body	= $('body');

	var Featherbox	= function(element, options){
		this.options	= $.extend({}, Featherbox.defaults, options);
		this.element	= element;
		this.$element	= $(element);

		this.create();
		if(this.options.autoShow){
			this.show();
		}
	};

	Featherbox.defaults	= {
		// Operation
		autoShow:	true,

		// Animation
		transitionOpenClass:	'__transitioning',
		transitionCloseClass:	'__transitioning',

		// Templating
		extraClass:		null,
		templateModal:	'

',
		templateClose:	'<button class="modal__close" type="button">Close</button>',
		selectorInsertContent:	'.modal',
		selectorInsertClose:	'.modal',

		// Operation
		selectorLoadElements:	'img,iframe'
	};

	$.extend(Featherbox.prototype, {
		options:	null,
		element:	null,

		$element:	null,
		$modal:		null,
		$close:		null,
		$templateModal:	null,
		$templateClose:	null,

		handlerClick:	null,
		handlerKeydown:	null,

		/**
		 * Builds the modal element (does not insert in document or display)
		 */
		create:	function(){
			var _this	= this;

			if(this.$modal){
				// Clean up existing
				this.close();
			}

			if(!this.$templateModal){
				this.$templateModal	= $($.parseHTML($.trim(this.options.templateModal)));
				this.$templateClose	= $($.parseHTML($.trim(this.options.templateClose)));

				if(this.options.extraClass !== null){
					this.$templateModal.addClass(this.options.extraClass);
				}
			}

			// Create modal
			this.$modal	= this.$templateModal.clone();
			this.$close	= this.$templateClose.clone();
			this.$modal.find(this.options.selectorInsertClose).append(this.$close);

			// Insert content
			this.$modal.find(this.options.selectorInsertContent).append(this.$element);

			// Monitor loading
			this._waitForLoad(this.$modal, this.options.selectorLoadElements, function(){
				_this._trigger('Load');
			});

			// Monitor close events
			window.setTimeout(function(){
				_this._closeOnClick();
				_this._closeOnEscape();
			}, 0);
		},

		/**
		 * Appends and shows the modal to the body, optionally transitioning in
		 *
		 * @param {bool} [animate=true]	Whether to trigger CSS classes for transitioning in
		 */
		show:	function(animate){
			(animate === undefined) && (animate = true);

			if(!this.$modal){
				// Nothing to show
				return;
			}

			var $modal	= this.$modal;
			var _this	= this;

			// Insert into page
			$modal
				.hide()
				.appendTo($body);

			var show	= function(){
				$modal.show();
				_this._trigger('OpenFinish');
			};
			this._trigger('Open');

			if(animate){
				// Animate in
				var className	= this.options.transitionOpenClass;

				$modal
					.addClass(className)
					.show();
				window.setTimeout(function(){
					$modal.removeClass(className);
					show();
				}, 0);
			} else {
				// No animation - display immediately
				show();
			}
		},

		/**
		 * Removes the modal from the document, optionally transitioning out before removal
		 *
		 * @param {bool} [animate=true]	Whether to trigger CSS classes for transitioning out
		 */
		close:	function(animate){
			(animate === undefined) && (animate = true);

			this._clearCloseOnClick();
			this._clearCloseOnEscape();

			if(!this.$modal){
				// Nothing to close
				return;
			}

			var $modal	= this.$modal;
			var _this	= this;

			this.$modal	= null;
			this.$close	= null;

			var remove	= function(){
				$modal.remove();
				_this._trigger('Close');
			};
			_this._trigger('CloseStart');

			if(animate){
				// Animate out
				var className	= this.options.transitionCloseClass;

				$modal.addClass(className);
				this._onTransitionEnd($modal, remove);
			} else {
				// No animation - remove immediately
				remove();
			}
		},

		/**
		 * Removes the modal from the document and clears any references to modal elements
		 */
		destroy:	function(){
			this._clearCloseOnClick();
			this._clearCloseOnEscape();

			this.$templateModal && this.$templateModal.remove();
			this.$templateClose && this.$templateClose.remove();

			this.$templateModal	= null;
			this.$templateClose	= null;

			this.$modal && this.$modal.remove();
			this.$modal	= null;
			this.$close	= null;

			this.element	= null;
			this.$element	= null;
		},

		/**
		 * Executes a function after CSS transitions have completed on the given modal element
		 *
		 * @param {$} $modal	The element to wait for transition end
		 * @param {Function} fn	A function to call after transitioning has completed
		 * @private
		 */
		_onTransitionEnd:		function($modal, fn){
			var event	= this._getTransitionEvent($modal[0]);
			if(!event){
				// No transition support
				fn();
				return;
			}

			$modal.one(event, function(){
				fn();
			});
		},
		/**
		 * Detects the transition-end event name for the current browser if supported
		 *
		 * @param {Element} element	A HTML element
		 * @return {string|null}	The transition-end event name, or null if not supported
		 * @private
		 */
		_getTransitionEvent:	function(element){
			var transitions = {
				'transition':		'transitionend',
				'OTransition':		'oTransitionEnd',
				'MozTransition':	'transitionend',
				'WebkitTransition':	'webkitTransitionEnd'
			};

			// Find supported event
			for(t in transitions){	if(!transitions.hasOwnProperty(t)){ continue; }
				if(element.style[t] !== undefined){
					return transitions[t];
				}
			}

			// Transition events not supported
			return null;
		},

		/**
		 * Triggers a jQuery event on the original content element
		 *
		 * @param {string} event	The name of the event (will be prefixed with 'featherbox')
		 * @param {Array} [params]	Additional custom params to pass to event listeners (`this` will be the prepended)
		 * @private
		 */
		_trigger:	function(event, params){
			event	= 'featherbox'+event;
			params	= params || [];

			params.unshift(this);

			this.$element.trigger(event, params);
		},

		/**
		 * Executes a function after all specified descendant elements have finished loading
		 *
		 * @param {$} $element			The jQuery element
		 * @param {string} selector		The selector for elements capable of triggering a 'load' event
		 * @param {Function} callback	A function to execute after all found elements have loaded
		 * @private
		 */
		_waitForLoad:		function($element, selector, callback){
			// Locate loadable elements
			var $loadable	= this.$modal.find(selector)
										 .add(this.$modal.filter(selector));	// Include container if loadable

			var total		= $loadable.length,
				progress	= 0;

			if(total === 0){
				// Nothing to load - trigger immediately
				window.setTimeout(function(){
					callback();
				}, 0);
			}

			$loadable.on('load', function(){
				progress++;

				if(progress >= total){
					// Loaded
					callback();
				}
			});
		},
		/**
		 * Sets up event handlers for dismissing the modal on overlay background or close button click
		 *
		 * @see _clearCloseOnClick
		 * @private
		 */
		_closeOnClick:		function(){
			var _this	= this;

			this._clearCloseOnClick();

			var handler	= function(e){
				if(!_this.$modal){
					// Nothing to show
					return;
				}

				if($.contains(_this.$modal[0], e.target)){
					// Clicking on modal
					if(e.target !== _this.$modal[0] && e.target !== _this.$close[0]){
						// Not clicking on background or close button - clicking on modal content - ignore click
						return;
					}
				}

				e.preventDefault();
				e.stopPropagation();

				_this.close();
			};
			this.handlerClick	= handler;

			$body.on('click', handler);
		},
		/**
		 * Clears handlers set by `_closeOnClick`
		 *
		 * @see _closeOnClick
		 * @private
		 */
		_clearCloseOnClick:	function(){
			if(!this.handlerClick){
				// Nothing to clear
				return;
			}

			var handler	= this.handlerClick;

			this.handlerClick	= null;

			$body.off('click', handler);
		},
		/**
		 * Sets up event handlers for dismissing the modal on escape key presses
		 *
		 * @see _clearCloseOnEscape
		 * @private
		 */
		_closeOnEscape:			function(){
			var keyCode	= 27;	// Escape key

			// Clear any existing handlers
			this._clearCloseOnEscape();

			var _this	= this;
			var handler	= function(e){
				if(e.keyCode === keyCode){
					_this.close();
				}
			};

			this.handlerKeydown	= handler;

			$window.on('keydown', handler);
		},
		/**
		 * Clears handlers set by `_closeOnEscape`
		 *
		 * @see _closeOnEscape
		 * @private
		 */
		_clearCloseOnEscape:	function(){
			if(!this.handlerKeydown){
				// Nothing to clear
				return;
			}

			var handler	= this.handlerKeydown;

			this.handlerKeydown	= null;

			$window.off('keydown', handler);
		}
	});

	$.featherbox		= Featherbox;
	$.fn.featherbox	= function(options){
		var modal	= new Featherbox(this, options);
		return $(this).data('featherbox', modal);
	};
}(jQuery));
<commit_msg>Made jQuery reference more explicit<commit_after>/*! Featherbox 0.4 | github.com/adamaveray/featherbox | Adam Averay | MIT */
;(function($){
	var $window	= $(window),
		$body	= $('body');

	var Featherbox	= function(element, options){
		this.options	= $.extend({}, Featherbox.defaults, options);
		this.element	= element;
		this.$element	= $(element);

		this.create();
		if(this.options.autoShow){
			this.show();
		}
	};

	Featherbox.defaults	= {
		// Operation
		autoShow:	true,

		// Animation
		transitionOpenClass:	'__transitioning',
		transitionCloseClass:	'__transitioning',

		// Templating
		extraClass:		null,
		templateModal:	'

',
		templateClose:	'<button class="modal__close" type="button">Close</button>',
		selectorInsertContent:	'.modal',
		selectorInsertClose:	'.modal',

		// Operation
		selectorLoadElements:	'img,iframe'
	};

	$.extend(Featherbox.prototype, {
		options:	null,
		element:	null,

		$element:	null,
		$modal:		null,
		$close:		null,
		$templateModal:	null,
		$templateClose:	null,

		handlerClick:	null,
		handlerKeydown:	null,

		/**
		 * Builds the modal element (does not insert in document or display)
		 */
		create:	function(){
			var _this	= this;

			if(this.$modal){
				// Clean up existing
				this.close();
			}

			if(!this.$templateModal){
				this.$templateModal	= $($.parseHTML($.trim(this.options.templateModal)));
				this.$templateClose	= $($.parseHTML($.trim(this.options.templateClose)));

				if(this.options.extraClass !== null){
					this.$templateModal.addClass(this.options.extraClass);
				}
			}

			// Create modal
			this.$modal	= this.$templateModal.clone();
			this.$close	= this.$templateClose.clone();
			this.$modal.find(this.options.selectorInsertClose).append(this.$close);

			// Insert content
			this.$modal.find(this.options.selectorInsertContent).append(this.$element);

			// Monitor loading
			this._waitForLoad(this.$modal, this.options.selectorLoadElements, function(){
				_this._trigger('Load');
			});

			// Monitor close events
			window.setTimeout(function(){
				_this._closeOnClick();
				_this._closeOnEscape();
			}, 0);
		},

		/**
		 * Appends and shows the modal to the body, optionally transitioning in
		 *
		 * @param {bool} [animate=true]	Whether to trigger CSS classes for transitioning in
		 */
		show:	function(animate){
			(animate === undefined) && (animate = true);

			if(!this.$modal){
				// Nothing to show
				return;
			}

			var $modal	= this.$modal;
			var _this	= this;

			// Insert into page
			$modal
				.hide()
				.appendTo($body);

			var show	= function(){
				$modal.show();
				_this._trigger('OpenFinish');
			};
			this._trigger('Open');

			if(animate){
				// Animate in
				var className	= this.options.transitionOpenClass;

				$modal
					.addClass(className)
					.show();
				window.setTimeout(function(){
					$modal.removeClass(className);
					show();
				}, 0);
			} else {
				// No animation - display immediately
				show();
			}
		},

		/**
		 * Removes the modal from the document, optionally transitioning out before removal
		 *
		 * @param {bool} [animate=true]	Whether to trigger CSS classes for transitioning out
		 */
		close:	function(animate){
			(animate === undefined) && (animate = true);

			this._clearCloseOnClick();
			this._clearCloseOnEscape();

			if(!this.$modal){
				// Nothing to close
				return;
			}

			var $modal	= this.$modal;
			var _this	= this;

			this.$modal	= null;
			this.$close	= null;

			var remove	= function(){
				$modal.remove();
				_this._trigger('Close');
			};
			_this._trigger('CloseStart');

			if(animate){
				// Animate out
				var className	= this.options.transitionCloseClass;

				$modal.addClass(className);
				this._onTransitionEnd($modal, remove);
			} else {
				// No animation - remove immediately
				remove();
			}
		},

		/**
		 * Removes the modal from the document and clears any references to modal elements
		 */
		destroy:	function(){
			this._clearCloseOnClick();
			this._clearCloseOnEscape();

			this.$templateModal && this.$templateModal.remove();
			this.$templateClose && this.$templateClose.remove();

			this.$templateModal	= null;
			this.$templateClose	= null;

			this.$modal && this.$modal.remove();
			this.$modal	= null;
			this.$close	= null;

			this.element	= null;
			this.$element	= null;
		},

		/**
		 * Executes a function after CSS transitions have completed on the given modal element
		 *
		 * @param {$} $modal	The element to wait for transition end
		 * @param {Function} fn	A function to call after transitioning has completed
		 * @private
		 */
		_onTransitionEnd:		function($modal, fn){
			var event	= this._getTransitionEvent($modal[0]);
			if(!event){
				// No transition support
				fn();
				return;
			}

			$modal.one(event, function(){
				fn();
			});
		},
		/**
		 * Detects the transition-end event name for the current browser if supported
		 *
		 * @param {Element} element	A HTML element
		 * @return {string|null}	The transition-end event name, or null if not supported
		 * @private
		 */
		_getTransitionEvent:	function(element){
			var transitions = {
				'transition':		'transitionend',
				'OTransition':		'oTransitionEnd',
				'MozTransition':	'transitionend',
				'WebkitTransition':	'webkitTransitionEnd'
			};

			// Find supported event
			for(t in transitions){	if(!transitions.hasOwnProperty(t)){ continue; }
				if(element.style[t] !== undefined){
					return transitions[t];
				}
			}

			// Transition events not supported
			return null;
		},

		/**
		 * Triggers a jQuery event on the original content element
		 *
		 * @param {string} event	The name of the event (will be prefixed with 'featherbox')
		 * @param {Array} [params]	Additional custom params to pass to event listeners (`this` will be the prepended)
		 * @private
		 */
		_trigger:	function(event, params){
			event	= 'featherbox'+event;
			params	= params || [];

			params.unshift(this);

			this.$element.trigger(event, params);
		},

		/**
		 * Executes a function after all specified descendant elements have finished loading
		 *
		 * @param {$} $element			The jQuery element
		 * @param {string} selector		The selector for elements capable of triggering a 'load' event
		 * @param {Function} callback	A function to execute after all found elements have loaded
		 * @private
		 */
		_waitForLoad:		function($element, selector, callback){
			// Locate loadable elements
			var $loadable	= this.$modal.find(selector)
										 .add(this.$modal.filter(selector));	// Include container if loadable

			var total		= $loadable.length,
				progress	= 0;

			if(total === 0){
				// Nothing to load - trigger immediately
				window.setTimeout(function(){
					callback();
				}, 0);
			}

			$loadable.on('load', function(){
				progress++;

				if(progress >= total){
					// Loaded
					callback();
				}
			});
		},
		/**
		 * Sets up event handlers for dismissing the modal on overlay background or close button click
		 *
		 * @see _clearCloseOnClick
		 * @private
		 */
		_closeOnClick:		function(){
			var _this	= this;

			this._clearCloseOnClick();

			var handler	= function(e){
				if(!_this.$modal){
					// Nothing to show
					return;
				}

				if($.contains(_this.$modal[0], e.target)){
					// Clicking on modal
					if(e.target !== _this.$modal[0] && e.target !== _this.$close[0]){
						// Not clicking on background or close button - clicking on modal content - ignore click
						return;
					}
				}

				e.preventDefault();
				e.stopPropagation();

				_this.close();
			};
			this.handlerClick	= handler;

			$body.on('click', handler);
		},
		/**
		 * Clears handlers set by `_closeOnClick`
		 *
		 * @see _closeOnClick
		 * @private
		 */
		_clearCloseOnClick:	function(){
			if(!this.handlerClick){
				// Nothing to clear
				return;
			}

			var handler	= this.handlerClick;

			this.handlerClick	= null;

			$body.off('click', handler);
		},
		/**
		 * Sets up event handlers for dismissing the modal on escape key presses
		 *
		 * @see _clearCloseOnEscape
		 * @private
		 */
		_closeOnEscape:			function(){
			var keyCode	= 27;	// Escape key

			// Clear any existing handlers
			this._clearCloseOnEscape();

			var _this	= this;
			var handler	= function(e){
				if(e.keyCode === keyCode){
					_this.close();
				}
			};

			this.handlerKeydown	= handler;

			$window.on('keydown', handler);
		},
		/**
		 * Clears handlers set by `_closeOnEscape`
		 *
		 * @see _closeOnEscape
		 * @private
		 */
		_clearCloseOnEscape:	function(){
			if(!this.handlerKeydown){
				// Nothing to clear
				return;
			}

			var handler	= this.handlerKeydown;

			this.handlerKeydown	= null;

			$window.off('keydown', handler);
		}
	});

	$.featherbox		= Featherbox;
	$.fn.featherbox	= function(options){
		var modal	= new Featherbox(this, options);
		return $(this).data('featherbox', modal);
	};
}(window.jQuery));
<|endoftext|>


<commit_before>/**
 * Brackets Themes Copyright (c) 2014 Miguel Castillo.
 *
 * Licensed under MIT
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global $, define, require, Mustache */

define(function(require, exports, module) {
    "use strict";

    var _                  = require("thirdparty/lodash"),
        Dialogs            = require("widgets/Dialogs"),
        Strings            = require("strings"),
        PreferencesManager = require("preferences/PreferencesManager");

    var prefs = PreferencesManager.getExtensionPrefs("brackets-themes");

    /**
     * Currently loaded themes that are available to choose from.
     */
    var loadedThemes = {};

    /**
     * Object with all default values that can be configure via the settings UI
     */
    var defaults = {
        "fontSize": 12,
        "lineHeight": '1.3em',
        "fontFamily": "'SourceCodePro-Medium', ＭＳ ゴシック, 'MS Gothic', monospace",
        "customScrollbars": true,
        "themes": ["thor-light-theme"]
    };

    var templates = {
        "settings": require("text!htmlContent/themes-settings.html")
    };

    /**
     * Cached html settings jQuery object for easier processing when opening the settings dialog
     */
    var $settings = $(templates.settings).addClass("themeSettings");

    /**
     * Opens the settings dialog
     */
    function showDialog() {
        var currentSettings = getValues();
        var newSettings     = {};
        var themes          = _.map(loadedThemes, function(theme) {return theme;});
        var template        = $("<div>").append($settings).html();
        var $template       = $(Mustache.render(template, {"settings": currentSettings, "themes": themes, "Strings": Strings}));

        // Select the correct theme.
        _.each(currentSettings.themes, function(item) {
            $template
                .find("[value='" + item + "']")
                .attr("selected", "selected");
        });

        $template
            .find("[data-toggle=tab].default")
            .tab("show");

        $template
            .on("change", "[data-target]:checkbox", function() {
                var $target = $(this);
                var attr = $target.attr("data-target");
                newSettings[attr] = $target.is(":checked");
            })
            .on("change", "[data-target]:text", function() {
                var $target = $(this);
                var attr = $target.attr("data-target");
                newSettings[attr] = $target.val();
            })
            .on("change", function() {
                var items;
                var $target = $(":selected", this);
                var attr = $target.attr("data-target");

                if (attr) {
                    items = $target.map(function(i, item) {
                        return $(item).val();
                    });

                    prefs.set(attr, items.toArray());
                }
            });

        Dialogs.showModalDialogUsingTemplate($template).done(function (id) {
            if (id === "save") {
                Object.keys(newSettings).forEach(function (setting) {
                    prefs.set(setting, newSettings[setting]);
                });
            }
        });
    }

    /**
     * Interface to set the themes that are available to chose from in the setting dialog
     * @param {ThemeManager.Theme} themes is a collection of themes created by the ThemeManager
     */
    function setThemes(themes) {
        loadedThemes = themes;
    }

    /**
     * @private
     * Gets all the configurable settings that need to be loaded in the settings dialog
     */
    function getValues() {
        return _.transform(defaults, function(result, value, key) {
            result[key] = prefs.get(key);
        });
    }

    /**
     * Restores themes to factory settings.
     */
    function restore() {
        prefs.set("themes", defaults.themes);
        prefs.set("fontSize", defaults.fontSize + "px");
        prefs.set("lineHeight", defaults.lineHeight);
        prefs.set("fontFamily", defaults.fontFamily);
        prefs.set("customScrollbars", defaults.customScrollbars);
    }

    prefs.definePreference("themes", "array", defaults.themes);
    prefs.definePreference("fontSize", "string", defaults.fontSize + "px");
    prefs.definePreference("lineHeight", "string", defaults.lineHeight);
    prefs.definePreference("fontFamily", "string", defaults.fontFamily);
    prefs.definePreference("customScrollbars", "boolean", defaults.customScrollbars);

    exports._setThemes = setThemes;
    exports._defaults  = defaults;
    exports.restore    = restore;
    exports.showDialog = showDialog;
});
<commit_msg>Moved around the settings template variable definition<commit_after>/**
 * Brackets Themes Copyright (c) 2014 Miguel Castillo.
 *
 * Licensed under MIT
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global $, define, require, Mustache */

define(function(require, exports, module) {
    "use strict";

    var _                  = require("thirdparty/lodash"),
        Dialogs            = require("widgets/Dialogs"),
        Strings            = require("strings"),
        PreferencesManager = require("preferences/PreferencesManager"),
        settingsTemplate   = require("text!htmlContent/themes-settings.html");

    var prefs = PreferencesManager.getExtensionPrefs("brackets-themes");

    /**
     * Currently loaded themes that are available to choose from.
     */
    var loadedThemes = {};

    /**
     * Object with all default values that can be configure via the settings UI
     */
    var defaults = {
        "fontSize": 12,
        "lineHeight": '1.3em',
        "fontFamily": "'SourceCodePro-Medium', ＭＳ ゴシック, 'MS Gothic', monospace",
        "customScrollbars": true,
        "themes": ["thor-light-theme"]
    };

    /**
     * Cached html settings jQuery object for easier processing when opening the settings dialog
     */
    var $settings = $(settingsTemplate).addClass("themeSettings");

    /**
     * Opens the settings dialog
     */
    function showDialog() {
        var currentSettings = getValues();
        var newSettings     = {};
        var themes          = _.map(loadedThemes, function(theme) {return theme;});
        var template        = $("<div>").append($settings).html();
        var $template       = $(Mustache.render(template, {"settings": currentSettings, "themes": themes, "Strings": Strings}));

        // Select the correct theme.
        _.each(currentSettings.themes, function(item) {
            $template
                .find("[value='" + item + "']")
                .attr("selected", "selected");
        });

        $template
            .find("[data-toggle=tab].default")
            .tab("show");

        $template
            .on("change", "[data-target]:checkbox", function() {
                var $target = $(this);
                var attr = $target.attr("data-target");
                newSettings[attr] = $target.is(":checked");
            })
            .on("change", "[data-target]:text", function() {
                var $target = $(this);
                var attr = $target.attr("data-target");
                newSettings[attr] = $target.val();
            })
            .on("change", function() {
                var items;
                var $target = $(":selected", this);
                var attr = $target.attr("data-target");

                if (attr) {
                    items = $target.map(function(i, item) {
                        return $(item).val();
                    });

                    prefs.set(attr, items.toArray());
                }
            });

        Dialogs.showModalDialogUsingTemplate($template).done(function (id) {
            if (id === "save") {
                Object.keys(newSettings).forEach(function (setting) {
                    prefs.set(setting, newSettings[setting]);
                });
            }
        });
    }

    /**
     * Interface to set the themes that are available to chose from in the setting dialog
     * @param {ThemeManager.Theme} themes is a collection of themes created by the ThemeManager
     */
    function setThemes(themes) {
        loadedThemes = themes;
    }

    /**
     * @private
     * Gets all the configurable settings that need to be loaded in the settings dialog
     */
    function getValues() {
        return _.transform(defaults, function(result, value, key) {
            result[key] = prefs.get(key);
        });
    }

    /**
     * Restores themes to factory settings.
     */
    function restore() {
        prefs.set("themes", defaults.themes);
        prefs.set("fontSize", defaults.fontSize + "px");
        prefs.set("lineHeight", defaults.lineHeight);
        prefs.set("fontFamily", defaults.fontFamily);
        prefs.set("customScrollbars", defaults.customScrollbars);
    }

    prefs.definePreference("themes", "array", defaults.themes);
    prefs.definePreference("fontSize", "string", defaults.fontSize + "px");
    prefs.definePreference("lineHeight", "string", defaults.lineHeight);
    prefs.definePreference("fontFamily", "string", defaults.fontFamily);
    prefs.definePreference("customScrollbars", "boolean", defaults.customScrollbars);

    exports._setThemes = setThemes;
    exports._defaults  = defaults;
    exports.restore    = restore;
    exports.showDialog = showDialog;
});
<|endoftext|>


<commit_before>// ==UserScript==
// @name SE Topbar Tools Meta/Main+Chat Links
// @description The links to meta (or main, as appropriate) and chat were rather popular; this brings them back.
// @namespace michaelb958
// @author michaelb958
// @license MIT (http://opensource.org/licenses/MIT)
// @include /^https?:\/\/.*(?:(?:stack(?:apps|exchange|overflow)|superuser|serverfault|askubuntu)\.com|mathoverflow\.net)\/.*/
// ==/UserScript==

function with_jQuery(f) {
  var s = document.createElement("script");
  s.type = "text/javascript";
  s.textContent = "(" + f.toString() + ")(jQuery)";
  s.setAttribute('data-with-jquery', '');
  document.head.appendChild(s);
};

with_jQuery(function($) {
  (window.StackExchangeTopbarToolsPluginInit
   = window.StackExchangeTopbarToolsPluginInit
   || []).push(function(SETT) {

    var meta = /^meta\./.test(location.host);
    SETT.links.prepend(location.host === 'stackapps.com' ? null : {
      id: 'main-meta-link',
      text: meta ? 'main' : 'meta',
      href: 'http://' + (meta ? location.hostname.substring(5)
                              : 'meta.' + location.hostname),
    }, {
      id: 'chat-link',
      text: 'chat',
      href: 'http://chat.' + (/stackoverflow\.com$/.test(location.host)
                              ? location.host : 'stackexchange.com'),
    });

  });
  if (typeof window.StackExchangeTopbarTools === 'object')
    window.StackExchangeTopbarTools.pluginsReady();
});
<commit_msg>Area 51 Discuss is a meta<commit_after>// ==UserScript==
// @name SE Topbar Tools Meta/Main+Chat Links
// @description The links to meta (or main, as appropriate) and chat were rather popular; this brings them back.
// @namespace michaelb958
// @author michaelb958
// @license MIT (http://opensource.org/licenses/MIT)
// @include /^https?:\/\/.*(?:(?:stack(?:apps|exchange|overflow)|superuser|serverfault|askubuntu)\.com|mathoverflow\.net)\/.*/
// ==/UserScript==

function with_jQuery(f) {
  var s = document.createElement("script");
  s.type = "text/javascript";
  s.textContent = "(" + f.toString() + ")(jQuery)";
  s.setAttribute('data-with-jquery', '');
  document.head.appendChild(s);
};

with_jQuery(function($) {
  (window.StackExchangeTopbarToolsPluginInit
   = window.StackExchangeTopbarToolsPluginInit
   || []).push(function(SETT) {

    var a51 = /^(discuss\.)?area51/.test(location.host),
        meta = /^(?:discuss|meta)\./.test(location.host);
    var mainMetaHost = meta
                     ? location.hostname.substring(a51 ? 8 : 5)
                     : (a51 ? 'discuss.' : 'meta.') + location.hostname;
    SETT.links.prepend(location.host === 'stackapps.com' ? null : {
      id: 'main-meta-link',
      text: meta ? 'main' : a51 ? 'discuss' : 'meta',
      href: 'http://' + mainMetaHost
    }, {
      id: 'chat-link',
      text: 'chat',
      href: 'http://chat.' + (/stackoverflow\.com$/.test(location.host)
                              ? location.host : 'stackexchange.com')
    });

  });
  if (typeof window.StackExchangeTopbarTools === 'object')
    window.StackExchangeTopbarTools.pluginsReady();
});
<|endoftext|>


<commit_before>let Promise       = require('bluebird')
let child_process = require('child_process')

let redisRepository       = require('../Repositories/RedisRepository')
let projectRepoisitory    = require('../Repositories/ProjectRepository')
let projectTypeRepository = require('../Repositories/ProjectTypeRepository')
let dataRepository        = require('../Repositories/DataRepository')

let simulationService = require('./SimulationService')
let fileService       = require('./FileService')
let errorMsgService   = require('./ErrorMsgService')

let config = require('../../config/config').dev.cuda

let compare = function (a, b) {
  return a.name.localeCompare(b.name)
}

let simulation = function (id, path, data, method) {
  simulationService.makeFile(path).then(() => {
    return simulationService.simulation(path, data)
  }).then(() => {
    handleSimulationData(id, path, method)
  }).catch(error => {
    //console.log(error)
  })
}

let handleSimulationData = function (id, path, method) {
  let configPath = '../.' + path + 'config'
  let config = require(configPath).config.simulationOutPutFileName

  let filesName  = ['baseSpin', 'bonusSpin', 'overallSpin', 'survivalRate']
  let tablesName = ['basegame', 'freegame', 'overall', 'survivalrate']

  for (let index in filesName) {
    if (config[filesName[index]] !== undefined && config[filesName[index]] !== null) {
      if (filesName[index] !== 'survivalRate') {
        dataRepository.uploadData(id, tablesName[index], path + 'result/' + config[filesName[index]] + csv, 'netWin' + ((filesName[index] === 'overallSpin') ? ',triger' : ''))
      } else {
        dataRepository.uploadData(id, tablesName[index], path + 'result/' + config[filesName[index]] + csv, 'id,hand,isSurvival')
      }
    }
  }
  for (let othersInfo of config.othersInfo) {
    let data = {
      name: othersInfo.infoName,
      data: path + 'result/' + othersInfo.fileName
    }
    if (method === 'insert') {
      dataRepository.insertData(id, 'others', data)
    } else if (method === 'update') {
      dataRepository.updateData(id, 'others', data)
    }
  }
}

// get all project
let getAllProject = function (token) {
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      return projectRepoisitory.getAllProject(accountId)
    }).then(allProject => {
      resolve(allProject)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

//get spectify project
let getProjectById = function (token, id) {
  return new Promise((resolve, reject) => {
    let data = {}
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      return projectRepoisitory.getProjectById(id)
    }).then(projectInfo => {
      resolve(projectInfo)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'file error') {
        reject(errorMsgService.fsError)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

//get all type of project
let getAllProjectType = function (token) {
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      return projectTypeRepository.getAllType()
    }).then(type => {
      resolve(type)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

// get spectify type of project
let getProjectTypeById = function (token, id) {
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      return projectTypeRepository.getTypeById(id)
    }).then(type => {
      resolve(type)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'Project type error') {
        reject(errorMsgService.noProjectType)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

let dataSet  = ['name', 'block', 'thread', 'runTime', 'reels', 'rows', 'betCost']
let fileName = ['symbol', 'stops', 'payTable', 'attr', 'pattern']

let csv    = '.csv'
let folder = './userProject/'

// create a new project
let create = function (token, body) {
  let userId
  let data
  let id
  let path
  let fields
  let files
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      userId = accountId
      data = {
        userId: userId
      }

      return fileService.processFormData(body)
    }).then(result => {
      fields = result.fields
      files  = result.files

      for (let i of dataSet) {
        if (fields[i] === undefined) {
          reject(errorMsgService.emptyInput)
          return
        } else {
          data[i] = fields[i]
        }
      }

      for (let i of fileName) {
        data[i] = './'
      }

      data.config    = './'
      data.gameLogic = './'

      return projectRepoisitory.createProject(data)
    }).then(() => {
      return projectRepoisitory.getNewestProject(userId)
    }).then(projectInfo => {
      id = projectInfo.id
      path = folder + userId + '/' + id + '/'
      return fileService.createFolder(path)
    }).then(() => {
      return fileService.createFolder(path + 'result')
    }).then(() => {
      let promise = []
      for (let i of fileName) {
        if (files[i] !== undefined) {
          if (!Array.isArray(files[i])) {
            data[i] = path + i + csv
            promise.push(fileService.moveFile(files[i].path, data[i]))
            if (i === 'payTable' && Array.isArray(files['stops'])) {
              data[i] = (data[i] + ',').repeat(files['stops'].length)
              data[i] = data[i].slice(0, -1)
            }
          } else {
            data[i] = ''
            files[i].sort(compare)
            for (let j in files[i]) {
              let filePath = path + i + j + csv
              data[i] += filePath + ','
              promise.push(fileService.moveFile(files[i][j].path, filePath))
            }
            data[i] = data[i].slice(0, -1)
          }
        }
      }

      if (files.config !== undefined) {
        data.config = path + 'config.js'
        promise.push(fileService.moveFile(files.config.path, data.config))
      }
      if (files.gameLogic !== undefined && files.gameLogic.length === 2) {
        files.gameLogic.sort(compare)
        data.gameLogic = path + 'SlotFunctions.cu,header.h'
        promise.push(fileService.moveFile(files.gameLogic[0].path, path + 'Header.h'))
        promise.push(fileService.moveFile(files.gameLogic[1].path, path + 'SlotFunctions.cu'))
      }

      let inputFile = ',' + (files['symbol'] !== undefined ? data['symbol'] : '') + '\n'
      for (let i of ['reels', 'rows', 'betCost']) {
        inputFile += ',' + data[i] + '\n'
      }
      for (let i of ['stops', 'payTable', 'attr', 'pattern']) {
        if (files[i] !== undefined) {
          inputFile += ',' + data[i] + '\n'
        }
      }

      promise.push(fileService.createFile(path + 'input.csv', inputFile))
      promise.push(projectRepoisitory.updateProject(id, data))

      return Promise.all(promise)
    }).then(() => {
      return child_process.exec('chmod -R 777 ' + path)
    }).then(() => {
      let promise = []
      for (let i of fileName) {
        if (Array.isArray(files[i])) {
          for (let j in files[i]) {
            let filePath = path + i + j + csv
            let cmd = "tr -d '\\r' < " + filePath + ' > ' + filePath
            promise.push(child_process.exec(cmd))
          }
        } else {
          let filePath = path + i + csv
          let cmd = "tr -d '\\r' < " + filePath + ' > ' + filePath
          promise.push(child_process.exec(cmd))
        }
      }
      return Promise.all(promise)
    }).then(() => {
      simulation(id, path, data, 'insert')
      resolve()
    }).catch(error => {
      console.log(error)
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'Project type error') {
        reject(errorMsgService.noProjectType)
      } else if (error === 'file error') {
        reject(errorMsgService.fsError)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

// update project
let update = function (token, id, body) {
  let data
  let userId
  let path
  let fields
  let files
  let oldData
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      userId = accountId
      path   = folder + userId + '/' + id + '/'

      data = {
        userId: userId
      }
      return projectRepoisitory.getProjectById(id)
    }).then(data => {
      oldData = data
      return fileService.processFormData(body)
    }).then(result => {
      fields = result.fields
      files = result.files

      for (let i of dataSet) {
        if (fields[i] !== undefined) {
          data[i] = fields[i]
        }
      }

      let promise = []

      for (let i of fileName) {
        if (files[i] !== undefined) {
          if (!Array.isArray(files[i])) {
            data[i] = path + i + csv
            promise.push(fileService.moveFile(files[i].path, data[i]))
            if (i === 'payTable' && Array.isArray(files['stops'])) {
              data[i] = (data[i] + ',').repeat(files['stops'].length)
              data[i] = data[i].slice(0, -1)
            }
          } else {
            data[i] = ''
            files[i].sort(compare)
            for (let j in files[i]) {
              let filePath = path + i + j + csv
              data[i] += filePath + ','
              promise.push(fileService.moveFile(files[i][j].path, filePath))
            }
            data[i] = data[i].slice(0, -1)
          }

        }
      }

      if (files.config !== undefined) {
        data.config = path + 'config.js'
        promise.push(fileService.moveFile(files.config.path, data.config))
      }
      if (files.gameLogic !== undefined && files.gameLogic.length === 2) {
        files.gameLogic.sort(compare)
        data.gameLogic = path + 'SlotFunctions.cu,header.h'
        promise.push(fileService.moveFile(files.gameLogic[0].path, path + 'Header.h'))
        promise.push(fileService.moveFile(files.gameLogic[1].path, path + 'SlotFunctions.cu'))
      }

      let inputFile = ''
      for (let i of ['symbol', 'reels', 'rows', 'betCost', 'stops', 'payTable', 'attr', 'pattern']) {
        inputFile += ',' + (data[i] !== undefined ? data[i] : oldData[i]) + '\n'
      }

      promise.push(fileService.createFile(path + 'input.csv', inputFile))
      promise.push(projectRepoisitory.updateProject(id, data))

      return Promise.all(promise)
    }).then(() => {
      return child_process.exec('chmod -R 777 ' + path)
    }).then(() => {
      let promise = []
      for (let i of fileName) {
        if (Array.isArray(files[i])) {
          for (let j in files[i]) {
            let filePath = path + i + j + csv
            let cmd = "tr -d '\\r' < " + filePath + ' > ' + filePath
            console.log(cmd)
            promise.push(child_process.exec(cmd))
          }
        } else {
          let filePath = path + i + csv
          let cmd = "tr -d '\\r' < " + filePath + ' > ' + filePath
          console.log(cmd)
          promise.push(child_process.exec(cmd))
        }
      }
      return Promise.all(promise)
    }).then(() => {
      simulation(id, path, data, 'update')
      resolve()
    }).catch(error => {
      console.log(error)
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'file error') {
        reject(errorMsgService.fsError)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

//delete project
let deleteProject = function (token, id) {
  let userId
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      userId = accountId
      return projectRepoisitory.deleteProject(id)
    }).then(() => {
      return fileService.deleteFolder(folder + userId + '/' + id)
    }).then(() => {
      resolve()
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'file error') {
        reject(errorMsgService.fsError)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

let getConfig = function (token, id) {
  let userId
  return new Promise((resolve, reject) => {
    redisRepository.getAccountId(token).then(accountId => {
      let path = '../../userProject/' + accountId + '/' + id + '/config'
      let config = require(path)
      resolve(config.config)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

module.exports = {
  getAllProject:      getAllProject,
  getProjectById:     getProjectById,
  getAllProjectType:  getAllProjectType,
  getProjectTypeById: getProjectTypeById,
  create:             create,
  update:             update,
  deleteProject:      deleteProject,
  getConfig:          getConfig
}<commit_msg>test tr<commit_after>let Promise       = require('bluebird')
let child_process = require('child-process-promise')

let redisRepository       = require('../Repositories/RedisRepository')
let projectRepoisitory    = require('../Repositories/ProjectRepository')
let projectTypeRepository = require('../Repositories/ProjectTypeRepository')
let dataRepository        = require('../Repositories/DataRepository')

let simulationService = require('./SimulationService')
let fileService       = require('./FileService')
let errorMsgService   = require('./ErrorMsgService')

let config = require('../../config/config').dev.cuda

let compare = function (a, b) {
  return a.name.localeCompare(b.name)
}

let simulation = function (id, path, data, method) {
  simulationService.makeFile(path).then(() => {
    return simulationService.simulation(path, data)
  }).then(() => {
    handleSimulationData(id, path, method)
  }).catch(error => {
    //console.log(error)
  })
}

let handleSimulationData = function (id, path, method) {
  let configPath = '../.' + path + 'config'
  let config = require(configPath).config.simulationOutPutFileName

  let filesName  = ['baseSpin', 'bonusSpin', 'overallSpin', 'survivalRate']
  let tablesName = ['basegame', 'freegame', 'overall', 'survivalrate']

  for (let index in filesName) {
    if (config[filesName[index]] !== undefined && config[filesName[index]] !== null) {
      if (filesName[index] !== 'survivalRate') {
        dataRepository.uploadData(id, tablesName[index], path + 'result/' + config[filesName[index]] + csv, 'netWin' + ((filesName[index] === 'overallSpin') ? ',triger' : ''))
      } else {
        dataRepository.uploadData(id, tablesName[index], path + 'result/' + config[filesName[index]] + csv, 'id,hand,isSurvival')
      }
    }
  }
  for (let othersInfo of config.othersInfo) {
    let data = {
      name: othersInfo.infoName,
      data: path + 'result/' + othersInfo.fileName
    }
    if (method === 'insert') {
      dataRepository.insertData(id, 'others', data)
    } else if (method === 'update') {
      dataRepository.updateData(id, 'others', data)
    }
  }
}

// get all project
let getAllProject = function (token) {
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      return projectRepoisitory.getAllProject(accountId)
    }).then(allProject => {
      resolve(allProject)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

//get spectify project
let getProjectById = function (token, id) {
  return new Promise((resolve, reject) => {
    let data = {}
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      return projectRepoisitory.getProjectById(id)
    }).then(projectInfo => {
      resolve(projectInfo)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'file error') {
        reject(errorMsgService.fsError)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

//get all type of project
let getAllProjectType = function (token) {
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      return projectTypeRepository.getAllType()
    }).then(type => {
      resolve(type)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

// get spectify type of project
let getProjectTypeById = function (token, id) {
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      return projectTypeRepository.getTypeById(id)
    }).then(type => {
      resolve(type)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'Project type error') {
        reject(errorMsgService.noProjectType)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

let dataSet  = ['name', 'block', 'thread', 'runTime', 'reels', 'rows', 'betCost']
let fileName = ['symbol', 'stops', 'payTable', 'attr', 'pattern']

let csv    = '.csv'
let folder = './userProject/'

// create a new project
let create = function (token, body) {
  let userId
  let data
  let id
  let path
  let fields
  let files
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      userId = accountId
      data = {
        userId: userId
      }

      return fileService.processFormData(body)
    }).then(result => {
      fields = result.fields
      files  = result.files

      for (let i of dataSet) {
        if (fields[i] === undefined) {
          reject(errorMsgService.emptyInput)
          return
        } else {
          data[i] = fields[i]
        }
      }

      for (let i of fileName) {
        data[i] = './'
      }

      data.config    = './'
      data.gameLogic = './'

      return projectRepoisitory.createProject(data)
    }).then(() => {
      return projectRepoisitory.getNewestProject(userId)
    }).then(projectInfo => {
      id = projectInfo.id
      path = folder + userId + '/' + id + '/'
      return fileService.createFolder(path)
    }).then(() => {
      return fileService.createFolder(path + 'result')
    }).then(() => {
      let promise = []
      for (let i of fileName) {
        if (files[i] !== undefined) {
          if (!Array.isArray(files[i])) {
            data[i] = path + i + csv
            promise.push(fileService.moveFile(files[i].path, data[i]))
            if (i === 'payTable' && Array.isArray(files['stops'])) {
              data[i] = (data[i] + ',').repeat(files['stops'].length)
              data[i] = data[i].slice(0, -1)
            }
          } else {
            data[i] = ''
            files[i].sort(compare)
            for (let j in files[i]) {
              let filePath = path + i + j + csv
              data[i] += filePath + ','
              promise.push(fileService.moveFile(files[i][j].path, filePath))
            }
            data[i] = data[i].slice(0, -1)
          }
        }
      }

      if (files.config !== undefined) {
        data.config = path + 'config.js'
        promise.push(fileService.moveFile(files.config.path, data.config))
      }
      if (files.gameLogic !== undefined && files.gameLogic.length === 2) {
        files.gameLogic.sort(compare)
        data.gameLogic = path + 'SlotFunctions.cu,header.h'
        promise.push(fileService.moveFile(files.gameLogic[0].path, path + 'Header.h'))
        promise.push(fileService.moveFile(files.gameLogic[1].path, path + 'SlotFunctions.cu'))
      }

      let inputFile = ',' + (files['symbol'] !== undefined ? data['symbol'] : '') + '\n'
      for (let i of ['reels', 'rows', 'betCost']) {
        inputFile += ',' + data[i] + '\n'
      }
      for (let i of ['stops', 'payTable', 'attr', 'pattern']) {
        if (files[i] !== undefined) {
          inputFile += ',' + data[i] + '\n'
        }
      }

      promise.push(fileService.createFile(path + 'input.csv', inputFile))
      promise.push(projectRepoisitory.updateProject(id, data))

      return Promise.all(promise)
    }).then(() => {
      return child_process.exec('chmod -R 777 ' + path)
    }).then(() => {
      let promise = []
      for (let i of fileName) {
        if (Array.isArray(files[i])) {
          for (let j in files[i]) {
            let filePath = path + i + j + csv
            let cmd = "tr -d '\\r' < " + filePath + ' > ' + filePath
            promise.push(child_process.exec(cmd))
          }
        } else {
          let filePath = path + i + csv
          let cmd = "tr -d '\\r' < " + filePath + ' > ' + filePath
          promise.push(child_process.exec(cmd))
        }
      }
      return Promise.all(promise)
    }).then(() => {
      simulation(id, path, data, 'insert')
      resolve()
    }).catch(error => {
      console.log(error)
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'Project type error') {
        reject(errorMsgService.noProjectType)
      } else if (error === 'file error') {
        reject(errorMsgService.fsError)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

// update project
let update = function (token, id, body) {
  let data
  let userId
  let path
  let fields
  let files
  let oldData
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      userId = accountId
      path   = folder + userId + '/' + id + '/'

      data = {
        userId: userId
      }
      return projectRepoisitory.getProjectById(id)
    }).then(data => {
      oldData = data
      return fileService.processFormData(body)
    }).then(result => {
      fields = result.fields
      files = result.files

      for (let i of dataSet) {
        if (fields[i] !== undefined) {
          data[i] = fields[i]
        }
      }

      let promise = []

      for (let i of fileName) {
        if (files[i] !== undefined) {
          if (!Array.isArray(files[i])) {
            data[i] = path + i + csv
            promise.push(fileService.moveFile(files[i].path, data[i]))
            if (i === 'payTable' && Array.isArray(files['stops'])) {
              data[i] = (data[i] + ',').repeat(files['stops'].length)
              data[i] = data[i].slice(0, -1)
            }
          } else {
            data[i] = ''
            files[i].sort(compare)
            for (let j in files[i]) {
              let filePath = path + i + j + csv
              data[i] += filePath + ','
              promise.push(fileService.moveFile(files[i][j].path, filePath))
            }
            data[i] = data[i].slice(0, -1)
          }

        }
      }

      if (files.config !== undefined) {
        data.config = path + 'config.js'
        promise.push(fileService.moveFile(files.config.path, data.config))
      }
      if (files.gameLogic !== undefined && files.gameLogic.length === 2) {
        files.gameLogic.sort(compare)
        data.gameLogic = path + 'SlotFunctions.cu,header.h'
        promise.push(fileService.moveFile(files.gameLogic[0].path, path + 'Header.h'))
        promise.push(fileService.moveFile(files.gameLogic[1].path, path + 'SlotFunctions.cu'))
      }

      let inputFile = ''
      for (let i of ['symbol', 'reels', 'rows', 'betCost', 'stops', 'payTable', 'attr', 'pattern']) {
        inputFile += ',' + (data[i] !== undefined ? data[i] : oldData[i]) + '\n'
      }

      promise.push(fileService.createFile(path + 'input.csv', inputFile))
      promise.push(projectRepoisitory.updateProject(id, data))

      return Promise.all(promise)
    }).then(() => {
      return child_process.exec('chmod -R 777 ' + path)
    }).then(() => {
      let promise = []
      for (let i of fileName) {
        if (Array.isArray(files[i])) {
          for (let j in files[i]) {
            let filePath = path + i + j + csv
            let cmd = "tr -d '\\r' < " + filePath + ' > ' + filePath
            console.log(cmd)
            promise.push(child_process.exec(cmd))
          }
        } else {
          let filePath = path + i + csv
          let cmd = "tr -d '\\r' < " + filePath + ' > ' + filePath
          console.log(cmd)
          promise.push(child_process.exec(cmd))
        }
      }
      return Promise.all(promise)
    }).then(() => {
      simulation(id, path, data, 'update')
      resolve()
    }).catch(error => {
      console.log(error)
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'file error') {
        reject(errorMsgService.fsError)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

//delete project
let deleteProject = function (token, id) {
  let userId
  return new Promise((resolve, reject) => {
    // check if the token is valid
    redisRepository.getAccountId(token).then(accountId => {
      userId = accountId
      return projectRepoisitory.deleteProject(id)
    }).then(() => {
      return fileService.deleteFolder(folder + userId + '/' + id)
    }).then(() => {
      resolve()
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else if (error === 'file error') {
        reject(errorMsgService.fsError)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

let getConfig = function (token, id) {
  let userId
  return new Promise((resolve, reject) => {
    redisRepository.getAccountId(token).then(accountId => {
      let path = '../../userProject/' + accountId + '/' + id + '/config'
      let config = require(path)
      resolve(config.config)
    }).catch(error => {
      if (error === 'token expired') {
        reject(errorMsgService.tokenExpired)
      } else {
        reject(errorMsgService.serverError)
      }
    })
  })
}

module.exports = {
  getAllProject:      getAllProject,
  getProjectById:     getProjectById,
  getAllProjectType:  getAllProjectType,
  getProjectTypeById: getProjectTypeById,
  create:             create,
  update:             update,
  deleteProject:      deleteProject,
  getConfig:          getConfig
}<|endoftext|>


<commit_before>
$("a[href^='#']").on('click', function(e) {
    e.preventDefault();
    var hash = this.hash;
    if (hash != '' && hash.indexOf('Modal') < 0) {
	$('html, body').animate({
	    scrollTop: $(hash).offset().top
	}, 300, function(){
	    window.location.hash = hash;
	});
    }
});

$(document).ready(function() {
    $('[data-toggle="popover"]').popover();

    $(".link-details a[href^='#']").hide();
    $(".link-stars a[href^='#']").hover(function(e) {
	$(".link-details a[href^='#']").hide();
	$(".link-details a[href=" + $(this).attr('href') + "]").show();
    });

    $('.link-stars-side a .name').hide();
    $('.link-stars-side a .btn').hover(function() {
	$('.link-stars-side a .name').hide();
	$(this).parent().find('.name').show();
    }, function() {
	$(this).parent().find('.name').hide();
    });

    $('.mainhome').css('min-height', $(window).height() - $('.navbar-Smile').height());
    $('.home-section').css('min-height', $(window).height());

    $('.link-stars-side').hide();
    $(window).scroll(
	function () {
	    if (($(window).scrollTop() + $(window).height())
		>= $("#home").height() + $('.bg-Rainbow-1').height() + $('.navbar-Smile').height()
		&& ($(window).scrollTop() + $(window).height())
		<= $("#home").height() + $('.navbar-Smile').height() + $('#links').height() + 100) {
		$('.link-stars-side').show();
	    } else {
		$('.link-stars-side').hide();
	    }
	    if ($('#activities .activities').html() == ''
		&& ($(window).scrollTop() + $(window).height())
		>= $("#home").height() + $('.navbar-Smile').height() + $('#links').height()) {
		$('#activities .activities').text('Loading...');
		$.get('/ajax/activities/', function(data) {
		    $('#activities .activities').html(data);
		    loadMoreActivities($('#activities .activities'), undefined, true, 1);
		});
		if ($('#myactivities').length > 0) {
		    $('#myactivities .activities').text('Loading...');
		    $.get('/ajax/feed/', function(data) {
			$('#myactivities .activities').html(data);
			loadMoreActivities($('#myactivities .activities'), undefined, true, 1);
		    });
		}
	    }
	    if (($(window).scrollTop() + $(window).height())
		>= $(".mainhome").height() - $('.mainhome .events').height() + $('.navbar-Smile').height() && !$('.mainhome .events').hasClass('loaded')) {
		$('.mainhome .events').addClass('loaded');
		$.getJSON('http://schoolido.lu/contest/json/current', function(data) {
		    if (data['current'] == true) {
			var event = $('.mainhome .events .event').first();
			event.css('background-image', 'url(\'/static/currentcontest.png\')');
			event.find('span').text(data['name']);
			event.find('small').text(data['begin'] + ' ' + data['end']);
			event.attr('href', '/contest/contest');
		    }
		});
	    }
	});
    $('.navbar-fixed-top').on('activate.bs.scrollspy', function () {
	var currentItem = $(".nav li.active > a").attr('href');
	if (currentItem == '#page-top') {
	    $('.navbar-fixed-top').fadeOut();
	} else {
	    $('.navbar-fixed-top').fadeIn();
	}
    })
});
<commit_msg>bugfix: LoadMore link of global activites loads following activities<commit_after>
$("a[href^='#']").on('click', function(e) {
    e.preventDefault();
    var hash = this.hash;
    if (hash != '' && hash.indexOf('Modal') < 0) {
	$('html, body').animate({
	    scrollTop: $(hash).offset().top
	}, 300, function(){
	    window.location.hash = hash;
	});
    }
});

$(document).ready(function() {
    $('[data-toggle="popover"]').popover();

    $(".link-details a[href^='#']").hide();
    $(".link-stars a[href^='#']").hover(function(e) {
	$(".link-details a[href^='#']").hide();
	$(".link-details a[href=" + $(this).attr('href') + "]").show();
    });

    $('.link-stars-side a .name').hide();
    $('.link-stars-side a .btn').hover(function() {
	$('.link-stars-side a .name').hide();
	$(this).parent().find('.name').show();
    }, function() {
	$(this).parent().find('.name').hide();
    });

    $('.mainhome').css('min-height', $(window).height() - $('.navbar-Smile').height());
    $('.home-section').css('min-height', $(window).height());

    $('.link-stars-side').hide();
    $(window).scroll(
	function () {
	    if (($(window).scrollTop() + $(window).height())
		>= $("#home").height() + $('.bg-Rainbow-1').height() + $('.navbar-Smile').height()
		&& ($(window).scrollTop() + $(window).height())
		<= $("#home").height() + $('.navbar-Smile').height() + $('#links').height() + 100) {
		$('.link-stars-side').show();
	    } else {
		$('.link-stars-side').hide();
	    }
	    if ($('#activities .activities').html() == ''
		&& ($(window).scrollTop() + $(window).height())
		>= $("#home").height() + $('.navbar-Smile').height() + $('#links').height()) {
		$('#activities .activities').text('Loading...');
		$.get('/ajax/activities/', function(data) {
		    $('#activities .activities').html(data);
		    loadMoreActivities($('#activities .activities'), undefined, undefined , undefined);
		});
		if ($('#myactivities').length > 0) {
		    $('#myactivities .activities').text('Loading...');
		    $.get('/ajax/feed/', function(data) {
			$('#myactivities .activities').html(data);
			loadMoreActivities($('#myactivities .activities'), undefined, true, 1);
		    });
		}
	    }
	    if (($(window).scrollTop() + $(window).height())
		>= $(".mainhome").height() - $('.mainhome .events').height() + $('.navbar-Smile').height() && !$('.mainhome .events').hasClass('loaded')) {
		$('.mainhome .events').addClass('loaded');
		$.getJSON('http://schoolido.lu/contest/json/current', function(data) {
		    if (data['current'] == true) {
			var event = $('.mainhome .events .event').first();
			event.css('background-image', 'url(\'/static/currentcontest.png\')');
			event.find('span').text(data['name']);
			event.find('small').text(data['begin'] + ' ' + data['end']);
			event.attr('href', '/contest/contest');
		    }
		});
	    }
	});
    $('.navbar-fixed-top').on('activate.bs.scrollspy', function () {
	var currentItem = $(".nav li.active > a").attr('href');
	if (currentItem == '#page-top') {
	    $('.navbar-fixed-top').fadeOut();
	} else {
	    $('.navbar-fixed-top').fadeIn();
	}
    })
});
<|endoftext|>


<commit_before>/**
 * flexselect: a jQuery plugin, version: %RELEASE_VERSION% (%RELEASE_DATE%)
 * @requires jQuery v1.3 or later
 *
 * FlexSelect is a jQuery plugin that makes it easy to convert a select box into
 * a Quicksilver-style, autocompleting, flex matching selection tool.
 *
 * For usage and examples, visit:
 * http://rmm5t.github.com/jquery-flexselect/
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2009-2012, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
 */
(function($) {
  $.flexselect = function(select, options) { this.init(select, options); };

  $.extend($.flexselect.prototype, {
    settings: {
      allowMismatch: false,
      allowMismatchBlank: true, // If "true" a user can backspace such that the value is nothing (even if no blank value was provided in the original criteria)
      sortBy: 'score', // 'score' || 'name'
      preSelection: true,
      selectedClass: "flexselect_selected",
      dropdownClass: "flexselect_dropdown",
      inputIdTransform:    function(id)   { return id + "_flexselect"; },
      inputNameTransform:  function(name) { return; },
      dropdownIdTransform: function(id)   { return id + "_flexselect_dropdown"; }
    },
    select: null,
    input: null,
    hidden: null,
    dropdown: null,
    dropdownList: null,
    cache: [],
    results: [],
    lastAbbreviation: null,
    abbreviationBeforeFocus: null,
    selectedIndex: 0,
    picked: false,
    dropdownMouseover: false, // Workaround for poor IE behaviors

    init: function(select, options) {
      this.settings = $.extend({}, this.settings, options);
      this.select = $(select);
      this.preloadCache();
      this.renderControls();
      this.wire();
    },

    preloadCache: function() {
      this.cache = this.select.children("option").map(function() {
        return { name: $.trim($(this).text()), value: $(this).val(), score: 0.0 };
      });
    },

    renderControls: function() {
      var selected = this.settings.preSelection ? this.select.children("option:selected") : null;

      this.hidden = $("<input type='hidden'/>").attr({
        id: this.select.attr("id"),
        name: this.select.attr("name")
      }).val(selected ? selected.val() : '');

      this.input = $("<input type='text' autocomplete='off' />").attr({
        id: this.settings.inputIdTransform(this.select.attr("id")),
        name: this.settings.inputNameTransform(this.select.attr("name")),
        accesskey: this.select.attr("accesskey"),
        tabindex: this.select.attr("tabindex"),
        style: this.select.attr("style")
      }).addClass(this.select.attr("class")).val($.trim(selected ? selected.text():  ''));

      this.dropdown = $("

").attr({
        id: this.settings.dropdownIdTransform(this.select.attr("id"))
      }).addClass(this.settings.dropdownClass);
      this.dropdownList = $("

");
      this.dropdown.append(this.dropdownList);

      this.select.after(this.input).after(this.hidden).remove();
      $("body").append(this.dropdown);
    },

    wire: function() {
      var self = this;

      this.input.click(function() {
        self.lastAbbreviation = null;
        self.focus();
      });

      this.input.mouseup(function(event) {
        // This is so Safari selection actually occurs.
        event.preventDefault();
      });

      this.input.focus(function() {
        self.abbreviationBeforeFocus = self.input.val();
        self.input.select();
        if (!self.picked) self.filterResults();
      });

      this.input.blur(function() {
        if (!self.dropdownMouseover) {
          self.hide();
          if (self.settings.allowMismatchBlank && $.trim($(this).val()) == '')
            return self.hidden.val('');
          if (!self.settings.allowMismatch && !self.picked)
            self.reset();
        }
      });

      this.dropdownList.mouseover(function (event) {
        if (event.target.tagName == "LI") {
          var rows = self.dropdown.find("li");
          self.markSelected(rows.index($(event.target)));
        }
      });
      this.dropdownList.mouseleave(function () {
        self.markSelected(-1);
      });
      this.dropdownList.mouseup(function (event) {
        self.pickSelected();
        self.focusAndHide();
      });
      this.dropdown.mouseover(function (event) {
        self.dropdownMouseover = true;
      });
      this.dropdown.mouseleave(function (event) {
        self.dropdownMouseover = false;
      });
      this.dropdown.mousedown(function (event) {
        event.preventDefault();
      });

      this.input.keyup(function(event) {
        switch (event.keyCode) {
          case 13: // return
            event.preventDefault();
            self.pickSelected();
            self.focusAndHide();
            break;
          case 27: // esc
            event.preventDefault();
            self.reset();
            self.focusAndHide();
            break;
          default:
            self.filterResults();
            break;
        }
      });

      this.input.keydown(function(event) {
        switch (event.keyCode) {
          case 9:  // tab
            self.pickSelected();
            self.hide();
            break;
          case 33: // pgup
            event.preventDefault();
            self.markFirst();
            break;
          case 34: // pgedown
            event.preventDefault();
            self.markLast();
            break;
          case 38: // up
            event.preventDefault();
            self.moveSelected(-1);
            break;
          case 40: // down
            event.preventDefault();
            self.moveSelected(1);
            break;
          case 13: // return
          case 27: // esc
            event.preventDefault();
            event.stopPropagation();
            break;
        }
      });
    },

    filterResults: function() {
      var abbreviation = this.input.val();
      if (abbreviation == this.lastAbbreviation) return;

      var results = [];
      $.each(this.cache, function() {
        this.score = LiquidMetal.score(this.name, abbreviation);
        if (this.score > 0.0) results.push(this);
      });
      this.results = results;

      if (this.settings.sortBy == 'score')
        this.sortResultsByScore();
      else if (this.settings.sortBy == 'name')
        this.sortResultsByName();

      this.renderDropdown();
      this.markFirst();
      this.lastAbbreviation = abbreviation;
      this.picked = false;
    },

    sortResultsByScore: function() {
      this.results.sort(function(a, b) { return b.score - a.score; });
    },

    sortResultsByName: function() {
      this.results.sort(function(a, b) { return a.name  b.name ? 1 : 0); });
    },

    renderDropdown: function() {
      var dropdownBorderWidth = this.dropdown.outerWidth() - this.dropdown.innerWidth();
      var inputOffset = this.input.offset();
      this.dropdown.css({
        width: (this.input.outerWidth() - dropdownBorderWidth) + "px",
        top: (inputOffset.top + this.input.outerHeight()) + "px",
        left: inputOffset.left + "px"
      });

      var list = this.dropdownList.html("");
      $.each(this.results, function() {
      // list.append($("
").html(this.name + " [" + Math.round(this.score*100)/100 + "]"));
        list.append($("
").html(this.name));
      });
      this.dropdown.show();
    },

    markSelected: function(n) {
      if (n > this.results.length) return;

      var rows = this.dropdown.find("li");
      rows.removeClass(this.settings.selectedClass);
      this.selectedIndex = n;

      if (n >= 0) $(rows[n]).addClass(this.settings.selectedClass);
    },

    pickSelected: function() {
      var selected = this.results[this.selectedIndex];
      if (selected) {
        this.input.val(selected.name);
        this.hidden.val(selected.value);
        this.picked = true;
      } else if (this.settings.allowMismatch) {
        this.hidden.val("");
      } else {
        this.reset();
      }
    },

    hide: function() {
      this.dropdown.hide();
      this.lastAbbreviation = null;
    },

    moveSelected: function(n) { this.markSelected(this.selectedIndex+n); },
    markFirst:    function()  { this.markSelected(0); },
    markLast:     function()  { this.markSelected(this.results.length - 1); },
    reset:        function()  { this.input.val(this.abbreviationBeforeFocus); },
    focus:        function()  { this.input.focus(); },
    focusAndHide: function()  { this.focus(); this.hide(); }
  });

  $.fn.flexselect = function(options) {
    this.each(function() {
      if (this.tagName == "SELECT") new $.flexselect(this, options);
    });
    return this;
  };
})(jQuery);<commit_msg>Bugfix to prevent a 'visibility:hidden' style on the SELECT from affecting the visibility of the newly created input element.<commit_after>/**
 * flexselect: a jQuery plugin, version: %RELEASE_VERSION% (%RELEASE_DATE%)
 * @requires jQuery v1.3 or later
 *
 * FlexSelect is a jQuery plugin that makes it easy to convert a select box into
 * a Quicksilver-style, autocompleting, flex matching selection tool.
 *
 * For usage and examples, visit:
 * http://rmm5t.github.com/jquery-flexselect/
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2009-2012, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
 */
(function($) {
  $.flexselect = function(select, options) { this.init(select, options); };

  $.extend($.flexselect.prototype, {
    settings: {
      allowMismatch: false,
      allowMismatchBlank: true, // If "true" a user can backspace such that the value is nothing (even if no blank value was provided in the original criteria)
      sortBy: 'score', // 'score' || 'name'
      preSelection: true,
      selectedClass: "flexselect_selected",
      dropdownClass: "flexselect_dropdown",
      inputIdTransform:    function(id)   { return id + "_flexselect"; },
      inputNameTransform:  function(name) { return; },
      dropdownIdTransform: function(id)   { return id + "_flexselect_dropdown"; }
    },
    select: null,
    input: null,
    hidden: null,
    dropdown: null,
    dropdownList: null,
    cache: [],
    results: [],
    lastAbbreviation: null,
    abbreviationBeforeFocus: null,
    selectedIndex: 0,
    picked: false,
    dropdownMouseover: false, // Workaround for poor IE behaviors

    init: function(select, options) {
      this.settings = $.extend({}, this.settings, options);
      this.select = $(select);
      this.preloadCache();
      this.renderControls();
      this.wire();
    },

    preloadCache: function() {
      this.cache = this.select.children("option").map(function() {
        return { name: $.trim($(this).text()), value: $(this).val(), score: 0.0 };
      });
    },

    renderControls: function() {
      var selected = this.settings.preSelection ? this.select.children("option:selected") : null;

      this.hidden = $("<input type='hidden'/>").attr({
        id: this.select.attr("id"),
        name: this.select.attr("name")
      }).val(selected ? selected.val() : '');

      this.input = $("<input type='text' autocomplete='off' />").attr({
        id: this.settings.inputIdTransform(this.select.attr("id")),
        name: this.settings.inputNameTransform(this.select.attr("name")),
        accesskey: this.select.attr("accesskey"),
        tabindex: this.select.attr("tabindex"),
        style: this.select.attr("style")
      }).addClass(this.select.attr("class")).val($.trim(selected ? selected.text():  '')).css({
        visibility: 'visible'
      });

      this.dropdown = $("

").attr({
        id: this.settings.dropdownIdTransform(this.select.attr("id"))
      }).addClass(this.settings.dropdownClass);
      this.dropdownList = $("

");
      this.dropdown.append(this.dropdownList);

      this.select.after(this.input).after(this.hidden).remove();
      $("body").append(this.dropdown);
    },

    wire: function() {
      var self = this;

      this.input.click(function() {
        self.lastAbbreviation = null;
        self.focus();
      });

      this.input.mouseup(function(event) {
        // This is so Safari selection actually occurs.
        event.preventDefault();
      });

      this.input.focus(function() {
        self.abbreviationBeforeFocus = self.input.val();
        self.input.select();
        if (!self.picked) self.filterResults();
      });

      this.input.blur(function() {
        if (!self.dropdownMouseover) {
          self.hide();
          if (self.settings.allowMismatchBlank && $.trim($(this).val()) == '')
            return self.hidden.val('');
          if (!self.settings.allowMismatch && !self.picked)
            self.reset();
        }
      });

      this.dropdownList.mouseover(function (event) {
        if (event.target.tagName == "LI") {
          var rows = self.dropdown.find("li");
          self.markSelected(rows.index($(event.target)));
        }
      });
      this.dropdownList.mouseleave(function () {
        self.markSelected(-1);
      });
      this.dropdownList.mouseup(function (event) {
        self.pickSelected();
        self.focusAndHide();
      });
      this.dropdown.mouseover(function (event) {
        self.dropdownMouseover = true;
      });
      this.dropdown.mouseleave(function (event) {
        self.dropdownMouseover = false;
      });
      this.dropdown.mousedown(function (event) {
        event.preventDefault();
      });

      this.input.keyup(function(event) {
        switch (event.keyCode) {
          case 13: // return
            event.preventDefault();
            self.pickSelected();
            self.focusAndHide();
            break;
          case 27: // esc
            event.preventDefault();
            self.reset();
            self.focusAndHide();
            break;
          default:
            self.filterResults();
            break;
        }
      });

      this.input.keydown(function(event) {
        switch (event.keyCode) {
          case 9:  // tab
            self.pickSelected();
            self.hide();
            break;
          case 33: // pgup
            event.preventDefault();
            self.markFirst();
            break;
          case 34: // pgedown
            event.preventDefault();
            self.markLast();
            break;
          case 38: // up
            event.preventDefault();
            self.moveSelected(-1);
            break;
          case 40: // down
            event.preventDefault();
            self.moveSelected(1);
            break;
          case 13: // return
          case 27: // esc
            event.preventDefault();
            event.stopPropagation();
            break;
        }
      });
    },

    filterResults: function() {
      var abbreviation = this.input.val();
      if (abbreviation == this.lastAbbreviation) return;

      var results = [];
      $.each(this.cache, function() {
        this.score = LiquidMetal.score(this.name, abbreviation);
        if (this.score > 0.0) results.push(this);
      });
      this.results = results;

      if (this.settings.sortBy == 'score')
        this.sortResultsByScore();
      else if (this.settings.sortBy == 'name')
        this.sortResultsByName();

      this.renderDropdown();
      this.markFirst();
      this.lastAbbreviation = abbreviation;
      this.picked = false;
    },

    sortResultsByScore: function() {
      this.results.sort(function(a, b) { return b.score - a.score; });
    },

    sortResultsByName: function() {
      this.results.sort(function(a, b) { return a.name  b.name ? 1 : 0); });
    },

    renderDropdown: function() {
      var dropdownBorderWidth = this.dropdown.outerWidth() - this.dropdown.innerWidth();
      var inputOffset = this.input.offset();
      this.dropdown.css({
        width: (this.input.outerWidth() - dropdownBorderWidth) + "px",
        top: (inputOffset.top + this.input.outerHeight()) + "px",
        left: inputOffset.left + "px"
      });

      var list = this.dropdownList.html("");
      $.each(this.results, function() {
      // list.append($("
").html(this.name + " [" + Math.round(this.score*100)/100 + "]"));
        list.append($("
").html(this.name));
      });
      this.dropdown.show();
    },

    markSelected: function(n) {
      if (n > this.results.length) return;

      var rows = this.dropdown.find("li");
      rows.removeClass(this.settings.selectedClass);
      this.selectedIndex = n;

      if (n >= 0) $(rows[n]).addClass(this.settings.selectedClass);
    },

    pickSelected: function() {
      var selected = this.results[this.selectedIndex];
      if (selected) {
        this.input.val(selected.name);
        this.hidden.val(selected.value);
        this.picked = true;
      } else if (this.settings.allowMismatch) {
        this.hidden.val("");
      } else {
        this.reset();
      }
    },

    hide: function() {
      this.dropdown.hide();
      this.lastAbbreviation = null;
    },

    moveSelected: function(n) { this.markSelected(this.selectedIndex+n); },
    markFirst:    function()  { this.markSelected(0); },
    markLast:     function()  { this.markSelected(this.results.length - 1); },
    reset:        function()  { this.input.val(this.abbreviationBeforeFocus); },
    focus:        function()  { this.input.focus(); },
    focusAndHide: function()  { this.focus(); this.hide(); }
  });

  $.fn.flexselect = function(options) {
    this.each(function() {
      if (this.tagName == "SELECT") new $.flexselect(this, options);
    });
    return this;
  };
})(jQuery);<|endoftext|>


<commit_before><commit_msg>Fix Issue #18 null signal created clicking Cancel<commit_after><|endoftext|>


<commit_before>var main = document.getElementById("main");

// <<: example
main.addEventListener("click", function(event) {
  event.stopPropagation();
  event.preventDefault();

  // ...
}, false);
// :>>
<commit_msg>Update/add some examples<commit_after>var main = document.getElementById("main");

// <<: example
main.addEventListener("click", function(event) {
  event.stopPropagation();
  event.preventDefault();

  // ...
});
// :>>
<|endoftext|>


<commit_before>// Abstract document class
// Each specific document class extends this one

'use strict';

var memoize               = require('memoizee/plain')
  , ensureDb              = require('dbjs/valid-dbjs')
  , defineDate            = require('dbjs-ext/date-time/date')
  , defineStringLine      = require('dbjs-ext/string/string-line')
  , _                     = require('mano').i18n.bind('Model: Documents')
  , defineFile            = require('./file')
  , defineStatusLog       = require('./lib/status-log')
  , defineFormSectionBase = require('./fomr-section-base');

module.exports = memoize(function (db) {
	var StringLine = defineStringLine(ensureDb(db))
	  , File       = defineFile(db)
	  , DateType   = defineDate(db)
	  , StatusLog  = defineStatusLog(db)
	  , FormSectionBase = defineFormSectionBase(db);

	db.Object.extend('Document', {
		// Document label, fallbacks to label as decided on constructor
		label: { type: StringLine, value: function () { return this.constructor.label; } },
		// Document legend, fallbacks to legend as decided on constructor
		legend: { type: StringLine, value: function () { return this.constructor.legend; } },
		// Resolves unique named id (in camelCase), that's usually used to resolve human readable urls.
		// e.g. if uniqueKey would be 'authorizedAlocoholLicence' then url token leading to document
		// (converted via es5-ext/string/#/camel-to-hyphen) would 'authorized-alcohol-licence'
		uniqueKey: { type: StringLine, value: function () { return this.key; } },
		// Which entity issued the document. In case of certificates it's an issuing institution,
		// in case of user uploads, it's a user that uploaded files (and that's the default)
		issuedBy: { type: db.Object, value: function () { return this.master.user; } },
		// Issue date. It's inputted by hand official issuance date
		issueDate: { type: DateType, required: true, label: _("Date of issuance") },
		// Document fields sections
		// It's about fields we want officials to fill either at revision (document upload) or
		// processing step (certificate upload)
		dataForm: { type: FormSectionBase, nested: true },
		// Map of uploaded files
		// This property should be used *only* to generate form controls
		// For "read" uses, always refer to "orderedFiles"
		files: { type: db.Object, nested: true },
		// Ordered (by upload date) list of files
		// Normally 'files' should provide that, but due to limitation of dbjs
		// we need a property that assures order and filters all cleared files
		orderedFiles: { type: File, multiple: true, value: function (_observe) {
			var files = [];
			_observe(this.files, true).forEach(function (file) {
				if (!_observe(file._path)) return;
				files.push(file);
			});
			return files.sort(function (a, b) {
				return a.getDescriptor('name')._lastOwnModified_ -
					b.getDescriptor('name')._lastOwnModified_;
			});
		} },
		// History of document processing
		statusLog: { type: StatusLog, multiple: true }
	}, {
		// Document label
		label: { type: StringLine },
		// Document legend
		legend: { type: StringLine },
		// Document abbrevation
		abbr: { type: StringLine }
	});

	// Below defines characteristics for each property on document.files map
	db.Document.prototype.files._descriptorPrototype_.setProperties({
		type: File,
		nested: true
	});

	return db.Document;
}, { normalizer: require('memoizee/normalizers/get-1')() });
<commit_msg>Fix typo<commit_after>// Abstract document class
// Each specific document class extends this one

'use strict';

var memoize               = require('memoizee/plain')
  , ensureDb              = require('dbjs/valid-dbjs')
  , defineDate            = require('dbjs-ext/date-time/date')
  , defineStringLine      = require('dbjs-ext/string/string-line')
  , _                     = require('mano').i18n.bind('Model: Documents')
  , defineFile            = require('./file')
  , defineStatusLog       = require('./lib/status-log')
  , defineFormSectionBase = require('./form-section-base');

module.exports = memoize(function (db) {
	var StringLine = defineStringLine(ensureDb(db))
	  , File       = defineFile(db)
	  , DateType   = defineDate(db)
	  , StatusLog  = defineStatusLog(db)
	  , FormSectionBase = defineFormSectionBase(db);

	db.Object.extend('Document', {
		// Document label, fallbacks to label as decided on constructor
		label: { type: StringLine, value: function () { return this.constructor.label; } },
		// Document legend, fallbacks to legend as decided on constructor
		legend: { type: StringLine, value: function () { return this.constructor.legend; } },
		// Resolves unique named id (in camelCase), that's usually used to resolve human readable urls.
		// e.g. if uniqueKey would be 'authorizedAlocoholLicence' then url token leading to document
		// (converted via es5-ext/string/#/camel-to-hyphen) would 'authorized-alcohol-licence'
		uniqueKey: { type: StringLine, value: function () { return this.key; } },
		// Which entity issued the document. In case of certificates it's an issuing institution,
		// in case of user uploads, it's a user that uploaded files (and that's the default)
		issuedBy: { type: db.Object, value: function () { return this.master.user; } },
		// Issue date. It's inputted by hand official issuance date
		issueDate: { type: DateType, required: true, label: _("Date of issuance") },
		// Document fields sections
		// It's about fields we want officials to fill either at revision (document upload) or
		// processing step (certificate upload)
		dataForm: { type: FormSectionBase, nested: true },
		// Map of uploaded files
		// This property should be used *only* to generate form controls
		// For "read" uses, always refer to "orderedFiles"
		files: { type: db.Object, nested: true },
		// Ordered (by upload date) list of files
		// Normally 'files' should provide that, but due to limitation of dbjs
		// we need a property that assures order and filters all cleared files
		orderedFiles: { type: File, multiple: true, value: function (_observe) {
			var files = [];
			_observe(this.files, true).forEach(function (file) {
				if (!_observe(file._path)) return;
				files.push(file);
			});
			return files.sort(function (a, b) {
				return a.getDescriptor('name')._lastOwnModified_ -
					b.getDescriptor('name')._lastOwnModified_;
			});
		} },
		// History of document processing
		statusLog: { type: StatusLog, multiple: true }
	}, {
		// Document label
		label: { type: StringLine },
		// Document legend
		legend: { type: StringLine },
		// Document abbrevation
		abbr: { type: StringLine }
	});

	// Below defines characteristics for each property on document.files map
	db.Document.prototype.files._descriptorPrototype_.setProperties({
		type: File,
		nested: true
	});

	return db.Document;
}, { normalizer: require('memoizee/normalizers/get-1')() });
<|endoftext|>