<commit_before>(function ($) {
	$.fn.tigronDatetimepicker = function (options) {
		if (typeof options.postFormat === 'undefined') {
			options.postFormat = options.format;
		}
		var getInput = function(element) {
			if ($(element).is('input')) {
				input = $(element);
			} else {
				input = $(element).find($(element).data('DateTimePicker').datepickerInput());
				if (input.length === 0) {
					input = $(element).find('input[type=text]');
				} else if (!input.is('input')) {
					throw new Error('CSS class "' + $(element).data('DateTimePicker').datepickerInput() + '" cannot be applied to non input element');
				}
			}
			return input;
		}

		cleaned_options = jQuery.extend(true, {}, options);
		delete cleaned_options.postFormat;

		$(this).datetimepicker(cleaned_options).on('dp.change', function(e) {
			input = getInput( $(this) );
			classname = $(input).attr('data-hidden-class');
			if (e.date === false) {
				value = '';
			} else {
				value = e.date.format(options.postFormat);
			}
			$('input.' + classname).val(value);
		});

		var count = $('input[class^="datetimepicker_"]').length + 1;

		$.each($(this), function(element, value) {
			input = getInput($(this));

			if ($(this).data('DateTimePicker').date() === null) {
				value = '';
			} else {
				value = $(this).data('DateTimePicker').date().format(options.postFormat);
				$(this).data('DateTimePicker').viewDate($(this).data('DateTimePicker').date());
			}

			$(input).after( $('<input>').attr('type', 'hidden').attr('name', $(input).attr('name')).val( value ).addClass('datetimepicker_' + count) );
			$(input).attr('data-hidden-class', 'datetimepicker_' + count);
			$(input).removeAttr('name');
			count++;
		})
	};
})(jQuery);
<commit_msg>Prevent element creating when init again<commit_after>(function ($) {
	$.fn.tigronDatetimepicker = function (options) {
		if (typeof options.postFormat === 'undefined') {
			options.postFormat = options.format;
		}
		var getInput = function(element) {
			if ($(element).is('input')) {
				input = $(element);
			} else {
				input = $(element).find($(element).data('DateTimePicker').datepickerInput());
				if (input.length === 0) {
					input = $(element).find('input[type=text]');
				} else if (!input.is('input')) {
					throw new Error('CSS class "' + $(element).data('DateTimePicker').datepickerInput() + '" cannot be applied to non input element');
				}
			}
			return input;
		}

		cleaned_options = jQuery.extend(true, {}, options);
		delete cleaned_options.postFormat;

		$(this).datetimepicker(cleaned_options).on('dp.change', function(e) {
			input = getInput( $(this) );
			classname = $(input).attr('data-hidden-class');
			if (e.date === false) {
				value = '';
			} else {
				value = e.date.format(options.postFormat);
			}
			$('input.' + classname).val(value);
		});

		var count = $('input[class^="datetimepicker_"]').length + 1;

		$.each($(this), function(element, value) {
			input = getInput($(this));

			if ($(this).data('DateTimePicker').date() === null) {
				value = '';
			} else {
				value = $(this).data('DateTimePicker').date().format(options.postFormat);
				$(this).data('DateTimePicker').viewDate($(this).data('DateTimePicker').date());
			}

			if ($(input).next().length > 0) {
				return true;
			}

			$(input).after( $('<input>').attr('type', 'hidden').attr('name', $(input).attr('name')).val( value ).addClass('datetimepicker_' + count) );
			$(input).attr('data-hidden-class', 'datetimepicker_' + count);
			$(input).removeAttr('name');
			count++;
		})
	};
})(jQuery);
<|endoftext|>


<commit_before>var http = require( "http" ),
	querystring = require( "querystring" );

function extend( a, b ) {
	for ( var p in b ) {
		a[ p ] = b[ p ];
	}

	return a;
};

function Client( settings) {
	if ( !settings.username ) {
		throw new Error( "Username is required." );
	}
	if ( !settings.password ) {
		throw new Error( "Password is required." );
	}

	extend( this, settings );
	this.authHeader = "Basic " +
		new Buffer( this.username + ":" + this.password ).toString( "base64" );
}

extend( Client.prototype, {
	version: 1,

	getBrowsers: function( fn ) {
		this.request({
			path: this.path( "/browsers" )
		}, fn );
	},

	createWorker: function( options, fn ) {
		var data = querystring.stringify( options );
		this.request({
			path: this.path( "/worker" ),
			method: "POST"
		}, data, fn );
	},

	getWorker: function( id, fn ) {
		this.request({
			path: this.path( "/worker/" + id )
		}, fn );
	},

	terminateWorker: function( id, fn ) {
		this.request({
			path: this.path( "/worker/" + id ),
			method: "DELETE"
		}, fn );
	},

	getWorkers: function( fn ) {
		this.request({
			path: this.path( "/workers" )
		}, fn );
	},

	path: function( path ) {
		return "/" + this.version + path;
	},

	request: function( options, data, fn ) {
		if ( typeof data === "function" ) {
			fn = data;
			data = null;
		}

		var headers = {
			authorization: this.authHeader
		};
		headers[ "content-length" ] = typeof data === "string" ? data.length : 0;

		var req = http.request( extend({
			host: "api.browserstack.com",
			port: 80,
			method: "GET",
			headers: headers
		}, options ), function( res ) {
			var response = "";
			res.setEncoding( "utf8" );
			res.on( "data", function( chunk ) {
				response += chunk;
			});
			res.on( "end", function() {
				if ( res.statusCode !== 200 ) {
					var message;
					if ( res.headers[ "content-type" ].indexOf( "json" ) !== -1 ) {
						message = JSON.parse( response ).message;
					} else {
						message = response;
					}
					if ( !message && res.statusCode === 403 ) {
						message = "Forbidden";
					}
					fn( new Error( message ) );
				} else {
					fn( null, JSON.parse( response ) );
				}
			});
		});

		if ( data ) {
			req.write( data );
		}
		req.end();
	}
});

module.exports = {
	createClient: function( settings ) {
		return new Client( settings );
	}
};
<commit_msg>Gracefully handle calls without a callback.<commit_after>var http = require( "http" ),
	querystring = require( "querystring" );

function extend( a, b ) {
	for ( var p in b ) {
		a[ p ] = b[ p ];
	}

	return a;
};

function Client( settings) {
	if ( !settings.username ) {
		throw new Error( "Username is required." );
	}
	if ( !settings.password ) {
		throw new Error( "Password is required." );
	}

	extend( this, settings );
	this.authHeader = "Basic " +
		new Buffer( this.username + ":" + this.password ).toString( "base64" );
}

extend( Client.prototype, {
	version: 1,

	getBrowsers: function( fn ) {
		this.request({
			path: this.path( "/browsers" )
		}, fn );
	},

	createWorker: function( options, fn ) {
		var data = querystring.stringify( options );
		this.request({
			path: this.path( "/worker" ),
			method: "POST"
		}, data, fn );
	},

	getWorker: function( id, fn ) {
		this.request({
			path: this.path( "/worker/" + id )
		}, fn );
	},

	terminateWorker: function( id, fn ) {
		this.request({
			path: this.path( "/worker/" + id ),
			method: "DELETE"
		}, fn );
	},

	getWorkers: function( fn ) {
		this.request({
			path: this.path( "/workers" )
		}, fn );
	},

	path: function( path ) {
		return "/" + this.version + path;
	},

	request: function( options, data, fn ) {
		if ( typeof data === "function" ) {
			fn = data;
			data = null;
		}
		fn = fn || function() {};

		var headers = {
			authorization: this.authHeader
		};
		headers[ "content-length" ] = typeof data === "string" ? data.length : 0;

		var req = http.request( extend({
			host: "api.browserstack.com",
			port: 80,
			method: "GET",
			headers: headers
		}, options ), function( res ) {
			var response = "";
			res.setEncoding( "utf8" );
			res.on( "data", function( chunk ) {
				response += chunk;
			});
			res.on( "end", function() {
				if ( res.statusCode !== 200 ) {
					var message;
					if ( res.headers[ "content-type" ].indexOf( "json" ) !== -1 ) {
						message = JSON.parse( response ).message;
					} else {
						message = response;
					}
					if ( !message && res.statusCode === 403 ) {
						message = "Forbidden";
					}
					fn( new Error( message ) );
				} else {
					fn( null, JSON.parse( response ) );
				}
			});
		});

		if ( data ) {
			req.write( data );
		}
		req.end();
	}
});

module.exports = {
	createClient: function( settings ) {
		return new Client( settings );
	}
};
<|endoftext|>


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

/**
 * PhET Simulations can be launched with query parameters which enable certain features.
 *
 * Here are the query parameters that are most useful for QA Testing:
 *
 * dev - enable developer-only features, such as showing the layout bounds
 * ea - enable assertions, internal code error checks
 * eall - enable all assertions, as above but with more time consuming checks
 * fuzzMouse - randomly sends mouse events to sim
 * profiler - shows profiling information for the sim
 * showPointerAreas - touch areas in red, mouse areas in blue, both dotted outlines
 *
 * Here are the other supported QA testing:
 *
 * accessibility - enable accessibility features, such as keyboard navigation (mileage may vary!)
 * fuzzTouches - randomly sends touch events to sim (not working as of 10/8/13)
 * locale - test with a specific locale
 * playbackInputEventLog - plays event logging back from the server, provide an optional name for the session
 * recordInputEventLog - enables input event logging, provide an optional name for the session, log is available via PhET menu
 * screenIndex - selects this screen on the home screen
 * showHomeScreen - if false, go immediate to screenIndex, defaults to screenIndex=0
 * standalone - runs screenIndex as a standalone sim, defaults to screenIndex=0
 * webglContextLossTimeout - if enabled, will create WebGL contexts that can simulate context loss
 *                         - if a value is specified, it will also simulate a context loss after the specified number
 *                         - of milliseconds has elapsed.
 *                         - The value can be omitted to manually simulate the context loss with simScene.simulateWebGLContextLoss()
 * webglContextLossIncremental - if this option is present, it will put the WebGLLayer into a testing mode which
 *                             - simulates context loss between successively increasing gl calls (starting at 1)
 *                             - this option should be used in conjunction with webglContextLossTimeout since
 *                             - it only triggers upon the first context lass.
 *
 * This file reads query parameters from browser window's URL.
 * This file must be loaded before requirejs is started up, and this file cannot be loaded as an AMD module.
 * The easiest way to do this is via a <script> tag in your HTML file.
 *
 * @author Sam Reid, PhET
 * @author Chris Malley (PixelZoom, Inc.)
 */
(function() {
  'use strict';

  if ( !window.phetcommon ) {
    window.phetcommon = {};
  }

  //Pre-populate the query parameters map so that multiple subsequent look-ups are fast
  var queryParamsMap = {};

  if ( typeof window !== 'undefined' && window.location.search ) {
    var params = window.location.search.slice( 1 ).split( '&' );
    for ( var i = 0; i < params.length; i++ ) {
      var nameValuePair = params[i].split( '=' );
      queryParamsMap[nameValuePair[0]] = decodeURIComponent( nameValuePair[1] );
    }
  }

  /**
   * Retrieves the first occurrence of a query parameter based on its key.
   * Returns undefined if the query parameter is not found.
   * @param {string} key
   * @return {string}
   */
  window.phetcommon.getQueryParameter = function( key ) {
    return queryParamsMap[key];
  };

}());
<commit_msg>updated the documentation for query parameters to indicate which ones are useful for testing<commit_after>// Copyright 2002-2013, University of Colorado Boulder

/**
 * PhET Simulations can be launched with query parameters which enable certain features.
 *
 * Here are the query parameters that are most useful for QA Testing:
 *
 * dev - enable developer-only features, such as showing the layout bounds
 * ea - enable assertions, internal code error checks
 * eall - enable all assertions, as above but with more time consuming checks
 * fuzzMouse - randomly sends mouse events to sim
 * profiler - shows profiling information for the sim
 * showPointerAreas - touch areas in red, mouse areas in blue, both dotted outlines
 *
 * Here are the other supported query parameters:
 *
 * accessibility - enable accessibility features, such as keyboard navigation (mileage may vary!)
 * fuzzTouches - randomly sends touch events to sim (not working as of 10/8/13)
 * locale - test with a specific locale
 * playbackInputEventLog - plays event logging back from the server, provide an optional name for the session
 * recordInputEventLog - enables input event logging, provide an optional name for the session, log is available via PhET menu
 * screenIndex - selects this screen on the home screen
 * showHomeScreen - if false, go immediate to screenIndex, defaults to screenIndex=0
 * standalone - runs screenIndex as a standalone sim, defaults to screenIndex=0
 * webglContextLossTimeout - if enabled, will create WebGL contexts that can simulate context loss
 *                         - if a value is specified, it will also simulate a context loss after the specified number
 *                         - of milliseconds has elapsed.
 *                         - The value can be omitted to manually simulate the context loss with simScene.simulateWebGLContextLoss()
 * webglContextLossIncremental - if this option is present, it will put the WebGLLayer into a testing mode which
 *                             - simulates context loss between successively increasing gl calls (starting at 1)
 *                             - this option should be used in conjunction with webglContextLossTimeout since
 *                             - it only triggers upon the first context lass.
 *
 * This file reads query parameters from browser window's URL.
 * This file must be loaded before requirejs is started up, and this file cannot be loaded as an AMD module.
 * The easiest way to do this is via a <script> tag in your HTML file.
 *
 * @author Sam Reid, PhET
 * @author Chris Malley (PixelZoom, Inc.)
 */
