RMAP_VERSION=2.260109001;
isMSIE = false;
isWindows = false;
if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){
isMSIE = true;
MSIEVersion=new Number(RegExp.$1);
}
if (/Windows (\d+\.\d+);/.test(navigator.userAgent)){
isWindows = true;
}

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
		|| this.searchVersion(navigator.appVersion)
		|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
				return data[i].identity;
			}
			else if (dataProp)
			return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
	{
		string: navigator.userAgent,
		subString: "Chrome",
		identity: "Chrome"
	},
	{ 	string: navigator.userAgent,
	subString: "OmniWeb",
	versionSearch: "OmniWeb/",
	identity: "OmniWeb"
	},
	{
		string: navigator.vendor,
		subString: "Apple",
		identity: "Safari"
	},
	{
		prop: window.opera,
		identity: "Opera"
	},
	{
		string: navigator.vendor,
		subString: "iCab",
		identity: "iCab"
	},
	{
		string: navigator.vendor,
		subString: "KDE",
		identity: "Konqueror"
	},
	{
		string: navigator.userAgent,
		subString: "Firefox",
		identity: "Firefox"
	},
	{
		string: navigator.vendor,
		subString: "Camino",
		identity: "Camino"
	},
	{		// for newer Netscapes (6+)
		string: navigator.userAgent,
		subString: "Netscape",
		identity: "Netscape"
	},
	{
		string: navigator.userAgent,
		subString: "MSIE",
		identity: "Explorer",
		versionSearch: "MSIE"
	},
	{
		string: navigator.userAgent,
		subString: "Gecko",
		identity: "Mozilla",
		versionSearch: "rv"
	},
	{ 		// for older Netscapes (4-)
		string: navigator.userAgent,
		subString: "Mozilla",
		identity: "Netscape",
		versionSearch: "Mozilla"
	}
	],
	dataOS : [
	{
		string: navigator.platform,
		subString: "Win",
		identity: "Windows"
	},
	{
		string: navigator.platform,
		subString: "Mac",
		identity: "Mac"
	},
	{
		string: navigator.platform,
		subString: "Linux",
		identity: "Linux"
	}
	]

};
BrowserDetect.init();

isIPHONE = (window.orientation === undefined) ? false : true;

DATA_SERVER = '/tangle/';
INFORMER_SERVER = '/informer/';
SEARCH_SERVER = '/search/';
//SEARCH_SERVER = '/finder/';
LEGENDA_SERVER = '/legenda/';
ROUTES_SERVER = '/quilt/';


function RequestURL(url, callbackfunc) {
	try {
		var request = new XMLHttpRequest();
	} catch (e) {
		var request = new ActiveXObject("Microsoft.XMLHTTP");
	}
	request.open("GET", url);
	request.onreadystatechange = function() {
		if (request.readyState == 4) {
			if (request.status == 200) {
				callbackfunc(request);
			}
		}
	};
	request.send(null);
}


function AnonRequestURL(url) {
	try {
		var request = new XMLHttpRequest();
	} catch (e) {
		var request = new ActiveXObject("Microsoft.XMLHTTP");
	}
	request.open("GET", url);
	request.send(null);
}


function ImageServer(x, y) {
	var serverid;
	var xeven = (Math.round(x/2) == x/2);
	var yeven = (Math.round(y/2) == y/2);
	if (!xeven && !yeven) serverid = 0;
	if (xeven && !yeven) serverid = 1;
	if (!xeven && yeven) serverid = 2;
	if (xeven && yeven) serverid = 3;
	//	return "d1.nakarte.ru/";
	return "http://i"+serverid+".nakarte.ru/";
}
function loadtilefunction(x, y, z) {
	return ImageServer(x, y) + 'tiles/' + this.area + '_ru/' + FillByZero(z, 11) + '/' + FillByZero(y, 6) + '/' + FillByZero(x, 6) + FillByZero(y, 6) + '.png';
}
function addhandler(element, event_type, func) {
	if (event_type == 'dblclick' /*&& BROWSER==safari*/) {
		element.ondblclick = func;
		return;
	}
	if (element.attachEvent) { // IE
		element.attachEvent('on' + event_type, func);
	} else if (element.addEventListener) { // W3C
		element.addEventListener(event_type, func, false);
	} else { // should not happen
		element['on' + event_type] = func;
	}
}

function cancelevent(e) {
	if (isMSIE) {
		e = event;
	}
	e.returnValue = false;
	e.cancelBubble = true;
	if (e.preventDefault) {
		e.preventDefault();
	}
	if (e.stopPropagation) {
		e.stopPropagation();
	}
}
function GetMouse(e) {
	if (isMSIE) {
		e = window.event;
	}
	return {x:e.clientX, y:e.clientY}
}
function GetKeyboardCode(e) {
	if (isMSIE) {
		e = window.event;
	}
	if (e.keyCode) {
		return e.keyCode;
	} else {
		return e;
	}
}
function GetMouseWheel(e) {
	if (isMSIE) {
		e = window.event;
	}
	return {x:e.screenX, y:e.screenY}
}
function encode_utf8( s ) {
	return unescape( encodeURIComponent( s ) );
}
function decode_utf8( s ){
	return decodeURIComponent( escape( s ) );
}
var UTF8 = {
	// public method for url encoding
	encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// public method for url decoding
	decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}
}
function $(id) {return document.getElementById(id)}
function $S(div, state) {
	div.style.visibility = (state) ? 'visible' : 'hidden';
}

function sizeof(obj) {
	var s = 0;
	for(var i in obj) {
		s++;
	}
	return s;
}
function CalcOffset(obj) {
	var curleft = 0;
	var curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return {left: curleft, top: curtop};
}
function FillByZero(str, count) {
	var newstr = '';
	str = str+'';
	count = count-str.length;
	for(var i=1;i<=count;i++){
		newstr += '0';
	}
	return newstr+str;
}
function ParseURL(wheretofind) {
	var vars, str, query, keypairs, numKP, keyName, keyValue;
	vars = new Object();
	str = wheretofind + '';
	var index = '#';
	query = str.substring((str.indexOf(index)) + 1);
	keypairs = new Object();
	numKP = 1;
	while (query.indexOf('&') > -1) {
		keypairs[numKP] = query.substring(0,query.indexOf('&'));
		query = query.substring((query.indexOf('&')) + 1);
		numKP++;
	}
	keypairs[numKP] = query;
	for (var i in keypairs) {
		keyName = keypairs[i].substring(0,keypairs[i].indexOf('='));
		keyValue = keypairs[i].substring((keypairs[i].indexOf('=')) + 1);
		while (keyValue.indexOf('+') > -1) {
			keyValue = keyValue.substring(0,keyValue.indexOf('+')) + ' ' + keyValue.substring(keyValue.indexOf('+') + 1);
		}
		keyValue = unescape(keyValue);
		vars[keyName] = keyValue;
	}
	delete vars[''];
	for (var key in vars) {
		if (key.indexOf('.') > -1) {
			keyName = key.substring(0,key.indexOf('.'));
			subkeyName = key.substring((key.indexOf('.')) + 1);
			if (!vars[keyName]) {
				vars[keyName] = {};
			}
			vars[keyName][subkeyName] = vars[key];
			delete vars[key];
		}
	}
	vars['hostname'] = wheretofind.hostname;
	vars['pathname'] = wheretofind.pathname;
	return vars;
}
function SimpleObject(params) {this.params = params;}

