;(function(){

if (!window._gaq)
	window._gaq = []


var myName = 'Tracker'

var Me =
{
	track: function (category, action, label, value)
	{
		try
		{
			window._gaq.push(['_trackEvent', category, action, label, value])
			
			return true
		}
		catch (ex)
		{
			this.log('could not report a track')
		}
	},
	
	log: function (str) { try { console.log(myName + ': ' + str) } catch (ex) {} }
}

self.className = Me
self[myName] = Me

})();
// at this stage no fixes or wrappers are loaded from any lib
// except for Tracker object that hmm… tracks :)
;(function(){

function log (str) { try { console.log('Oops: ' + str) } catch (ex) {} }

var myName = 'Oops'

var Me =
{
	enabled: false,
	masking: true,
	total: 0,
	
	handler: function (message, uri, line)
	{
		try
		{
			return Me.onerror.apply(Me, arguments)
		}
		catch (ex) { log('error on error reporting') }
	},
	
	onerror: function (message, uri, line)
	{
		if (typeof message == 'object')
		{
			// an event was caught
			if (message.target)
				this.report('warning', 'unable to load "' + message.target.src + '"')
		}
		else
		{
			// cutting out current page uri prefix
			if (typeof uri == 'string')
				uri = uri.replace('^' + location.protocol + '//' + location.hostname, '')
			
			this.report('error', message + ' at ' + uri + ':' + line)
		}
		
		return this.masking
	},
	
	report: function (type, message)
	{
		try // to fully describe an error
		{
			Tracker.track('Oops', type, message, this.total++)
		}
		catch (ex)
		{
			log('could not report')
		}
		
		return true
	},
	
	maybeEnable: function ()
	{
		if (!/Oops=disabled/.test(document.cookie))
			this.enable()
	},
	
	enable: function ()
	{
		if (this.enabled)
			return
		this.enabled = true
		
		window.onerror = this.handler
		log('error catching enabled')
	},
	
	disable: function ()
	{
		if (!this.enabled)
			return
		this.enabled = false
		
		window.onerror = null
		log('error catching disabled')
	},
	
	log: function (message)
	{
		Tracker.track('Oops', 'log', message)
	},
	
	error: function (message)
	{
		Tracker.track('Oops', 'error', message)
	},
	
	time: function (message, time)
	{
		Tracker.track('Oops', 'time', message, time)
	}
}

self.className = Me
self[myName] = Me

})();
Oops.maybeEnable()

// defining spaces
if (!self.Programica) self.Programica = {}

// preparing DOM prototypes
if (!self.Element)
	self.Element = {}

if (!self.Element.prototype)
	self.Element.prototype = document.createElement('div').__proto__ || {}

if (!self.HTMLFormElement)
	self.HTMLFormElement = {}

if (!self.HTMLFormElement.prototype)
	self.HTMLFormElement.prototype = document.createElement('form').__proto__ || {}


// base objects extensions
if (!Object.extend)
	Object.extend = function (d, s) { if (d) for (var p in s) d[p] = s[p]; return d }

if (!Object.copy)
	Object.copy = function (s) { var d = {}; for (var k in s) d[k] = s[k]; return d }

if (!Object.keys)
	Object.keys = function (s) { var r = []; for (var k in s) r.push(k); return r }

if (!Math.longRandom)
	Math.longRandom = function () { return (new Date()).getTime().toString() + Math.round(Math.random() * 1E+17) }

if (!String.localeCompare)
	String.localeCompare = function (a, b) { return a < b ? -1 : (a > b ? 1 : 0) }

if (!Array.prototype.forEach)
	Array.prototype.forEach = function (f, inv) { for (var i = 0, len = this.length; i < len; i++) f.call(inv, this[i], i, this) }

if (!Array.prototype.indexOf)
	Array.prototype.indexOf = function(v, i)
	{
		var len = this.length,
			i = Number(i) || 0
		i = (i < 0) ? (Math.ceil(i) + len) : Math.floor(i)
		
		for (; i < len; i++)
			if (i in this && this[i] === v)
				return i
		return -1
	}


if (!Array.prototype.map)
	Array.prototype.map = function(f, inv)
	{
		var len = this.length,
			res = new Array(len)
		for (var i = 0; i < len; i++)
			if (i in this)
				res[i] = f.call(inv, this[i], i, this)
		return res
	}

if (!Array.copy)
	Array.copy = function (src) { return Array.prototype.slice.call(src) }

if (!Function.prototype.delay)
	Function.prototype.delay = function (delay, args, inv) { var me = this; return setTimeout(function () { return me.apply(inv, args || arguments) }, delay || 10) }

if (!Function.prototype.bind)
	Function.prototype.bind = function (inv, args) { var me = this; return function () { me.apply(inv, args || arguments) } }


function $   (id)   { return document.getElementById(id) }
function $E  (type, props)
{
	var node = document.createElement(type)
	if (props)
		for (var i in props)
			node.setAttribute(i, props[i])
	return node
}

$.onload = function (fn) { return self.addEventListener('load', fn, false) }
$.include = function (src)
{
	var me = arguments.callee
	var cache = me.cache || (me.cache = {}) 
	if (me.cache[src])
		return me.cache[src]
	var node = document.createElement('script')
	node.type = 'text/javascript'
	node.src = src
	document.getElementsByTagName('head')[0].appendChild(node)
	cache[src] = node
	return node
}






$.onready = function (fn) { return this.onready.listeners.push(fn) }
$.onready.done = 0
$.onready.listeners = []
$.onready.run = function (e)
{
	if (this.done++)
		return
	
	if (!e)
		e = {type:'contentready'}
	
	var listeners = this.listeners
	for (var i = 0; i < listeners.length; i++)
		listeners[i].call(document, e)
}
$.onload(function (e) { $.onready.run(e) })
self.addEventListener('DOMContentLoaded', function (e) { $.onready.run(e) }, false)

// DOM для всех

