/* This notice must be untouched at all times.

wz_jsgraphics.js    v. 3.05
The latest version is available at
http://www.walterzorn.com
or http://www.devira.com
or http://www.walterzorn.de

Copyright (c) 2002-2009 Walter Zorn. All rights reserved.
Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
Last modified: 2. 2. 2009

Performance optimizations for Internet Explorer
by Thomas Frank and John Holdsworth.
fillPolygon method implemented by Matthieu Haller.

High Performance JavaScript Graphics Library.
Provides methods
- to draw lines, rectangles, ellipses, polygons
	with specifiable line thickness,
- to fill rectangles, polygons, ellipses and arcs
- to draw text.
NOTE: Operations, functions and branching have rather been optimized
to efficiency and speed than to shortness of source code.

LICENSE: LGPL

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (LGPL) as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA,
or see http://www.gnu.org/copyleft/lesser.html
*/


var jg_ok, jg_ie, jg_fast, jg_dom, jg_moz;


function _chkDHTM(wnd, x, i)
// Under XUL, owner of 'document' must be specified explicitly
{
	x = wnd.document.body || null;
	jg_ie = x && typeof x.insertAdjacentHTML != "undefined" && wnd.document.createElement;
	jg_dom = (x && !jg_ie &&
		typeof x.appendChild != "undefined" &&
		typeof wnd.document.createRange != "undefined" &&
		typeof (i = wnd.document.createRange()).setStartBefore != "undefined" &&
		typeof i.createContextualFragment != "undefined");
	jg_fast = jg_ie && wnd.document.all && !wnd.opera;
	jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined";
	jg_ok = !!(jg_ie || jg_dom);
}

function _pntCnvDom()
{
	var x = this.wnd.document.createRange();
	x.setStartBefore(this.cnv);
	x = x.createContextualFragment(jg_fast? this._htmRpc() : this.htm);
	if(this.cnv) this.cnv.appendChild(x);
	this.htm = "";
}

function _pntCnvIe()
{
	if(this.cnv) this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this._htmRpc() : this.htm);
	this.htm = "";
}

function _pntDoc()
{
	this.wnd.document.write(jg_fast? this._htmRpc() : this.htm);
	this.htm = '';
}

function _pntN()
{
	;
}