(function() {
  'use strict';

  if ( !window.phetcommon ) {
    window.phetcommon = {};
  }

  //Pre-populate the query parameters map so that multiple subsequent look-ups are fast
  var queryParamsMap = {};

  if ( typeof window !== 'undefined' && window.location.search ) {
    var params = window.location.search.slice( 1 ).split( '&' );
    for ( var i = 0; i < params.length; i++ ) {
      var nameValuePair = params[i].split( '=' );
      queryParamsMap[nameValuePair[0]] = decodeURIComponent( nameValuePair[1] );
    }
  }

  /**
   * Retrieves the first occurrence of a query parameter based on its key.
   * Returns undefined if the query parameter is not found.
   * @param {string} key
   * @return {string}
   */
  window.phetcommon.getQueryParameter = function( key ) {
    return queryParamsMap[key];
  };

}());
<|endoftext|>


<commit_before>var mode = "mario";
var currentLevel = 0;
var currentQuadrant = 1;
var charList = [];
var blocksList = [];
var textList = [];
var jimmy;

/*
 * Many different classes are avaliable:
 * 	 character
 * 	 wall
 * 		WORLD
 * 		portal
 * 		transitionwall
 * 		dangerblock
 * 		text
 * You probably won't need to call new WORLD()
*/

// Credit to Chris Pickett @ Stack Overflow for this one
function findElemWithKey(array, propList, value) {
	for(var i = 0; i < array.length; i++) {
		var endProp = array[i];
		for (var j=0; j<propList.length; j++) {
			if (!endProp[propList[j]]) {
				break;
			}
			endProp = endProp[propList[j]];
		}
		if(endProp === value) {
			return i;
		}
	}
	return -1;
}

function Vector(x, y) {
	this.x = x?x:0;
	this.y = y?y:0;
	this.magnitude = function() {
		return Math.sqrt(this.x*this.x + this.y*this.y);
	};
	this.Plus = function(v) {
		this.x += v.x;
		this.y += v.y;
	};
	this.Scale = function(c) {
		this.x *= c;
		this.y *= c;
	};
	this.asUnit = function() {
		return scalarMultiply(
			1/this.magnitude(),
			this
		);
	};
	this.isZero = function() {
		return (this.magnitude() === 0);
	};
	this.toString = function() {
		return "(" + this.x + ", " + this.y + ")";
	};
}

function addVectors(v1, v2) {
	return new Vector(
		v1.x+v2.x,
		v1.y+v2.y
	);
}

function subtractVectors(v1, v2) {
	return new Vector(
		v1.x-v2.x,
		v1.y-v2.y
	);
}

function sumVectors(vList) {
	var sum = new Vector(0, 0);
	for (var index=0; index<vList.length; index++) {
		sum.Plus( vList[index] );
	}
	return sum;
}

function scalarMultiply(c, v) {
	return new Vector(c*v.x, c*v.y);
}

function dotProduct(v1, v2) {
	return (v1.x*v2.x + v1.y*v2.y);
}

function someOtherProduct(v1, v2) {
	return new Vector(
		v1.x*v2.x,
		v1.y*v2.y
	);
}

// projection u onto v
// vector component of u parallel to v
function projection(u, v) {
	return scalarMultiply(
		dotProduct(u, v)/(v.magnitude()*v.magnitude()),
		v
	);
}

function projectionDirection(u, v) {
	return scalarMultiply(
		Math.abs(dotProduct(u, v)/(v.magnitude()*v.magnitude())),
		v
	);
}

function minOfVectors(v1, v2) {
	return new Vector(
		Math.min(v1.x, v2.x),
		Math.min(v1.y, v2.y)
	);
}

function minAbsOfVectors(v1, v2) {
	return new Vector(
		Math.min(Math.abs(v1.x), Math.abs(v2.x)),
		Math.min(Math.abs(v1.y), Math.abs(v2.y))
	);
}

function maxOfVectors(v1, v2) {
	return new Vector(
		Math.max(v1.x, v2.x),
		Math.max(v1.y, v2.y)
	);
}

function maxAbsOfVectors(v1, v2) {
	return new Vector(
		Math.max(Math.abs(v1.x), Math.abs(v2.x)),
		Math.max(Math.abs(v1.y), Math.abs(v2.y))
	);
}

function signForVectors(v) {
	return new Vector (
		sign(v.x),
		sign(v.y)
	);
}

function componetSwap(v) {
	return new Vector(
		v.y,
		v.x
	);
}

// Class for all characters in the game
// Properties are position, speed, image, and radius
// Object is then added to the charList array
function character(xpos, ypos, img1, img2) {
	this.position = new Vector(xpos, ypos);
	this.orientation = 1;
	this.rotation = 0;
	this.forceList = [];
	this.velocity = new Vector(0, 0);
	this.acceleration = new Vector(0, 0);
	this.maxVelocity = new Vector(15, 35);
	this.appliedForce = new Vector(3, 12);
	this.friction = new Vector(0, 0);
	this.normalForce = new Vector(0, 0);
	this.mu = -0.3;
	this.bouncieness = 0;
	this.image = img1;
	this.jumpImage = img2?img2:img1;
	this.canJump = {
		x:false,
		y:false
	};
	this.jump = function() {
		if (this.canJump.y) {
			this.forceList.push(
				new Vector(
					0,
					this.appliedForce.y*(mode=="mario"?1:-1)
				)
			);
		}
		//this.velocity.x += (this.appliedForce.x)*(this.canJump.x)*(jumpX);
		//this.velocity.y += (this.appliedForce.y)*(this.canJump.y)*(mode=="mario"?1:-1);   // The last segment accounts for the direction you should jump in, determined by mode
//		this.canJump.x *= true;
		this.canJump.y = false;
	};
	this.health = 100;
	this.inventory = [];
	charList.push(this);
}

// Currently, a class for all blocks in the game
// Properties are where and image
// Object is then added to the blocksList array
function wall(x, y, dx, dy) {
	this.where = {
		corner: new Vector(x, y),
		change: new Vector(dx, dy)
	};
	this.mu = -0.3;   // I don't think the actual greek letter would be valid
	this.bouncieness = 0;
	this.image = {
		invert: document.getElementById("blockPic"),
		mario: document.getElementById("blockPic")
	};
	this.collide = function(who) {

	};
	blocksList.push(this);
}

function WORLD(x, y, sx, sy) {
	this.where = {
		corner: new Vector(
			-gameArea.canvas.width/2,
			-gameArea.canvas.height/2
		),
		change: new Vector(
			gameArea.canvas.width,
			gameArea.canvas.height
		)
	};
	this.size = {   // sorta wierd having two similar objects, but for different purposes. Shouldn't they be instantiated seperately, in to two blocks
		where: {
			corner: new Vector(
				(x?x:this.where.corner.x-1),
				(y?y:this.where.corner.y-1)
			),
			change: new Vector(
				(sx?sx:this.where.change.x),
				(sy?sy:this.where.change.y)
			)
		}
	};
	this.velocity = new Vector(0, 0);
	this.acceleration = new Vector(0, 0);
	this.mu = 0;
	this.bouncieness = 0;
	this.image = {
		invert: document.getElementById("transwallPic"),
		mario: document.getElementById("transwallPic")
	};
	this.collide = function(who) {
		if (who === jimmy) {
			var potentialWorld = {
				where: {
					corner: {
						x: this.where.corner.x-sign(isCollision(this, jimmy, "horizontal"))*Math.max(Math.abs(jimmy.velocity.x), 5),
						y: this.where.corner.y-sign(isCollision(this, jimmy, "vertical"))*Math.max(Math.abs(jimmy.velocity.y), 5)
					},
					change: this.where.change
				}
			};
			scoochScreen(
				(Math.abs(isCollision(this, jimmy, "horizontal"))<300)*							 // If jimmy is close enough to the screen to scooch
				(Math.abs(isCollision(potentialWorld, this.size, "horizontal"))>=this.where.change.x)*	  // If it will fit
				-sign(isCollision(this, jimmy, "horizontal"))*Math.max(Math.abs(jimmy.velocity.x), 5),  // Direction and magnitude to scooch

				(Math.abs(isCollision(this, jimmy, "vertical"))<150)*
				(Math.abs(isCollision(potentialWorld, this.size, "vertical"))>=this.where.change.y)*
				-sign(isCollision(this, jimmy, "vertical"))*Math.max(Math.abs(jimmy.velocity.y), 5)
			);
		}
	};
	this.do = function(t) {
		if (jimmy.health <= 0) {
			changeLevel(currentLevel, 1);
		}
	};
	blocksList.push(this);
}

function portal(x, y, dx, dy, n, q) {
/*	wall.call(this);
	this.prototype = new wall();
	this.prototype.constructor = portal;
	this.collide = function(who) {
		if (who==jimmy)
		{
			currentLevel++;
			changeLevel();
		}
	};*/

	this.where = {
		corner: new Vector(x, y),
		change: new Vector(dx, dy)
	};
	this.mu = 0;
	this.bouncieness = 0;
	this.image = {
		invert: document.getElementById("portalPic"),
		mario: document.getElementById("portalPic")
	};
	this.collide = function(who) {
		if (who==jimmy)
		{
			changeLevel(n?n:currentLevel+1, q?q:1);
		}

	};
	blocksList.push(this);
}

function transitionwall(x, y, dx, dy, n) {
	this.where = {
		corner: new Vector(x, y),
		change: new Vector(dx, dy)
	};
	this.mu = 0;
	this.bouncieness = 0;
	this.image = {
		invert: document.getElementById("transwallPic"),
		mario: document.getElementById("transwallPic")
	};
	this.collide = function(who) {
		if (who==jimmy)
		{
			changeLevel(currentLevel, (n?n:currentQuadrant+1));
		}

	};
	blocksList.push(this);
}

function dangerblock(x, y, dx, dy) {
	this.where = {
		corner: new Vector(x, y),
		change: new Vector(dx, dy)
	};
	this.mu = 0;
	this.bouncieness = 0;
	this.image = {
		invert: document.getElementById("dangerblockPic"),
		mario: document.getElementById("dangerblockPic")
	};
	this.collide = function(who) {
		if (who==jimmy)
		{
			jimmy.health-=2;
		}

	};
	blocksList.push(this);
}

function movingBlock(x, y, dx, dy, f, g) {
	this.where = {
		corner: new Vector(x, y),
		change: new Vector(dx, dy)
	};
	this.velocity = new Vector(0, 0);
	this.acceleration = new Vector(0, 0);
	this.mu = 0;
	this.bouncieness = 0;
	this.image = {
		invert: document.getElementById("blockPic"),
		mario: document.getElementById("blockPic")
	};
	this.do = f?f:function(t) {};
	this.collide = g?g:function(who) {
		if (who)
		{
			who.position.Plus( this.velocity );
		}

	};
	blocksList.push(this);
}

function simpleActionBlock(x, y, img, f, g) {
	this.where = {
		corner: new Vector(x, y),
		change: new Vector(img.width, img.height)
	};
	this.velocity = new Vector(0, 0);
	this.acceleration = new Vector(0, 0);
	this.mu = 0;
	this.bouncieness = 0;
	this.image = {
		invert: img,
		mario: img
	};
	this.collide = f?f:function(who) {
		if (who)
		{
			who.position.Plus( this.velocity );
		}

	};
	this.do = g?g:function(t) {};
	blocksList.push(this);
}