;(function(){


var proto = Element.prototype

if (!document.getElementsByClassName)
{
	// from prototype 1.5.1.1
	proto.getElementsByClassName = document.getElementsByClassName = function (className, tagName)
	{
		// geting elems with native function
		var children = this.getElementsByTagName(tagName || '*')
		// predeclaring vars
		var elements = [], child, l = 0
		// precompile regexp
		var rex = new RegExp("(?:\\s+|^)" + className + "(?:\\s+|$)")
		// length is constant, so caching its value
		var len = children.length
		
		// memory for array of nodes will be allocated only once
		elements.length = len
		for (var i = 0; i < len; i++)
		{
			// even caching the reference for children[i] gives us some nanoseconds ;)
			child = children[i]
			// just rely on RegExp engine
			if (rex.test(child.className))
			{
				// simple assignment
				elements[l] = child
				// simple increment
				l++
			}
		}
		// truncating garbage length
		elements.length = l
		
		return elements
	}
}

proto.setClassName = function (cn)
{
	this.className = cn
	return cn
}

proto.addClassName = function (cn)
{
	this.remClassName(cn)
	this.className += ' ' + cn
	return cn
}

proto.remClassName = function (cn)
{
	if (this.className)
		this.className = this.className.replace(new RegExp('(?:\\s+|^)' + cn + '(?:\\s+|$)', 'g'), ' ').replace(/^\s+|\s+$/g, '')
	return cn
}

proto.hasClassName = function (cn)
{
	return (this.className == cn || (new RegExp('(?:\\s+|^)' + cn + '(?:\\s+|$)')).test(this.className))
}

proto.disable = function ()
{
	this.setAttribute('disabled', true)
	this.addClassName('disabled')
}

proto.enable = function ()
{
	this.removeAttribute('disabled')
	this.remClassName('disabled')
}

proto.empty = function ()
{
	var node
	while (node = this.firstChild)
		this.removeChild(node)
}

proto.show = function ()
{
	if (this.onshow)
	{
		if (typeof this.onshow == 'string')
			this.onshow = eval('function (event) { ' + this.onshow + ' }')
		
		if (this.onshow({}) === false)
			return false
	}
	
	this.style.visibility = 'visible'
	this.style.display = 'block'
	
	return true
}

proto.hide = function (t)
{
	if (this.onhide)
	{
		if (typeof this.onhide == 'string')
			this.onhide = eval('function (event) { ' + this.onhide + ' }')
		
		if (this.onhide({}) === false)
			return false
	}
	
	this.style.display = 'none'
	
	return true
}

proto.setVisible = function (show)
{
	if (show && !this.visible()) this.show()
	else if(!show) this.hide()
}

proto.visible = function ()
{
	return this.offsetWidth && this.style.display != 'none' && parseFloat(this.style.opacity) != 0
}

proto.toggle = function ()
{
	return this.visible() ? this.hide() : this.show()
}

proto.remove = function ()
{
	return this.parentNode ? this.parentNode.removeChild(this) : this
}

proto.getComputedStyle = function (prop)
{
	return document.defaultView.getComputedStyle(this, null)
}


})();
;(function () {

var PA = Programica.Animation = function (prms)
{
	prms = prms || {}

	// defaults
	this.trans	= []
	this.duration			= prms.duration || 1,
	this.unit				= prms.unit != null ? prms.unit : PA.defaults.unit
	this.motion				= prms.motion || PA.defaults.type
	this.running			= false
	this.complete			= false
	this.node				= prms.node || false
	this.animationTypes		= PA.Types
	
	this.onstart = this.oncomplete = this.onstep = function () {}
	
	switch (typeof this.motion)
	{
		case 'string':
			this.motion = this.animationTypes[this.motion] || null
			break
		case 'function':
			break
		default:
			this.motion = null
	}
	
	if (prms.trans)
		for (var i = 0; i < prms.trans.length; i++)
			if (prms.trans[i])
				this.trans.push(prms.trans[i])
}

Element.prototype.animate = function (motion, props, duration, unit)
{
	var trans = []
	for (var i in props)
	{
		var pi = props[i]
		if (pi.length == 2)
			trans.push({property: i, begin: pi[0], end: pi[1]})
		else
			trans.push({property: i, begin: null, end: pi[0] || pi})
	}
	return new PA({node: this, motion: motion, duration: duration, trans: trans, unit: unit}).start()
}


PA.fps = 60
PA.defaults = {unit: 'px', type: 'linearTween'}

PA.prototype =
{
	start: function ()
	{
		// if animation is already started
		if (this.running)
			return this
		
		// only one animation per node for now
		if (this.node.animation)
			this.node.animation.stop()
		this.node.animation = this
		
		this.running = true
		this.complete = false
		
		var t = this
		if (this.motion == this.animationTypes.directJump)
		{
			this.frame = this.totalFrames - 1
			setTimeout(function () { t.renderForceLast(); t.stop(); t.complete = true; t.oncomplete() }, 0)
		}
		else
		{
			this.frame = 0
			this.totalFrames = this.duration * PA.fps
			
			for (var i = 0; i < this.trans.length; i++)
			{
				var tr = this.trans[i]
				if (tr.begin == null)
					tr.begin = this.getStyleProperty(tr.property)
				tr.step = ( tr.end - tr.begin ) / this.totalFrames
			}
			
			this.timer = PA.addTimer( function () { t.step() } )
		}
		
		this.onstart()
		return this
	},
	
	stop: function ()
	{
		if (this.running)
		{
			this.node.animation = null
			this.running = false
			PA.removeTimer(this.timer)
		}
		
		return this
	},
	
	step: function ()
	{
		this.render()
		this.onstep()
		
		if (this.frame >= this.totalFrames - 1)
		{
			this.stop()
			this.complete = true
			this.oncomplete()
		}
		
		this.frame++
	},
	
	renderForceLast: function ()
	{
		for (var i = 0; i < this.trans.length; i++)
		{
			var t = this.trans[i]
			this.setStyleProperty(t.property, t.end)
		}
	},
	
	render: function ()
	{
		for (var i = 0; i < this.trans.length; i++)
		{
			var t = this.trans[i]
			if ( t.property != null && t.begin != null && t.end != null  )
				this.setStyleProperty(t.property, this.motion(this.frame + 1, t.begin, t.end - t.begin, this.totalFrames))
			else
				throw new Error("Corupted transformation: " + t)
		}
	},

	getStyleProperty: function (p)
	{
		if (p == "top" && !this.node.style[p])
			return this.node.offsetTop
		
		if (p == "left" && !this.node.style[p])
			return this.node.offsetLeft
		
		
		if (p == "opacity" && isNaN(parseFloat(this.node.style[p])))
			return 1
		
		
		if (/scroll/.test(p))
			return this.node[p]
		
		return parseFloat(this.node.style[p]) || 0
	},
	
	setStyleProperty: function (p, value)
	{
		try
		{
			if (/color/.test(p))
				return this.node.style[p] = 'rgb(' + parseInt(value) + ',' + parseInt(value) + ',' + parseInt(value) + ')'
			
			// for SVG elements
			if (p == 'r')
				return this.node.r.baseVal.value = value
			
			
			if (/scroll/.test(p))
				return this.node[p] = Math.round(value)
			
			if (p == "opacity")
				return this.node.style[p] = value
			
			if ((p == 'width' || p == 'height') && value < 0)
				value = 0
			
			if (this.unit == 'em')
				return this.node.style[p] = Math.round(value * 100) / 100 + this.unit
			
			return this.node.style[p] = Math.round(value) + this.unit
		}
		catch (ex)
		{
			log(ex + p + value)
			return value
		}
	}
}

PA.addTimer = function (func)
{
	if (!this.timer)
	{
		var t = this
		this.timer = setInterval(function (d) { t.time(d) }, 1000 / this.fps)
	}
	
	return this.timers.push(func)
}

PA.removeTimer = function (num)
{
	var ts = this.timers
	ts[num-1] = null
	
	while (ts[ts.length-1] === null)
		ts.length--
	
	if (!ts.length)
		clearInterval(this.timer), this.timer = null
}

PA.timers = []

PA.time = function (d)
{
	for (var i = 0; i < this.timers.length; i++)
		this.timers[i] && this.timers[i](d)
}


;(function(){var M=Math;var e=M.cos;var f=M.sin;var g=M.sqrt;var h=M.PI;var i=M.pow;var j=M.abs;var k=M.asin;var l=Programica.Animation.Types={directJump:function(t,b,c,d){},linearTween:function(t,b,c,d){return c*t/d+b},easeInQuad:function(t,b,c,d){return c*(t/=d)*t+b},easeOutQuad:function(t,b,c,d){return-c*(t/=d)*(t-2)+b},easeInOutQuad:function(t,b,c,d){return((t/=d/2)<1)?c/2*t*t+b:-c/2*((--t)*(t-2)-1)+b},easeInCubic:function(t,b,c,d){return c*(t/=d)*t*t+b},easeOutCubic:function(t,b,c,d){return c*((t=t/d-1)*t*t+1)+b},easeInOutCubic:function(t,b,c,d){return((t/=d/2)<1)?c/2*t*t*t+b:c/2*((t-=2)*t*t+2)+b},easeInQuart:function(t,b,c,d){return c*(t/=d)*t*t*t+b},easeOutQuart:function(t,b,c,d){return-c*((t=t/d-1)*t*t*t-1)+b},easeInOutQuart:function(t,b,c,d){return((t/=d/2)<1)?c/2*t*t*t*t+b:-c/2*((t-=2)*t*t*t-2)+b},easeInQuint:function(t,b,c,d){return c*(t/=d)*t*t*t*t+b},easeOutQuint:function(t,b,c,d){return c*((t=t/d-1)*t*t*t*t+1)+b},easeInOutQuint:function(t,b,c,d){return((t/=d/2)<1)?c/2*t*t*t*t*t+b:c/2*((t-=2)*t*t*t*t+2)+b},easeInSine:function(t,b,c,d){return-c*e(t/d*(h/2))+c+b},easeOutSine:function(t,b,c,d){return c*f(t/d*(h/2))+b},easeInOutSine:function(t,b,c,d){return-c/2*(e(h*t/d)-1)+b},easeInExpo:function(t,b,c,d){return(t==0)?b:c*i(2,10*(t/d-1))+b},easeOutExpo:function(t,b,c,d){return(t==d)?b+c:c*(-i(2,-10*t/d)+1)+b},easeInCirc:function(t,b,c,d){return-c*(g(1-(t/=d)*t)-1)+b},easeOutCirc:function(t,b,c,d){return c*g(1-(t=t/d-1)*t)+b},easeInOutCirc:function(t,b,c,d){return((t/=d/2)<1)?-c/2*(g(1-t*t)-1)+b:c/2*(g(1-(t-=2)*t)+1)+b},easeInBounce:function(t,b,c,d){return c-l.easeOutBounce(d-t,0,c,d)+b},easeInOutExpo:function(t,b,c,d){if(t==0)return b;if(t==d)return b+c;if((t/=d/2)<1)return c/2*i(2,10*(t-1))+b;return c/2*(-i(2,-10*--t)+2)+b},easeInElastic:function(t,b,c,d,a,p){if(t==0)return b;if((t/=d)==1)return b+c;if(!p)p=d*.3;if(a<j(c)){var s=p/4;a=c}else var s=p/(2*h)*k(c/a);return-(a*i(2,10*(t-=1))*f((t*d-s)*(2*h)/p))+b},easeOutElastic:function(t,b,c,d,a,p){if(t==0)return b;if((t/=d)==1)return b+c;if(!p)p=d*.3;if(a<j(c)){var s=p/4;a=c}else var s=p/(2*h)*k(c/a);return a*i(2,-10*t)*f((t*d-s)*(2*h)/p)+c+b},easeInOutElastic:function(t,b,c,d,a,p){if(t==0)return b;if((t/=d/2)==2)return b+c;if(!p)p=d*(.3*1.5);if(a<j(c)){a=c;var s=p/4}else var s=p/(2*h)*k(c/a);if(t<1)return-.5*(a*i(2,10*(t-=1))*f((t*d-s)*(2*h)/p))+b;else return a*i(2,-10*(t-=1))*f((t*d-s)*(2*h)/p)*.5+c+b},easeInBack:function(t,b,c,d,s){if(s==null)s=1.70158;return c*(t/=d)*t*((s+1)*t-s)+b},easeOutBack:function(t,b,c,d,s){if(s==null)s=1.70158;return c*((t=t/d-1)*t*((s+1)*t+s)+1)+b},easeInOutBack:function(t,b,c,d,s){if(s==null)s=1.70158;if((t/=d/2)<1)return c/2*(t*t*(((s*=(1.525))+1)*t-s))+b;else return c/2*((t-=2)*t*(((s*=(1.525))+1)*t+s)+2)+b},easeOutBounce:function(t,b,c,d){if((t/=d)<(1/2.75))return c*(7.5625*t*t)+b;else if(t<(2/2.75))return c*(7.5625*(t-=(1.5/2.75))*t+.75)+b;else if(t<(2.5/2.75))return c*(7.5625*(t-=(2.25/2.75))*t+.9375)+b;else return c*(7.5625*(t-=(2.625/2.75))*t+.984375)+b},easeInOutBounce:function(t,b,c,d){if(t<d/2)return l.easeInBounce(t*2,0,c,d)*.5+b;else return l.easeOutBounce(t*2-d,0,c,d)*.5+c*.5+b}}})();

})();