function _mkDiv(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:' + w + 'px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background-color:' + this.color +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}

function _mkDivIe(x, y, w, h)
{
	this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';';
}

function _mkDivPrt(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'border-left:' + w + 'px solid ' + this.color + ';'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:0px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background-color:' + this.color +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}

var _regex =  /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
function _htmRpc()
{
	return this.htm.replace(
		_regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2px;top:$3px;width:$4px;height:$5px"></div>\n');
}

function _htmPrtRpc()
{
	return this.htm.replace(
		_regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2px;top:$3px;width:$4px;height:$5px;border-left:$4px solid $1"></div>\n');
}

function _mkLin(x1, y1, x2, y2)
{
	if(x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	if(dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while(dx > 0)
		{--dx;
			++x;
			if(p > 0)
			{
				this._mkDiv(ox, y, x-ox, 1);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this._mkDiv(ox, y, x2-ox+1, 1);
	}

	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if(y2 <= y1)
		{
			while(dy > 0)
			{--dy;
				if(p > 0)
				{
					this._mkDiv(x++, y, 1, oy-y+1);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this._mkDiv(x2, y2, 1, oy-y2+1);
		}
		else
		{
			while(dy > 0)
			{--dy;
				y += yIncr;
				if(p > 0)
				{
					this._mkDiv(x++, oy, 1, y-oy);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this._mkDiv(x2, oy, 1, y2-oy+1);
		}
	}
}

function _mkLin2D(x1, y1, x2, y2)
{
	if(x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	var s = this.stroke;
	if(dx >= dy)
	{
		if(dx > 0 && s-3 > 0)
		{
			var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.ceil(s/2);

		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while(dx > 0)
		{--dx;
			++x;
			if(p > 0)
			{
				this._mkDiv(ox, y, x-ox+ad, _s);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this._mkDiv(ox, y, x2-ox+ad+1, _s);
	}

	else
	{
		if(s-3 > 0)
		{
			var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.round(s/2);

		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if(y2 <= y1)
		{
			++ad;
			while(dy > 0)
			{--dy;
				if(p > 0)
				{
					this._mkDiv(x++, y, _s, oy-y+ad);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this._mkDiv(x2, y2, _s, oy-y2+ad);
		}
		else
		{
			while(dy > 0)
			{--dy;
				y += yIncr;
				if(p > 0)
				{
					this._mkDiv(x++, oy, _s, y-oy+ad);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this._mkDiv(x2, oy, _s, y2-oy+ad+1);
		}
	}
}

function _mkLinDott(x1, y1, x2, y2)
{
	if(x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1,
	drw = true;
	if(dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx;
		while(dx > 0)
		{--dx;
			if(drw) this._mkDiv(x, y, 1, 1);
			drw = !drw;
			if(p > 0)
			{
				y += yIncr;
				p += pru;
			}
			else p += pr;
			++x;
		}
	}
	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy;
		while(dy > 0)
		{--dy;
			if(drw) this._mkDiv(x, y, 1, 1);
			drw = !drw;
			y += yIncr;
			if(p > 0)
			{
				++x;
				p += pru;
			}
			else p += pr;
		}
	}
	if(drw) this._mkDiv(x, y, 1, 1);
}

function _mkOv(left, top, width, height)
{
	var a = (++width)>>1, b = (++height)>>1,
	wod = width&1, hod = height&1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	ox = 0, oy = b,
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
	st = (aa2>>1)*(1-(b<<1)) + bb2,
	tt = (bb2>>1) - aa2*((b<<1)-1),
	w, h;
	while(y > 0)
	{
		if(st < 0)
		{
			st += bb2*((x<<1)+3);
			tt += bb4*(++x);
		}
		else if(tt < 0)
		{
			st += bb2*((x<<1)+3) - aa4*(y-1);
			tt += bb4*(++x) - aa2*(((y--)<<1)-3);
			w = x-ox;
			h = oy-y;
			if((w&2) && (h&2))
			{
				this._mkOvQds(cx, cy, x-2, y+2, 1, 1, wod, hod);
				this._mkOvQds(cx, cy, x-1, y+1, 1, 1, wod, hod);
			}
			else this._mkOvQds(cx, cy, x-1, oy, w, h, wod, hod);
			ox = x;
			oy = y;
		}
		else
		{
			tt -= aa2*((y<<1)-3);
			st -= aa4*(--y);
		}
	}
	w = a-ox+1;
	h = (oy<<1)+hod;
	y = cy-oy;
	this._mkDiv(cx-a, y, w, h);
	this._mkDiv(cx+ox+wod-1, y, w, h);
}

function _mkOv2D(left, top, width, height)
{
	var s = this.stroke;
	width += s+1;
	height += s+1;
	var a = width>>1, b = height>>1,
	wod = width&1, hod = height&1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
	st = (aa2>>1)*(1-(b<<1)) + bb2,
	tt = (bb2>>1) - aa2*((b<<1)-1);

	if(s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0))
	{
		var ox = 0, oy = b,
		w, h,
		pxw;
		while(y > 0)
		{
			if(st < 0)
			{
				st += bb2*((x<<1)+3);
				tt += bb4*(++x);
			}
			else if(tt < 0)
			{
				st += bb2*((x<<1)+3) - aa4*(y-1);
				tt += bb4*(++x) - aa2*(((y--)<<1)-3);
				w = x-ox;
				h = oy-y;

				if(w-1)
				{
					pxw = w+1+(s&1);
					h = s;
				}
				else if(h-1)
				{
					pxw = s;
					h += 1+(s&1);
				}
				else pxw = h = s;
				this._mkOvQds(cx, cy, x-1, oy, pxw, h, wod, hod);
				ox = x;
				oy = y;
			}
			else
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
			}
		}
		this._mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
		this._mkDiv(cx+a+wod-s, cy-oy, s, (oy<<1)+hod);
	}

	else
	{
		var _a = (width-(s<<1))>>1,
		_b = (height-(s<<1))>>1,
		_x = 0, _y = _b,
		_aa2 = (_a*_a)<<1, _aa4 = _aa2<<1, _bb2 = (_b*_b)<<1, _bb4 = _bb2<<1,
		_st = (_aa2>>1)*(1-(_b<<1)) + _bb2,
		_tt = (_bb2>>1) - _aa2*((_b<<1)-1),

		pxl = new Array(),
		pxt = new Array(),
		_pxb = new Array();
		pxl[0] = 0;
		pxt[0] = b;
		_pxb[0] = _b-1;
		while(y > 0)
		{
			if(st < 0)
			{
				pxl[pxl.length] = x;
				pxt[pxt.length] = y;
				st += bb2*((x<<1)+3);
				tt += bb4*(++x);
			}
			else if(tt < 0)
			{
				pxl[pxl.length] = x;
				st += bb2*((x<<1)+3) - aa4*(y-1);
				tt += bb4*(++x) - aa2*(((y--)<<1)-3);
				pxt[pxt.length] = y;
			}
			else
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
			}

			if(_y > 0)
			{
				if(_st < 0)
				{
					_st += _bb2*((_x<<1)+3);
					_tt += _bb4*(++_x);
					_pxb[_pxb.length] = _y-1;
				}
				else if(_tt < 0)
				{
					_st += _bb2*((_x<<1)+3) - _aa4*(_y-1);
					_tt += _bb4*(++_x) - _aa2*(((_y--)<<1)-3);
					_pxb[_pxb.length] = _y-1;
				}
				else
				{
					_tt -= _aa2*((_y<<1)-3);
					_st -= _aa4*(--_y);
					_pxb[_pxb.length-1]--;
				}
			}
		}

		var ox = -wod, oy = b,
		_oy = _pxb[0],
		l = pxl.length,
		w, h;
		for(var i = 0; i < l; i++)
		{
			if(typeof _pxb[i] != "undefined")
			{
				if(_pxb[i] < _oy || pxt[i] < oy)
				{
					x = pxl[i];
					this._mkOvQds(cx, cy, x, oy, x-ox, oy-_oy, wod, hod);
					ox = x;
					oy = pxt[i];
					_oy = _pxb[i];
				}
			}
			else
			{
				x = pxl[i];
				this._mkDiv(cx-x, cy-oy, 1, (oy<<1)+hod);
				this._mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
				ox = x;
				oy = pxt[i];
			}
		}
		this._mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
		this._mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
	}
}

function _mkOvDott(left, top, width, height)
{
	var a = (++width)>>1, b = (++height)>>1,
	wod = width&1, hod = height&1, hodu = hod^1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
	st = (aa2>>1)*(1-(b<<1)) + bb2,
	tt = (bb2>>1) - aa2*((b<<1)-1),
	drw = true;
	while(y > 0)
	{
		if(st < 0)
		{
			st += bb2*((x<<1)+3);
			tt += bb4*(++x);
		}
		else if(tt < 0)
		{
			st += bb2*((x<<1)+3) - aa4*(y-1);
			tt += bb4*(++x) - aa2*(((y--)<<1)-3);
		}
		else
		{
			tt -= aa2*((y<<1)-3);
			st -= aa4*(--y);
		}
		if(drw && y >= hodu) this._mkOvQds(cx, cy, x, y, 1, 1, wod, hod);
		drw = !drw;
	}
}

function _mkRect(x, y, w, h)
{
	var s = this.stroke;
	this._mkDiv(x, y, w, s);
	this._mkDiv(x+w, y, s, h);
	this._mkDiv(x, y+h, w+s, s);
	this._mkDiv(x, y+s, s, h-s);
}

function _mkRectDott(x, y, w, h)
{
	this.drawLine(x, y, x+w, y);
	this.drawLine(x+w, y, x+w, y+h);
	this.drawLine(x, y+h, x+w, y+h);
	this.drawLine(x, y, x, y+h);
}

function jsgFont()
{
	this.PLAIN = 'font-weight:normal;';
	this.BOLD = 'font-weight:bold;';
	this.ITALIC = 'font-style:italic;';
	this.ITALIC_BOLD = this.ITALIC + this.BOLD;
	this.BOLD_ITALIC = this.ITALIC_BOLD;
}
var Font = new jsgFont();

function jsgStroke()
{
	this.DOTTED = -1;
}
var Stroke = new jsgStroke();

function jsGraphics(cnv, wnd)
{
	this.setColor = function(x)
	{
		this.color = x.toLowerCase();
	};

	this.setStroke = function(x)
	{
		this.stroke = x;
		if(!(x+1))
		{
			this.drawLine = _mkLinDott;
			this._mkOv = _mkOvDott;
			this.drawRect = _mkRectDott;
		}
		else if(x-1 > 0)
		{
			this.drawLine = _mkLin2D;
			this._mkOv = _mkOv2D;
			this.drawRect = _mkRect;
		}
		else
		{
			this.drawLine = _mkLin;
			this._mkOv = _mkOv;
			this.drawRect = _mkRect;
		}
	};

	this.setPrintable = function(arg)
	{
		this.printable = arg;
		if(jg_fast)
		{
			this._mkDiv = _mkDivIe;
			this._htmRpc = arg? _htmPrtRpc : _htmRpc;
		}
		else this._mkDiv = arg? _mkDivPrt : _mkDiv;
	};

	this.setFont = function(fam, sz, sty)
	{
		this.ftFam = fam;
		this.ftSz = sz;
		this.ftSty = sty || Font.PLAIN;
	};

	this.drawPolyline = this.drawPolyLine = function(x, y)
	{
		for (var i=x.length - 1; i;)
		{--i;
			this.drawLine(x[i], y[i], x[i+1], y[i+1]);
		}
	};

	this.fillRect = function(x, y, w, h)
	{
		this._mkDiv(x, y, w, h);
	};

	this.drawPolygon = function(x, y)
	{
		this.drawPolyline(x, y);
		this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
	};

	this.drawEllipse = this.drawOval = function(x, y, w, h)
	{
		this._mkOv(x, y, w, h);
	};

	this.fillEllipse = this.fillOval = function(left, top, w, h)
	{
		var a = w>>1, b = h>>1,
		wod = w&1, hod = h&1,
		cx = left+a, cy = top+b,
		x = 0, y = b, oy = b,
		aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
		st = (aa2>>1)*(1-(b<<1)) + bb2,
		tt = (bb2>>1) - aa2*((b<<1)-1),
		xl, dw, dh;
		if(w) while(y > 0)
		{
			if(st < 0)
			{
				st += bb2*((x<<1)+3);
				tt += bb4*(++x);
			}
			else if(tt < 0)
			{
				st += bb2*((x<<1)+3) - aa4*(y-1);
				xl = cx-x;
				dw = (x<<1)+wod;
				tt += bb4*(++x) - aa2*(((y--)<<1)-3);
				dh = oy-y;
				this._mkDiv(xl, cy-oy, dw, dh);
				this._mkDiv(xl, cy+y+hod, dw, dh);
				oy = y;
			}
			else
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
			}
		}
		this._mkDiv(cx-a, cy-oy, w, (oy<<1)+hod);
	};

	this.fillArc = function(iL, iT, iW, iH, fAngA, fAngZ)
	{
		var a = iW>>1, b = iH>>1,
		iOdds = (iW&1) | ((iH&1) << 16),
		cx = iL+a, cy = iT+b,
		x = 0, y = b, ox = x, oy = y,
		aa2 = (a*a)<<1, aa4 = aa2<<1, bb2 = (b*b)<<1, bb4 = bb2<<1,
		st = (aa2>>1)*(1-(b<<1)) + bb2,
		tt = (bb2>>1) - aa2*((b<<1)-1),
		// Vars for radial boundary lines
		xEndA, yEndA, xEndZ, yEndZ,
		iSects = (1 << (Math.floor((fAngA %= 360.0)/180.0) << 3))
				| (2 << (Math.floor((fAngZ %= 360.0)/180.0) << 3))
				| ((fAngA >= fAngZ) << 16),
		aBndA = new Array(b+1), aBndZ = new Array(b+1);
		
		// Set up radial boundary lines
		fAngA *= Math.PI/180.0;
		fAngZ *= Math.PI/180.0;
		xEndA = cx+Math.round(a*Math.cos(fAngA));
		yEndA = cy+Math.round(-b*Math.sin(fAngA));
		_mkLinVirt(aBndA, cx, cy, xEndA, yEndA);
		xEndZ = cx+Math.round(a*Math.cos(fAngZ));
		yEndZ = cy+Math.round(-b*Math.sin(fAngZ));
		_mkLinVirt(aBndZ, cx, cy, xEndZ, yEndZ);

		while(y > 0)
		{
			if(st < 0) // Advance x
			{
				st += bb2*((x<<1)+3);
				tt += bb4*(++x);
			}
			else if(tt < 0) // Advance x and y
			{
				st += bb2*((x<<1)+3) - aa4*(y-1);
				ox = x;
				tt += bb4*(++x) - aa2*(((y--)<<1)-3);
				this._mkArcDiv(ox, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects);
				oy = y;
			}
			else // Advance y
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
				if(y && (aBndA[y] != aBndA[y-1] || aBndZ[y] != aBndZ[y-1]))
				{
					this._mkArcDiv(x, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects);
					ox = x;
					oy = y;
				}
			}
		}
		this._mkArcDiv(x, 0, oy, cx, cy, iOdds, aBndA, aBndZ, iSects);
		if(iOdds >> 16) // Odd height
		{
			if(iSects >> 16) // Start-angle > end-angle
			{
				var xl = (yEndA <= cy || yEndZ > cy)? (cx - x) : cx;
				this._mkDiv(xl, cy, x + cx - xl + (iOdds & 0xffff), 1);
			}
			else if((iSects & 0x01) && yEndZ > cy)
				this._mkDiv(cx - x, cy, x, 1);
		}
	};

/* fillPolygon method, implemented by Matthieu Haller.
This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib.
C source of GD 1.8.4 found at http://www.boutell.com/gd/

THANKS to Kirsten Schulz for the polygon fixes!

The intersection finding technique of this code could be improved
by remembering the previous intertersection, and by using the slope.
That could help to adjust intersections to produce a nice
interior_extrema. */
	this.fillPolygon = function(array_x, array_y)
	{
		var i;
		var y;
		var miny, maxy;
		var x1, y1;
		var x2, y2;
		var ind1, ind2;
		var ints;

		var n = array_x.length;
		if(!n) return;

		miny = array_y[0];
		maxy = array_y[0];
		for(i = 1; i < n; i++)
		{
			if(array_y[i] < miny)
				miny = array_y[i];

			if(array_y[i] > maxy)
				maxy = array_y[i];
		}
		for(y = miny; y <= maxy; y++)
		{
			var polyInts = new Array();
			ints = 0;
			for(i = 0; i < n; i++)
			{
				if(!i)
				{
					ind1 = n-1;
					ind2 = 0;
				}
				else
				{
					ind1 = i-1;
					ind2 = i;
				}
				y1 = array_y[ind1];
				y2 = array_y[ind2];
				if(y1 < y2)
				{
					x1 = array_x[ind1];
					x2 = array_x[ind2];
				}
				else if(y1 > y2)
				{
					y2 = array_y[ind1];
					y1 = array_y[ind2];
					x2 = array_x[ind1];
					x1 = array_x[ind2];
				}
				else continue;

				 //  Modified 11. 2. 2004 Walter Zorn
				if((y >= y1) && (y < y2))
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);

				else if((y == maxy) && (y > y1) && (y <= y2))
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
			}
			polyInts.sort(_CompInt);
			for(i = 0; i < ints; i+=2)
				this._mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1);
		}
	};

	this.drawString = function(txt, x, y)
	{
		this.htm += '<div style="position:absolute;white-space:nowrap;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'font-family:' +  this.ftFam + ';'+
			'font-size:' + this.ftSz + ';'+
			'color:' + this.color + ';' + this.ftSty + '">'+
			txt +
			'<\/div>';
	};

/* drawStringRect() added by Rick Blommers.
Allows to specify the size of the text rectangle and to align the
text both horizontally (e.g. right) and vertically within that rectangle */
	this.drawStringRect = function(txt, x, y, width, halign)
	{
		this.htm += '<div style="position:absolute;overflow:hidden;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'width:'+width +'px;'+
			'text-align:'+halign+';'+
			'font-family:' +  this.ftFam + ';'+
			'font-size:' + this.ftSz + ';'+
			'color:' + this.color + ';' + this.ftSty + '">'+
			txt +
			'<\/div>';
	};

	this.drawImage = function(imgSrc, x, y, w, h, a)
	{
		this.htm += '<div style="position:absolute;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			// w (width) and h (height) arguments are now optional.
			// Added by Mahmut Keygubatli, 14.1.2008
			(w? ('width:' +  w + 'px;') : '') +
			(h? ('height:' + h + 'px;'):'')+'">'+
			'<img src="' + imgSrc +'"'+ (w ? (' width="' + w + '"'):'')+ (h ? (' height="' + h + '"'):'') + (a? (' '+a) : '') + '>'+
			'<\/div>';
	};

	this.clear = function()
	{
		this.htm = "";
		if(this.cnv) this.cnv.innerHTML = "";
	};

	this._mkOvQds = function(cx, cy, x, y, w, h, wod, hod)
	{
		var xl = cx - x, xr = cx + x + wod - w, yt = cy - y, yb = cy + y + hod - h;
		if(xr > xl+w)
		{
			this._mkDiv(xr, yt, w, h);
			this._mkDiv(xr, yb, w, h);
		}
		else
			w = xr - xl + w;
		this._mkDiv(xl, yt, w, h);
		this._mkDiv(xl, yb, w, h);
	};
	
	this._mkArcDiv = function(x, y, oy, cx, cy, iOdds, aBndA, aBndZ, iSects)
	{
		var xrDef = cx + x + (iOdds & 0xffff), y2, h = oy - y, xl, xr, w;

		if(!h) h = 1;
		x = cx - x;

		if(iSects & 0xff0000) // Start-angle > end-angle
		{
			y2 = cy - y - h;
			if(iSects & 0x00ff)
			{
				if(iSects & 0x02)
				{
					xl = Math.max(x, aBndZ[y]);
					w = xrDef - xl;
					if(w > 0) this._mkDiv(xl, y2, w, h);
				}
				if(iSects & 0x01)
				{
					xr = Math.min(xrDef, aBndA[y]);
					w = xr - x;
					if(w > 0) this._mkDiv(x, y2, w, h);
				}
			}
			else
				this._mkDiv(x, y2, xrDef - x, h);
			y2 = cy + y + (iOdds >> 16);
			if(iSects & 0xff00)
			{
				if(iSects & 0x0100)
				{
					xl = Math.max(x, aBndA[y]);
					w = xrDef - xl;
					if(w > 0) this._mkDiv(xl, y2, w, h);
				}
				if(iSects & 0x0200)
				{
					xr = Math.min(xrDef, aBndZ[y]);
					w = xr - x;
					if(w > 0) this._mkDiv(x, y2, w, h);
				}
			}
			else
				this._mkDiv(x, y2, xrDef - x, h);
		}
		else
		{
			if(iSects & 0x00ff)
			{
				if(iSects & 0x02)
					xl = Math.max(x, aBndZ[y]);
				else
					xl = x;
				if(iSects & 0x01)
					xr = Math.min(xrDef, aBndA[y]);
				else
					xr = xrDef;
				y2 = cy - y - h;
				w = xr - xl;
				if(w > 0) this._mkDiv(xl, y2, w, h);
			}
			if(iSects & 0xff00)
			{
				if(iSects & 0x0100)
					xl = Math.max(x, aBndA[y]);
				else
					xl = x;
				if(iSects & 0x0200)
					xr = Math.min(xrDef, aBndZ[y]);
				else
					xr = xrDef;
				y2 = cy + y + (iOdds >> 16);
				w = xr - xl;
				if(w > 0) this._mkDiv(xl, y2, w, h);
			}
		}
	};

	this.setStroke(1);
	this.setFont("verdana,geneva,helvetica,sans-serif", "12px", Font.PLAIN);
	this.color = "#000000";
	this.htm = "";
	this.wnd = wnd || window;

	if(!jg_ok) _chkDHTM(this.wnd);
	if(jg_ok)
	{
		if(cnv)
		{
			if(typeof(cnv) == "string")
				this.cont = document.all? (this.wnd.document.all[cnv] || null)
					: document.getElementById? (this.wnd.document.getElementById(cnv) || null)
					: null;
			else if(cnv == window.document)
				this.cont = document.getElementsByTagName("body")[0];
			// If cnv is a direct reference to a canvas DOM node
			// (option suggested by Andreas Luleich)
			else this.cont = cnv;
			// Create new canvas inside container DIV. Thus the drawing and clearing
			// methods won't interfere with the container's inner html.
			// Solution suggested by Vladimir.
			this.cnv = this.wnd.document.createElement("div");
			this.cnv.style.fontSize=0;
			this.cont.appendChild(this.cnv);
			this.paint = jg_dom? _pntCnvDom : _pntCnvIe;
		}
		else
			this.paint = _pntDoc;
	}
	else
		this.paint = _pntN;

	this.setPrintable(false);
}

function _mkLinVirt(aLin, x1, y1, x2, y2)
{
	var dx = Math.abs(x2-x1), dy = Math.abs(y2-y1),
	x = x1, y = y1,
	xIncr = (x1 > x2)? -1 : 1,
	yIncr = (y1 > y2)? -1 : 1,
	p,
	i = 0;
	if(dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1);
		p = pr-dx;
		while(dx > 0)
		{--dx;
			if(p > 0)    //  Increment y
			{
				aLin[i++] = x;
				y += yIncr;
				p += pru;
			}
			else p += pr;
			x += xIncr;
		}
	}
	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1);
		p = pr-dy;
		while(dy > 0)
		{--dy;
			y += yIncr;
			aLin[i++] = x;
			if(p > 0)    //  Increment x
			{
				x += xIncr;
				p += pru;
			}
			else p += pr;
		}
	}
	for(var len = aLin.length, i = len-i; i;)
		aLin[len-(i--)] = x;
};

function _CompInt(x, y)
{
	return(x - y);
}

;
Drupal.locale = { 'pluralFormula': function ($n) { return Number(($n!=1)); }, 'strings': {"":{"Disabled":"Deaktiviert","Edit":"Bearbeiten","Configure":"Konfigurieren","Show":"Anzeigen","Select all rows in this table":"Alle Zeilen dieser Tabelle ausw\u00e4hlen","Deselect all rows in this table":"Alle Zeilen dieser Tabelle abw\u00e4hlen","Not published":"Nicht ver\u00f6ffentlicht","Please wait...":"Bitte warten...","Hide":"Ausblenden","Loading":"Laden","By @name on @date":"Von @name am @date","By @name":"Von @name","Not in menu":"Nicht im Men\u00fc","Alias: @alias":"Alias: @alias","No alias":"Kein Alias","New revision":"Neue Version","Drag to re-order":"Ziehen um die Reihenfolge zu \u00e4ndern","Changes made in this table will not be saved until the form is submitted.":"\u00c4nderungen in dieser Tabelle werden nicht gespeichert, bis dieses Formular abgesendet wurde.","Show shortcuts":"Tastaturkombinationen anzeigen","This permission is inherited from the authenticated user role.":"Diese Berechtigung wird von der Rolle \u201aAuthentifizierte Benutzer\u2018 ererbt.","No revision":"Keine Version","Requires a title":"Ben\u00f6tigt einen Titel","(active tab)":"(aktiver Reiter)","An AJAX HTTP error occurred.":"Ein AJAX-HTTP-Fehler ist aufgetreten","HTTP Result Code: !status":"HTTP-R\u00fcckgabe-Code: !status","An AJAX HTTP request terminated abnormally.":"Eine AJAX-Anfrage ist abnormal beendet worden.","Debugging information follows.":"Im Folgenden finden Sie Debugging-Informationen.","Path: !uri":"Pfad: !uri","StatusText: !statusText":"Statustext: !statusText","ResponseText: !responseText":"Antworttext: !responseText","ReadyState: !readyState":"ReadyState: !readyState","Hide summary":"Zusammenfassung verbergen","Edit summary":"Zusammenfassung bearbeiten","Don't display post information":"Beitragsinformationen nicht anzeigen","@title dialog":"@title Dialog","The selected file %filename cannot be uploaded. Only files with the following extensions are allowed: %extensions.":"Die ausgew\u00e4hlte Datei %filename konnte nicht gespeichert werden. Nur Dateien mit den folgenden Erweiterungen sind zul\u00e4ssig: %extensions.","Re-order rows by numerical weight instead of dragging.":"Zeilen mittels numerischer Gewichtung ordnen statt mit Drag-and-Drop","Show row weights":"Zeilenreihenfolge anzeigen","Hide row weights":"Zeilenreihenfolge ausblenden","Autocomplete popup":"Popup zur automatischen Vervollst\u00e4ndigung","Searching for matches...":"Suche \u2026","Hide shortcuts":"Shortcuts ausblenden"}} };;
/**
 * cvi_map_lib.js 2.4 (14-Aug-2010) (c) by Christian Effenberger 
 * All Rights Reserved. Source: mapper.netzgesta.de
 * Distributed under Netzgestade Software License Agreement.
 * This license permits free of charge use on non-commercial 
 * and private web sites only under special conditions. 
 * Read more at... http://www.netzgesta.de/cvi/LICENSE.html	
 * Commercial licenses available via... cvi[at]netzgesta[dot]de	
 * syntax:
	cvi_map.defaultRadius 		= 0;			//INT  0-100 (px radius)
	cvi_map.defaultOpacity 		= 33;  			//INT  0-100 (% opacity)
	cvi_map.defaultBordercolor 	= '#0000ff'; 	//STR '#000000'-'#ffffff'
	cvi_map.defaultAreacolor 	= '#000000'; 	//STR '#000000'-'#ffffff'
	cvi_map.defaultNoborder 	= false; 		//BOOLEAN
	cvi_map.defaultNofade 		= false; 		//BOOLEAN
	cvi_map.defaultShowcoords 	= false; 		//BOOLEAN
	cvi_map.defaultImgsrc		= ''; 			//STR (path&file)
	cvi_map.defaultMapid		= ''; 			//STR (id)
	cvi_map.remove( image );
	cvi_map.add( image, options );
	cvi_map.modify( image, options );
	cvi_map.add( image, { radius: value, opacity: value, bordercolor: value, areacolor: value, noborder: value,  nofade: value, showcoords: value } );
	cvi_map.modify( image, { radius: value, opacity: value, bordercolor: value, areacolor: value, noborder: value,  nofade: value, showcoords: value, imgsrc: value, mapid: value} );
 *
 showCoords(map_name,area_id,xpos,ypos,width,height);
 extAreaOver(image_id,area_id); 
 extAreaOut(image_id,area_id); 
 *
**/

var canvascheck = document.createElement('canvas');
var isIE = window.navigator.systemLanguage&&(!document.documentMode||document.documentMode<9)?1:0;
var isI8 = isIE&&document.documentMode?1:0;
var isVM = isIE&&document.namespaces?1:0; 
var isCV = canvascheck.getContext?1:0;
var isJG = 0, jg = new Array();

function showCoords(map,ele,x,y,w,h) {}

function getClassValue(classes,string){
	var temp = 0; var pos = string.length;
	for (var j=0;j<classes.length;j++) {
		if (classes[j].indexOf(string) == 0) {
			temp = Math.min(classes[j].substring(pos),100);
			break;
		}
	}
	return Math.max(0,temp);
}
function getClassRGBColor(classes,string,color){
	var temp, val = color, pos = string.length;
	for (var j=0;j<classes.length;j++) {
		if (classes[j].indexOf(string) == 0) {
			temp = classes[j].substring(pos);
			val = temp.toLowerCase();
			break;
		}
	}
	if(!val.match(/^[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i)) {val = color||'000000'; }
	if(!isCV) {return val; }else {
		function hex2dec(hex){return(Math.max(0,Math.min(parseInt(hex,16),255)));}
		var cr=hex2dec(val.substr(0,2)),cg=hex2dec(val.substr(2,2)),cb=hex2dec(val.substr(4,2));
		return cr+','+cg+','+cb;
	}
}
function performRGBColor(val,color){
	if(!val.match(/^#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]$/i)) {val = color||'#000000'; }
	if(!isCV) {return val.substr(1,6); }else {
		function hex2dec(hex){return(Math.max(0,Math.min(parseInt(hex,16),255)));}
		var cr=hex2dec(val.substr(1,2)),cg=hex2dec(val.substr(3,2)),cb=hex2dec(val.substr(5,2));
		return cr+','+cg+','+cb;
	}
}			
function getClassAttribute(classes,string){
	var temp = 0; var pos = string.length;
	for (var j=0;j<classes.length;j++) {
		if (classes[j].indexOf(string) == 0) {
			temp = 1; break;
		}
	}
	return temp;
}
function fadeCanvas(id,opac) {
	var obj = document.getElementById(id);
    if(obj.fading==1 && opac<=100) {
		obj.style.opacity = opac/100; opac += 10;
		window.setTimeout("fadeCanvas('"+id+"',"+opac+")",10);
	}
}
function setAreaOver(obj,id,bd,co,op,nb,f,z) {
	var a, i, j, d, c, o, b, n, l, r, v, u, x, y, p, context, k = 0, t = '', r = obj.getAttribute('rel'), canvas = document.getElementById(id);
	if(r!=null) {d = r.split(","); v = d.unshift(obj.id); }else {d = new Array(obj.id); }
	function setAttr() {
		if(l.indexOf('forcegroup')!=-1) {k = getClassAttribute(u,"forcegroup");}else {k=0;}
		if(l.indexOf('iopacity')!=-1) {o = getClassValue(u,"iopacity")/100;}else {o=op;}	
		if(l.indexOf('iborder')!=-1) {b = getClassRGBColor(u,"iborder",bd);}else {b=bd;}
		if(l.indexOf('icolor')!=-1) {c = getClassRGBColor(u,"icolor",co);}else {c=co;}
		if(l.indexOf('noborder')!=-1) {n = getClassAttribute(u,"noborder");}else {n=nb;}
	}	
	if(isVM) {
		for(a=0;a<d.length;a++) {
			obj = document.getElementById(d[a]); p = '', l = obj.className, u = l.split(" "), v = obj.coords.split(",");
			if(k==0) {setAttr();} 
			if(obj.shape.toLowerCase()=='rect') {
				t += '<v:rect unselectable="on" strokeweight="1" filled="t" stroked="'+(n<1?"t":"f")+'" strokecolor="#'+b+'" style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+parseInt(v[0])+'px;top:'+parseInt(v[1])+'px;width:'+parseInt(v[2]-v[0])+'px;height:'+parseInt(v[3]-v[1])+'px;"><v:fill color="#'+c+'" opacity="'+o+'" /></v:rect>';
			}else if(obj.shape.toLowerCase()=='circle') {
				t += '<v:oval unselectable="on" strokeweight="1" filled="t" stroked="'+(n<1?"t":"f")+'" strokecolor="#'+b+'" style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+parseInt(v[0]-v[2])+'px;top:'+parseInt(v[1]-v[2])+'px;width:'+(parseInt(v[2])*2)+'px;height:'+(parseInt(v[2])*2)+'px;"><v:fill color="#'+c+'" opacity="'+o+'" /></v:oval>';
			}else {
				for(j=2;j<v.length;j+=2) {p += parseInt(v[j])+','+parseInt(v[j+1])+',';}
				t += '<v:shape unselectable="on" strokeweight="1" filled="t" stroked="'+(n<1?"t":"f")+'" strokecolor="#'+b+'" coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+parseInt(v[0])+','+parseInt(v[1])+' l '+p+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"><v:fill color="#'+c+'" opacity="'+o+'" /></v:shape>'; 
			}
		} canvas.innerHTML = t;
	}else if(isCV) {
		if(f<1) {canvas.fading = 0; canvas.style.opacity = 0;}
		context = canvas.getContext("2d");
		for(a=0;a<d.length;a++) {
			obj = document.getElementById(d[a]); l = obj.className, u = l.split(" "), v = obj.coords.split(",");
			if(k==0) {setAttr();} context.beginPath();
			if(obj.shape.toLowerCase()=='rect') {
				context.rect(0.5+parseInt(v[0]),0.5+parseInt(v[1]),parseInt(v[2]-v[0]),parseInt(v[3]-v[1])); context.closePath();
			}else if(obj.shape.toLowerCase()=='circle') {
				context.arc(0.5+parseInt(v[0]),0.5+parseInt(v[1]),parseInt(v[2]),0,(Math.PI/180)*360,false);		
			}else {
				context.moveTo(parseInt(v[0]),parseInt(v[1])); for(j=2;j<v.length;j+=2) {context.lineTo(parseInt(v[j]),parseInt(v[j+1]));} context.closePath();
			} 
			context.fillStyle = 'rgba('+c+','+o+')'; context.strokeStyle = 'rgba('+b+',1)'; context.fill(); if(n<1) {context.stroke();}
		} if(f<1) {canvas.fading = 1; fadeCanvas(id,0);}
	}else {
		o = op; l = obj.className; u = l.split(" ");
		if(l.indexOf('forcegroup')!=-1) { k = getClassAttribute(u,"forcegroup");
		if(k!=0) {if(l.indexOf('iopacity')!=-1) {o = getClassValue(u,"iopacity")/100; k=0;}}}
		if(isIE) {canvas.style.filter = "Alpha(opacity="+(o*100)+")";}else {canvas.style.opacity = o; canvas.style.MozOpacity = o; canvas.style.KhtmlOpacity = o;}
		for(a=0;a<d.length;a++) {
			obj = document.getElementById(d[a]); l = obj.className, u = l.split(" "), v = obj.coords.split(",");
			if(k==0) {
				if(l.indexOf('forcegroup')!=-1) {k = getClassAttribute(u,"forcegroup");}else {k=0;}
				if(l.indexOf('icolor')!=-1) {c = getClassRGBColor(u,"icolor",co);}else {c=co;}
			} jg[z].setColor("#"+c);
			if(obj.shape.toLowerCase()=='rect') {
				jg[z].fillRect(parseInt(v[0]),parseInt(v[1]),parseInt(v[2]-v[0])+1,parseInt(v[3]-v[1])+1);
			}else if(obj.shape.toLowerCase()=='circle') {
				jg[z].fillEllipse(parseInt(v[0]-v[2]),parseInt(v[1]-v[2]),parseInt(v[2])*2+1,parseInt(v[2])*2+1);
			}else {x = new Array(); y = new Array(); i = 0; for(j=0;j<v.length;j+=2) {x[i] = parseInt(v[j]); y[i] = parseInt(v[j+1]); i++;} jg[z].fillPolygon(x,y);
			} jg[z].paint();
		}
	}
}
function setAreaOut(obj,id,f,z) {
	var canvas = document.getElementById(id);
	if(isVM) {canvas.innerHTML = '';}else 
	if(isJG) {jg[z].clear();}else if(isCV) {
		var context = canvas.getContext("2d");
		context.clearRect(0,0,canvas.width,canvas.height);
	}
}
function extAreaOver(image,area) {
	var img = document.getElementById(image);
	var obj = document.getElementById(area);
	var cav = document.getElementById(img.canvasid);
	var bc = performRGBColor(img.options['bordercolor'],'#0000ff');
	var ac = performRGBColor(img.options['areacolor'],'#000000');
	var op = img.options['opacity']/100;	
	if(img && obj && cav) setAreaOver(obj,img.canvasid,bc,ac,op,img.options['noborder'],img.options['nofade'],img.jg);
} 
function extAreaOut(image,area) {
	var img = document.getElementById(image);
	var obj = document.getElementById(area);
	var cav = document.getElementById(img.canvasid);
	if(img && obj && cav) setAreaOut(obj,img.canvasid,img.options['nofade'],img.jg);
} 
function getCoords(e,n,a,i,x,y,w,h,pw,ph) {
	var t, o, ox, oy, ex, ey, cx, cy, px=0, py=0;
	if (!e) {e = window.event; }
	if (e.pageX || e.pageY) {px = e.pageX; py = e.pageY;}
	ex = e.clientX; ey = e.clientY;
	if(self.pageXOffset||self.pageYOffset) {
		ox = self.pageXOffset; if(ox>0 && px==ex) {ex -= ox; }
		oy = self.pageYOffset; if(oy>0 && py==ey) {ey -= oy; }
	}else if(document.documentElement) {
		ox = document.documentElement.scrollLeft; 
		oy = document.documentElement.scrollTop;
	}else if(document.body) {
		ox = document.body.scrollLeft; oy = document.body.scrollTop;
	} 
	if(document.body.scrollHeight!=ph||document.body.scrollWidth!=pw) {
		var o = document.getElementById(i);
		var t = findPosXY(o); x = t.x; y = t.y;
	}
	cx = Math.min(Math.max(ex+ox-x,0),w); 
	cy = Math.min(Math.max(ey+oy-y,0),h);
	showCoords(n,a,cx,cy,w,h);
}
function findPosXY(ele) {
	var t; var d = {x:ele.offsetLeft, y:ele.offsetTop };
	if(ele.offsetParent) { t = findPosXY(ele.offsetParent); d.x += t.x; d.y += t.y;}
	return d;
}
function roundedRect(ctx,x,y,width,height,radius,nopath){
	if (!nopath) ctx.beginPath();
	ctx.moveTo(x,y+radius);
	ctx.lineTo(x,y+height-radius);
	ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
	ctx.lineTo(x+width-radius,y+height);
	ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
	ctx.lineTo(x+width,y+radius);
	ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
	ctx.lineTo(x+radius,y);
	ctx.quadraticCurveTo(x,y,x,y+radius);
	if (!nopath) ctx.closePath();
}
function getRadius(radius,width,height){
	var part = (Math.min(width,height)/100);
	radius = Math.max(Math.min(100,radius/part),0);
	return radius + '%';
}

var cvi_map = {
	defaultRadius : 0,
	defaultOpacity : 33,
	defaultBordercolor : '#0000ff',
	defaultAreacolor : '#000000',
	defaultNoborder : false,
	defaultNofade : false,
	defaultShowcoords : false,
	defaultImgsrc : '',
	defaultMapid : '',
	defaultDelayed : false,
	add: function(image, options) {
		var map, mapname = image.useMap.split("#");
		if(mapname[1]!=''&&mapname[1].length>=1) {map = document.getElementsByName(mapname[1])[0];}
		if(image.tagName.toUpperCase() == "IMG" && map) {
			var defopts = { "radius" : cvi_map.defaultRadius, "opacity" : cvi_map.defaultOpacity, "bordercolor" : cvi_map.defaultBordercolor, "areacolor" : cvi_map.defaultAreacolor, "noborder" : cvi_map.defaultNoborder, "nofade" : cvi_map.defaultNofade, "showcoords" : cvi_map.defaultShowcoords, "imgsrc" : cvi_map.defaultImgsrc, "mapid" : cvi_map.defaultMapid, "delayed" : cvi_map.defaultDelayed };
			if(options) {
				for(var i in defopts) { if(!options[i]) { options[i] = defopts[i]; }}
			}else {
				options = defopts;
			}
			var imageWidth  = ('iwidth'  in options) ? parseInt(options.iwidth)  : image.width;
			var imageHeight = ('iheight' in options) ? parseInt(options.iheight) : image.height;
			try {
				var object = image.parentNode;
				object.style.position = (object.style.position=='static'||object.style.position==''?'relative':object.style.position);
				object.style.height = image.height+'px';
				object.style.width = image.width+'px';
				object.style.padding = 0+'px';
				object.style.MozUserSelect = "none";
				object.style.KhtmlUserSelect = "none"; 
				object.unselectable = "on";
				var blind, bgrnd, canvas; image.jg = 0;
				if(isVM) {
					if(document.namespaces['v']==null) {
						var e=["shape","shapetype","group","background","path","formulas","handles","fill","stroke","shadow","textbox","textpath","imagedata","line","polyline","curve","roundrect","oval","rect","arc","image"],s=document.createStyleSheet(); 
						for(var i=0; i<e.length; i++) {s.addRule("v\\:"+e[i],"behavior: url(#default#VML);");} document.namespaces.add("v","urn:schemas-microsoft-com:vml");
					}
					canvas = document.createElement(['<var style="zoom:1;overflow:hidden;display:block;width:'+image.width+'px;height:'+image.height+'px;padding:0;">'].join(''));
					bgrnd = document.createElement(['<var style="zoom:1;overflow:hidden;display:block;width:'+image.width+'px;height:'+image.height+'px;padding:0;">'].join(''));
					dummy = document.createElement(['<var style="zoom:1;overflow:hidden;display:block;width:'+image.width+'px;height:'+image.height+'px;padding:0;">'].join(''));// NEW
				}else if(isCV) {
					canvas = document.createElement('canvas');
					bgrnd = document.createElement('canvas');
				}else {
					canvas = document.createElement('div');
					bgrnd = document.createElement('img'); 
					bgrnd.src = image.src;
					if(typeof(window['jsGraphics']) !== 'undefined') {
						image.jg = parseInt(jg.length); 
						jg[image.jg] = new jsGraphics(canvas); isJG = 1;
					}
				}
				canvas.id = image.id+'_canvas';
				canvas.style.height = image.height+'px';
				canvas.style.width = image.width+'px';
				canvas.height = image.height;
				canvas.width = image.width;
				canvas.left = 0; canvas.top = 0;
				canvas.style.position = 'absolute';
				canvas.style.left = 0+'px';
				canvas.style.top = 0+'px';
				canvas.fading = 0;
				image.className = '';
				image.style.cssText = '';
				image.left = 0; image.top = 0;
				image.style.position = 'absolute';
				image.style.height = image.height+'px';
				image.style.width = image.width+'px';
				image.style.left = 0+'px';
				image.style.top = 0+'px';
				image.style.MozUserSelect = "none";
				image.style.KhtmlUserSelect = "none"; 
				image.unselectable = "on";
				image.options = options;
				image.canvasid = image.id+'_canvas';
				image.dummyid = image.id+'_dummy'; // NEW
				image.bgrndid = image.id+'_image';
				image.blindid = map.name+'_blind';
				image.mapname = map.name;
				image.areas = map.innerHTML;
				image.active = false;
				if(isIE) {image.style.filter = "Alpha(opacity=0)";}else {image.style.opacity = 0; image.style.MozOpacity = 0; image.style.KhtmlOpacity = 0;}
				bgrnd.id = image.bgrndid;
				bgrnd.left = 0; bgrnd.top = 0;
				bgrnd.style.position = 'absolute';
				bgrnd.style.height = image.height+'px';
				bgrnd.style.width = image.width+'px';
				bgrnd.style.left = 0+'px';
				bgrnd.style.top = 0+'px';
				bgrnd.height = image.height; 
				bgrnd.width = image.width;				
				blind = document.createElement('div');
				blind.id = image.blindid;
				blind.className = "blind_area";
				blind.left = 0; blind.top = 0;
				blind.style.position = 'absolute';
				blind.style.height = image.height+'px';
				blind.style.width = image.width+'px';
				blind.style.left = 0+'px';
				blind.style.top = 0+'px';
				blind.innerHTML = " ";
				object.insertBefore(canvas,image);
				object.insertBefore(bgrnd,canvas);
				object.insertBefore(blind,image);
				cvi_map.modify(image, options);
			} catch (e) {}
		}
	},

	modify: function(image, options) {
		try {		
			var radius = (typeof options['radius']=='number'?options['radius']:image.options['radius']); image.options['radius']=radius;
			var opacity = (typeof options['opacity']=='number'?options['opacity']:image.options['opacity']); image.options['opacity']=opacity;
			var bcolor = (typeof options['bordercolor']=='string'?options['bordercolor']:image.options['bordercolor']); image.options['bordercolor']=bcolor;
			var acolor = (typeof options['areacolor']=='string'?options['areacolor']:image.options['areacolor']); image.options['areacolor']=acolor;
			var noborder = (typeof options['noborder']=='boolean'?options['noborder']:image.options['noborder']); image.options['noborder']=noborder;
			var nofade = (typeof options['nofade']=='boolean'?options['nofade']:image.options['nofade']); image.options['nofade']=nofade;
			var showcoords = (typeof options['showcoords']=='boolean'?options['showcoords']:image.options['showcoords']); image.options['showcoords']=showcoords;
			var delayed = (typeof options['delayed']=='boolean'?options['delayed']:image.options['delayed']); image.options['delayed']=delayed;
			var imgsrc = (typeof options['imgsrc']=='string'?options['imgsrc']:image.options['imgsrc']); image.options['imgsrc']=imgsrc;
			var mapid = (typeof options['mapid']=='string'?options['mapid']:image.options['mapid']); image.options['mapid']=mapid;
			var context, func, ih = image.height, iw = image.width; 
			var radius = parseInt(Math.min(Math.min(iw/4,ih/4),radius));
			var opacity = opacity==0?0.33:opacity/100; 
			var bcolor = performRGBColor(bcolor,'#0000ff');
			var acolor = performRGBColor(acolor,'#000000');	
			var canvas = document.getElementById(image.canvasid);
			var dummy = document.getElementById(image.dummyid);
			var bgrnd = document.getElementById(image.bgrndid);
			var map = document.getElementsByName(image.mapname)[0];
			var opac = 100;
			function replace() {
				if(mapid!='') {
					var tmp = document.getElementById(mapid);
					if(tmp) {map.innerHTML = tmp.innerHTML;}
				}else {
					map.innerHTML = image.areas; 
				}
			}
			function prepare() {
				if(!delayed) {replace();}
				for(var j=0;j<map.areas.length;j++) {
					if(map.areas[j].shape.match(/(rect|poly|circle)/i)) {
						if(window.opera||map.areas[j].coords!='') {
							if(map.areas[j].id=='') {map.areas[j].id = image.mapname+'_'+j;}
							if(isVM||isIE) {
								func=map.areas[j].onmouseover; if(func!=null) {tmp=String(func); func=(tmp.indexOf('function')>=0?tmp.match(/\{([^}]+)\}/):tmp); func=(typeof(func)=='object'?func[1]:func);}
								map.areas[j].onmouseover = new Function('setAreaOver(this,"'+canvas.id+'","'+bcolor+'","'+acolor+'",'+opacity+','+noborder+','+nofade+','+image.jg+');'+func); 
								func=map.areas[j].onmouseout; if(func!=null) {tmp=String(func); func=(tmp.indexOf('function')>=0?tmp.match(/\{([^}]+)\}/):tmp); func=(typeof(func)=='object'?func[1]:func);}
								map.areas[j].onmouseout = new Function('setAreaOut(this,"'+canvas.id+'",'+nofade+','+image.jg+');'+func); 
							}else {
								func = map.areas[j].getAttribute("onmouseover"); map.areas[j].setAttribute("onmouseover","setAreaOver(this,'"+canvas.id+"','"+bcolor+"','"+acolor+"',"+opacity+","+noborder+","+nofade+","+image.jg+");"+func); 
								func = map.areas[j].getAttribute("onmouseout"); map.areas[j].setAttribute("onmouseout","setAreaOut(this,'"+canvas.id+"',"+nofade+","+image.jg+");"+func); 
							}
						}
					}
				}
				if(showcoords) {
					var atr, t = findPosXY(image), ph = document.body.scrollHeight, pw = document.body.scrollWidth;
					if(isVM||isIE) {
						image.onmousemove = new Function('getCoords(event,"'+image.mapname+'",0,"'+image.id+'",'+t.x+','+t.y+','+iw+','+ih+','+pw+','+ph+');'+image.movefunc); 
					}else {
						image.setAttribute("onmousemove","getCoords(event,'"+image.mapname+"',0,'"+image.id+"',"+t.x+","+t.y+","+iw+","+ih+","+pw+","+ph+");"+image.movefunc); 
					}
					if(map.length>0) {
						for(var j=0;j<map.areas.length;j++) {
							if(map.areas[j].shape.match(/(rect|poly|circle)/i)) { 
								if(window.opera||map.areas[j].coords!='') {
									atr = map.areas[j].id;
									if(isVM||isIE) {
										func=map.areas[j].onmousemove; if(func!=null) {tmp=String(func); func=(tmp.indexOf('function')>=0?tmp.match(/\{([^}]+)\}/):tmp); func=(typeof(func)=='object'?func[1]:func);}
										map.areas[j].onmousemove = new Function('getCoords(event,"'+image.mapname+'","'+atr+'","'+image.id+'",'+t.x+','+t.y+','+iw+','+ih+','+pw+','+ph+');'+func); 
									}else {
										func = map.areas[j].getAttribute("onmousemove"); map.areas[j].setAttribute("onmousemove","getCoords(event,'"+image.mapname+"','"+atr+"','"+image.id+"',"+t.x+","+t.y+","+iw+","+ih+","+pw+","+ph+");"+func); 
									}
								}
							}
						}
					}
				}
			}
			if(canvas && bgrnd && map) {
				if(isCV) {
					context = canvas.getContext("2d");
					context.clearRect(0,0,canvas.width,canvas.height);
				}else if(isVM) {
					canvas.innerHTML = '';
				}else {
					if(isIE) {canvas.style.filter = "Alpha(opacity="+(opacity*100)+")";}else { canvas.style.opacity = opacity; canvas.style.MozOpacity = opacity; canvas.style.KhtmlOpacity = opacity;} 
					if(isJG) {jg[image.jg].clear();}
				}
				if(delayed) {replace();	}
				if(isCV) {
					if(imgsrc!='') {
						var img = new Image();
						img.onload = function() {
							context = bgrnd.getContext("2d");
							context.clearRect(0,0,bgrnd.width,bgrnd.height);
							context.save();
							if(radius>0) {
								roundedRect(context,0,0,bgrnd.width,bgrnd.height,radius);
								context.clip();
							}
							context.fillStyle = 'rgba(0,0,0,0)';
							context.fillRect(0,0,bgrnd.width,bgrnd.height);
							context.drawImage(img,0,0,bgrnd.width,bgrnd.height);
							context.restore();
							prepare();
						}
						img.src = imgsrc;
					}else {	
						context = bgrnd.getContext("2d");
						context.clearRect(0,0,bgrnd.width,bgrnd.height);
						context.save();
						if(radius>0) {
							roundedRect(context,0,0,bgrnd.width,bgrnd.height,radius);
							context.clip();
						}
						context.fillStyle = 'rgba(0,0,0,0)';
						context.fillRect(0,0,bgrnd.width,bgrnd.height);
						context.drawImage(image,0,0,bgrnd.width,bgrnd.height);
						context.restore();
						prepare();
					}
				}else if(isVM) {
					if(radius>0) {radius = getRadius(radius,bgrnd.width,bgrnd.height);}	
					bgrnd.innerHTML = '<v:roundrect arcsize="'+radius+'" strokeweight="0" filled="t" stroked="f" fillcolor="#ffffff" style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:0px;top:0px;width:'+bgrnd.width+'px;height:'+bgrnd.height+'px;"><v:fill src="'+(imgsrc!=''?imgsrc:image.src)+'" type="frame" /></v:roundrect>';
					prepare();
				}else {
					bgrnd.src = imgsrc!=''?imgsrc:image.src;
					prepare();
				} image.active = true;
				if(isVM||isIE) {
					func = image.onmousemove; if(func!=null) {tmp=String(func); func=(tmp.indexOf('function')>=0?tmp.match(/\{([^}]+)\}/):tmp); func=(typeof(func)=='object'?func[1]:func);} image.movefunc = func;
				}else {
					image.movefunc = image.getAttribute("onmousemove"); 
				}
			}
		} catch (e) {}
	},

	remove : function(image) {
		var ele, object = image.parentNode;
		if(image.active) {
			if(isIE) { image.style.filter = "Alpha(opacity=100)";}else {image.style.opacity = 100; image.style.MozOpacity = 100; image.style.KhtmlOpacity = 100;}
			ele = document.getElementsByName(image.mapname)[0]; ele.innerHTML = image.areas; image.active = false; image.areas = ''; 	
			if(isVM||isIE) {image.onmousemove = image.movefunc;}else {image.setAttribute("onmousemove",image.movefunc);}
			ele = document.getElementById(image.canvasid); if(ele) {object.removeChild(ele);}
			ele = document.getElementById(image.blindid); if(ele) {object.removeChild(ele);}
			ele = document.getElementById(image.bgrndid); if(ele) {object.removeChild(ele);}
		}
	}
};
/*
* Copyright (C) 2009 Joel Sutherland
* Licenced under the MIT license
* http://www.newmediacampaigns.com/page/jcaption-a-jquery-plugin-for-simple-image-captions
*/
(function($) {
	$.fn.jcaption = function(settings) {
		settings = $.extend({
			wrapperElement: 'div',
			wrapperClass: 'caption',
			captionElement: 'p',
			imageAttr: 'alt',
			requireText: true,
			copyStyle: false,
			removeStyle: true,
			removeAlign: true,
			copyAlignmentToClass: false,
			copyFloatToClass: true,
			autoWidth: true,
			animate: false,
			show: {opacity: 'show'},
			showDuration: 200,
			hide: {opacity: 'hide'},
			hideDuration: 200	
		}, settings);

		return $(this).each(function(){
			//Only add the caption after the image has been loaded.  This makes sure we can know the width of the caption.
			
			$(this).bind('load', function(){
				
				//Make sure the captioning isn't applied twice when the IE fix at the bottom is applied
				if($(this).data('loaded')) return false;
				$(this).data('loaded', true);
			
				//Shorthand for the image we will be applying the caption to
				var image = $(this);
				
				//Only create captions if there is content for the caption
				if(image.attr(settings.imageAttr).length > 0 || !settings.requireText){
					
					//Wrap the image with the caption div
					image.wrap("<" + settings.wrapperElement + " class='" + settings.wrapperClass + "'></" + settings.wrapperElement + ">");
					
					//Save Image Float
					var imageFloat = image.css('float')
					
					//Save Image Style
					var imageStyle = image.attr('style');
					if(settings.removeStyle) image.removeAttr('style');
					
					//Save Image Align
					var imageAlign = image.attr('align');
					if(settings.removeAlign) image.removeAttr('align');
					
					//Put Caption in the Wrapper Div
					var div = $(this).parent().append('<' + settings.captionElement + '>' + image.attr(settings.imageAttr) + '</' + settings.captionElement + '>');
					
					if(settings.animate){
						$(this).next().hide();
						$(this).parent().hover(
						function(){
							$(this).find('p').animate(settings.show, settings.showDuration);
						},
						function(){
							$(this).find('p').animate(settings.hide, settings.hideDuration);
						});
					}
					
					//Copy Image Style to Div
					if(settings.copyStyle) div.attr('style',imageStyle);
					
					//If there is an alignment on the image (for example align="left") add "left" as a class on the caption.  This helps deal with older Text Editors like TinyMCE
					if(settings.copyAlignmentToClass) div.addClass(imageAlign);
					
					//Transfers the float style from the image to the caption container
					if(settings.copyFloatToClass) div.addClass(imageFloat);
					
					//Properly size the caption div based on the loaded image's size
					if(settings.autoWidth) div.width(image.width());
				}
			});
			
			// Thanks to Captify for this bit!
			//if the image has already loaded (due to being cached), force the load function to be called
			if (this.complete || this.naturalWidth > 0){
				$(this).trigger('load');
			}
		});
	}
})(jQuery);
;

(function ($) {
  Drupal.Panels = {};

  Drupal.Panels.autoAttach = function() {
    if ($.browser.msie) {
      // If IE, attach a hover event so we can see our admin links.
      $("div.panel-pane").hover(
        function() {
          $('div.panel-hide', this).addClass("panel-hide-hover"); return true;
        },
        function() {
          $('div.panel-hide', this).removeClass("panel-hide-hover"); return true;
        }
      );
      $("div.admin-links").hover(
        function() {
          $(this).addClass("admin-links-hover"); return true;
        },
        function(){
          $(this).removeClass("admin-links-hover"); return true;
        }
      );
    }
  };

  $(Drupal.Panels.autoAttach);
})(jQuery);
;