function text(v, x, y, s, f) {
	this.value = v;
	this.where = {
		corner: new Vector(x, y),
		change: new Vector(gameArea.measureText(v), (s?s:18))
	};
	this.mu = 0;
	this.bouncieness = 0;
	this.font = (s?s:18) + "pt " + (f?f:"Trebuchet MS");
	textList.push(this);
}
<commit_msg>Delete classes.js<commit_after><|endoftext|>


<commit_before>import $ from 'jquery';
import app from '../app';
import {
  formatCurrency,
  convertAndFormatCurrency,
  convertCurrency,
  formatPrice,
  getCurrencyValidity,
  renderFormattedCurrency,
  renderPairedCurrency,
} from './currency';
import {
  getServerCurrency,
  renderCryptoIcon,
  getBlockChainTxUrl,
  getBlockChainAddressUrl,
  getCurrencyByCode as getCryptoCurByCode,
} from '../data/cryptoCurrencies';
import {
  isHiRez, isLargeWidth, isSmallHeight, getAvatarBgImage, getListingBgImage,
} from './responsive';
import { upToFixed } from './number';
import twemoji from 'twemoji';
import { splitIntoRows } from './';
import { tagsDelimiter } from '../utils/lib/selectize';
import is from 'is_js';

export function polyT(...args) {
  return app.polyglot.t(...args);
}

export function parseEmojis(text, className = '', attrs = {}) {
  const parsed = twemoji.parse(text,
    icon => (`../imgs/emojis/72X72/${icon}.png`));
  const $parsed = $(`<div>${parsed}</div>`);

  $parsed.find('img')
    .each((index, img) => {
      const $img = $(img);
      $img.addClass(`emoji ${className}`);

      Object.keys(attrs)
        .forEach(attr => {
          $img.attr(attr, attrs[attr]);
        });
    });

  return $parsed.html();
}

/**
 * If the average is a number, show the last 2 digits and trim any trailing zeroes.
 * @param {number} average - the average rating
 * @param {number} count - the number of ratings
 */
export function formatRating(average, count) {
  const avIsNum = typeof average === 'number';
  const ratingAverage = avIsNum ? average.toFixed(1) : 0;
  const ratingCount = typeof count === 'number' ? ` (${count})` : 0;
  return `${parseEmojis('⭐')} ${ratingAverage}${ratingCount}`;
}

export const getServerUrl = app.getServerUrl.bind(app);

const currencyExport = {
  formatPrice,
  formatCurrency,
  convertAndFormatCurrency,
  convertCurrency,
  getCurrencyValidity,
  getServerCurrency,
  getCryptoCurByCode,
  formattedCurrency: renderFormattedCurrency,
  pairedCurrency: renderPairedCurrency,
  cryptoIcon: renderCryptoIcon,
  getBlockChainTxUrl,
  getBlockChainAddressUrl,
};

export {
  currencyExport as currencyMod,
  isHiRez,
  isLargeWidth,
  isSmallHeight,
  getAvatarBgImage,
  getListingBgImage,
  upToFixed,
  splitIntoRows,
  is,
  tagsDelimiter,
};
<commit_msg>Don't show invalid counts<commit_after>import $ from 'jquery';
import app from '../app';
import {
  formatCurrency,
  convertAndFormatCurrency,
  convertCurrency,
  formatPrice,
  getCurrencyValidity,
  renderFormattedCurrency,
  renderPairedCurrency,
} from './currency';
import {
  getServerCurrency,
  renderCryptoIcon,
  getBlockChainTxUrl,
  getBlockChainAddressUrl,
  getCurrencyByCode as getCryptoCurByCode,
} from '../data/cryptoCurrencies';
import {
  isHiRez, isLargeWidth, isSmallHeight, getAvatarBgImage, getListingBgImage,
} from './responsive';
import { upToFixed } from './number';
import twemoji from 'twemoji';
import { splitIntoRows } from './';
import { tagsDelimiter } from '../utils/lib/selectize';
import is from 'is_js';

export function polyT(...args) {
  return app.polyglot.t(...args);
}

export function parseEmojis(text, className = '', attrs = {}) {
  const parsed = twemoji.parse(text,
    icon => (`../imgs/emojis/72X72/${icon}.png`));
  const $parsed = $(`<div>${parsed}</div>`);

  $parsed.find('img')
    .each((index, img) => {
      const $img = $(img);
      $img.addClass(`emoji ${className}`);

      Object.keys(attrs)
        .forEach(attr => {
          $img.attr(attr, attrs[attr]);
        });
    });

  return $parsed.html();
}

/**
 * If the average is a number, show the last 2 digits and trim any trailing zeroes.
 * @param {number} average - the average rating
 * @param {number} count - the number of ratings
 */
export function formatRating(average, count) {
  const avIsNum = typeof average === 'number';
  const ratingAverage = avIsNum ? average.toFixed(1) : 0;
  const ratingCount = typeof count === 'number' ? ` (${count})` : '';
  return `${parseEmojis('⭐')} ${ratingAverage}${ratingCount}`;
}

export const getServerUrl = app.getServerUrl.bind(app);

const currencyExport = {
  formatPrice,
  formatCurrency,
  convertAndFormatCurrency,
  convertCurrency,
  getCurrencyValidity,
  getServerCurrency,
  getCryptoCurByCode,
  formattedCurrency: renderFormattedCurrency,
  pairedCurrency: renderPairedCurrency,
  cryptoIcon: renderCryptoIcon,
  getBlockChainTxUrl,
  getBlockChainAddressUrl,
};

export {
  currencyExport as currencyMod,
  isHiRez,
  isLargeWidth,
  isSmallHeight,
  getAvatarBgImage,
  getListingBgImage,
  upToFixed,
  splitIntoRows,
  is,
  tagsDelimiter,
};
<|endoftext|>


<commit_before>/*
**  slideshow -- Observe and Control Slideshow Applications
**  Copyright (c) 2014 Ralf S. Engelschall <http://engelschall.com>
**
**  This Source Code Form is subject to the terms of the Mozilla Public
**  License (MPL), version 2.0. If a copy of the MPL was not distributed
**  with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
**
**  File:     slideshow-cli.js
**  Purpose:  Command Line Interface (CLI)
**  Language: Node/JavaScript
*/

/* global require: false */
/* global console: false */
/* global process: false */

/*  external requirements  */
var readline  = require("readline");
var chalk     = require("chalk");
var slideshow = require("./slideshow-api");

/*  define the known applications  */
var apps = {
    "powerpoint": true,
    "keynote":    true
};

/*  define the known commands (and their argument)  */
var commands = {
    /*  CLI-specific  */
    "help":   [],
    "use":    [ "application-type" ],

    /*  API-derived  */
    "stat":   [],
    "info":   [],
    "boot":   [],
    "quit":   [],
    "open":   [ "presentation-filename" ],
    "close":  [],
    "start":  [],
    "stop":   [],
    "pause":  [],
    "resume": [],
    "first":  [],
    "last":   [],
    "goto":   [ "slide-number" ],
    "prev":   [],
    "next":   []
};

/*  the interactive CLI variant  */
var cliInteractive = function () {
    /*  start with a non-existing slideshow  */
    var ss = null;

    /*  create the stdin/stdout based readline interface  */
    var rl = readline.createInterface({
        input:  process.stdin,
        output: process.stdout
    });

    /*  provide CLI  */
    rl.setPrompt("slideshow> ");
    rl.prompt();
    rl.on("line", function (line) {
        /*  determine command  */
        var argv = line.trim().split(/\s+/);
        var info = commands[argv[0]];
        var prompt = true;
        if (typeof info === "undefined")
            console.log(chalk.red("ERROR: invalid command (use \"help\" for usage)"));
        else if (info.length !== (argv.length - 1))
            console.log(chalk.red("ERROR: invalid number of arguments (expected: " + info.join(" ") + ")"));
        else {
            /*  process CLI-specific commands  */
            if (argv[0] === "help")
                Object.keys(commands).forEach(function (cmd) {
                    console.log(chalk.green("    " + cmd + " " + (
                        commands[cmd].map(function (arg) { return "<" + arg + ">"; }).join(" ")
                    )));
                });
            else if (argv[0] === "use") {
                if (typeof apps[argv[1]] === "undefined")
                    console.log(chalk.red("ERROR: invalid argument (expected: " + Object.keys(apps).join(", ") + ")"));
                else {
                    if (ss !== null)
                        ss.end();
                    ss = new slideshow(argv[1]);
                    rl.setPrompt("slideshow(" + argv[1] + ")> ");
                }
            }

            /*  process API-derived commands  */
            else {
                if (ss === null)
                    console.log(chalk.red("ERROR: you have to choose with \"use\" an application first"));
                else {
                    ss[argv[0]](argv[1]).then(function (response) {
                        console.log(chalk.green(JSON.stringify(response, null, "    ")));
                        rl.prompt();
                    }, function (error) {
                        console.log(chalk.red("ERROR: " + error));
                        rl.prompt();
                    });
                    prompt = false;
                }
            }
        }

        /*  provide prompt for next iteration  */
        if (prompt)
            rl.prompt();
    });

    /*  gracefully stop CLI  */
    rl.on("close", function() {
        console.log("");
        process.exit(0);
    });
};

/*  the batch CLI variant  */
var cliBatch = function (argv) {
    if (argv.length === 1 && argv[0] === "help") {
        Object.keys(commands).forEach(function (cmd) {
            if (cmd !== "use" && cmd !== "help") {
                console.log(chalk.green("slideshow <application> " + cmd + " " + (
                    commands[cmd].map(function (arg) { return "<" + arg + ">"; }).join(" ")
                )));
            }
        });
        process.exit(0);
    }
    if (argv.length < 2) {
        console.log(chalk.red("ERROR: invalid number of arguments (use \"help\" for usage)"));
        process.exit(1);
    }
    if (typeof apps[argv[0]] === "undefined") {
        console.log(chalk.red("ERROR: invalid application (expected: " + Object.keys(apps).join(", ") + ")"));
        process.exit(1);
    }
    var ss = new slideshow(argv[0]);
    var info = commands[argv[1]];
    if (typeof info === "undefined") {
        console.log(chalk.red("ERROR: invalid connector command (use \"help\" for usage)"));
        process.exit(1);
    }
    else if (info.length !== (argv.length - 2)) {
        console.log(chalk.red("ERROR: invalid number of connector arguments (expected: " + info.join(" ") + ")"));
        process.exit(1);
    }
    ss[argv[1]](argv[2]).then(function (response) {
        console.log(chalk.green(JSON.stringify(response, null, "    ")));
        process.exit(0);
    }, function (error) {
        console.log(chalk.red("ERROR: " + error));
        process.exit(1);
    });
};

/*  dispatch according to type of operation  */
if (process.argv.length === 2)
    cliInteractive();
else
    cliBatch(process.argv.splice(2));

<commit_msg>fix CLI installation for NPM<commit_after>#!/usr/bin/env node
/*
**  slideshow -- Observe and Control Slideshow Applications
**  Copyright (c) 2014 Ralf S. Engelschall <http://engelschall.com>
**
**  This Source Code Form is subject to the terms of the Mozilla Public
**  License (MPL), version 2.0. If a copy of the MPL was not distributed
**  with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
**
**  File:     slideshow-cli.js
**  Purpose:  Command Line Interface (CLI)
**  Language: Node/JavaScript
*/

/* global require: false */
/* global console: false */
/* global process: false */

/*  external requirements  */
var readline  = require("readline");
var chalk     = require("chalk");
var slideshow = require("./slideshow-api");

/*  define the known applications  */
var apps = {
    "powerpoint": true,
    "keynote":    true
};

/*  define the known commands (and their argument)  */
var commands = {
    /*  CLI-specific  */
    "help":   [],
    "use":    [ "application-type" ],

    /*  API-derived  */
    "stat":   [],
    "info":   [],
    "boot":   [],
    "quit":   [],
    "open":   [ "presentation-filename" ],
    "close":  [],
    "start":  [],
    "stop":   [],
    "pause":  [],
    "resume": [],
    "first":  [],
    "last":   [],
    "goto":   [ "slide-number" ],
    "prev":   [],
    "next":   []
};