function Geo(map, TILE_SIZE) {
	this.datums = {
		datum1: {
			Semimajor : 6378135.0,
			Semiminor : 0.0,
			Flattering : 298.257223563,
			InversFlattering : 1.0/298.257223563,
			MetersPerUnit : 1,
			base: {
				esq : 0.00669342,
				e1sq : 0.00673853,
				e1 : 0.00167898,
				A0 : 0.998325,
				A2 : 0.00251425,
				A4 : 2.63822e-06,
				A6 : 3.38728e-09,
				A8 : -4.82385e-12,
				a : 6378245,
				x0 : 0,
				y0 : -6.1716e+06,
				k0 : 1,
				lon0 : 37.5
			}
		},
		wgs84: {
			Semimajor : 6378135.0,
			Semiminor : 0.0,
			Flattering : 298.257223563,
			InversFlattering : 1.0/298.257223563,
			MetersPerUnit : 111180.0
		}
	};
	this.routes_autoupdatecallfunction = function(drawer,redraw) {
		var cmap = $('map');
		var _self_ = this;
		if (!this.router) {
			this.router = cmap.router;
		};

		if (this.router) {
			this.router.drawfunctions.routes = this.drawfunction = function(routes) {
				drawer.drawler.drawL(routes, false, false, {join: 'miter', width: 3, good: true, arrowscale: 3, outline: {width: .5}}, cmap.currentposition.z);
			};
			this.router.redrawfunctions.routes = function() {
				if (cmap.surfaces['routes'].state) cmap.surfaces['routes'].flags.autoupdatecallfunction(cmap.surfaces['routes'].drawer, true)
			};
		};
		if ((!redraw&&(drawer.drawler.canvas.childNodes.length>0))||!this.router) return false;

		drawer.drawler.clear();
		this.router.drawroutes(this.router.todraw.routes,false,false,redraw);
	};
	this.points_autoupdatecallfunction = function(drawer,redraw) {
		var cmap = $('map');
		var _self_ = this;
		if (!this.router) {
			this.router = cmap.router;
		};
		if (this.router) {
			this.router.eventsdrawfunction = ((cmap.surfaces['routes'])?  (function() {if (cmap.surfaces['routes'].state) cmap.surfaces['routes'].flags.autoupdatecallfunction(cmap.surfaces['routes'].drawer, 'norecalc')}) : (function() {}));
			this.router.drawfunctions.points = this.drawfunction = function(points) {
				return drawer.drawler.drawP(points,false,false, {
					shadow: true,
					group: 'movable',
					events: _self_.router.setpointevents()
				})
			};

			this.router.redrawfunctions.points = function() {
				if (cmap.surfaces['points'].state) cmap.surfaces['points'].flags.autoupdatecallfunction(cmap.surfaces['points'].drawer, true)
			};
		};

		if (!redraw&&(drawer.drawler.canvas.childNodes.length>0)) return false;
		if (redraw) drawer.drawler.clear();

		this.router.drawpoints(this.router.todraw.points);
	}

	this.maps = {
		moscow: {
			extent: {
				x1:-161294.640636731,
				y1:-185458.562477162,
				x2:225789.623006343,
				y2:186546.195520016
			},
			//									defaultcenter: {
			//										x: 7502.29,
			//										y: 9888.56
			//									},
			// with banner
			defaultcenter: {
				x: 10030.3356,
				y: 10975.1226
			},
			scalelist: [2000, 4000, 8000, 16000, 32000, 64000, 128000, 256000, 512000],
			miniscalelist: [128000, 128000, 256000, 256000, 256000, 512000, 512000, 512000, 512000],
			defaultscalenum : 7,
			description: 'Москва и область',
			htmltitle: 'Карта Москвы и Московской области',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction: loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 8
				}
			},
			{
				id: 'traffic',
				type: 'vector',
				flags: {
					index: 1,
					getdatafunction: function(coords1, coords2, z, callbackfunc) {
						try {
							var request = new XMLHttpRequest();
						} catch (e) {
							var request = new ActiveXObject("Microsoft.XMLHTTP");
						}
						var dists = [10,10,15,50,40,30,20,13,13];
						var trafficurl = DATA_SERVER+"traffic_map?x1="+coords1.x+"&y1="+coords2.y+"&x2="+coords2.x+"&y2="+coords1.y+"&z="+z+'&transform=1&dist='+dists[z]+'&rnd='+(Math.round(Math.random()*1000000000));
						request.open("GET", trafficurl);
						request.onreadystatechange = function() {
							if (request.readyState == 4) {
								if (request.status == 200) {
									callbackfunc(request.responseText);
								}
							}
						};
						request.send(null);
					},
					getinformer: function(callbackfunc) {
						try {
							var request = new XMLHttpRequest();
						} catch (e) {
							var request = new ActiveXObject("Microsoft.XMLHTTP");
						}
						request.open("GET", INFORMER_SERVER+'?format=json&rnd='+(Math.round(Math.random()*1000000000)));
						request.onreadystatechange = function() {
							if (request.readyState == 4) {
								if (request.status == 200) {
									callbackfunc(request.responseText);
								}
							}
						};
						request.send(null);
					},
					zoomvalidfrom: 0,
					zoomvalidto: 8,
					autoupdatepriod: 30*60*1000,
					autoupdatecallfunction: function(drawer, forced) {
						var cmap = $('map');
						var lefttop = cmap.geo.Geo2Screen(cmap.currentposition.x, cmap.currentposition.y, cmap.geo.map.scalelist[cmap.currentposition.z]);
						var curstate = {x: lefttop.x, y: lefttop.y, z: cmap.currentposition.z};
						if (this.prevstate == undefined) {
							this.prevstate = {z: -1};
						}
						if (!forced && curstate.z == this.prevstate.z && (Math.abs(curstate.x-this.prevstate.x) < cmap.visiblebox.center.x) && (Math.abs(curstate.y-this.prevstate.y) < cmap.visiblebox.center.y))  {
							return false;
						}
						this.prevstate = curstate;

						lefttop.x -= (cmap.visiblebox.width);
						lefttop.y -= (cmap.visiblebox.height);

						var rightbottom = {};

						rightbottom.x = lefttop.x + cmap.visiblebox.width*2;
						rightbottom.y = lefttop.y + cmap.visiblebox.height*2;

						var lefttop = cmap.geo.Screen2Geo(lefttop.x, lefttop.y, cmap.geo.map.scalelist[cmap.currentposition.z]);
						var rightbottom = cmap.geo.Screen2Geo(rightbottom.x, rightbottom.y, cmap.geo.map.scalelist[cmap.currentposition.z]);

						this.getdatafunction({x: lefttop.gx, y: lefttop.gy}, {x: rightbottom.gx, y: rightbottom.gy}, cmap.currentposition.z, function(datasrc) {
							var cmap = $('map');
							var data = eval(datasrc);
							if (typeof data != 'object') return false;
							var lefttop = cmap.geo.Geo2Screen(cmap.currentposition.x, cmap.currentposition.y, cmap.geo.map.scalelist[cmap.currentposition.z]);
							lefttop.x -= cmap.visiblebox.center.x-cmap.movabledivoffsets.left;
							lefttop.y -= cmap.visiblebox.center.y-cmap.movabledivoffsets.top;
							var colorlist = {
								0:   "rgb(127, 0, 0)",
								11: "rgb(255, 80, 20)",
								22: "rgb(255, 80, 20)",
								33: "rgb(255, 153, 0)",
								44: "rgb(255, 153, 0)",
								55: "rgb(255, 221, 0)",
								66: "rgb(255, 221, 0)",
								77: "rgb(255, 255, 255)",
								88: "rgb(255, 255, 255)",
								99: "rgb(255, 255, 255)"
							};
							var data_to_draw = [];
							for(var i in data) {
								var edge = data[i];
								if (edge && edge.fact != undefined) {
									var color = Math.round(edge.fact);
									var obj = [];
                                                                        if (color >= 66 || color == 11) continue;
//									if (color >= 66 || color < 11) continue;
									(!edge.fact)&&(edge.attributes=false);
									for(var j in edge.points) {
										var point = edge.points[j];
										point.x = Math.round((point.pt.x*1)-lefttop.x);
										point.y = Math.round((point.pt.y*1)-lefttop.y);
										obj.push(point);
									}
									if (edge.group_depth != 1) {
										data_to_draw.push({line: obj, dir: edge.dir, color: colorlist[color], attributes: edge.attributes})
									}
								}
							}
							drawer.drawler.drawL(data_to_draw, true, true, {outline: true});
						});
						if ($('trafficswitch')) {
							if (cmap.trafficswitch_state || cmap.trafficswitch_state==undefined) {
								$('trafficswitch').style.visibility = 'visible';
								$('traffic_div').style.visibility = 'visible';
							}
							this.getinformer(function(datasrc) {
								//								var cmap = $('map');
								var data = eval('('+datasrc+')');
								var value = data.full_value;
								var imvalue = data.value;
								if (imvalue < 1) imvalue = 1;
								if (imvalue > 5) imvalue = 5;
								var trend = data.trend;
								var trendsign = "";
								if (trend > 0) {
									trendsign = "&uarr;";
								} else if (trend < 0) {
									trendsign = "&darr;";
								}
								$('trafficinformer_img').src = 'i/informer'+(imvalue) + '.png';
								$('trafficinformer_img').alt = value;
								$('trafficinformer_img').title = value;
								$('trafficinformer_text').innerHTML = value + '%&nbsp;';
								$('trafficinformer_trend').innerHTML = trendsign;
							});
						}
					}
				}
			},
			{
				id:'routes',
				type: 'vector',
				flags: {
					index: 2,
					zoomvalidfrom: 0,
					zoomvalidto: 8,
					autoupdatecallfunction: this.routes_autoupdatecallfunction
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 88888,
					zoomvalidfrom: 0,
					zoomvalidto: 8,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : true,
			cid : 105,
			gid : 32
		},
		piter: {
			extent: {
				x1: -259841.045940,
				y1: -222696.177113,
				x2: 259841.045447,
				y2: 155814.605728
			},
			defaultcenter: {
				x: -67466.55,
				y: -4984.72
			},
			scalelist: [2000, 4000, 8000, 16000, 32000, 64000, 128000, 256000],
			miniscalelist: [128000, 128000, 256000, 256000, 256000, 256000, 256000, 256000],
			defaultscalenum : 6,
			description: 'Санкт-Петербург и область',
			htmltitle: 'Карта Санкт-Петербурга и Ленинградской области',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction:loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 7
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 1,
					zoomvalidfrom: 0,
					zoomvalidto: 7,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : false,
			cid: 158,
			gid : 65
		},
		vgrad: {
			extent: {
				x1: -15440.069335938,
				y1: -39501.019531250,
				x2: 12978.388671875,
				y2: 3681.806884766
			},
			defaultcenter: {
				x: 1258.74,
				y: -12507.52
			},
			scalelist: [4000, 8000, 16000, 32000, 64000, 128000],
			miniscalelist: [128000, 128000, 128000, 128000, 128000, 128000],
			defaultscalenum : 3,
			description: 'Волгоград',
			htmltitle: 'Карта Волгограда',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction: loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 5
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 1,
					zoomvalidfrom: 0,
					zoomvalidto: 5,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : false,
			cid: 30,
			gid: 9
		},
		eburg: {
			extent: {
				x1: -3725.903907,
				y1: -30015.585938,
				x2: 20770.285156,
				y2: 0.0
			},
			defaultcenter: {
				x: 6693.4429,
				y: -18264.4671
			},
			scalelist: [2000, 4000, 8000, 16000, 32000, 64000],
			miniscalelist: [64000, 64000, 64000, 64000, 64000, 64000],
			defaultscalenum : 4,
			description: 'Екатеринбург',
			htmltitle: 'Карта Екатеринбурга',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction: loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 5
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 1,
					zoomvalidfrom: 0,
					zoomvalidto: 5,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : false,
			cid: 45,
			gid: 68
		},
		kazan: {
			extent: {
				x1: -26091.979543339,
				y1: -18002.811587189,
				x2: 4951.189878539,
				y2: 11527.763280369
			},
			defaultcenter: {
				x: -11354.9404,
				y: 583.6148
			},
			scalelist: [2000, 4000, 8000, 16000, 32000, 64000],
			miniscalelist: [64000, 64000, 64000, 64000, 64000, 64000],
			defaultscalenum : 3,
			description: 'Казань',
			htmltitle: 'Карта Казани',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction: loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 5
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 1,
					zoomvalidfrom: 0,
					zoomvalidto: 5,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : false,
			cid: 58,
			gid: 59
		},
		kirov: {
			extent: {
				x1: 975.161033582,
				y1: 1267.323300000,
				x2: 17048.445600000,
				y2: 24031.293300000
			},
			defaultcenter: {
				x: 9740.31,
				y: 14033.95
			},
			scalelist: [2000, 4000, 8000, 16000, 32000, 64000],
			miniscalelist: [64000, 64000, 64000, 64000, 64000, 64000],
			defaultscalenum : 3,
			description: 'Киров',
			htmltitle: 'Карта Кирова',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction: loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 5
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 1,
					zoomvalidfrom: 0,
					zoomvalidto: 5,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : false
		},
		nnov: {
			extent: {
				x1: -18081.865234375,
				y1: -16988.314453125,
				x2: 10695.836914062,
				y2: 10142.624023438
			},
			defaultcenter: {
				x: -5493.74,
				y: -2186.54
			},
			scalelist: [4000, 8000, 16000, 32000, 64000],
			miniscalelist: [64000, 64000, 64000, 64000, 64000],
			defaultscalenum : 3,
			description: 'Нижний Новгород',
			htmltitle: 'Карта Нижнего Новгорода',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction: loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 4
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 1,
					zoomvalidfrom: 0,
					zoomvalidto: 4,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : false,
			cid: 119,
			gid: 36
		},
		omsk: {
			extent: {
				x1: -21214.755859375,
				y1: -14928.646484375,
				x2: 1762.463134766,
				y2: 9143.850585938
			},
			defaultcenter: {
				x: -8715.6,
				y: -1808.46
			},
			scalelist: [4000, 8000, 16000, 32000, 64000],
			miniscalelist: [64000, 64000, 64000, 64000, 64000],
			defaultscalenum : 3,
			description: 'Омск',
			htmltitle: 'Карта Омска',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction: loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 4
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 1,
					zoomvalidfrom: 0,
					zoomvalidto: 4,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : false,
			cid: 131,
			gid: 39
		},
		samara: {
			extent: {
				x1: 1131.652832,
				y1: -26869.195312,
				x2: 25106.271484,
				y2: 10007.001953
			},
			defaultcenter: {
				x: 14014.944140,
				y: -12816.122089
			},
			scalelist: [2000, 4000, 8000, 16000, 32000, 64000],
			miniscalelist: [64000, 64000, 64000, 64000, 64000, 64000],
			defaultscalenum : 3,
			description: 'Самара',
			htmltitle: 'Карта Самары',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction: loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 5
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 1,
					zoomvalidfrom: 0,
					zoomvalidto: 5,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : false,
			cid: 157,
			gid: 64
		},
		togliatti: {
			extent: {
				x1: -52576.992173233,
				y1: 12345.934141124,
				x2: 0.000000000,
				y2: 28960.407259675
			},
			defaultcenter: {
				x: -38291.18,
				y: 20766.04
			},
			scalelist: [2000, 4000, 8000, 16000, 32000],
			miniscalelist: [32000, 32000, 32000, 32000, 32000, 32000],
			defaultscalenum : 3,
			description: 'Тольятти',
			htmltitle: 'Карта Тольятти',
			datum: 'datum1',
			defaultsurfaces : [
			{
				id:'background',
				type: 'tiles',
				loadtilefunction: loadtilefunction,
				flags: {
					index: 0,
					zoomvalidfrom: 0,
					zoomvalidto: 4
				}
			},
			{
				id:'points',
				type: 'vector',
				flags: {
					index: 1,
					zoomvalidfrom: 0,
					zoomvalidto: 4,
					autoupdatecallfunction: this.points_autoupdatecallfunction
				}
			}
			],
			isgeo : false,
			cid: 183,
			gid: 39128
		}
	}
	this.Geo2Tile = function (geocoords, scale) {
		var pix_width = Math.round(this.geo_width*(28.346472)/(scale/(this.datum.MetersPerUnit*100)));
		var pix_height = Math.round((this.geo_height * pix_width) / this.geo_width);
		var pix_center_left = Math.round((geocoords.x - this.map.extent.x1) * (pix_width/this.geo_width));
		var pix_center_top = Math.round((this.map.extent.y2 - geocoords.y) * (pix_height/this.geo_height));
		return {
			xnum: Math.floor(pix_center_left/this.TILE_SIZE),
			ynum: Math.floor(pix_center_top/this.TILE_SIZE),
			left: pix_center_left % this.TILE_SIZE,
			top: pix_center_top % this.TILE_SIZE,
			scale: scale,
			mapid: this.mapid
		}
	}
	this.Tile2Geo = function(tileinfo, scale) {
		var pix_width = Math.round(this.geo_width*(28.346472)/(scale/(this.datum.MetersPerUnit*100)));
		var pix_height = Math.round((this.geo_height * pix_width) / this.geo_width);
		var pixx = (tileinfo.xnum)*this.TILE_SIZE+tileinfo.left;
		var pixy = (tileinfo.ynum)*this.TILE_SIZE+tileinfo.top;
		return {
			x: this.map.extent.x1 + (pixx * (this.geo_width/pix_width)),
			y: this.map.extent.y2 - (pixy * (this.geo_height/pix_height))
		}
	}
	this.Screen2Geo = function(x, y, scale) {
		var pix_width = Math.round(this.geo_width*(28.346472)/(scale/(this.datum.MetersPerUnit*100)));
		var pix_height = Math.round((this.geo_height * pix_width) / this.geo_width);
		return {
			gx: this.map.extent.x1 + (x * (this.geo_width/pix_width)),
			gy: this.map.extent.y2 - (y * (this.geo_height/pix_height))
		}

	}
	this.Geo2Screen = function(gx, gy, scale) {
		var pix_width = Math.round(this.geo_width*(28.346472)/(scale/(this.datum.MetersPerUnit*100)));
		var pix_height = Math.round((this.geo_height * pix_width) / this.geo_width);
		return {
			x: Math.round((gx - this.map.extent.x1) * (pix_width/this.geo_width)),
			y: Math.round((this.map.extent.y2 - gy) * (pix_height/this.geo_height))
		}
	}
	this.GeoInPix = function(scale) {
		var mp = this.Screen2Geo(1, 1, scale);
		return {x: (mp.gx-this.map.extent.x1), y: (mp.gy-this.map.extent.y2)};
	}
	this.ComprehensiveScale = function(r, viewbounds) {
		r.width = Math.abs(r.x2-r.x1);
		r.height = Math.abs(r.y2-r.y1);
		if(r.width > r.height) {
			return (r.width*this.datum.MetersPerUnit*100)/(viewbounds.width/28.346472);
		} else {
			return (r.height*this.datum.MetersPerUnit*100)/(viewbounds.height/28.346472);
		}
	}
	this.NearestScale = function(scale) {
		for(var i in this.map.scalelist) {
			if (this.map.scalelist[i] > scale) {
				return i;
			}
		}
		return 0;
	}

	this.GeoDistance = function(start, end) {
		var a = start;
		var b = end;
		a.y = 0.01745329252 * a.y;
		a.x = -0.01745329252 * a.x;
		b.y = 0.01745329252 * b.y;
		b.x = -0.01745329252 * b.x;

		var F = (a.y + b.y) / 2.0;
		var G = (a.y - b.y) / 2.0;
		var L = (a.x - b.x) / 2.0;

		var sing = Math.sin(G);
		var cosl = Math.cos(L);
		var cosf = Math.cos(F);
		var sinl = Math.sin(L);
		var sinf = Math.sin(F);
		var cosg = Math.cos(G);

		var S = sing*sing*cosl*cosl + cosf*cosf*sinl*sinl;
		var C = cosg*cosg*cosl*cosl + sinf*sinf*sinl*sinl;
		var W = Math.atan2(Math.sqrt(S),Math.sqrt(C));
		var R = Math.sqrt((S*C))/W;
		var H1 = (3 * R - 1.0) / (2.0 * C);
		var H2 = (3 * R + 1.0) / (2.0 * S);
		var D = 2 * W * this.datum.Semimajor;
		return (D * (1 + this.datum.InversFlattering * H1 * sinf*sinf*cosg*cosg - this.datum.InversFlattering * H2 * cosf*cosf*sing*sing));
	}
	this.FromLatLon = function(lat, lon) {
		lon = lon * (Math.PI/180);
		lat = lat * (Math.PI/180);
		lon0 = this.datum.base.lon0 * (Math.PI/180);

		var sinlat = Math.sin(lat);
		var coslat = Math.cos(lat);
		var tanlat = sinlat / coslat;
		var sinsqlat = sinlat*sinlat;
		var cossqlat = coslat*coslat;
		var T = tanlat*tanlat;
		var N = this.datum.base.a/Math.sqrt(1-this.datum.base.esq*sinsqlat);
		var C = this.datum.base.e1sq*cossqlat;
		var Q = coslat*(lon-lon0);
		var Q2 = Q * Q;
		var Q3 = Q2 * Q;
		var Q4 = Q3 * Q;
		var Q5 = Q4 * Q;
		var Q6 = Q5 * Q;

		var M = this.datum.base.a*(this.datum.base.A0*lat-this.datum.base.A2*Math.sin(2*lat)+this.datum.base.A4*Math.sin(4*lat)-this.datum.base.A6*Math.sin(6*lat)+this.datum.base.A8*Math.sin(8*lat));
		var x = (this.datum.base.k0*N*(Q+(1-T+C)*Q3/6+ (5-18*T+T*T+72*C-58*this.datum.base.e1sq)*Q5/120) + this.datum.base.x0);
		var y = (this.datum.base.k0*(M+N*tanlat*(Q*Q/2+(5-T+9*C+4*C*C)*Q4/24 + (61-58*T+T*T+600*C-330*this.datum.base.e1sq)*Q6/720))+ this.datum.base.y0);
		return {x:x,y:y};
	}
	this.ToLatLon = function(x, y) {
		var epsilon = 2.0E-12;
		var highPrecision = false;
		var errmax = highPrecision ? epsilon / 100000 : epsilon;
		var maxiter = highPrecision ? 1000 : 100;
		var lon0 = this.datum.base.lon0 * (Math.PI/180);

		x = x - this.datum.base.x0;
		y = y - this.datum.base.y0;

		M = y / this.datum.base.k0;
		mu = M/(this.datum.base.a*this.datum.base.A0);

		phi1 = mu + (3*this.datum.base.e1/2-27*this.datum.base.e1*this.datum.base.e1*this.datum.base.e1/32)*Math.sin(2*mu)+ (21*this.datum.base.e1*this.datum.base.e1/16-55*this.datum.base.e1*this.datum.base.e1*this.datum.base.e1*this.datum.base.e1/32)*Math.sin(4*mu)+(151*this.datum.base.e1*this.datum.base.e1*this.datum.base.e1/96)*Math.sin(6*mu);

		var iter = 0;
		var sinphi1, cosphi1, eff, eff1, delta;
		do {
			sinphi1 = Math.sin(2*phi1);
			cosphi1 = Math.cos(2*phi1);
			eff = this.datum.base.A0*phi1 - this.datum.base.A2 * sinphi1 - M/this.datum.base.a;
			eff1 = this.datum.base.A0 - 2*this.datum.base.A2*cosphi1;

			sinphi1 = Math.sin(4*phi1);
			cosphi1 = Math.cos(4*phi1);
			eff += this.datum.base.A4*sinphi1;
			eff1 += 4*this.datum.base.A4*cosphi1;

			sinphi1 = Math.sin(6*phi1);
			cosphi1 = Math.cos(6*phi1);
			eff -= this.datum.base.A6*sinphi1;
			eff1 -= 6*this.datum.base.A6*cosphi1;

			sinphi1 = Math.sin(8*phi1);
			cosphi1 = Math.cos(8*phi1);
			eff += this.datum.base.A8*sinphi1;
			eff1 -= 8*this.datum.base.A8*cosphi1;

			delta = eff/eff1;

			phi1 -= delta;
		} while ((Math.abs(delta) > errmax) && (++iter < maxiter));

		sinphi1 = Math.sin(phi1);
		cosphi1 = Math.cos(phi1);

		var tanphi1 = sinphi1 / cosphi1;
		var sinsqphi1 = sinphi1 * sinphi1;
		var cossqphi1 = cosphi1 * cosphi1;
		var tansqphi1 = tanphi1 * tanphi1;

		var N1 = this.datum.base.a/Math.sqrt(1-this.datum.base.esq*sinsqphi1);
		var T1 = tansqphi1;
		var C1 = this.datum.base.e1sq*cossqphi1;
		var R1 = this.datum.base.a*(1-this.datum.base.esq)/Math.pow(1-this.datum.base.esq*sinsqphi1, 1.5);
		var D = x/(N1*this.datum.base.k0);

		var lon = (D-(1+2*T1+C1)*D*D*D/6+ (5-2*C1+28*T1-3*C1*C1+8*this.datum.base.e1sq+24*T1*T1)*D*D*D*D*D/120) / cosphi1;
		lon = (lon + lon0) * (180/Math.PI);

		var lat = (phi1 - (N1*tanphi1/R1) * (D*D/2- (5+3*T1+10*C1-4*C1*C1-9*this.datum.base.e1sq)*D*D*D*D/24+ (61+90*T1+298*C1+45*T1*T1-252*this.datum.base.e1sq-3*C1*C1)*D*D*D*D*D*D/720));
		lat = lat * (180/Math.PI);

		return {lat: lat, lon: lon};
	}
	this.__KrasovskiWGS_dB = function(Bd, Ld, H) {
		var B, L, M, N, dB;
		B = Bd * Math.PI / 180;
		L = Ld * Math.PI / 180;
		M = this.__KrasovskiWGS.a * (1 - this.__KrasovskiWGS.e2) / Math.pow((1 - this.__KrasovskiWGS.e2 * Math.pow(Math.sin(B), 2)), 1.5);
		N = this.__KrasovskiWGS.a * Math.pow((1 - this.__KrasovskiWGS.e2 * Math.pow(Math.sin(B), 2)), -0.5);

		var sinB = Math.sin(B);
		var cosB = Math.cos(B);
		var sinBcosB = sinB*cosB;
		var e2cosB = 1 + this.__KrasovskiWGS.e2 * Math.cos(2 * B);
		var e2sinBcosB = this.__KrasovskiWGS.e2 * sinBcosB;
		var p1 = N / this.__KrasovskiWGS.a * e2sinBcosB * this.__KrasovskiWGS.da;
		var p2 = (N * N / this.__KrasovskiWGS.a * this.__KrasovskiWGS.a + 1) * N * sinBcosB * this.__KrasovskiWGS.de2 / 2;
		var p3 = (this.__KrasovskiWGS.dx * Math.cos(L) + this.__KrasovskiWGS.dy * Math.sin(L)) * sinB + this.__KrasovskiWGS.dz * Math.cos(B);
		dB = this.__KrasovskiWGS.ro / ((M + H) * (p1 + p2 - p3));
		return dB;
	}
	this.__KrasovskiWGS_dL = function(Bd, Ld, H) {
		var B, L, N, dL;
		B = Bd * Math.PI / 180;
		L = Ld * Math.PI / 180;
		N = this.__KrasovskiWGS.a * Math.pow((1 - this.__KrasovskiWGS.e2 * Math.pow(Math.sin(B), 2)), -0.5);
		dL = this.__KrasovskiWGS.ro / ((N + H) * Math.cos(B)) * (-this.__KrasovskiWGS.dx * Math.sin(L) + this.__KrasovskiWGS.dy * Math.cos(L)) + Math.tan(B) * (1 - this.__KrasovskiWGS.e2) * (this.__KrasovskiWGS.wx * Math.cos(L) + this.__KrasovskiWGS.wy * Math.sin(L)) - this.__KrasovskiWGS.wz;
		return dL;
	}
	this.KrasovskiWGS = function(lat, lon, direction) {
		this.__KrasovskiWGS = {};
		this.__KrasovskiWGS.ro = 206264.8062;
		this.__KrasovskiWGS.aP = 6378245;
		this.__KrasovskiWGS.alP = 1 / 298.3;
		this.__KrasovskiWGS.e2P = (2 * this.__KrasovskiWGS.alP) - (this.__KrasovskiWGS.alP * this.__KrasovskiWGS.alP);
		this.__KrasovskiWGS.aW = 6378137;
		this.__KrasovskiWGS.alW = 1 / 298.257223563;
		this.__KrasovskiWGS.e2W = (2 * this.__KrasovskiWGS.alW) - (this.__KrasovskiWGS.alW * this.__KrasovskiWGS.alW);
		this.__KrasovskiWGS.a = (this.__KrasovskiWGS.aP + this.__KrasovskiWGS.aW) / 2;
		this.__KrasovskiWGS.e2 = (this.__KrasovskiWGS.e2P + this.__KrasovskiWGS.e2W) / 2;
		this.__KrasovskiWGS.da = this.__KrasovskiWGS.aW - this.__KrasovskiWGS.aP;
		this.__KrasovskiWGS.de2 = this.__KrasovskiWGS.e2W - this.__KrasovskiWGS.e2P;
		this.__KrasovskiWGS.dx = 23.92;
		this.__KrasovskiWGS.dy = -141.27;
		this.__KrasovskiWGS.dz = -80.9;
		this.__KrasovskiWGS.wx = 0;
		this.__KrasovskiWGS.wy = 0;
		this.__KrasovskiWGS.wz = 0;
		this.__KrasovskiWGS.ms = 0;
		var H = 0;

		var lat, lon;
		if (direction == 0) {
			lat = lat + this.__KrasovskiWGS_dB(lat, lon, H) / 3600;
			lon = lon + this.__KrasovskiWGS_dL(lat, lon, H) / 3600;
		} else {
			lat = lat - this.__KrasovskiWGS_dB(lat, lon, H) / 3600;
			lon = lon - this.__KrasovskiWGS_dL(lat, lon, H) / 3600;
		}
		return {lat: lat, lon: lon};

	}
	if (this.maps[map] == undefined) return false;
	this.TILE_SIZE = TILE_SIZE;
	this.map = this.maps[map];
	this.mapid = map;
	this.datum = this.datums[this.map.datum];
	this.geo_width = this.map.extent.x2-this.map.extent.x1;
	this.geo_height = this.map.extent.y2-this.map.extent.y1;
}

