| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852 | /** * jscolor - JavaScript Color Picker * * @link    http://jscolor.com * @license For open source use: GPLv3 *          For commercial use: JSColor Commercial License * @author  Jan Odvarko * @version 2.0.4 * * See usage examples at http://jscolor.com/examples/ */"use strict";if (!window.jscolor) { window.jscolor = (function () {var jsc = {	register : function () {		jsc.attachDOMReadyEvent(jsc.init);		jsc.attachEvent(document, 'mousedown', jsc.onDocumentMouseDown);		jsc.attachEvent(document, 'touchstart', jsc.onDocumentTouchStart);		jsc.attachEvent(window, 'resize', jsc.onWindowResize);	},	init : function () {		if (jsc.jscolor.lookupClass) {			jsc.jscolor.installByClassName(jsc.jscolor.lookupClass);		}	},	tryInstallOnElements : function (elms, className) {		var matchClass = new RegExp('(^|\\s)(' + className + ')(\\s*(\\{[^}]*\\})|\\s|$)', 'i');		for (var i = 0; i < elms.length; i += 1) {			if (elms[i].type !== undefined && elms[i].type.toLowerCase() == 'color') {				if (jsc.isColorAttrSupported) {					// skip inputs of type 'color' if supported by the browser					continue;				}			}			var m;			if (!elms[i].jscolor && elms[i].className && (m = elms[i].className.match(matchClass))) {				var targetElm = elms[i];				var optsStr = null;				var dataOptions = jsc.getDataAttr(targetElm, 'jscolor');				if (dataOptions !== null) {					optsStr = dataOptions;				} else if (m[4]) {					optsStr = m[4];				}				var opts = {};				if (optsStr) {					try {						opts = (new Function ('return (' + optsStr + ')'))();					} catch(eParseError) {						jsc.warn('Error parsing jscolor options: ' + eParseError + ':\n' + optsStr);					}				}				targetElm.jscolor = new jsc.jscolor(targetElm, opts);			}		}	},	isColorAttrSupported : (function () {		var elm = document.createElement('input');		if (elm.setAttribute) {			elm.setAttribute('type', 'color');			if (elm.type.toLowerCase() == 'color') {				return true;			}		}		return false;	})(),	isCanvasSupported : (function () {		var elm = document.createElement('canvas');		return !!(elm.getContext && elm.getContext('2d'));	})(),	fetchElement : function (mixed) {		return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;	},	isElementType : function (elm, type) {		return elm.nodeName.toLowerCase() === type.toLowerCase();	},	getDataAttr : function (el, name) {		var attrName = 'data-' + name;		var attrValue = el.getAttribute(attrName);		if (attrValue !== null) {			return attrValue;		}		return null;	},	attachEvent : function (el, evnt, func) {		if (el.addEventListener) {			el.addEventListener(evnt, func, false);		} else if (el.attachEvent) {			el.attachEvent('on' + evnt, func);		}	},	detachEvent : function (el, evnt, func) {		if (el.removeEventListener) {			el.removeEventListener(evnt, func, false);		} else if (el.detachEvent) {			el.detachEvent('on' + evnt, func);		}	},	_attachedGroupEvents : {},	attachGroupEvent : function (groupName, el, evnt, func) {		if (!jsc._attachedGroupEvents.hasOwnProperty(groupName)) {			jsc._attachedGroupEvents[groupName] = [];		}		jsc._attachedGroupEvents[groupName].push([el, evnt, func]);		jsc.attachEvent(el, evnt, func);	},	detachGroupEvents : function (groupName) {		if (jsc._attachedGroupEvents.hasOwnProperty(groupName)) {			for (var i = 0; i < jsc._attachedGroupEvents[groupName].length; i += 1) {				var evt = jsc._attachedGroupEvents[groupName][i];				jsc.detachEvent(evt[0], evt[1], evt[2]);			}			delete jsc._attachedGroupEvents[groupName];		}	},	attachDOMReadyEvent : function (func) {		var fired = false;		var fireOnce = function () {			if (!fired) {				fired = true;				func();			}		};		if (document.readyState === 'complete') {			setTimeout(fireOnce, 1); // async			return;		}		if (document.addEventListener) {			document.addEventListener('DOMContentLoaded', fireOnce, false);			// Fallback			window.addEventListener('load', fireOnce, false);		} else if (document.attachEvent) {			// IE			document.attachEvent('onreadystatechange', function () {				if (document.readyState === 'complete') {					document.detachEvent('onreadystatechange', arguments.callee);					fireOnce();				}			})			// Fallback			window.attachEvent('onload', fireOnce);			// IE7/8			if (document.documentElement.doScroll && window == window.top) {				var tryScroll = function () {					if (!document.body) { return; }					try {						document.documentElement.doScroll('left');						fireOnce();					} catch (e) {						setTimeout(tryScroll, 1);					}				};				tryScroll();			}		}	},	warn : function (msg) {		if (window.console && window.console.warn) {			window.console.warn(msg);		}	},	preventDefault : function (e) {		if (e.preventDefault) { e.preventDefault(); }		e.returnValue = false;	},	captureTarget : function (target) {		// IE		if (target.setCapture) {			jsc._capturedTarget = target;			jsc._capturedTarget.setCapture();		}	},	releaseTarget : function () {		// IE		if (jsc._capturedTarget) {			jsc._capturedTarget.releaseCapture();			jsc._capturedTarget = null;		}	},	fireEvent : function (el, evnt) {		if (!el) {			return;		}		if (document.createEvent) {			var ev = document.createEvent('HTMLEvents');			ev.initEvent(evnt, true, true);			el.dispatchEvent(ev);		} else if (document.createEventObject) {			var ev = document.createEventObject();			el.fireEvent('on' + evnt, ev);		} else if (el['on' + evnt]) { // alternatively use the traditional event model			el['on' + evnt]();		}	},	classNameToList : function (className) {		return className.replace(/^\s+|\s+$/g, '').split(/\s+/);	},	// The className parameter (str) can only contain a single class name	hasClass : function (elm, className) {		if (!className) {			return false;		}		return -1 != (' ' + elm.className.replace(/\s+/g, ' ') + ' ').indexOf(' ' + className + ' ');	},	// The className parameter (str) can contain multiple class names separated by whitespace	setClass : function (elm, className) {		var classList = jsc.classNameToList(className);		for (var i = 0; i < classList.length; i += 1) {			if (!jsc.hasClass(elm, classList[i])) {				elm.className += (elm.className ? ' ' : '') + classList[i];			}		}	},	// The className parameter (str) can contain multiple class names separated by whitespace	unsetClass : function (elm, className) {		var classList = jsc.classNameToList(className);		for (var i = 0; i < classList.length; i += 1) {			var repl = new RegExp(				'^\\s*' + classList[i] + '\\s*|' +				'\\s*' + classList[i] + '\\s*$|' +				'\\s+' + classList[i] + '(\\s+)',				'g'			);			elm.className = elm.className.replace(repl, '$1');		}	},	getStyle : function (elm) {		return window.getComputedStyle ? window.getComputedStyle(elm) : elm.currentStyle;	},	setStyle : (function () {		var helper = document.createElement('div');		var getSupportedProp = function (names) {			for (var i = 0; i < names.length; i += 1) {				if (names[i] in helper.style) {					return names[i];				}			}		};		var props = {			borderRadius: getSupportedProp(['borderRadius', 'MozBorderRadius', 'webkitBorderRadius']),			boxShadow: getSupportedProp(['boxShadow', 'MozBoxShadow', 'webkitBoxShadow'])		};		return function (elm, prop, value) {			switch (prop.toLowerCase()) {			case 'opacity':				var alphaOpacity = Math.round(parseFloat(value) * 100);				elm.style.opacity = value;				elm.style.filter = 'alpha(opacity=' + alphaOpacity + ')';				break;			default:				elm.style[props[prop]] = value;				break;			}		};	})(),	setBorderRadius : function (elm, value) {		jsc.setStyle(elm, 'borderRadius', value || '0');	},	setBoxShadow : function (elm, value) {		jsc.setStyle(elm, 'boxShadow', value || 'none');	},	getElementPos : function (e, relativeToViewport) {		var x=0, y=0;		var rect = e.getBoundingClientRect();		x = rect.left;		y = rect.top;		if (!relativeToViewport) {			var viewPos = jsc.getViewPos();			x += viewPos[0];			y += viewPos[1];		}		return [x, y];	},	getElementSize : function (e) {		return [e.offsetWidth, e.offsetHeight];	},	// get pointer's X/Y coordinates relative to viewport	getAbsPointerPos : function (e) {		if (!e) { e = window.event; }		var x = 0, y = 0;		if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {			// touch devices			x = e.changedTouches[0].clientX;			y = e.changedTouches[0].clientY;		} else if (typeof e.clientX === 'number') {			x = e.clientX;			y = e.clientY;		}		return { x: x, y: y };	},	// get pointer's X/Y coordinates relative to target element	getRelPointerPos : function (e) {		if (!e) { e = window.event; }		var target = e.target || e.srcElement;		var targetRect = target.getBoundingClientRect();		var x = 0, y = 0;		var clientX = 0, clientY = 0;		if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {			// touch devices			clientX = e.changedTouches[0].clientX;			clientY = e.changedTouches[0].clientY;		} else if (typeof e.clientX === 'number') {			clientX = e.clientX;			clientY = e.clientY;		}		x = clientX - targetRect.left;		y = clientY - targetRect.top;		return { x: x, y: y };	},	getViewPos : function () {		var doc = document.documentElement;		return [			(window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0),			(window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)		];	},	getViewSize : function () {		var doc = document.documentElement;		return [			(window.innerWidth || doc.clientWidth),			(window.innerHeight || doc.clientHeight),		];	},	redrawPosition : function () {		if (jsc.picker && jsc.picker.owner) {			var thisObj = jsc.picker.owner;			var tp, vp;			if (thisObj.fixed) {				// Fixed elements are positioned relative to viewport,				// therefore we can ignore the scroll offset				tp = jsc.getElementPos(thisObj.targetElement, true); // target pos				vp = [0, 0]; // view pos			} else {				tp = jsc.getElementPos(thisObj.targetElement); // target pos				vp = jsc.getViewPos(); // view pos			}			var ts = jsc.getElementSize(thisObj.targetElement); // target size			var vs = jsc.getViewSize(); // view size			var ps = jsc.getPickerOuterDims(thisObj); // picker size			var a, b, c;			switch (thisObj.position.toLowerCase()) {				case 'left': a=1; b=0; c=-1; break;				case 'right':a=1; b=0; c=1; break;				case 'top':  a=0; b=1; c=-1; break;				default:     a=0; b=1; c=1; break;			}			var l = (ts[b]+ps[b])/2;			// compute picker position			if (!thisObj.smartPosition) {				var pp = [					tp[a],					tp[b]+ts[b]-l+l*c				];			} else {				var pp = [					-vp[a]+tp[a]+ps[a] > vs[a] ?						(-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :						tp[a],					-vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?						(-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :						(tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)				];			}			var x = pp[a];			var y = pp[b];			var positionValue = thisObj.fixed ? 'fixed' : 'absolute';			var contractShadow =				(pp[0] + ps[0] > tp[0] || pp[0] < tp[0] + ts[0]) &&				(pp[1] + ps[1] < tp[1] + ts[1]);			jsc._drawPosition(thisObj, x, y, positionValue, contractShadow);		}	},	_drawPosition : function (thisObj, x, y, positionValue, contractShadow) {		var vShadow = contractShadow ? 0 : thisObj.shadowBlur; // px		jsc.picker.wrap.style.position = positionValue;		jsc.picker.wrap.style.left = x + 'px';		jsc.picker.wrap.style.top = y + 'px';		jsc.setBoxShadow(			jsc.picker.boxS,			thisObj.shadow ?				new jsc.BoxShadow(0, vShadow, thisObj.shadowBlur, 0, thisObj.shadowColor) :				null);	},	getPickerDims : function (thisObj) {		var displaySlider = !!jsc.getSliderComponent(thisObj);		var dims = [			2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.width +				(displaySlider ? 2 * thisObj.insetWidth + jsc.getPadToSliderPadding(thisObj) + thisObj.sliderSize : 0),			2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.height +				(thisObj.closable ? 2 * thisObj.insetWidth + thisObj.padding + thisObj.buttonHeight : 0)		];		return dims;	},	getPickerOuterDims : function (thisObj) {		var dims = jsc.getPickerDims(thisObj);		return [			dims[0] + 2 * thisObj.borderWidth,			dims[1] + 2 * thisObj.borderWidth		];	},	getPadToSliderPadding : function (thisObj) {		return Math.max(thisObj.padding, 1.5 * (2 * thisObj.pointerBorderWidth + thisObj.pointerThickness));	},	getPadYComponent : function (thisObj) {		switch (thisObj.mode.charAt(1).toLowerCase()) {			case 'v': return 'v'; break;		}		return 's';	},	getSliderComponent : function (thisObj) {		if (thisObj.mode.length > 2) {			switch (thisObj.mode.charAt(2).toLowerCase()) {				case 's': return 's'; break;				case 'v': return 'v'; break;			}		}		return null;	},	onDocumentMouseDown : function (e) {		if (!e) { e = window.event; }		var target = e.target || e.srcElement;		if (target._jscLinkedInstance) {			if (target._jscLinkedInstance.showOnClick) {				target._jscLinkedInstance.show();			}		} else if (target._jscControlName) {			jsc.onControlPointerStart(e, target, target._jscControlName, 'mouse');		} else {			// Mouse is outside the picker controls -> hide the color picker!			if (jsc.picker && jsc.picker.owner) {				jsc.picker.owner.hide();			}		}	},	onDocumentTouchStart : function (e) {		if (!e) { e = window.event; }		var target = e.target || e.srcElement;		if (target._jscLinkedInstance) {			if (target._jscLinkedInstance.showOnClick) {				target._jscLinkedInstance.show();			}		} else if (target._jscControlName) {			jsc.onControlPointerStart(e, target, target._jscControlName, 'touch');		} else {			if (jsc.picker && jsc.picker.owner) {				jsc.picker.owner.hide();			}		}	},	onWindowResize : function (e) {		jsc.redrawPosition();	},	onParentScroll : function (e) {		// hide the picker when one of the parent elements is scrolled		if (jsc.picker && jsc.picker.owner) {			jsc.picker.owner.hide();		}	},	_pointerMoveEvent : {		mouse: 'mousemove',		touch: 'touchmove'	},	_pointerEndEvent : {		mouse: 'mouseup',		touch: 'touchend'	},	_pointerOrigin : null,	_capturedTarget : null,	onControlPointerStart : function (e, target, controlName, pointerType) {		var thisObj = target._jscInstance;		jsc.preventDefault(e);		jsc.captureTarget(target);		var registerDragEvents = function (doc, offset) {			jsc.attachGroupEvent('drag', doc, jsc._pointerMoveEvent[pointerType],				jsc.onDocumentPointerMove(e, target, controlName, pointerType, offset));			jsc.attachGroupEvent('drag', doc, jsc._pointerEndEvent[pointerType],				jsc.onDocumentPointerEnd(e, target, controlName, pointerType));		};		registerDragEvents(document, [0, 0]);		if (window.parent && window.frameElement) {			var rect = window.frameElement.getBoundingClientRect();			var ofs = [-rect.left, -rect.top];			registerDragEvents(window.parent.window.document, ofs);		}		var abs = jsc.getAbsPointerPos(e);		var rel = jsc.getRelPointerPos(e);		jsc._pointerOrigin = {			x: abs.x - rel.x,			y: abs.y - rel.y		};		switch (controlName) {		case 'pad':			// if the slider is at the bottom, move it up			switch (jsc.getSliderComponent(thisObj)) {			case 's': if (thisObj.hsv[1] === 0) { thisObj.fromHSV(null, 100, null); }; break;			case 'v': if (thisObj.hsv[2] === 0) { thisObj.fromHSV(null, null, 100); }; break;			}			jsc.setPad(thisObj, e, 0, 0);			break;		case 'sld':			jsc.setSld(thisObj, e, 0);			break;		}		jsc.dispatchFineChange(thisObj);	},	onDocumentPointerMove : function (e, target, controlName, pointerType, offset) {		return function (e) {			var thisObj = target._jscInstance;			switch (controlName) {			case 'pad':				if (!e) { e = window.event; }				jsc.setPad(thisObj, e, offset[0], offset[1]);				jsc.dispatchFineChange(thisObj);				break;			case 'sld':				if (!e) { e = window.event; }				jsc.setSld(thisObj, e, offset[1]);				jsc.dispatchFineChange(thisObj);				break;			}		}	},	onDocumentPointerEnd : function (e, target, controlName, pointerType) {		return function (e) {			var thisObj = target._jscInstance;			jsc.detachGroupEvents('drag');			jsc.releaseTarget();			// Always dispatch changes after detaching outstanding mouse handlers,			// in case some user interaction will occur in user's onchange callback			// that would intrude with current mouse events			jsc.dispatchChange(thisObj);		};	},	dispatchChange : function (thisObj) {		if (thisObj.valueElement) {			if (jsc.isElementType(thisObj.valueElement, 'input')) {				jsc.fireEvent(thisObj.valueElement, 'change');			}		}	},	dispatchFineChange : function (thisObj) {		if (thisObj.onFineChange) {			var callback;			if (typeof thisObj.onFineChange === 'string') {				callback = new Function (thisObj.onFineChange);			} else {				callback = thisObj.onFineChange;			}			callback.call(thisObj);		}	},	setPad : function (thisObj, e, ofsX, ofsY) {		var pointerAbs = jsc.getAbsPointerPos(e);		var x = ofsX + pointerAbs.x - jsc._pointerOrigin.x - thisObj.padding - thisObj.insetWidth;		var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;		var xVal = x * (360 / (thisObj.width - 1));		var yVal = 100 - (y * (100 / (thisObj.height - 1)));		switch (jsc.getPadYComponent(thisObj)) {		case 's': thisObj.fromHSV(xVal, yVal, null, jsc.leaveSld); break;		case 'v': thisObj.fromHSV(xVal, null, yVal, jsc.leaveSld); break;		}	},	setSld : function (thisObj, e, ofsY) {		var pointerAbs = jsc.getAbsPointerPos(e);		var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;		var yVal = 100 - (y * (100 / (thisObj.height - 1)));		switch (jsc.getSliderComponent(thisObj)) {		case 's': thisObj.fromHSV(null, yVal, null, jsc.leavePad); break;		case 'v': thisObj.fromHSV(null, null, yVal, jsc.leavePad); break;		}	},	_vmlNS : 'jsc_vml_',	_vmlCSS : 'jsc_vml_css_',	_vmlReady : false,	initVML : function () {		if (!jsc._vmlReady) {			// init VML namespace			var doc = document;			if (!doc.namespaces[jsc._vmlNS]) {				doc.namespaces.add(jsc._vmlNS, 'urn:schemas-microsoft-com:vml');			}			if (!doc.styleSheets[jsc._vmlCSS]) {				var tags = ['shape', 'shapetype', 'group', 'background', 'path', 'formulas', 'handles', 'fill', 'stroke', 'shadow', 'textbox', 'textpath', 'imagedata', 'line', 'polyline', 'curve', 'rect', 'roundrect', 'oval', 'arc', 'image'];				var ss = doc.createStyleSheet();				ss.owningElement.id = jsc._vmlCSS;				for (var i = 0; i < tags.length; i += 1) {					ss.addRule(jsc._vmlNS + '\\:' + tags[i], 'behavior:url(#default#VML);');				}			}			jsc._vmlReady = true;		}	},	createPalette : function () {		var paletteObj = {			elm: null,			draw: null		};		if (jsc.isCanvasSupported) {			// Canvas implementation for modern browsers			var canvas = document.createElement('canvas');			var ctx = canvas.getContext('2d');			var drawFunc = function (width, height, type) {				canvas.width = width;				canvas.height = height;				ctx.clearRect(0, 0, canvas.width, canvas.height);				var hGrad = ctx.createLinearGradient(0, 0, canvas.width, 0);				hGrad.addColorStop(0 / 6, '#F00');				hGrad.addColorStop(1 / 6, '#FF0');				hGrad.addColorStop(2 / 6, '#0F0');				hGrad.addColorStop(3 / 6, '#0FF');				hGrad.addColorStop(4 / 6, '#00F');				hGrad.addColorStop(5 / 6, '#F0F');				hGrad.addColorStop(6 / 6, '#F00');				ctx.fillStyle = hGrad;				ctx.fillRect(0, 0, canvas.width, canvas.height);				var vGrad = ctx.createLinearGradient(0, 0, 0, canvas.height);				switch (type.toLowerCase()) {				case 's':					vGrad.addColorStop(0, 'rgba(255,255,255,0)');					vGrad.addColorStop(1, 'rgba(255,255,255,1)');					break;				case 'v':					vGrad.addColorStop(0, 'rgba(0,0,0,0)');					vGrad.addColorStop(1, 'rgba(0,0,0,1)');					break;				}				ctx.fillStyle = vGrad;				ctx.fillRect(0, 0, canvas.width, canvas.height);			};			paletteObj.elm = canvas;			paletteObj.draw = drawFunc;		} else {			// VML fallback for IE 7 and 8			jsc.initVML();			var vmlContainer = document.createElement('div');			vmlContainer.style.position = 'relative';			vmlContainer.style.overflow = 'hidden';			var hGrad = document.createElement(jsc._vmlNS + ':fill');			hGrad.type = 'gradient';			hGrad.method = 'linear';			hGrad.angle = '90';			hGrad.colors = '16.67% #F0F, 33.33% #00F, 50% #0FF, 66.67% #0F0, 83.33% #FF0'			var hRect = document.createElement(jsc._vmlNS + ':rect');			hRect.style.position = 'absolute';			hRect.style.left = -1 + 'px';			hRect.style.top = -1 + 'px';			hRect.stroked = false;			hRect.appendChild(hGrad);			vmlContainer.appendChild(hRect);			var vGrad = document.createElement(jsc._vmlNS + ':fill');			vGrad.type = 'gradient';			vGrad.method = 'linear';			vGrad.angle = '180';			vGrad.opacity = '0';			var vRect = document.createElement(jsc._vmlNS + ':rect');			vRect.style.position = 'absolute';			vRect.style.left = -1 + 'px';			vRect.style.top = -1 + 'px';			vRect.stroked = false;			vRect.appendChild(vGrad);			vmlContainer.appendChild(vRect);			var drawFunc = function (width, height, type) {				vmlContainer.style.width = width + 'px';				vmlContainer.style.height = height + 'px';				hRect.style.width =				vRect.style.width =					(width + 1) + 'px';				hRect.style.height =				vRect.style.height =					(height + 1) + 'px';				// Colors must be specified during every redraw, otherwise IE won't display				// a full gradient during a subsequential redraw				hGrad.color = '#F00';				hGrad.color2 = '#F00';				switch (type.toLowerCase()) {				case 's':					vGrad.color = vGrad.color2 = '#FFF';					break;				case 'v':					vGrad.color = vGrad.color2 = '#000';					break;				}			};						paletteObj.elm = vmlContainer;			paletteObj.draw = drawFunc;		}		return paletteObj;	},	createSliderGradient : function () {		var sliderObj = {			elm: null,			draw: null		};		if (jsc.isCanvasSupported) {			// Canvas implementation for modern browsers			var canvas = document.createElement('canvas');			var ctx = canvas.getContext('2d');			var drawFunc = function (width, height, color1, color2) {				canvas.width = width;				canvas.height = height;				ctx.clearRect(0, 0, canvas.width, canvas.height);				var grad = ctx.createLinearGradient(0, 0, 0, canvas.height);				grad.addColorStop(0, color1);				grad.addColorStop(1, color2);				ctx.fillStyle = grad;				ctx.fillRect(0, 0, canvas.width, canvas.height);			};			sliderObj.elm = canvas;			sliderObj.draw = drawFunc;		} else {			// VML fallback for IE 7 and 8			jsc.initVML();			var vmlContainer = document.createElement('div');			vmlContainer.style.position = 'relative';			vmlContainer.style.overflow = 'hidden';			var grad = document.createElement(jsc._vmlNS + ':fill');			grad.type = 'gradient';			grad.method = 'linear';			grad.angle = '180';			var rect = document.createElement(jsc._vmlNS + ':rect');			rect.style.position = 'absolute';			rect.style.left = -1 + 'px';			rect.style.top = -1 + 'px';			rect.stroked = false;			rect.appendChild(grad);			vmlContainer.appendChild(rect);			var drawFunc = function (width, height, color1, color2) {				vmlContainer.style.width = width + 'px';				vmlContainer.style.height = height + 'px';				rect.style.width = (width + 1) + 'px';				rect.style.height = (height + 1) + 'px';				grad.color = color1;				grad.color2 = color2;			};						sliderObj.elm = vmlContainer;			sliderObj.draw = drawFunc;		}		return sliderObj;	},	leaveValue : 1<<0,	leaveStyle : 1<<1,	leavePad : 1<<2,	leaveSld : 1<<3,	BoxShadow : (function () {		var BoxShadow = function (hShadow, vShadow, blur, spread, color, inset) {			this.hShadow = hShadow;			this.vShadow = vShadow;			this.blur = blur;			this.spread = spread;			this.color = color;			this.inset = !!inset;		};		BoxShadow.prototype.toString = function () {			var vals = [				Math.round(this.hShadow) + 'px',				Math.round(this.vShadow) + 'px',				Math.round(this.blur) + 'px',				Math.round(this.spread) + 'px',				this.color			];			if (this.inset) {				vals.push('inset');			}			return vals.join(' ');		};		return BoxShadow;	})(),	//	// Usage:	// var myColor = new jscolor(<targetElement> [, <options>])	//	jscolor : function (targetElement, options) {		// General options		//		this.value = null; // initial HEX color. To change it later, use methods fromString(), fromHSV() and fromRGB()		this.valueElement = targetElement; // element that will be used to display and input the color code		this.styleElement = targetElement; // element that will preview the picked color using CSS backgroundColor		this.required = true; // whether the associated text <input> can be left empty		this.refine = true; // whether to refine the entered color code (e.g. uppercase it and remove whitespace)		this.hash = false; // whether to prefix the HEX color code with # symbol		this.uppercase = true; // whether to uppercase the color code		this.onFineChange = null; // called instantly every time the color changes (value can be either a function or a string with javascript code)		this.activeClass = 'jscolor-active'; // class to be set to the target element when a picker window is open on it		this.minS = 0; // min allowed saturation (0 - 100)		this.maxS = 100; // max allowed saturation (0 - 100)		this.minV = 0; // min allowed value (brightness) (0 - 100)		this.maxV = 100; // max allowed value (brightness) (0 - 100)		// Accessing the picked color		//		this.hsv = [0, 0, 100]; // read-only  [0-360, 0-100, 0-100]		this.rgb = [255, 255, 255]; // read-only  [0-255, 0-255, 0-255]		// Color Picker options		//		this.width = 181; // width of color palette (in px)		this.height = 101; // height of color palette (in px)		this.showOnClick = true; // whether to display the color picker when user clicks on its target element		this.mode = 'HSV'; // HSV | HVS | HS | HV - layout of the color picker controls		this.position = 'bottom'; // left | right | top | bottom - position relative to the target element		this.smartPosition = true; // automatically change picker position when there is not enough space for it		this.sliderSize = 16; // px		this.crossSize = 8; // px		this.closable = false; // whether to display the Close button		this.closeText = 'Close';		this.buttonColor = '#000000'; // CSS color		this.buttonHeight = 18; // px		this.padding = 12; // px		this.backgroundColor = '#FFFFFF'; // CSS color		this.borderWidth = 1; // px		this.borderColor = '#BBBBBB'; // CSS color		this.borderRadius = 8; // px		this.insetWidth = 1; // px		this.insetColor = '#BBBBBB'; // CSS color		this.shadow = true; // whether to display shadow		this.shadowBlur = 15; // px		this.shadowColor = 'rgba(0,0,0,0.2)'; // CSS color		this.pointerColor = '#4C4C4C'; // px		this.pointerBorderColor = '#FFFFFF'; // px        this.pointerBorderWidth = 1; // px        this.pointerThickness = 2; // px		this.zIndex = 1000;		this.container = null; // where to append the color picker (BODY element by default)		for (var opt in options) {			if (options.hasOwnProperty(opt)) {				this[opt] = options[opt];			}		}		this.hide = function () {			if (isPickerOwner()) {				detachPicker();			}		};		this.show = function () {			drawPicker();		};		this.redraw = function () {			if (isPickerOwner()) {				drawPicker();			}		};		this.importColor = function () {			if (!this.valueElement) {				this.exportColor();			} else {				if (jsc.isElementType(this.valueElement, 'input')) {					if (!this.refine) {						if (!this.fromString(this.valueElement.value, jsc.leaveValue)) {							if (this.styleElement) {								this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;								this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;								this.styleElement.style.color = this.styleElement._jscOrigStyle.color;							}							this.exportColor(jsc.leaveValue | jsc.leaveStyle);						}					} else if (!this.required && /^\s*$/.test(this.valueElement.value)) {						this.valueElement.value = '';						if (this.styleElement) {							this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;							this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;							this.styleElement.style.color = this.styleElement._jscOrigStyle.color;						}						this.exportColor(jsc.leaveValue | jsc.leaveStyle);					} else if (this.fromString(this.valueElement.value)) {						// managed to import color successfully from the value -> OK, don't do anything					} else {						this.exportColor(2);					}				} else {					// not an input element -> doesn't have any value					this.exportColor();				}			}		};		this.exportColor = function (flags) {            if (flags == 2) {                if (this.styleElement) {                    this.styleElement.style.backgroundImage = 'none';                    this.styleElement.style.backgroundColor = 'transparent';                    this.styleElement.style.color = '#000';                }            } else {			    if (!(flags & jsc.leaveValue) && this.valueElement) {				    var value = this.toString();				    if (this.uppercase) { value = value.toUpperCase(); }				    if (this.hash) { value = '#' + value; }				    if (jsc.isElementType(this.valueElement, 'input')) {					    this.valueElement.value = value;				    } else {					    this.valueElement.innerHTML = value;				    }			    }			    if (!(flags & jsc.leaveStyle)) {				    if (this.styleElement) {					    this.styleElement.style.backgroundImage = 'none';					    this.styleElement.style.backgroundColor = '#' + this.toString();					    this.styleElement.style.color = this.isLight() ? '#000' : '#FFF';				    }			    }			    if (!(flags & jsc.leavePad) && isPickerOwner()) {				    redrawPad();			    }			    if (!(flags & jsc.leaveSld) && isPickerOwner()) {				    redrawSld();			    }            }		};		// h: 0-360		// s: 0-100		// v: 0-100		//		this.fromHSV = function (h, s, v, flags) { // null = don't change			if (h !== null) {				if (isNaN(h)) { return false; }				h = Math.max(0, Math.min(360, h));			}			if (s !== null) {				if (isNaN(s)) { return false; }				s = Math.max(0, Math.min(100, this.maxS, s), this.minS);			}			if (v !== null) {				if (isNaN(v)) { return false; }				v = Math.max(0, Math.min(100, this.maxV, v), this.minV);			}			this.rgb = HSV_RGB(				h===null ? this.hsv[0] : (this.hsv[0]=h),				s===null ? this.hsv[1] : (this.hsv[1]=s),				v===null ? this.hsv[2] : (this.hsv[2]=v)			);			this.exportColor(flags);		};		// r: 0-255		// g: 0-255		// b: 0-255		//		this.fromRGB = function (r, g, b, flags) { // null = don't change			if (r !== null) {				if (isNaN(r)) { return false; }				r = Math.max(0, Math.min(255, r));			}			if (g !== null) {				if (isNaN(g)) { return false; }				g = Math.max(0, Math.min(255, g));			}			if (b !== null) {				if (isNaN(b)) { return false; }				b = Math.max(0, Math.min(255, b));			}			var hsv = RGB_HSV(				r===null ? this.rgb[0] : r,				g===null ? this.rgb[1] : g,				b===null ? this.rgb[2] : b			);			if (hsv[0] !== null) {				this.hsv[0] = Math.max(0, Math.min(360, hsv[0]));			}			if (hsv[2] !== 0) {				this.hsv[1] = hsv[1]===null ? null : Math.max(0, this.minS, Math.min(100, this.maxS, hsv[1]));			}			this.hsv[2] = hsv[2]===null ? null : Math.max(0, this.minV, Math.min(100, this.maxV, hsv[2]));			// update RGB according to final HSV, as some values might be trimmed			var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);			this.rgb[0] = rgb[0];			this.rgb[1] = rgb[1];			this.rgb[2] = rgb[2];			this.exportColor(flags);		};		this.fromString = function (str, flags) {			var m;			if (m = str.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i)) {				// HEX notation				//				if (m[1].length === 6) {					// 6-char notation					this.fromRGB(						parseInt(m[1].substr(0,2),16),						parseInt(m[1].substr(2,2),16),						parseInt(m[1].substr(4,2),16),						flags					);				} else {					// 3-char notation					this.fromRGB(						parseInt(m[1].charAt(0) + m[1].charAt(0),16),						parseInt(m[1].charAt(1) + m[1].charAt(1),16),						parseInt(m[1].charAt(2) + m[1].charAt(2),16),						flags					);				}				return true;			} else if (m = str.match(/^\W*rgba?\(([^)]*)\)\W*$/i)) {				var params = m[1].split(',');				var re = /^\s*(\d*)(\.\d+)?\s*$/;				var mR, mG, mB;				if (					params.length >= 3 &&					(mR = params[0].match(re)) &&					(mG = params[1].match(re)) &&					(mB = params[2].match(re))				) {					var r = parseFloat((mR[1] || '0') + (mR[2] || ''));					var g = parseFloat((mG[1] || '0') + (mG[2] || ''));					var b = parseFloat((mB[1] || '0') + (mB[2] || ''));					this.fromRGB(r, g, b, flags);					return true;				}			}			return false;		};		this.toString = function () {			return (				(0x100 | Math.round(this.rgb[0])).toString(16).substr(1) +				(0x100 | Math.round(this.rgb[1])).toString(16).substr(1) +				(0x100 | Math.round(this.rgb[2])).toString(16).substr(1)			);		};		this.toHEXString = function () {			return '#' + this.toString().toUpperCase();		};		this.toRGBString = function () {			return ('rgb(' +				Math.round(this.rgb[0]) + ',' +				Math.round(this.rgb[1]) + ',' +				Math.round(this.rgb[2]) + ')'			);		};		this.isLight = function () {			return (				0.213 * this.rgb[0] +				0.715 * this.rgb[1] +				0.072 * this.rgb[2] >				255 / 2			);		};		this._processParentElementsInDOM = function () {			if (this._linkedElementsProcessed) { return; }			this._linkedElementsProcessed = true;			var elm = this.targetElement;			do {				// If the target element or one of its parent nodes has fixed position,				// then use fixed positioning instead				//				// Note: In Firefox, getComputedStyle returns null in a hidden iframe,				// that's why we need to check if the returned style object is non-empty				var currStyle = jsc.getStyle(elm);				if (currStyle && currStyle.position.toLowerCase() === 'fixed') {					this.fixed = true;				}				if (elm !== this.targetElement) {					// Ensure to attach onParentScroll only once to each parent element					// (multiple targetElements can share the same parent nodes)					//					// Note: It's not just offsetParents that can be scrollable,					// that's why we loop through all parent nodes					if (!elm._jscEventsAttached) {						jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);						elm._jscEventsAttached = true;					}				}			} while ((elm = elm.parentNode) && !jsc.isElementType(elm, 'body'));		};		// r: 0-255		// g: 0-255		// b: 0-255		//		// returns: [ 0-360, 0-100, 0-100 ]		//		function RGB_HSV (r, g, b) {			r /= 255;			g /= 255;			b /= 255;			var n = Math.min(Math.min(r,g),b);			var v = Math.max(Math.max(r,g),b);			var m = v - n;			if (m === 0) { return [ null, 0, 100 * v ]; }			var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);			return [				60 * (h===6?0:h),				100 * (m/v),				100 * v			];		}		// h: 0-360		// s: 0-100		// v: 0-100		//		// returns: [ 0-255, 0-255, 0-255 ]		//		function HSV_RGB (h, s, v) {			var u = 255 * (v / 100);			if (h === null) {				return [ u, u, u ];			}			h /= 60;			s /= 100;			var i = Math.floor(h);			var f = i%2 ? h-i : 1-(h-i);			var m = u * (1 - s);			var n = u * (1 - s * f);			switch (i) {				case 6:				case 0: return [u,n,m];				case 1: return [n,u,m];				case 2: return [m,u,n];				case 3: return [m,n,u];				case 4: return [n,m,u];				case 5: return [u,m,n];			}		}		function detachPicker () {			jsc.unsetClass(THIS.targetElement, THIS.activeClass);			jsc.picker.wrap.parentNode.removeChild(jsc.picker.wrap);			delete jsc.picker.owner;		}		function drawPicker () {			// At this point, when drawing the picker, we know what the parent elements are			// and we can do all related DOM operations, such as registering events on them			// or checking their positioning			THIS._processParentElementsInDOM();			if (!jsc.picker) {				jsc.picker = {					owner: null,					wrap : document.createElement('div'),					box : document.createElement('div'),					boxS : document.createElement('div'), // shadow area					boxB : document.createElement('div'), // border					pad : document.createElement('div'),					padB : document.createElement('div'), // border					padM : document.createElement('div'), // mouse/touch area					padPal : jsc.createPalette(),					cross : document.createElement('div'),					crossBY : document.createElement('div'), // border Y					crossBX : document.createElement('div'), // border X					crossLY : document.createElement('div'), // line Y					crossLX : document.createElement('div'), // line X					sld : document.createElement('div'),					sldB : document.createElement('div'), // border					sldM : document.createElement('div'), // mouse/touch area					sldGrad : jsc.createSliderGradient(),					sldPtrS : document.createElement('div'), // slider pointer spacer					sldPtrIB : document.createElement('div'), // slider pointer inner border					sldPtrMB : document.createElement('div'), // slider pointer middle border					sldPtrOB : document.createElement('div'), // slider pointer outer border					btn : document.createElement('div'),					btnT : document.createElement('span') // text				};				jsc.picker.pad.appendChild(jsc.picker.padPal.elm);				jsc.picker.padB.appendChild(jsc.picker.pad);				jsc.picker.cross.appendChild(jsc.picker.crossBY);				jsc.picker.cross.appendChild(jsc.picker.crossBX);				jsc.picker.cross.appendChild(jsc.picker.crossLY);				jsc.picker.cross.appendChild(jsc.picker.crossLX);				jsc.picker.padB.appendChild(jsc.picker.cross);				jsc.picker.box.appendChild(jsc.picker.padB);				jsc.picker.box.appendChild(jsc.picker.padM);				jsc.picker.sld.appendChild(jsc.picker.sldGrad.elm);				jsc.picker.sldB.appendChild(jsc.picker.sld);				jsc.picker.sldB.appendChild(jsc.picker.sldPtrOB);				jsc.picker.sldPtrOB.appendChild(jsc.picker.sldPtrMB);				jsc.picker.sldPtrMB.appendChild(jsc.picker.sldPtrIB);				jsc.picker.sldPtrIB.appendChild(jsc.picker.sldPtrS);				jsc.picker.box.appendChild(jsc.picker.sldB);				jsc.picker.box.appendChild(jsc.picker.sldM);				jsc.picker.btn.appendChild(jsc.picker.btnT);				jsc.picker.box.appendChild(jsc.picker.btn);				jsc.picker.boxB.appendChild(jsc.picker.box);				jsc.picker.wrap.appendChild(jsc.picker.boxS);				jsc.picker.wrap.appendChild(jsc.picker.boxB);			}			var p = jsc.picker;			var displaySlider = !!jsc.getSliderComponent(THIS);			var dims = jsc.getPickerDims(THIS);			var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);			var padToSliderPadding = jsc.getPadToSliderPadding(THIS);			var borderRadius = Math.min(				THIS.borderRadius,				Math.round(THIS.padding * Math.PI)); // px			var padCursor = 'crosshair';			// wrap			p.wrap.style.clear = 'both';			p.wrap.style.width = (dims[0] + 2 * THIS.borderWidth) + 'px';			p.wrap.style.height = (dims[1] + 2 * THIS.borderWidth) + 'px';			p.wrap.style.zIndex = THIS.zIndex;			// picker			p.box.style.width = dims[0] + 'px';			p.box.style.height = dims[1] + 'px';			p.boxS.style.position = 'absolute';			p.boxS.style.left = '0';			p.boxS.style.top = '0';			p.boxS.style.width = '100%';			p.boxS.style.height = '100%';			jsc.setBorderRadius(p.boxS, borderRadius + 'px');			// picker border			p.boxB.style.position = 'relative';			p.boxB.style.border = THIS.borderWidth + 'px solid';			p.boxB.style.borderColor = THIS.borderColor;			p.boxB.style.background = THIS.backgroundColor;			jsc.setBorderRadius(p.boxB, borderRadius + 'px');			// IE hack:			// If the element is transparent, IE will trigger the event on the elements under it,			// e.g. on Canvas or on elements with border			p.padM.style.background =			p.sldM.style.background =				'#FFF';			jsc.setStyle(p.padM, 'opacity', '0');			jsc.setStyle(p.sldM, 'opacity', '0');			// pad			p.pad.style.position = 'relative';			p.pad.style.width = THIS.width + 'px';			p.pad.style.height = THIS.height + 'px';			// pad palettes (HSV and HVS)			p.padPal.draw(THIS.width, THIS.height, jsc.getPadYComponent(THIS));			// pad border			p.padB.style.position = 'absolute';			p.padB.style.left = THIS.padding + 'px';			p.padB.style.top = THIS.padding + 'px';			p.padB.style.border = THIS.insetWidth + 'px solid';			p.padB.style.borderColor = THIS.insetColor;			// pad mouse area			p.padM._jscInstance = THIS;			p.padM._jscControlName = 'pad';			p.padM.style.position = 'absolute';			p.padM.style.left = '0';			p.padM.style.top = '0';			p.padM.style.width = (THIS.padding + 2 * THIS.insetWidth + THIS.width + padToSliderPadding / 2) + 'px';			p.padM.style.height = dims[1] + 'px';			p.padM.style.cursor = padCursor;			// pad cross			p.cross.style.position = 'absolute';			p.cross.style.left =			p.cross.style.top =				'0';			p.cross.style.width =			p.cross.style.height =				crossOuterSize + 'px';			// pad cross border Y and X			p.crossBY.style.position =			p.crossBX.style.position =				'absolute';			p.crossBY.style.background =			p.crossBX.style.background =				THIS.pointerBorderColor;			p.crossBY.style.width =			p.crossBX.style.height =				(2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';			p.crossBY.style.height =			p.crossBX.style.width =				crossOuterSize + 'px';			p.crossBY.style.left =			p.crossBX.style.top =				(Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2) - THIS.pointerBorderWidth) + 'px';			p.crossBY.style.top =			p.crossBX.style.left =				'0';			// pad cross line Y and X			p.crossLY.style.position =			p.crossLX.style.position =				'absolute';			p.crossLY.style.background =			p.crossLX.style.background =				THIS.pointerColor;			p.crossLY.style.height =			p.crossLX.style.width =				(crossOuterSize - 2 * THIS.pointerBorderWidth) + 'px';			p.crossLY.style.width =			p.crossLX.style.height =				THIS.pointerThickness + 'px';			p.crossLY.style.left =			p.crossLX.style.top =				(Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2)) + 'px';			p.crossLY.style.top =			p.crossLX.style.left =				THIS.pointerBorderWidth + 'px';			// slider			p.sld.style.overflow = 'hidden';			p.sld.style.width = THIS.sliderSize + 'px';			p.sld.style.height = THIS.height + 'px';			// slider gradient			p.sldGrad.draw(THIS.sliderSize, THIS.height, '#000', '#000');			// slider border			p.sldB.style.display = displaySlider ? 'block' : 'none';			p.sldB.style.position = 'absolute';			p.sldB.style.right = THIS.padding + 'px';			p.sldB.style.top = THIS.padding + 'px';			p.sldB.style.border = THIS.insetWidth + 'px solid';			p.sldB.style.borderColor = THIS.insetColor;			// slider mouse area			p.sldM._jscInstance = THIS;			p.sldM._jscControlName = 'sld';			p.sldM.style.display = displaySlider ? 'block' : 'none';			p.sldM.style.position = 'absolute';			p.sldM.style.right = '0';			p.sldM.style.top = '0';			p.sldM.style.width = (THIS.sliderSize + padToSliderPadding / 2 + THIS.padding + 2 * THIS.insetWidth) + 'px';			p.sldM.style.height = dims[1] + 'px';			p.sldM.style.cursor = 'default';			// slider pointer inner and outer border			p.sldPtrIB.style.border =			p.sldPtrOB.style.border =				THIS.pointerBorderWidth + 'px solid ' + THIS.pointerBorderColor;			// slider pointer outer border			p.sldPtrOB.style.position = 'absolute';			p.sldPtrOB.style.left = -(2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';			p.sldPtrOB.style.top = '0';			// slider pointer middle border			p.sldPtrMB.style.border = THIS.pointerThickness + 'px solid ' + THIS.pointerColor;			// slider pointer spacer			p.sldPtrS.style.width = THIS.sliderSize + 'px';			p.sldPtrS.style.height = sliderPtrSpace + 'px';			// the Close button			function setBtnBorder () {				var insetColors = THIS.insetColor.split(/\s+/);				var outsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];				p.btn.style.borderColor = outsetColor;			}			p.btn.style.display = THIS.closable ? 'block' : 'none';			p.btn.style.position = 'absolute';			p.btn.style.left = THIS.padding + 'px';			p.btn.style.bottom = THIS.padding + 'px';			p.btn.style.padding = '0 15px';			p.btn.style.height = THIS.buttonHeight + 'px';			p.btn.style.border = THIS.insetWidth + 'px solid';			setBtnBorder();			p.btn.style.color = THIS.buttonColor;			p.btn.style.font = '12px sans-serif';			p.btn.style.textAlign = 'center';			try {				p.btn.style.cursor = 'pointer';			} catch(eOldIE) {				p.btn.style.cursor = 'hand';			}			p.btn.onmousedown = function () {				THIS.hide();			};			p.btnT.style.lineHeight = THIS.buttonHeight + 'px';			p.btnT.innerHTML = '';			p.btnT.appendChild(document.createTextNode(THIS.closeText));			// place pointers			redrawPad();			redrawSld();			// If we are changing the owner without first closing the picker,			// make sure to first deal with the old owner			if (jsc.picker.owner && jsc.picker.owner !== THIS) {				jsc.unsetClass(jsc.picker.owner.targetElement, THIS.activeClass);			}			// Set the new picker owner			jsc.picker.owner = THIS;			// The redrawPosition() method needs picker.owner to be set, that's why we call it here,			// after setting the owner			if (jsc.isElementType(container, 'body')) {				jsc.redrawPosition();			} else {				jsc._drawPosition(THIS, 0, 0, 'relative', false);			}			if (p.wrap.parentNode != container) {				container.appendChild(p.wrap);			}			jsc.setClass(THIS.targetElement, THIS.activeClass);		}		function redrawPad () {			// redraw the pad pointer			switch (jsc.getPadYComponent(THIS)) {			case 's': var yComponent = 1; break;			case 'v': var yComponent = 2; break;			}			var x = Math.round((THIS.hsv[0] / 360) * (THIS.width - 1));			var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));			var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);			var ofs = -Math.floor(crossOuterSize / 2);			jsc.picker.cross.style.left = (x + ofs) + 'px';			jsc.picker.cross.style.top = (y + ofs) + 'px';			// redraw the slider			switch (jsc.getSliderComponent(THIS)) {			case 's':				var rgb1 = HSV_RGB(THIS.hsv[0], 100, THIS.hsv[2]);				var rgb2 = HSV_RGB(THIS.hsv[0], 0, THIS.hsv[2]);				var color1 = 'rgb(' +					Math.round(rgb1[0]) + ',' +					Math.round(rgb1[1]) + ',' +					Math.round(rgb1[2]) + ')';				var color2 = 'rgb(' +					Math.round(rgb2[0]) + ',' +					Math.round(rgb2[1]) + ',' +					Math.round(rgb2[2]) + ')';				jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);				break;			case 'v':				var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 100);				var color1 = 'rgb(' +					Math.round(rgb[0]) + ',' +					Math.round(rgb[1]) + ',' +					Math.round(rgb[2]) + ')';				var color2 = '#000';				jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);				break;			}		}		function redrawSld () {			var sldComponent = jsc.getSliderComponent(THIS);			if (sldComponent) {				// redraw the slider pointer				switch (sldComponent) {				case 's': var yComponent = 1; break;				case 'v': var yComponent = 2; break;				}				var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));				jsc.picker.sldPtrOB.style.top = (y - (2 * THIS.pointerBorderWidth + THIS.pointerThickness) - Math.floor(sliderPtrSpace / 2)) + 'px';			}		}		function isPickerOwner () {			return jsc.picker && jsc.picker.owner === THIS;		}		function blurValue () {			THIS.importColor();		}		// Find the target element		if (typeof targetElement === 'string') {			var id = targetElement;			var elm = document.getElementById(id);			if (elm) {				this.targetElement = elm;			} else {				jsc.warn('Could not find target element with ID \'' + id + '\'');			}		} else if (targetElement) {			this.targetElement = targetElement;		} else {			jsc.warn('Invalid target element: \'' + targetElement + '\'');		}		if (this.targetElement._jscLinkedInstance) {			jsc.warn('Cannot link jscolor twice to the same element. Skipping.');			return;		}		this.targetElement._jscLinkedInstance = this;		// Find the value element		this.valueElement = jsc.fetchElement(this.valueElement);		// Find the style element		this.styleElement = jsc.fetchElement(this.styleElement);		var THIS = this;		var container =			this.container ?			jsc.fetchElement(this.container) :			document.getElementsByTagName('body')[0];		var sliderPtrSpace = 3; // px		// For BUTTON elements it's important to stop them from sending the form when clicked		// (e.g. in Safari)		if (jsc.isElementType(this.targetElement, 'button')) {			if (this.targetElement.onclick) {				var origCallback = this.targetElement.onclick;				this.targetElement.onclick = function (evt) {					origCallback.call(this, evt);					return false;				};			} else {				this.targetElement.onclick = function () { return false; };			}		}		/*		var elm = this.targetElement;		do {			// If the target element or one of its offsetParents has fixed position,			// then use fixed positioning instead			//			// Note: In Firefox, getComputedStyle returns null in a hidden iframe,			// that's why we need to check if the returned style object is non-empty			var currStyle = jsc.getStyle(elm);			if (currStyle && currStyle.position.toLowerCase() === 'fixed') {				this.fixed = true;			}			if (elm !== this.targetElement) {				// attach onParentScroll so that we can recompute the picker position				// when one of the offsetParents is scrolled				if (!elm._jscEventsAttached) {					jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);					elm._jscEventsAttached = true;				}			}		} while ((elm = elm.offsetParent) && !jsc.isElementType(elm, 'body'));		*/		// valueElement		if (this.valueElement) {			if (jsc.isElementType(this.valueElement, 'input')) {				var updateField = function () {					THIS.fromString(THIS.valueElement.value, jsc.leaveValue);					jsc.dispatchFineChange(THIS);				};				jsc.attachEvent(this.valueElement, 'keyup', updateField);				jsc.attachEvent(this.valueElement, 'input', updateField);				jsc.attachEvent(this.valueElement, 'blur', blurValue);				this.valueElement.setAttribute('autocomplete', 'off');			}		}		// styleElement		if (this.styleElement) {			this.styleElement._jscOrigStyle = {				backgroundImage : this.styleElement.style.backgroundImage,				backgroundColor : this.styleElement.style.backgroundColor,				color : this.styleElement.style.color			};		}		if (this.value) {			// Try to set the color from the .value option and if unsuccessful,			// export the current color			this.fromString(this.value) || this.exportColor();		} else {			this.importColor();		}	}};//================================// Public properties and methods//================================// By default, search for all elements with class="jscolor" and install a color picker on them.//// You can change what class name will be looked for by setting the property jscolor.lookupClass// anywhere in your HTML document. To completely disable the automatic lookup, set it to null.//jsc.jscolor.lookupClass = 'jscolor';jsc.jscolor.installByClassName = function (className) {	var inputElms = document.getElementsByTagName('input');	var buttonElms = document.getElementsByTagName('button');	jsc.tryInstallOnElements(inputElms, className);	jsc.tryInstallOnElements(buttonElms, className);};jsc.register();return jsc.jscolor;})(); }
 |