/*  the interactive CLI variant  */
var cliInteractive = function () {
    /*  start with a non-existing slideshow  */
    var ss = null;

    /*  create the stdin/stdout based readline interface  */
    var rl = readline.createInterface({
        input:  process.stdin,
        output: process.stdout
    });

    /*  provide CLI  */
    rl.setPrompt("slideshow> ");
    rl.prompt();
    rl.on("line", function (line) {
        /*  determine command  */
        var argv = line.trim().split(/\s+/);
        var info = commands[argv[0]];
        var prompt = true;
        if (typeof info === "undefined")
            console.log(chalk.red("ERROR: invalid command (use \"help\" for usage)"));
        else if (info.length !== (argv.length - 1))
            console.log(chalk.red("ERROR: invalid number of arguments (expected: " + info.join(" ") + ")"));
        else {
            /*  process CLI-specific commands  */
            if (argv[0] === "help")
                Object.keys(commands).forEach(function (cmd) {
                    console.log(chalk.green("    " + cmd + " " + (
                        commands[cmd].map(function (arg) { return "<" + arg + ">"; }).join(" ")
                    )));
                });
            else if (argv[0] === "use") {
                if (typeof apps[argv[1]] === "undefined")
                    console.log(chalk.red("ERROR: invalid argument (expected: " + Object.keys(apps).join(", ") + ")"));
                else {
                    if (ss !== null)
                        ss.end();
                    ss = new slideshow(argv[1]);
                    rl.setPrompt("slideshow(" + argv[1] + ")> ");
                }
            }

            /*  process API-derived commands  */
            else {
                if (ss === null)
                    console.log(chalk.red("ERROR: you have to choose with \"use\" an application first"));
                else {
                    ss[argv[0]](argv[1]).then(function (response) {
                        console.log(chalk.green(JSON.stringify(response, null, "    ")));
                        rl.prompt();
                    }, function (error) {
                        console.log(chalk.red("ERROR: " + error));
                        rl.prompt();
                    });
                    prompt = false;
                }
            }
        }

        /*  provide prompt for next iteration  */
        if (prompt)
            rl.prompt();
    });

    /*  gracefully stop CLI  */
    rl.on("close", function() {
        console.log("");
        process.exit(0);
    });
};

/*  the batch CLI variant  */
var cliBatch = function (argv) {
    if (argv.length === 1 && argv[0] === "help") {
        Object.keys(commands).forEach(function (cmd) {
            if (cmd !== "use" && cmd !== "help") {
                console.log(chalk.green("slideshow <application> " + cmd + " " + (
                    commands[cmd].map(function (arg) { return "<" + arg + ">"; }).join(" ")
                )));
            }
        });
        process.exit(0);
    }
    if (argv.length < 2) {
        console.log(chalk.red("ERROR: invalid number of arguments (use \"help\" for usage)"));
        process.exit(1);
    }
    if (typeof apps[argv[0]] === "undefined") {
        console.log(chalk.red("ERROR: invalid application (expected: " + Object.keys(apps).join(", ") + ")"));
        process.exit(1);
    }
    var ss = new slideshow(argv[0]);
    var info = commands[argv[1]];
    if (typeof info === "undefined") {
        console.log(chalk.red("ERROR: invalid connector command (use \"help\" for usage)"));
        process.exit(1);
    }
    else if (info.length !== (argv.length - 2)) {
        console.log(chalk.red("ERROR: invalid number of connector arguments (expected: " + info.join(" ") + ")"));
        process.exit(1);
    }
    ss[argv[1]](argv[2]).then(function (response) {
        console.log(chalk.green(JSON.stringify(response, null, "    ")));
        process.exit(0);
    }, function (error) {
        console.log(chalk.red("ERROR: " + error));
        process.exit(1);
    });
};

/*  dispatch according to type of operation  */
if (process.argv.length === 2)
    cliInteractive();
else
    cliBatch(process.argv.splice(2));

<|endoftext|>


<commit_before>/**
* Timehaze.js
*/

/**
* Constants
*/

// Number of seconds in a...
var MINUTE = 60;
var HOUR = MINUTE * 60;
var DAY = HOUR * 24;
var MONTH = DAY * 30.4166;  // 1 month = 365/12 days
var YEAR = MONTH * 12;
var DECADE = YEAR * 10;
var CENTURY = DECADE * 10;
var MILLENNIUM = CENTURY * 10;

/**
* Properties
*/

var fuzzyLabels = {
  "infinity": "infinity",
  "millennia": "millennia",
  "millennium": "millennium",
  "centuries": "centuries",
  "century": "century",
  "decades": "decades",
  "decade": "decade",
  "years": "years",
  "year": "year",
  "months": "months",
  "month": "month",
  "weeks": "weeks",
  "week": "week",
  "days": "days",
  "day": "day",
  "hours": "hours",
  "hour": "hour",
  "minutes": "minutes",
  "minute": "minute",
  "seconds": "seconds",
  "second": "second",
  "moments": "moments",
  "moment": "moment",
  "a": "a",
  "an": "an",
  "now": "right now",
  "yesterday": "yesterday",
  "tomorrow": "tomorrow",
  "half": "half",
  "ago": "ago",
  "in": "in",
  "last": "last",
  "next": "next",
  "less": "less",
  "more": "more",
  "than": "than",
  "few": "a few",
  "lot": "a lot",
  "and": "and",
  "at": "at",
  "almost": "almost",
  "monday": "Monday",
  "tuesday": "Tuesday",
  "wednesday": "Wednesday",
  "thursday": "Thursday",
  "friday": "Friday",
  "saturday": "Saturday",
  "sunday": "Sunday",
  "january": "January",
  "february": "February",
  "march": "March",
  "april": "April",
  "may": "May",
  "june": "June",
  "july": "July",
  "august": "August",
  "september": "September",
  "october": "October",
  "november": "November",
  "december": "December"
};
this.fuzzyLabels = fuzzyLabels;

/**
* Objects
*/
function Delta(_timestamp, _comparison) {
  this.timestamp = _timestamp;
  this.comparison = (typeof _comparison === "undefined") ? new Date() : _comparison;

  function timePrecedenceFor(timedelta, fuzzyLabel){
    if(timedelta > 0){
      return fuzzyLabel + " " + fuzzyLabels["ago"];
    }
    return fuzzyLabels["in"] + " " + fuzzyLabel;
  }

  this.ago =  function(){
    var dx = this.timestamp.getTime()/1000.0 - this.comparison.getTime()/1000.0;
    var adx = Math.abs(dx);
    var output = "";

    // assign fuzzy labels
    if(adx < 10){  // now
      output += fuzzyLabels["now"];
      return output;
    }
    else if(adx < 30){  // moments
      return timePrecedenceFor(dx, fuzzyLabels["moments"]);
    }
    else if(adx < 2*MINUTE){ // 1 minute
      return timePrecedenceFor(dx, "1 "+fuzzyLabels["minute"]);
    }
    else if(adx < 15*MINUTE){  // a few minutes
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["minutes"]);
    }
    else if(adx < 45*MINUTE){  // half an hour
      return timePrecedenceFor(dx, fuzzyLabels["half"]+" "+fuzzyLabels["an"]+" "+fuzzyLabels["hour"]);
    }
    else if(adx < 60*MINUTE){  // almost an hour
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" 1 "+fuzzyLabels["hour"]);
    }
    else if(adx < 2*HOUR){  // 1 hour
      return timePrecedenceFor(dx, "1 "+fuzzyLabels["hour"]);
    }
    else if(adx < 9*HOUR){  // a few hours
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["hours"]);
    }
    else if(adx < 12*HOUR){  // almost half a day
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" "+fuzzyLabels["half"]+" "+fuzzyLabels["a"]+" "+fuzzyLabels["day"]);
    }
    else if(adx < 18*HOUR){  // half a day
      return timePrecedenceFor(dx, fuzzyLabels["half"]+" "+fuzzyLabels["a"]+" "+fuzzyLabels["day"]);
    }
    else if(adx < 2*DAY){  // a day
      return timePrecedenceFor(dx, fuzzyLabels["a"]+" "+fuzzyLabels["day"]);
    }
    else if(adx < 5*DAY){  // a few days
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["days"]);
    }
    else if(adx < 7*DAY){  // almost a week
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" "+fuzzyLabels["a"]+" "+fuzzyLabels["week"]);
    }
    else if(adx < 14*DAY){  // a week
      return timePrecedenceFor(dx, fuzzyLabels["a"]+" "+fuzzyLabels["week"]);
    }
    else if(adx < 21*DAY){  // a few weeks
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["weeks"]);
    }
    else if(adx < MONTH){  // almost 1 month
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" 1 "+fuzzyLabels["month"]);
    }
    else if(adx < 2*MONTH){  // 1 month
      return timePrecedenceFor(dx, "1 "+fuzzyLabels["month"]);
    }
    else if(adx < 9*MONTH){  // a few months
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["months"]);
    }
    else if(adx < YEAR){  // almost 1 year
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" 1 "+fuzzyLabels["year"]);
    }
    else if(adx < 2*YEAR){  // 1 year
      return timePrecedenceFor(dx, "1 "+fuzzyLabels["year"]);
    }
    else if(adx < 8*YEAR){  // 1 year
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["years"]);
    }
    else if(adx < DECADE){  // almost 1 decade
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" 1 "+fuzzyLabels["decade"]);
    }

    else{
      throw new Error("Impossible to assign a fuzzy label");
    }
  };

  this.interval =  function(){
    console.log("Delta.interval");
  };

  this.calendar =  function(){
    console.log("Delta.calendar");
  };

  this.raw =  function(){
    var secs = (this.timestamp - this.comparison)/1000.0
    return JSON.stringify({
      "timestamp": this.timestamp,
      "comparison": this.comparison,
      "delta": {
        "centuries": secs/CENTURY,
        "decades": secs/DECADE,
        "years": secs/YEAR,
        "month": secs/MONTH,
        "days": secs/DAY,
        "hours": secs/HOUR,
        "minutes": secs/MINUTE,
        "seconds": secs
      }});
  };
}

/**
* Module exports
*/

exports.delta = function(timestamp, comparison) {
  return new Delta(timestamp, comparison);
}

exports.setFuzzyLabels = function(labels) {
  for (var key in labels){
    this.fuzzyLabels[key] = labels[key];
  }
}

exports.getFuzzyLabels = function() {
  return this.fuzzyLabels;
}
<commit_msg>Add more timestamps for ago mode<commit_after>/**
* Timehaze.js
*/

/**
* Constants
*/

// Number of seconds in a...
var MINUTE = 60;
var HOUR = MINUTE * 60;
var DAY = HOUR * 24;
var MONTH = DAY * 30.4166;  // 1 month = 365/12 days
var YEAR = MONTH * 12;
var DECADE = YEAR * 10;
var CENTURY = DECADE * 10;
var MILLENNIUM = CENTURY * 10;

/**
* Properties
*/

var fuzzyLabels = {
  "infinity": "infinity",
  "millennia": "millennia",
  "millennium": "millennium",
  "centuries": "centuries",
  "century": "century",
  "decades": "decades",
  "decade": "decade",
  "years": "years",
  "year": "year",
  "months": "months",
  "month": "month",
  "weeks": "weeks",
  "week": "week",
  "days": "days",
  "day": "day",
  "hours": "hours",
  "hour": "hour",
  "minutes": "minutes",
  "minute": "minute",
  "seconds": "seconds",
  "second": "second",
  "moments": "moments",
  "moment": "moment",
  "a": "a",
  "an": "an",
  "now": "right now",
  "yesterday": "yesterday",
  "tomorrow": "tomorrow",
  "half": "half",
  "ago": "ago",
  "in": "in",
  "last": "last",
  "next": "next",
  "less": "less",
  "more": "more",
  "than": "than",
  "few": "a few",
  "lot": "a lot",
  "and": "and",
  "at": "at",
  "almost": "almost",
  "monday": "Monday",
  "tuesday": "Tuesday",
  "wednesday": "Wednesday",
  "thursday": "Thursday",
  "friday": "Friday",
  "saturday": "Saturday",
  "sunday": "Sunday",
  "january": "January",
  "february": "February",
  "march": "March",
  "april": "April",
  "may": "May",
  "june": "June",
  "july": "July",
  "august": "August",
  "september": "September",
  "october": "October",
  "november": "November",
  "december": "December"
};
this.fuzzyLabels = fuzzyLabels;

