,]
//	  }
//	- 'origin' (default)
//
// This expects: 
// 	- the block is directly nested in the container
// 	- the block can be scaled
// 	- the block has an origin set
//
function getRelativeOffset(container, block, point){
	point = point == null ? {} : point
	var l = point.left
	var t = point.top
	var scale = point.scale
	// get the input data...
	var s = getElementScale(block)
	var o = getElementOrigin(block)
	// get only the value we need...
	var W = container.width()
	var H = container.height()
	// we need this to make everything relative to the container...
	var co = container.offset()
	var offset = getElementOffset(block)
	var bo = block.offset()
	scale = scale == 'screen' ? 1 
		: scale == 'elem' ? s
		: scale == null ? s
		: scale
	// normalize the l,t to element scale...
	if(l != null && t != null){
		// get only the value we need...
		// NOTE: width and height are used to calculate the correction
		//		due to origin/scale...
		var w = block.width()
		var h = block.height()
		o = {
			// target offset scale...
			top: t*scale 
				// set origin to top left corner of element (compensate
				// for scaling)...
				+ (h - h*s) / (h / o.top), 
			left: l*scale 
				+ (w - w*s) / (w / o.left),
		}
	}
	return {
		top: offset.top + (H/2 - offset.top) - o.top,
		left: offset.left + (W/2 - offset.left) - o.left,
	}
}
// NOTE: at this point this works only on the X axis...
function setElementTransform(elem, offset, scale, duration){
	elem = $(elem)
	//var t3d = USE_3D_TRANSFORM ? 'translateZ(0)' : ''
	var t3d = USE_3D_TRANSFORM ? 'translate3d(0,0,0)' : ''
	//var translate = USE_3D_TRANSFORM ? 'translate3d' : 'translate'
	var translate = 'translate'
	if(offset == null){
		offset = getElementOffset(elem)
	// number -- only the x coord...
	} else if(typeof(offset) == typeof(1)){
		offset = {
			left: offset,
			top: 0
		}
	// array...
	} else if(offset.indexOf){
		offset = {
			left: offset[0] ? offset[0] : 0,
			top: offset[1] ? offset[1] : 0
		}
	}
	if(scale == null){
		var scale = getElementScale(elem)
	}
	if(USE_TRANSFORM){
		var transform = translate+'('+ 
				Math.round(offset.left) +'px, '+
				//Math.round(offset.top) +'px'+ (USE_3D_TRANSFORM && ', 0px' || '') +') '
				Math.round(offset.top) +'px) '
			+'scale('+ scale +') '
			+ t3d
		elem.css({
			'-ms-transform' : transform, 
			'-webkit-transform' : transform, 
			'-moz-transform' : transform, 
			'-o-transform' : transform, 
			'transform' : transform, 
			// XXX can we avoid this here?? 
			left: 0,
			// XXX is this correct???
			top: ''
		}, duration)
	} else {
		//var transform = translate+'(0px, 0px'+ (USE_3D_TRANSFORM && ', 0px' || '') +') '
		var transform = translate+'(0px, 0px) '
			+'scale('+ scale +') '
			+ t3d
		elem.css({
			// NOTE: this will be wrong during a transition, that's why we 
			// 		can pass the pre-calculated offset as an argument...
			left: Math.round(offset.left),
			top: Math.round(offset.top),
			// XXX can we avoid this here?? 
			'-ms-transform' : transform, 
			'-webkit-transform' : transform, 
			'-moz-transform' : transform, 
			'-o-transform' : transform, 
			'transform' : transform, 
		}, duration)
	}
	return elem
}
// Run a function controllably in an animation frame
//
// NOTE: we do not need to make this run several callbacks as the 
// 		browser already does this and will do the loop faster...
function animationFrameRunner(func){
	var next
	var _nop = function(){ return this }
	var frame
	if(this === window){
		self = new animationFrameRunner
	} else {
		self = this
	}
	self.func = func
	var _tick = function(){
		func(Date.now())
		frame = getAnimationFrame(next)
	}
	// main user interface...
	var start = function(){
		next = _tick
		this.start = _nop
		this.stop = stop
		// start things up...
		// NOTE: we are not calling _tick here directly to avoid stray,
		// 		off-frame call to func...
		frame = getAnimationFrame(next)
		return this
	}
	var stop = function(){
		if(frame != null){
			cancelAnimationFrame(frame)
			frame = null
		}
		next = _nop
		this.start = start
		this.stop = _nop 
		return this
	}
	// setup the ticker in stopped state...
	stop.call(self)
	return self
}
// XXX make this a drop-in replacement for setElementTransform...
// XXX cleanup, still flacky...
function animateElementTo(elem, to, duration, easing, speed, callback, use_transitions){
	// stop all ongoing animations on the current elem...
	stopAnimation(elem)
	use_transitions = use_transitions != null ? 
							use_transitions 
							: USE_TRANSITIONS_FOR_ANIMATION
	// use transition for animation...
	if(use_transitions){
		setTransitionEasing(elem, easing)
		duration == null && setTransitionDuration(elem, duration)
		setElementTransform(elem, to)
	// manually animate...
	} else {
		if(typeof(to) == typeof(1)){
			to = {
				left: to,
				top: 0,
			}
		}
		if(typeof(speed) == typeof(2)){
			speed = {
				x: speed,
				y: 0,
			}
		}
		if(duration == null){
			duration = getElementTransitionDuration(elem)
		}
		setTransitionDuration(elem, 0)
		var start = Date.now()
		var then = start + duration
		var from = getElementOffset(elem)
		var cur = {
			top: from.top,
			left: from.left
		}
		var dist = {
			top: to.top - from.top,
			left: to.left - from.left,
		}
		// XXX are we using this...
		elem.animating = true
		elem.next_frame = null
		// remember step start position...
		var s_t = cur.top
		var s_l = cur.left
		function animate(){
			// prevent running animations till next call of animateElementTo(..)
			if(elem.next_frame === false){
				return
			}
			var t = Date.now()
			// end of the animation...
			if(t >= then){
				setElementTransform(elem, to)
				return
			}
			if(!elem.animating){
				// XXX jittery...
				setElementTransform(elem, cur)
				return
			}
			// remember step start position...
			s_t = cur.top
			s_l = cur.left
			// animate a step with speed...
			if(speed != null){
				// NOTE: these are almost identical, they are inlined 
				// 		for speed...
				if(Math.abs(dist.top) >= 1){
					dy = ((t - start) * speed.y)
					if(Math.abs(dist.top) > Math.abs(dy)){
						dist.top -= dy
						cur.top = Math.round(cur.top + dy)
						// normalize...
						cur.top = Math.abs(dist.top) <= 1 ? to.top : cur.top
						// calc speed for next step...
						speed.y = dist.top / (duration - (t - start))
					} else {
						cur.top = to.top
					}
				}
				if(Math.abs(dist.left) >= 1){
					dx = ((t - start) * speed.x)
					if(Math.abs(dist.left) > Math.abs(dx)){
						dist.left -= dx
						cur.left = Math.round(cur.left + dx)
						// normalize...
						cur.left = Math.abs(dist.left) <= 1 ? to.left : cur.left
						// calc speed for next step...
						speed.x = dist.left / (duration - (t - start))
					} else {
						cur.left = to.left
					}
				}
			// liner animate...
			} else {
				var r = (t - start) / duration
				cur.top = Math.round(from.top + (dist.top * r))
				cur.left = Math.round(from.left + (dist.left * r)) 
			}
			setElementTransform(elem, cur)
			callback != null && callback({
				x: cur.left - s_l,
				y: cur.top - s_t,
			})
			// sched next frame...
			elem.next_frame = getAnimationFrame(animate)
		}
		animate()
	}
}
function stopAnimation(elem){
	if(elem.next_frame){
		cancelAnimationFrame(elem.next_frame)
		elem.next_frame = false
		return
	}
}
// XXX account for other transitions...
// XXX make a sync version...
function setElementOffset(elem, l, t, scale){
	return setElementTransform(elem, [l, t], scale)
}
function setElementScale(elem, scale){
	return setElementTransform(elem, null, scale)
}
function setElementOrigin(elem, x, y, z){
	x = x == null ? '50%' : x
	y = y == null ? '50%' : y
	z = z == null ? '0' : z
	var value = x +' '+ y +' '+ z
	return $(elem).css({
		'transform-origin': value, 
		'-o-transform-origin':  value,
		'-ms-transform-origin':  value,
		'-moz-transform-origin':  value,
		'-webkit-transform-origin':  value,
	})
}
// a sync version of setElementOrigin(..), this will not trigger transforms...
function setElementOriginSync(elem, x, y, z){
	x = x == null ? '50%' : x
	y = y == null ? '50%' : y
	z = z == null ? '0' : z
	var value = x +' '+ y +' '+ z
	elem = $(elem)
	var e = elem[0]
	e.style.display = 'none'
	// now kick the browser into recognition of our changes NOW ;)
	getComputedStyle(e).display
	e.style['-o-transform-origin'] =  value
	e.style['-ms-transform-origin'] =  value
	e.style['-moz-transform-origin'] =  value
	e.style['-webkit-transform-origin'] =  value
	e.style['transform-origin'] = value
	e.style.display = ''
	getComputedStyle(e).display
	return $(elem)
}
// this is like setElementOrigin(..) but will compensate for element 
// shift when scaled...
// NOTE: this will work only of translate is used for positioning...
function shiftOriginTo(elem, l, t, scale){
	var o = getElementOrigin(elem)
	var scale = scale || getElementScale(elem)
	var offset = getElementOffset(elem)
	// calculate the offset change and compensate...
	var cl = offset.left + ((o.left - o.left*scale) - (l - l*scale))
	var ct = offset.top + ((o.top - o.top*scale) - (t - t*scale))
	setElementOffset(elem, cl, ct)
	return setElementOriginSync(elem, l+'px', t+'px')
}
function setTransitionEasing(elem, ease){
	if(typeof(ms) == typeof(0)){
		ms = ms + 'ms'
	}
	return $(elem).css({
		'transition-timing-function': ease, 
		'-moz-transition-timing-function': ease,
		'-o-transition-timing-function': ease,
		'-ms-transition-timing-function': ease,
		'-webkit-transition-timing-function': ease
	})
}
function setTransitionDuration(elem, ms){
	if(typeof(ms) == typeof(0)){
		ms = ms + 'ms'
	}
	return elem.css({
		'transition-duration': ms, 
		'-moz-transition-duration': ms,
		'-o-transition-duration': ms,
		'-ms-transition-duration': ms,
		'-webkit-transition-duration': ms
	})
}
/************************************************ jQuery extensions **/
jQuery.fn.reverseChildren = function(){
	return $(this).each(function(_, e){
		return $(e).append($(e).children().detach().get().reverse())
	})
}
jQuery.fn.sortChildren = function(func){
	return $(this).each(function(_, e){
		return $(e).append($(e).children().detach().get().sort(func))
	})
}
/************************************************** Deferred utils ***/
// Deferred worker pool...
//
// 		makeDeferredPool([size][, paused]) -> pool
//
//
// This will create and return a pooled queue of deferred workers.
//
//
// The pool can be in one of the folowing states:
//
// 	- filling
// 		This state prevents .depleted() from triggering until the pool 
// 		exits the filling state.
// 		This helps us to prevent premature depletion of the pool in 
// 		cases where the queue is depleted faster than it is being filled.
//
// 	- paused
// 		This state prevents any new queued workers from starting.
//
//
// Public interface:
//
// 		.enqueue(obj, func, args) -> deferred
// 			Add a worker to queue.
// 			If the pool is not filled and not paused, this will run the
// 			worker right away.
// 			If the pool is full the worker is added to queue (FIFO) and
// 			ran in its turn.
//
// 		.dropQueue() -> pool
// 			Drop the queued workers.
// 			NOTE: this will not stop the already running workers.
//
//
//		.filling()
//			Enter the filling state
//
//		.doneFilling()
//			Exit the filling state
//			NOTE: this will trigger .depleted() if at the time of call
//				both the pool and queue are empty.
//
//
// 		.pause() -> pool
// 			Pause the queue.
// 			NOTE: this also has a second form: .pause(func), see below.
//
// 		.resume() -> pool
// 			Restart the queue.
//
//
//		.isFilling() -> bool
//			Test if the pool is being filled -- filling state.
//
// 		.isRunning() -> bool
// 			Test if any workers are running in the pool.
// 			NOTE: this will return false ONLY when the pool is empty.
//
// 		.isPaused() -> bool
// 			Test if pool is in a paused state.
// 			NOTE: some workers may sill be finishing up so if you want
// 					to test whether any workers are still running use
// 					.isRunning()
//
//
// Event handler/callback registration:
//
// 		.on(evt, func) -> pool
// 			Register a handler (func) for an event (evt).
//
// 		.off(evt[, func]) -> pool
// 			Remove a handler (func) form and event (evt).
// 			NOTE: if func is omitted, remove all handlers from the given
// 					event...
//
// 		.progress(func) -> pool
// 			Register a progress handler.
// 			The handler is called after each worker is done and will get
// 			passed:
// 				- workers done count
// 				- workers total count
// 			Short hand for:
// 				.on('progress', func) -> pool
// 			NOTE: the total number of workers can change as new workers
// 					are added or the queue is cleared...
// 			
// 		.fail(func) -> pool
// 			Register a worker fail handler.
// 			The handler is called when a worker goes into the fail state.
// 			This will get passed:
// 				- workers done count
// 				- workers total count
// 			Short hand for:
// 				.on('fail', func) -> pool
// 			NOTE: this will not stop the execution of other handlers.
//
// 		.pause(func) -> pool
// 			Register a pause handler.
// 			This handler is called after the last worker finishes when 
// 			the queue is paused.
// 			Short hand for:
// 				.on('progress', func) -> pool
//
// 		.resume(func) -> pool
// 			Short hand for:
// 				.on('resume', func) -> pool
//
// 		.depleted(func) -> pool
// 			Register a depleted pool handler.
// 			The handler will get called when the queue and pool are empty
// 			(depleted) and the last worker is done.
// 			Short hand for:
// 				.on('deplete', func) -> pool
//
// XXX should this be an object or a factory???
function makeDeferredPool(size, paused){
	size = size == null ? POOL_SIZE : size
	size = size < 0 ? 1 
		: size > 512 ? 512
		: size
	paused = paused == null ? false : paused
	var Pool = {
		pool: [],
		queue: [],
		size: size,
		// XXX do we need to hide or expose them and use their API???
		_event_handlers: {
			deplete: $.Callbacks(),
			progress: $.Callbacks(),
			pause: $.Callbacks(),
			resume: $.Callbacks(),
			fail: $.Callbacks()
		},
		_paused: paused,
	}
	// Run a worker...
	//
	// This will:
	// 	- create and add a worker to the pool, which will:
	// 		- run an element from the queue
	// 		- remove self from pool
	// 		- if the pool is not full, create another worker (call 
	// 		  ._run(..)) else exit
	// 		- call ._fill() to replenish the pool
	Pool._run = function(deferred, func, args){
		var that = this
		var pool = this.pool
		var pool_size = this.size
		var queue = this.queue
		var run = this._run
		// run an element from the queue...
		var worker = func.apply(null, args)
		pool.push(worker)
		// NOTE: this is explicitly after the pool push to avoid the 
		// 		possible race condition of the worker exiting and 
		// 		triggering .always(..) before being added to the pool...
		worker
			.always(function(){
				// prepare to remove self from pool...
				var i = pool.indexOf(this)
				Pool._event_handlers.progress.fire(pool.length - pool.len, pool.length + queue.length)
				// remove self from queue...
				delete pool[i]
				// shrink the pool if it's overfilled...
				// i.e. do not pop another worker and let the "thread" die.
				if(pool.len > pool_size){
					// remove self...
					return
				}
				// pause the queue -- do not do anything else...
				if(that._paused == true){
					// if pool is empty fire the pause event...
					if(pool.len == 0){
						Pool._event_handlers.pause.fire()
					}
					return
				}
				// get the next queued worker...
				var next = queue.splice(0, 1)[0]
				// run the next worker if it exists...
				if(next != null){
					run.apply(that, next)
				// empty queue AND empty pool mean we are done...
				} else if(pool.len == 0){
					var l = pool.length
					// NOTE: potential race condition -- something can be
					// 		pushed to pool just before it's "compacted"...
					pool.length = 0
				
					if(!that._filling){
						that._event_handlers.deplete.fire(l)
					}
				}
				// keep the pool full...
				that._fill()
			})
			.fail(function(){
				Pool._event_handlers.fail.fire(pool.length - pool.len, pool.length + queue.length)
				deferred.reject.apply(deferred, arguments)
			})
			.progress(function(){
				deferred.notify.apply(deferred, arguments)
			})
			.done(function(){
				deferred.resolve.apply(deferred, arguments)
			})
		return worker
	}
	// Fill the pool...
	//
	Pool._fill = function(){
		var that = this
		var pool_size = this.size
		var run = this._run
		var l = this.pool.len
		if(this._paused != true 
				&& l < pool_size 
				&& this.queue.length > 0){
			this.queue.splice(0, pool_size - l)
				.forEach(function(e){
					run.apply(that, e)
				})
		}
		return this
	}
	// Public methods...
	// Add a worker to queue...
	//
	Pool.enqueue = function(func){
		var deferred = $.Deferred()
		// add worker to queue...
		this.queue.push([deferred, func, [...arguments].slice(1)])
		// start work if we have not already...
		this._fill()
		//return this
		return deferred
	}
	// Drop the queued workers...
	//
	// NOTE: this will not stop the running workers...
	// XXX should this return the pool or the dropped queue???
	Pool.dropQueue = function(){
		this.queue.splice(0, this.queue.length)
		return this
	}
	// Filling state...
	//
	// When this mode is set, it will prevent the queue from triggering
	// the depleated action until .doneFilling() is called...
	//
	// This is to prevent the pool depleting before the queue is filled
	// in the case of tasks ending faster than they are added...
	Pool.filling = function(){
		this._filling = true
		return this
	}
	Pool.doneFilling = function(){
		delete this._filling
		// trigger depleted if we are empty...
		if(this.pool.len == 0 && this.queue.length == 0){
			that._event_handlers.deplete.fire(l)
		}
		return this
	}
	Pool.isFilling = function(){
		return this._filling == true
	}
	// Paused state...
	//
	// NOTE: this will not directly cause .isRunning() to return false 
	// 		as this will not directly spot all workers, it will just 
	// 		pause the queue and the workers that have already started
	// 		will keep running until they are done, and only when the 
	// 		pool is empty will the .isRunning() return false.
	//
	// XXX test...
	Pool.pause = function(func){
		if(func == null){
			this._paused = true
		} else {
			this.on('pause', func)
		}
		return this
	}
	// XXX test...
	Pool.resume = function(func){
		if(func == null){
			this._paused = false
			this._event_handlers['resume'].forEach(function(f){ f() })
			this._fill()
		} else {
			this.on('resume', func)
		}
		return this
	}
	Pool.isPaused = function(){
		return this._paused
	}
	Pool.isRunning = function(){
		return this.pool.len > 0
	}
	// Generic event handlers...
	Pool.on = function(evt, handler){
		this._event_handlers[evt].add(handler)
		return this
	}
	// NOTE: if this is not given a handler, it will clear all handlers 
	// 		from the given event...
	Pool.off = function(evt, handler){
		if(handler != null){
			this._event_handlers[evt].remove(handler)
		} else {
			this._event_handlers[evt].empty()
		}
		return this
	}
	// Register a queue depleted handler...
	//
	// This occurs when a populated queue is depleted and the last worker
	// is done.
	//
	// NOTE: this is similar to jQuery.Deferred().done(..) but differs in
	// 		that the pool can fill up and get depleted more than once, 
	// 		thus, the handlers may get called more than once per pool 
	// 		life...
	// NOTE: it is recommended to fill the queue faster than the workers
	// 		finish, as this may get called after last worker is done and
	// 		the next is queued...
	Pool.depleted = function(func){
		return this.on('deplete', func)
	}
	// Deferred compatibility...
	//
	// NOTE: the key difference between this and the deferred is that this
	// 		does not have memory and can get called multiple times...
	// XXX is this correct???
	//Pool.done = Pool.depleted
	// Register queue progress handler...
	//
	// This occurs after each worker is done.
	//
	// handler will be passed:
	// 	- the pool object
	// 	- workers done
	// 	- total workers (done + queued)
	Pool.progress = function(func){
		return this.on('progress', func)
	}
	// Register worker fail handler...
	//
	Pool.fail = function(func){
		return this.on('fail', func)
	}
	return Pool
}
/**************************************************** JS utilities ***/
// Get screen dpi...
//
// This will calculate the value and save it to screen.dpi
//
// if force is true this will re-calculate the value.
//
// NOTE: this needs the body loaded to work...
// NOTE: this may depend on page zoom...
// NOTE: yes, this is a hack, but since we have no other reliable way to
// 		do this...
function getDPI(force){
	if(screen.dpi == null || force){
		var e = $('')
			.css({
				position: 'absolute',
				width: '1in',
				left: '-100%',
				top: '-100%'
			})
			.appendTo($('body'))
		var res = e.width()
		e.remove()
		screen.dpi = res
		return res	
	} else {
		return screen.dpi
	}
}
// XXX is this correct???
$(getDPI)
// return 1, -1, or 0 depending on sign of x
function sign(x){
	return (x > 0) - (x < 0)
}
var getAnimationFrame = (window.requestAnimationFrame
		|| window.webkitRequestAnimationFrame 
		|| window.mozRequestAnimationFrame
		|| window.oRequestAnimationFrame
		|| window.msRequestAnimationFrame
		|| function(callback){ 
			setTimeout(callback, 1000/60) 
		})
var cancelAnimationFrame = (window.cancelAnimationFrame 
		|| window.webkitCancelAnimationFrame 
		|| window.mozCancelAnimationFrame
		|| window.oCancelAnimationFrame
		|| window.msCancelAnimationFrame
		|| clearTimeout)
function logCalls(func, logger){
	var that = this
	var _func = function(){
		logger(func, arguments)
		return func.apply(that, arguments)
	}
	_func.name = func.name
	return _func
}
function assyncCall(func){
	var that = this
	var _func = function(){
		var res = $.Deferred()
		setTimeout(function(){
			res.resolve(func.apply(that, arguments))
		}, 0)
		return res
	}
	_func.name = func.name
	return _func
}
// Quote a string and convert to RegExp to match self literally.
function quoteRegExp(str){
	return str.replace(/([\.\\\/\(\)\[\]\$\*\+\-\{\}\@\^\&\?\<\>])/g, '\\$1')
}
/**********************************************************************
* vim:set ts=4 sw=4 :                                                */