(function(win) {
	var whiteSpaceRe = /^\s*|\s*$/g,
		undefined;
	var tinymce = {
		majorVersion : '3',
		minorVersion : '3.7',
		releaseDate : '2010-06-10',
		_init : function() {
			var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
			t.isOpera = win.opera && opera.buildNumber;
			t.isWebKit = /WebKit/.test(ua);
			t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);
			t.isIE6 = t.isIE && /MSIE [56]/.test(ua);
			t.isGecko = !t.isWebKit && /Gecko/.test(ua);
			t.isMac = ua.indexOf('Mac') != -1;
			t.isAir = /adobeair/i.test(ua);
			t.isIDevice = /(iPad|iPhone)/.test(ua);
			// TinyMCE .NET webcontrol might be setting the values for TinyMCE
			if (win.tinyMCEPreInit) {
				t.suffix = tinyMCEPreInit.suffix;
				t.baseURL = tinyMCEPreInit.base;
				t.query = tinyMCEPreInit.query;
				return;
			}
			// Get suffix and base
			t.suffix = '';
			// If base element found, add that infront of baseURL
			nl = d.getElementsByTagName('base');
			for (i=0; i :
			s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);
			cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name
			// Create namespace for new class
			ns = t.createNS(s[3].replace(/\.\w+$/, ''));
			// Class already exists
			if (ns[cn])
				return;
			// Make pure static class
			if (s[2] == 'static') {
				ns[cn] = p;
				if (this.onCreate)
					this.onCreate(s[2], s[3], ns[cn]);
				return;
			}
			// Create default constructor
			if (!p[cn]) {
				p[cn] = function() {};
				de = 1;
			}
			// Add constructor and methods
			ns[cn] = p[cn];
			t.extend(ns[cn].prototype, p);
			// Extend
			if (s[5]) {
				sp = t.resolve(s[5]).prototype;
				scn = s[5].match(/\.(\w+)$/i)[1]; // Class name
				// Extend constructor
				c = ns[cn];
				if (de) {
					// Add passthrough constructor
					ns[cn] = function() {
						return sp[scn].apply(this, arguments);
					};
				} else {
					// Add inherit constructor
					ns[cn] = function() {
						this.parent = sp[scn];
						return c.apply(this, arguments);
					};
				}
				ns[cn].prototype[cn] = ns[cn];
				// Add super methods
				t.each(sp, function(f, n) {
					ns[cn].prototype[n] = sp[n];
				});
				// Add overridden methods
				t.each(p, function(f, n) {
					// Extend methods if needed
					if (sp[n]) {
						ns[cn].prototype[n] = function() {
							this.parent = sp[n];
							return f.apply(this, arguments);
						};
					} else {
						if (n != cn)
							ns[cn].prototype[n] = f;
					}
				});
			}
			// Add static methods
			t.each(p['static'], function(f, n) {
				ns[cn][n] = f;
			});
			if (this.onCreate)
				this.onCreate(s[2], s[3], ns[cn].prototype);
		},
		walk : function(o, f, n, s) {
			s = s || this;
			if (o) {
				if (n)
					o = o[n];
				tinymce.each(o, function(o, i) {
					if (f.call(s, o, i, n) === false)
						return false;
					tinymce.walk(o, f, n, s);
				});
			}
		},
		createNS : function(n, o) {
			var i, v;
			o = o || win;
			n = n.split('.');
			for (i=0; i= items.length) {
				for (i = 0, l = base.length; i < l; i++) {
					if (i >= items.length || base[i] != items[i]) {
						bp = i + 1;
						break;
					}
				}
			}
			if (base.length < items.length) {
				for (i = 0, l = items.length; i < l; i++) {
					if (i >= base.length || base[i] != items[i]) {
						bp = i + 1;
						break;
					}
				}
			}
			if (bp == 1)
				return path;
			for (i = 0, l = base.length - (bp - 1); i < l; i++)
				out += "../";
			for (i = bp - 1, l = items.length; i < l; i++) {
				if (i != bp - 1)
					out += "/" + items[i];
				else
					out += items[i];
			}
			return out;
		},
		toAbsPath : function(base, path) {
			var i, nb = 0, o = [], tr, outPath;
			// Split paths
			tr = /\/$/.test(path) ? '/' : '';
			base = base.split('/');
			path = path.split('/');
			// Remove empty chunks
			each(base, function(k) {
				if (k)
					o.push(k);
			});
			base = o;
			// Merge relURLParts chunks
			for (i = path.length - 1, o = []; i >= 0; i--) {
				// Ignore empty or .
				if (path[i].length == 0 || path[i] == ".")
					continue;
				// Is parent
				if (path[i] == '..') {
					nb++;
					continue;
				}
				// Move up
				if (nb > 0) {
					nb--;
					continue;
				}
				o.push(path[i]);
			}
			i = base.length - nb;
			// If /a/b/c or /
			if (i <= 0)
				outPath = o.reverse().join('/');
			else
				outPath = base.slice(0, i).join('/') + '/' + o.reverse().join('/');
			// Add front / if it's needed
			if (outPath.indexOf('/') !== 0)
				outPath = '/' + outPath;
			// Add traling / if it's needed
			if (tr && outPath.lastIndexOf('/') !== outPath.length - 1)
				outPath += tr;
			return outPath;
		},
		getURI : function(nh) {
			var s, t = this;
			// Rebuild source
			if (!t.source || nh) {
				s = '';
				if (!nh) {
					if (t.protocol)
						s += t.protocol + '://';
					if (t.userInfo)
						s += t.userInfo + '@';
					if (t.host)
						s += t.host;
					if (t.port)
						s += ':' + t.port;
				}
				if (t.path)
					s += t.path;
				if (t.query)
					s += '?' + t.query;
				if (t.anchor)
					s += '#' + t.anchor;
				t.source = s;
			}
			return t.source;
		}
	});
})();
(function() {
	var each = tinymce.each;
	tinymce.create('static tinymce.util.Cookie', {
		getHash : function(n) {
			var v = this.get(n), h;
			if (v) {
				each(v.split('&'), function(v) {
					v = v.split('=');
					h = h || {};
					h[unescape(v[0])] = unescape(v[1]);
				});
			}
			return h;
		},
		setHash : function(n, v, e, p, d, s) {
			var o = '';
			each(v, function(v, k) {
				o += (!o ? '' : '&') + escape(k) + '=' + escape(v);
			});
			this.set(n, o, e, p, d, s);
		},
		get : function(n) {
			var c = document.cookie, e, p = n + "=", b;
			// Strict mode
			if (!c)
				return;
			b = c.indexOf("; " + p);
			if (b == -1) {
				b = c.indexOf(p);
				if (b != 0)
					return null;
			} else
				b += 2;
			e = c.indexOf(";", b);
			if (e == -1)
				e = c.length;
			return unescape(c.substring(b + p.length, e));
		},
		set : function(n, v, e, p, d, s) {
			document.cookie = n + "=" + escape(v) +
				((e) ? "; expires=" + e.toGMTString() : "") +
				((p) ? "; path=" + escape(p) : "") +
				((d) ? "; domain=" + d : "") +
				((s) ? "; secure" : "");
		},
		remove : function(n, p) {
			var d = new Date();
			d.setTime(d.getTime() - 1000);
			this.set(n, '', d, p, d);
		}
	});
})();
tinymce.create('static tinymce.util.JSON', {
	serialize : function(o) {
		var i, v, s = tinymce.util.JSON.serialize, t;
		if (o == null)
			return 'null';
		t = typeof o;
		if (t == 'string') {
			v = '\bb\tt\nn\ff\rr\""\'\'\\\\';
			return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g, function(a, b) {
				i = v.indexOf(b);
				if (i + 1)
					return '\\' + v.charAt(i + 1);
				a = b.charCodeAt().toString(16);
				return '\\u' + '0000'.substring(a.length) + a;
			}) + '"';
		}
		if (t == 'object') {
			if (o.hasOwnProperty && o instanceof Array) {
					for (i=0, v = '['; i 0 ? ',' : '') + s(o[i]);
					return v + ']';
				}
				v = '{';
				for (i in o)
					v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : '';
				return v + '}';
		}
		return '' + o;
	},
	parse : function(s) {
		try {
			return eval('(' + s + ')');
		} catch (ex) {
			// Ignore
		}
	}
	});