/**
* Objects
*/
function Delta(_timestamp, _comparison) {
  this.timestamp = _timestamp;
  this.comparison = (typeof _comparison === "undefined") ? new Date() : _comparison;

  function timePrecedenceFor(timedelta, fuzzyLabel){
    if(timedelta > 0){
      return fuzzyLabel + " " + fuzzyLabels["ago"];
    }
    return fuzzyLabels["in"] + " " + fuzzyLabel;
  }

  this.ago =  function(){
    var dx = this.timestamp.getTime()/1000.0 - this.comparison.getTime()/1000.0;
    var adx = Math.abs(dx);
    var output = "";

    // assign fuzzy labels
    if(adx < 10){  // now
      output += fuzzyLabels["now"];
      return output;
    }
    else if(adx < 30){  // moments
      return timePrecedenceFor(dx, fuzzyLabels["moments"]);
    }
    else if(adx < 2*MINUTE){ // 1 minute
      return timePrecedenceFor(dx, "1 "+fuzzyLabels["minute"]);
    }
    else if(adx < 15*MINUTE){  // a few minutes
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["minutes"]);
    }
    else if(adx < 45*MINUTE){  // half an hour
      return timePrecedenceFor(dx, fuzzyLabels["half"]+" "+fuzzyLabels["an"]+" "+fuzzyLabels["hour"]);
    }
    else if(adx < 60*MINUTE){  // almost an hour
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" 1 "+fuzzyLabels["hour"]);
    }
    else if(adx < 2*HOUR){  // 1 hour
      return timePrecedenceFor(dx, "1 "+fuzzyLabels["hour"]);
    }
    else if(adx < 9*HOUR){  // a few hours
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["hours"]);
    }
    else if(adx < 12*HOUR){  // almost half a day
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" "+fuzzyLabels["half"]+" "+fuzzyLabels["a"]+" "+fuzzyLabels["day"]);
    }
    else if(adx < 18*HOUR){  // half a day
      return timePrecedenceFor(dx, fuzzyLabels["half"]+" "+fuzzyLabels["a"]+" "+fuzzyLabels["day"]);
    }
    else if(adx < 2*DAY){  // a day
      return timePrecedenceFor(dx, fuzzyLabels["a"]+" "+fuzzyLabels["day"]);
    }
    else if(adx < 5*DAY){  // a few days
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["days"]);
    }
    else if(adx < 7*DAY){  // almost a week
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" "+fuzzyLabels["a"]+" "+fuzzyLabels["week"]);
    }
    else if(adx < 14*DAY){  // a week
      return timePrecedenceFor(dx, fuzzyLabels["a"]+" "+fuzzyLabels["week"]);
    }
    else if(adx < 21*DAY){  // a few weeks
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["weeks"]);
    }
    else if(adx < MONTH){  // almost 1 month
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" 1 "+fuzzyLabels["month"]);
    }
    else if(adx < 2*MONTH){  // a month
      return timePrecedenceFor(dx, fuzzyLabels["a"]+" "+fuzzyLabels["month"]);
    }
    else if(adx < 9*MONTH){  // a few months
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["months"]);
    }
    else if(adx < YEAR){  // almost 1 year
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" 1 "+fuzzyLabels["year"]);
    }
    else if(adx < 2*YEAR){  // 1 year
      return timePrecedenceFor(dx, "1 "+fuzzyLabels["year"]);
    }
    else if(adx < 8*YEAR){  // 1 year
      return timePrecedenceFor(dx, fuzzyLabels["few"]+" "+fuzzyLabels["years"]);
    }
    else if(adx < DECADE){  // almost 1 decade
      return timePrecedenceFor(dx, fuzzyLabels["almost"]+" 1 "+fuzzyLabels["decade"]);
    }

    else{
      throw new Error("Impossible to assign a fuzzy label");
    }
  };

  this.interval =  function(){
    console.log("Delta.interval");
  };

  this.calendar =  function(){
    console.log("Delta.calendar");
  };

  this.raw =  function(){
    var secs = (this.timestamp - this.comparison)/1000.0
    return JSON.stringify({
      "timestamp": this.timestamp,
      "comparison": this.comparison,
      "delta": {
        "centuries": secs/CENTURY,
        "decades": secs/DECADE,
        "years": secs/YEAR,
        "month": secs/MONTH,
        "days": secs/DAY,
        "hours": secs/HOUR,
        "minutes": secs/MINUTE,
        "seconds": secs
      }});
  };
}

/**
* Module exports
*/

exports.delta = function(timestamp, comparison) {
  return new Delta(timestamp, comparison);
}

exports.setFuzzyLabels = function(labels) {
  for (var key in labels){
    this.fuzzyLabels[key] = labels[key];
  }
}

exports.getFuzzyLabels = function() {
  return this.fuzzyLabels;
}
<|endoftext|>


<commit_before>//    Timeline.js
//    (c) 2010-2011 Tim Hudson
//    Timeline.js may be freely distributed under the MIT license.

(function(context) {

  var cache = [];

  var timeline = {};

  // Add animation object which requires start, stop and callback { start: 0, stop: 0.4, callback: function() {} }
  timeline.add = function(animation) {

    // Cache of all animations
    cache.push(animation);

    return this;
  };

  timeline.remove = function(animation) {

    var index = cache.indexOf(animation);

    if (index !== -1) {
      cache.splice(index, 1);
    }

    return this;
  };

  timeline.run = function(value) {

    function animate() {

      var l = cache.length;

      for(var i = 0; i < l; i++) {

        var animation = cache[i],
            _time = relativeTime(animation.start, animation.stop),
            _values = relativeValues(animation, _time);
            repeat = animation.previousTime === _time;

        // Run animation if not a repeat of last update
        if (!repeat) animation.callback(_values, _time);

        // Cache previous time
        animation.previousTime = _time;
      }

      return this;
    }

    function relativeTime(start, stop) {
      var length = stop - start,
          position = value - start,
          _time = position / length;

      ret = _time >= 1 ? 1 :
            _time <= 0 ? 0 : _time;

      return ret;
    }

    function relativeValues(animation, relativeTime) {

      var animationFrom = animation['from'],
          animationTo = animation['to'];

      var ret = {};

      for ( var key in animation['to'] ) {

        ret[key] = (( animationTo[key] - animationFrom[key]) * relativeTime ) + animationFrom[key];

      }

      return ret;
    }

    animate();

    return this;

  };

  context.timeline = timeline;

}(this));<commit_msg>cleaned up for loop<commit_after>//    Timeline.js
//    (c) 2010-2011 Tim Hudson
//    Timeline.js may be freely distributed under the MIT license.

(function(context) {

  var cache = [];

  var timeline = {};

  // Add animation object which requires start, stop and callback { start: 0, stop: 0.4, callback: function() {} }
  timeline.add = function(animation) {

    // Cache of all animations
    cache.push(animation);

    return this;
  };

  timeline.remove = function(animation) {

    var index = cache.indexOf(animation);

    if (index !== -1) {
      cache.splice(index, 1);
    }

    return this;
  };

  timeline.run = function(value) {

    function animate() {

      for(var i = 0, l = cache.length; i < l; i++) {

        var animation = cache[i],
            _time = relativeTime(animation.start, animation.stop),
            _values = relativeValues(animation, _time);
            repeat = animation.previousTime === _time;

        // Run animation if not a repeat of last update
        if (!repeat) animation.callback(_values, _time);

        // Cache previous time
        animation.previousTime = _time;
      }

      return this;
    }

    function relativeTime(start, stop) {
      var length = stop - start,
          position = value - start,
          _time = position / length;

      ret = _time >= 1 ? 1 :
            _time <= 0 ? 0 : _time;

      return ret;
    }

    function relativeValues(animation, relativeTime) {

      var animationFrom = animation['from'],
          animationTo = animation['to'];

      var ret = {};

      for ( var key in animation['to'] ) {

        ret[key] = (( animationTo[key] - animationFrom[key]) * relativeTime ) + animationFrom[key];

      }

      return ret;
    }

    animate();

    return this;

  };

  context.timeline = timeline;

}(this));<|endoftext|>


<commit_before>/*
 * Javascript translation definition
 * Example to help translation of some English strings in some js files
 *
 * $Id: language.js 30343 2010-10-27 12:50:51Z xavidp $
 */

lang = {
//	"Very Secure" : "Very Secure",
//	"Secure" : "Secure",
//	"Very Strong" : "Very Strong",
//	"Strong" : "Strong",
//	"Average" : "Average",
//	"Weak" : "Weak",
//	"Very Weak" : "Very Weak",
//	"Strength" : "Strength",
//	"Valid User Name" : "Valid User Name",
//	"Passwords match" : "Passwords match",
//	"Valid Email" : "Valid Email",
//	"Close" : "Close",
//	"Submit" : "Submit",
//	"Insert" : "Insert",
//	"Replace" : "Replace",
//	"Match" : "Match",
//	"Do not match" : "Do not match",
//	"Advanced options" : "Advanced options",
//	"Pick a file." : "Pick a file.",
};
<commit_msg>[FIX]Hebrew language translation completed<commit_after>/*
 * Javascript translation definition
 * Example to help translation of some English strings in some js files
 *
 * $Id: language.js 30343 2010-10-27 12:50:51Z xavidp $
 */

lang = {
"Very Secure" : "מאובטח מאוד",
"Secure" : "מאובטח",
"Very Strong" : "חזק מאוד",
"Strong" : "חזק",
"Average" : "ממוצע",
"Weak" : "חלש",
"Very Weak" : "חלש מאוד",
"Strength" : "רמה",
"Valid User Name" : "שם משתמש תקף",
"Passwords match" : "ססמאות זהים",
"Valid Email" : "דואר אלקטרוני תקף",
"Close" : "סגור",
"Submit" : "להגיש",
"Insert" : "להכניס",
"Replace" : "להחליף",
"Match" : "מתאים",
"Do not match" : "אין התאמה",
"Advanced options" : "אפשרויות מתקדמות",
"Pick a file." : "בחירת הקובץ.",
};
<|endoftext|>


<commit_before>"use strict";

//public interface
var drawing = {};

/*
 * exemple of room & openings description
 */

var temp_openings = [
  {
    posx : 450,
    posy : 100,
    orientation : "horizontal",
    type : "door"
  },
  {
    posx : 300,
    posy : 150,
    orientation : "vertical",
    type : "door"
  },
  {
    posx : 350,
    posy : 250,
    orientation : "horizontal",
    type : "door"
  },
  {
    posx : 350,
    posy : 400,
    orientation : "horizontal",
    type : "window"
  },
  {
    posx : 500,
    posy : 400,
    orientation : "horizontal",
    type : "window"
  },
  {
    posx : 300,
    posy : 320,
    orientation : "vertical",
    type : "window"
  }
];

var temp_rooms = [
  {
    name : "chambre 1" ,
    height : 150,
    width : 200,
    posx : 100,
    posy : 100
  },
  {
    name : "salon",
    height : 150,
    width : 250,
    posx : 300,
    posy : 100
  },
  {
    name : "cuisine",
    height : 150,
    width : 250,
    posx : 300,
    posy : 250
  }
];