function rMap(divid, area, position) {
	var cmap = this.div = $(divid);
	if (this.div == null) {
		return false;
	}
	this.div.Setmousemovefunc = function() {
		this.mousemovefunc = {
			funcs : new Array(),
			nums : {},
			endfuncs: {},
			defalt : 0,
			add : function(name, func, startfunc, endfunc) {
				if (this.nums[name] != undefined) {
					this.del(name);
				};
				if (startfunc) startfunc();
				this.nums[name] = (this.funcs.push(func)-1);
				if (endfunc) this.endfuncs[name] = endfunc;
			},
			addFirst : function(name, func, startfunc, endfunc) {
				if (startfunc) startfunc();
				this.funcs.unshift(func);
				for (var i in this.nums) {
					this.nums[i] ++;
				};
				this.nums[name] = 0;
				if (endfunc) this.endfuncs[name] = endfunc;
			},
			addFromNum : function(num, name, func) {

			},
			addBefore : function(name1, name2, func) {

			},
			addAfter : function(name1, name2, func) {

			},
			del : function(name) {
				if (this.nums[name] == undefined) return false;
				var num = this.nums[name];
				if (this.endfuncs[name]) {
					this.endfuncs[name]();
					delete this.endfuncs[name];
				};
				delete this.nums[name];
				for (var i in this.nums) {
					if (this.nums[i]>num) {
						this.nums[i] --;
					};
				};
				this.funcs.splice(num, 1);
			}
		};
	};
	this.div.InitRouter = function() {
		//		var cmap = this;
		var getdatafunction = function(coords1, coords2, z, callbackfunc) {
			try {
				var request = new XMLHttpRequest();
			} catch (e) {
				var request = new ActiveXObject("Microsoft.XMLHTTP");
			}
			var jams = (cmap.use_jams_routes) ? '' : '&ignore_jams=1';
			if (cmap.router.dotransform==true) {
				var transform = '&transform=1';
				z = cmap.geo.map.scalelist[z];
				var url = ROUTES_SERVER+"path/?sx="+coords1.geocoords.gx+"&sy="+coords1.geocoords.gy+"&ex="+coords2.geocoords.gx+"&ey="+coords2.geocoords.gy+"&z="+z+jams+transform;
			} else {
				var transform = '';
				var url = LEGENDA_SERVER+"path/?sx="+coords1.geocoords.gx+"&sy="+coords1.geocoords.gy+"&ex="+coords2.geocoords.gx+"&ey="+coords2.geocoords.gy+"&z="+z+jams;
			}
			request.open("GET", url);
			request.onreadystatechange = function() {
				if (request.readyState == 4) {
					if (request.status == 200) {
						var datas = request.responseText.concat(']');
						datas = '['.concat(datas);
						callbackfunc(datas);
					} else if (request.status == 404 || request.status == 500 ) {
						cmap.panel.Show(false);
						cmap.ShowMessage('Невозможно проложить маршрут через указанные точки');
						return false;
					}
				}
			};
			request.send(null);
		};
		if (!this.router) {
			this.router = new InitRouter(function() {
				var lefttop = cmap.geo.Geo2Screen(cmap.currentposition.x, cmap.currentposition.y, cmap.geo.map.scalelist[cmap.currentposition.z]);
				lefttop.x -= cmap.visiblebox.center.x-cmap.movabledivoffsets.left;
				lefttop.y -= cmap.visiblebox.center.y-cmap.movabledivoffsets.top;
				return lefttop;
			}, function(gx,gy) {
				return cmap.geo.Geo2Screen(gx, gy, cmap.geo.map.scalelist[cmap.currentposition.z]);
			}, function(x,y) {
				return cmap.geo.Screen2Geo(x, y, cmap.geo.map.scalelist[cmap.currentposition.z]);
			}, function(p1,p2,callback) {
				getdatafunction(p1, p2, cmap.currentposition.z, function(datasrc){ var data = eval(datasrc); callback(data[0])});
			});
		};
	};
	this.div.ChangeArea = function(area, firstrun) {
		if (area == this.area) return false;
		this.StopTimer('addremovetiles');
		if ($('searchresults_list')) { this.removeChild($('searchresults_list'));}
		if ($('infowindow')) {	this.removeChild($('infowindow'));}
		for(var i in this.surfaces) {
			this.RemoveSurface(i);
		}
		for(var i in this.requesters) {
			delete this.requesters[i];
		}
		this.SetArea(area);
		if (this.scaler) {
			this.removeChild(this.scaler.div);
		}
		this.ActivateScaler();
		if (firstrun != undefined) {
			var putpoint = this.GetURLData();
		} else {
			this.currentroute = false;
		}
		if (this.defaultposition) {
			this.currentposition = this.defaultposition;
		}
		this.RecalcData();
		if (!firstrun) {
			var fr = document.createElement('IFRAME');
			fr.style.position = 'absolute';
			fr.style.visibility = 'hidden';
			fr.style.width = fr.style.height = '1px';
			fr.src = "empty.html";
			$('bigbanner').innerHTML = "";
			var  w = window;
			$('bigbanner').appendChild(fr);
			var scr = (area=='moscow')? '<script src=\"http://ad.rambler.ru/i.ban?pg=7470&ifr=16\"><\/script>' : '<script src=\"http://ad.rambler.ru/i.ban?pg=6685&ifr=16\"><\/script>';
			var ready1 = false;
			var fff = function() {
				if ((!fr.contentWindow.document.body || !fr.contentWindow.document.body.innerHTML.length) && !ready1) window.setTimeout(function(){fff()},1);
				else {
					ready1 = true;
					fr.contentWindow.document.write('\<body\>');
					fr.contentWindow.document.write(scr);
					fr.contentWindow.document.write('\<\/body\>');
					var ready2 = false;
					var ff = function() {
						if (fr.contentWindow==null) return;
						if ((!fr.contentWindow||!fr.contentWindow.document.body||fr.contentWindow.document.body.childNodes.length<2) && !ready2) window.setTimeout(function(){ff()},1);
						else {
							ready2 = true;
							$('bigbanner').innerHTML = fr.contentWindow.document.body.innerHTML;
						}
					}
					ff();
				};
			};
			fff();
		}
		this.AddDefaultSurfaces();
		if (this.zoomer) {
			this.removeChild(this.zoomer.div);
		}
		if (!isIPHONE && !this.embed)  this.ActivateMinimap(this.area,this);
		this.panel.Clear();
		this.panel.Show(false);
		this.panel.EmbedCorrect(this.embed, this.without_search);
		if (this.embed) {
			//$('header').style.display = 'none';
			if (!this.without_search) {
				$('header').style.display = 'block';
				for (var i=0; i<$('headertable').rows.length; i++) {
					$('headertable').rows[i].style.display = 'none';
					for (var j=0; j<$('headertable').rows[i].cells.length; j++) {
						$('headertable').rows[i].cells[j].style.display = 'none';
					};
				};
				$('searchformtd').style.display = $('searchformtd').parentNode.style.display = 'block';
			} else $('header').style.display = 'none';
			$('traffic_div').style.display = 'none';
			$('trafficswitch').style.display = 'none';
			$('banner').style.display = 'none';
			//$('minibanner').style.display = 'none';
			$('copyright').style.display = 'none';
			$('scaler').style.display = 'none';
		} else {
			$('header').style.display = 'block';
			$('searchform').style.display = 'block';
			$('traffic_div').style.display = 'block';
			$('trafficswitch').style.display = 'block';
			$('banner').style.display = 'block';
			$('copyright').style.display = 'block';
			$('scaler').style.display = 'block';
		}
		if (!isIPHONE) {
			if (this.surfaces['routes']) {
				$('routes_form_div').style.display = 'none';
				$('search_form_div').style.display = 'block';
				$('search_half_form_div').style.display = 'none';
				if (!this.embed) $('query').focus();
			} else {
				$('routes_form_div').style.display = 'none';
				$('search_form_div').style.display = 'none';
				$('search_half_form_div').style.display = 'block';
				$('queryh').focus();
			}
		}
		if ($('show_hide_infpanel')&&$('routes_form_div').style.display=='none') $('show_hide_infpanel').style.visibility = 'hidden';
		if (!this.geo.map.cid) $('searchform').style.display = 'none';
		this.mouse = {x: this.visiblebox.center.x, y: this.visiblebox.center.y};
		document.title =  'Рамблер-Накарте :: '+this.geo.map.htmltitle;

		if (this.fullview) {
			this.zoomer.div.style.visibility = 'hidden';
			$('header').style.display = 'none';
			$('traffic_div').style.display = 'none';
			$('trafficswitch').style.display = 'none';
		}

		if (this.hidetraffic) {
			this.SetSurfaceState('traffic', map.trafficswitch_state);
			$('traffic_canvas').style.display =  'none';
			$('traffic_div').style.visibility = 'hidden';

		}
		if ($('banner') && !this.embed) {
			this.ActivateZoomer(-220, 10);
		} else {
			this.ActivateZoomer(-10, 10);
		}
		this.zoomer.ShiftToZoom(this.currentposition.z);
		this.DeleteRoute();
		if (this.urlvalues.query) {
			if (/*isMSIE || */BrowserDetect.browser=='Opera') {
				var val = this.urlvalues.query;
			} else {
				var val = UTF8.decode(this.urlvalues.query);
			}
			this.bringfirst = true;
			if (this.surfaces['routes']) {
				$('query').value = val;
			} else {
				$('queryh').value = val;
			}
			this.DoSearch(val);
		}
		if (putpoint) {
			this.ShowObject(putpoint);
		}
		if (this.bookmark && this.bookmark.area != area) {
			if ($('bookmark')) {
				$('bookmark').parentNode.removeChild($('bookmark'));
				if (this.scaler) this.scaler.div.style.left = '1px';
			}
		} else {
			if (!firstrun) this.AppendBookmark(this.bookmark);
		}
	}
	this.div.SetArea = function(area) {
		this.area = area;
		this.geo = new Geo(this.area, this.TILE_SIZE);
		if (this.geo.map == undefined) this.SetArea('moscow');
		this.currentposition.x = this.geo.map.defaultcenter.x;
		this.currentposition.y = this.geo.map.defaultcenter.y;
		this.currentposition.z = this.geo.map.defaultscalenum;
	}
	this.div.GetURLData = function() {
		var urlvalues = ParseURL(window.location);
		if (!urlvalues) {
			return false;
		}
		if (urlvalues.gid != undefined) {
			var tmp = new Geo('moscow', this.TILE_SIZE);
			for(var mi in tmp.maps) {
				if (tmp.maps[mi].gid == urlvalues.gid) {
					urlvalues.a = mi;
					break;
				}
			}
		}
		if (urlvalues.a != undefined) {
			this.area = urlvalues.a;
			this.geo = new Geo(this.area, this.TILE_SIZE);
			this.currentposition.x = this.geo.map.defaultcenter.x;
			this.currentposition.y = this.geo.map.defaultcenter.y;
			this.currentposition.z = this.geo.map.defaultscalenum;
		}
		if (urlvalues.gx & urlvalues.gy && urlvalues.z) {
			var q = this.geo.FromLatLon(urlvalues.gy*1, urlvalues.gx*1);
			this.currentposition.x = q.x;
			this.currentposition.y = q.y;
			this.currentposition.z = urlvalues.z*1;
		}
		if (urlvalues.lat && urlvalues.lon && urlvalues.z) {
			var q = this.geo.FromLatLon(urlvalues.lat*1, urlvalues.lon*1);
			this.currentposition.x = q.x;
			this.currentposition.y = q.y;
			this.currentposition.z = urlvalues.z*1;
		} else if (urlvalues.x && urlvalues.y && urlvalues.z) {
			this.currentposition.x = urlvalues.x*1;
			this.currentposition.y = urlvalues.y*1;
			this.currentposition.z = urlvalues.z*1;
		}
		if (urlvalues.routeslat && urlvalues.routeslon && urlvalues.routeflat && urlvalues.routeflon) {
			var rs = this.geo.FromLatLon(urlvalues.routeslat*1, urlvalues.routeslon*1);
			var rf = this.geo.FromLatLon(urlvalues.routeflat*1, urlvalues.routeflon*1);
			this.currentroute = {
				start_point : {x: rs.x, y: rs.y},
				finish_point : {x: rf.x, y: rf.y}
			};
		}
		if (urlvalues.routesx && urlvalues.routesy && urlvalues.routefx && urlvalues.routefy) {
			this.currentroute = {
				start_point : {x: urlvalues.routesx, y:urlvalues.routesy},
				finish_point : {x: urlvalues.routefx, y:urlvalues.routefy}
			};
		}
		if (urlvalues.fullview) {
			this.fullview = true;
		}
		if (urlvalues.embed) {
			this.embed = true;
		}
		if (urlvalues.withoutsearch) {
			this.without_search = true;
		}
		if (urlvalues.hidetraffic) {
			this.hidetraffic = true;
		}
		if (urlvalues.utext) {
			if (urlvalues.gx == undefined) {
				var q = {x: this.currentposition.x, y: this.currentposition.y};
			} else {
				var q = this.geo.FromLatLon(urlvalues.gy*1, urlvalues.gx*1);
			}
			if (urlvalues.gz == undefined) {
				q.z = this.currentposition.z;
			} else {
				q.z = urlvalues.gz*1;
			}
			if (/*isMSIE || */BrowserDetect.browser=='Opera') {
				var val = urlvalues.utext;
			} else {
				var val = UTF8.decode(urlvalues.utext);
			}
			if (/*isMSIE || */BrowserDetect.browser=='Opera') {
				var valadd = urlvalues.utextadd;
			} else {
				var valadd = UTF8.decode(urlvalues.utextadd);
			}
			var putpoint = {
				title: val,
				text: valadd,
				x: q.x,
				y: q.y,
				z: q.z
			}
		}
		this.urlvalues = urlvalues;
		if (putpoint) {
			return putpoint;
		}
	}
	this.div.SetPosition = function(x, y, z) {
		this.currentposition.x = x;
		this.currentposition.y = y;
		this.currentposition.z = z;
	}

	this.div.AddVectorSurface = function(id, flags, state) {
		var surface = new this.VectorSurface(id);
		surface.id = id;
		surface.type = 'vector';
		surface.flags = flags;
		surface.visiblebox = this.visiblebox;
		surface.state = (state != undefined) ? state : true;
		surface.drawer = new InitDrawler(surface.div, id+'_canvas');
		surface.drawer.drawler.scale = this.currentposition.z;
		surface.div.style.zIndex = surface.flags.index;
		if (this.currentposition.z >= flags.zoomvalidfrom && this.currentposition.z <= flags.zoomvalidto) {
			this.movablediv.appendChild(surface.div);
			if (flags.autoupdatepriod != undefined) {
				flags.id = id;
				this.StartTimer('autoupdate_'+id, flags);
			}
			if (flags.autoupdatecallfunction != undefined && surface.state) {
				flags.autoupdatecallfunction(surface.drawer, true);
			}

		}
		this.surfaces[surface.id] = surface;
		return true;
	}



	this.div.SetSurfaceState = function(id, state) {
		if (!this.surfaces[id]) {
			return false;
		}
		$S(this.surfaces[id].div, state);
		this.surfaces[id].state = state;
	}
	this.div.AddMatrixSurface = function(id, loadtilefunction, flags, state) {
		if (this.surfaces[id]) {
			return false;
		}
		var surface = new this.MatrixSurface(id, loadtilefunction, flags, this);
		surface.id = id;
		surface.state = (state != undefined) ? state : true;
		surface.loadtilefunction = loadtilefunction;
		surface.TILE_SIZE = this.TILE_SIZE;
		surface.area = this.area;
		surface.TILE_CACHESIZE = this.TILE_CACHESIZE;
		surface.visiblebox = this.visiblebox;
		surface.div.style.zIndex = surface.flags.index;

		if (this.currentposition.z >= flags.zoomvalidfrom && this.currentposition.z <= flags.zoomvalidto) {
			this.movablediv.appendChild(surface.div);
			surface.mosttile = this.geo.Geo2Tile({x:this.geo.map.extent.x2, y:this.geo.map.extent.y1}, this.geo.map.scalelist[this.currentposition.z]);
			if (surface.mosttile.left > 0) {surface.mosttile.xnum++;}
			if (surface.mosttile.top > 0) {surface.mosttile.ynum++;}
			var centertile = this.geo.Geo2Tile({x: this.currentposition.x, y: this.currentposition.y}, this.geo.map.scalelist[this.currentposition.z]);
			centertile.left = this.visiblebox.center.x-centertile.left;
			centertile.top = this.visiblebox.center.y-centertile.top;
			surface.AddTile(centertile);
			surface.AddTiles();
			
			if (flags.autoupdatepriod != undefined) {
				flags.id = id;
				this.StartTimer('autoupdate_'+id, flags);
			}
			if (flags.autoupdatecallfunction != undefined && surface.state) {
				flags.autoupdatecallfunction();
			}
		}
		this.surfaces[surface.id] = surface;
		return true;
	}
	this.div.RemoveSurface = function(id) {
		if (this.surfaces[id].div.parentNode) {
			this.movablediv.removeChild(this.surfaces[id].div);
		}
		delete this.surfaces[id];
	}
	this.div.SetVisuals = function(params) {
		if (params.nodataimage) {
			this.nodataimage = params.nodataimage;
		}
	}
	this.div.CheckKeyboard = function(e) {
		var shiftx, shifty;

		if (!this.keyboardflags.left && !this.keyboardflags.up && !this.keyboardflags.right && !this.keyboardflags.down) {
			this.keyboardinfo.movingstep = 1;
			return;
		}
		if (this.keyboardinfo.movingstep <= this.keyboardinfo.MAP_MAX_STEP) {
			this.keyboardinfo.movingstep += this.keyboardinfo.MAP_INC_STEP;
		}
		shiftx = 0;
		shifty = 0;
		if (this.keyboardflags.left) {
			shiftx = this.keyboardinfo.movingstep;
		}
		if (this.keyboardflags.up) {
			shifty = this.keyboardinfo.movingstep;
		}
		if (this.keyboardflags.right) {
			shiftx = -this.keyboardinfo.movingstep;
		}
		if (this.keyboardflags.down) {
			shifty = -this.keyboardinfo.movingstep;
		}
		this.movablediv.style.left = (this.movabledivoffsets.left+shiftx) + 'px';
		this.movablediv.style.top = (this.movabledivoffsets.top+shifty) + 'px';
		this.RecalcData();
	}

	this.div.PressKeyboard = function(e) {
		var keycode = GetKeyboardCode(e);
		switch (keycode) {
			/* ESC */ 		case 27: this.keyboardflags.esc = true; break;
			/* LEFT ARROW */	case 37: this.keyboardflags.left = true; break;
			/* UP ARROW */	case 38: this.keyboardflags.up = true; break;
			/* RIGHT ARROW */	case 39: this.keyboardflags.right = true; break;
			/* DOWN ARROW */	case 40: this.keyboardflags.down = true; break;
			/* "G" KEY */	case 71:
			if (this.surfaces['points']&&this.surfaces['points'].state) {
				this.surfaces['points'].flags.setstartstoppoint(this.mouse);
			};
			break;
		}
	}
	this.div.UnPressKeyboard = function(e) {
		var keycode = GetKeyboardCode(e);
		switch (keycode) {
			/* ESC */ 		case 27: this.keyboardflags.esc = false; break;
			/* LEFT ARROW */	case 37: this.keyboardflags.left = false; break;
			/* UP ARROW */	case 38: this.keyboardflags.up = false; break;
			/* RIGHT ARROW */	case 39: this.keyboardflags.right = false; break;
			/* DOWN ARROW */	case 40: this.keyboardflags.down = false; break;
		}
	}
	this.div.StartTimer = function(timerid, flags) {
		var mapname = this.id;
		if (timerid == 'addremovetiles' && !this.timers[timerid]) {
			this.timers[timerid] = window.setInterval(function(e) {$(mapname).AddRemoveTiles();}, 0.001);
		}
		if (flags != undefined && flags.id != undefined && timerid == ('autoupdate_'+flags.id) && !this.timers[timerid]) {
			this.timers[timerid] = window.setInterval(function(e) {
				for(var i in $(mapname).surfaces) {
					if (i == flags.id) {
						if ($(mapname).surfaces[i].state) {
							$(mapname).StopTimer(timerid);
							var loadtilefunction = $(mapname).surfaces[i].loadtilefunction;
							var type = $(mapname).surfaces[i].type;
							var state = $(mapname).surfaces[i].state;
							$(mapname).RemoveSurface(i);
							switch (type) {
								case 'tiles' :
								$(mapname).AddMatrixSurface(i, loadtilefunction, flags, state)
								break;
								case 'vector' :
								$(mapname).AddVectorSurface(i, flags, state);
								break;
							}
						}
					}
				}
			}, flags.autoupdatepriod);
		}
	}
	this.div.StopTimer = function(timerid) {
		if (this.timers[timerid]) {
			window.clearInterval(this.timers[timerid]);
			delete this.timers[timerid];
		}
	}
	this.div.AddRemoveTiles =  function() {
		for(var i in this.surfaces) {
			if (this.surfaces[i].tiles != undefined) {
				this.surfaces[i].AddTiles();
				this.surfaces[i].RemoveTiles();
				var centertile = false;
				for (var j in this.surfaces[i].tiles) {
					centertile = this.surfaces[i].tiles[j];
					break;
				};
				if (!centertile) {
					centertile = this.geo.Geo2Tile({x: this.currentposition.x, y: this.currentposition.y}, this.geo.map.scalelist[this.currentposition.z]);
					centertile.left = this.visiblebox.center.x-centertile.left;
					centertile.top = this.visiblebox.center.y-centertile.top;
					this.surfaces[i].AddTile(centertile);
					this.surfaces[i].AddTiles();
					this.surfaces[i].RemoveTiles();
				};
			}
		}
		this.StopTimer('addremovetiles');
	}

	this.div.MatrixSurface = function (id, loadtilefunction, flags, cmap) {
		this.tiles = [];
		this.div = document.createElement('DIV');
		this.group = 'tiles';
		this.flags = flags;
		this.type = 'tiles';
		this.loadtilefunction = loadtilefunction;
		this.stattile = document.createElement('IMG');
		this.stattile.className='tileimage';
		this.AddTile = function(tileinfo) {
			var tile = this.stattile.cloneNode(true);
			tile.xnum = tileinfo.xnum;
			tile.ynum = tileinfo.ynum;
			tile.scale = tileinfo.scale;
			tile.mapid = tileinfo.mapid;
			tile.id = tileinfo.xnum+'x'+tileinfo.ynum;
			tile.group = 'tiles';
			if (this.tiles[tile.id]) return false;
			this.div.appendChild(tile);

			tile.style.left = tileinfo.left-cmap.movabledivoffsets.left+'px';
			tile.style.top = tileinfo.top-cmap.movabledivoffsets.top+'px';
			if (tile.xnum < 0 || tile.ynum < 0 || tile.xnum > this.mosttile.xnum || tile.ynum > this.mosttile.ynum) {
				tile.src = cmap.nodataimage;
			} else {
				tile.src = this.loadtilefunction(tileinfo.xnum, tileinfo.ynum, tileinfo.scale);
			}
			this.tiles[tile.id] = tile;
		}
		this.RemoveTile = function(tile) {
			this.div.removeChild(tile);
			delete this.tiles[tile.id];
		}
		this.AddNearTile = function (tile) {
			var tilebox, r, newtilebox;
			tilebox = {
				x1 : cmap.movabledivoffsets.left+tile.offsetLeft,
				y1 : cmap.movabledivoffsets.top+tile.offsetTop,
				x2 : cmap.movabledivoffsets.left+tile.offsetLeft+cmap.TILE_SIZE,
				y2 : cmap.movabledivoffsets.top+tile.offsetTop+cmap.TILE_SIZE
			};
			r = false;
			newtilebox = {x1: tilebox.x1-this.TILE_SIZE, y1: tilebox.y1, x2: tilebox.x1, y2: tilebox.y2}
			if (!this.tiles[(tile.xnum-1)+'x'+(tile.ynum)] && this.isVisible(newtilebox)) {
				this.AddTile({xnum: (tile.xnum-1), ynum: tile.ynum, left: newtilebox.x1, top: newtilebox.y1, scale: tile.scale, mapid: tile.mapid});
				r = true;
			}
			newtilebox = {x1: tilebox.x1, y1: tilebox.y1-this.TILE_SIZE, x2: tilebox.x2, y2: tilebox.y1}
			if (!this.tiles[(tile.xnum)+'x'+(tile.ynum-1)] && this.isVisible(newtilebox)) {
				this.AddTile({xnum: (tile.xnum), ynum: (tile.ynum-1), left: newtilebox.x1, top: newtilebox.y1, scale: tile.scale, mapid: tile.mapid});
				r = true;
			}
			newtilebox = {x1:tilebox.x2, y1: tilebox.y1, x2: tilebox.x2+this.TILE_SIZE, y2: tilebox.y2}
			if (!this.tiles[(tile.xnum+1)+'x'+(tile.ynum)] && this.isVisible(newtilebox)) {
				this.AddTile({xnum: (tile.xnum+1), ynum: (tile.ynum), left: newtilebox.x1, top: newtilebox.y1, scale: tile.scale, mapid: tile.mapid});
				r = true;
			}
			newtilebox = {x1: tilebox.x1, y1: tilebox.y2, x2: tilebox.x2, y2: tilebox.y2+this.TILE_SIZE}
			if (!this.tiles[(tile.xnum)+'x'+(tile.ynum+1)] && this.isVisible(newtilebox)) {
				this.AddTile({xnum: (tile.xnum), ynum: (tile.ynum+1), left: newtilebox.x1, top: newtilebox.y1, scale: tile.scale, mapid: tile.mapid});
				r = true;
			}
			return r;
		}
		this.isVisible = function(tile) {
			if ((tile.x2 < this.visiblebox.x1-this.TILE_CACHESIZE) || (tile.x1 > this.visiblebox.x2+this.TILE_CACHESIZE) || (tile.y2 < this.visiblebox.y1-this.TILE_CACHESIZE) || (tile.y1 > this.visiblebox.y2+this.TILE_CACHESIZE)) {
				return false;
			}
			return true;
		}
		this.AddTiles = function() {
			var end, result, r;
			end = false;
			while(!end) {
				result = false;
				for(var i in this.tiles) {
					r = this.AddNearTile(this.tiles[i]);
					result |= r;
				}
				end = !result;
			}
		}
		this.RemoveTiles = function() {
			var tilebox;
			for(var i in this.tiles) {
				tilebox = {
					x1 : cmap.movabledivoffsets.left+this.tiles[i].offsetLeft,
					y1 : cmap.movabledivoffsets.top+this.tiles[i].offsetTop,
					x2 : cmap.movabledivoffsets.left+this.tiles[i].offsetLeft+this.TILE_SIZE,
					y2 : cmap.movabledivoffsets.top+this.tiles[i].offsetTop+this.TILE_SIZE
				};
				if (!this.isVisible(tilebox)) {
					this.RemoveTile(this.tiles[i]);
				}
			}
		}
		this.div.id = id;
		this.div.style.position = 'absolute';
		this.div.style.width = '0px';
		this.div.style.height = '0px';
		this.div.style.left = '0px';
		this.div.style.top = '0px';
	}
	this.div.VectorSurface = function(id) {
		this.div = document.createElement('DIV');
		this.div.id = id;
		this.div.style.position = 'absolute';
		this.div.style.width = '0px';
		this.div.style.height = '0px';
		this.div.style.left = '0px';
		this.div.style.top = '0px';
	}
	this.div.CreateMovableDIV = function() {
		this.movablediv = document.createElement("DIV");
		this.movablediv.style.position = 'absolute';
		this.movablediv.style.left = '0px';
		this.movablediv.style.top = '0px';
		this.movablediv.style.width = '0px';
		this.movablediv.style.height = '0px';
		this.movablediv.id = 'movablediv';
		this.appendChild(this.movablediv);
	}
	this.div.RecalcData = function() {
		var mof = CalcOffset(this.movablediv);
		var dx = mof.left - this.movabledivoffsets.left;
		var dy = mof.top - this.movabledivoffsets.top;
		this.movabledivoffsets 	= mof;

		var newvisiblebox = {
			x1: this.offsetParent.offsetLeft+this.offsetLeft,
			y1: this.offsetParent.offsetTop+this.offsetTop,
			x2: this.offsetParent.offsetLeft+this.offsetLeft+this.offsetWidth,
			y2: this.offsetParent.offsetTop+this.offsetTop+this.offsetHeight,
			width: this.offsetWidth,
			height: this.offsetHeight,
			center : {
				x : Math.floor(this.offsetWidth/2),
				y : Math.floor(this.offsetHeight/2)
			}
		}
		var vdx = {};
		vdx.width = this.visiblebox.width - newvisiblebox.width;
		vdx.height = this.visiblebox.height - newvisiblebox.height;
		this.visiblebox = newvisiblebox;
		var xdiff = Math.floor(vdx.width/2);
		var ydiff = Math.floor(vdx.height/2);
		if (xdiff / 2 != Math.round(xdiff/2)) {
			xdiff++;
		}
		if (ydiff / 2 != Math.round(ydiff/2)) {
			ydiff++;
		}
		var screencoords = this.geo.Geo2Screen(this.currentposition.x, this.currentposition.y, this.geo.map.scalelist[this.currentposition.z]);
		var geo = this.geo.Screen2Geo(screencoords.x - dx - xdiff, screencoords.y - dy - ydiff, this.geo.map.scalelist[this.currentposition.z]);
		this.currentposition.x = geo.gx;
		this.currentposition.y = geo.gy;
	}
	this.div.GetMouse = function(e) {
		var mouse = GetMouse(e);
		mouse.x -= this.offsetLeft;
		mouse.y -= this.offsetTop;
		return mouse;
	}
	this.div.GetTarget = function(e) {
		if (isMSIE) {
			return window.event.srcElement;
		}
		return e.target;
	}
	this.div.MouseDown = function(e) {
		var mouse = this.GetMouse(e);
		var target = this.GetTarget(e);
		this.dragging = true;
		this.itisclick = true;

		if (target.group == 'tiles' || ((target.tagName == 'path' || target.tagName == 'CANVAS' || target.tagName == 'shape' || target.tagName == 'svg')&&!target.group)) {
			var onminimap = false;
			if ((this.minimap)&&((target.parentNode.parentNode===this.minimap.div.movablediv)||target.parentNode===this.minimap.div)) {
				mouse.x -= this.minimap.div.offsetLeft;
				mouse.y -= this.minimap.div.offsetTop;
				if (Math.abs(this.dx)>=1) this.dx = 0;
				if (Math.abs(this.dy)>=1) this.dy = 0;
				this.minimap.div.dx = mouse.x-this.minimap.div.movablediv.offsetLeft;
				this.minimap.div.dy = mouse.y-this.minimap.div.movablediv.offsetTop;
				onminimap = true;
			} else {
				this.dx = mouse.x-this.movablediv.offsetLeft;
				this.dy = mouse.y-this.movablediv.offsetTop;
				if (this.minimap) {
					if (Math.abs(this.minimap.div.dx)>=1) this.minimap.div.dx = 0;
					if (Math.abs(this.minimap.div.dy)>=1) this.minimap.div.dy = 0;
				};
			};
			var _self_ = this;
			this.mousemovefunc.add('tiles', function(target, mouse, main) {
				if (target.group == 'tiles' || ((target.tagName == 'path' || target.tagName == 'CANVAS' || target.tagName == 'shape' || target.tagName == 'svg')&&!target.group)) {
					if (!main.dragging) return false;
					if (onminimap&&main.minimap) {
						main.minimap.div.movablediv.style.left = (mouse.x-main.minimap.div.dx-main.minimap.div.offsetLeft) + 'px';
						main.minimap.div.movablediv.style.top = (mouse.y-main.minimap.div.dy-main.minimap.div.offsetTop) + 'px';
						main.minimap.div.StartTimer('addremovetiles');
						main.minimap.div.RecalcData();
						main.MoveMapToGeo({dx: (-main.minimap.div.currentposition.x+main.currentposition.x), dy: (-main.minimap.div.currentposition.y+main.currentposition.y)});
					} else {
						main.movablediv.style.left = (mouse.x-main.dx) + 'px';
						main.movablediv.style.top = (mouse.y-main.dy) + 'px';
						main.StartTimer('addremovetiles');
						main.RecalcData();
						if (main.minimap) {
							main.minimap.div.MoveMapToGeo({dx: (-main.currentposition.x+main.minimap.div.currentposition.x), dy: (-main.currentposition.y+main.minimap.div.currentposition.y)});
						};
					};
				}
				return true;
			}, false, function() {
				if (_self_.itisclick) {
					var diff, ginp;
					if (onminimap) {
						diff = {dx: (_self_.mouse.x-_self_.minimap.div.visiblebox.center.x-_self_.minimap.div.offsetLeft), dy: (_self_.mouse.y-_self_.minimap.div.visiblebox.center.y-_self_.minimap.div.offsetTop)};
						ginp = _self_.minimap.div.geo.GeoInPix(_self_.minimap.div.geo.map.scalelist[_self_.minimap.div.currentposition.z]);
						diff.dx *= ginp.x;
						diff.dy *= ginp.y;
						_self_.JumpToPosition((_self_.currentposition.x+diff.dx), (_self_.currentposition.y+diff.dy), _self_.currentposition.z);
					};
				};
			});
		}
		if (target.group == 'movable') {
			if (target.onmousedownF) target.onmousedownF(mouse,this);
			this.mousemovefunc.add('movable', function(targ, mous, main) {
				if (target.ondragF) {
					target.ondragF(mous,main);
					return true;
				};
				return false;
			}, false, function() {
				if (target.onmouseupF) target.onmouseupF();
			});
		}
		if (target.group == 'zoomer') {
			this.zoomer.div.slider.dy = this.mouse.y-this.zoomer.div.slider.offsetTop;
			this.zoomer.div.slider.moving = true;
			this.mousemovefunc.add('zoomer', function(target, mouse, main) {
				if (target.group == 'zoomer' || main.zoomer.div.slider.moving) {
					if (!main.zoomer.div.slider.moving) return false;
					var newy = mouse.y-main.zoomer.div.slider.dy;
					if (newy >= main.zoomer.div.slider.miny && newy <= main.zoomer.div.slider.maxy) {
						main.zoomer.div.slider.style.top = newy+'px';
					}
				}
				return true;
			});
		}
		if (target.group == 'zoomer_step') {
			this.ChangeZoom(this.visiblebox.center.x, this.visiblebox.center.y,  target.zoomnumber-this.currentposition.z)
		}
		if (target.id == 'zoomin') {
			this.ChangeZoom(this.visiblebox.center.x, this.visiblebox.center.y,  -1)
		}
		if (target.id == 'zoomout') {
			this.ChangeZoom(this.visiblebox.center.x, this.visiblebox.center.y,  1)
		}
		return false;
	}
	this.div.MouseMove = function(e) {
		this.mouse = this.GetMouse(e);
		var target = this.GetTarget(e);
		this.itisclick = false;
		for (var i=0; i<this.mousemovefunc.funcs.length; i++) {
			if (!this.mousemovefunc.funcs[i](target,this.mouse,this)) return true;
		};
		if (target.tagName=="OBJECT") return true;
		this.RecalcData();
		return false;
	}
	this.div.MouseUp = function(e) {
		if (e.button==2) return false;
		this.mouse = this.GetMouse(e);
		var target = this.GetTarget(e);
		if (!this.dragging) return true;

		if (this.dragging) {
			this.mousemovefunc.del('tiles');
			this.mousemovefunc.del('zoomer');
			this.mousemovefunc.del('movable');
			for(var i in this.surfaces) {
				if (this.surfaces[i].type != undefined && this.surfaces[i].type == 'vector') {
					if (this.surfaces[i].state && this.currentposition.z >= this.surfaces[i].flags.zoomvalidfrom && this.currentposition.z <=this.surfaces[i].flags.zoomvalidto) {
						this.surfaces[i].flags.autoupdatecallfunction(this.surfaces[i].drawer);
					}
				}
			}
			this.dragging = false;
		}
		if (target.group == 'zoomer' || this.zoomer.div.slider.moving) {
			if (!this.zoomer.div.slider.moving) return true;
			this.zoomer.div.slider.moving = false;
			newzoom = Math.round((this.zoomer.div.slider.offsetTop-28)/13);
			this.zoomer.div.slider.style.top = newzoom*13+25+3;
			if (newzoom == this.currentposition.z) {
				return false;
			}
			this.ChangeZoom(this.visiblebox.center.x, this.visiblebox.center.y,  newzoom-this.currentposition.z);
		}
		if (this.itisclick) {
			this.itisclick = false;
		};
		this.UpdateLocation();
		return false;
	}
	this.div.DoubleClick = function(e) {
		var mouse = this.GetMouse(e);
		var target = this.GetTarget(e);
		if ((this.minimap)&&((target.parentNode.parentNode===this.minimap.div.movablediv)||target.parentNode===this.minimap.div)) {
			this.ChangeZoom(mouse.x, mouse.y, -1);
			this.minimap.div.ChangeZoom((mouse.x-this.minimap.div.offsetLeft), (mouse.y-this.minimap.div.offsetTop), -1);
			this.JumpToPosition(this.minimap.div.currentposition.x, this.minimap.div.currentposition.y, this.minimap.div.currentposition.z);
		} else this.ChangeZoom(mouse.x, mouse.y, -1);
		return false;
	}

	this.div.ChangeZoom = function(mousex, mousey, delta) {
		// zoomin - delta < 0
		// zoomout - delta > 0
		if (delta == 0) return 0;
		var tempsurface = [];
		var scalefactor = (delta > 0)?-2:1;
		this.currentposition.z += delta;
		if (this.currentposition.z > sizeof(this.geo.map.scalelist)-1) {
			this.currentposition.z = sizeof(this.geo.map.scalelist)-1;
			return;
		}
		if (this.currentposition.z < 0) {
			this.currentposition.z = 0;
			return;
		}
		this.StopTimer('addremovetiles');

		var xdiff = Math.round((this.visiblebox.center.x-mousex)/scalefactor);
		var ydiff = Math.round((this.visiblebox.center.y-mousey)/scalefactor);
		var screencoords = this.geo.Geo2Screen(this.currentposition.x, this.currentposition.y, this.geo.map.scalelist[this.currentposition.z]);
		var geo = this.geo.Screen2Geo(screencoords.x - xdiff, screencoords.y - ydiff, this.geo.map.scalelist[this.currentposition.z]);
		this.currentposition.x = geo.gx;
		this.currentposition.y = geo.gy;
		for(var i in this.surfaces) {
			var loadtilefunction = this.surfaces[i].loadtilefunction;
			var flags = this.surfaces[i].flags;
			var type = this.surfaces[i].type;
			var state = this.surfaces[i].state;
			this.RemoveSurface(i);
			switch (type) {
				case 'tiles' :
				this.AddMatrixSurface(i, loadtilefunction, flags, state)
				break;
				case 'vector' :
				this.AddVectorSurface(i, flags, state);
				break;
			}
		}
		this.zoomer.ShiftToZoom(this.currentposition.z);
		this.SetBookmarkState(this.currentposition.z);
		this.RecalcData();
		this.UpdateLocation();
		if (this.minimap) this.minimap.div.JumpToPosition(this.currentposition.x, this.currentposition.y, this.currentposition.z, this.visiblebox, this.geo.map.scalelist[this.currentposition.z]);
	}
	this.div.Wheel = function(e) {
		var delta;
		var target = this.GetTarget(e);
		if (target.group == 'tiles' || target.group == 'zoomer' ||  target.tagName == 'CANVAS' || target.group == 'zoomer_step' || target.tagName == 'path' || target.tagName == 'shape' || target.tagName == 'svg') {
			delta = 0;
			if (!e) {e = window.event;}
			if (e.wheelDelta) {
				delta = e.wheelDelta/120;
			} else if (e.detail) {delta = -e.detail/3;}
			if (delta > 0) {	delta = -1;} else {delta = 1;}
			if ((this.minimap)&&((target.parentNode.parentNode===this.minimap.div.movablediv)||target.parentNode===this.minimap.div)) {
				this.minimap.div.ChangeZoom((this.mouse.x-this.minimap.div.offsetLeft), (this.mouse.y-this.minimap.div.offsetTop), delta);
				this.JumpToPosition(this.minimap.div.currentposition.x, this.minimap.div.currentposition.y, this.minimap.div.currentposition.z);
			} else this.ChangeZoom(this.mouse.x, this.mouse.y, delta);
			cancelevent(e);
			return false;
		} else {
			return true;
		}
	}
	this.div.UpdateLocation = function(qqq) {
		var before = window.location.href;
		var state = '';
		var route = '';
		var fullview = '';
		var embed = '';
		var withoutsearch = '';
		var hidetraffic = '';
		if (this.geo.map.isgeo) {
			var cr =  this.geo.ToLatLon(this.currentposition.x, this.currentposition.y);
			cr.lat = Math.round(cr.lat*10000)/10000;
			cr.lon = Math.round(cr.lon*10000)/10000;
			state = 'lat='+cr.lat+'&lon='+cr.lon+'&z='+this.currentposition.z;

			if (this.currentroute != undefined && this.currentroute.start_point != undefined) {
				var crs = this.geo.ToLatLon(this.currentroute.start_point.x, this.currentroute.start_point.y);
				crs.lon = Math.round(crs.lon*10000)/10000;
				crs.lat = Math.round(crs.lat*10000)/10000;
				var crf =  this.geo.ToLatLon(this.currentroute.finish_point.x, this.currentroute.finish_point.y);
				crf.lon = Math.round(crf.lon*10000)/10000;
				crf.lat = Math.round(crf.lat*10000)/10000;
				route = '&routeslat='+crs.lat+'&routeslon='+crs.lon+'&routeflat='+crf.lat+'&routeflon='+crf.lon;
			}

		} else {
			var currentcenter = {};
			currentcenter.x = Math.round(this.currentposition.x*10000)/10000;
			currentcenter.y = Math.round(this.currentposition.y*10000)/10000;
			state = 'x='+currentcenter.x+'&y='+currentcenter.y+'&z='+this.currentposition.z;
			if (this.currentroute != undefined && this.currentroute.start_point != undefined) {
				route = '&routesx='+this.currentroute.start_point.x+'&routesy='+this.currentroute.start_point.y+'&routefx='+this.currentroute.finish_point.x+'&routefy='+this.currentroute.finish_point.y;
			}
		}
		if (this.fullview) {
			fullview = '&fullview=1';
		}
		if (this.embed) {
			embed = '&embed=1';
		}
		if (this.without_search) {
			withoutsearch = '&withoutsearch=1'
		}
		if (this.hidetraffic) {
			hidetraffic = '&hidetraffic=1';
		}
		var after = window.location.protocol+'//'+window.location.host + '/#'+state+'&a='+this.area+route+fullview+embed+withoutsearch+hidetraffic;
		window.location.href = after;
		this.UpdateScaler();
	}
	this.div.Scaler = function() {
		this.div = document.createElement('DIV');
		this.div.id = 'scaler';
		this.div.style.zIndex = '999999';

		this.inforer = document.createElement('DIV'); // info
		this.div.appendChild(this.inforer);

		this.ruler = document.createElement('DIV'); // ruler
		this.ruler.style.border = '1px solid #000000';
		this.ruler.style.background = '#639ADC';
		this.ruler.style.height = '3px';
		this.ruler.innerHTML = '<img SRC=i/blankdot.gif>';
		this.ruler.style.width = '100px';
		this.ruler.style.zIndex = '999999';
		this.div.appendChild(this.ruler);
	}
	this.div.ActivateScaler = function() {
		this.scaler = new this.Scaler();
		if (!isIPHONE) this.appendChild(this.scaler.div);
	}
	this.div.UpdateScaler = function() {
		var first = this.geo.Geo2Screen(this.currentposition.x, this.currentposition.y, this.geo.map.scalelist[this.currentposition.z]);
		var second = this.geo.Screen2Geo(first.x+1, first.y, this.geo.map.scalelist[this.currentposition.z]);
		var cr1 =  this.geo.ToLatLon(this.currentposition.x, this.currentposition.y);
		var cr2 =  this.geo.ToLatLon(second.gx, second.gy);
		var meters_in_pixel = this.geo.GeoDistance({x: cr1.lat, y: cr1.lon}, {x: cr2.lat, y: cr2.lon});
		meters_in_pixel = Math.round(100*meters_in_pixel);
		var vals = 'м';
		if (meters_in_pixel > 2000) {
			vals = 'км';
			meters_in_pixel = Math.round(meters_in_pixel/1000*10)/10;
		} else if (meters_in_pixel > 100) {
			meters_in_pixel = Math.round(meters_in_pixel/50)*50;
		}
		this.scaler.inforer.innerHTML = meters_in_pixel+' '+vals;
	}
	this.div.Minimap = function() {
		this.div = document.createElement('DIV');
		this.div.id = 'minimap';
	}
	this.div.ActivateMinimap = function(area, parent) {
		if (!this.minimap) this.minimap = new this.Minimap(this.currentposition.z);

		while (this.minimap.div.childNodes.length>0) {
			this.minimap.div.removeChild(this.minimap.div.firstChild);
		};
		this.minimap.div.style.border = 'none';
		this.minimap.div.style.position = 'absolute';
		this.minimap.div.style.display = 'block';
		this.minimap.div.style.zIndex = '77777';
		//		if ($('banner')) {
		//			this.minimap.div.style.right  = '220px';
		//		} else {
		this.minimap.div.style.right  = '2px';
		//		}
		this.minimap.div.style.bottom  = '15px';
		if (!isIPHONE) cmap.appendChild(this.minimap.div);

		this.minimap.div.SetArea = this.SetArea;
		this.minimap.div.CreateMovableDIV = this.CreateMovableDIV;
		this.minimap.div.AddDefaultSurfaces = this.AddDefaultSurfaces;
		this.minimap.div.AddMatrixSurface = this.AddMatrixSurface;
		this.minimap.div.AddVectorSurface = this.AddVectorSurface;
		this.minimap.div.MatrixSurface = this.MatrixSurface;
		this.minimap.div.VectorSurface = this.VectorSurface;
		this.minimap.div.StartTimer = this.StartTimer;
		this.minimap.div.StopTimer = this.StopTimer;
		this.minimap.div.AddRemoveTiles = this.AddRemoveTiles;
		this.minimap.div.RemoveSurface = this.RemoveSurface;
		this.minimap.div.MoveMapToGeo = this.MoveMapToGeo;
		this.minimap.div.ShiftPositionByDiff = this.ShiftPositionByDiff;
		this.minimap.div.SlideFromTo = this.SlideFromTo;
		this.minimap.div.SmoothExec = this.SmoothExec;

		this.minimap.div.JumpToPosition = function(x, y, z, size, scale) {
			this.currentposition.x = x;
			this.currentposition.y = y;
			this.currentposition.z = z;
			for(var i in this.surfaces) {
				var loadtilefunction = this.surfaces[i].loadtilefunction;
				var flags = this.surfaces[i].flags;
				var type = this.surfaces[i].type;
				var state = this.surfaces[i].state;
				this.RemoveSurface(i);
				switch (type) {
					case 'tiles' :
					this.AddMatrixSurface(i, loadtilefunction, flags, state)
					break;
					case 'vector' :
					this.AddVectorSurface(i, flags, state);
					break;
				}
			}
			this.RecalcData();
			if (size&&scale) this.SetShowBox(size, scale);
		};

		this.minimap.div.ChangeZoom = function(mousex, mousey, delta) {
			if (delta == 0) return 0;
			var tempsurface = [];
			this.currentposition.z += delta;
			if (this.currentposition.z > sizeof(this.geo.map.scalelist)-1) {
				this.currentposition.z = sizeof(this.geo.map.scalelist)-1;
				return;
			}
			if (this.currentposition.z < 0) {
				this.currentposition.z = 0;
				return;
			}
			var scalefactor = (delta > 0)? -0.5 : 1;
			if ((this.geo.map.scalelist[this.currentposition.z-delta]/this.geo.map.scalelist[this.currentposition.z])==1) scalefactor = 0;
			this.StopTimer('addremovetiles');
			var xdiff = Math.round((this.visiblebox.center.x-mousex)*scalefactor);
			var ydiff = Math.round((this.visiblebox.center.y-mousey)*scalefactor);
			var screencoords = this.geo.Geo2Screen(this.currentposition.x, this.currentposition.y, this.geo.map.scalelist[this.currentposition.z]);
			var geo = this.geo.Screen2Geo(screencoords.x - xdiff, screencoords.y - ydiff, this.geo.map.scalelist[this.currentposition.z]);
			this.currentposition.x = geo.gx;
			this.currentposition.y = geo.gy;
			for(var i in this.surfaces) {
				var loadtilefunction = this.surfaces[i].loadtilefunction;
				var flags = this.surfaces[i].flags;
				var type = this.surfaces[i].type;
				var state = this.surfaces[i].state;
				this.RemoveSurface(i);
				switch (type) {
					case 'tiles' :
					this.AddMatrixSurface(i, loadtilefunction, flags, state)
					break;
					case 'vector' :
					this.AddVectorSurface(i, flags, state);
					break;
				}
			};
			this.RecalcData();
		};

		this.minimap.div.visiblebox = {
			x1: this.minimap.div.offsetParent.offsetLeft,
			y1: this.minimap.div.offsetParent.offsetTop,
			x2: this.minimap.div.offsetParent.offsetLeft+this.minimap.div.offsetWidth,
			y2: this.minimap.div.offsetParent.offsetTop+this.minimap.div.offsetHeight,
			width: this.minimap.div.offsetWidth,
			height: this.minimap.div.offsetHeight,
			center : {
				x : Math.floor(this.minimap.div.offsetWidth/2),
				y : Math.floor(this.minimap.div.offsetHeight/2)
			}
		};

		this.minimap.div.RecalcData = function() {
			var mof = {left: this.movablediv.offsetLeft, top: this.movablediv.offsetTop};
			var dx = mof.left - this.movabledivoffsets.left;
			var dy = mof.top - this.movabledivoffsets.top;
			this.movabledivoffsets 	= mof;

			var newvisiblebox = {
				x1: this.offsetParent.offsetLeft,
				y1: this.offsetParent.offsetTop,
				x2: this.offsetParent.offsetLeft+this.offsetWidth,
				y2: this.offsetParent.offsetTop+this.offsetHeight,
				width: this.offsetWidth,
				height: this.offsetHeight,
				center : {
					x : Math.floor(this.offsetWidth/2),
					y : Math.floor(this.offsetHeight/2)
				}
			}
			var vdx = {};
			vdx.width = this.visiblebox.width - newvisiblebox.width;
			vdx.height = this.visiblebox.height - newvisiblebox.height;
			this.visiblebox = newvisiblebox;
			var xdiff = Math.floor(vdx.width/2);
			var ydiff = Math.floor(vdx.height/2);
			if (xdiff / 2 != Math.round(xdiff/2)) {
				xdiff++;
			}
			if (ydiff / 2 != Math.round(ydiff/2)) {
				ydiff++;
			}
			var screencoords = this.geo.Geo2Screen(this.currentposition.x, this.currentposition.y, this.geo.map.scalelist[this.currentposition.z]);
			var geo = this.geo.Screen2Geo(screencoords.x - dx - xdiff, screencoords.y - dy - ydiff, this.geo.map.scalelist[this.currentposition.z]);
			this.currentposition.x = geo.gx;
			this.currentposition.y = geo.gy;
		};
		this.minimap.div.SetShowBox = function(size, scale) {
			var ginp = this.geo.GeoInPix(scale);
			var geosize = {width: (size.width*ginp.x), height: (size.height*ginp.y)};
			ginp = this.geo.GeoInPix(this.geo.map.scalelist[this.currentposition.z]);
			size = {width: (geosize.width/ginp.x), height: (geosize.height/ginp.y)};
			if ((this.offsetWidth/this.offsetHeight)!=(size.width/size.height)) this.SetSize(size.width, size.height);
			if (!this.showbox) {
				this.showbox = document.createElement('DIV');
				this.showbox.style.border = '1px solid #000000';
				this.showbox.style.position = 'absolute';
				this.showbox.group = 'tiles';
				this.showbox.id = 'mini_showbox';
			};
			this.showbox.style.left = Math.round(this.visiblebox.width/2-size.width/2)+'px';
			this.showbox.style.top = Math.round(this.visiblebox.height/2-size.height/2)+'px';
			this.showbox.style.width = Math.round(size.width)+'px';
			this.showbox.style.height = Math.round(size.height)+'px';
			if (!$(this.showbox.id)) this.appendChild(this.showbox);
		};
		this.minimap.div.SetSize = function(w,h) {
			if ($('banner')) {
				var factor = (w>h)? 270/w : 200/h;
			} else {
				var factor = (w>h)? 270/w : 200/h;
			}
			this.style.width = factor*w+'px';
			this.style.height = factor*h+'px';
			this.visiblebox = {
				x1: this.offsetParent.offsetLeft,
				y1: this.offsetParent.offsetTop,
				x2: this.offsetParent.offsetLeft+this.offsetWidth,
				y2: this.offsetParent.offsetTop+this.offsetHeight,
				width: this.offsetWidth,
				height: this.offsetHeight,
				center : {
					x : Math.floor(this.offsetWidth/2),
					y : Math.floor(this.offsetHeight/2)
				}
			};
			this.JumpToPosition(this.currentposition.x, this.currentposition.y, this.currentposition.z)
			this.SetBorder();
			this.SetHeader();
		};

		this.minimap.div.SetBorder = function() {
			if (!this.border) {
				this.border = document.createElement('DIV');
				this.border.id = 'mini_border';
				this.border.group = 'tiles';
				this.border.style.border = '1px solid #639ADC';
				this.border.style.position = 'absolute';
				this.border.style.left = '0px';
				this.border.style.top = '0px';
				this.border.style.zIndex = '999999';
			};
			this.border.style.height = (this.offsetHeight-2)+'px';
			this.border.style.width = (this.offsetWidth-2)+'px';
			if (!$(this.border.id)) this.appendChild(this.border);
		};

		this.minimap.div.SetHeader = function() {
			return;
			if (!this.header) {
				this.header = document.createElement('DIV');
				this.header.id = 'mini_header';
				this.header.group = 'header';
				this.header.style.backgroundColor = '#639ADC';
				this.header.style.zIndex = 999999;
				this.header.style.width = '10px';
				this.header.style.position = 'absolute';
				this.header.style.left = '0px';
				this.header.style.top = '0px';
				this.header.style.cursor = 'pointer';
				var _self = this;
				this.header.onclick = function() {
					if (_self.style.right=='1px') {
						_self.style.right = (-_self.offsetWidth+10)+'px';
					} else {
						_self.style.right = '1px';
					};
				};
			};
			this.header.style.height = this.offsetHeight+'px';
			if (!$(this.header.id)) this.appendChild(this.header);
		};

		this.minimap.div.TILE_SIZE = 256;
		this.minimap.div.TILE_CACHESIZE = 1*this.minimap.div.TILE_SIZE;
		this.minimap.div.timers = {};
		this.minimap.div.surfaces = {};
		this.minimap.div.smooths = {};
		this.minimap.div.currentposition = {};
		this.minimap.div.movabledivoffsets = {left: 0, top:0};
		this.minimap.div.dx = 0;
		this.minimap.div.dy = 0;
		this.minimap.div.CreateMovableDIV();
		this.minimap.div.movablediv.id = 'mini_movablediv';
		this.minimap.div.SetArea(area);
		if (this.minimap.div.geo.map.miniscalelist) {
			this.minimap.div.geo.map.scalelist = this.minimap.div.geo.map.miniscalelist;
		} else {
			var list = this.minimap.div.geo.map.scalelist.length/3;
		};
		this.minimap.div.currentposition.z = this.currentposition.z;
		this.minimap.div.currentposition.x = this.currentposition.x;
		this.minimap.div.currentposition.y = this.currentposition.y;
		this.minimap.div.geo.map.defaultsurfaces[0].flags.zoomvalidto = 8;
		this.minimap.div.geo.map.defaultsurfaces = [this.minimap.div.geo.map.defaultsurfaces[0]];
		this.minimap.div.geo.map.defaultsurfaces[0].id = 'mini_background';
		this.minimap.div.RecalcData();
		this.minimap.div.AddDefaultSurfaces();

		this.minimap.div.SetShowBox(this.visiblebox, this.geo.map.scalelist[this.currentposition.z]);
		this.minimap.div.SetBorder();
		this.minimap.div.SetHeader();
	}
	this.div.Zoomer = function(zoomcount, initzoom) {
		var temp;
		this.div = document.createElement('DIV');
		this.div.id = 'zoomer';
		this.div.style.zIndex = 99999;
		this.div.style.position = 'absolute';
		this.div.style.height = (25*2+13*zoomcount) + 'px';
		this.div.style.width = '28px';
		temp = document.createElement('IMG');
		temp.src = 'i/slider_top.png';
		temp.className='fixpng';
		temp.style.position = 'absolute';
		temp.style.left = '0px';
		temp.style.top = '0px';
		temp.style.width = '28px';
		temp.style.height = '25px';
		temp.id = 'zoomin';
		temp.group = 'zoomer';
		temp.style.cursor = 'pointer';
		this.div.appendChild(temp);
		for(var i=0;i<zoomcount;i++){
			temp = document.createElement('IMG');
			temp.src = 'i/slider_step.png';
			temp.className='fixpng';
			temp.style.position = 'absolute';
			temp.style.left = '0px';
			temp.style.top = (25+i*13)+'px';
			temp.style.width = '28px';
			temp.style.height = '13px';
			temp.style.cursor = 'pointer';
			temp.id = "zoom_step_"+i;
			temp.group = 'zoomer_step';
			temp.zoomnumber = i;
			this.div.appendChild(temp);
		}
		temp = document.createElement('IMG');
		temp.src = 'i/slider_bottom.png';
		temp.className='fixpng';
		temp.style.position = 'absolute';
		temp.style.left = '0px';
		temp.style.bottom = '0px';
		temp.style.width = '28px';
		temp.style.height = '25px';
		temp.id = 'zoomout';
		temp.group = 'zoomer';
		temp.style.cursor = 'pointer';
		this.div.appendChild(temp);

		this.div.slider = document.createElement('IMG');
		this.div.slider.src = 'i/slider_slider.png';
		this.div.slider.className='fixpng';
		this.div.slider.style.position = 'absolute';
		this.div.slider.style.left = '5px';
		this.div.slider.style.top = (initzoom*13+25+3)+'px';
		this.div.slider.style.width = '18px';
		this.div.slider.style.height = '5px';
		this.div.slider.style.cursor = 'pointer';
		this.div.slider.id = 'slider';
		this.div.slider.group = 'zoomer';
		this.div.appendChild(this.div.slider);
		this.div.slider.dy = 0;
		this.div.slider.miny = 22;
		this.div.slider.maxy = (zoomcount-1)*13+25+10;

		this.ShiftToZoom = function(zoomnumber) {
			this.div.slider.style.top = (zoomnumber*13+25+3)+'px';
		}
	}
	this.div.ActivateZoomer = function(hpos, vpos) {
		this.zoomer = new this.Zoomer(this.geo.map.scalelist.length, this.currentposition.z);
		if (hpos >= 0) {
			this.zoomer.div.style.left = hpos+'px';
		}
		if (hpos < 0) {
			this.zoomer.div.style.right = (hpos*-1)+'px';
		}
		if (vpos >= 0) {
			if ($('header')) {
				this.zoomer.div.style.top = ($('header').offsetHeight+vpos)+'px';
			} else {
				this.zoomer.div.style.top = vpos+'px';
			}
		}
		if (vpos < 0) {
			this.zoomer.div.style.bottom = (vpos*-1)+'px';
		}
		if (!isIPHONE) this.appendChild(this.zoomer.div);
	}
	this.div.CheckChangeSize = function() {
		if (this.visiblebox.width != this.currentsize.width || this.visiblebox.height != this.currentsize.height) {
			this.StopTimer('addremovetiles');
			this.StartTimer('addremovetiles');
			this.currentsize.height = this.visiblebox.height;
			this.currentsize.width = this.visiblebox.width;
		}
	}

	this.div.Resize = function() {
		if (this.offsetWidth != this.currentsize.width || this.offsetHeight != this.currentsize.height) {
			this.RecalcData();
			var xdiff = Math.round((this.offsetWidth - this.currentsize.width)/2);
			var ydiff = Math.round((this.offsetHeight - this.currentsize.height)/2);
			if (xdiff / 2 != Math.round(xdiff/2)) {
				xdiff--;
			}
			if (ydiff / 2 != Math.round(ydiff/2)) {
				ydiff--;
			}
			this.currentsize.width = this.offsetWidth;
			this.currentsize.height = this.offsetHeight;
			this.ShiftPositionByDiff(xdiff, ydiff);
			this.UpdateLocation();
			this.ResizeBanner();
			this.ResizePanel();
			if (this.minimap) this.minimap.div.SetShowBox(this.visiblebox, this.geo.map.scalelist[this.currentposition.z]);
			var self = this;
			//			this.SlideFromTo(this.visiblebox.center, {x: (this.visiblebox.center.x+xdiff), y: (this.visiblebox.center.y+ydiff)}, false, function(){
			//				self.UpdateLocation();
			//				self.ResizeBanner();
			//				self.ResizePanel();
			//			});
		}
	}
	this.div.ShiftPositionByDiff = function(diffx, diffy) {
		if (diffx != 0) this.movablediv.style.left = (this.movablediv.offsetLeft + diffx) + 'px';
		if (diffy != 0) this.movablediv.style.top = (this.movablediv.offsetTop + diffy) + 'px';
	}
	this.div.MoveMapToGeo = function(dgeocoords, dcoords) {
		if (!dcoords) dcoords = {dx: 0, dy: 0};
		var geoinpix = this.geo.GeoInPix(this.geo.map.scalelist[this.currentposition.z]);
		dcoords.dx += dgeocoords.dx/geoinpix.x;
		dcoords.dy += dgeocoords.dy/geoinpix.y;
		if (Math.abs(dcoords.dx)>=1) {
			this.movablediv.style.left = (this.movablediv.offsetLeft+Math.round(dcoords.dx)) + 'px';
			dcoords.dx -= Math.round(dcoords.dx);
		};
		if (Math.abs(dcoords.dy)>=1) {
			this.movablediv.style.top = (this.movablediv.offsetTop+Math.round(dcoords.dy)) + 'px';
			dcoords.dy -= Math.round(dcoords.dy);
		};
		this.StartTimer('addremovetiles');
		this.RecalcData();
	}

	this.div.SlideFromTo = function(from, to, progressfunc, endfunction) {
		if (from.x == to.x && from.y == to.y) {
			endfunction();
			return;
		}
		var self = this;
		var slidedata = {};
		var X = to.x-from.x;
		var Y = to.y-from.y;
		var steps = ((Math.abs(X)<Math.abs(Y)))? Math.abs(Y) : Math.abs(X);
		var T = 2;
		var den = 1;

		this.SmoothExec(
		'sliding2',
		function() {
			slidedata.line = [];
			slidedata.func = function() {};
			slidedata.endfunction = function() {};
			if (progressfunc) slidedata.func = progressfunc;
			if (endfunction) slidedata.endfunction = endfunction;
			var stepsizeX, stepsizeY, remX=0, remY=0, l={x:0,y:0}, xx, yy, simbol=1, middle=0;

			stepsizeX = X/steps;
			stepsizeY = Y/steps;

			for (var i=1; i<=steps; i += simbol) {
				remX += (stepsizeX+(i)*(i)*stepsizeX/den);
				remY += (stepsizeY+(i)*(i)*stepsizeY/den);
				xx = Math.round(remX);
				remX -= Math.round(remX);
				yy = Math.round(remY);
				remY -= Math.round(remY);
				l.x += xx;
				l.y += yy;
				if (((Math.abs(l.x)>Math.abs(X/2))||(Math.abs(l.y)>Math.abs(Y/2)))&&(simbol>0)) {
					l.x -= xx;
					l.y -= yy;
					if (((xx>80)||(yy>80))&&(middle>0)) {
						i += simbol;
					};
					xx = X-2*l.x;
					yy = Y-2*l.y;
					l.x += xx;
					l.y += yy;
					simbol = -1;
					if (slidedata.line.length > 0) {
						slidedata.line[slidedata.line.length-1].x += xx;
						slidedata.line[slidedata.line.length-1].y += yy;
					} else {
						slidedata.line.push({x: xx, y: yy});
					}
					continue;
				} else if ((xx>80)||(yy>80)) {
					middle += simbol;
					i -= simbol;
					if (middle==0) i += simbol;
				};
				if ((Math.abs(l.x)>Math.abs(X))||(Math.abs(l.y)>Math.abs(Y))) {
					xx = X-(l.x-xx);
					yy = Y-(l.y-yy);
					i = steps+10;
				};
				slidedata.line.push({x: xx, y: yy});
			};
		},
		function() {
			var curpoint = slidedata.line.shift();
			self.movablediv.style.left = (self.movablediv.offsetLeft+curpoint.x) + 'px';
			self.movablediv.style.top = (self.movablediv.offsetTop+curpoint.y) + 'px';
			self.StartTimer('addremovetiles');
			self.RecalcData();
			slidedata.func();
		},
		function() {
			return (slidedata.line.length == 0);
		},
		function() {
			slidedata.endfunction();
		},
		T
		);
	}

	this.div.BindInput = function(inputelementid, action, callfunction) {
		if ($(inputelementid)) {
			addhandler($(inputelementid), action, callfunction);
		}
	}
	this.div.JumpToPosition = function(x, y, z) {
		var lefttop = this.geo.Geo2Screen(this.currentposition.x, this.currentposition.y, this.geo.map.scalelist[this.currentposition.z]);
		lefttop.x -= this.visiblebox.center.x-this.movabledivoffsets.left;
		lefttop.y -= this.visiblebox.center.y-this.movabledivoffsets.top;

		var newlefttop = this.geo.Geo2Screen(x, y, this.geo.map.scalelist[z]);
		newlefttop.x -= this.visiblebox.center.x-this.movabledivoffsets.left;
		newlefttop.y -= this.visiblebox.center.y-this.movabledivoffsets.top;

		var diff = {dx : lefttop.x - newlefttop.x, dy: lefttop.y - newlefttop.y};
		if ((z == this.currentposition.z) && (Math.abs(diff.dx) < 2000) && (Math.abs(diff.dy) < 2000)) {
			var self = this;
			this.SlideFromTo(this.visiblebox.center, {x: this.visiblebox.center.x+diff.dx, y: this.visiblebox.center.y+diff.dy}, function(){
				if (self.minimap) self.minimap.div.JumpToPosition(self.currentposition.x, self.currentposition.y, self.currentposition.z, self.visiblebox, self.geo.map.scalelist[self.currentposition.z]);
			}, function(){
				if (self.minimap) self.minimap.div.JumpToPosition(self.currentposition.x, self.currentposition.y, self.currentposition.z, self.visiblebox, self.geo.map.scalelist[self.currentposition.z]);
				self.UpdateLocation();
			});
			return;
		} else {
			this.currentposition.x = x;
			this.currentposition.y = y;
			this.currentposition.z = z;
			this.zoomer.ShiftToZoom(this.currentposition.z);
			for(var i in this.surfaces) {
				var loadtilefunction = this.surfaces[i].loadtilefunction;
				var flags = this.surfaces[i].flags;
				var type = this.surfaces[i].type;
				var state = this.surfaces[i].state;
				this.RemoveSurface(i);
				switch (type) {
					case 'tiles' :
					this.AddMatrixSurface(i, loadtilefunction, flags, state)
					break;
					case 'vector' :
					this.AddVectorSurface(i, flags, state);
					break;
				}
			}
		}
		this.RecalcData();
		this.UpdateLocation(true);
		if (this.minimap) this.minimap.div.JumpToPosition(this.currentposition.x, this.currentposition.y, this.currentposition.z, this.visiblebox, this.geo.map.scalelist[this.currentposition.z]);
	}


	this.div.ShowObject = function(target) {
		//		var screencoords = this.geo.Geo2Screen(target.x, target.y, this.geo.map.scalelist[this.currentposition.z]);
		//		var center = this.geo.Geo2Screen(this.currentposition.x, this.currentposition.y, this.geo.map.scalelist[this.currentposition.z]);
		//
		//		var x =  (screencoords.x - this.movabledivoffsets.left - center.x + this.visiblebox.center.x);
		//		var y =  (screencoords.y - this.movabledivoffsets.top - center.y + this.visiblebox.center.y);
		//
		var d = document.createElement('DIV');
		var title = target.title;
		var text = '';
		if (target.alldata && target.alldata.streetadr) {
			title = target.alldata.streetadr;
		} else if (target.text) {
			text = target.text;
		}
		var d1 = document.createElement('DIV');
		d1.className = 'search_results_item_object';
		d1.appendChild(document.createTextNode(title))
		var d2 = document.createElement('DIV');
		d2.appendChild(document.createTextNode(text))
		d2.className = 'search_results_item_object_subinfo';

		d.appendChild(d1);
		d.appendChild(d2);
		d.className = 'pushpin';
		var P = this.router.setanypoint({gx:target.x, gy: target.y}, d);
		var _self_ = this;
		var F = function() {
			if (P.point_properties.style=='svg') {
				if (P.eventscallback == undefined) {
					P.eventscallback = {};
				}
				P.oldprop = {content:  P.content, click: P.eventscallback.onclick};
				P.eventscallback.onclick = F;
				P.content = '<img src="i/bluepoint.gif">';
				_self_.router.changePointProp(P, {style: 'div', position: {x: -10, y: -46}});
			} else {
				if (P.oldprop) {
					P.content = P.oldprop.content;
					P.eventscallback.onclick = P.oldprop.click;
				};
				_self_.router.changePointProp(P, {style: 'svg', buttons: [{color: "rgb(20,100,20)", func: F}]});
			};
		}
		P.point_properties = {
			//			style: 'div',
			border: 1,
			radius: 5,
			fillcolor: 'rgb(255,255,255)',
			closebutton: true,
			//			buttons: [{color: "rgb(20,100,20)", func: F}],
			events: this.router.setpointevents()
		};
		P.point_properties.events.ondrag =  function(){this.div.dcoords.click = false};
		this.router.data2draw({points: [P]}, true);
	}
	this.div.ShowExternalObject = function(target, defstate) {
		var d0 = document.createElement('DIV');
		d0.className = 'pushpin';

		var banpix = document.createElement('IMG');
		banpix.src = target.banpix;
		banpix.style.visibility = 'hidden';

		d0.appendChild(banpix);
		var P = this.router.setanypoint({gx:target.x, gy: target.y}, d0);
		var _self_ = this;
		var _Pself = P;
		P.setState = function(state, first)  {
			var __selfp = this;
			switch(state) {
				case 0:
					this.content = '<div style="width:22px; height:22px; cursor:pointer; background: url('+target.miniicon+')"></div>';
					this.point_properties = {
						ptype : 'external',
						style: 'div',
						noshadow: true,
						border: 1,
						bordercolor: 'rgb(0,71,148)',
						buttons: [],
						radius: 10,
						closebutton: false,
						opacity: 1,
						events: _self_.router.setpointevents(),
						fillcolor: 'rgb(255,255,255)'
					};
					if (this.eventscallback == undefined) {
						this.eventscallback = {};
					}
					this.eventscallback.onclick = function() {
						__selfp.setState(2);
					};
				break;
				case 1:
					var d = document.createElement('DIV');
					d.style.position = 'relative';
					d.style.padding = '10px';
					d.style.width = '200px';

					var d2 = document.createElement('DIV');
					d2.style.position = 'absolute';
					d2.style.left = '-53px';
					d2.style.top = '20px';
					d2.style.width = '22px';
					d2.style.height = '22px';
					d2.style.cursor = 'pointer';
					d2.style.background = 'url('+target.miniicon+')';

					d.appendChild(d2);

					var d3 = document.createElement('DIV');
					var p1 = document.createElement('P');
					p1.className = 'search_results_item_object';
					p1.style.fontWeight ='bold';
					p1.style.whiteSpace = 'nowrap';
					p1.appendChild(document.createTextNode(target.title));
					var p2 = document.createElement('P');
					p2.className = 'search_results_item_object';
					p2.style.whiteSpace = 'normal';
					p2.appendChild(document.createTextNode(target.address));
					d3.appendChild(p1);
					d3.appendChild(p2);

					d.appendChild(d3);
					this.content = d;

					var button = document.createElement('IMG');
					button.style.width = '15px';
					button.style.height = '15px';
					button.src = 'i/bdown.gif';

					this.point_properties = {
						ptype : 'external',
						style: 'svg2',
						noshadow: true,
						border: 2,
						bordercolor: 'rgb(0,71,148)',
						svgposition: {x: 10, y: 2},
						buttons: [{func: function() {__selfp.setState(2)}, object: button}],
						radius: 10,
						opacity: 1,
						closebutton: false,
						events: _self_.router.setpointevents(),
						fillcolor: 'rgb(255,255,255)'
					};
					if (this.eventscallback&&this.eventscallback.onclick)  this.eventscallback.onclick = false;
				break;
				case 2:
					var d = document.createElement('DIV');
					d.style.position = 'relative';
					d.style.padding = '10px';
					d.style.width = '200px';

					var d2 = document.createElement('DIV');
					d2.style.position = 'absolute';
					d2.style.left = '-53px';
					d2.style.top = '20px';
					d2.style.width = '22px';
					d2.style.height = '22px';
					d2.style.cursor = 'pointer';
					d2.style.background = 'url('+target.miniicon+')';

					addhandler(d2, 'click', function(e) {
						__selfp.setState(0);
					});

					var d3 = document.createElement('DIV');
					d3.appendChild(d2);
					var p1 = document.createElement('P');
					p1.className = 'search_results_item_object';
					p1.style.whiteSpace = 'nowrap';
					p1.style.fontWeight ='bold';
					p1.appendChild(document.createTextNode(target.title));
					var p2 = document.createElement('P');
					p2.className = 'search_results_item_object';
					p2.style.whiteSpace = 'normal';
					p2.appendChild(document.createTextNode(target.address));
					d3.appendChild(p1);
					d3.appendChild(p2);

					d.appendChild(d3);

					var d3 = document.createElement('DIV');
					var p1 = document.createElement('P');
					p1.className = 'search_results_item_object';
					p1.style.whiteSpace = 'nowrap';

					var ahref = document.createElement('A');
					ahref.target = '_blank';
					ahref.href = target.link;

					var img = document.createElement('IMG');
					img.src = target.logo;
					img.border = '0';
					img.style.height = '20px';
					img.style.width = target.logox+'px';
					img.style.paddingTop = '10px';
					img.style.paddingBottom = '10px';
					img.style.border = '0px';

					ahref.appendChild(img);

					p1.appendChild(ahref);
					var p2 = document.createElement('P');
					p2.className = 'search_results_item_object';
					p2.style.whiteSpace = 'nowrap';
					p2.appendChild(document.createTextNode('Телефон: '+target.phone));
					p2.style.paddingBottom = '10px';

					var p3 = document.createElement('P');
					p3.className = 'search_results_item_object';
					p3.style.whiteSpace = 'nowrap';
					p3.innerHTML = 'Перейти на <a target=_blank href="'+ target.link+'">www.peugeot.ru</a>';
					p3.style.paddingBottom = '10px';

					var p4 = document.createElement('A');
					p4.className = 'search_results_item_object';
					p4.style.whiteSpace = 'nowrap';
					p4.style.float = 'right';
					p4.style.cursor = 'pointer';
					p4.appendChild(document.createTextNode('Скрыть'));
					p4.style.paddingBottom = '10px';
					addhandler(p4, 'click', function(e) {
						__selfp.setState(0);
					});

					d3.appendChild(p1);
					d3.appendChild(p2);
					d3.appendChild(p3);
					d3.appendChild(p4);

					d.appendChild(d3);
					this.content = d;

					var button = document.createElement('IMG');
					button.style.width = '15px';
					button.style.height = '15px';
					button.src = 'i/bup.gif';

					this.point_properties = {
						ptype : 'external',
						style: 'svg2',
						noshadow: true,
						border: 2,
						bordercolor: 'rgb(0,71,148)',
						svgposition: {x: 10, y: 2},
						buttons: [{func: function() {__selfp.setState(1)}, object: button}],
						radius: 10,
						closebutton: false,
						opacity: 1,
						events: _self_.router.setpointevents(),
						fillcolor: 'rgb(255,255,255)'
					};

				break;
			}
			this.point_properties.events.ondrag =  function(){this.div.dcoords.click = false};
			if (!first) _self_.router.changePointProp(this, this.point_properties);
		}
		P.setState(defstate, true);

		this.router.data2draw({points: [P]}, true);
	}
	this.div.ShowMessage = function(message) {
		if ($('infowindow')) {
			this.removeChild($('infowindow'));
		}
		this.div = document.createElement('DIV');
		this.div.innerHTML = message;
		this.div.className = 'infowindow';
		this.div.id = "infowindow";
		this.appendChild(this.div);
		var temp = document.createElement('DIV');
		temp.style.height = '18px';
		closeimage = document.createElement('IMG');
		closeimage.src = 'i/close.png';
		closeimage.style.cursor = 'pointer';
		closeimage.style.position = 'absolute';
		closeimage.style.right = '2px';
		closeimage.style.bottom = '2px';
		addhandler(closeimage, 'click', function(e) {
			cmap.removeChild($('infowindow'));
		});
		temp.appendChild(closeimage);
		this.div.appendChild(temp);
		this.div.style.width = '300px';
		this.div.style.height = '100px';
		this.div.style.left = Math.round(this.visiblebox.center.x - this.div.offsetWidth/2) + 'px';
		this.div.style.top = Math.round(this.visiblebox.center.y - this.div.offsetHeight/2) + 'px';
		return false;
	}

	this.div.ResizePanel = function() {
		if ($('footer')) {
			this.panel.style.height = ($('footer').offsetTop-$('header').offsetHeight)+'px';
		} else {
			this.panel.style.top = '300px';
		}
		var headerdivoffsetHeight = 0;
		for(var i in this.panel.datas) {
			headerdivoffsetHeight += this.panel.datas[i].headerdiv.offsetHeight;
		}
		for(var i in this.panel.datas) {
			if (this.panel.datas[i].contentdiv) {
				this.panel.datas[i].contentdiv.style.height = (this.panel.offsetHeight - headerdivoffsetHeight-24) +'px';
			}
		}
	}
	this.div.InformPanel = function() {
		this.div = document.createElement('DIV');
		this.div.id = 'informpanel';
		this.div.className = 'searchresultsdiv';
		this.div.style.zIndex = '999999';
		this.div.style.position = 'absolute';
		this.div.style.display = 'none';
		this.div.style.left = '1px';
		this.div.style.width = '400px';
		this.div.style.height = '300px';
		if ($('header')) {
//			this.div.style.top = ($('header').offsetHeight)+'px';
			this.div.style.top = '59px';
		} else {
			this.div.style.top = '0px';
		}
		if ($('footer')) {
//			this.div.style.height = ($('footer').offsetTop-$('header').offsetHeight+18)+'px';
			this.div.style.height = ($('footer').offsetTop-100)+'px';
		} else {
			this.div.style.top = '300px';
		}

		var progressimg = document.createElement('IMG');
		progressimg.src = 'i/progress.gif';
		progressimg.id = 'progress_bar_in_panel';
		progressimg.style.cursor = 'pointer';
		progressimg.style.position = 'absolute';
		progressimg.style.top = '50%';
		progressimg.style.left = '50%';
		progressimg.style.display = 'none';

		this.div.appendChild(progressimg);

		this.appendChild(this.div);

		this.div.EmbedCorrect = function(embed, withoutsearch) {
			if (embed&&!withoutsearch) {
				var chinfpaneldiv = document.createElement('DIV');
				chinfpaneldiv.style.padding = '2px';
				chinfpaneldiv.style.height = '20px';
				var chinfpanel = document.createElement('INPUT');
				chinfpanel.id = 'show_hide_infpanel';
				chinfpanel.type = "button";
				chinfpanel.checked = false;
				chinfpanel.disabled = true;
				chinfpanel.value = ((chinfpanel.checked)? 'скрыть' : 'показать')+' панель информации';
				addhandler(chinfpanel, 'click', function(e) {
					if ($('informpanel')) {
						chinfpanel.checked = !chinfpanel.checked;
						chinfpanel.value = ((chinfpanel.checked)? 'скрыть' : 'показать')+' панель информации';
						$('informpanel').style.visibility = ($('show_hide_infpanel').checked)? 'visible' : 'hidden';
					};
				});
				chinfpaneldiv.appendChild(chinfpanel);
				//chinfpaneldiv.appendChild(document.createTextNode('показать панель информации'));
				if ($('searchformtd')) {
					$('searchformtd').appendChild(chinfpaneldiv);
				}
			};
		}

		this.div.CreateResultObject = function(object) {
			var clean_object = {
				title: object.title.text.replace('&#8470;', '№'),
				text: object.text,
				x: object.x,
				y: object.y,
				z: 0,
				alldata: object
			}
			return clean_object;
		}
		this.div.CreateGroups = function(search_objects) {
			var groups = {};
			for(var i in search_objects) {
				var object = search_objects[i];
				if (!groups[object.group_name]) {
					groups[object.group_name] = {
						data: [],
						title: object.group_name
					};
				}
				groups[object.group_name].data.push(this.CreateResultObject(object))
			}
			return groups;
		}
		this.div.AddResultItem = function(object, i, callback) {
			var item = document.createElement('DIV');

			var maininfo = document.createElement('SPAN');
			maininfo.appendChild(document.createTextNode(object.title));
			maininfo.className = 'search_results_item';
			maininfo.content = object;
			maininfo.id = 'search_results_item_'+i+'_'+object.id;
			item.appendChild(maininfo);

			if (object.text) {
				var subinfo = document.createElement('SPAN');
				object.text = object.text.replace('&quot;', '"');
				object.text = object.text.replace('&quot;', '"');
				object.text = object.text.replace('&quot;', '"');
				object.text = object.text.replace('&quot;', '"');
				subinfo.appendChild(document.createTextNode(' ('+object.text+')'));
				subinfo.className = 'search_results_item_subinfo';
				item.appendChild(subinfo);
			}
			addhandler(maininfo, 'click', function(e) {
				var target = cmap.GetTarget(e);
				if (target.content && target.content.x && target.content.y) {
					callback(target.content);
				}
			});
			return item;
		}
		this.div.datas = {};
		this.div.Clear = function() {
			for(var i in this.datas) {
				if (this.datas[i].headerdiv) {
					this.removeChild(this.datas[i].headerdiv);
					delete this.datas[i].headerdiv;
				}
				if (this.datas[i].contentdiv) {
					this.removeChild(this.datas[i].contentdiv);
					delete this.datas[i].contentdiv;
				}
				if (this.datas[i].footerdiv) {
					this.removeChild(this.datas[i].footerdiv);
					delete this.datas[i].footerdiv;
				}
				delete this.datas[i];
			}
		}
		this.div.Show = function(state) {
			if ($('show_hide_infpanel')) {
				$('show_hide_infpanel').disabled = !state;
				$('show_hide_infpanel').checked = state;
				$('show_hide_infpanel').value = (($('show_hide_infpanel').checked)? 'скрыть' : 'показать')+' панель информации';
				this.style.visibility = (state) ? 'visible' : 'hidden';
				this.style.top = ($('header').offsetHeight)+'px';
				this.style.width = (cmap.offsetWidth<400)? (cmap.offsetWidth-((cmap.offsetWidth<70)? 0 : 50)+'px') : '400px';
			};
			this.style.display = (state) ? 'block' : 'none';

			cmap.scaler.div.style.left = (state) ? (this.offsetWidth+3+'px') : '1px';
			if (!isIPHONE)  {
				//				if ($('bigbanner') && $('bigbanner').style.display == 'none') {
				//$('minibanner').style.left = (state) ? (this.offsetWidth+3+'px') : '1px';
				//				}
			}
			if (state && $('infowindow')) {
				cmap.removeChild($('infowindow'));
			}
		}
		this.div.Progress = function(state) {
			$('progress_bar_in_panel').style.display = (state) ? 'block' : 'none';
		}
		this.div.AddData = function(id, content) {
			this.Progress(false);
			this.datas[id] = {};
			if (content.header) {
				this.datas[id].headerdiv = document.createElement('DIV');
				this.datas[id].headerdiv.style.width = (this.offsetWidth-22) + 'px';
				this.datas[id].headerdiv.style.borderBottom = '1px solid #639ADC';
				this.datas[id].headerdiv.style.padding = '10px';
				this.datas[id].headerdiv.style.height = '12px';
				if (typeof content.header == 'object') {
					this.datas[id].headerdiv.appendChild(content.header);
				} else {
					this.datas[id].headerdiv.innerHTML = content.header;
				}
				if (content.headercloses == true) {
					var closeimg = document.createElement('IMG');
					closeimg.src = 'i/close.gif';
					closeimg.style.cursor = 'pointer';
					closeimg.style.position = 'absolute';
					closeimg.style.top = '10px';
					closeimg.style.right = '8px';
					addhandler(closeimg, 'click', function(e) {
						cmap.DeleteRoute();
						cmap.panel.Clear();
						cmap.panel.Show(false);
					});
					this.datas[id].headerdiv.appendChild(closeimg);
				}
				this.appendChild(this.datas[id].headerdiv);
			}
			if (content.tree) {
				this.datas[id].contentdiv = document.createElement('DIV');
				this.datas[id].contentdiv.style.position = 'absolute';
				this.datas[id].contentdiv.id = 'searchresults_list_content';
				this.datas[id].contentdiv.style.overflow = 'auto';
				this.datas[id].contentdiv.style.left = '0px';
				this.datas[id].contentdiv.style.padding = '10px';
				this.datas[id].contentdiv.style.width = (this.offsetWidth-24) + 'px';
				var headerdivoffsetHeight = 0;
				for(var i in this.datas) {
					headerdivoffsetHeight += this.datas[i].headerdiv.offsetHeight;
				}
				this.datas[id].contentdiv.style.height = (this.offsetHeight - headerdivoffsetHeight-24) +'px';
				this.appendChild(this.datas[id].contentdiv);
				var groups = this.CreateGroups(content.tree);
				for(var i in groups) {
					var group_item = document.createElement('DIV');
					group_item.className = 'search_results_group';
					group_item.id = i;
					group_item.appendChild(document.createTextNode(groups[i].title));
					this.datas[id].contentdiv.appendChild(group_item);
					var group_content_item = document.createElement('DIV');
					group_content_item.id = 'search_results_group_content_'+i;
					group_content_item.style.display ='block';
					this.datas[id].contentdiv.appendChild(group_content_item);
					for(var j in groups[i].data) {
						group_content_item.appendChild(this.AddResultItem(groups[i].data[j], i, function(s) {
							content.onsubmit(s);
						}));
					}
				}
			}
			if (content.list) {
				this.datas[id].contentdiv = document.createElement('DIV');
				this.datas[id].contentdiv.style.position = 'absolute';
				this.datas[id].contentdiv.id = 'searchresults_list_content';
				this.datas[id].contentdiv.style.overflow = 'auto';
				this.datas[id].contentdiv.style.left = '0px';
				this.datas[id].contentdiv.style.width = (this.offsetWidth-3) + 'px';
				var headerdivoffsetHeight = 0;
				for(var i in this.datas) {
					headerdivoffsetHeight += this.datas[i].headerdiv.offsetHeight;
				}
				this.datas[id].contentdiv.style.height = (this.offsetHeight - headerdivoffsetHeight-2) +'px';
				this.appendChild(this.datas[id].contentdiv);
				var clickfunc = function(e) {
					var target = cmap.GetTarget(e);
					if (target.x && target.y) {
						cmap.JumpToPosition(target.x, target.y, 1);
						if (cmap.hightlitedpoint) {
							cmap.hightlitedpoint.removeself();
						}
						if (target.click_from_legend_do_pushpin == false) {
							return;
						}
						var d = document.createElement('DIV');
						d.innerHTML = target.text;
						d.className = 'pushpin';

						cmap.hightlitedpoint = cmap.router.setanypoint({gx:target.x, gy: target.y}, d);
						var F = function() {
							if (cmap.hightlitedpoint.point_properties.style=='svg') {
								if (cmap.hightlitedpoint.eventscallback == undefined) {
									cmap.hightlitedpoint.eventscallback = {};
								}
								cmap.hightlitedpoint.oldprop = {content:  cmap.hightlitedpoint.content, click: cmap.hightlitedpoint.eventscallback.onclick};
								cmap.hightlitedpoint.eventscallback.onclick = F;
								cmap.hightlitedpoint.content = '<img src="i/bluepoint.gif">';
								cmap.router.changePointProp(cmap.hightlitedpoint, {style: 'div', position: {x: -10, y: -46}});
							} else {
								if (cmap.hightlitedpoint.oldprop) {
									cmap.hightlitedpoint.content = cmap.hightlitedpoint.oldprop.content;
									cmap.hightlitedpoint.eventscallback.onclick = cmap.hightlitedpoint.oldprop.click;
								};
								cmap.router.changePointProp(cmap.hightlitedpoint, {style: 'svg', buttons: [{color: "rgb(20,100,20)", func: F}]});
							};
						}
						cmap.hightlitedpoint.point_properties = {
							//			style: 'div',
							border: 1,
							radius: 5,
							fillcolor: 'rgb(255,255,255)',
							closebutton: true,
							//			buttons: [{color: "rgb(20,100,20)", func: F}],
							events: cmap.router.setpointevents(function(){})
						};
						cmap.hightlitedpoint.point_properties.events.ondrag =  function(){this.div.dcoords.click = false};
						cmap.router.data2draw({points: [cmap.hightlitedpoint]}, true);
					}
				}

				var table = document.createElement('TABLE');
				table.cellSpacing = 4;
				table.cellPadding = 0;
				table.width = (this.datas[id].contentdiv.offsetWidth-17) + 'px';
				table.border = 0;
				var c = 0;
				var oTR = '';
				var oTD = '';
				var padd = 0;
				var glen = 0;
				var gtime = 0;
				var gjam = 0;

				for(var i in content.list) {
					var text = content.list[i].text + ' '+content.list[i].obj+'';

					oTR = table.insertRow(i);
					oTR.className="route_results_item";
					oTR.valign = 'top';
					addhandler(oTR, 'click', clickfunc);

					oTD = oTR.insertCell(0);
					oTD.align = 'center';
					oTD.innerHTML = content.list[i].bullet;
					oTD.x = content.list[i].x;
					oTD.y = content.list[i].y;
					oTD.text = text;
					oTD.style.paddingTop = padd+'px';
					oTD.click_from_legend_do_pushpin = content.list[i].click_from_legend_do_pushpin;

					oTD = oTR.insertCell(1);
					oTD.innerHTML = text;
					oTD.x = content.list[i].x;
					oTD.y = content.list[i].y;
					oTD.text = text;
					oTD.style.paddingTop = padd+'px';
					oTD.click_from_legend_do_pushpin = content.list[i].click_from_legend_do_pushpin;

					oTD = oTR.insertCell(2);
					glen += content.list[i].length;
					gtime += content.list[i].time;

					var addtext = "";
					if (content.list[i].length > 0) {
						if (content.list[i].length > 1000) {
							addtext = ' ' + Math.round(content.list[i].length/1000*10)/10 +' км';
						} else {
							addtext = ' ' +content.list[i].length +'м';
						}
					} else {
						switch (content.list[i].angle) {
							case 100:
							case 150:
							addtext = "&rarr;";
							// right
							break;
							case 200:
							case 250:
							addtext = "&larr;";
							// right
							break;
						}
					}
					oTD.align ='right';
					oTD.innerHTML = addtext;
					oTD.style.whiteSpace = 'nowrap';
					oTD.style.paddingRight = '4px';
					oTD.x = content.list[i].x;
					oTD.y = content.list[i].y;
					oTD.text = text;
					oTD.style.paddingTop = padd+'px';
					oTD.click_from_legend_do_pushpin = content.list[i].click_from_legend_do_pushpin;
				}
				oTR = table.insertRow(0);
				oTR.valign = 'top';

				oTD = oTR.insertCell(0);
				oTD.colSpan = 3;
				if (glen > 1000) {
					glen = Math.round(glen/1000*10)/10 +' км';
				} else {
					glen = glen +'м';
				}
				var ghour = parseInt(gtime / (60 * 60));

				var gmin = parseInt(gtime / 60-ghour*60);

				if (ghour < 0) {
					ghour = '00';
				} else if (ghour < 10) {
					ghour = '0'+ghour;
				}
				if (gmin < 1) {
					gmin = '00';
				} else if (gmin < 10) {
					gmin = '0'+gmin;
				}
				oTD.innerHTML = 'Длина маршрута: '+ glen + ' (в пути: ' + ghour + ':' + gmin +')';
				//				oTD.innerHTML += ' Средняя загрузка: '+ Math.round( gjam*100 / sizeof(content.list[i])) + '%';
				oTD.style.paddingTop = padd+'px';
				this.datas[id].contentdiv.appendChild(table);
			}
		}
		return this.div;
	}
	this.div.DeleteRoute = function(id) {
		while(this.router.todraw.points[0]) {
			this.router.todraw.points[0].removeself();
		}
		this.currentroute = false;
		this.UpdateLocation(true);
	}
	this.div.RebuildRoute = function(id) {
		if (this.currentroute) {
			this.panel.Clear();
			var cr = this.currentroute;
			this.DeleteRoute();
			this.currentroute = cr;
			this.panel.Progress(true);
			this.ShowRoute(this.currentroute.start_point, this.currentroute.finish_point);
			this.UpdateLocation();
		}
	}
	this.div.ShowLegend = function(list) {
		this.panel.Clear();
		this.panel.Show(true);
		if ($('show_hide_infpanel')&&$('informpanel')) {
			$('show_hide_infpanel').checked = !$('show_hide_infpanel').checked;
			$('show_hide_infpanel').value = (($('show_hide_infpanel').checked)? 'скрыть' : 'показать')+' панель информации';
			$('informpanel').style.visibility = ($('show_hide_infpanel').checked)? 'visible' : 'hidden';
		};
		var header = document.createElement('DIV');

		var asktraf = document.createElement('SPAN');
		//		asktraf.style.float = 'left';
		var chtraf = document.createElement('INPUT');
		chtraf.id = 'ignore_jams_switch';
		chtraf.type = "checkbox";
		chtraf.checked = chtraf.defaultChecked = this.use_jams_routes;
		addhandler(chtraf, 'click', function(e) {
			cmap.use_jams_routes = $('ignore_jams_switch').checked;
			cmap.RebuildRoute();
		});
		asktraf.appendChild(chtraf);

		asktraf.appendChild(document.createTextNode(' Объезжать пробки?'));
		header.appendChild(asktraf);

		var reverse = document.createElement('A');
		reverse.style.right = '1px';
		reverse.style.position = 'absolute';
		reverse.style.paddingRight = '40px';
		reverse.appendChild(document.createTextNode('Проложить в обратную сторону'));
		addhandler(reverse, 'click', function(e) {
			var s = cmap.currentroute;
			var n = {};
			n.start_point = s.finish_point;
			n.finish_point = s.start_point;
			cmap.currentroute = n;
			cmap.panel.Clear();
			cmap.panel.Progress(true);
			cmap.ShowRoute(n.start_point, n.finish_point);
		});
		header.appendChild(reverse);
		this.panel.AddData('points', {header: header,  list: list, headercloses: true, headerhides: true});
	}
	this.div.ShowRoute = function(from, to) {
		this.DeleteRoute();
		$('routequery1').value = (from.title||from.name||from.text||" ");
		$('routequery2').value = (to.title||to.name||to.text||" ");
		from.x = from.x*1;
		from.y = from.y*1;
		to.x = to.x*1;
		to.y = to.y*1;
		var self = this.router;

		this.currentroute = {
			start_point : from,
			finish_point : to
		};
		this.UpdateLocation();
		var d1 = document.createElement('DIV');
		d1.innerHTML = "Начало маршрута";
		d1.className = 'pushpin';
		var d2 = document.createElement('DIV');
		d2.innerHTML = "Конец маршрута";
		d2.className = 'pushpin';



		var events = this.router.setpointevents();
		//		events.ondrag =  function(){this.div.dcoords.click = false};

		var build_legend = function(mass) {
			var list = [];

			var c = 1;
			for(var pointid in mass.legend) {
				var object = {};
				object.bullet = c;
				object.time = mass.legend[pointid].time;
				object.text = mass.legend[pointid].text;
				object.obj = mass.legend[pointid].obj;
				object.x = mass.geom[mass.legend[pointid].pt_idx].gx;
				object.y = mass.geom[mass.legend[pointid].pt_idx].gy;
				object.length = mass.legend[pointid].length*1;
				object.angle = mass.legend[pointid].angle*1;
				object.jam = mass.legend[pointid].jam*1;
				list.push(object);
				c++;
			}
			cmap.ShowLegend(list);
		}

		this.router.setdata(
		[
		{
			coords: {gx:from.x, gy:from.y},
			content: d1,
			eventscallback: {
				onmousedown_before: function(div) { self.dotransform = true;},
				onmouseup_before: function(div) { self.dotransform = false;},
				onmouseup_after: function(div) {
					$('routequery1').value = '';
					cmap.currentroute.start_point.x = div.start_path.startpoint.geocoords.gx;
					cmap.currentroute.start_point.y = div.start_path.startpoint.geocoords.gy;
					build_legend(div.start_path)
				}
			},
			point_properties : {events: events, border: 1, radius: 5, fillcolor: 'rgb(255,255,255)'}
		},
		{
			coords: {gx:to.x, gy:to.y},
			content: d2,
			eventscallback: {
				onmousedown_before: function(div) { self.dotransform = true;},
				onmouseup_before: function(div) { self.dotransform = false;},
				onmouseup_after: function(div) {
					$('routequery2').value = '';
					cmap.currentroute.finish_point.x = div.end_path.endpoint.geocoords.gx;
					cmap.currentroute.finish_point.y = div.end_path.endpoint.geocoords.gy;
					build_legend(div.end_path)
				}
			},
			point_properties : {events: events, border: 1, radius: 5, fillcolor: 'rgb(255,255,255)'}
		}
		],
		function(mass) {
			self.data2draw(mass, true);
			build_legend(mass.routes[0][0]);
		}
		);

		//		var newzoom = 1*this.geo.NearestScale(this.geo.ComprehensiveScale({x1: from.x, y1: from.y, x2: to.x, y2: to.y}, {width: this.visiblebox.width, height: this.visiblebox.height}));
		//		newzoom += 2;
		//		if (newzoom > this.geo.map.scalelist.length-1) {
		//			newzoom -= 2;
		//		}
		//		this.JumpToPosition(((from.x+to.x)/2), ((from.y+to.y)/2), newzoom);
	}
	this.div.DoRouteSearch = function(querystring1, querystring2) {
		cmap.panel.Show(false);
		if ($('infowindow')) {
			cmap.removeChild($('infowindow'));
		}

		if (!querystring1) {
			this.ShowMessage('Не задан пункт отправления');
			return false;
		}
		if (!querystring2) {
			this.ShowMessage('Не задан пункт назначения');
			return false;
		}
		if (querystring1 == querystring2) {
			this.ShowMessage('Пункт отправления и назначения совпадают');
			return false;
		}
		var searchid = 'rid_'+querystring1;
		var searchself = this;
		querystring1 = querystring1.replace(/\"/g, '\\"');
		querystring2 = querystring2.replace(/\"/g, '\\"');
		querystring1 = encodeURI(querystring1);
		this.MakeSearchRequest(searchid, SEARCH_SERVER+'?query='+querystring1+'&fmt=json', function(sid) {
			//		this.MakeSearchRequest(searchid, SEARCH_SERVER+'?sub=0&rnd='+(Math.round(Math.random()*1000000000))+'&mapid='+this.area+'_ru&layer=*,-metro,-afisha,-afishasearch&expr=%22'+querystring1+'%22&sortby=TEXT%2BM,STREETADR%2BM&crutch=апож', function(sid) {
			var search_objects = [];
			eval('(search_objects='+searchself.requesters[sid].responseText+')');
			if (search_objects['response']['error']) {

				//			if(search_objects[0] && search_objects[0].params && search_objects[0].params.error == 'No matches') {
				searchself.panel.Show(false);
				searchself.ShowMessage('Не найден пункт отправления');
				return false;
			}
			search_objects = search_objects['response']['long']['content']['elements'];
			//			var search_objects = [];
			//			eval(searchself.requesters[sid].responseText);
			//			if(search_objects[0] && search_objects[0].params && search_objects[0].params.error == 'No matches') {
			//				searchself.ShowMessage('Не найден пункт отправления');
			//				return false;
			//			}
			searchself.AskDestination(querystring2, search_objects);
		});
	}
	this.div.AskDestination = function(querystring2, start_point_list) {
		var searchid = 'rid_'+querystring2;
		var searchself = this;
		querystring2 = encodeURI(querystring2);
		this.MakeSearchRequest(searchid, SEARCH_SERVER+'?query='+querystring2+'&fmt=json', function(sid) {
			//		this.MakeSearchRequest(searchid, SEARCH_SERVER+'?sub=0&rnd='+(Math.round(Math.random()*1000000000))+'&mapid='+this.area+'_ru&layer=*,-metro,-afisha,-afishasearch&expr=%22'+querystring2+'%22&sortby=TEXT%2BM,STREETADR%2BM&crutch=апож', function(sid) {
			var search_objects = [];
			eval('(search_objects='+searchself.requesters[sid].responseText+')');
			if (search_objects['response']['error']) {

				//			if(search_objects[0] && search_objects[0].params && search_objects[0].params.error == 'No matches') {
				searchself.panel.Show(false);
				searchself.ShowMessage('Не найден пункт назначения');
				return false;
			}
			search_objects = search_objects['response']['long']['content']['elements'];
			//			var search_objects = [];
			//			eval(searchself.requesters[sid].responseText);
			//			if(search_objects[0] && search_objects[0].params && search_objects[0].params.error == 'No matches') {
			//				searchself.ShowMessage('Не найден пункт отправления');
			//				return false;
			//			}
			//			var search_objects = [];
			//			eval(searchself.requesters[sid].responseText);
			//
			//			if(search_objects[0] && search_objects[0].params && search_objects[0].params.error == 'No matches') {
			//				searchself.ShowMessage('Не найден пункт назначения');
			//				return false;
			//			}

			searchself.panel.Clear();
			searchself.panel.Show(true);
			searchself.panel.AddData('start_point', {
				header: 'Уточните пункт отправления:',
				tree: start_point_list,
				onsubmit: function(target) {
					searchself.panel.Clear();
					searchself.panel.Progress(true);
					searchself.panel.AddData('start_point', {header: 'Пункт отправления: <b>'+(target.name||target.text)+'</b>', headercloses: true, headerhides: true});
					searchself.panel.AddData('finish_point', {
						header: 'Уточните пункт назначения:',
						tree: search_objects,
						onsubmit: function(target2) {
							searchself.panel.Clear();
							searchself.panel.Progress(true);
							searchself.ShowRoute(target, target2);
						}
					});

				}
			});
		});
	}
	this.div.DoSearch = function(querystring) {
		this.panel.Clear();
		if ($('infowindow')) {
			cmap.removeChild($('infowindow'));
		}
		if (!querystring) return;
		var searchid = 'id_'+querystring;
		var searchself = this;
		querystring = querystring.replace(/\"/g, '\\"');
		this.panel.Progress(true);
		if (BrowserDetect.OS=='Windows') {
			querystring = encodeURI(querystring);
		}
		this.MakeSearchRequest(searchid, SEARCH_SERVER+'?query='+querystring+'&fmt=json&mode=all&ipg-nCity='+cmap.geo.map.cid, function(sid) {
			//		this.MakeSearchRequest(searchid, SEARCH_SERVER+'?sub=0&rnd='+(Math.round(Math.random()*1000000000))+'&mapid='+this.area+'_ru&layer=*,-metro,-afisha,-afishasearch&expr=%22'+querystring+'%22&sortby=TEXT%2BM,STREETADR%2BM&crutch=апож', function(sid) {
			var search_objects = [];
			eval('(search_objects='+searchself.requesters[sid].responseText+')');
			if (search_objects['response']['error']) {
				searchself.panel.Show(false);
				searchself.ShowMessage('Не найдено');
				return false;
			}
			search_objects = search_objects['response']['long']['content']['elements'];
			cmap.DeleteRoute();
			cmap.panel.Clear();
			if (cmap.bringfirst==true || sizeof(search_objects) == 1) {
				cmap.bringfirst = false;
				var object = search_objects[0];
				object = searchself.panel.CreateResultObject(object);
				searchself.panel.Show(false);
				cmap.JumpToPosition(object.x, object.y, object.z);
				cmap.ShowObject(object);
			} else {
				// makesort!
				//				d3(dump(search_objects))
				search_objects.sort(
				function(a, b) {
					if (a.text == 'город Москва' && b.text != 'город Москва') {
						return -1;
					} else if (a.text == 'город Москва' && b.text == 'город Москва') {
						return a.dist - b.dist;
					} else {
						return 1;
					}
				}
				);
				//				d3(dump(search_objects))
				searchself.panel.Show(true);
				searchself.panel.AddData('search_result', {
					header: 'Уточните:',
					tree: search_objects,
					headercloses: true,
					headerhides: true,
					onsubmit: function(target) {
						searchself.panel.Show(false);
						cmap.JumpToPosition(target.x, target.y, target.z);
						cmap.ShowObject(target);
					}
				});
			}
		});
	}
	this.div.MakeSearchRequest = function(searchid, url, callbackfunction) {
		if (this.requesters[searchid]) {
			callbackfunction(searchid);
			return;
		}
		var request;
		try {
			request = new XMLHttpRequest();
		} catch (e) {
			request = new ActiveXObject("Microsoft.XMLHTTP");
		}
		request.onreadystatechange = function() {
			if (request.readyState == 4) {
				if (request.status == 200) {
					callbackfunction(searchid);
				} else if (request.status == undefined) {
				} else {
				}
			}
		}
		this.requesters[searchid] = request;
		request.open("GET", url+'&rnd='+(Math.round(Math.random()*1000000000)));
		request.send(null);
	}
	this.div.AddDefaultSurfaces = function() {
		if (this.geo.map.defaultsurfaces != undefined) {
			for(var i in this.geo.map.defaultsurfaces) {
				switch (this.geo.map.defaultsurfaces[i].type) {
					case 'tiles' :
					this.AddMatrixSurface(this.geo.map.defaultsurfaces[i].id, this.geo.map.defaultsurfaces[i].loadtilefunction, this.geo.map.defaultsurfaces[i].flags)
					break;
					case 'vector' :
					this.AddVectorSurface(this.geo.map.defaultsurfaces[i].id, this.geo.map.defaultsurfaces[i].flags);
					break;
				}
			}
		}
	}
	this.div.ResizeBanner = function() {
		if ($('banner')) {
			$('banner').style.top = $('header').offsetHeight + 'px';
//			$('banner').style.height = (this.currentsize.height-$('header').offsetHeight-1) + 'px'; 
		}
	}

	this.div.SetBookmarkStateTo = function(state) {
		for(var p in self.router.todraw.points) {
			var point = self.router.todraw.points[p];
			if (point.point_properties.ptype == 'external') {
				point.setState(state)
			}
		}

	}
	this.div.SetBookmarkState = function(zoomnum) {
		if (!this.bookmark) return false;
		var state = this.bookmark.states[zoomnum];
		this.SetBookmarkStateTo(state);
	}

	this.div.HideBookmarkData = function(obj, hided) {
		obj.style.background = 'url('+hided+')';
		var todel = [];
		for(var p in self.router.todraw.points) {
			var point = self.router.todraw.points[p];
			if (point.point_properties.ptype == 'external') {
				todel.push(point);
			}
		}
		while(todel.length > 0) {
			todel.pop().removeself();
		}

	}
	this.div.ShowBookmarkData = function(obj, opened, xml, state) {
		obj.style.background = 'url('+opened+')';
		var test = RequestURL(xml, function(request) {
			self.ShowGeoRSS(request.responseXML, state);
		});
	}
	this.div.AppendBookmark = function(obj) {
		if (!obj) return false;
		this.bookmark = obj;
		if (obj.area != this.area) return;
		var id = obj.id;
		var hided = obj.hided;
		var opened = obj.opened;
		var xml = obj.xml;
		var div = document.createElement('DIV');
		div.id = 'bookmark';
		div.style.zIndex = '999999';
		div.style.position = 'absolute';
		div.style.cursor = 'pointer';
		div.style.left = '0px';
		div.style.bottom = '0px';
		div.style.width = '237px';
		div.style.height = '43px';
		div.style.background = 'url('+hided+')';
		div.state = false;
		var self = this;
		if ($('footer')) {
			$('footer').appendChild(div);
			$('footer').style.overflow = 'visible';
			if (this.scaler) this.scaler.div.style.left = '238px';
		} else this.appendChild(div);

		var i_stat = document.createElement('IMG');
		i_stat.style.visibility  = 'hidden';
		i_stat.id = 'bookmark_image_banner_pix';
		div.appendChild(i_stat);

		var i_stat2 = document.createElement('IMG');
		i_stat2.style.visibility  = 'hidden';
		i_stat2.id = 'bookmark_image_banner_pix2';
		div.appendChild(i_stat2);

		div.onclick = function(e) {
			var obj = $(self.GetTarget(e).id);
			obj.state = !obj.state;
			if (obj.state) {
				self.ShowBookmarkData(obj, opened, xml, self.bookmark.states[self.currentposition.z]);
				$('bookmark_image_banner_pix').src = 'http://ad.rambler.ru/ban.ban?pg=6833&bn=163124';
				var RndNum4NoCash = Math.round(Math.random() * 1000000000);
				var ar_Tail='unknown'; if (document.referrer) ar_Tail = escape(document.referrer);
				$('bookmark_image_banner_pix2').src = 'http://ad.adriver.ru/cgi-bin/rle.cgi?sid=1&ad=150215&bt=21&pid=280986&bid=540320&bn=540320&rnd='+ RndNum4NoCash + '&tail256=' + ar_Tail;
			} else {
				self.HideBookmarkData(obj, hided);
				$('bookmark_image_banner_pix').src = 'http://ad.rambler.ru/ban.ban?pg=6834&bn=163125';
			}
		}
	}
	this.div.ExternalData = function(path) {
		var self = this;
		var test = RequestURL(path, function(request) {
			self.GeoRSSdata = request.responseXML;
		});
	}
	this.div.ShowGeoRSS = function(xmlDoc, state) {
		var items = xmlDoc.documentElement.getElementsByTagName("item");
		for( var i = 0; i < items.length; i++ ) {
			var itemtags = items.item(i).getElementsByTagName("*");
			var lat, lon, title, link, description, address, phone, logo, link, miniicon, logox, banpix = '';
			for ( var j = 0; j < itemtags.length; j++ ) {
				var tag = itemtags[j].nodeName;
				if (tag == 'geo:lat') {
					lat = itemtags[j].firstChild.data;
				} else if (tag == 'geo:long') {
					lon = itemtags[j].firstChild.data;
				} else if (tag == 'georss:point' || tag == 'point') {
					var ptArr=itemtags[j].firstChild.data.split(" ");
					lat = ptArr[0];
					lon = ptArr[1];
				} else if (tag == 'gml:pos') {
					var ptArr=itemtags[j].firstChild.data.split(" ");
					lat = ptArr[0];
					lon = ptArr[1];
				} else if (tag == 'title') {
					title = itemtags[j].firstChild.data;
				} else if (tag == 'address') {
					address = itemtags[j].firstChild.data;
				} else if (tag == 'phone') {
					phone = itemtags[j].firstChild.data;
				} else if (tag == 'logo') {
					logo = itemtags[j].firstChild.data;
				} else if (tag == 'logox') {
					logox = itemtags[j].firstChild.data;
				} else if (tag == 'miniicon') {
					miniicon = itemtags[j].firstChild.data;
				} else if (tag == 'link') {
					link = itemtags[j].firstChild.data;
				} else if (tag == 'banpix') {
					banpix = itemtags[j].firstChild.data;
				} else if (tag == 'description') {
					description = itemtags[j].firstChild.data;
				}
			}
			var object = {};
			if (title && lat && lon) {
				var temp = this.geo.KrasovskiWGS(lat*1, lon*1);
				var temp2 = this.geo.FromLatLon(temp.lat, temp.lon);
				var object = {
					title: title,
					logox: logox,
					miniicon: miniicon,
					address: address,
					phone: phone,
					logo: logo,
					link: link,
					banpix: banpix,
					x: temp2.x,
					y: temp2.y,
					ptype: 'external'
				}
				this.ShowExternalObject(object, state);
			}
		}
	}
	this.div.smooths = {};
	this.div.SmoothExec = function(id, startfunc, periodicalfunc, checkendfunc, endfunc, speed) {
		var self = this;
		if (this.smooths[id]&&this.smooths[id].interval) {
			window.clearInterval(self.smooths[id].interval);
			self.smooths[id].endfunc();
		};
		this.smooths[id] = {};
		this.smooths[id].startfunc = startfunc;
		this.smooths[id].periodicalfunc = periodicalfunc;
		this.smooths[id].checkendfunc = checkendfunc;
		this.smooths[id].endfunc = endfunc;
		this.smooths[id].startfunc();
		this.smooths[id].interval = window.setInterval(
		function(e) {
			if (self.smooths[id].checkendfunc()) {
				window.clearInterval(self.smooths[id].interval);
				self.smooths[id].endfunc();
				self.smooths[id] = {};
			} else {
				self.smooths[id].periodicalfunc();
			}
		}, speed);
	}
	var str = window.location+'';
	var qpos = str.indexOf('?');
	if (qpos > 0) {
		var str = str.replace('?', '#');
		location.href = str;
		return false;
	};
	this.div.area = null;
	this.div.currentroute = false;
	this.div.surfaces = {};
	this.div.requesters = {};
	this.div.TILE_SIZE = 256;
	this.div.TILE_CACHESIZE = 1*this.div.TILE_SIZE;

	this.div.style.cursor = 'move';
	this.div.keyboardflags = {};
	this.div.keyboardinfo = {
		MAP_MAX_STEP : 20,
		MAP_INC_STEP : 1,
		movingstep : 1
	};
	this.div.timers = {};
	this.div.currentposition = {};
	this.div.movabledivoffsets = {left: 0, top:0};
	this.div.dx = 0;
	this.div.dy = 0;
	this.div.panel = this.div.InformPanel();
	this.div.visiblebox = {
		x1: this.div.offsetParent.offsetLeft+this.div.offsetLeft,
		y1: this.div.offsetParent.offsetTop+this.div.offsetTop,
		x2: this.div.offsetParent.offsetLeft+this.div.offsetLeft+this.div.offsetWidth,
		y2: this.div.offsetParent.offsetTop+this.div.offsetTop+this.div.offsetHeight,
		width: this.div.offsetWidth,
		height: this.div.offsetHeight,
		center : {
			x : Math.floor(this.div.offsetWidth/2),
			y : Math.floor(this.div.offsetHeight/2)
		}
	}
	this.div.defaultposition = false;
	if (position != undefined) {
		this.div.defaultposition = position;
	}
	this.div.use_jams_routes = true;
	this.div.fullview = false;
	this.div.embed = false;
	this.div.without_search = false;
	this.div.hidetraffic = false;
	this.div.query = false;
	this.div.InitRouter();
	this.div.CreateMovableDIV();
	this.div.Setmousemovefunc();
	this.div.ChangeArea(area, true);

	if (this.div.currentroute) {
		this.div.panel.Show(true);
		this.div.panel.Progress(true);
		this.div.RebuildRoute();
	}
	this.div.currentsize = {};
	this.div.currentsize.width = this.div.visiblebox.width;
	this.div.currentsize.height = this.div.visiblebox.height;
	this.div.ResizeBanner();



	var self = this.div;

	addhandler(self, 'mousedown', function(e) { var v = self.MouseDown(e); if (!v) {cancelevent(e);} return v; });
	addhandler(self, 'mouseup', function(e) { var v = self.MouseUp(e); if (!v) {cancelevent(e);} return v; });
	addhandler(document, 'mouseup', function(e) { var v = self.MouseUp(e); if (!v) {cancelevent(e);} return v; });
	addhandler(document, 'mousemove', function(e) { var v = self.MouseMove(e);  if (!v) {cancelevent(e);} return v; });
//	addhandler(self, 'dblclick', function(e) { var v = self.DoubleClick(e);  if (!v) {cancelevent(e);} return v; });


	addhandler(window, 'resize', function(e) {  self.Resize(); });

	//	addhandler(document, 'keydown', function(e) { self.PressKeyboard(e); self.StartTimer('keyboard');  });
	//	addhandler(self, 'keyup', function(e) { self.UnPressKeyboard(e); self.CheckKeyboard(e); self.StopTimer('keyboard'); self.StopTimer('addremovetiles');  });

	addhandler(window, 'DOMMouseScroll', function(e) { self.Wheel(e) });
	self.onmousewheel = self.onmousewheel = self.Wheel; // FF





	return self;

}
