/*!
 * Copyright (c) 2009 Simo Kinnunen.
 * Licensed under the MIT license.
 */

var Cufon = (function() {
	
	var api = function() {	
		return api.replace.apply(null, arguments);
	};
	
	var DOM = api.DOM = {
			
		ready: (function() {
		
			var complete = false, readyStatus = { loaded: 1, complete: 1 };
		
			var queue = [], perform = function() {
				if (complete) return;
				complete = true;
				for (var fn; fn = queue.shift(); fn());
			};
			
			// Gecko, Opera, WebKit r26101+
			
			if (document.addEventListener) {
				document.addEventListener('DOMContentLoaded', perform, false);
				window.addEventListener('pageshow', perform, false); // For cached Gecko pages
			}
			
			// Old WebKit, Internet Explorer
			
			if (!window.opera && document.readyState) (function() {
				readyStatus[document.readyState] ? perform() : setTimeout(arguments.callee, 10);
			})();
			
			// Internet Explorer
			
			if (document.readyState && document.createStyleSheet) (function() {
				try {
					document.body.doScroll('left');
					perform();
				}
				catch (e) {
					setTimeout(arguments.callee, 1);
				}
			})();
			
			addEvent(window, 'load', perform); // Fallback
			
			return function(listener) {
				if (!arguments.length) perform();
				else complete ? listener() : queue.push(listener);
			};
			
		})()
		
	};

	var CSS = api.CSS = {
	
		Size: function(value, base) {
		
			this.value = parseFloat(value);
			this.unit = String(value).match(/[a-z%]*$/)[0] || 'px';
		
			this.convert = function(value) {
				return value / base * this.value;
			};
			
			this.convertFrom = function(value) {
				return value / this.value * base;
			};
			
			this.toString = function() {
				return this.value + this.unit;
			};

		},
		
		color: cached(function(value) {
			var parsed = {};
			parsed.color = value.replace(/^rgba\((.*?),\s*([\d.]+)\)/, function($0, $1, $2) {
				parsed.opacity = parseFloat($2);
				return 'rgb(' + $1 + ')';
			});
			return parsed;
		}),
	
		getStyle: function(el) {
			var view = document.defaultView;
			if (view && view.getComputedStyle) return new Style(view.getComputedStyle(el, null));
			if (el.currentStyle) return new Style(el.currentStyle);
			return new Style(el.style);
		},
		
		gradient: cached(function(value) {
			var gradient = {
				id: value,
				type: value.match(/^-([a-z]+)-gradient\(/)[1],
				stops: []
			}, colors = value.substr(value.indexOf('(')).match(/([\d.]+=)?(#[a-f0-9]+|[a-z]+\(.*?\)|[a-z]+)/ig);
			for (var i = 0, l = colors.length, stop; i < l; ++i) {
				stop = colors[i].split('=', 2).reverse();
				gradient.stops.push([ stop[1] || i / (l - 1), stop[0] ]);
			}
			return gradient;
		}),
		
		quotedList: cached(function(value) {
			// doesn't work properly with empty quoted strings (""), but
			// it's not worth the extra code.
			var list = [], re = /\s*((["'])([\s\S]*?[^\\])\2|[^,]+)\s*/g, match;
			while (match = re.exec(value)) list.push(match[3] || match[1]);
			return list;
		}),
		
		recognizesMedia: cached(function(media) {
			var el = document.createElement('style'), container, supported;
			el.type = 'text/css';
			el.media = media;
			container = elementsByTagName('head')[0];
			container.insertBefore(el, container.firstChild);
			supported = !!(el.sheet || el.styleSheet);
			container.removeChild(el);
			return supported;
		}),

		supports: function(property, value) {
			var checker = document.createElement('span').style;
			if (checker[property] === undefined) return false;
			checker[property] = value;
			return checker[property] === value;
		},
		
		textAlign: function(word, style, position, wordCount) {
			if (style.get('textAlign') == 'right') {
				if (position > 0) word = ' ' + word;
			}
			else if (position < wordCount - 1) word += ' ';
			return word;
		},
		
		textDecoration: function(el, style) {
			if (!style) style = this.getStyle(el);
			var types = {
				underline: null,
				overline: null,
				'line-through': null
			};
			for (var search = el; search.parentNode && search.parentNode.nodeType == 1; ) {
				var foundAll = true;
				for (var type in types) {
					if (!hasOwnProperty(types, type) || types[type]) continue;
					if (style.get('textDecoration').indexOf(type) != -1) types[type] = style.get('color');
					foundAll = false;
				}
				if (foundAll) break; // this is rather unlikely to happen
				style = this.getStyle(search = search.parentNode);
			}
			return types;
		},
		
		textShadow: cached(function(value) {
			if (value == 'none') return null;
			var shadows = [], currentShadow = {}, result, offCount = 0;
			var re = /(#[a-f0-9]+|[a-z]+\(.*?\)|[a-z]+)|(-?[\d.]+[a-z%]*)|,/ig;
			while (result = re.exec(value)) {
				if (result[0] == ',') {
					shadows.push(currentShadow);
					currentShadow = {}, offCount = 0;
				}
				else if (result[1]) {
					currentShadow.color = result[1];
				}
				else {
					currentShadow[[ 'offX', 'offY', 'blur' ][offCount++]] = result[2];
				}
			}
			shadows.push(currentShadow);
			return shadows;
		}),
		
		textTransform: function(text, style) {
			return text[{
				uppercase: 'toUpperCase',
				lowercase: 'toLowerCase'
			}[style.get('textTransform')] || 'toString']();
		},
		
		whiteSpace: (function() {
			var ignore = {
				inline: 1,
				'inline-block': 1,
				'run-in': 1
			};
			return function(text, style, node) {
				if (ignore[style.get('display')]) return text;
				if (!node.previousSibling) text = text.replace(/^\s+/, '');
				if (!node.nextSibling) text = text.replace(/\s+$/, '');
				return text;
			};
		})()
		
	};
	
	CSS.ready = (function() {
		
		// don't do anything in Safari 2 (it doesn't recognize any media type)
		var complete = !CSS.recognizesMedia('all');
		
		var queue = [], perform = function() {
			complete = true;
			for (var fn; fn = queue.shift(); fn());
		};
		
		var linkElements = elementsByTagName('link'), watch = {
			stylesheet: 1
		};
		
		function allStylesLoaded() {
			var sheet, i, link;
			for (i = 0; link = linkElements[i]; ++i) {
				if (link.disabled || !watch[link.rel.toLowerCase()] || !CSS.recognizesMedia(link.media || 'screen')) continue;
				sheet = link.sheet || link.styleSheet;
				// in Opera sheet.disabled is true when it's still loading,
				// even though link.disabled is false. they stay in sync if
				// set manually.
				if (!sheet || sheet.disabled) return false;
			}
			return true;
		}
		
		DOM.ready(function() {
			if (complete || allStylesLoaded()) perform();
			else setTimeout(arguments.callee, 10);
		});
		
		return function(listener) {
			if (complete) listener();
			else queue.push(listener);
		};
		
	})();
	
	function Font(data) {
		
		var face = this.face = data.face;
		this.glyphs = data.glyphs;
		this.w = data.w;
		this.baseSize = parseInt(face['units-per-em'], 10);
		
		this.family = face['font-family'].toLowerCase();
		this.weight = face['font-weight'];
		this.style = face['font-style'] || 'normal';
		
		this.viewBox = (function () {
			var parts = face.bbox.split(/\s+/);
			var box = {
				minX: parseInt(parts[0], 10),
				minY: parseInt(parts[1], 10),
				maxX: parseInt(parts[2], 10),
				maxY: parseInt(parts[3], 10)
			};
			box.width = box.maxX - box.minX,
			box.height = box.maxY - box.minY;
			box.toString = function() {
				return [ this.minX, this.minY, this.width, this.height ].join(' ');
			};
			return box;
		})();
		
		this.ascent = -parseInt(face.ascent, 10);
		this.descent = -parseInt(face.descent, 10);
		
		this.height = -this.ascent + this.descent;
		
	}
	
	function FontFamily() {

		var styles = {}, mapping = {
			oblique: 'italic',
			italic: 'oblique'
		};
		
		this.add = function(font) {
			(styles[font.style] || (styles[font.style] = {}))[font.weight] = font;
		};
		
		this.get = function(style, weight) {
			var weights = styles[style] || styles[mapping[style]]
				|| styles.normal || styles.italic || styles.oblique;
			if (!weights) return null;
			// we don't have to worry about "bolder" and "lighter"
			// because IE's currentStyle returns a numeric value for it,
			// and other browsers use the computed value anyway
			weight = {
				normal: 400,
				bold: 700
			}[weight] || parseInt(weight, 10);
			if (weights[weight]) return weights[weight];
			// http://www.w3.org/TR/CSS21/fonts.html#propdef-font-weight
			// Gecko uses x99/x01 for lighter/bolder
			var up = {
				1: 1,
				99: 0
			}[weight % 100], alts = [], min, max;
			if (up === undefined) up = weight > 400;
			if (weight == 500) weight = 400;
			for (var alt in weights) {
				if (!hasOwnProperty(weights, alt)) continue;
				alt = parseInt(alt, 10);
				if (!min || alt < min) min = alt;
				if (!max || alt > max) max = alt;
				alts.push(alt);
			}
			if (weight < min) weight = min;
			if (weight > max) weight = max;
			alts.sort(function(a, b) {
				return (up
					? (a > weight && b > weight) ? a < b : a > b
					: (a < weight && b < weight) ? a > b : a < b) ? -1 : 1;
			});
			return weights[alts[0]];
		};
	
	}
	
	function HoverHandler() {
		
		function contains(node, anotherNode) {
			if (node.contains) return node.contains(anotherNode);
			return node.compareDocumentPosition(anotherNode) & 16;
		}
		
		function onOverOut(e) {
			var related = e.relatedTarget;
			if (!related || contains(this, related)) return;
			trigger(this);
		}
		
		function onEnterLeave(e) {
			trigger(this);
		}

		function trigger(el) {
			// A timeout is needed so that the event can actually "happen"
			// before replace is triggered. This ensures that styles are up
			// to date.
			setTimeout(function() {
				api.replace(el, sharedStorage.get(el).options, true);
			}, 10);
		}
		
		this.attach = function(el) {
			if (el.onmouseenter === undefined) {
				addEvent(el, 'mouseover', onOverOut);
				addEvent(el, 'mouseout', onOverOut);
			}
			else {
				addEvent(el, 'mouseenter', onEnterLeave);
				addEvent(el, 'mouseleave', onEnterLeave);
			}
		};
		
	}
	
	function Storage() {
		
		var map = {}, at = 0;
		
		function identify(el) {
			return el.cufid || (el.cufid = ++at);
		}
		
		this.get = function(el) {
			var id = identify(el);
			return map[id] || (map[id] = {});
		};
		
	}
	
	function Style(style) {
		
		var custom = {}, sizes = {};
		
		this.get = function(property) {
			return custom[property] != undefined ? custom[property] : style[property];
		};
		
		this.getSize = function(property, base) {
			return sizes[property] || (sizes[property] = new CSS.Size(this.get(property), base));
		};
		
		this.extend = function(styles) {
			for (var property in styles) {
				if (hasOwnProperty(styles, property)) custom[property] = styles[property];
			}
			return this;
		};
		
	}
	
	function addEvent(el, type, listener) {
		if (el.addEventListener) {
			el.addEventListener(type, listener, false);
		}
		else if (el.attachEvent) {
			el.attachEvent('on' + type, function() {
				return listener.call(el, window.event);
			});
		}
	}
	
	function attach(el, options) {
		var storage = sharedStorage.get(el);
		if (storage.options) return el;
		if (options.hover && options.hoverables[el.nodeName.toLowerCase()]) {
			hoverHandler.attach(el);
		}
		storage.options = options;
		return el;
	}
	
	function cached(fun) {
		var cache = {};
		return function(key) {
			if (!hasOwnProperty(cache, key)) cache[key] = fun.apply(null, arguments);
			return cache[key];
		};	
	}
	
	function getFont(el, style) {
		if (!style) style = CSS.getStyle(el);
		var families = CSS.quotedList(style.get('fontFamily').toLowerCase()), family;
		for (var i = 0, l = families.length; i < l; ++i) {
			family = families[i];
			if (fonts[family]) return fonts[family].get(style.get('fontStyle'), style.get('fontWeight'));
		}
		return null;
	}
	
	function elementsByTagName(query) {
		return document.getElementsByTagName(query);
	}
	
	function hasOwnProperty(obj, property) {
		return obj.hasOwnProperty(property);
	}
	
	function merge() {
		var merged = {}, args, key;
		for (var i = 0, l = arguments.length; args = arguments[i], i < l; ++i) {
			for (key in args) {
				if (hasOwnProperty(args, key)) merged[key] = args[key];
			}
		}
		return merged;
	}
	
	function process(font, text, style, options, node, el) {
		var separate = options.separate;
		if (separate == 'none') return engines[options.engine].apply(null, arguments);
		var fragment = document.createDocumentFragment(), processed;
		var parts = text.split(separators[separate]), needsAligning = (separate == 'words');
		if (needsAligning && HAS_BROKEN_REGEXP) {
			// @todo figure out a better way to do this
			if (/^\s/.test(text)) parts.unshift('');
			if (/\s$/.test(text)) parts.push('');
		}
		for (var i = 0, l = parts.length; i < l; ++i) {
			processed = engines[options.engine](font,
				needsAligning ? CSS.textAlign(parts[i], style, i, l) : parts[i],
				style, options, node, el, i < l - 1);
			if (processed) fragment.appendChild(processed);
		}
		return fragment;
	}
	
	function replaceElement(el, options) {
		var font, style, node, nodeType, nextNode, redraw;
		for (node = attach(el, options).firstChild; node; node = nextNode) {
			nodeType = node.nodeType;
			nextNode = node.nextSibling;
			redraw = false;
			if (nodeType == 1) {
				if (!node.firstChild) continue;
				if (!/cufon/.test(node.className)) {
					arguments.callee(node, options);
					continue;
				}
				else redraw = true;
			}
			else if (nodeType != 3) continue;
			if (!style) style = CSS.getStyle(el).extend(options);
			if (!font) font = getFont(el, style);
			if (!font) continue;
			if (redraw) {
				engines[options.engine](font, null, style, options, node, el);
				continue;
			}
			var text = CSS.whiteSpace(node.data, style, node);
			if (text === '') continue;
			var processed = process(font, text, style, options, node, el);
			if (processed) node.parentNode.replaceChild(processed, node);
			else node.parentNode.removeChild(node);
		}
	}
	
	var HAS_BROKEN_REGEXP = ' '.split(/\s+/).length == 0;
	
	var sharedStorage = new Storage();
	var hoverHandler = new HoverHandler();
	var replaceHistory = [];
	
	var engines = {}, fonts = {}, defaultOptions = {
		enableTextDecoration: false,
		engine: null,
		//fontScale: 1,
		//fontScaling: false,
		hover: false,
		hoverables: {
			a: true
		},
		printable: true,
		//rotation: 0,
		//selectable: false,
		selector: (
				window.Sizzle
			||	(window.jQuery && function(query) { return jQuery(query); }) // avoid noConflict issues
			||	(window.dojo && dojo.query)
			||	(window.$$ && function(query) { return $$(query); })
			||	(window.$ && function(query) { return $(query); })
			||	(document.querySelectorAll && function(query) { return document.querySelectorAll(query); })
			||	elementsByTagName
		),
		separate: 'words', // 'none' and 'characters' are also accepted
		textShadow: 'none'
	};
	
	var separators = {
		words: /\s+/,
		characters: ''
	};
	
	api.now = function() {
		DOM.ready();
		return api;
	};
	
	api.refresh = function() {
		var currentHistory = replaceHistory.splice(0, replaceHistory.length);
		for (var i = 0, l = currentHistory.length; i < l; ++i) {
			api.replace.apply(null, currentHistory[i]);
		}
		return api;
	};
	
	api.registerEngine = function(id, engine) {
		if (!engine) return api;
		engines[id] = engine;
		return api.set('engine', id);
	};
	
	api.registerFont = function(data) {
		var font = new Font(data), family = font.family;
		if (!fonts[family]) fonts[family] = new FontFamily();
		fonts[family].add(font);
		return api.set('fontFamily', '"' + family + '"');
	};
	
	api.replace = function(elements, options, ignoreHistory) {
		options = merge(defaultOptions, options);
		if (!options.engine) return api; // there's no browser support so we'll just stop here
		if (typeof options.textShadow == 'string')
			options.textShadow = CSS.textShadow(options.textShadow);
		if (typeof options.color == 'string' && /^-/.test(options.color))
			options.textGradient = CSS.gradient(options.color);
		if (!ignoreHistory) replaceHistory.push(arguments);
		if (elements.nodeType || typeof elements == 'string') elements = [ elements ];
		CSS.ready(function() {
			for (var i = 0, l = elements.length; i < l; ++i) {
				var el = elements[i];
				if (typeof el == 'string') api.replace(options.selector(el), options, true);
				else replaceElement(el, options);
			}
		});
		return api;
	};
	
	api.set = function(option, value) {
		defaultOptions[option] = value;
		return api;
	};
	
	return api;
	
})();

Cufon.registerEngine('canvas', (function() {

	// Safari 2 doesn't support .apply() on native methods
	
	var check = document.createElement('canvas');
	if (!check || !check.getContext || !check.getContext.apply) return;
	check = null;
	
	var HAS_INLINE_BLOCK = Cufon.CSS.supports('display', 'inline-block');
	
	// Firefox 2 w/ non-strict doctype (almost standards mode)
	var HAS_BROKEN_LINEHEIGHT = !HAS_INLINE_BLOCK && (document.compatMode == 'BackCompat' || /frameset|transitional/i.test(document.doctype.publicId));
	
	var styleSheet = document.createElement('style');
	styleSheet.type = 'text/css';
	styleSheet.appendChild(document.createTextNode(
		'.cufon-canvas{text-indent:0}' +
		'@media screen,projection{' +
			'.cufon-canvas{display:inline;display:inline-block;position:relative;vertical-align:middle' + 
			(HAS_BROKEN_LINEHEIGHT
				? ''
				: ';font-size:1px;line-height:1px') +
			'}.cufon-canvas .cufon-alt{display:-moz-inline-box;display:inline-block;width:0;height:0;overflow:hidden}' +
			(HAS_INLINE_BLOCK
				? '.cufon-canvas canvas{position:relative}'
				: '.cufon-canvas canvas{position:absolute}') +
		'}' +
		'@media print{' +
			'.cufon-canvas{padding:0 !important}' +
			'.cufon-canvas canvas{display:none}' +
			'.cufon-canvas .cufon-alt{display:inline}' +
		'}'
	));
	document.getElementsByTagName('head')[0].appendChild(styleSheet);

	function generateFromVML(path, context) {
		var atX = 0, atY = 0;
		var code = [], re = /([mrvxe])([^a-z]*)/g, match;
		generate: for (var i = 0; match = re.exec(path); ++i) {
			var c = match[2].split(',');
			switch (match[1]) {
				case 'v':
					code[i] = { m: 'bezierCurveTo', a: [ atX + ~~c[0], atY + ~~c[1], atX + ~~c[2], atY + ~~c[3], atX += ~~c[4], atY += ~~c[5] ] };
					break;
				case 'r':
					code[i] = { m: 'lineTo', a: [ atX += ~~c[0], atY += ~~c[1] ] };
					break;
				case 'm':
					code[i] = { m: 'moveTo', a: [ atX = ~~c[0], atY = ~~c[1] ] };
					break;
				case 'x':
					code[i] = { m: 'closePath' };
					break;
				case 'e':
					break generate;
			}
			context[code[i].m].apply(context, code[i].a);
		}
		return code;
	}
	
	function interpret(code, context) {
		for (var i = 0, l = code.length; i < l; ++i) {
			var line = code[i];
			context[line.m].apply(context, line.a);
		}
	}
	
	return function(font, text, style, options, node, el) {
		
		var redraw = (text === null);
		
		var viewBox = font.viewBox;
		
		var size = style.getSize('fontSize', font.baseSize);
		
		var letterSpacing = style.get('letterSpacing');
		letterSpacing = (letterSpacing == 'normal') ? 0 : size.convertFrom(parseInt(letterSpacing, 10));
		
		var expandTop = 0, expandRight = 0, expandBottom = 0, expandLeft = 0;
		var shadows = options.textShadow, shadowOffsets = [];
		if (shadows) {
			for (var i = shadows.length; i--;) {
				var shadow = shadows[i];
				var x = size.convertFrom(parseFloat(shadow.offX));
				var y = size.convertFrom(parseFloat(shadow.offY));
				shadowOffsets[i] = [ x, y ];
				if (y < expandTop) expandTop = y;
				if (x > expandRight) expandRight = x;
				if (y > expandBottom) expandBottom = y;
				if (x < expandLeft) expandLeft = x;
			}
		}
		
		var chars = Cufon.CSS.textTransform(redraw ? node.alt : text, style).split('');
		
		var width = 0, lastWidth = null;
		
		for (var i = 0, l = chars.length; i < l; ++i) {
			var glyph = font.glyphs[chars[i]] || font.missingGlyph;
			if (!glyph) continue;
			width += lastWidth = Number(glyph.w || font.w) + letterSpacing;
		}
		
		if (lastWidth === null) return null; // there's nothing to render
		
		expandRight += (viewBox.width - lastWidth);
		expandLeft += viewBox.minX;
		
		var wrapper, canvas;
		
		if (redraw) {
			wrapper = node;
			canvas = node.firstChild;
		}
		else {
			wrapper = document.createElement('span');
			wrapper.className = 'cufon cufon-canvas';
			wrapper.alt = text;
			
			canvas = document.createElement('canvas');
			wrapper.appendChild(canvas);
			
			if (options.printable) {
				var print = document.createElement('span');
				print.className = 'cufon-alt';
				print.appendChild(document.createTextNode(text));
				wrapper.appendChild(print);
			}
		}
		
		var wStyle = wrapper.style;
		var cStyle = canvas.style;
		
		var height = size.convert(viewBox.height);
		var roundedHeight = Math.ceil(height);
		var roundingFactor = roundedHeight / height;
		
		canvas.width = Math.ceil(size.convert(width * roundingFactor + expandRight - expandLeft));
		canvas.height = Math.ceil(size.convert(viewBox.height - expandTop + expandBottom));
		
		// minY has no part in canvas.height
		expandTop += viewBox.minY;
		
		cStyle.top = Math.round(size.convert(expandTop - font.ascent)) + 'px';
		cStyle.left = Math.round(size.convert(expandLeft)) + 'px';
		
		var wrapperWidth = Math.ceil(size.convert(width * roundingFactor)) + 'px';
		
		if (HAS_INLINE_BLOCK) {
			wStyle.width = wrapperWidth;
			wStyle.height = size.convert(font.height) + 'px';
		}
		else {
			wStyle.paddingLeft = wrapperWidth;
			wStyle.paddingBottom = (size.convert(font.height) - 1) + 'px';
		}
		
		var g = canvas.getContext('2d'), scale = height / viewBox.height;
		
		// proper horizontal scaling is performed later
		g.scale(scale, scale * roundingFactor);
		g.translate(-expandLeft, -expandTop);
		
		g.lineWidth = font.face['underline-thickness'];
		
		g.save();
		
		function line(y, color) {
			g.strokeStyle = color;
			
			g.beginPath();
			
			g.moveTo(0, y);
			g.lineTo(width, y);
			
			g.stroke();
		}
		
		var textDecoration = options.enableTextDecoration ? Cufon.CSS.textDecoration(el, style) : {};
		
		if (textDecoration.underline) line(-font.face['underline-position'], textDecoration.underline);
		if (textDecoration.overline) line(font.ascent, textDecoration.overline);
		
		g.fillStyle = style.get('color');
		
		function renderText() {
			g.scale(roundingFactor, 1);
			for (var i = 0, l = chars.length; i < l; ++i) {
				var glyph = font.glyphs[chars[i]] || font.missingGlyph;
				if (!glyph) continue;
				if (glyph.d) {
					g.beginPath();
					if (glyph.code) interpret(glyph.code, g);
					else glyph.code = generateFromVML('m' + glyph.d, g);
					g.fill();
				}
				g.translate(Number(glyph.w || font.w) + letterSpacing, 0);
			}
			g.restore();
		}
		
		if (shadows) {
			for (var i = shadows.length; i--;) {
				var shadow = shadows[i];
				g.save();
				g.fillStyle = shadow.color;
				g.translate.apply(g, shadowOffsets[i]);
				renderText();
			}
		}
		
		var gradient = options.textGradient;
		if (gradient) {
			var stops = gradient.stops, fill = g.createLinearGradient(0, viewBox.minY, 0, viewBox.maxY);
			for (var i = 0, l = stops.length; i < l; ++i) {
				fill.addColorStop.apply(fill, stops[i]);
			}
			g.fillStyle = fill;
		}
		
		renderText();
		
		if (textDecoration['line-through']) line(-font.descent, textDecoration['line-through']);
		
		return wrapper;
			
	};
	
})());

Cufon.registerEngine('vml', (function() {

	if (!document.namespaces) return;
	
	if (document.namespaces.cvml == null) {
		document.namespaces.add('cvml', 'urn:schemas-microsoft-com:vml');
	}
	
	var check = document.createElement('cvml:shape');
	check.style.behavior = 'url(#default#VML)';
	if (!check.coordsize) return; // VML isn't supported
	check = null;
	
	document.write('<style type="text/css">' +
		'.cufon-vml-canvas{text-indent:0}' +
		'@media screen{' + 
			'cvml\\:shape,cvml\\:fill,cvml\\:shadow{behavior:url(#default#VML);display:block;antialias:true;position:absolute}' +
			'.cufon-vml-canvas{position:absolute;text-align:left}' +
			'.cufon-vml{display:inline-block;position:relative;vertical-align:middle}' +
			'.cufon-vml .cufon-alt{position:absolute;left:-10000in;font-size:1px}' +
			'a .cufon-vml{cursor:pointer}' +
		'}' +
		'@media print{' + 
			'.cufon-vml *{display:none}' +
			'.cufon-vml .cufon-alt{display:inline}' +
		'}' +
	'</style>');

	function getFontSizeInPixels(el, value) {
		return getSizeInPixels(el, /(?:em|ex|%)$/i.test(value) ? '1em' : value);
	}
	
	// Original by Dead Edwards.
	// Combined with getFontSizeInPixels it also works with relative units.
	function getSizeInPixels(el, value) {
		if (/px$/i.test(value)) return parseFloat(value);
		var style = el.style.left, runtimeStyle = el.runtimeStyle.left;
		el.runtimeStyle.left = el.currentStyle.left;
		el.style.left = value;
		var result = el.style.pixelLeft;
		el.style.left = style;
		el.runtimeStyle.left = runtimeStyle;
		return result;
	}
	
	var fills = {};
	
	function gradientFill(gradient) {
		var id = gradient.id;
		if (!fills[id]) {
			var stops = gradient.stops, fill = document.createElement('cvml:fill'), colors = [];
			fill.type = 'gradient';
			fill.angle = 180;
			fill.focus = '0';
			fill.method = 'sigma';
			fill.color = stops[0][1];
			for (var j = 1, k = stops.length - 1; j < k; ++j) {
				colors.push(stops[j][0] * 100 + '% ' + stops[j][1]);
			}
			fill.colors = colors.join(',');
			fill.color2 = stops[k][1];
			fills[id] = fill;
		}
		return fills[id];
	}
	
	return function(font, text, style, options, node, el, hasNext) {
		
		var redraw = (text === null);
		
		if (redraw) text = node.alt;
		
		// @todo word-spacing, text-decoration
	
		var viewBox = font.viewBox;
		
		var size = style.computedFontSize || (style.computedFontSize = new Cufon.CSS.Size(getFontSizeInPixels(el, style.get('fontSize')) + 'px', font.baseSize));
		
		var letterSpacing = style.computedLSpacing;
		
		if (letterSpacing == undefined) {
			letterSpacing = style.get('letterSpacing');
			style.computedLSpacing = letterSpacing = (letterSpacing == 'normal') ? 0 : ~~size.convertFrom(getSizeInPixels(el, letterSpacing));
		}
		
		var wrapper, canvas;
		
		if (redraw) {
			wrapper = node;
			canvas = node.firstChild;
		}
		else {
			wrapper = document.createElement('span');
			wrapper.className = 'cufon cufon-vml';
			wrapper.alt = text;
			
			canvas = document.createElement('span');
			canvas.className = 'cufon-vml-canvas';
			wrapper.appendChild(canvas);
			
			if (options.printable) {
				var print = document.createElement('span');
				print.className = 'cufon-alt';
				print.appendChild(document.createTextNode(text));
				wrapper.appendChild(print);
			}
			
			// ie6, for some reason, has trouble rendering the last VML element in the document.
			// we can work around this by injecting a dummy element where needed.
			// @todo find a better solution
			if (!hasNext) wrapper.appendChild(document.createElement('cvml:shape'));
		}
		
		var wStyle = wrapper.style;
		var cStyle = canvas.style;
		
		var height = size.convert(viewBox.height), roundedHeight = Math.ceil(height);
		var roundingFactor = roundedHeight / height;
		var minX = viewBox.minX, minY = viewBox.minY;
		
		cStyle.height = roundedHeight;
		cStyle.top = Math.round(size.convert(minY - font.ascent));
		cStyle.left = Math.round(size.convert(minX));
		
		wStyle.height = size.convert(font.height) + 'px';
		
		var textDecoration = options.enableTextDecoration ? Cufon.CSS.textDecoration(el, style) : {};
		
		var color = style.get('color');
		var chars = Cufon.CSS.textTransform(text, style).split('');
		
		var width = 0, offsetX = 0, advance = null;
		
		var glyph, shape, shadows = options.textShadow;
		
		// pre-calculate width
		for (var i = 0, k = 0, l = chars.length; i < l; ++i) {
			glyph = font.glyphs[chars[i]] || font.missingGlyph;
			if (glyph) width += advance = ~~(glyph.w || font.w) + letterSpacing;
		}
		
		if (advance === null) return null;
		
		var fullWidth = -minX + width + (viewBox.width - advance);
	
		var shapeWidth = size.convert(fullWidth * roundingFactor), roundedShapeWidth = Math.round(shapeWidth);
		
		var coordSize = fullWidth + ',' + viewBox.height, coordOrigin;
		var stretch = 'r' + coordSize + 'ns';
		
		var fill = options.textGradient && gradientFill(options.textGradient);
		
		for (i = 0; i < l; ++i) {
			
			glyph = font.glyphs[chars[i]] || font.missingGlyph;
			if (!glyph) continue;
			
			if (redraw) {
				// some glyphs may be missing so we can't use i
				shape = canvas.childNodes[k];
				if (shape.firstChild) shape.removeChild(shape.firstChild); // shadow, fill
			}
			else { 
				shape = document.createElement('cvml:shape');
				canvas.appendChild(shape);
			}
			
			shape.stroked = 'f';
			shape.coordsize = coordSize;
			shape.coordorigin = coordOrigin = (minX - offsetX) + ',' + minY;
			shape.path = (glyph.d ? 'm' + glyph.d + 'xe' : '') + 'm' + coordOrigin + stretch;
			shape.fillcolor = color;
			
			if (fill) shape.appendChild(fill.cloneNode(false));
			
			// it's important to not set top/left or IE8 will grind to a halt
			var sStyle = shape.style;
			sStyle.width = roundedShapeWidth;
			sStyle.height = roundedHeight;
			
			if (shadows) {
				// due to the limitations of the VML shadow element there
				// can only be two visible shadows. opacity is shared
				// for all shadows.
				var shadow1 = shadows[0], shadow2 = shadows[1];
				var color1 = Cufon.CSS.color(shadow1.color), color2;
				var shadow = document.createElement('cvml:shadow');
				shadow.on = 't';
				shadow.color = color1.color;
				shadow.offset = shadow1.offX + ',' + shadow1.offY;
				if (shadow2) {
					color2 = Cufon.CSS.color(shadow2.color);
					shadow.type = 'double';
					shadow.color2 = color2.color;
					shadow.offset2 = shadow2.offX + ',' + shadow2.offY;
				}
				shadow.opacity = color1.opacity || (color2 && color2.opacity) || 1;
				shape.appendChild(shadow);
			}
			
			offsetX += ~~(glyph.w || font.w) + letterSpacing;
			
			++k;
			
		}
		
		wStyle.width = Math.max(Math.ceil(size.convert(width * roundingFactor)), 0);
		
		return wrapper;
		
	};
	
})());
//futura below here
Cufon.registerFont({"w":189,"face":{"font-family":"Klavika Light","font-weight":300,"font-stretch":"normal","units-per-em":"360","panose-1":"2 0 5 6 4 0 0 2 0 4","ascent":"288","descent":"-72","x-height":"4","bbox":"-4 -285.934 311 76","underline-thickness":"7.2","underline-position":"-40.68","stemh":"19","stemv":"21","unicode-range":"U+0020-U+007E"},"glyphs":{" ":{"w":79},"!":{"d":"51,-62r-12,0v-5,-58,-4,-122,-4,-185r21,0r0,125xm34,0r0,-31r23,0r0,31r-23,0","w":90},"\"":{"d":"45,-159r-18,0r0,-88r18,0r0,88xm100,-159r-18,0r0,-88r18,0r0,88","w":127},"#":{"d":"174,-64r-32,0r-3,64r-18,0r4,-64r-61,0r-3,64r-18,0r3,-64r-32,0r1,-17r33,0r3,-76r-33,0r1,-17r34,0r3,-59r17,0r-3,59r61,0r3,-59r18,0r-4,59r31,0r-1,17r-31,0r-4,76r32,0xm69,-157r-4,76r61,0r4,-76r-61,0"},"$":{"d":"105,39r-20,0r0,-36v-19,0,-39,-4,-54,-11r3,-16v41,10,105,24,105,-33v0,-35,0,-38,-52,-52v-51,-14,-51,-27,-51,-67v0,-38,14,-58,56,-60r0,-36r20,0r0,36v16,1,31,3,47,7r-2,18v-41,-6,-100,-22,-100,35v0,37,1,38,42,50v57,18,61,24,61,68v0,42,-19,59,-55,61r0,36"},"%":{"d":"208,-237r-98,241r-16,-7r99,-240xm71,-243v51,-1,51,35,51,83v0,30,-15,48,-51,48v-51,1,-51,-36,-51,-84v0,-29,15,-47,51,-47xm71,-228v-41,-2,-32,34,-33,69v0,19,8,31,33,31v41,1,32,-33,33,-68v0,-20,-8,-32,-33,-32xm231,-127v51,-1,51,35,51,83v0,30,-15,48,-51,48v-51,1,-52,-35,-52,-84v0,-29,16,-47,52,-47xm231,-112v-40,-2,-34,33,-34,68v0,20,9,32,34,32v40,2,32,-33,33,-68v0,-20,-8,-32,-33,-32","w":303},"&":{"d":"208,-111r-36,0r0,105v-52,17,-152,18,-141,-47v-2,-35,4,-61,33,-68v-31,-11,-28,-35,-28,-71v0,-58,81,-57,132,-43r-3,18v-37,-8,-108,-20,-108,25v0,35,-2,63,37,62r114,0r0,19xm51,-54v-9,46,62,42,101,34r0,-91v-53,0,-113,-10,-101,57","w":222},"'":{"d":"45,-159r-18,0r0,-88r18,0r0,88","w":72},"(":{"d":"98,45r-16,10v-73,-100,-73,-230,0,-329r16,10v-39,62,-50,103,-50,155v0,51,11,92,50,154","w":108},")":{"d":"26,55r-15,-10v39,-62,49,-103,49,-154v0,-52,-10,-93,-49,-155r15,-10v73,99,74,229,0,329","w":108},"*":{"d":"44,-140r29,-45r-53,0r0,-13r54,0r-30,-46r11,-7r31,47r30,-47r11,7r-29,46r54,0r0,13r-54,0r29,45r-11,7r-30,-47r-31,47","w":171},"+":{"d":"21,-78r0,-19r63,0r0,-64r20,0r0,64r63,0r0,19r-63,0r0,64r-20,0r0,-64r-63,0"},",":{"d":"32,0r0,-31r22,0v3,32,-8,50,-17,70r-10,-4r13,-35r-8,0","w":86},"-":{"d":"23,-92r0,-18r84,0r0,18r-84,0","w":130},".":{"d":"32,0r0,-31r23,0r0,31r-23,0","w":87},"\/":{"d":"133,-243r-89,285r-21,0r89,-285r21,0","w":158},"0":{"d":"94,-236v102,0,72,94,72,178v0,36,-19,62,-72,62v-102,0,-72,-95,-72,-179v0,-36,19,-61,72,-61xm94,-217v-83,0,-51,93,-51,158v0,29,12,44,51,44v40,0,51,-15,51,-44r0,-114v0,-30,-11,-44,-51,-44"},"1":{"d":"27,0r0,-18r59,0r0,-194r-56,20r-6,-18v28,-7,47,-23,83,-23r0,215r59,0r0,18r-139,0"},"2":{"d":"155,-180v0,52,-68,117,-100,161r102,0r0,19r-128,0r0,-19v29,-44,104,-106,105,-160v13,-48,-67,-41,-99,-30r-4,-18v13,-4,36,-9,57,-9v56,0,67,20,67,56"},"3":{"d":"27,-4r3,-18v41,10,114,16,107,-32v11,-57,-40,-57,-93,-54r0,-18v37,1,87,5,87,-31v0,-39,0,-63,-45,-60v-16,0,-38,2,-53,5r-2,-18v50,-13,121,-8,121,44v0,34,3,59,-27,69v26,5,36,30,33,64v9,59,-75,66,-131,49"},"4":{"d":"177,-63r-32,0r0,63r-21,0r0,-63r-108,0r0,-21r96,-149r33,0r0,152r32,0r0,18xm37,-81r87,0r0,-137"},"5":{"d":"39,-111r0,-122r120,0r0,19r-99,0r0,84v52,-4,109,7,101,56v3,52,-8,77,-71,78v-19,0,-42,-2,-60,-8r4,-18v39,10,106,18,106,-34v0,-36,-2,-55,-42,-55r-59,0"},"6":{"d":"121,-217v-76,-4,-72,34,-71,97v12,-5,35,-10,52,-10v56,0,62,28,62,76v0,36,-17,58,-66,58v-93,0,-61,-83,-68,-159v-7,-74,56,-91,128,-76r-2,18v-9,-3,-24,-4,-35,-4xm143,-75v9,-47,-65,-38,-93,-25v-2,47,-4,85,48,85v43,0,47,-21,45,-60"},"7":{"d":"27,-214r0,-19r146,0r0,18r-115,215r-23,0r115,-214r-123,0"},"8":{"d":"161,-180v1,31,-7,44,-43,61v39,18,49,32,49,67v0,39,-22,56,-73,56v-91,0,-97,-99,-25,-123v-35,-17,-42,-33,-41,-61v0,-31,15,-56,66,-56v51,0,67,25,67,56xm146,-53v0,-33,-9,-36,-52,-56v-43,18,-52,23,-52,56v0,29,14,38,52,38v38,0,52,-9,52,-38xm49,-183v-1,32,6,37,45,55v39,-18,47,-23,46,-55v0,-21,-11,-34,-46,-34v-35,0,-45,12,-45,34"},"9":{"d":"68,-15v78,4,71,-34,71,-97v-12,4,-35,9,-52,9v-57,0,-62,-27,-62,-76v0,-36,18,-57,66,-57v94,0,60,83,68,159v7,73,-57,92,-128,75r2,-17v9,2,24,4,35,4xm46,-158v-9,46,64,39,93,26v2,-47,4,-85,-48,-85v-43,0,-47,20,-45,59"},":":{"d":"32,0r0,-31r23,0r0,31r-23,0xm32,-115r0,-31r23,0r0,31r-23,0","w":87},";":{"d":"32,0r0,-31r22,0v3,32,-8,50,-17,70r-10,-4r13,-35r-8,0xm32,-115r0,-31r22,0r0,31r-22,0","w":86},"<":{"d":"18,-80r0,-15r143,-84r9,15r-131,76r132,76r-9,16"},"=":{"d":"32,-111r0,-17r125,0r0,17r-125,0xm32,-49r0,-17r125,0r0,17r-125,0"},">":{"d":"171,-95r0,15r-144,84r-9,-16r132,-76r-131,-76r9,-15"},"?":{"d":"68,-83r-13,-16v25,-25,72,-36,64,-87v10,-57,-50,-49,-94,-40r-3,-18v16,-4,36,-7,52,-7v56,0,66,19,66,64v0,60,-42,75,-72,104xm55,0r0,-35r23,0r0,35r-23,0","w":164},"@":{"d":"154,-100r10,-58v-20,-5,-44,-9,-47,13v-2,14,-6,28,-8,42v-3,24,33,10,45,3xm118,-74v-41,0,-20,-44,-18,-71v3,-39,52,-37,83,-23r-13,76v35,12,59,-16,59,-52v0,-53,-34,-83,-90,-83v-54,0,-97,43,-97,107v0,63,35,107,109,107v24,0,47,-6,70,-16r5,15v-88,47,-203,-1,-203,-106v0,-73,50,-123,116,-123v71,0,108,42,108,99v0,52,-51,91,-91,60v-11,5,-22,10,-38,10","w":270},"A":{"d":"190,0r-23,-63r-111,0r-23,63r-20,0r83,-240r31,0r84,240r-21,0xm112,-228r-50,147r99,0","w":223},"B":{"d":"181,-80v0,101,-74,79,-149,80r0,-240v59,3,142,-17,142,47v0,34,2,59,-27,68v18,3,34,18,34,45xm127,-19v35,1,33,-28,33,-61v0,-44,-64,-32,-106,-33r0,94r73,0xm116,-132v39,0,37,-27,37,-63v0,-40,-62,-22,-99,-26r0,89r62,0","w":201},"C":{"d":"108,-224v-88,0,-53,89,-60,158v-6,58,63,55,114,46r2,18v-65,16,-143,3,-137,-64v7,-87,-25,-177,80,-177v17,0,39,1,57,5r-2,18v-17,-2,-38,-4,-54,-4","w":183},"D":{"d":"32,-240r80,0v99,-2,74,86,74,169v0,41,-16,71,-74,71r-80,0r0,-240xm54,-221r0,202v54,1,118,6,111,-51v-8,-64,26,-156,-53,-151r-58,0","w":212},"E":{"d":"32,0r0,-240r135,0r0,19r-113,0r0,89r105,0r0,19r-105,0r0,94r114,0r0,19r-136,0","w":192},"F":{"d":"54,0r-22,0r0,-240r137,0r0,19r-115,0r0,93r107,0r0,19r-107,0r0,109","w":183},"G":{"d":"107,-224v-89,0,-50,89,-59,157v-8,57,60,58,108,46r0,-85r21,0r0,100v-23,6,-50,10,-73,10v-105,0,-68,-92,-77,-178v-7,-70,80,-78,145,-63r-2,18v-20,-3,-43,-5,-63,-5","w":205},"H":{"d":"191,0r-21,0r0,-114r-116,0r0,114r-22,0r0,-240r22,0r0,107r116,0r0,-107r21,0r0,240","w":223},"I":{"d":"55,-240r0,240r-21,0r0,-240r21,0","w":89},"J":{"d":"32,-240r22,0r0,238v0,30,-3,32,-44,71r-14,-15v36,-34,36,-36,36,-54r0,-240","w":84},"K":{"d":"54,-240r0,240r-22,0r0,-240r22,0xm184,-240r-97,118r103,122r-26,0r-102,-122r95,-118r27,0","w":204},"L":{"d":"54,-240r0,221r108,0r0,19r-130,0r0,-240r22,0","w":177},"M":{"d":"234,0r-5,-219r-70,188r-32,0r-70,-188r-5,219r-21,0r7,-240r31,0r74,196r74,-196r31,0r8,240r-22,0","w":286},"N":{"d":"166,0r-113,-219r0,219r-21,0r0,-240r31,0r114,219r0,-219r20,0r0,240r-31,0","w":229},"O":{"d":"195,-172v0,90,23,176,-84,176v-107,0,-84,-86,-84,-176v0,-41,22,-71,84,-71v61,0,84,30,84,71xm111,-15v90,0,63,-83,63,-156v0,-35,-17,-53,-63,-53v-90,0,-63,84,-63,156v0,34,17,53,63,53","w":221},"P":{"d":"32,0r0,-240r82,0v65,0,66,36,66,93v0,34,-18,56,-66,56r-60,0r0,91r-22,0xm158,-147v0,-42,3,-74,-44,-74r-60,0r0,110v44,-2,104,12,104,-36","w":195},"Q":{"d":"153,50r-19,8r-24,-54v-106,1,-83,-86,-83,-176v0,-41,22,-71,84,-71v107,0,84,85,84,175v0,36,-18,64,-63,70xm111,-15v90,0,63,-83,63,-156v0,-35,-17,-53,-63,-53v-90,0,-63,84,-63,156v0,34,17,53,63,53","w":221},"R":{"d":"184,0r-62,-92r-68,0r0,92r-22,0r0,-240r85,0v65,0,66,35,66,92v0,27,-11,46,-39,53r64,95r-24,0xm162,-148v0,-42,2,-73,-44,-73r-64,0r0,110v45,-2,108,13,108,-37","w":222},"S":{"d":"169,-59v0,39,-13,63,-74,63v-21,0,-47,-4,-68,-12r4,-17v43,13,117,22,117,-33v0,-37,-1,-41,-54,-54v-58,-13,-64,-23,-64,-72v0,-39,14,-59,74,-59v21,0,46,3,62,8r-3,18v-17,-4,-40,-7,-58,-7v-48,0,-54,11,-54,41v0,39,1,41,51,53v63,16,67,25,67,71","w":195},"T":{"d":"83,0r0,-221r-74,0r0,-19r169,0r0,19r-74,0r0,221r-21,0","w":186},"U":{"d":"175,-240r21,0r0,172v0,41,-24,72,-83,72v-58,0,-82,-31,-82,-72r0,-172r21,0r0,172v0,33,21,53,61,53v41,0,62,-20,62,-53r0,-172","w":226},"V":{"d":"106,-19r78,-221r21,0r-84,240r-29,0r-85,-240r21,0","w":212},"W":{"d":"213,0r-53,-225r-53,225r-33,0r-65,-240r21,0r60,224r53,-224r34,0r54,224r60,-224r20,0r-64,240r-34,0","w":320},"X":{"d":"13,0r80,-122r-78,-118r23,0r66,101r67,-101r23,0r-78,118r80,122r-23,0r-69,-105r-68,105r-23,0","w":208},"Y":{"d":"27,-240r71,145r70,-145r22,0r-82,166r0,74r-21,0r0,-74r-82,-166r22,0","w":195},"Z":{"d":"180,-221r-131,202r133,0r0,19r-157,0r0,-19r131,-202r-127,0r0,-19r151,0r0,19","w":207},"[":{"d":"101,45r-65,0r0,-329r65,0r0,19r-44,0r0,291r44,0r0,19","w":111},"\\":{"d":"114,42r-89,-285r21,0r89,285r-21,0","w":158},"]":{"d":"76,45r-65,0r0,-19r44,0r0,-291r-44,0r0,-19r65,0r0,329","w":111},"^":{"d":"35,-137r-17,-10r52,-100r23,0r52,100r-16,10r-47,-91","w":163},"_":{"d":"155,13r-154,0r0,-9r154,0r0,9","w":156},"`":{"d":"85,-211r-10,14v-15,-8,-33,-18,-48,-29r10,-16v16,11,33,22,48,31","w":111},"a":{"d":"84,-179v98,0,55,102,64,179r-18,0r-2,-14v-33,26,-105,29,-105,-31v0,-58,52,-49,104,-49v1,-39,3,-66,-42,-66v-17,0,-35,2,-52,6r-3,-18v14,-4,36,-7,54,-7xm127,-33r0,-42v-35,3,-89,-12,-83,30v-3,47,59,30,83,12","w":174},"b":{"d":"109,-179v63,-2,45,64,50,121v6,62,-70,71,-128,55r0,-244r20,-3r0,84v15,-7,34,-13,58,-13xm51,-144r0,125v41,9,94,5,88,-39v-6,-41,17,-101,-33,-101v-21,0,-38,6,-55,15","w":182},"c":{"d":"86,-160v-60,0,-42,55,-45,104v-3,46,42,45,82,37r3,18v-53,15,-106,-2,-106,-56v0,-66,-10,-125,66,-122v12,0,28,2,40,5r-3,17v-14,-2,-27,-3,-37,-3","w":144},"d":{"d":"75,4v-66,0,-46,-71,-50,-129v-4,-54,58,-62,108,-48r0,-74r21,-3r0,250r-19,0r-1,-17v-18,14,-40,21,-59,21xm133,-37r0,-117v-37,-6,-92,-19,-87,29v4,42,-20,111,30,110v22,0,41,-9,57,-22","w":184},"e":{"d":"42,-81v-2,41,1,68,46,66v18,0,38,-3,56,-8r3,17v-16,6,-39,10,-60,10v-73,1,-66,-54,-65,-119v0,-36,16,-64,65,-64v63,1,66,41,64,98r-109,0xm87,-161v-39,0,-47,23,-45,61r88,0v2,-37,-3,-61,-43,-61","w":172},"f":{"d":"127,-249r-3,16v-27,-4,-58,-10,-58,23r0,35r54,0r-2,18r-52,0r0,157r-21,0r0,-157r-32,0r0,-18r32,0v-3,-44,2,-82,46,-79v10,0,25,2,36,5","w":128},"g":{"d":"143,27v3,-51,-110,-5,-110,-60v0,-9,4,-20,16,-30v-44,-28,-36,-126,42,-116v26,3,48,6,77,4r0,15r-21,2v31,51,-2,124,-80,102v-14,12,-22,33,2,36v40,4,100,1,94,46v10,57,-85,55,-136,40r3,-17v33,10,125,16,113,-22xm138,-114v1,-34,-10,-47,-47,-47v-37,0,-48,13,-47,47v0,33,15,42,47,42v32,0,47,-11,47,-42","w":184},"h":{"d":"159,0r-21,0r0,-142v0,-13,-7,-17,-19,-17v-15,0,-46,8,-68,20r0,139r-20,0r0,-247r20,-3r0,90v34,-17,108,-38,108,21r0,139","w":187},"i":{"d":"51,0r-20,0r0,-175r20,0r0,175xm51,-208r-20,0r0,-39r20,0r0,39","w":82},"j":{"d":"31,-175r20,0r0,188v0,26,-5,29,-40,62r-14,-16v30,-26,34,-28,34,-50r0,-184xm51,-208r-20,0r0,-39r20,0r0,39","w":80},"k":{"d":"51,0r-20,0r0,-247r20,-3r0,250xm130,-175r26,0r-70,86r73,89r-27,0r-71,-89","w":169},"l":{"d":"51,0r-20,0r0,-247r20,-3r0,250","w":82},"m":{"d":"266,0r-21,0r0,-142v0,-13,-7,-17,-19,-17v-16,0,-45,8,-67,20r0,139r-21,0r0,-142v0,-13,-7,-17,-19,-17v-15,0,-46,8,-68,20r0,139r-20,0r0,-175r18,0r1,16v29,-13,90,-37,106,0v35,-18,110,-40,110,20r0,139","w":294},"n":{"d":"159,0r-21,0r0,-142v0,-13,-7,-17,-19,-17v-15,0,-46,8,-68,20r0,139r-20,0r0,-175r18,0r1,16v33,-18,109,-40,109,20r0,139","w":187},"o":{"d":"158,-115v0,66,5,119,-68,119v-74,-1,-70,-53,-68,-119v0,-36,18,-64,68,-64v49,0,68,28,68,64xm90,-15v56,0,47,-51,47,-101v0,-29,-15,-44,-47,-44v-57,0,-48,50,-48,101v0,29,15,44,48,44","w":179},"p":{"d":"110,-179v65,0,45,72,49,129v4,54,-57,62,-108,48r0,73r-20,3r0,-249r19,0r1,16v17,-13,39,-20,59,-20xm51,-138r0,117v38,7,92,17,88,-29v-4,-42,21,-112,-31,-110v-21,0,-40,9,-57,22","w":183},"q":{"d":"74,4v-62,2,-46,-64,-51,-121v-5,-62,71,-71,129,-55r0,243r-21,3r0,-84v-14,8,-33,14,-57,14xm131,-32r0,-124v-39,-10,-94,-4,-87,38v7,41,-17,101,33,101v21,0,38,-5,54,-15","w":182},"r":{"d":"104,-179r3,21v-18,8,-39,21,-56,32r0,126r-20,0r0,-175r18,0r1,26v19,-12,38,-24,54,-30","w":112},"s":{"d":"135,-44v12,51,-71,56,-110,39r4,-17v30,8,85,19,85,-22v0,-25,-1,-27,-41,-37v-43,-10,-47,-21,-47,-53v0,-48,65,-52,107,-39r-2,18v-28,-5,-92,-15,-84,22v0,24,1,26,34,35v51,13,54,21,54,54","w":156},"t":{"d":"117,-19r4,16v-30,11,-76,14,-76,-31r0,-123r-34,0r0,-18r34,0r0,-42r21,-3r0,45r53,0r-2,18r-51,0r0,121v-5,29,31,23,51,17","w":133},"u":{"d":"29,-175r21,0r0,142v0,12,7,17,19,17v14,0,45,-8,67,-20r0,-139r21,0r0,175r-18,0r-2,-16v-33,18,-108,40,-108,-20r0,-139","w":187},"v":{"d":"156,-175r-59,175r-32,0r-60,-175r22,0r54,160r54,-160r21,0","w":161},"w":{"d":"80,0r-31,0r-40,-175r20,0r36,161r47,-161r28,0r48,161r36,-161r20,0r-40,175r-32,0r-46,-160","w":252},"x":{"d":"32,0r-23,0r59,-88r-58,-87r22,0r47,70r47,-70r23,0r-59,87r60,88r-23,0r-48,-72","w":158},"y":{"d":"156,-175r-85,246r-21,0r27,-71r-12,0r-60,-175r22,0r54,160r54,-160r21,0","w":159},"z":{"d":"22,-158r1,-17r113,0r0,17r-94,141r97,0r0,17r-119,0r0,-17r94,-141r-92,0","w":157},"{":{"d":"22,-126v14,1,22,-2,21,-15v8,-61,-32,-160,61,-143r0,18v-18,1,-40,-5,-40,15r0,109v0,13,-5,25,-23,25v18,1,23,13,23,26r0,109v-1,20,23,13,40,14r0,19v-34,2,-61,-2,-61,-36r0,-108v1,-12,-8,-15,-21,-14r0,-19","w":111},"|":{"d":"52,-284r0,360r-14,0r0,-360r14,0","w":89},"}":{"d":"68,-141v-1,13,8,16,22,15r0,19v-14,-1,-23,2,-22,14v-8,61,32,161,-61,144r0,-19v17,-1,40,6,40,-14r0,-109v0,-13,5,-25,23,-26v-18,0,-23,-12,-23,-25r0,-109v1,-20,-22,-14,-40,-15r0,-18v34,-2,61,2,61,35r0,108","w":111},"~":{"d":"149,-123r15,6v-7,21,-18,41,-44,41v-26,0,-39,-28,-58,-28v-15,0,-21,11,-29,30r-15,-7v9,-24,22,-40,44,-40v27,0,39,28,59,28v16,0,22,-15,28,-30","w":178},"\u00a0":{"w":79}}});