if (!self.Programica)
	self.Programica = {}

// light infantile browser matching
Programica.userAgentRegExps =
{
	MSIE: /MSIE/,
	MSIE6: /MSIE 6/,
	MSIE7: /MSIE 7/,
	Gecko: /Gecko\//,
	Opera: /Opera/,
	Opera9: /Opera\/9/,
	Safari: /AppleWebKit/,
	Safari2: /AppleWebKit\/4/,
	Safari3: /AppleWebKit\/5/
}
        
Programica.htmlUserAgentSetter = function (doc, ua)
{
	doc = doc || document
	ua = ua || navigator.userAgent
	
	var htmlNode = doc.documentElement
	for (var p in this.userAgentRegExps)
		if (this.userAgentRegExps[p].test(ua))
			htmlNode.className = (htmlNode.className || '') + ' ' + p
}


// 1, 2, 5: банкир, банкира, банкиров
String.prototype.plural = Number.prototype.plural = function (a, b, c)
{
	if (this % 1)
		return b
	
	var v = Math.abs(this) % 100
	if (11 <= v && v <= 19)
		return c
	
	v = v % 10
	if (2 <= v && v <= 4)
		return b
	if (v == 1)
		return a
	
	return c
}

Date.rusMonths = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']
Date.rusMonths2 = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']
Date.prototype.toRusDate = function () { return this.getDate() + ' ' + Date.rusMonths2[this.getMonth()] + ' ' + this.getFullYear() }