(function (){ // begin scope

  const INNER_WALL_W = 4;
  const OPENING_SIZE = 30;
  const SVG_ID = 'drawing';
  const TEXT_OFFSET = 40;

  var room_colors = [
    "blue",
    "green",
    "yellow",
    "red",
  ];

  var svg_area = SVG(SVG_ID).size("100%", "100%");

  //layer containing objects
  //the order matters when drawing
  var floor_layer = svg_area
    .group()
    .addClass("drawing__room_floor");
  var wall_layer = svg_area
    .group()
    .addClass("drawing__room");
  var opening_layer = svg_area
    .group()
    .addClass("drawing__opening");
  var hole_mask_layer = svg_area
    .group()
    .addClass("drawing__opening_holes");
  var text_layer = svg_area
    .group()
    .addClass("drawing__text");

  //the canvas max and min values, used when creating masks
  var canvas_limit = {
    min_x : 0,
    min_y : 0,
    max_x : 0,
    max_y : 0,
  };

  function update_canvas_limits(posx, posy, width, height) {
      if( (posx - INNER_WALL_W) < canvas_limit.min_x ){
        canvas_limit.min_x = (posx - INNER_WALL_W);
      }
      if( (posy - INNER_WALL_W) < canvas_limit.min_y ){
        canvas_limit.min_y = (posy - INNER_WALL_W);
      }

      if( (posx + INNER_WALL_W + width) > canvas_limit.max_x ){
        canvas_limit.max_x = (posx + INNER_WALL_W + width);
      }
      if( (posy + INNER_WALL_W + height) > canvas_limit.max_y ){
        canvas_limit.max_y = (posy + INNER_WALL_W + height);
      }
  }

  //methods to draw openings on the canvas
  var opening_model = {};

  opening_model.door = function(svg_area, posx, posy, size, orientation) {
    //posx passed to the function is the middle of the door
    var x, y;
    if (orientation == "horizontal") {
      x = posx - (size/2);
      y = posy;
    }
    else {
      x = posx;
      y = posy - (size/2);
    }
    return svg_area
      .path(" M "+x+" "+y
          + " h "+size
          + " c "+0+" "+(size/2)+" "+(-size/2)+" "+size+" "+(-size)+" "+size
          + " v "+(-size));
  }

  opening_model.window = function(svg_area, posx, posy, size, orientation) {
    //posx passed to the function is the middle of the door
    var x, y;
    var window_shape;

    if (orientation == "horizontal") {
      window_shape = svg_area
        .rect(size, INNER_WALL_W)
        .x(posx - (size/2) )
        .y(posy - INNER_WALL_W / 2 );
    }
    else {
      window_shape = svg_area
        .rect(INNER_WALL_W, size)
        .x( posx - INNER_WALL_W / 2 )
        .y( posy - (size/2) );
    }

    return window_shape
  }

  //public methods
  drawing.draw_rooms = function( rooms ) {

    for (var i=0; i<rooms.length; i++) {
      var r = rooms[i];

      var floor_rect = svg_area
        .rect(r.width , r.height )
        .x(r.posx)
        .y(r.posy)
        .fill(room_colors[ i % room_colors.length ]);

      floor_layer.add(floor_rect);

      //draw the walls
      var room_rect = svg_area
        .rect(r.width , r.height )
        .x(r.posx)
        .y(r.posy);

      wall_layer.add(room_rect);

      update_canvas_limits(r.posx, r.posy, r.width, r.height);

      //draw the text
      var room_name = svg_area
        .text(r.name)
        .x(r.posx + TEXT_OFFSET )
        .y(r.posy + TEXT_OFFSET );

      text_layer.add(room_name);

    }
  }

  drawing.draw_openings = function( openings ) {

    //put global mask contour in the path
    var holes_path = "M" + canvas_limit.min_x + " " + canvas_limit.min_y
      + " H " + canvas_limit.max_x
      + " V " + canvas_limit.max_y
      + " H " + canvas_limit.min_x
      + " V " + canvas_limit.min_y
      + "z";

    for (var i=0; i<openings.length; i++) {
      var o = openings[i];

      var opening_shape = opening_model[o.type](
          svg_area,
          o.posx, o.posy,
          OPENING_SIZE,
          o.orientation);

      opening_layer.add(opening_shape);

      if(o.orientation == "horizontal"){
        holes_path += "M " + (o.posx - (OPENING_SIZE/2))
          + " "   + (o.posy - INNER_WALL_W)
          + " v " + INNER_WALL_W*2
          + " h " + OPENING_SIZE
          + " v " + (-INNER_WALL_W*2)
          + " h " + (-OPENING_SIZE)
          + "z"
      }
      else {
        holes_path += "M " + (o.posx - INNER_WALL_W)
          + "   " + (o.posy - (OPENING_SIZE/2))
          + " v " + OPENING_SIZE
          + " h " + INNER_WALL_W*2
          + " v " + (-OPENING_SIZE)
          + " h " + (-INNER_WALL_W*2)
          + "z"
      }
    }

    var mask = svg_area
      .path(holes_path);

    hole_mask_layer.add(mask);

    wall_layer.clipWith(mask);
  }

  //drag events on the drawing
  var svg_element = document.getElementById(SVG_ID);

  svg_element.onmousedown = function(e) {
    if(e.buttons == 1){

      var start_box = svg_area.viewbox();
      var start_e = { clientX : e.clientX, clientY : e.clientY };

      svg_element.onmousemove = function(e) {
        var new_box = {
          x : start_box.x - (e.clientX - start_e.clientX),
          y : start_box.y - (e.clientY - start_e.clientY),
          width : start_box.width,
          height : start_box.height
        }
        svg_area.viewbox(new_box);
      }

    }
  }

  svg_element.onmouseleave = function(e) {
    svg_element.onmousemove = null;
  }

  svg_element.onmouseup = function(e) {
    if(e.buttons != 1){
        svg_element.onmousemove = null;
    }
  }

}()) // end scope

drawing.draw_rooms(temp_rooms);
drawing.draw_openings(temp_openings);

// vim: set ts=2 sw=2:
<commit_msg>zoom in and out with mousewheel<commit_after>"use strict";

//public interface
var drawing = {};

/*
 * exemple of room & openings description
 */

var temp_openings = [
  {
    posx : 450,
    posy : 100,
    orientation : "horizontal",
    type : "door"
  },
  {
    posx : 300,
    posy : 150,
    orientation : "vertical",
    type : "door"
  },
  {
    posx : 350,
    posy : 250,
    orientation : "horizontal",
    type : "door"
  },
  {
    posx : 350,
    posy : 400,
    orientation : "horizontal",
    type : "window"
  },
  {
    posx : 500,
    posy : 400,
    orientation : "horizontal",
    type : "window"
  },
  {
    posx : 300,
    posy : 320,
    orientation : "vertical",
    type : "window"
  }
];

var temp_rooms = [
  {
    name : "chambre 1" ,
    height : 150,
    width : 200,
    posx : 100,
    posy : 100
  },
  {
    name : "salon",
    height : 150,
    width : 250,
    posx : 300,
    posy : 100
  },
  {
    name : "cuisine",
    height : 150,
    width : 250,
    posx : 300,
    posy : 250
  }
];

(function (){ // begin scope

  const INNER_WALL_W = 4;
  const OPENING_SIZE = 30;
  const SVG_ID = 'drawing';
  const TEXT_OFFSET = 40;
  const ZOOM_STEP = 0.1;

  var room_colors = [
    "blue",
    "green",
    "yellow",
    "red",
  ];

  var svg_area = SVG(SVG_ID).size("100%", "100%");

  //layer containing objects
  //the order matters when drawing
  var floor_layer = svg_area
    .group()
    .addClass("drawing__room_floor");
  var wall_layer = svg_area
    .group()
    .addClass("drawing__room");
  var opening_layer = svg_area
    .group()
    .addClass("drawing__opening");
  var hole_mask_layer = svg_area
    .group()
    .addClass("drawing__opening_holes");
  var text_layer = svg_area
    .group()
    .addClass("drawing__text");

  //the canvas max and min values, used when creating masks
  var canvas_limit = {
    min_x : 0,
    min_y : 0,
    max_x : 0,
    max_y : 0,
  };

  function update_canvas_limits(posx, posy, width, height) {
      if( (posx - INNER_WALL_W) < canvas_limit.min_x ){
        canvas_limit.min_x = (posx - INNER_WALL_W);
      }
      if( (posy - INNER_WALL_W) < canvas_limit.min_y ){
        canvas_limit.min_y = (posy - INNER_WALL_W);
      }

      if( (posx + INNER_WALL_W + width) > canvas_limit.max_x ){
        canvas_limit.max_x = (posx + INNER_WALL_W + width);
      }
      if( (posy + INNER_WALL_W + height) > canvas_limit.max_y ){
        canvas_limit.max_y = (posy + INNER_WALL_W + height);
      }
  }

  //methods to draw openings on the canvas
  var opening_model = {};

  opening_model.door = function(svg_area, posx, posy, size, orientation) {
    //posx passed to the function is the middle of the door
    var x, y;
    if (orientation == "horizontal") {
      x = posx - (size/2);
      y = posy;
    }
    else {
      x = posx;
      y = posy - (size/2);
    }
    return svg_area
      .path(" M "+x+" "+y
          + " h "+size
          + " c "+0+" "+(size/2)+" "+(-size/2)+" "+size+" "+(-size)+" "+size
          + " v "+(-size));
  }

  opening_model.window = function(svg_area, posx, posy, size, orientation) {
    //posx passed to the function is the middle of the door
    var x, y;
    var window_shape;

    if (orientation == "horizontal") {
      window_shape = svg_area
        .rect(size, INNER_WALL_W)
        .x(posx - (size/2) )
        .y(posy - INNER_WALL_W / 2 );
    }
    else {
      window_shape = svg_area
        .rect(INNER_WALL_W, size)
        .x( posx - INNER_WALL_W / 2 )
        .y( posy - (size/2) );
    }

    return window_shape
  }

  //public methods
  drawing.draw_rooms = function( rooms ) {

    for (var i=0; i<rooms.length; i++) {
      var r = rooms[i];

      var floor_rect = svg_area
        .rect(r.width , r.height )
        .x(r.posx)
        .y(r.posy)
        .fill(room_colors[ i % room_colors.length ]);

      floor_layer.add(floor_rect);

      //draw the walls
      var room_rect = svg_area
        .rect(r.width , r.height )
        .x(r.posx)
        .y(r.posy);

      wall_layer.add(room_rect);

      update_canvas_limits(r.posx, r.posy, r.width, r.height);

      //draw the text
      var room_name = svg_area
        .text(r.name)
        .x(r.posx + TEXT_OFFSET )
        .y(r.posy + TEXT_OFFSET );

      text_layer.add(room_name);

    }
  }

  drawing.draw_openings = function( openings ) {

    //put global mask contour in the path
    var holes_path = "M" + canvas_limit.min_x + " " + canvas_limit.min_y
      + " H " + canvas_limit.max_x
      + " V " + canvas_limit.max_y
      + " H " + canvas_limit.min_x
      + " V " + canvas_limit.min_y
      + "z";

    for (var i=0; i<openings.length; i++) {
      var o = openings[i];

      var opening_shape = opening_model[o.type](
          svg_area,
          o.posx, o.posy,
          OPENING_SIZE,
          o.orientation);

      opening_layer.add(opening_shape);

      if(o.orientation == "horizontal"){
        holes_path += "M " + (o.posx - (OPENING_SIZE/2))
          + " "   + (o.posy - INNER_WALL_W)
          + " v " + INNER_WALL_W*2
          + " h " + OPENING_SIZE
          + " v " + (-INNER_WALL_W*2)
          + " h " + (-OPENING_SIZE)
          + "z"
      }
      else {
        holes_path += "M " + (o.posx - INNER_WALL_W)
          + "   " + (o.posy - (OPENING_SIZE/2))
          + " v " + OPENING_SIZE
          + " h " + INNER_WALL_W*2
          + " v " + (-OPENING_SIZE)
          + " h " + (-INNER_WALL_W*2)
          + "z"
      }
    }

    var mask = svg_area
      .path(holes_path);

    hole_mask_layer.add(mask);

    wall_layer.clipWith(mask);
  }

  //drag events on the drawing
  var svg_element = document.getElementById(SVG_ID);
  var ref_viewbox = svg_area.viewbox();
  var scaling_factor = 1;

  svg_element.onmousedown = function(e) {
    if(e.buttons == 1){

      var start_box = svg_area.viewbox();
      var start_e = {
        clientX : e.clientX,
        clientY : e.clientY
      };

      svg_element.onmousemove = function(e) {
        var new_box = {
          x : (start_box.x - (e.clientX - start_e.clientX ) * scaling_factor) ,
          y : (start_box.y - (e.clientY - start_e.clientY ) * scaling_factor) ,
          width : start_box.width,
          height : start_box.height
        }
        svg_area.viewbox(new_box);
      }

    }
  }

  svg_element.onmouseleave = function(e) {
    svg_element.onmousemove = null;
  }

  svg_element.onmouseup = function(e) {
    if(e.buttons != 1){
        svg_element.onmousemove = null;
    }
  }

  svg_element.onwheel = function(e) {
    var start_viewbox = svg_area.viewbox();
    var new_viewbox = {};
    var delta;

    if( e.deltaY < 0 ) {
      delta = -1;
    }
    else if ( e.deltaY > 0) {
      delta = 1;
    }

    scaling_factor += ZOOM_STEP * delta ;

    new_viewbox.height = ref_viewbox.height * scaling_factor;
    new_viewbox.width  = ref_viewbox.width  * scaling_factor;
    new_viewbox.x
      = start_viewbox.x + (( start_viewbox.width - new_viewbox.width ) /2)
    new_viewbox.y
      = start_viewbox.y + (( start_viewbox.height - new_viewbox.height ) /2)

    console.log(ref_viewbox);
    console.log(new_viewbox);

    if (new_viewbox.height <= 0 || new_viewbox.width <= 0) {
        return;
    }

    svg_area.viewbox(new_viewbox);
  }

}()) // end scope

drawing.draw_rooms(temp_rooms);
drawing.draw_openings(temp_openings);

// vim: set ts=2 sw=2:
<|endoftext|>