tinymce.create('static tinymce.util.XHR', {
	send : function(o) {
		var x, t, w = window, c = 0;
		// Default settings
		o.scope = o.scope || this;
		o.success_scope = o.success_scope || o.scope;
		o.error_scope = o.error_scope || o.scope;
		o.async = o.async === false ? false : true;
		o.data = o.data || '';
		function get(s) {
			x = 0;
			try {
				x = new ActiveXObject(s);
			} catch (ex) {
			}
			return x;
		};
		x = w.XMLHttpRequest ? new XMLHttpRequest() : get('Microsoft.XMLHTTP') || get('Msxml2.XMLHTTP');
		if (x) {
			if (x.overrideMimeType)
				x.overrideMimeType(o.content_type);
			x.open(o.type || (o.data ? 'POST' : 'GET'), o.url, o.async);
			if (o.content_type)
				x.setRequestHeader('Content-Type', o.content_type);
			x.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
			x.send(o.data);
			function ready() {
				if (!o.async || x.readyState == 4 || c++ > 10000) {
					if (o.success && c < 10000 && x.status == 200)
						o.success.call(o.success_scope, '' + x.responseText, x, o);
					else if (o.error)
						o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);
					x = null;
				} else
					w.setTimeout(ready, 10);
			};
			// Syncronous request
			if (!o.async)
				return ready();
			// Wait for response, onReadyStateChange can not be used since it leaks memory in IE
			t = w.setTimeout(ready, 10);
		}
	}
});
(function() {
	var extend = tinymce.extend, JSON = tinymce.util.JSON, XHR = tinymce.util.XHR;
	tinymce.create('tinymce.util.JSONRequest', {
		JSONRequest : function(s) {
			this.settings = extend({
			}, s);
			this.count = 0;
		},
		send : function(o) {
			var ecb = o.error, scb = o.success;
			o = extend(this.settings, o);
			o.success = function(c, x) {
				c = JSON.parse(c);
				if (typeof(c) == 'undefined') {
					c = {
						error : 'JSON Parse error.'
					};
				}
				if (c.error)
					ecb.call(o.error_scope || o.scope, c.error, x);
				else
					scb.call(o.success_scope || o.scope, c.result);
			};
			o.error = function(ty, x) {
				ecb.call(o.error_scope || o.scope, ty, x);
			};
			o.data = JSON.serialize({
				id : o.id || 'c' + (this.count++),
				method : o.method,
				params : o.params
			});
			// JSON content type for Ruby on rails. Bug: #1883287
			o.content_type = 'application/json';
			XHR.send(o);
		},
		'static' : {
			sendRPC : function(o) {
				return new tinymce.util.JSONRequest().send(o);
			}
		}
	});
}());
(function(tinymce) {
	// Shorten names
	var each = tinymce.each,
		is = tinymce.is,
		isWebKit = tinymce.isWebKit,
		isIE = tinymce.isIE,
		blockRe = /^(H[1-6R]|P|DIV|ADDRESS|PRE|FORM|T(ABLE|BODY|HEAD|FOOT|H|R|D)|LI|OL|UL|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|MENU|ISINDEX|SAMP)$/,
		boolAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'),
		mceAttribs = makeMap('src,href,style,coords,shape'),
		encodedChars = {'&' : '&', '"' : '"', '<' : '<', '>' : '>'},
		encodeCharsRe = /[<>&\"]/g,
		simpleSelectorRe = /^([a-z0-9],?)+$/i,
		tagRegExp = /<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)(\s*\/?)>/g,
		attrRegExp = /(\w+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
	function makeMap(str) {
		var map = {}, i;
		str = str.split(',');
		for (i = str.length; i >= 0; i--)
			map[str[i]] = 1;
		return map;
	};
	tinymce.create('tinymce.dom.DOMUtils', {
		doc : null,
		root : null,
		files : null,
		pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/,
		props : {
			"for" : "htmlFor",
			"class" : "className",
			className : "className",
			checked : "checked",
			disabled : "disabled",
			maxlength : "maxLength",
			readonly : "readOnly",
			selected : "selected",
			value : "value",
			id : "id",
			name : "name",
			type : "type"
		},
		DOMUtils : function(d, s) {
			var t = this, globalStyle;
			t.doc = d;
			t.win = window;
			t.files = {};
			t.cssFlicker = false;
			t.counter = 0;
			t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; 
			t.stdMode = d.documentMode === 8;
			t.settings = s = tinymce.extend({
				keep_values : false,
				hex_colors : 1,
				process_html : 1
			}, s);
			// Fix IE6SP2 flicker and check it failed for pre SP2
			if (tinymce.isIE6) {
				try {
					d.execCommand('BackgroundImageCache', false, true);
				} catch (e) {
					t.cssFlicker = true;
				}
			}
			// Build styles list
			if (s.valid_styles) {
				t._styles = {};
				// Convert styles into a rule list
				each(s.valid_styles, function(value, key) {
					t._styles[key] = tinymce.explode(value);
				});
			}
			tinymce.addUnload(t.destroy, t);
		},
		getRoot : function() {
			var t = this, s = t.settings;
			return (s && t.get(s.root_element)) || t.doc.body;
		},
		getViewPort : function(w) {
			var d, b;
			w = !w ? this.win : w;
			d = w.document;
			b = this.boxModel ? d.documentElement : d.body;
			// Returns viewport size excluding scrollbars
			return {
				x : w.pageXOffset || b.scrollLeft,
				y : w.pageYOffset || b.scrollTop,
				w : w.innerWidth || b.clientWidth,
				h : w.innerHeight || b.clientHeight
			};
		},
		getRect : function(e) {
			var p, t = this, sr;
			e = t.get(e);
			p = t.getPos(e);
			sr = t.getSize(e);
			return {
				x : p.x,
				y : p.y,
				w : sr.w,
				h : sr.h
			};
		},
		getSize : function(e) {
			var t = this, w, h;
			e = t.get(e);
			w = t.getStyle(e, 'width');
			h = t.getStyle(e, 'height');
			// Non pixel value, then force offset/clientWidth
			if (w.indexOf('px') === -1)
				w = 0;
			// Non pixel value, then force offset/clientWidth
			if (h.indexOf('px') === -1)
				h = 0;
			return {
				w : parseInt(w) || e.offsetWidth || e.clientWidth,
				h : parseInt(h) || e.offsetHeight || e.clientHeight
			};
		},
		getParent : function(n, f, r) {
			return this.getParents(n, f, r, false);
		},
		getParents : function(n, f, r, c) {
			var t = this, na, se = t.settings, o = [];
			n = t.get(n);
			c = c === undefined;
			if (se.strict_root)
				r = r || t.getRoot();
			// Wrap node name as func
			if (is(f, 'string')) {
				na = f;
				if (f === '*') {
					f = function(n) {return n.nodeType == 1;};
				} else {
					f = function(n) {
						return t.is(n, na);
					};
				}
			}
			while (n) {
				if (n == r || !n.nodeType || n.nodeType === 9)
					break;
				if (!f || f(n)) {
					if (c)
						o.push(n);
					else
						return n;
				}
				n = n.parentNode;
			}
			return c ? o : null;
		},
		get : function(e) {
			var n;
			if (e && this.doc && typeof(e) == 'string') {
				n = e;
				e = this.doc.getElementById(e);
				// IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick
				if (e && e.id !== n)
					return this.doc.getElementsByName(n)[1];
			}
			return e;
		},
		getNext : function(node, selector) {
			return this._findSib(node, selector, 'nextSibling');
		},
		getPrev : function(node, selector) {
			return this._findSib(node, selector, 'previousSibling');
		},
		select : function(pa, s) {
			var t = this;
			return tinymce.dom.Sizzle(pa, t.get(s) || t.get(t.settings.root_element) || t.doc, []);
		},
		is : function(n, selector) {
			var i;
			// If it isn't an array then try to do some simple selectors instead of Sizzle for to boost performance
			if (n.length === undefined) {
				// Simple all selector
				if (selector === '*')
					return n.nodeType == 1;
				// Simple selector just elements
				if (simpleSelectorRe.test(selector)) {
					selector = selector.toLowerCase().split(/,/);
					n = n.nodeName.toLowerCase();
					for (i = selector.length - 1; i >= 0; i--) {
						if (selector[i] == n)
							return true;
					}
					return false;
				}
			}
			return tinymce.dom.Sizzle.matches(selector, n.nodeType ? [n] : n).length > 0;
		},
		add : function(p, n, a, h, c) {
			var t = this;
			return this.run(p, function(p) {
				var e, k;
				e = is(n, 'string') ? t.doc.createElement(n) : n;
				t.setAttribs(e, a);
				if (h) {
					if (h.nodeType)
						e.appendChild(h);
					else
						t.setHTML(e, h);
				}
				return !c ? p.appendChild(e) : e;
			});
		},
		create : function(n, a, h) {
			return this.add(this.doc.createElement(n), n, a, h, 1);
		},
		createHTML : function(n, a, h) {
			var o = '', t = this, k;
			o += '<' + n;
			for (k in a) {
				if (a.hasOwnProperty(k))
					o += ' ' + k + '="' + t.encode(a[k]) + '"';
			}
			if (tinymce.is(h))
				return o + '>' + h + '' + n + '>';
			return o + ' />';
		},
		remove : function(node, keep_children) {
			return this.run(node, function(node) {
				var parent, child;
				parent = node.parentNode;
				if (!parent)
					return null;
				if (keep_children) {
					while (child = node.firstChild) {
						// IE 8 will crash if you don't remove completely empty text nodes
						if (!tinymce.isIE || child.nodeType !== 3 || child.nodeValue)
							parent.insertBefore(child, node);
						else
							node.removeChild(child);
					}
				}
				return parent.removeChild(node);
			});
		},
		setStyle : function(n, na, v) {
			var t = this;
			return t.run(n, function(e) {
				var s, i;
				s = e.style;
				// Camelcase it, if needed
				na = na.replace(/-(\D)/g, function(a, b){
					return b.toUpperCase();
				});
				// Default px suffix on these
				if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v)))
					v += 'px';
				switch (na) {
					case 'opacity':
						// IE specific opacity
						if (isIE) {
							s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")";
							if (!n.currentStyle || !n.currentStyle.hasLayout)
								s.display = 'inline-block';
						}
						// Fix for older browsers
						s[na] = s['-moz-opacity'] = s['-khtml-opacity'] = v || '';
						break;
					case 'float':
						isIE ? s.styleFloat = v : s.cssFloat = v;
						break;
					
					default:
						s[na] = v || '';
				}
				// Force update of the style data
				if (t.settings.update_styles)
					t.setAttrib(e, '_mce_style');
			});
		},
		getStyle : function(n, na, c) {
			n = this.get(n);
			if (!n)
				return false;
			// Gecko
			if (this.doc.defaultView && c) {
				// Remove camelcase
				na = na.replace(/[A-Z]/g, function(a){
					return '-' + a;
				});
				try {
					return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na);
				} catch (ex) {
					// Old safari might fail
					return null;
				}
			}
			// Camelcase it, if needed
			na = na.replace(/-(\D)/g, function(a, b){
				return b.toUpperCase();
			});
			if (na == 'float')
				na = isIE ? 'styleFloat' : 'cssFloat';
			// IE & Opera
			if (n.currentStyle && c)
				return n.currentStyle[na];
			return n.style[na];
		},
		setStyles : function(e, o) {
			var t = this, s = t.settings, ol;
			ol = s.update_styles;
			s.update_styles = 0;
			each(o, function(v, n) {
				t.setStyle(e, n, v);
			});
			// Update style info
			s.update_styles = ol;
			if (s.update_styles)
				t.setAttrib(e, s.cssText);
		},
		setAttrib : function(e, n, v) {
			var t = this;
			// Whats the point
			if (!e || !n)
				return;
			// Strict XML mode
			if (t.settings.strict)
				n = n.toLowerCase();
			return this.run(e, function(e) {
				var s = t.settings;
				switch (n) {
					case "style":
						if (!is(v, 'string')) {
							each(v, function(v, n) {
								t.setStyle(e, n, v);
							});
							return;
						}
						// No mce_style for elements with these since they might get resized by the user
						if (s.keep_values) {
							if (v && !t._isRes(v))
								e.setAttribute('_mce_style', v, 2);
							else
								e.removeAttribute('_mce_style', 2);
						}
						e.style.cssText = v;
						break;
					case "class":
						e.className = v || ''; // Fix IE null bug
						break;
					case "src":
					case "href":
						if (s.keep_values) {
							if (s.url_converter)
								v = s.url_converter.call(s.url_converter_scope || t, v, n, e);
							t.setAttrib(e, '_mce_' + n, v, 2);
						}
						break;
					
					case "shape":
						e.setAttribute('_mce_style', v);
						break;
				}
				if (is(v) && v !== null && v.length !== 0)
					e.setAttribute(n, '' + v, 2);
				else
					e.removeAttribute(n, 2);
			});
		},
		setAttribs : function(e, o) {
			var t = this;
			return this.run(e, function(e) {
				each(o, function(v, n) {
					t.setAttrib(e, n, v);
				});
			});
		},
		getAttrib : function(e, n, dv) {
			var v, t = this;
			e = t.get(e);
			if (!e || e.nodeType !== 1)
				return false;
			if (!is(dv))
				dv = '';
			// Try the mce variant for these
			if (/^(src|href|style|coords|shape)$/.test(n)) {
				v = e.getAttribute("_mce_" + n);
				if (v)
					return v;
			}
			if (isIE && t.props[n]) {
				v = e[t.props[n]];
				v = v && v.nodeValue ? v.nodeValue : v;
			}
			if (!v)
				v = e.getAttribute(n, 2);
			// Check boolean attribs
			if (/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(n)) {
				if (e[t.props[n]] === true && v === '')
					return n;
				return v ? n : '';
			}
			// Inner input elements will override attributes on form elements
			if (e.nodeName === "FORM" && e.getAttributeNode(n))
				return e.getAttributeNode(n).nodeValue;
			if (n === 'style') {
				v = v || e.style.cssText;
				if (v) {
					v = t.serializeStyle(t.parseStyle(v), e.nodeName);
					if (t.settings.keep_values && !t._isRes(v))
						e.setAttribute('_mce_style', v);
				}
			}
			// Remove Apple and WebKit stuff
			if (isWebKit && n === "class" && v)
				v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, '');
			// Handle IE issues
			if (isIE) {
				switch (n) {
					case 'rowspan':
					case 'colspan':
						// IE returns 1 as default value
						if (v === 1)
							v = '';
						break;
					case 'size':
						// IE returns +0 as default value for size
						if (v === '+0' || v === 20 || v === 0)
							v = '';
						break;
					case 'width':
					case 'height':
					case 'vspace':
					case 'checked':
					case 'disabled':
					case 'readonly':
						if (v === 0)
							v = '';
						break;
					case 'hspace':
						// IE returns -1 as default value
						if (v === -1)
							v = '';
						break;
					case 'maxlength':
					case 'tabindex':
						// IE returns default value
						if (v === 32768 || v === 2147483647 || v === '32768')
							v = '';
						break;
					case 'multiple':
					case 'compact':
					case 'noshade':
					case 'nowrap':
						if (v === 65535)
							return n;
						return dv;
					case 'shape':
						v = v.toLowerCase();
						break;
					default:
						// IE has odd anonymous function for event attributes
						if (n.indexOf('on') === 0 && v)
							v = ('' + v).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/, '$1');
				}
			}
			return (v !== undefined && v !== null && v !== '') ? '' + v : dv;
		},
		getPos : function(n, ro) {
			var t = this, x = 0, y = 0, e, d = t.doc, r;
			n = t.get(n);
			ro = ro || d.body;
			if (n) {
				// Use getBoundingClientRect on IE, Opera has it but it's not perfect
				if (isIE && !t.stdMode) {
					n = n.getBoundingClientRect();
					e = t.boxModel ? d.documentElement : d.body;
					x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border
					x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x;
					n.top += t.win.self != t.win.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset
					return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};
				}
				r = n;
				while (r && r != ro && r.nodeType) {
					x += r.offsetLeft || 0;
					y += r.offsetTop || 0;
					r = r.offsetParent;
				}
				r = n.parentNode;
				while (r && r != ro && r.nodeType) {
					x -= r.scrollLeft || 0;
					y -= r.scrollTop || 0;
					r = r.parentNode;
				}
			}
			return {x : x, y : y};
		},
		parseStyle : function(st) {
			var t = this, s = t.settings, o = {};
			if (!st)
				return o;
			function compress(p, s, ot) {
				var t, r, b, l;
				// Get values and check it it needs compressing
				t = o[p + '-top' + s];
				if (!t)
					return;
				r = o[p + '-right' + s];
				if (t != r)
					return;
				b = o[p + '-bottom' + s];
				if (r != b)
					return;
				l = o[p + '-left' + s];
				if (b != l)
					return;
				// Compress
				o[ot] = l;
				delete o[p + '-top' + s];
				delete o[p + '-right' + s];
				delete o[p + '-bottom' + s];
				delete o[p + '-left' + s];
			};
			function compress2(ta, a, b, c) {
				var t;
				t = o[a];
				if (!t)
					return;
				t = o[b];
				if (!t)
					return;
				t = o[c];
				if (!t)
					return;
				// Compress
				o[ta] = o[a] + ' ' + o[b] + ' ' + o[c];
				delete o[a];
				delete o[b];
				delete o[c];
			};
			st = st.replace(/&(#?[a-z0-9]+);/g, '&$1_MCE_SEMI_'); // Protect entities
			each(st.split(';'), function(v) {
				var sv, ur = [];
				if (v) {
					v = v.replace(/_MCE_SEMI_/g, ';'); // Restore entities
					v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';});
					v = v.split(':');
					sv = tinymce.trim(v[1]);
					sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];});
					sv = sv.replace(/rgb\([^\)]+\)/g, function(v) {
						return t.toHex(v);
					});
					if (s.url_converter) {
						sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) {
							return 'url(' + s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null) + ')';
						});
					}
					o[tinymce.trim(v[0]).toLowerCase()] = sv;
				}
			});
			compress("border", "", "border");
			compress("border", "-width", "border-width");
			compress("border", "-color", "border-color");
			compress("border", "-style", "border-style");
			compress("padding", "", "padding");
			compress("margin", "", "margin");
			compress2('border', 'border-width', 'border-style', 'border-color');
			if (isIE) {
				// Remove pointless border
				if (o.border == 'medium none')
					o.border = '';
			}
			return o;
		},
		serializeStyle : function(o, name) {
			var t = this, s = '';
			function add(v, k) {
				if (k && v) {
					// Remove browser specific styles like -moz- or -webkit-
					if (k.indexOf('-') === 0)
						return;
					switch (k) {
						case 'font-weight':
							// Opera will output bold as 700
							if (v == 700)
								v = 'bold';
							break;
						case 'color':
						case 'background-color':
							v = v.toLowerCase();
							break;
					}
					s += (s ? ' ' : '') + k + ': ' + v + ';';
				}
			};
			// Validate style output
			if (name && t._styles) {
				each(t._styles['*'], function(name) {
					add(o[name], name);
				});
				each(t._styles[name.toLowerCase()], function(name) {
					add(o[name], name);
				});
			} else
				each(o, add);
			return s;
		},
		loadCSS : function(u) {
			var t = this, d = t.doc, head;
			if (!u)
				u = '';
			head = t.select('head')[0];
			each(u.split(','), function(u) {
				var link;
				if (t.files[u])
					return;
				t.files[u] = true;
				link = t.create('link', {rel : 'stylesheet', href : tinymce._addVer(u)});
				// IE 8 has a bug where dynamically loading stylesheets would produce a 1 item remaining bug
				// This fix seems to resolve that issue by realcing the document ones a stylesheet finishes loading
				// It's ugly but it seems to work fine.
				if (isIE && d.documentMode) {
					link.onload = function() {
						d.recalc();
						link.onload = null;
					};
				}
				head.appendChild(link);
			});
		},
		addClass : function(e, c) {
			return this.run(e, function(e) {
				var o;
				if (!c)
					return 0;
				if (this.hasClass(e, c))
					return e.className;
				o = this.removeClass(e, c);
				return e.className = (o != '' ? (o + ' ') : '') + c;
			});
		},
		removeClass : function(e, c) {
			var t = this, re;
			return t.run(e, function(e) {
				var v;
				if (t.hasClass(e, c)) {
					if (!re)
						re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g");
					v = e.className.replace(re, ' ');
					v = tinymce.trim(v != ' ' ? v : '');
					e.className = v;
					// Empty class attr
					if (!v) {
						e.removeAttribute('class');
						e.removeAttribute('className');
					}
					return v;
				}
				return e.className;
			});
		},
		hasClass : function(n, c) {
			n = this.get(n);
			if (!n || !c)
				return false;
			return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1;
		},
		show : function(e) {
			return this.setStyle(e, 'display', 'block');
		},
		hide : function(e) {
			return this.setStyle(e, 'display', 'none');
		},
		isHidden : function(e) {
			e = this.get(e);
			return !e || e.style.display == 'none' || this.getStyle(e, 'display') == 'none';
		},
		uniqueId : function(p) {
			return (!p ? 'mce_' : p) + (this.counter++);
		},
		setHTML : function(e, h) {
			var t = this;
			return this.run(e, function(e) {
				var x, i, nl, n, p, x;
				h = t.processHTML(h);
				if (isIE) {
					function set() {
						// Remove all child nodes
						while (e.firstChild)
							e.firstChild.removeNode();
						try {
							// IE will remove comments from the beginning
							// unless you padd the contents with something
							e.innerHTML = '
' + h;
							e.removeChild(e.firstChild);
						} catch (ex) {
							// IE sometimes produces an unknown runtime error on innerHTML if it's an block element within a block element for example a div inside a p
							// This seems to fix this problem
							// Create new div with HTML contents and a BR infront to keep comments
							x = t.create('div');
							x.innerHTML = '
' + h;
							// Add all children from div to target
							each (x.childNodes, function(n, i) {
								// Skip br element
								if (i)
									e.appendChild(n);
							});
						}
					};
					// IE has a serious bug when it comes to paragraphs it can produce an invalid
					// DOM tree if contents like this 
 is inserted
					// It seems to be that IE doesn't like a root block element placed inside another root block element
					if (t.settings.fix_ie_paragraphs)
						h = h.replace(/<\/p>|
]+)><\/p>|
/gi, ' 
');
					set();
					if (t.settings.fix_ie_paragraphs) {
						// Check for odd paragraphs this is a sign of a broken DOM
						nl = e.getElementsByTagName("p");
						for (i = nl.length - 1, x = 0; i >= 0; i--) {
							n = nl[i];
							if (!n.hasChildNodes()) {
								if (!n._mce_keep) {
									x = 1; // Is broken
									break;
								}
								n.removeAttribute('_mce_keep');
							}
						}
					}
					// Time to fix the madness IE left us
					if (x) {
						// So if we replace the p elements with divs and mark them and then replace them back to paragraphs
						// after we use innerHTML we can fix the DOM tree
						h = h.replace(/]+)>|
/ig, '
');
						h = h.replace(/<\/p>/gi, '
');
						// Set the new HTML with DIVs
						set();
						// Replace all DIV elements with the _mce_tmp attibute back to paragraphs
						// This is needed since IE has a annoying bug see above for details
						// This is a slow process but it has to be done. :(
						if (t.settings.fix_ie_paragraphs) {
							nl = e.getElementsByTagName("DIV");
							for (i = nl.length - 1; i >= 0; i--) {
								n = nl[i];
								// Is it a temp div
								if (n._mce_tmp) {
									// Create new paragraph
									p = t.doc.createElement('p');
									// Copy all attributes
									n.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi, function(a, b) {
										var v;
										if (b !== '_mce_tmp') {
											v = n.getAttribute(b);
											if (!v && b === 'class')
												v = n.className;
											p.setAttribute(b, v);
										}
									});
									// Append all children to new paragraph
									for (x = 0; x]+)\/>|/gi, ''); // Force open
			// Store away src and href in _mce_src and mce_href since browsers mess them up
			if (s.keep_values) {
				// Wrap scripts and styles in comments for serialization purposes
				if (/';
			bi = s.body_id || 'tinymce';
			if (bi.indexOf('=') != -1) {
				bi = t.getParam('body_id', '', 'hash');
				bi = bi[t.id] || bi;
			}
			bc = s.body_class || '';
			if (bc.indexOf('=') != -1) {
				bc = t.getParam('body_class', '', 'hash');
				bc = bc[t.id] || '';
			}
			t.iframeHTML += '