Humanize =
{
	adjustTextSize: function (nodes)
	{
		for (var i = 0; i < nodes.length; i++)
		{
			var node = nodes[i]
			
			if (node.scrollWidth > node.offsetWidth)
			{
				var text = node.firstChild,
					string = text.nodeValue
				node.realText = string
				text.nodeValue = string.substr(0, 16) + '…'
				node.title = string
			}
		}
	},
	
	adjustTextSizeOfNodes: function (root, selector)
	{
		var me = this
		setTimeout(function () { me.adjustTextSize(cssQuery(selector, root)) }, 1)
	}
}
// based on json2 (http://www.JSON.org/json2.js)
// WARNING: this is not JSON library, it is not secure, it is for internal use only
// if you do not understand the difference please use original json2.js library

;(function ()
{
	// Format integers to have at least two digits.
	function f (n) { return n < 10 ? '0' + n : n }
	
	var escapeable = new RegExp('[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]', 'g'),
	Object_hasOwnProperty = Object.hasOwnProperty,
	Date_constructor = Date,
	String_constructor = String,
	meta =
	{
		'\b': '\\b',
		'\t': '\\t',
		'\n': '\\n',
		'\f': '\\f',
		'\r': '\\r',
		'"' : '\\"',
		'\\': '\\\\'
	}
	
	function quoteReplacer (a)
	{
		return meta[a] || '\\u' + ('0000' + (+(a.charCodeAt(0))).toString(16)).slice(-4)
	}
	
	function quote (string)
	{
		escapeable.lastIndex = 0
		return '"' + string.replace(escapeable, quoteReplacer) + '"'
	}
	
	
	function str (value)
	{
		var i, k, v, length
		
		switch (typeof value)
		{
			case 'string':
				return quote(value)
			
			case 'number':
			case 'boolean':
			case 'null':
				return String_constructor(value)
			
			// Objects
			case 'object':
				// Null
				if (!value)
					return 'null'
				
				var partial = [], partial_length = 0
				
				// Array
				if (typeof value.length === 'number' && !(value.propertyIsEnumerable('length')))
				{
					length = value.length
					if (length === 0)
						return '[]'
					
					for (i = 0; i < length; i += 1)
						partial[i] = str(value[i])
					
					return '[' + partial.join(',') + ']'
				}
				
				// Date
				if (value.constructor === Date_constructor)
					return value.getUTCFullYear() + '-' +
							f(value.getUTCMonth() + 1) + '-' +
							f(value.getUTCDate()) + 'T' +
							f(value.getUTCHours()) + ':' +
							f(value.getUTCMinutes()) + ':' +
							f(value.getUTCSeconds()) + 'Z';
				
				// Plain object
				for (k in value)
					if (Object_hasOwnProperty.call(value, k))
						partial[partial_length++] = quote(k) + ':' + str(value[k])
				
				return partial_length === 0 ? '{}' : '{' + partial.join(',') + '}'
		}
	}
	
	function parse (code)
	{
		return eval('(' + code + ')')
	}
	
	Object.stringify = str
	Object.parse = parse
	
}) ();

/*
 * Sizzle CSS Selector Engine - v1.0
 *  Copyright 2009, The Dojo Foundation
 *  Released under the MIT, BSD, and GPL Licenses.
 *  More information: http://sizzlejs.com/
 */