<commit_before>exports.ru = {
    profile: 'Профиль',
    logout: 'Выход',
    search: 'Поиск...',

    buttonsTxt: {
        add: 'Добавить',
        enable: 'Включить',
        disable: 'Отключить',
        cancel: 'Отмена',
        back: 'Назад',
        close: 'Закрыть',
        edit: 'Редактировать',
        'delete': 'Удалить',
        submit: 'Подвердить',
        save: 'Сохранить',
        confirm: 'Подтвердить',
        create: 'Создать',
        subscribe: 'Подписаться',
        send: 'Отправить',
        show: 'Показать',
        change: 'Сменить',
        refresh: 'Обновить',
        download: 'Скачать'
    },

    dateTime: {
        seconds: 'Только что',
        minutes: {
            min: 'минуту',
            middle: 'минуты',
            max: 'минут'
        },
        hours: {
            min: 'час',
            middle: 'часа',
            max: 'часов'
        },

        days: {
            min: 'день',
            middle: 'дня',
            max: 'дней'
        }
    },

    crudText: {
        confirm: {
            title: 'Подтверждение',
            body: 'Пожалуйста, подтвердите операцию'
        },

        table: {
            search: 'Поиск',
            info: 'Показано с _START_ по _END_ из _TOTAL_ записей',
            length: '_MENU_ количество записей',
            empty: 'Таблица пустая',
            emptyTable: 'Нет данных для таблицы',
            zeroRecords: 'Нет совпадений в таблице',
            filtered: '- поиск в _MAX_ записей',
            prev: 'Назад',
            next: 'Вперед',
            processing: 'Обработка...'
        },

        create: 'Создать',
        add: 'Добавить',
        remove: 'Убрать',
        save: 'Сохранить',
        process: 'Обработка задания...',
        cancel: 'Отмена',
        waitForOperation: 'Дождитесь обработки текущего процесса заданий прежде чем начать новый',
        warning: 'Внимание',
        success: 'Успешно',
        refresh: 'Обновить',
        empty: 'Выберите задания для отправки',
        done: 'Обработка заданий завершена.',
        operation: 'Операция',

        status: {
            created: 'Создан',
            success: 'Успешно',
            paused: 'Выключен',
            process: 'В обработке',
            error: 'Ошибка',
            deleted: 'Удален',
            warning: 'Ошибка',
            unknown: 'Неизвестно'
        }
    },

    home: {
        menu: 'Приборная панель',
        index: ''
    },

    management: {
        menu: 'Управление',
        users: 'Пользователи',
        groups: 'Группы',
        roles: 'Роли'
    },

    haproxy: {
        menu: 'HAProxy',
        configs: 'Конф. файлы',
        settings: 'Настройки'
    },

    nginx: {
        menu: 'NGINX',
        configs: 'Конф. файлы',
        groups: 'Группы конфигов',
        templates: 'Шаблоны'
    },

    monitoring: {
        menu: 'Мониторинг',
        nodes: 'Узлы',
        netmap: 'Сетевая карта узлов',
        settings: 'Настройки'
    },

    server: {
        menu: 'Сервера',
        info: 'Информация',
        groups: 'Группы'
    },

    task: {
        created: 'Задание успешно отправлено в очередь.',
        createError: 'Произошла внутренняя ошибка сервера при отправке задания. Обратитесь к администратору.',
        success: 'Задание успешно выполнено. Открыть задание.',
        error: 'Задание завершилось с ошибкой. Открыть задание.',

        title: {
            success: 'Успешно',
            warning: 'Предупреждение',
            danger: 'Ошибка'
        }
    },

    validation: {
        required: "Поле обязательное для ввода.",
        remote: "Исправьте это поле.",
        email: "Введите корректный email адрес.",
        url: "Введите корректный URL адрес.",
        date: "Введите корректную дату.",
        dateISO: "Введите корректную дату (ISO формат).",
        number: "Введите число.",
        digits: "Введите целое число.",
        creditcard: "Введите корректный номер карты.",
        equalTo: "Введите тоже самое значение еще раз",
        accept: "Введите значение с допустимым расширением.",
        maxlength: "Введите не более чем {0} символов.",
        minlength: "Введите не менее чем {0} символов.",
        rangelength: "Введите значение, содержащие от {0} до {1} символов.",
        range: "Введите значение в диапозоне от {0} до {1}.",
        max: "Введите значение, которое меньше или равно {0}.",
        min: "Введите значение, которое больше или равно {0}.",
        regex: 'Данные не соответствуют шаблону {0}.'
    }
};

exports.us = {
    profile: 'My Profile',
    logout: 'Log Out',
    search: 'Search...',

    buttonsTxt: {
        add: 'Add',
        enable: 'Enable',
        disable: 'Disable',
        cancel: 'Cancel',
        back: 'Back',
        close: 'Close',
        edit: 'Edit',
        'delete': 'Delete',
        submit: 'Submit',
        save: 'Save',
        confirm: 'Confirm',
        create: 'Create',
        subscribe: 'Subscribe',
        send: 'Send',
        show: 'Show',
        change: 'Change',
        refresh: 'Refresh',
        download: 'Download'
    },

    dateTime: {
        seconds: 'Just now',
        minutes: {
            min: 'minute',
            middle: 'mins',
            max: 'mins'
        },
        hours: {
            min: 'hour',
            middle: 'hrs',
            max: 'hrs'
        },

        days: {
            min: 'day',
            middle: 'days',
            max: 'days'
        }
    },

    crudText: {
        confirm: {
            title: 'Confirm',
            body: 'Please, confirm the operation'
        },

        create: 'Create',
        add: 'Add',
        remove: 'Remove',
        save: 'Save',
        process: 'Processing the tasks...',
        cancel: 'Cancel',
        waitForOperation: 'Wait for the current processing of tasks before beginning the new',
        warning: 'Warning',
        success: 'Success',
        refresh: 'Refresh',
        empty: 'Select tasks for processing',
        done: 'Processing the tasks is completed.',
        operation: 'Operation',

        status: {
            created: 'Created',
            success: 'Success',
            paused: 'Paused',
            process: 'Processing',
            error: 'Error',
            deleted: 'Deleted',
            warning: 'Error',
            unknown: 'Unknown'
        }
    },

    home: {
        menu: 'Dashboard',
        index: ''
    },

    management: {
        menu: 'Management',
        users: 'Users',
        groups: 'Groups',
        roles: 'Roles'
    },

    haproxy: {
        menu: 'HAProxy',
        configs: 'Configs',
        settings: 'Settings'
    },

    nginx: {
        menu: 'NGINX',
        configs: 'Configs',
        groups: 'Config groups',
        templates: 'Templates'
    },

    monitoring: {
        menu: 'Monitoring',
        nodes: 'Nodes',
        netmap: 'Network map nodes',
        settings: 'Settings'
    },

    server: {
        menu: 'Servers',
        info: 'Info',
        groups: 'Groups'
    },

    task: {
        created: 'Task has been successfully sent to the queue.',
        createError: 'An internal server error occurred while sending a task. Contact your administrator.',
        success: 'Task completed successfully. View task.',
        error: 'Task failed. View task.',

        title: {
            success: 'Success',
            warning: 'Warning',
            danger: 'Error'
        }
    },

    validation: {
        required: 'This field is required.',
        remote: "Please fix this field.",
        email: "Please enter a valid email address.",
        url: "Please enter a valid URL.",
        date: "Please enter a valid date.",
        dateISO: "Please enter a valid date (ISO).",
        number: "Please enter a valid number.",
        digits: "Please enter only digits.",
        creditcard: "Please enter a valid credit card number.",
        equalTo: "Please enter the same value again.",
        accept: "Please enter a value with a valid extension.",
        maxlength: "Please enter no more than {0} characters.",
        minlength: "Please enter at least {0} characters.",
        rangelength: "Please enter a value between {0} and {1} characters long.",
        range: "Please enter a value between {0} and {1}.",
        max: "Please enter a value less than or equal to {0}.",
        min: "Please enter a value greater than or equal to {0}.",
        regex: 'The data do not match the pattern {0}.'
    }
};<commit_msg>add 404 words, remove modules menus<commit_after>exports.ru = {
    profile: 'Профиль',
    logout: 'Выход',
    search: 'Поиск...',

    buttonsTxt: {
        add: 'Добавить',
        enable: 'Включить',
        disable: 'Отключить',
        cancel: 'Отмена',
        back: 'Назад',
        close: 'Закрыть',
        edit: 'Редактировать',
        'delete': 'Удалить',
        submit: 'Подвердить',
        save: 'Сохранить',
        confirm: 'Подтвердить',
        create: 'Создать',
        subscribe: 'Подписаться',
        send: 'Отправить',
        show: 'Показать',
        change: 'Сменить',
        refresh: 'Обновить',
        download: 'Скачать'
    },

    dateTime: {
        seconds: 'Только что',
        minutes: {
            min: 'минуту',
            middle: 'минуты',
            max: 'минут'
        },
        hours: {
            min: 'час',
            middle: 'часа',
            max: 'часов'
        },

        days: {
            min: 'день',
            middle: 'дня',
            max: 'дней'
        }
    },

    crudText: {
        confirm: {
            title: 'Подтверждение',
            body: 'Пожалуйста, подтвердите операцию'
        },

        table: {
            search: 'Поиск',
            info: 'Показано с _START_ по _END_ из _TOTAL_ записей',
            length: '_MENU_ количество записей',
            empty: 'Таблица пустая',
            emptyTable: 'Нет данных для таблицы',
            zeroRecords: 'Нет совпадений в таблице',
            filtered: '- поиск в _MAX_ записей',
            prev: 'Назад',
            next: 'Вперед',
            processing: 'Обработка...'
        },

        create: 'Создать',
        add: 'Добавить',
        remove: 'Убрать',
        save: 'Сохранить',
        process: 'Обработка задания...',
        cancel: 'Отмена',
        waitForOperation: 'Дождитесь обработки текущего процесса заданий прежде чем начать новый',
        warning: 'Внимание',
        success: 'Успешно',
        refresh: 'Обновить',
        empty: 'Выберите задания для отправки',
        done: 'Обработка заданий завершена.',
        operation: 'Операция',

        status: {
            created: 'Создан',
            success: 'Успешно',
            paused: 'Выключен',
            process: 'В обработке',
            error: 'Ошибка',
            deleted: 'Удален',
            warning: 'Ошибка',
            unknown: 'Неизвестно'
        }
    },

    modulesTitle: 'Модули',

    home: {
        menu: 'Приборная панель',
        index: ''
    },

    management: {
        menu: 'Управление',
        users: 'Пользователи',
        groups: 'Группы',
        roles: 'Роли'
    },

    server: {
        menu: 'Сервера',
        info: 'Информация',
        groups: 'Группы'
    },

    task: {
        created: 'Задание успешно отправлено в очередь.',
        createError: 'Произошла внутренняя ошибка сервера при отправке задания. Обратитесь к администратору.',
        success: 'Задание успешно выполнено. Открыть задание.',
        error: 'Задание завершилось с ошибкой. Открыть задание.',

        title: {
            success: 'Успешно',
            warning: 'Предупреждение',
            danger: 'Ошибка'
        }
    },

    validation: {
        required: "Поле обязательное для ввода.",
        remote: "Исправьте это поле.",
        email: "Введите корректный email адрес.",
        url: "Введите корректный URL адрес.",
        date: "Введите корректную дату.",
        dateISO: "Введите корректную дату (ISO формат).",
        number: "Введите число.",
        digits: "Введите целое число.",
        creditcard: "Введите корректный номер карты.",
        equalTo: "Введите тоже самое значение еще раз",
        accept: "Введите значение с допустимым расширением.",
        maxlength: "Введите не более чем {0} символов.",
        minlength: "Введите не менее чем {0} символов.",
        rangelength: "Введите значение, содержащие от {0} до {1} символов.",
        range: "Введите значение в диапозоне от {0} до {1}.",
        max: "Введите значение, которое меньше или равно {0}.",
        min: "Введите значение, которое больше или равно {0}.",
        regex: 'Данные не соответствуют шаблону {0}.'
    },

    404: {
        title: 'Упс! Кажется вы потерялись.',
        text: 'Мы не можем найти запрашиваемою страницу.',
        home: 'Домой'
    }
};