;(function(){var o=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,i=0,d=Object.prototype.toString;var b=function(C,s,z,u){z=z||[];var e=s=s||document;if(s.nodeType!==1&&s.nodeType!==9){return[]}if(!C||typeof C!=="string"){return z}var A=[],B,x,F,E,y,r,q=true,v=n(s);o.lastIndex=0;while((B=o.exec(C))!==null){A.push(B[1]);if(B[2]){r=RegExp.rightContext;break}}if(A.length>1&&j.exec(C)){if(A.length===2&&f.relative[A[0]]){x=g(A[0]+A[1],s)}else{x=f.relative[A[0]]?[s]:b(A.shift(),s);while(A.length){C=A.shift();if(f.relative[C]){C+=A.shift()}x=g(C,x)}}}else{if(!u&&A.length>1&&s.nodeType===9&&!v&&f.match.ID.test(A[0])&&!f.match.ID.test(A[A.length-1])){var G=b.find(A.shift(),s,v);s=G.expr?b.filter(G.expr,G.set)[0]:G.set[0]}if(s){var G=u?{expr:A.pop(),set:a(u)}:b.find(A.pop(),A.length===1&&(A[0]==="~"||A[0]==="+")&&s.parentNode?s.parentNode:s,v);x=G.expr?b.filter(G.expr,G.set):G.set;if(A.length>0){F=a(x)}else{q=false}while(A.length){var t=A.pop(),w=t;if(!f.relative[t]){t=""}else{w=A.pop()}if(w==null){w=s}f.relative[t](F,w,v)}}else{F=A=[]}}if(!F){F=x}if(!F){throw"Syntax error, unrecognized expression: "+(t||C)}if(d.call(F)==="[object Array]"){if(!q){z.push.apply(z,F)}else{if(s&&s.nodeType===1){for(var D=0;F[D]!=null;D++){if(F[D]&&(F[D]===true||F[D].nodeType===1&&h(s,F[D]))){z.push(x[D])}}}else{for(var D=0;F[D]!=null;D++){if(F[D]&&F[D].nodeType===1){z.push(x[D])}}}}}else{a(F,z)}if(r){b(r,e,z,u);b.uniqueSort(z)}return z};b.uniqueSort=function(q){if(c){hasDuplicate=false;q.sort(c);if(hasDuplicate){for(var e=1;e<q.length;e++){if(q[e]===q[e-1]){q.splice(e--,1)}}}}};b.matches=function(e,q){return b(e,null,null,q)};b.find=function(w,e,x){var v,t;if(!w){return[]}for(var s=0,r=f.order.length;s<r;s++){var u=f.order[s],t;if((t=f.match[u].exec(w))){var q=RegExp.leftContext;if(q.substr(q.length-1)!=="\\"){t[1]=(t[1]||"").replace(/\\/g,"");v=f.find[u](t,e,x);if(v!=null){w=w.replace(f.match[u],"");break}}}}if(!v){v=e.getElementsByTagName("*")}return{set:v,expr:w}};b.filter=function(z,y,C,s){var r=z,E=[],w=y,u,e,v=y&&y[0]&&n(y[0]);while(z&&y.length){for(var x in f.filter){if((u=f.match[x].exec(z))!=null){var q=f.filter[x],D,B;e=false;if(w==E){E=[]}if(f.preFilter[x]){u=f.preFilter[x](u,w,C,E,s,v);if(!u){e=D=true}else{if(u===true){continue}}}if(u){for(var t=0;(B=w[t])!=null;t++){if(B){D=q(B,u,t,w);var A=s^!!D;if(C&&D!=null){if(A){e=true}else{w[t]=false}}else{if(A){E.push(B);e=true}}}}}if(D!==undefined){if(!C){w=E}z=z.replace(f.match[x],"");if(!e){return[]}break}}}if(z==r){if(e==null){throw"Syntax error, unrecognized expression: "+z}else{break}}r=z}return w};var f=b.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(e){return e.getAttribute("href")}},relative:{"+":function(w,e,v){var t=typeof e==="string",x=t&&!/\W/.test(e),u=t&&!x;if(x&&!v){e=e.toUpperCase()}for(var s=0,r=w.length,q;s<r;s++){if((q=w[s])){while((q=q.previousSibling)&&q.nodeType!==1){}w[s]=u||q&&q.nodeName===e?q||false:q===e}}if(u){b.filter(e,w,true)}},">":function(v,q,w){var t=typeof q==="string";if(t&&!/\W/.test(q)){q=w?q:q.toUpperCase();for(var r=0,e=v.length;r<e;r++){var u=v[r];if(u){var s=u.parentNode;v[r]=s.nodeName===q?s:false}}}else{for(var r=0,e=v.length;r<e;r++){var u=v[r];if(u){v[r]=t?u.parentNode:u.parentNode===q}}if(t){b.filter(q,v,true)}}},"":function(s,q,u){var r=i++,e=p;if(!q.match(/\W/)){var t=q=u?q:q.toUpperCase();e=m}e("parentNode",q,r,s,t,u)},"~":function(s,q,u){var r=i++,e=p;if(typeof q==="string"&&!q.match(/\W/)){var t=q=u?q:q.toUpperCase();e=m}e("previousSibling",q,r,s,t,u)}},find:{ID:function(q,r,s){if(typeof r.getElementById!=="undefined"&&!s){var e=r.getElementById(q[1]);return e?[e]:[]}},NAME:function(r,u,v){if(typeof u.getElementsByName!=="undefined"){var q=[],t=u.getElementsByName(r[1]);for(var s=0,e=t.length;s<e;s++){if(t[s].getAttribute("name")===r[1]){q.push(t[s])}}return q.length===0?null:q}},TAG:function(e,q){return q.getElementsByTagName(e[1])}},preFilter:{CLASS:function(s,q,r,e,v,w){s=" "+s[1].replace(/\\/g,"")+" ";if(w){return s}for(var t=0,u;(u=q[t])!=null;t++){if(u){if(v^(u.className&&(" "+u.className+" ").indexOf(s)>=0)){if(!r){e.push(u)}}else{if(r){q[t]=false}}}}return false},ID:function(e){return e[1].replace(/\\/g,"")},TAG:function(q,e){for(var r=0;e[r]===false;r++){}return e[r]&&n(e[r])?q[1]:q[1].toUpperCase()},CHILD:function(e){if(e[1]=="nth"){var q=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(e[2]=="even"&&"2n"||e[2]=="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(q[1]+(q[2]||1))-0;e[3]=q[3]-0}e[0]=i++;return e},ATTR:function(t,q,r,e,u,v){var s=t[1].replace(/\\/g,"");if(!v&&f.attrMap[s]){t[1]=f.attrMap[s]}if(t[2]==="~="){t[4]=" "+t[4]+" "}return t},PSEUDO:function(t,q,r,e,u){if(t[1]==="not"){if(t[3].match(o).length>1||/^\w/.test(t[3])){t[3]=b(t[3],null,null,q)}else{var s=b.filter(t[3],q,r,true^u);if(!r){e.push.apply(e,s)}return false}}else{if(f.match.POS.test(t[0])||f.match.CHILD.test(t[0])){return true}}return t},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){e.parentNode.selectedIndex;return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(r,q,e){return !!b(e[3],r).length},header:function(e){return/h\d/i.test(e.nodeName)},text:function(e){return"text"===e.type},radio:function(e){return"radio"===e.type},checkbox:function(e){return"checkbox"===e.type},file:function(e){return"file"===e.type},password:function(e){return"password"===e.type},submit:function(e){return"submit"===e.type},image:function(e){return"image"===e.type},reset:function(e){return"reset"===e.type},button:function(e){return"button"===e.type||e.nodeName.toUpperCase()==="BUTTON"},input:function(e){return/input|select|textarea|button/i.test(e.nodeName)}},setFilters:{first:function(q,e){return e===0},last:function(r,q,e,s){return q===s.length-1},even:function(q,e){return e%2===0},odd:function(q,e){return e%2===1},lt:function(r,q,e){return q<e[3]-0},gt:function(r,q,e){return q>e[3]-0},nth:function(r,q,e){return e[3]-0==q},eq:function(r,q,e){return e[3]-0==q}},filter:{PSEUDO:function(v,r,s,w){var q=r[1],t=f.filters[q];if(t){return t(v,s,r,w)}else{if(q==="contains"){return(v.textContent||v.innerText||"").indexOf(r[3])>=0}else{if(q==="not"){var u=r[3];for(var s=0,e=u.length;s<e;s++){if(u[s]===v){return false}}return true}}}},CHILD:function(e,s){var v=s[1],q=e;switch(v){case"only":case"first":while(q=q.previousSibling){if(q.nodeType===1){return false}}if(v=="first"){return true}q=e;case"last":while(q=q.nextSibling){if(q.nodeType===1){return false}}return true;case"nth":var r=s[2],y=s[3];if(r==1&&y==0){return true}var u=s[0],x=e.parentNode;if(x&&(x.sizcache!==u||!e.nodeIndex)){var t=0;for(q=x.firstChild;q;q=q.nextSibling){if(q.nodeType===1){q.nodeIndex=++t}}x.sizcache=u}var w=e.nodeIndex-y;if(r==0){return w==0}else{return(w%r==0&&w/r>=0)}}},ID:function(q,e){return q.nodeType===1&&q.getAttribute("id")===e},TAG:function(q,e){return(e==="*"&&q.nodeType===1)||q.nodeName===e},CLASS:function(q,e){return(" "+(q.className||q.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(u,s){var r=s[1],e=f.attrHandle[r]?f.attrHandle[r](u):u[r]!=null?u[r]:u.getAttribute(r),v=e+"",t=s[2],q=s[4];return e==null?t==="!=":t==="="?v===q:t==="*="?v.indexOf(q)>=0:t==="~="?(" "+v+" ").indexOf(q)>=0:!q?v&&e!==false:t==="!="?v!=q:t==="^="?v.indexOf(q)===0:t==="$="?v.substr(v.length-q.length)===q:t==="|="?v===q||v.substr(0,q.length+1)===q+"-":false},POS:function(t,q,r,u){var e=q[2],s=f.setFilters[e];if(s){return s(t,r,q,u)}}}};var j=f.match.POS;for(var l in f.match){f.match[l]=new RegExp(f.match[l].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var a=function(q,e){q=Array.prototype.slice.call(q);if(e){e.push.apply(e,q);return e}return q};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(k){a=function(t,s){var q=s||[];if(d.call(t)==="[object Array]"){Array.prototype.push.apply(q,t)}else{if(typeof t.length==="number"){for(var r=0,e=t.length;r<e;r++){q.push(t[r])}}else{for(var r=0;t[r];r++){q.push(t[r])}}}return q}}var c;if(document.documentElement.compareDocumentPosition){c=function(q,e){var r=q.compareDocumentPosition(e)&4?-1:q===e?0:1;if(r===0){hasDuplicate=true}return r}}else{if("sourceIndex" in document.documentElement){c=function(q,e){var r=q.sourceIndex-e.sourceIndex;if(r===0){hasDuplicate=true}return r}}else{if(document.createRange){c=function(s,q){var r=s.ownerDocument.createRange(),e=q.ownerDocument.createRange();r.selectNode(s);r.collapse(true);e.selectNode(q);e.collapse(true);var t=r.compareBoundaryPoints(Range.START_TO_END,e);if(t===0){hasDuplicate=true}return t}}}}(function(){var q=document.createElement("div"),r="script"+(new Date).getTime();q.innerHTML="<a name='"+r+"'/>";var e=document.documentElement;e.insertBefore(q,e.firstChild);if(!!document.getElementById(r)){f.find.ID=function(t,u,v){if(typeof u.getElementById!=="undefined"&&!v){var s=u.getElementById(t[1]);return s?s.id===t[1]||typeof s.getAttributeNode!=="undefined"&&s.getAttributeNode("id").nodeValue===t[1]?[s]:undefined:[]}};f.filter.ID=function(u,s){var t=typeof u.getAttributeNode!=="undefined"&&u.getAttributeNode("id");return u.nodeType===1&&t&&t.nodeValue===s}}e.removeChild(q)})();(function(){var e=document.createElement("div");e.appendChild(document.createComment(""));if(e.getElementsByTagName("*").length>0){f.find.TAG=function(q,u){var t=u.getElementsByTagName(q[1]);if(q[1]==="*"){var s=[];for(var r=0;t[r];r++){if(t[r].nodeType===1){s.push(t[r])}}t=s}return t}}e.innerHTML="<a href='#'></a>";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){f.attrHandle.href=function(q){return q.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var e=b,r=document.createElement("div");r.innerHTML="<p class='TEST'></p>";if(r.querySelectorAll&&r.querySelectorAll(".TEST").length===0){return}b=function(v,u,s,t){u=u||document;if(!t&&u.nodeType===9&&!n(u)){try{return a(u.querySelectorAll(v),s)}catch(w){}}return e(v,u,s,t)};for(var q in e){b[q]=e[q]}})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var e=document.createElement("div");e.innerHTML="<div class='test e'></div><div class='test'></div>";if(e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}f.order.splice(1,0,"CLASS");f.find.CLASS=function(q,r,s){if(typeof r.getElementsByClassName!=="undefined"&&!s){return r.getElementsByClassName(q[1])}}})()}function m(q,v,u,z,w,y){var x=q=="previousSibling"&&!y;for(var s=0,r=z.length;s<r;s++){var e=z[s];if(e){if(x&&e.nodeType===1){e.sizcache=u;e.sizset=s}e=e[q];var t=false;while(e){if(e.sizcache===u){t=z[e.sizset];break}if(e.nodeType===1&&!y){e.sizcache=u;e.sizset=s}if(e.nodeName===v){t=e;break}e=e[q]}z[s]=t}}}function p(q,v,u,z,w,y){var x=q=="previousSibling"&&!y;for(var s=0,r=z.length;s<r;s++){var e=z[s];if(e){if(x&&e.nodeType===1){e.sizcache=u;e.sizset=s}e=e[q];var t=false;while(e){if(e.sizcache===u){t=z[e.sizset];break}if(e.nodeType===1){if(!y){e.sizcache=u;e.sizset=s}if(typeof v!=="string"){if(e===v){t=true;break}}else{if(b.filter(v,[e]).length>0){t=e;break}}}e=e[q]}z[s]=t}}}var h=document.compareDocumentPosition?function(q,e){return q.compareDocumentPosition(e)&16}:function(q,e){return q!==e&&(q.contains?q.contains(e):true)};var n=function(e){return e.nodeType===9&&e.documentElement.nodeName!=="HTML"||!!e.ownerDocument&&e.ownerDocument.documentElement.nodeName!=="HTML"};var g=function(e,w){var s=[],t="",u,r=w.nodeType?[w]:w;while((u=f.match.PSEUDO.exec(e))){t+=u[0];e=e.replace(f.match.PSEUDO,"")}e=f.relative[e]?e+"*":e;for(var v=0,q=r.length;v<q;v++){b(e,r[v],s)}return b.filter(t,s)};window.cssQuery=window.Sizzle=b})();

Programica.RollingImagesLite = function (node, conf)
{
	this.conf = {duration: 1, animationType: 'easeOutBack'}
	Object.extend(this.conf, conf)
	this.current = null
	this.mainNode = node
	this.mainNode.RollingImagesLite = this
	
	
	var t = this
	function mouseup (e)
	{
		e.preventDefault()
		clearInterval(t.svInt)
		document.removeEventListener('mouseup', mouseup, false)
	}
	
	this.prevmousedown = function (e)
	{
		e.preventDefault()
		clearInterval(t.svInt)
		t.goPrev()
		t.svInt = setInterval(function () { t.goPrev() }, t.conf.duration * 1000 * 0.5 + 150)
		document.addEventListener('mouseup', mouseup, false)
	}
	
	this.nextmousedown = function (e)
	{
		e.preventDefault()
		clearInterval(t.svInt)
		t.goNext()
		t.svInt = setInterval(function () { t.goNext() }, t.conf.duration * 1000 * 0.5 + 150)
		document.addEventListener('mouseup', mouseup, false)
	}
	
	this.sync()
	if (this.conf.goInit !== false)
		this.goInit()
}

Programica.RollingImagesLite.prototype =
{
	sync: function ()
	{
		this.viewport = this.my('viewport')[0]
		if (!this.viewport)
			throw new Error('Can`t find viewport for ' + this.mainNode)
		if (!this.viewport.animate)
			throw new Error('Viewport can`t be animated!')
		
		this.points = this.my('point')
		this.buttons = this.my('button')
		this.aPrev = this.my('prev')[0]
		this.aNext = this.my('next')[0]
		
		// if syncing when pushed
		clearInterval(this.svInt)
		
		var t = this
		if (this.aPrev)
			this.aPrev.addEventListener('mousedown', this.prevmousedown, false)
		
		if (this.aNext)
			this.aNext.addEventListener('mousedown', this.nextmousedown, false)
		
		for (var i = 0, il = this.buttons.length; i < il; i++)
			this.buttons[i].onmousedown = function (fi) { return function () { t.goToFrame(fi) } } (i)
		
		this.updateNavigation()
	},
	
	goPrev: function () { if (this.current > 0) this.goToFrame(this.current - 1) },
	goNext: function () { if (this.current < this.points.length - 1) this.goToFrame(this.current + 1) },
	my: function (cn) { return this.mainNode.getElementsByClassName(cn) },
	
	goInit: function ()
	{
		return this.goToFrame(0, 'directJump')
	},
	
	goToFrame: function (n, anim, dur) { return this.points ? this.goToNode(this.points[n || 0], anim, dur) : null },
	
	goToNode: function (node, anim, dur)
	{
		if (!node)
			return null
		
		if (this.mainNode.onjump)
			if (this.mainNode.onjump(node) === false)
				return null
		
		// change number of current node
		for (var i = 0, il = this.points.length; i < il; i++)
			if (this.points[i] == node)
				this.setCurrent(i)
		
		return this.animateTo(node.offsetLeft, node.offsetTop, anim, dur)
	},
	
	animateTo: function (left, top, anim, dur) { return this.viewport.animate(anim || this.conf.animationType, {scrollLeft: left, scrollTop: top}, dur || this.conf.duration) },
	
	jumpTo: function (left, top) { this.viewport.scrollLeft = left; this.viewport.scrollTop = top },
	jumpToFrame: function (n)
	{
		var node = this.points[n]
		if (node)
		{
			this.setCurrent(n)
			this.jumpTo(node.offsetLeft, node.offsetTop)
		}
	},
	
	updateNavigation: function ()
	{
		for (var i = 0, il = this.buttons.length; i < il; i++)
			this.buttons[i].remClassName('selected-button')
		
		var button = this.buttons[this.current]
		if (button)
			button.addClassName('selected-button')
		
		if (this.aPrev)
			this.current > 0 ? this.aPrev.enable() : this.aPrev.disable()
		
		if (this.aNext)
			this.current < this.points.length - 1 ? this.aNext.enable() : this.aNext.disable()
	},
	
	setCurrent: function (num)
	{
    // if (num == this.current)
		//	return
		
		this.current = num
		this.updateNavigation()
		
		var cp = this.points[this.current]
		if (this.onselect)
			this.onselect(cp, this.current)
		
		if (cp && cp.onselect)
			cp.onselect()
	}
}


;(function(){

var doc = document, undef, myName = 'NodesShortcut'

function T (text)
{
	return doc.createTextNode(text)
}

function N (tag)
{
	return doc.createElement(tag)
}

function Nc (tag, cn)
{
	var node = doc.createElement(tag)
	node.className = cn
	return node
}

function Nct (tag, cn, text)
{
	var node = doc.createElement(tag)
	node.className = cn
	node.appendChild(doc.createTextNode(text))
	return node
}


function E (tag, cn, props)
{
	var node = doc.createElement(tag)
	if (cn !== undef) node.className = cn
	if (props)
		for (var i in props)
			node.setAttribute(i, props[i])
	return node
}

var Me = self[myName] = {}
	funcs = Me.funcs = {T: T, N: N, Nc: Nc, Nct: Nct, E: E}

var pairs = []
for (var k in funcs)
	pairs.push(k + '=' + myName + '.funcs.' + k)

Me.code = 'var ' + pairs.join(',')
Me.include = function () { return this.code }


})();


;(function(){

var account = 'UA-1635720-11'

if (!window._gaq)
	window._gaq = []

window._gaq.push(['_setAccount', account])
window._gaq.push(['_trackPageview'])

// async loading of async ga.js :)
function load ()
{
	// untouched inclusion snippet
	var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
	ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
	(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
}
$.onready(function () { setTimeout(function () { load() }, 250) })

})();
;(function(){

var myName = 'Statistics'

var Me =
{
	magazinePromoViewed: function (promo)
	{
		this.track('magazine-promo-viewed', promo ? promo.name : ('' + promo))
	},
	
	cocktailsFilterSelected: function (name)
	{
		this.track('cocktails-filter-selected', name)
	},
	
	cocktailViewRecipe: function (cocktail)
	{
		this.track('cocktail-view-recipe', cocktail ? cocktail.name : ('' + cocktail))
	},
	
	cocktailAddedToCalculator: function (cocktail)
	{
		this.track('cocktail-added-to-calculator', cocktail ? cocktail.name : ('' + cocktail))
	},
	
	toolPopupOpened: function (tool)
	{
		this.track('tool-popup', tool ? tool.name : ('' + tool))
	},
	
	ingredientPopupOpened: function (ingredient)
	{
		this.track('ingredient-popup', ingredient ? ingredient.name : ('' + ingredient))
	},
	
	ingredientTypedIn: function (ingredient)
	{
		this.track('ingredient-typed-in', ingredient ? ingredient.name : ('' + ingredient))
	},
	
	ingredientSelected: function (ingredient)
	{
		this.track('ingredient-selected', ingredient ? ingredient.name : ('' + ingredient))
	},
	
	track: function (action, label, value)
	{
		setTimeout(function () { Tracker.track('UserAction', action, label, value) }, 500)
	}
}

Me.className = myName
self[myName] = Me

})();
// ported from rutils.rb
;(function(){

var LOWER =
{
	"і":"i","ґ":"g","ё":"yo","№":"#","є":"e",
	"ї":"yi","а":"a","б":"b",
	"в":"v","г":"g","д":"d","е":"e","ж":"zh",
	"з":"z","и":"i","й":"y","к":"k","л":"l",
	"м":"m","н":"n","о":"o","п":"p","р":"r",
	"с":"s","т":"t","у":"u","ф":"f","х":"h",
	"ц":"ts","ч":"ch","ш":"sh","щ":"sch","ъ":"'",
	"ы":"yi","ь":"","э":"e","ю":"yu","я":"ya"
}

var UPPER =
{
	"Ґ":"G","Ё":"YO","Є":"E","Ї":"YI","І":"I",
	"А":"A","Б":"B","В":"V","Г":"G",
	"Д":"D","Е":"E","Ж":"ZH","З":"Z","И":"I",
	"Й":"Y","К":"K","Л":"L","М":"M","Н":"N",
	"О":"O","П":"P","Р":"R","С":"S","Т":"T",
	"У":"U","Ф":"F","Х":"H","Ц":"TS","Ч":"CH",
	"Ш":"SH","Щ":"SCH","Ъ":"'","Ы":"YI","Ь":"",
	"Э":"E","Ю":"YU","Я":"YA"
}

var undef, myName = 'RuTils', Me = self[myName] = 
{
	// Заменяет кириллицу в строке на латиницу. Немного специфично потому что поддерживает
	// комби-регистр (Щука -> Shuka)
	translify: function (str)
	{
		var res = []
		
		for (var i = 0; i < str.length; i++)
		{
			var c = str.charAt(i), r
			
			if ((r = UPPER[c]) !== undef)
			{
				if (LOWER[str.charAt(i+1)] !== undef)
					r = r.toLowerCase().capitalize()
			}
			else
			{
				r = LOWER[c]
				if (r === undef)
					r = c
			}
			
			res[i] = r
		}
		
		return res.join('')
	},
	
	dirify: function (s)
	{
		return s.translify()
				.replace(/(\s&\s)|(\s&amp;\s)/g, ' and ')
				.replace(/\W/g, ' ')
				.replace(/^_+|_+$/g, '')
				.replace(/^\s+|\s+$/g, '') // trim
				.translify() // yes, second
				.replace(/[\s\-]+/g, '-')
				.toLowerCase()
	}
}

// log("Щука".trans() == 'schuka')
// log("апельсиновый сок".trans() == 'apelsinovyiy-sok')

String.prototype.translify = function ()
{
	return Me.translify(this);
}

String.prototype.trans = function ()
{
	return Me.dirify(this);
}


})();

;(function(){

var myName = 'RoundedCorners'

function Me () {}

Me.round = function (node)
{
	node.appendChild(this.corners.cloneNode(true))
}

Me.init = function (node)
{
	var corners = this.corners = document.createElement('b')
	corners.className = 'rounding-corners'
	
	var classes = ['lt', 'rt', 'rb', 'lb']
	for (var i = 0, il = classes.length; i < il; i++)
	{
		var corner = document.createElement('b')
		corner.className = classes[i]
		corners.appendChild(corner)
	}
}

Me.className = myName
self[myName] = Me

Me.init()

})();

String.prototype.htmlName = function () { return this.replace(/[^\w\-\.]/g, "_").toLowerCase() }
String.prototype.capitalize = function () { return this.charAt(0).toUpperCase() + this.substr(1) }