exports.us = {
    profile: 'My Profile',
    logout: 'Log Out',
    search: 'Search...',

    buttonsTxt: {
        add: 'Add',
        enable: 'Enable',
        disable: 'Disable',
        cancel: 'Cancel',
        back: 'Back',
        close: 'Close',
        edit: 'Edit',
        'delete': 'Delete',
        submit: 'Submit',
        save: 'Save',
        confirm: 'Confirm',
        create: 'Create',
        subscribe: 'Subscribe',
        send: 'Send',
        show: 'Show',
        change: 'Change',
        refresh: 'Refresh',
        download: 'Download'
    },

    dateTime: {
        seconds: 'Just now',
        minutes: {
            min: 'minute',
            middle: 'mins',
            max: 'mins'
        },
        hours: {
            min: 'hour',
            middle: 'hrs',
            max: 'hrs'
        },

        days: {
            min: 'day',
            middle: 'days',
            max: 'days'
        }
    },

    crudText: {
        confirm: {
            title: 'Confirm',
            body: 'Please, confirm the operation'
        },

        create: 'Create',
        add: 'Add',
        remove: 'Remove',
        save: 'Save',
        process: 'Processing the tasks...',
        cancel: 'Cancel',
        waitForOperation: 'Wait for the current processing of tasks before beginning the new',
        warning: 'Warning',
        success: 'Success',
        refresh: 'Refresh',
        empty: 'Select tasks for processing',
        done: 'Processing the tasks is completed.',
        operation: 'Operation',

        status: {
            created: 'Created',
            success: 'Success',
            paused: 'Paused',
            process: 'Processing',
            error: 'Error',
            deleted: 'Deleted',
            warning: 'Error',
            unknown: 'Unknown'
        }
    },

    modulesTitle: 'Modules',

    home: {
        menu: 'Dashboard',
        index: ''
    },

    management: {
        menu: 'Management',
        users: 'Users',
        groups: 'Groups',
        roles: 'Roles'
    },

    server: {
        menu: 'Servers',
        info: 'Info',
        groups: 'Groups'
    },

    task: {
        created: 'Task has been successfully sent to the queue.',
        createError: 'An internal server error occurred while sending a task. Contact your administrator.',
        success: 'Task completed successfully. View task.',
        error: 'Task failed. View task.',

        title: {
            success: 'Success',
            warning: 'Warning',
            danger: 'Error'
        }
    },

    validation: {
        required: 'This field is required.',
        remote: "Please fix this field.",
        email: "Please enter a valid email address.",
        url: "Please enter a valid URL.",
        date: "Please enter a valid date.",
        dateISO: "Please enter a valid date (ISO).",
        number: "Please enter a valid number.",
        digits: "Please enter only digits.",
        creditcard: "Please enter a valid credit card number.",
        equalTo: "Please enter the same value again.",
        accept: "Please enter a value with a valid extension.",
        maxlength: "Please enter no more than {0} characters.",
        minlength: "Please enter at least {0} characters.",
        rangelength: "Please enter a value between {0} and {1} characters long.",
        range: "Please enter a value between {0} and {1}.",
        max: "Please enter a value less than or equal to {0}.",
        min: "Please enter a value greater than or equal to {0}.",
        regex: 'The data do not match the pattern {0}.'
    },

    404: {
        title: 'Oops! I think you are lost.',
        text: 'We can not find the requested page.',
        home: 'Home'
    }
};<|endoftext|>


<commit_before>const spawn = require('child_process').spawn;
const path = require('path');
const resolveBin = require('resolve-bin');

function runCompiler(source, name, executable, config) {
  return new Promise((resolve, reject) => {
    resolveBin(name, {executable}, (err, bin) => {
      const tsconfig = path.join(source, 'tsconfig.json');
      const extras = config ? Object.keys(config).reduce((accumulator, key) => {
        return accumulator.concat(key, config[key])
      }, []) : [];

      const childProcess = spawn('node', [bin, '-p', tsconfig].concat(extras));

      childProcess.stdout.on('data', data => process.stdout.write(data));
      childProcess.stderr.on('data', data => process.stderr.write(data));
      childProcess.on('close', code => code === 0 ? resolve(code) : reject(code));
    });
  });
}

// Compiles TypeScript files using the Angular compiler.
module.exports.ngc = (source, overrides) => {
  return done => {
    runCompiler(source, '@angular/compiler-cli', 'ngc', overrides).then(done, done);
  };
};

// Compiles TypeScript files using the TypeScript compiler.
module.exports.tsc = (source, overrides) => {
  return done => {
    runCompiler(source, 'typescript', 'tsc', overrides).then(done, done);
  };
};
<commit_msg>chore: slightly shorter way to generate the cli args<commit_after>const spawn = require('child_process').spawn;
const path = require('path');
const resolveBin = require('resolve-bin');

function runCompiler(source, name, executable, overrides) {
  return new Promise((resolve, reject) => {
    resolveBin(name, {executable}, (err, bin) => {
      const tsconfig = path.join(source, 'tsconfig.json');
      const args = Object.keys(overrides || {}).reduce((accumulator, key) => {
        return accumulator.concat(key, overrides[key])
      }, [bin, '-p', tsconfig]);
      const childProcess = spawn('node', args);

      childProcess.stdout.on('data', data => process.stdout.write(data));
      childProcess.stderr.on('data', data => process.stderr.write(data));
      childProcess.on('close', code => code === 0 ? resolve(code) : reject(code));
    });
  });
}

// Compiles TypeScript files using the Angular compiler.
module.exports.ngc = (source, overrides) => {
  return done => {
    runCompiler(source, '@angular/compiler-cli', 'ngc', overrides).then(done, done);
  };
};

// Compiles TypeScript files using the TypeScript compiler.
module.exports.tsc = (source, overrides) => {
  return done => {
    runCompiler(source, 'typescript', 'tsc', overrides).then(done, done);
  };
};
<|endoftext|>


<commit_before>module.exports = {
  'Content-Security-Policy-Report-Only': [
    `default-src 'self'`,
    `script-src 'self' https://*.firebaseio.com/ https://unpkg.com`,
    `style-src 'self' 'unsafe-inline' blob: https://fonts.googleapis.com/`,
    `font-src 'self' https://fonts.gstatic.com/`,
    `img-src 'self' data blob: https://content.dropboxapi.com/ https://www.gravatar.com/avatar/`,
    `child-src 'self' blob`,
    `connect-src 'self' blob: wss://*.firebaseio.com/ https://*.googleapis.com/ https://*.dropboxapi.com/`,
    `frame-src 'self' https://*.firebaseio.com/`,
    `object-src 'none'`,
    `worker-src 'self' blob:`,
    `report-uri https://sjofartstidningen.report-uri.com/r/d/csp/reportOnly`,
  ].join('; '),
  'X-Frame-Options': 'SAMEORIGIN',
  'X-XSS-Protection': '1; mode=block',
  'X-Content-Type-Options': 'nosniff',
  'Referrer-Policy': 'no-referrer-when-downgrade',
  'Expect-CT':
    'max-age=0, report-uri="https://sjofartstidningen.report-uri.com/r/d/ct/reportOnly"',
};
<commit_msg>fix: Fix CSP-headers<commit_after>module.exports = {
  'Content-Security-Policy-Report-Only': [
    `default-src 'self'`,
    `script-src 'self' https://*.firebaseio.com/ https://unpkg.com`,
    `style-src 'self' 'unsafe-inline' blob: https://fonts.googleapis.com/`,
    `font-src 'self' https://fonts.gstatic.com/`,
    `img-src 'self' data: blob: https://content.dropboxapi.com/ https://www.gravatar.com/avatar/`,
    `child-src 'self' blob: data:`,
    `connect-src 'self' blob: wss://*.firebaseio.com/ https://*.googleapis.com/ https://*.dropboxapi.com/`,
    `frame-src 'self' https://*.firebaseio.com/`,
    `object-src 'none'`,
    `worker-src 'self' blob:`,
    `report-uri https://sjofartstidningen.report-uri.com/r/d/csp/reportOnly`,
  ].join('; '),
  'X-Frame-Options': 'SAMEORIGIN',
  'X-XSS-Protection': '1; mode=block',
  'X-Content-Type-Options': 'nosniff',
  'Referrer-Policy': 'no-referrer-when-downgrade',
  'Expect-CT':
    'max-age=0, report-uri="https://sjofartstidningen.report-uri.com/r/d/ct/reportOnly"',
};
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.search',
  name: 'Toolbar',
  extends: 'foam.u2.View',
  properties: [
    {
      class: 'FObjectProperty',
      of: 'foam.mlang.predicate.Predicate',
      name: 'data',
      factory: function() {
        return foam.mlang.predicate.True.create();
      }
    },
    {
      class: 'String', // TODO: remove.
      name: 'search',
      label: 'Search',
      view: { class: 'foam.u2.TextField' },
      maxLength: 0
    }
  ],
  methods: [
    function initE() {
      this.SUPER();
      this.tag({
        class: 'foam.u2.detail.SectionedDetailPropertyView',
        data: this,
        prop: this.DATA_
      });
    }
  ]
});
<commit_msg>Added final documentation<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.search',
  name: 'Toolbar',
  extends: 'foam.u2.View',

  documentation: `
    A toolbar which features filtering, searching and exporting
  `,

  properties: [
    {
      class: 'FObjectProperty',
      of: 'foam.mlang.predicate.Predicate',
      name: 'data',
      factory: function() {
        return foam.mlang.predicate.True.create();
      }
    },
    {
      class: 'String', // TODO: remove.
      name: 'search',
      label: 'Search',
      view: { class: 'foam.u2.TextField' },
      maxLength: 0
    }
  ],
  methods: [
    function initE() {
      this.SUPER();
      this.tag({
        class: 'foam.u2.detail.SectionedDetailPropertyView',
        data: this,
        prop: this.DATA_
      });
    }
  ]
});
<|endoftext|>


<commit_before>const gulp = require('gulp');
const config = require('../config');
const $ = config.plugins;
const isProduction = config.isProduction;

const browserify = require('browserify');
const vueify = require('vueify');
const babelify = require('babelify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const envify = require('envify/custom');

gulp.task('compile', [
  'compile:vue',
  'compile:scss',
]);

gulp.task('compile:vue', () => {
  const vues = config.src.vue;

  Object.keys(vues).forEach((src) => {
    const dist = vues[src];

    let browser = browserify(src, {
      debug: true,
      extensions: ['.js', '.vue'],
      transform: [
        vueify,
        babelify,
      ],
    });

    if (isProduction) {
      browser = browser.transform(
        {global: true},
        envify({NODE_ENV: 'production'})
      );
    }

    browser
      .bundle()
      .on('error', (err) => {
        console.log(err.message);
        console.log(err.stack);
      })
      .pipe($.plumber())
      .pipe(source(dist))
      .pipe(buffer())
      .pipe($.if(!isProduction, $.sourcemaps.init()))
      .pipe($.if(isProduction, $.uglify()))
      .pipe($.if(!isProduction, $.sourcemaps.write(config.map)))
      .pipe(gulp.dest(config.dist.js));
  });
});

gulp.task('compile:scss', () => {
  gulp
    .src(config.src.scss)
    .pipe($.plumber())
    .pipe($.if(!isProduction, $.sourcemaps.init()))
    .pipe($.sass({outputStyle: 'expanded'})
      .on('error', $.sass.logError))
    .pipe($.if(isProduction, $.cssmin()))
    .pipe($.if(!isProduction, $.sourcemaps.write(config.map)))
    .pipe(gulp.dest(config.dist.css));
});
<commit_msg>Run lint:es task in compile:vue task<commit_after>const gulp = require('gulp');
const config = require('../config');
const $ = config.plugins;
const isProduction = config.isProduction;

const browserify = require('browserify');
const vueify = require('vueify');
const babelify = require('babelify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const envify = require('envify/custom');

gulp.task('compile', [
  'compile:vue',
  'compile:scss',
]);

gulp.task('compile:vue', ['lint:es'], () => {
  const vues = config.src.vue;

  Object.keys(vues).forEach((src) => {
    const dist = vues[src];

    let browser = browserify(src, {
      debug: true,
      extensions: ['.js', '.vue'],
      transform: [
        vueify,
        babelify,
      ],
    });

    if (isProduction) {
      browser = browser.transform(
        {global: true},
        envify({NODE_ENV: 'production'})
      );
    }

    browser
      .bundle()
      .on('error', (err) => {
        console.log(err.message);
        console.log(err.stack);
      })
      .pipe($.plumber())
      .pipe(source(dist))
      .pipe(buffer())
      .pipe($.if(!isProduction, $.sourcemaps.init()))
      .pipe($.if(isProduction, $.uglify()))
      .pipe($.if(!isProduction, $.sourcemaps.write(config.map)))
      .pipe(gulp.dest(config.dist.js));
  });
});

gulp.task('compile:scss', () => {
  gulp
    .src(config.src.scss)
    .pipe($.plumber())
    .pipe($.if(!isProduction, $.sourcemaps.init()))
    .pipe($.sass({outputStyle: 'expanded'})
      .on('error', $.sass.logError))
    .pipe($.if(isProduction, $.cssmin()))
    .pipe($.if(!isProduction, $.sourcemaps.write(config.map)))
    .pipe(gulp.dest(config.dist.css));
});
<|endoftext|>