text: /* dCodes Framework */
  (function($) {
  
  	$.panGallery = function (wrapper, settings) {
  
  	var componentInited=false;
  	var componentWrapper = $(wrapper);
  	
  	var isIEbelow9 = false;
  	if ($.browser.msie  && parseInt($.browser.version, 10) < 9) {
  		isIEbelow9 = true;
  	} 
  	
  	/*window.onorientationchange = detectOrientation;
  	function detectOrientation(){
  		if(typeof window.onorientationchange != 'undefined'){
  			if ( orientation == 0 ) {
  				 //Do Something In Portrait Mode
  				 //alert('Portrait 0');
  			}
  			else if ( orientation == 90 ) {
  				 //Do Something In Landscape Mode
  				  //alert('Landscape 90 The screen is turned to the left.');
  			}
  			else if ( orientation == -90 ) {
  				 //Do Something In Landscape Mode
  				  //alert('Landscape -90 The screen is turned to the right.');
  			}
  			else if ( orientation == 180 ) {
  				 //Do Something In Landscape Mode
  				 // alert('Landscape 180 Upside down portrait.');
  			}
  		}
  	}*/
  	var isIOS=false, agent = navigator.userAgent;
  	if(agent.indexOf('iPhone') > -1 || agent.indexOf('iPod') > -1 || agent.indexOf('iPad') > -1) {
  		 isIOS=true;
  		 //ios safari orientation change bug
  		 var metas = document.getElementsByTagName('meta'),i;
  		 for (i=0; i<metas.length; i++) {
  		    if (metas[i].name == "viewport") {
  			  metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
  		    }
  		 }
  		 document.addEventListener("gesturestart", gestureStart, false);
  		 function gestureStart() {
  			for (i=0; i<metas.length; i++) {
  			  if (metas[i].name == "viewport") {
  				metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
  			  }
  			}
  		 }
  	}
  	
  	var retina = window.devicePixelRatio > 1 ? true : false;
  	if (retina) {
  		//alert('retina');
  	}
  	//alert(window.devicePixelRatio);
  
  	
  	
  	
  	
  	var componentFixedSize = settings.componentFixedSize;
  	
  	var _body = $('body');
  	var _window = $(window);
  	var _doc = $(document);
  	
  	centerComponent();
  	
  	var imagePreloader=componentWrapper.find('.imagePreloader');
  	
  	var isMobile = jQuery.browser.mobile;
  	if(!isMobile) isMobile = (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent));//recheck
  	//isMobile=true;
  	
  	var thumbsHorizontal;
  	var flipGallerySides = settings.flipGallerySides;
  	var defaultGallerySide=settings.defaultGallerySide;
  	if(defaultGallerySide=='bottom'){
  		thumbsHorizontal = true;	
  	}else if(defaultGallerySide=='right'){
  		thumbsHorizontal = false;	
  	}else if(defaultGallerySide=='autoselect'){
  		var h = getComponentSizeClear('h'), w = getComponentSizeClear('w');
  		if(h < 500 || w < 500){
  			if(getComponentSizeClear('h') <= w){
  				thumbsHorizontal = false;
  			}else{
  				thumbsHorizontal = true;
  			}
  		}else{
  			thumbsHorizontal = true;//make default on larger screen
  		}
  	}
  	defaultGallerySide=thumbsHorizontal;//save value
  	
  	var thumbsScrollValue=35;
  	var imagePreloaderOrigMarg;
  	if(thumbsHorizontal){//remember this on the beginning before we first apply this
  		imagePreloaderOrigMarg = parseInt(imagePreloader.css('marginTop'),10);
  	}else{
  		imagePreloaderOrigMarg = parseInt(imagePreloader.css('marginLeft'),10);
  	}
  	
  	var windowResizeTimeoutID;
  	var windowResizeTimeout = 500;//execute resize after time finish
  	
  	var reCheckAddressTimeoutID;
  	var reCheckAddressTimeout = 250;//address sometimes doesnt fire on beginning
  	
  	var useInfo=false;
  	var info_wrapper;
  	if(componentWrapper.find('.info_wrapper').length>0){
  		info_wrapper=componentWrapper.find('.info_wrapper');
  		useInfo=true;
  		var checkInfoCloseIntervalID;
  		var checkInfoCloseInterval = 100;
  		var autoOpenDescription=isMobile?false:settings.autoOpenDescription;
  		var info_holder=componentWrapper.find('.info_holder');
  		var info_holderMasker=componentWrapper.find('.info_holderMasker');
  		var info_holderMaskerOrigW = info_holderMasker.width();
  		var infoOpened=false;
  		var infoExist=false;
  		var info_toggle = componentWrapper.find('.info_toggle').css('cursor','pointer').bind('click', toggleInfoHandler);
  		var info_toggleSrc = info_toggle.find('img');
  		var scrollPaneApi;
  		var infoPTag;
  		var infoProposedH = 300;//proposed info height
  		var info_bg=componentWrapper.find('.info_bg');
  		var infoResizeQue=false;//if info display none in pan mode, and resize happens, resize it after we show it
  	}
  
  	var slideshowOn=settings.slideshowOn;
  	var slideshowTimeout = settings.slideshowDelay * 1000;//in miliseconds
  	var slideshowTimeoutID; 
  
  	var loadInterval = 100;//image load check interval
  	var loadIntervalID;
  	
  	var leftCaptionPadding,rightCaptionPadding;
  	
  	var _thumbScrollIntervalID;
  	var current_category;
  	
  	var isSwipe=false;//differentiate swipe and navigate to url on same image
  	
  	var elementsVisible=true;//pan/no pan mode
  	
  	var linkSrc;
  	var targetSrc;
  	
  	var imageStartScale=isMobile ? 'scaled' : settings.imageStartScale;
  	var randomPlay=settings.randomPlay;
  	var loopingOn=true;
  	
  	var thumbWidth;
  	var thumbHeight;
  	
  	var panHolder=componentWrapper.find('.panHolder');
  	
  	if(!isMobile){
  		panHolder.bind("mousemove", function(e){
  			 if(panAbility && imageEnlarged) mouseMoveHandler(e);
  		});
  	}
  	
  	var nextImage=null;//for image crossfade
  	var prevImage = null;
  	var currentImage=null;
  	
  	var thumbWrapper = componentWrapper.find('.thumbWrapper');
  	var thumbHolder = componentWrapper.find('.thumbHolder');
  	
  	var thumb_backward=componentWrapper.find('.thumb_backward').css('cursor','pointer');
  	var thumb_forward=componentWrapper.find('.thumb_forward').css('cursor','pointer');
  	
  	var galleryControls = componentWrapper.find('.galleryControls');
  	
  	var slideshowToggle = componentWrapper.find('.slideshow_toggle').css('cursor','pointer').bind('click',toggleSlideshow);
  	var slideshowToggleSrc = slideshowToggle.find('img');
  	if(slideshowOn) slideshowToggleSrc.attr('src', 'data/icons/slideshow_pause.png');
  	
  	var image_backward = componentWrapper.find('.image_backward').bind('click',backwardHandler).css({opacity: 0,cursor:'pointer'});
  	var image_forward = componentWrapper.find('.image_forward').bind('click',forwardHandler).css({opacity: 0,cursor:'pointer'});
  	
  	var image_backward_height = image_backward.height();
  	var image_forward_height = image_forward.height();
  	
  	var image_sizeToggle = componentWrapper.find('.image_sizeToggle').css('cursor','pointer').bind('click',sizeToggleHandler);
  	var image_sizeToggleSrc = image_sizeToggle.find('img');
  	
  	var thumbArr = [];//holds thumbs
  	var liArr = [];//holds li thumb holders
  	var imageDataArr = [];//holds image data
  	var menuDivArr=[];//for menu disabling
  
  	var allThumbsSize = 0;//for thumbHolder scroll
  	
  	//thumb rollover/out speed, ease
  	var thumbEaseOutType='easeOutSine';
  	var thumbEaseOverType='easeOutExpo';
  	var thumbSpeedOver = 500;
  	var thumbSpeedOut = 700;
  	//thumb left/rigth scroll speed, ease
  	var thumbScrollEase='easeOutSine';
  	var thumbScrollSpeed = 500;
  	
  	var playlistLength;
  	
  	var categoryArr=[];
  	var deepLink;
  	var _addressSet=false;
  	var _swfAddressInited=false;
  	var swfAddressTimeout=500;
  	var swfAddressTimeoutID;
  	var _externalChangeEvent;
  	var useDeeplink=settings.useDeeplink;
  	var startUrl=settings.startUrl;
      var activeCategory;
  	var currentCategory;
  	var activeItem;
  	if(isEmpty(startUrl)){
  		activeCategory=-1;//start with menu
  	}
  	var transitionFinishInterval=100;
  	var transitionFinishIntervalID;
  	
  	var scrollThumbs=false;//scroll thumbs on mouse over
  	 
  	var thumbBackwardSize;
  	var thumbForwardSize;
  	var scrollDifference;
  	
  	var thumbScale = isMobile ? 1 : settings.thumbScale;//thumb rollover scale
  	var thumbScaleWidth;
  	var thumbScaleHeight;
  	
  	var marginRotationCorrection;
  	
  	var imageEnlarged = false;//image enlarged or not
      var panAbility = false;//if image size can be toggled
      var transitionOn = false;	
  	var animatePan = settings.animatePan; //animate image pan
      var imageLoaded = false;
  	
  	var lastActiveMenuItem = null;//for thumb disabling
     
      var imagePanSpeed=800; //image pan
      var imagePanEase="easeOutCirc";
     
      var imageSizeToggleSpeed=500; //toggle image size
      var imageSizeToggleEase="easeOutExpo";
     
      var imageOnOffSpeed=500; //show hide image
      var imageOnOffEase="easeOutSine";
     
      //image pan math
      var panHolderWidth;
      var panHolderHeight;
      var fullImageWidth;
      var fullImageHeight;
  	var imageScaledWidth;
  	var imageScaledHeight;
      var mouseX;
  	var mouseY;
  	var mousePercentX;
  	var mousePercentY;
  	var destX;
  	var destY;
  	var thePosA;
  	var thePosB;
  	var thePosC;
  	var thePosD;
  	var marginLeft;
  	var marginTop;
     
     //*** mobile pan
     
      var div_ref = null,
  	div_half_width = null,
  	div_half_height = null,
  	div_width = null,
  	div_height = null,
  	img_ref = null,
  	img_orig_width = null,
  	img_orig_height = null,
  	img_zoom_width = null,
  	img_zoom_height = null,
  	img_start_left = null,
  	img_start_top = null,
  	img_current_left = null,
  	img_current_top = null,
  	zoom_level = 0,
  	zoom_levels = [],
  	zoom_level_count = [],
  	click_last = 0,
  	origin = null,
  	edgeBoundary=true,//make image edges drag boundary instead of half width/height
  	mobilePanOn=false,
  	mobileZoomInited=false;
  	
  	div_ref = panHolder[0];
  	
  	//************ end mobile pan
     
     
     
      //menu
  	var menuExist=true;
  	var menuThumbRatio;
  	var menuInited=false;
  	var menuBorderWidth;
      var menuToggle;
      var menuWrapper, menuWrapperOrigH;
  	var menuWidth;
  	var menuHeight;
  	var menuHolder;
  	var numberOfMenuItems;
  	var origNumberOfMenuItems;
  	var currentNumberOfMenuItems; 
  	var menuThumbArr=[];//holds menu images
  	
  	var menuRowMaskerArr=[];
  	var menuRowHolderArr=[];
  	var allMenuRowMaskerArr =[];
  	var allMenuRowHolderArr =[];
  	
  	var menuRowMaskerWidth;
  	var menuRowMaskerHeight;
  	var menuRowMaskerOrigWidth,menuRowMaskerOrigHeight;
  	
  	var menu_backward;
  	var menu_forward;
  	var menu_close;
  	
  	var menuRowCounter=0;
  	var menuTransitionOn=false;//menu items transition
  	var menuDirection;//left,right
  	var menuTransitionEase = "easeOutExpo";
  	var menuTransitionTime= 1000;
  	var menuControlsToggleEase = "easeOutSine";
  	var menuControlsToggleTime= 400;
  	var menuPreloading=false;
  	var menuLoaded=false;
  	var menuOpened=false;
  	var menuOpenToggle;
     
      var categoryDataArr = thumbHolder.find("div[class=category]");
  	var categoryLength = categoryDataArr.size();
  	//console.log('categoryLength = ', categoryLength);
     
  	//get data for deeplink
  	var i = 0, j, tempArr, category, len, obj, imgs, img, src, n, n2, str_to_filter;
  	for(i; i < categoryLength;i++){
  		category = $(categoryDataArr[i]);
  		j = 0;
  		tempArr=[];
  		obj = {};
  		
  		str_to_filter = filterAllowedChars( category.attr('data-address'));
  		obj.categoryName = str_to_filter;//get category names
  		//console.log(str_to_filter);
  		obj.mediaName=tempArr;
  		categoryArr.push(obj);
  		
  		imgs = category.find('ul li');
  		len = imgs.length;
  		for(j; j < len;j++){//get media names
  			img = $(imgs[j]);
  			
  			src = img.attr('data-imagePath');
  			n = src.substr(src.lastIndexOf('/')+1);//find last slash
  			n2 = n.substr(0, n.lastIndexOf('.'));//find last dot before extension
  			str_to_filter = filterAllowedChars(n2);
  			tempArr.push(str_to_filter);
  			//console.log(i,j,str_to_filter);
  			
  			/*
  			src = img.attr('data-address');
  			str_to_filter = filterAllowedChars(src);
  			tempArr.push(str_to_filter);
  			*/
  		}
  	}
     
     	var pm_settings = {'randomPlay': randomPlay, 'loopingOn': loopingOn};
  	var _playlistManager = $.playlistManager(pm_settings);
  	$(_playlistManager).bind('ap_PlaylistManager.COUNTER_READY', function(){
  		//console.log('COUNTER_READY');
  		
  		if(useDeeplink){
  		
  			if(!_addressSet){
  				//console.log('...1');
  				$.address.value(findAddress2(_playlistManager.getCounter()));
  				if(!$.address.history()) $.address.history(true);//restore history
  			}else{
  				//console.log('...2');
  				_addressSet=false;
  				disableActiveItem();
  				//switch image containers
  				loadImage();
  			}
  		
  		}else{
  			disableActiveItem();
  			//switch image containers
  			loadImage();
  		}
  	});
  	$(_playlistManager).bind('ap_PlaylistManager.PLAYLIST_END', function(){
  		disableActiveItem();
  	});
     
     	initMenu();
      
  	
  	
  	//*********** swfaddress handling
  	
  	/*
  	http://www.asual.com/jquery/address/docs/
  				
  	internalChange is called when we set value ourselves; 
  	externalChange is called when the URL is changed or the browser backward or forward button is pressed. 
  	
  	I don't want to an AJAX request if there are no query parameters in the URL, which is why I test for an empty object.
  	if($.isEmptyObject(event.parameters))
  	return;
  	  
  	jQuery.address.strict(false);//Note that you need to disable plugin's strict option, otherwise it would add slash symbol immediately after hash symbol, like this: #/11.
  	*/
  	
  	function filterAllowedChars(str) {
  		var allowedChars = "_-";
  		var n = str.length;
  		var returnStr = "";
  		var i = 0;
  		var _char;
  		var z;
  		for (i; i < n; i++) {
  			_char = str.charAt(i).toLowerCase(); //convert to lowercase
  			if (_char == "\\") _char = "/";
  			z = getCharCode(_char);			
  			if ((z >= getCharCode("a") && z <= getCharCode("z")) || (z >= getCharCode("0") && z <= getCharCode("9")) || allowedChars.indexOf(_char) >= 0) {
  				//only accepted characters (this will remove the spaces as well)
  				returnStr += _char;
  			}
  		}
  		return returnStr;
  	}
  	
  	function getCharCode(s) {
  		return s.charCodeAt(0);
  	}
  	
  	if(useDeeplink){
  		//console.log($.address.strict());
  		//$.address.strict(false);
  		//$.address.init(initAddress);
  		$.address.internalChange(internalChange);
  		$.address.externalChange(externalChange);
  	}
  	
  	function initAddress(e) {
  		e.stopPropagation();
  		//console.log("init: ", e.value);
  	}
  	
  	function transitionFinishHandler() {
  		if(!transitionOn){//when module transition finishes
  			if(transitionFinishIntervalID) clearInterval(transitionFinishIntervalID);
  			if(swfAddressTimeoutID) clearTimeout(swfAddressTimeoutID);
  			onChange(_externalChangeEvent);
  		}
  	}
  	
  	function swfAddressTimeoutHandler() {
  		//timeout if user repeatedly pressing back/forward browser buttons to stop default action executing immediatelly
  		if(swfAddressTimeoutID) clearTimeout(swfAddressTimeoutID);
  		onChange(_externalChangeEvent);
  	}
  	
  	function internalChange(e) {
  		e.stopPropagation();
  		if(reCheckAddressTimeoutID) clearTimeout(reCheckAddressTimeoutID);
  		//console.log("internalChange: ", e.value);
  		onChange(e);
  	}
  	
  	function reCheckAddress() {
  		if(reCheckAddressTimeoutID) clearTimeout(reCheckAddressTimeoutID);
  		_addressSet=true;
  		$.address.history(false);//skip the "/"
  		
  		if(!isEmpty(startUrl)){
  			$.address.value(startUrl);
  			if(!$.address.history()) $.address.history(true);//restore history
  		}else{
  			//open menu
  			toggleMenuHandler(true);
  		}
  	}
  	
  	function externalChange(e) {
  		e.stopPropagation();
  		if(reCheckAddressTimeoutID) clearTimeout(reCheckAddressTimeoutID);
  		//console.log("externalChange: ", e.value);
  		_externalChangeEvent = e;
  		
  		if(!transitionOn){
  			if(!_swfAddressInited){
  				//on the beginning onExternalChange fires first, then onInternalChange immediatelly, so skip onExternalChange call
  
  				if(e.value == "/"){
  					//console.log('strict mode off, skip /');
  					
  					_addressSet=true;
  					$.address.history(false);//skip the "/"
  					
  					if(!isEmpty(startUrl)){
  						$.address.value(startUrl);
  						if(!$.address.history()) $.address.history(true);//restore history
  					}else{
  						//open menu
  						toggleMenuHandler(true);
  					}
  					
  				}else if(isEmpty(e.value)){
  					//console.log('strict mode on');
  					_addressSet=true;
  					$.address.history(false);//skip the ""
  					
  					if(!isEmpty(startUrl)){
  						$.address.value(startUrl);
  						if(!$.address.history()) $.address.history(true);//restore history
  					}else{
  						//open menu
  						toggleMenuHandler(true);
  					}
  				}else{
  					//other deeplink start
  					//console.log('other deeplink start');
  					onChange(e);
  				}
  				
  				return;
  			}
  			if(swfAddressTimeoutID) clearTimeout(swfAddressTimeoutID);
  			swfAddressTimeoutID = setTimeout(swfAddressTimeoutHandler, swfAddressTimeout);
  		}else{
  			if(swfAddressTimeoutID) clearTimeout(swfAddressTimeoutID);
  			//wait for transition finish
  			if(transitionFinishIntervalID) clearInterval(transitionFinishIntervalID);
  			transitionFinishIntervalID = setInterval(transitionFinishHandler, transitionFinishInterval);
  		}
  	}
  	
  	function onChange(e) {
  		e.stopPropagation();
  		//console.log("onChange: ", e.value);
  		
  		if(slideshowTimeoutID) clearTimeout(slideshowTimeoutID);
  		
  		if(!_swfAddressInited){
  			_swfAddressInited = true;
  		}
  		
  		deepLink = e.value;
  		if(deepLink.charAt(0) == "/") deepLink = deepLink.substring(1)//check if first character is slash
  		if(deepLink.charAt(deepLink.length - 1) == "/") deepLink = deepLink.substring(0, deepLink.length - 1)//check if last character is slash
  		//console.log("onChange after trim: ", deepLink);
  
  		if(!findAddress(deepLink)){
  			alert('404 page not found, check your deeplinks!');
  			$.address.history(false);//skip invalid url
  			return false;
  		}
  
  		//check for category change
  		if(currentCategory == undefined || currentCategory != activeCategory){
  			cleanCategory();
  		}
  		
  		//console.log('console.log(_playlistManager.getCounter(), activeItem); = ', _playlistManager.getCounter(), activeItem);
  		_addressSet=false;
  		if(_playlistManager.getCounter() != activeItem){
  			//console.log('1a.......');
  			_addressSet=true;
  			if(_playlistManager.getCounter()!=-1)enableActiveItem();
  			_playlistManager.setCounter(activeItem, false);
  		}else{
  			//console.log('2a.......');
  			disableActiveItem();
  			loadImage();
  		}
  	}
  	
  	function findAddress(value){
  		//console.log('findAddress');
  		
  		//var currentURL = window.location.href;
  		//console.log(currentURL);
  		
  		var arr = value.split('/');
  		if(arr.length!=2) return false;
  		//console.log(arr);
  		var category_name=arr[0],media_name=arr[1],categoryFound=false,nameFound=false,i = 0;
  		
  		for(i; i < categoryLength;i++){
  			if(categoryArr[i].categoryName == category_name){
  				//console.log('activeCategory = ', i, ' , category_name = ', category_name);
  				activeCategory = i;
  				categoryFound=true;
  				break;	
  			}
  		}
  		if(!categoryFound) return false;
  	
  		i = 0, arr = categoryArr[activeCategory].mediaName;
  		var len = arr.length;
  		for(i; i < len;i++){
  			if(arr[i] == media_name){
  				//console.log('activeItem = ', i, ' , media_name = ', media_name);
  				activeItem = i;
  				nameFound=true;
  				break;	
  			}
  		}
  		
  		if(!categoryFound || !nameFound){
  			return false;
  		}else{
  			return true;	
  		}
  	}
  	
  	function findCounterByName(value){
  		var found=false, i = 0, arr = categoryArr[activeCategory].mediaName, len = arr.length;
  		for(i; i < len;i++){
  			if(arr[i] == value){
  				//console.log(i, value);
  				activeItem = i;
  				found=true;
  				break;	
  			}
  		}
  		if(!found){
  			return false;
  		}else{
  			return true;	
  		}
  	}
  	
  	function findCategoryByName(value){
  		var found=false, i = 0;
  		for(i; i < categoryLength;i++){
  			if(categoryArr[i].categoryName == value){
  				//console.log(i, value);
  				activeCategory = i;
  				found=true;
  				break;	
  			}
  		}
  		if(!found){
  			return false;
  		}else{
  			return true;	
  		}
  	}
  	
  	function findAddress2(i){//return media name with requested counter
  		//console.log('findAddress2');
  		var arr = categoryArr[activeCategory].mediaName;
  		return categoryArr[activeCategory].categoryName+'/'+arr[i];
  	}
  	
  	//*******************
  	
      function initMenu(){
  		
  		if(categoryLength > 1){
  			menuToggle = componentWrapper.find('.menu_toggle').css('cursor','pointer').bind('click', toggleMenuHandler);
  			menuWrapper = componentWrapper.find('.menuWrapper');
  			menuWrapperOrigH = menuWrapper.height();
  			menuHolder = menuWrapper.find('.menuHolder');
  			
  			//get menu border size
  			menuWidth = menuWrapper.width();
  			menuBorderWidth = Math.abs((menuWidth - menuHolder.width()) / 2);
  			
  			menuRowMaskerOrigWidth = menuHolder.find('.menuRowMasker').width();
  			menuRowMaskerOrigHeight = menuHolder.find('.menuRowMasker').height();
  			//console.log(menuRowMaskerOrigWidth, menuRowMaskerOrigHeight);
  			menuThumbRatio = menuRowMaskerOrigWidth / menuRowMaskerOrigHeight;
  			
  			currentNumberOfMenuItems = origNumberOfMenuItems = menuHolder.find("div[class=menuRowMasker]").size(); 
  			
  			allMenuRowMaskerArr = menuHolder.find('.menuRowMasker');//store all menu rows
  			allMenuRowHolderArr = menuHolder.find('.menuRowHolder');
  			
  			if(!isMobile){
  				allMenuRowHolderArr.each(function(){
  					$(this).bind('mouseover',overMenuItem).bind('mouseout',outMenuItem);
  				});
  			}
  			//zIndex:10 to sit above captions
  			menu_backward=componentWrapper.find('.menu_backward').css({cursor:'pointer', opacity:0, display:'none', zIndex:10}).bind("click", menuBackwardToggle);
  			menu_forward=componentWrapper.find('.menu_forward').css({cursor:'pointer', opacity:0, display:'none', zIndex:10}).bind("click", menuForwardToggle);
  			menu_close=componentWrapper.find('.menu_close').css({cursor: 'pointer', display: 'none', zIndex:10}).bind("click", toggleMenuHandler);
  			
  			var data, categoryItem, i=0;
  			for(i; i < categoryLength; i++){
  				  categoryItem=$(categoryDataArr[i]);
  				  data = {};
  				  data.url=categoryItem.attr('data-menuThumbPath');
  				  data.loaded=false;
  				  data.id=i;
  				  menuThumbArr.push(data);
  			}
  			checkMenuSize();
  			 
  		}else{//remove menu
  			menuExist=false;
  			componentWrapper.find('.menu_toggle').remove();
  			componentWrapper.find('.menuWrapper').remove();
  			galleryControls.removeClass('galleryControls').addClass('galleryControls_noMenu');
  	    }
  		
  		if(!isMobile){
  			thumbWrapper.bind("mousemove", scrollThumbsOnMove);
  		}else{
  			setThumbScroll();
  		}
  		
  		if(!useDeeplink){
  			if(isEmpty(startUrl)){
  				//open menu
  				toggleMenuHandler(true);
  			}else{
  				activeCategory = settings.activeCategory;	
  				activeItem=0;
  				initCategory();
  			}
  		}else{
  			//fix for window.load instead of document.ready
  			/*
  			if(reCheckAddressTimeoutID) clearTimeout(reCheckAddressTimeoutID);
  			reCheckAddressTimeoutID = setTimeout(function(){
  				if(reCheckAddressTimeoutID) clearTimeout(reCheckAddressTimeoutID);
  				reCheckAddress();
  			},reCheckAddressTimeout);	
  			*/
  		}
  	}
  	
  	//*********
     
      function initCategory(){
  		//console.log('initCategory ');
  		currentCategory = activeCategory; 
  		//reset all
  		if(loadIntervalID) clearInterval(loadIntervalID);
  		  
  		if(image_sizeToggleSrc) image_sizeToggleSrc.attr('src', 'data/icons/image_toggle_plus.png');
  		
  		liArr=[];
  		thumbArr = [];
  	    imageDataArr = [];
  		allThumbsSize = 0;
  		 
  		imageEnlarged = false;
  		imageLoaded = false;
  		panAbility = false;
  		infoOpened = false;
  		mobilePanOn=false;
  		isSwipe=false;
  		 
  		var i=0,li,a,thumb,_item, url, obj, target;
  		 
  		current_category = $(categoryDataArr[activeCategory]).css('display','block');
  		  
  		playlistLength =  current_category.find('ul li').size();
  		//console.log('playlistLength = ', playlistLength);
  		//get thumb size
  		thumbWidth = parseInt(current_category.attr('data-thumbWidth'),10);
  		thumbHeight = parseInt(current_category.attr('data-thumbHeight'),10);
  		//console.log(thumbWidth, thumbHeight);
  		
  		/*
  		if(isMobile){
  			var ir = thumbWidth/thumbHeight;//save thumb ratio
  			//set new desired width and height
  			thumbWidth = 70;
  			thumbHeight = thumbWidth * (1/ir);
  			//console.log(thumbWidth, thumbHeight);
  		}else{
  			thumbWidth = parseInt(current_category.attr('data-thumbWidth'),10);
  			thumbHeight = parseInt(current_category.attr('data-thumbHeight'),10);
  		}
  		*/
  		
  		current_category.find('ul li').each(function() {
  	   		 _item = $(this);
  			 
  			 obj = {};
  			 obj.url = _item.attr('data-imagePath');
  			  //check description
  			 if(_item.attr('data-description') != undefined && !isEmpty(_item.attr('data-description'))){
  				obj.description = _item.attr('data-description');
  			 }
  			 //check link
  			 if(_item.attr('data-link') != undefined && !isEmpty(_item.attr('data-link'))){
  				 obj.link = _item.attr('data-link');
  				 if(_item.attr('data-target') != undefined && !isEmpty(_item.attr('data-target'))){
  					 target =_item.attr('data-target'); 
  				 }else{
  					 target='_blank';
  				 }
  			 	 obj.target = target;
  			 }
  			 imageDataArr.push(obj);
  			 
  			 //load thumbs
  			 url=_item.attr('data-thumbPath') +"?rand=" + (Math.random() * 99999999);
  			 //console.log(url);
  			 
  			 a = $('<a href="#"/>');
  			 
  			 if(thumbsHorizontal){
  				 li = $('<li/>').addClass('thumbs').append(a).appendTo(thumbHolder);
  			 }else{
  				 li = $('<li/>').addClass('thumbs_v').append(a).appendTo(thumbHolder);
  			 }
  			 
  			 thumb = $(new Image()).attr('data-id',i).bind('click', clickPlaylistItem).appendTo(a).css({
  				display: 'block',
  				width: thumbWidth+'px',
  				height: thumbHeight+'px',
  				opacity: isIEbelow9 ? 1 : 0
  			 }).load(function() {
  				 //console.log($(this));
  				 $(this).stop().animate({opacity: 1}, 500);//fade in thumb
  			 }).error(function(e) {
  				 //console.log("error " + e);
  			 }).attr('src', url);
  			 
  			 thumbArr.push(thumb);
  			 liArr.push(li);
  			 
  			 if(!isMobile){
  				 thumb.bind('mouseover', overPlaylistItem);
  				 thumb.bind('mouseout', outPlaylistItem);
  			 }
  			 i++;
  	    });
  	 
  		thumbScaleWidth = thumbWidth * thumbScale;//thumb scaled width, height
  		thumbScaleHeight = thumbHeight * thumbScale;
  		
  		makeThumbHolder();
  		
  		checkThumbScroll();
  		
  		alignImageControls();//because of diff sized thumbs
  		
  		_playlistManager.setPlaylistItems(playlistLength);
  		if(!useDeeplink){
  			_playlistManager.setCounter(activeItem, false);
  		}
  	}
  	 
  	//********* THUMBS
  	 
  	function _scrollThumbsBack() {
  		var value;
  		if(thumbsHorizontal){
  			value = parseInt(thumbHolder.css('left'),10);
  			value+=thumbsScrollValue;
  			if(value > 0){
  				if(_thumbScrollIntervalID) clearInterval(_thumbScrollIntervalID);
  				value = 0;
  			}
  			thumbHolder.css('left', value+'px');
  		}else{
  			value = parseInt(thumbHolder.css('top'),10);
  			value+=thumbsScrollValue;
  			if(value > 0){
  				if(_thumbScrollIntervalID) clearInterval(_thumbScrollIntervalID);
  				value = 0;
  			}
  			thumbHolder.css('top', value+'px');
  		}
  		return false;
  	}
  	
  	function _scrollThumbsForward() {
  		var value;
  		if(thumbsHorizontal){
  			value = parseInt(thumbHolder.css('left'),10);
  			value-=thumbsScrollValue;
  			if(value < getComponentSize('w') - allThumbsSize - scrollDifference){
  				if(_thumbScrollIntervalID) clearInterval(_thumbScrollIntervalID);
  				value = getComponentSize('w')- allThumbsSize - scrollDifference;
  			}
  			thumbHolder.css('left', value+'px');
  		}else{
  			value = parseInt(thumbHolder.css('top'),10);
  			value-=thumbsScrollValue;
  			if(value < getComponentSize('h') - allThumbsSize - scrollDifference){
  				if(_thumbScrollIntervalID) clearInterval(_thumbScrollIntervalID);
  				value = getComponentSize('h')- allThumbsSize - scrollDifference;
  			}
  			thumbHolder.css('top', value+'px');
  		}
  		return false;
  	}
  	 
  	function setThumbScroll(){
  		thumb_backward.bind('mousedown touchstart MozTouchDown', function(){
  			if(_thumbScrollIntervalID) clearInterval(_thumbScrollIntervalID);
  			_thumbScrollIntervalID = setInterval(function() { _scrollThumbsBack(); }, 100);
  			return false;
  		});
  		thumb_backward.bind('mouseup touchend MozTouchUp', function(){
  			if(_thumbScrollIntervalID) clearInterval(_thumbScrollIntervalID);
  			return false;
  		});
  		thumb_forward.bind('mousedown touchstart MozTouchDown', function(){
  			if(_thumbScrollIntervalID) clearInterval(_thumbScrollIntervalID);
  			_thumbScrollIntervalID = setInterval(function() { _scrollThumbsForward(); }, 100);
  			return false;
  		});
  		thumb_forward.bind('mouseup touchend MozTouchUp', function(){
  			if(_thumbScrollIntervalID) clearInterval(_thumbScrollIntervalID);
  			return false;
  		});
  	 }
  	 
  	 function scrollThumbsOnMove(e){
  		//console.log('scrollThumbsOnMove: ', scrollThumbs);
  		if(!componentInited) return;
  		if(scrollThumbs){
  			var z, v, w, h;
  			if(thumbsHorizontal){
  				z = parseInt(thumbWrapper.css('left'),10) + componentWrapper.offset().left, w = (getComponentSize('w')-scrollDifference);
  				v = (w - allThumbsSize)/w * (e.pageX - z);
  				thumbHolder.css('left',v+'px');
  			}else{
  				z = parseInt(thumbWrapper.css('top'),10) + componentWrapper.offset().top, h = (getComponentSize('h')-scrollDifference);
  				v = (h - allThumbsSize)/h * (e.pageY - z);
  				thumbHolder.css('top',v+'px');
  			}
  		}
  		return false;
  	 }
  	 
  	 function checkThumbScroll(){//toggle visiblity of thumb scroll buttons
  	 	 //console.log('checkThumbScroll');
  		 if(thumbsHorizontal){
  			if(allThumbsSize > getComponentSize('w')-scrollDifference){
  				 scrollThumbs = true;
  				 if(!imageEnlarged){
  					 thumb_backward.css({opacity: 1, display:'block'});
  					 thumb_forward.css({opacity: 1, display:'block'});
  				 }
  				 thumbWrapper.css('left',thumbBackwardSize+'px');
  			}else{
  				 scrollThumbs = false;
  				 thumb_backward.css('display', 'none');
  				 thumb_forward.css('display', 'none');
  				 thumbWrapper.css('left',getComponentSize('w')/2-allThumbsSize/2+'px');//center thumbs if lees then component size
  			}
  		 }else{
  			if(allThumbsSize > getComponentSize('h')-scrollDifference){
  				 scrollThumbs = true;
  				 if(!imageEnlarged){
  					 thumb_backward.css({opacity: 1, display:'block'});
  					 thumb_forward.css({opacity: 1, display:'block'});
  				 }
  				 thumbWrapper.css('top',thumbBackwardSize+'px');
  			}else{
  				 scrollThumbs = false;
  				 thumb_backward.css('display', 'none');
  				 thumb_forward.css('display', 'none');
  				 thumbWrapper.css('top',getComponentSize('h')/2-allThumbsSize/2+'px');//center thumbs if lees then component size
  			}
  		 }
  	 }
  	 
  	 function checkThumbScroll2(){//just return scrollThumbs value
  		 if(thumbsHorizontal){
  			if(allThumbsSize > getComponentSize('w')-scrollDifference){
  				 scrollThumbs = true;
  			}else{
  				 scrollThumbs = false;
  			}
  		 }else{
  			if(allThumbsSize > getComponentSize('h')-scrollDifference){
  				 scrollThumbs = true;
  			}else{
  				 scrollThumbs = false;
  			}
  		 }
  	 }
  	 
  	 //*********** MENU
  	  
  	 function preloadMenuRows(){
  		//console.log("preloadMenuRows");
  		var img,url,data=findToPreload(),id;
  		if(data){
  			url = data.url;
  			//console.log("preloading = " + url, ', data.id = ', data.id);
  			
  			img=$(new Image()).css({
  				display: 'block',
  				position: 'relative',
  				top: 0+'px',
  				left: 0+'px',
  				width: 100+'%',
  				height: 100+'%'
  			}).load(function() {
  				id = $(this).attr('data-id');
  				//console.log(id);
  				menuThumbArr[id] = $(this);//save loaded menu images
  				checkMenuLoaded();
  				if(!menuLoaded){
  					if(!menuPreloading){
  						preloadMenuRows();
  					}
  				}else{
  					//console.log(menuThumbArr);
  				}
  			 }).error(function(e) {
  				//console.log("error " + e);
  			 }).attr({'data-id':data.id, 'src': url});
  		 }else{
  			 
  		 }
  	 }
  	 
  	 function findToPreload(){//find to preload
  		 var data,i = 0;
  	  	 for(i; i < categoryLength; i++){
  			if(menuThumbArr[i].loaded == false){
  				data=menuThumbArr[i];
  				menuThumbArr[i].loaded = true;//set loaded immediatelly so it doesnt take this url again on function call
  				break;
  			}
  		 }
  		 return data;
  	 }
  	  
  	 function checkMenuLoaded(){//find if all menu items are loaded
  	     //console.log('checkMenuLoaded');
  		 var i = 0,allLoaded = true;
  	  	 for(i; i < categoryLength; i++){
  			if(menuThumbArr[i].loaded == false){
  				allLoaded=false;
  				break;
  			}
  		 }
  		 if(allLoaded){
  			//console.log('allLoaded');
  			menuLoaded = true; 
  		 } 
  		 return allLoaded;
  	 }
  	
  	 function loadMenuRows(){
  		//console.log('loadMenuRows');
  		var i = menuRowCounter * numberOfMenuItems,len=i + numberOfMenuItems;
  		if(len>categoryLength) len=categoryLength;
  		var loadCounter=0,img,url,id,endLoad = len - i;
  		
  		for(i; i < len; i++){
  			
  			url=menuThumbArr[i].url +"?rand=" + (Math.random() * 99999999);
  			
  			img=$(new Image()).
  			css({
  				display: 'block',
  				position: 'relative',
  				top: 0+'px',
  				left: 0+'px',
  				width: 100+'%',
  				height: 100+'%'
  			}).load(function() {
  				id = $(this).attr('data-id');
  				//console.log(id);
  				menuThumbArr[id] = $(this);//save loaded menu images
  				loadCounter++;
  				if(loadCounter == endLoad){
  					setMenuRows();
  					menuPreloading=false;
  					if(!menuLoaded){
  						preloadMenuRows();
  					}
  				}
  			 }).error(function(e) {
  				 //console.log("error " + e);
  			 }).attr({'data-id': i, 'src': url});
  		 }
  	 }
  	 
  	 function makeMenuCaption(i, div, menuRowHolder){
  		
  		var caption,captionHtml,captionDiv,topCaptionPadding,bottomCaptionPadding, caption_data;  
  		 
  		caption_data = $(categoryDataArr[i]); 
  		 
  		if(caption_data.attr('data-title') == undefined)return false;//no menu caption 
  		 
  		captionHtml=caption_data.attr('data-title');
  		
  		captionDiv = $("<div/>").html(captionHtml).addClass('menu_title').appendTo(componentWrapper);
  		
  		leftCaptionPadding =parseInt(captionDiv.css('paddingLeft'));
  		rightCaptionPadding =parseInt(captionDiv.css('paddingRight'));
  		topCaptionPadding =parseInt(captionDiv.css('paddingTop'));
  		bottomCaptionPadding =parseInt(captionDiv.css('paddingBottom')); 
  		
  		captionDiv.css({width:menuRowMaskerWidth - leftCaptionPadding - rightCaptionPadding+'px', zIndex:1});
  		
  		if(!isMobile){
  			captionDiv.css('top',menuRowMaskerHeight+'px');
  		}else{//opened on mobile
  			captionDiv.css('top',menuRowMaskerHeight-captionDiv.outerHeight()+'px');
  		}
  		
  		captionDiv.appendTo(div);
  		menuRowHolder.data('caption',captionDiv); 
  	 }
  	 
  	 function makeMenuDiv(id){
  		 var div = $('<div/>').
  		 attr({
  			 'data-id': id, 
  			 'data-title':'menuItemDiv'})
  		 .bind('click', clickCategoryItem)
  		 .css({
  				position: 'relative',
  				top: 0+'px',
  				left: 0+'px',
  				width: menuRowMaskerWidth+'px',
  				height: menuRowMaskerHeight+'px',
  				'float': 'left',
  				overflow: 'hidden',
  				cursor: id != undefined ? 'pointer' : 'default'
  		 });
  		 return div;
  	 }
  	
  	 function setMenuRows(time){
  		//console.log('setMenuRows');
  		//console.log('menuRowCounter = ', menuRowCounter, numberOfMenuItems);
  		var i = menuRowCounter * numberOfMenuItems,len=i + numberOfMenuItems,menuRowHolder, img,j = 0,slideDelay = 100,imgInside,div,outDiv,id;
  		//console.log(len, categoryLength);
  		//if(len > categoryLength) len = categoryLength;//we need to remove last items from the list if there are not equal number of menu items for all rows
  		
  		var animTime = time ? time : menuTransitionTime;
  		
  		for(i; i < len; i++){
  			
  			  img=$(menuThumbArr[i]);
  			  //console.log(img);
  			  id = img.attr('data-id');
  			  menuRowHolder = $(menuRowHolderArr[j]);
  			  
  			  if(menuRowHolder.children().size()==0){//first time menu intro
  				  //console.log('first time menu intro');	  
  				  div = makeMenuDiv(id);
  				  if(id != undefined) menuDivArr[id] = div;
  				
  				  //caption
  				  if(id != undefined) makeMenuCaption(i, div, menuRowHolder);
  						
  				  if(id == activeCategory){
  					  div.css('cursor', 'default');
  					  lastActiveMenuItem = div;	 
  				  }
  						
  				  menuRowHolder.css('marginLeft', parseInt(-menuRowMaskerWidth)+'px');//position outside 
  				  div.append(img).appendTo(menuRowHolder);
  						  
  				  if(i==len-1){ //last tween
  					  menuRowHolder.delay(slideDelay * j).animate({marginLeft: 0+'px'},{duration: animTime,easing: menuTransitionEase,complete: endMenuTransition});
  			      }else{
  					  menuRowHolder.delay(slideDelay * j).animate({marginLeft: 0+'px'},{duration: animTime, easing: menuTransitionEase});
  				  }
  				  
  			  }else{//other times while moving through the menu
  				
  				  if(menuDirection=="right"){
  					 //console.log('right');
  					
  					 div = makeMenuDiv(id);
  					 if(id != undefined) menuDivArr[id] = div;
  						
  					 //caption
  					 if(id != undefined) makeMenuCaption(i, div, menuRowHolder);
  						
  					 if(id == activeCategory){
  						 div.css('cursor', 'default');
  						 lastActiveMenuItem = div;	 
  					 }
  						
  					 div.css('marginLeft',parseInt(- menuRowMaskerWidth)+'px').append(img);//position outside 
  					 imgInside = menuRowHolder.find('div[data-title=menuItemDiv]');
  					 div.data('outDiv',imgInside).prependTo(menuRowHolder); 
  						
  					 if(i==len-1){ //last tween
  						
  						div.delay(slideDelay * j).animate({marginLeft: 0+'px'},{
  							duration: animTime, 
  							easing: menuTransitionEase,
  							complete:  function(){
  								var t_div = $(this);
  								outDiv = t_div.data('outDiv');
  								if(t_div.css('title') == 'activeMenuItem'){
  									t_div.css('cursor', 'pointer');
  									lastActiveMenuItem=null;
  								}
  								outDiv.remove();//remove out image
  								endMenuTransition();
  							}
  						});
  				  
  					 }else{
  						 
  						div.delay(slideDelay * j).animate({marginLeft: 0+'px'}, {
  							duration: animTime, 
  							easing: menuTransitionEase,
  							complete:  function(){
  								var t_div = $(this);
  								outDiv =t_div.data('outDiv');
  								if(t_div.css('title') == 'activeMenuItem'){
  									t_div.css('cursor', 'pointer');
  									lastActiveMenuItem=null;
  								}
  								outDiv.remove();//remove out image
  							}
  						});
  					}
  					   
  				}else{//left
  					//console.log('left');
  					
  					div = makeMenuDiv(id);
  					if(id != undefined) menuDivArr[id] = div;
  						
  					//caption
  					if(id != undefined) makeMenuCaption(i, div, menuRowHolder);
  					 
  					if(id == activeCategory){
  						 div.css('cursor', 'default');
  						 lastActiveMenuItem = div;	 
  					}
  					
  					div.append(img);
  					imgInside = $(menuRowHolder.find('div[data-title=menuItemDiv]'));
  					menuRowHolder.append(div);
  					
  					if(i==len-1){ //last tween
  						
  						imgInside.delay(slideDelay * j).animate({marginLeft: parseInt(- menuRowMaskerWidth)+'px'},{
  							duration: animTime, 
  							easing: menuTransitionEase,
  							complete:  function(){
  								outDiv =$(this);
  								if(outDiv.css('title') == 'activeMenuItem'){
  									outDiv.css('cursor', 'pointer');
  									lastActiveMenuItem=null;
  								}
  								outDiv.remove();//remove out image
  								endMenuTransition();
  							}
  						});
  				  
  					 }else{
  						 
  						imgInside.delay(slideDelay * j).animate({marginLeft: parseInt(- menuRowMaskerWidth)+'px'},{
  							duration: animTime, 
  							easing: menuTransitionEase,
  							complete:  function(){
  								outDiv =$(this);
  								if(outDiv.css('title') == 'activeMenuItem'){
  									outDiv.css('cursor', 'pointer');
  									lastActiveMenuItem=null;
  								}
  								outDiv.remove();//remove out image
  							}
  						});
  					 }
  				  }
  			  }
  		   j++;
  		}
  	 }
  		  
  	 function overMenuItem(e){
  		if (!e) var e = window.event;
  		e.cancelBubble = true;
  		if (e.stopPropagation) e.stopPropagation();
  		var currentTarget = $(e.currentTarget);
  		
  		var caption=currentTarget.data('caption');
  		if(!caption) return;
  		var newy=menuRowMaskerHeight - caption.outerHeight()+1;
  		caption.stop().animate({top: newy+'px'}, {duration: 500, easing: 'easeOutQuint'});
  	 }
  		
  	 function outMenuItem(e){
  		if (!e) var e = window.event;
  		e.cancelBubble = true;
  		if (e.stopPropagation) e.stopPropagation();
  		var currentTarget = $(e.currentTarget);
  		
  		var caption=currentTarget.data('caption');
  		if(!caption) return;
  		caption.stop().animate({top: menuRowMaskerHeight+'px'}, {duration: 500, easing: 'easeOutQuint'});
  	}
  	  
  	function hideMenuControls(instant){
  		 if(!instant){
  			  menu_backward.stop().animate({opacity: 0},{
  				   duration: menuControlsToggleTime, 
  				   easing: menuControlsToggleEase,
  				   complete: function() {
  					  menu_backward.css('display', 'none');
  					}
  			  }); 
  			  menu_forward.stop().animate({opacity: 0},{
  				   duration: menuControlsToggleTime, 
  				   easing: menuControlsToggleEase,
  				   complete: function() {
  					  menu_forward.css('display', 'none');
  					}
  			  });
  		}else{
  			menu_backward.css({display:'none', opacity:0});
  			menu_forward.css({display:'none', opacity:0});
  		}
      }
  	
      function showMenuControls(){
  	   //console.log("showMenuControls");
  	   if(categoryLength <= numberOfMenuItems) return;
  	   if(menuRowCounter == 0){//beginning
  		    menu_forward.css('display','block').stop().animate({opacity: 1},{ duration: menuControlsToggleTime, easing: menuControlsToggleEase});
  	   }else if(menuRowCounter ==(Math.ceil(categoryLength/numberOfMenuItems) - 1)){///end
  			menu_backward.css('display','block').stop().animate({opacity: 1},{duration: menuControlsToggleTime, easing: menuControlsToggleEase}); 
  	   }else{//both visible
  			menu_backward.css('display','block').stop().animate({opacity: 1},{duration: menuControlsToggleTime, easing: menuControlsToggleEase}); 
  			menu_forward.css('display','block').stop().animate({opacity: 1},{duration: menuControlsToggleTime, easing: menuControlsToggleEase});  
  	   }
     }
  	   
     function menuBackwardToggle(e){
  	   if(menuTransitionOn) return;
  	   menuTransitionOn = true;
  	   hideMenuControls();
  	   menuRowCounter--;
  	   menuDirection="left";
  	   if(!menuLoaded){
  		   menuPreloading=true;
  	  	   loadMenuRows();
  	   }else{
  		   setMenuRows();
  	   }
  	   return false;
     }
     
     function menuForwardToggle(){
  	   if(menuTransitionOn) return;
  	   menuTransitionOn = true;
  	   hideMenuControls();
  	   menuRowCounter++;
  	   menuDirection="right";
  	   if(!menuLoaded){
  		   menuPreloading=true;
  	  	   loadMenuRows();
  	   }else{
  		   setMenuRows();
  	   }
  	   return false;
     }
  	   
     function endMenuTransition(){
  	   //console.log("endMenuTransition");
  	   showMenuControls();
  	   menuTransitionOn=false;
     }
     
     //*************** CATEGORY
     
     function clickCategoryItem(e){
  	    //console.log("clickCategoryItem");
  		if(menuOpenToggle) return false;
  		
  		if (!e) var e = window.event;
  		e.cancelBubble = true;
  		if (e.stopPropagation) e.stopPropagation();
  		var currentTarget = $(e.currentTarget);
  		var id = $(currentTarget).attr('data-id');
  		
  		//console.log("id = ", id);
  		if(id == undefined || id == "" || id == activeCategory) return false;
  		transitionOn=true;//if we click undefined first, set this after 'id' check above 
  		activeCategory = id;
  		
  		if(lastActiveMenuItem){
  			lastActiveMenuItem.css('cursor', 'pointer');
  		}
  		currentTarget.css('cursor', 'default');
  		lastActiveMenuItem = currentTarget;
  		 
  		//close menu
  		toggleMenuHandler();
  		
  		if(useDeeplink){
  			$.address.value(findAddress2(0));
  			if(!$.address.history()) $.address.history(true);//restore history
  		}else{
  			cleanCategory();
  		}
  		return false;
  	}
  	
  	function cleanCategory(){
  		if(componentInited){
  			//remove info
  			if(useInfo){
  				closeInfo();
  				if(info_toggle)info_toggle.css('display','none');
  				if(info_toggleSrc)info_toggleSrc.attr('src','data/icons/info_toggle.png');
  			} 
  			if(isMobile)cleanMobileZoom();
  			//remove images
  			if(nextImage){
  				nextImage=null;
  			};
  			if(prevImage){
  				prevImage.unbind("dragstart").unbind("selectstart").unbindSwipe().unbind('click', navigateToUrl);
  				prevImage.remove();
  				prevImage = null;
  			}
  			if(currentImage){
  				currentImage.unbind("dragstart").unbind("selectstart").unbindSwipe().unbind('click', navigateToUrl);
  				currentImage.remove();
  				currentImage=null;
  			}
  			panHolder.empty();//remove images
  			
  			//remove thumbs
  			var i = 0, len = thumbArr.length;
  			for(i; i < len; i++){
  				$(thumbArr[i]).remove(); 
  			}
  			thumbArr=[];
  			thumbHolder.empty();
  			liArr = [];
  			
  			if(current_category)current_category.css('display','none');
  		}
  		if(!useDeeplink)activeItem = 0;//reset
  		initCategory();	
  	}
  		
  	function toggleMenuHandler(hidePreloader){//open,close menu
  		if(menuOpenToggle) return;
  		menuOpenToggle = true;
  		
  		if(hidePreloader){
  			imagePreloader.stop().animate({opacity: 0}, 500, "easeOutSine", function(){
  				imagePreloader.css('display', 'none');
  			});	
  		}
  		
  		if(!menuOpened){
  			 
  			menuWrapper.css({opacity: 0, display: 'block'});
  			if(componentInited)menu_close.css('display','block');
  			
  			alignMenu();//align menu before showing
  			
  		    menuWrapper.stop().animate({opacity: 1}, {
  			   duration: 700, 
  			   easing: "easeOutSine",
  			   complete: function() {
  				  menuOpened = true;
  				  menuOpenToggle = false;
  			   }
  		    });
  			
  		}else{
  			
  		   menuWrapper.stop().animate({opacity: 0},{
  			   duration: 700, 
  			   easing: "easeOutSine",
  			   complete: function() {
  				  menuWrapper.css('display', 'none');
  				  menuOpened = false;
  				  menuOpenToggle = false;
  			   }
  		  });
  		}
  		return false;
  	}
  		
  	//***************** INFO
  	
  	function checkImageLink() {
  		if(!currentImage) return;
  		var data = imageDataArr[_playlistManager.getCounter()];
  		//console.log(data, data.link);
  		if(data.link != undefined){
  			currentImage.bind('click', navigateToUrl).css('cursor', 'pointer');
  			linkSrc = data.link;
  			targetSrc = data.target;
  		}else{
  			currentImage.unbind('click', navigateToUrl).css('cursor', 'default');
  		}
  	}
  	
  	function checkDescription() {
  		//console.log('checkDescription');
  		var data = imageDataArr[_playlistManager.getCounter()];
  		infoExist=false;//reset
  		if(data.description != undefined){
  			infoExist = true;
  		}else{
  			//no description
  			if(info_toggle)info_toggle.css('display','none');	
  		}
  		if(infoExist){
  			//reuse p tag for description becuase of scrollPaneApi.reinitialise
  			if(infoPTag){
  				infoPTag.html(data.description);
  			}else{
  				infoPTag = $("<p/>").html(data.description).addClass('image_description').appendTo(info_holder);
  			}
  			//check info height
  			checkInfoSize();
  			
  			if(info_toggleSrc)info_toggleSrc.attr('src','data/icons/info_toggle.png');
  			if(info_toggle)info_toggle.css('display','block');
  			if(autoOpenDescription) toggleInfoHandler();
  		}
  	}
  	
  	function checkInfoSize() {
  		//console.log('checkInfoSize');
  		if(infoExist){
  			//check width first
  			var w = getComponentSizeClear('w'), h = getComponentSizeClear('h'), h1 = h - info_toggle.height();
  			//check width				
  			if(w <= info_holderMasker.width()){
  				info_holderMasker.width(w);
  				if(info_bg)info_bg.width(w);//transparent bg
  			}else{
  				info_holderMasker.width(info_holderMaskerOrigW);
  				if(info_bg){
  					var w2 = info_holderMaskerOrigW + 20 < w ? info_holderMaskerOrigW + 20 : info_holderMaskerOrigW + (w - info_holderMaskerOrigW);//get remainder if more
  					info_bg.width(w2);
  				}
  			}
  			//check height
  			if(h1 <= infoProposedH){
  				info_holder.height(h1);
  				if(info_bg)info_bg.height(h1);
  			}else{
  				info_holder.height(infoProposedH);//proposed height
  				if(info_bg){
  					var h3 = infoProposedH + 25 < h1 ? infoProposedH + 25 : infoProposedH + (h1 - infoProposedH);//get remainder if more
  					info_bg.height(h3);
  				}
  			}	
  			if(infoOpened)info_holderMasker.height(info_holder.height());//fix
  			
  			if(!scrollPaneApi){
  				scrollPaneApi = info_holder.jScrollPane().data().jsp;
  				info_holder.jScrollPane();
  			}else{
  				if(elementsVisible){
  					scrollPaneApi.reinitialise();
  					scrollPaneApi.scrollToY(0);
  				}
  			}
  		}
  	}
  	
  	function toggleInfoHandler() {
  		//console.log('toggleInfoHandler');
  		if(!infoOpened){
  			var h = info_holder.height();
  			info_holderMasker.stop().animate({'height': h+'px'}, {duration: 800, easing: "easeOutExpo"});
  			if(info_bg)info_bg.show();
  			if(info_toggleSrc)info_toggleSrc.attr('src','data/icons/close.png');
  			infoOpened=true;
  		}else{
  			info_holderMasker.stop().animate({'height': 0+'px'}, {duration: 500, easing: "easeOutExpo"});
  			if(info_bg)info_bg.hide();
  			if(info_toggleSrc)info_toggleSrc.attr('src','data/icons/info_toggle.png');
  			infoOpened=false;	
  		}
  		return false;
  	}
  	
  	function closeInfo() {
  		//console.log('closeInfo');
  		if(info_bg)info_bg.hide();
  		info_holderMasker.stop().animate({'height': 0+'px'}, {duration: 500, easing: "easeOutExpo", complete: function(){
  			infoOpened=false;	
  			if(infoPTag) infoPTag.html();
  		}});
  	}
  	
  	//********** IMAGE
     
      function loadImage(){
  	   imageLoaded=false;//reset
  	   
  	   if(componentInited && useInfo) closeInfo();
     
     	   var url = imageDataArr[_playlistManager.getCounter()].url +"?rand=" + (Math.random() * 99999999);
  	   //console.log(url);
  	   
  	   if(loadIntervalID) clearInterval(loadIntervalID);
  	   loadIntervalID = setInterval(checkLoaded, loadInterval);
  	   
  	   //show preloader
  	   imagePreloader.css('display', 'block').stop().animate({'opacity': 1}, 500, "easeOutSine");
     	
  	   var img = $(new Image()).prependTo(panHolder).css({
  		  display: 'block',
  		  position: 'relative',
  		  opacity: 0
  	   }).load(function() {
  			//hide preloader
  			imagePreloader.stop().animate({opacity: 0}, 500, "easeOutSine", function(){
  				imagePreloader.css('display', 'none');
  			});
  			nextImage = $(this);
  		    imageLoaded=true;
  	   }).error(function(e) {
  			//console.log("error " + e);
  	   }).attr('src', url);
     }
     
     function checkLoaded(){
  		if(imageLoaded){
  			if(loadIntervalID) clearInterval(loadIntervalID);
  			if(isMobile)cleanMobileZoom();
  			//check info
  			if(useInfo)checkDescription();
  			setImage();
  		}	
     }
     
     function setImage(){
  	   //console.log('setImage');
  	   imageEnlarged = false;//reset
  	   isSwipe=false;
  	   
  	   if(currentImage) prevImage = currentImage;	
  	   currentImage = nextImage;	
  	   
  	   panHolderWidth=panHolder.width();
  	   panHolderHeight=panHolder.height();
  	   fullImageWidth=currentImage.width();
  	   fullImageHeight=currentImage.height();  
  	  
  	   checkImageSize();
  	   
  	   if(prevImage)prevImage.stop().animate({opacity: 0}, imageOnOffSpeed, imageOnOffEase);
  	   currentImage.stop().animate({opacity: 1}, imageOnOffSpeed, imageOnOffEase, imageOn);
  	   
  	   currentImage.bind("dragstart", function(e) { e.preventDefault(); return false; }).bind("selectstart", function(e) { e.preventDefault(); return false; });
  	   currentImage.touchSwipe(swipeHandler, true); 
  		
  	   if(!componentInited){
  			componentInited=true;	
  			
  			alignImageControls();
  			galleryControls.css({opacity: 0, display: 'block'}).stop().animate({opacity: 1}, imageOnOffSpeed, imageOnOffEase);
  			thumb_backward.stop().animate({opacity: 1}, imageOnOffSpeed, imageOnOffEase);
  			thumb_forward.stop().animate({opacity: 1}, imageOnOffSpeed, imageOnOffEase);
  			image_forward.css('display','block').stop().animate({opacity: 1}, imageOnOffSpeed, imageOnOffEase);
  			image_backward.css({opacity: 0, display: 'block'}).stop().animate({opacity: 1}, imageOnOffSpeed, imageOnOffEase);
  			if(useInfo) info_wrapper.stop().animate({opacity: 1}, imageOnOffSpeed, imageOnOffEase);
  			panGalleryReady();
  	   }
     }
     
     function checkImageSize(){//apply this only on beginning when image loads, otherwise apply checkImageSizeOnResize()
  		 var data = getImageScaledDimensions();
  		 
  		 if(imageStartScale == 'scaled'){
  			 var imageScaledWidth = data.w;
  			 var imageScaledHeight = data.h;
  
  			 var x = getComponentSize('w') / 2 - imageScaledWidth / 2;
  			 var y = getComponentSize('h') / 2 - imageScaledHeight / 2;
  		
  			 currentImage.css({
  				 width: imageScaledWidth+'px',
  				 height: imageScaledHeight+'px',
  				 left: x+'px',
  				 top: y+'px'
  			 }); 
  			 
  			 panAbility = false;//reset
  			 if(fullImageWidth > getComponentSize('w') || fullImageHeight > getComponentSize('h')){
  				 panAbility = true;
  			 }
  			 //console.log('panAbility = ', panAbility);
  			 
  			 if(panAbility){
  				 if(image_sizeToggleSrc) image_sizeToggleSrc.attr('src', 'data/icons/image_toggle_plus.png');
  				 if(image_sizeToggle) image_sizeToggle.css('display','block').animate({opacity: 1}, {duration: 500,easing: 'easeOutSine'}); 
  			 }else{
  				if(image_sizeToggle)  image_sizeToggle.animate({opacity: 0},{duration: 500, easing: 'easeOutSine', complete: function(){
  					 image_sizeToggle.css('display','none');
  				 }}); 
  			 }
  		 }else{
  			  
  			 var x = getComponentSize('w') / 2 - fullImageWidth / 2;
  			 var y = getComponentSize('h') / 2 - fullImageHeight / 2;
  			   
  			 currentImage.css({
  				 left: x+'px',
  				 top: y+'px'
  			 }); 
  			 
  			 panAbility = false;//reset
  			 if(fullImageWidth > getComponentSize('w') || fullImageHeight > getComponentSize('h')){
  				 panAbility = true;
  			 }
  			 //console.log('panAbility = ', panAbility);
  			 
  			 if(panAbility){
  				 imageEnlarged = true;
  				 if(image_sizeToggleSrc)image_sizeToggleSrc.attr('src', 'data/icons/image_toggle_minus.png');//reverse
  				 if(image_sizeToggle)image_sizeToggle.css('display','block').animate({opacity: 1}, {duration: 500,easing: 'easeOutSine'}); 
  				 if(isMobile && !mobileZoomInited){
  					 initMobileZoom();
  				 }
  			 }else{
  				 if(image_sizeToggle)image_sizeToggle.animate({opacity: 0},{duration: 500, easing: 'easeOutSine', complete: function(){
  					 image_sizeToggle.css('display','none');
  				 }}); 
  			 }
  		 }
  	}
  	
  	function checkImageSizeOnResize(){
  		 var data = getImageScaledDimensions();
  		 
  		 var imageScaledWidth = data.w;
  		 var imageScaledHeight = data.h;
  		 var x = getComponentSize('w') / 2 - imageScaledWidth / 2;
  		 var y = getComponentSize('h') / 2 - imageScaledHeight / 2;
  	
  		 currentImage.css({
  			 width: imageScaledWidth+'px',
  			 height: imageScaledHeight+'px',
  			 left: x+'px',
  			 top: y+'px'
  		 }); 
  		 
  		 panAbility = false;//reset
  		 if(fullImageWidth > getComponentSize('w') || fullImageHeight > getComponentSize('h')){
  			 panAbility = true;
  		 }
  		 //console.log('panAbility = ', panAbility);
  		 
  		 if(panAbility){
  			 if(image_sizeToggleSrc)image_sizeToggleSrc.attr('src', 'data/icons/image_toggle_plus.png');
  			 if(image_sizeToggle)image_sizeToggle.css('display','block').animate({opacity: 1}, {duration: 500,easing: 'easeOutSine'}); 
  		 }else{
  			 if(image_sizeToggle)image_sizeToggle.animate({opacity: 0},{duration: 500, easing: 'easeOutSine', complete: function(){
  				 image_sizeToggle.css('display','none');
  			 }}); 
  		 }
  	}
  	
  	function getImageScaledDimensions(){
  		var data,w = fullImageWidth,h = fullImageHeight,ratio = currentImage.height()/currentImage.width();
  		
  		if (w>getComponentSize('w')) {
  			w = getComponentSize('w');
  			h = Math.round(w*ratio);
  		}
  		if (h>getComponentSize('h')) {
  			h = getComponentSize('h');
  			w = Math.round(h/ratio);
  		}
  		data = {w: w, h: h};
  		return data;
  	}
     
      function imageOn(){
  	   //console.log('imageOn: ', prevImage);
  	   if(prevImage){
  		   //prevImage.unbind("dragstart").unbind("selectstart").unbindSwipe().unbind('click', navigateToUrl);
  		   prevImage.remove();//remove previous image
  		   prevImage=null;
  	   }
  	   transitionOn = false;	
  	   checkImageLink();
  	   if(slideshowOn){
  		   if(slideshowTimeoutID) clearTimeout(slideshowTimeoutID);
  		   slideshowTimeoutID = setTimeout(nextSlide, slideshowTimeout);
  	   }
      }
  	
  	function hideNonPanElements(){
  		if(slideshowOn){
  		    if(slideshowTimeoutID) clearTimeout(slideshowTimeoutID);
  	    }
  		//resize pan holder to full size since there are no thumbs
  		panHolder.css({height: getComponentSizeClear('h')+'px', width: getComponentSizeClear('w')+'px'});	
  		if(!isMobile){
  			var time = 300;
  			if(useInfo){
  				info_wrapper.stop().animate({opacity: 0},{duration: time, easing: 'easeOutQuart', complete: function(){
  				 	$(this).css('display','none');
  				}}); 
  			}
  			if(menuExist && menuOpened){
  				menuWrapper.stop().animate({opacity: 0},{duration: time, easing: 'easeOutQuart', complete: function(){
  				 	$(this).css('display','none');
  				}}); 
  			}
  			galleryControls.stop().animate({opacity: 0},{duration: time, easing: 'easeOutQuart', complete: function(){
  				$(this).css('display','none');
  			}}); 
  			thumbWrapper.stop().animate({opacity: 0},{duration: time, easing: 'easeOutQuart', complete: function(){
  				$(this).css('display','none');
  			}}); 
  			thumb_backward.stop().animate({opacity: 0},{duration: time, easing: 'easeOutQuart', complete: function(){
  				$(this).css('display','none');
  			}}); 
  			thumb_forward.stop().animate({opacity: 0},{duration: time, easing: 'easeOutQuart', complete: function(){
  				$(this).css('display','none');
  			}}); 
  			image_backward.stop().animate({opacity: 0},{duration: time, easing: 'easeOutQuart', complete: function(){
  				$(this).css('display','none');
  			}}); 
  			image_forward.stop().animate({opacity: 0},{duration: time, easing: 'easeOutQuart', complete: function(){
  				$(this).css('display','none');
  			}}); 
  		}else{
  			if(useInfo){
  				info_wrapper.css('display','none');	
  			}
  			if(menuExist && menuOpened){
  				menuWrapper.css('display','none');	
  			}
  			galleryControls.css('display','none');	
  			thumbWrapper.css('display','none');	
  			
  			thumb_backward.css('display','none');	
  			thumb_forward.css('display','none');
  			
  			image_backward.css('display','none');	
  			image_forward.css('display','none');
  		}
  		elementsVisible = false;
  	}
     
      function showNonPanElements(){
  		var time;
  		if(!isMobile){
  			time = 300;
  			if(useInfo){
  				if(infoResizeQue){
  					checkInfoSize();
  					infoResizeQue=false;	
  				}
  				info_wrapper.stop().css({opacity: 0, display:'block'}).animate({opacity: 1},{duration: time, easing: 'easeOutQuart'}); 
  			}
  			if(menuExist && menuOpened){
  				menuWrapper.stop().css({opacity: 0, display:'block'}).animate({opacity: 1},{duration: time, easing: 'easeOutQuart'}); 
  			}
  			galleryControls.stop().css({opacity: 0, display:'block'}).animate({opacity: 1},{duration: time, easing: 'easeOutQuart'}); 
  			thumbWrapper.stop().css({opacity: 0, display:'block'}).animate({opacity: 1},{duration: time, easing: 'easeOutQuart'});
  			 
  			checkThumbScroll2(); 
  			if(scrollThumbs){
  				thumb_backward.stop().css({opacity: 0, display:'block'}).animate({opacity: 1},{duration: time, easing: 'easeOutQuart'}); 
  				thumb_forward.stop().css({opacity: 0, display:'block'}).animate({opacity: 1},{duration: time, easing: 'easeOutQuart'}); 
  			}
  			image_backward.stop().css({opacity: 0, display:'block'}).animate({opacity: 1},{duration: time, easing: 'easeOutQuart'}); 
  			image_forward.stop().css({opacity: 0, display:'block'}).animate({opacity: 1},{duration: time, easing: 'easeOutQuart'}); 
  		}else{
  			time=0;
  			if(useInfo){
  				if(infoResizeQue){
  					checkInfoSize();
  					infoResizeQue=false;	
  				}
  				info_wrapper.css({opacity: 1, display:'block'});
  			}
  			if(menuExist && menuOpened){
  				menuWrapper.css({opacity: 1, display:'block'});
  			}
  			galleryControls.css({opacity: 1, display:'block'});
  			thumbWrapper.css({opacity: 1, display:'block'});
  			
  			checkThumbScroll2(); 
  			if(scrollThumbs){
  				thumb_backward.css({opacity: 1, display:'block'});
  				thumb_forward.css({opacity: 1, display:'block'});
  			}
  			image_backward.css({opacity: 1, display:'block'});
  			image_forward.css({opacity: 1, display:'block'});
  		}
  		panHolder.css({height: getComponentSize('h')+'px', width: getComponentSize('w')+'px'});	
  		
  		if(slideshowOn){
  		    if(slideshowTimeoutID) clearTimeout(slideshowTimeoutID);
  		    slideshowTimeoutID = setTimeout(nextSlide, slideshowTimeout + time);
  	    }
  		elementsVisible = true;
  	}
     
     	function showNonPanElements2(){
  		if(useInfo){
  			if(infoResizeQue){
  				checkInfoSize();
  				infoResizeQue=false;	
  			}
  			info_wrapper.css({opacity: 1, display:'block'});
  		}
  		if(menuExist && menuOpened){
  			menuWrapper.css({opacity: 1, display:'block'});
  		}
  		galleryControls.css({opacity: 1, display:'block'});
  		thumbWrapper.css({opacity: 1, display:'block'});
  		
  		checkThumbScroll2(); 
  		if(scrollThumbs){
  			thumb_backward.css({opacity: 1, display:'block'});
  			thumb_forward.css({opacity: 1, display:'block'});
  		}
  		image_backward.css({opacity: 1, display:'block'});
  		image_forward.css({opacity: 1, display:'block'});
  		panHolder.css({height: getComponentSize('h')+'px', width: getComponentSize('w')+'px'});	
  		elementsVisible = true;
  	}
     
      function sizeToggleHandler(){
  	   if(!componentInited) return;
  	   if(!panAbility || transitionOn) return;
  	   transitionOn = true; 
  	   
  	   var x,y;
  	   if(imageEnlarged){
  		   	  mobilePanOn=false;
  			  
  			  var data = getImageScaledDimensions();
  			  imageScaledWidth = data.w;
  			  imageScaledHeight = data.h;
  			  x = getComponentSize('w') / 2 - imageScaledWidth / 2;
  			  y = getComponentSize('h') / 2 - imageScaledHeight / 2;
  	   
  			  currentImage.stop().animate({
  				  left: x+'px', 
  				  top: y+'px',
  				  width: imageScaledWidth+'px', 
  				  height: imageScaledHeight+'px'},{ 
  				  duration: imageSizeToggleSpeed, 
  				  easing: imageSizeToggleEase,
  				  complete: toggleImageSizeDone
  			  }); 
  			  imageEnlarged = false;
  		}else{
  			  hideNonPanElements();
  			
  			  x = getComponentSizeClear('w') / 2 - fullImageWidth / 2;
  			  y = getComponentSizeClear('h') / 2 - fullImageHeight / 2;
  			  
  			  currentImage.stop().animate({
  				  left: x+'px', 
  				  top: y+'px',
  				  width: fullImageWidth+'px', 
  				  height: fullImageHeight+'px'},{
  				  duration: imageSizeToggleSpeed, 
  				  easing: imageSizeToggleEase,
  				  complete: toggleImageSizeDone
  			  }); 
  			  imageEnlarged = true;
  		}
  		return false;
     }
  	
     function toggleImageSizeDone(){
  		if(imageEnlarged){
  			if(image_sizeToggleSrc)image_sizeToggleSrc.attr('src', 'data/icons/image_toggle_minus.png');
  			if(isMobile){
  				if(!mobileZoomInited){
  					initMobileZoom();
  				}else{
  					mobilePanOn=true;
  				}
  			}
  		}else{
  			if(image_sizeToggleSrc)image_sizeToggleSrc.attr('src', 'data/icons/image_toggle_plus.png');
  			if(!elementsVisible)showNonPanElements();
  		}
  		transitionOn = false;
  		if(slideshowOn){
  		   if(slideshowTimeoutID) clearTimeout(slideshowTimeoutID);
  		   slideshowTimeoutID = setTimeout(nextSlide, slideshowTimeout);
  	    }
  	}
  		
  	function mouseMoveHandler(e){
  		if(!componentInited) return;
  		
  		if (!e) var e = _window.event;
  		if(e.cancelBubble) e.cancelBubble = true;
  		else if (e.stopPropagation) e.stopPropagation();
  		
  		var topValue;
  		if(!transitionOn){
  			
  			panHolderWidth=panHolder.width();
  	 		panHolderHeight=panHolder.height();
  			
  			mouseX=(e.pageX - panHolder.offset().left);//main container position offset
  			mouseY=(e.pageY - panHolder.offset().top);
  			
  			mousePercentX=mouseX/panHolderWidth;
  			mousePercentY=mouseY/panHolderHeight;
  			
  			destX=-(((fullImageWidth-(panHolderWidth))-panHolderWidth)*(mousePercentX));
  			destY=-(((fullImageHeight-(panHolderHeight))-panHolderHeight)*(mousePercentY));
  			
  			thePosA=mouseX-destX;
  			thePosB=destX-mouseX;
  			thePosC=mouseY-destY;
  			thePosD=destY-mouseY;
  			
  			marginLeft=parseInt($(currentImage).css("marginLeft"),10);
  			marginTop=parseInt($(currentImage).css("marginTop"),10);
  			
  			topValue = -thePosC-marginTop;
  			if(topValue < - (fullImageHeight - getComponentSize('h'))) topValue = - (fullImageHeight - getComponentSize('h'));
  			
  			if(mouseX>destX || mouseY>destY){
  				if(!animatePan){
  					if(fullImageWidth > getComponentSize('w')) currentImage.css("left",-thePosA-marginLeft+'px'); 
  					if(fullImageHeight > getComponentSize('h')) currentImage.css("top",-thePosC-marginTop+'px'); //without easing
  				}else{ //with easing
  					if(fullImageWidth > getComponentSize('w') && fullImageHeight < getComponentSize('h')){
  						currentImage.stop().animate({left: -thePosA-marginLeft+'px'}, imagePanSpeed,imagePanEase);
  					}else if(fullImageWidth < getComponentSize('w') && fullImageHeight > getComponentSize('h')){
  						currentImage.stop().animate({top: topValue+'px'}, imagePanSpeed,imagePanEase); 
  					}else if(fullImageWidth >= getComponentSize('w') && fullImageHeight >= getComponentSize('h')){
  						currentImage.stop().animate({left: -thePosA-marginLeft+'px', top: topValue+'px'}, imagePanSpeed,imagePanEase);
  					}
  				}
  			}
  			else if(mouseX<destX || mouseY<destY){
  				if(!animatePan){
  					if(fullImageWidth > getComponentSize('w')) currentImage.css("left",thePosB-marginLeft+'px'); 
  					if(fullImageHeight > getComponentSize('h')) currentImage.css("top",thePosD-marginTop+'px'); //without easing
  				}else{ //with easing
  
  					if(fullImageWidth > getComponentSize('w') && fullImageHeight < getComponentSize('h')){
  						currentImage.stop().animate({left: thePosB-marginLeft+'px'}, imagePanSpeed,imagePanEase);
  					}else if(fullImageWidth < getComponentSize('w') && fullImageHeight > getComponentSize('h')){
  						currentImage.stop().animate({top: thePosD-marginTop+'px'}, imagePanSpeed,imagePanEase);
  					}else if(fullImageWidth >= getComponentSize('w') && fullImageHeight >= getComponentSize('h')){
  						currentImage.stop().animate({left: thePosB-marginLeft+'px', top: thePosD-marginTop+'px'}, imagePanSpeed,imagePanEase);
  					}
  				}
  			} 
  			else {
  				currentImage.stop();
  			}
  		}
      }
  	
  	//************ mobile pan
  
  	function image_zoom(change) {
  		
  		var new_zoom,
  			new_zoom_width,
  			new_zoom_height,
  			ratio;
  			
  		new_zoom = (zoom_level + change);
  
  		if (new_zoom >= zoom_level_count) {
  			if (new_zoom > zoom_level_count) {
  				return;
  			}
  		} 
  
  		if (new_zoom <= 0) {
  			if (new_zoom < 0) {
  				return;
  			}
  		}
  
  		zoom_level = new_zoom;
  		
  		//console.log(zoom_levels[new_zoom]);
  
  		img_ref.style.width = zoom_levels[new_zoom] + 'px';
  
  		new_zoom_width = img_ref.width;
  		new_zoom_height = img_ref.height;
  
  		if (img_current_left === null) { // center
  			//img_current_left = (div_half_width - (new_zoom_width  / 2));
  			//img_current_top  = (div_half_height - (new_zoom_height / 2));
  			img_current_left = (div_half_width - (img_orig_width  / 2));
  			img_current_top  = (div_half_height - (img_orig_height / 2));
  		} else {
  			ratio = (new_zoom_width / img_zoom_width);
  			img_current_left = (div_half_width - ((div_half_width - img_current_left) * ratio));
  			img_current_top  = (div_half_height - ((div_half_height - img_current_top)  * ratio));
  		}
  
  		img_zoom_width = new_zoom_width;
  		img_zoom_height = new_zoom_height;
  
  		img_ref.style.left = img_current_left + 'px';
  		img_ref.style.top = img_current_top + 'px';
  	
  	}
  	
  	function image_zoom_in() {
  		image_zoom(1);
  	}
  	
  	function image_zoom_out() {
  		image_zoom(-1);
  	}
  	
  	function event_coords(e) {
  		var coords = [];
  		if (e.touches && e.touches.length) {
  			coords[0] = e.touches[0].clientX;
  			coords[1] = e.touches[0].clientY;
  		} else {
  			coords[0] = e.clientX;
  			coords[1] = e.clientY;
  		}
  		return coords;
  	}
  	
  	function image_move_update() {
  		// Boundary check
  		var max_left = (div_half_width - img_zoom_width),
  			max_top = (div_half_height - img_zoom_height),
  			max_left2 = (div_width - img_zoom_width),
  			max_top2 = (div_height - img_zoom_height);
  	
  		if(!edgeBoundary){
  			if (img_current_left > div_half_width)  { img_current_left = div_half_width; }
  			if (img_current_top  > div_half_height) { img_current_top  = div_half_height; }
  			if (img_current_left < max_left)        { img_current_left = max_left; }
  			if (img_current_top  < max_top)         { img_current_top  = max_top;  }
  			
  			img_ref.style.left = img_current_left + 'px';
  			img_ref.style.top  = img_current_top + 'px';
  		}else{
  			//if image smaller than screen, make this side as edgeBoundary = false
  			if(img_zoom_width > div_width){
  				if (img_current_left > 0) { img_current_left = 0; }
  				if (img_current_left < max_left2) { img_current_left = max_left2; }
  				img_ref.style.left = img_current_left + 'px';
  			}else{
  				//if (img_current_left > div_half_width)  { img_current_left = div_half_width; }
  				//if (img_current_left < max_left)        { img_current_left = max_left; }
  			}
  			if(img_zoom_height > div_height){
  				if (img_current_top  > 0) { img_current_top  = 0; }
  				if (img_current_top  < max_top2) { img_current_top  = max_top2;  }
  				img_ref.style.top  = img_current_top + 'px';
  			}else{
  				//if (img_current_top  > div_half_height) { img_current_top  = div_half_height; }
  				//if (img_current_top  < max_top)         { img_current_top  = max_top;  }
  			}
  		}
  	}
  	
  	function image_move_event(e) {
  		if(!mobilePanOn)return;
  		e = e || window.event;
  	
  		var currentPos = event_coords(e);
  		img_current_left = (img_start_left + (currentPos[0] - origin[0]));
  		img_current_top = (img_start_top + (currentPos[1] - origin[1]));
  		image_move_update();
  	
  		if (e.preventDefault) {
  			e.preventDefault();
  		} else {
  			e.returnValue = false;
  		}
  		return false;
  	}
  	
  	function image_move_start(e) {
  		if(!mobilePanOn)return;
  		e = e || window.event;
  		if (e.preventDefault) {
  			e.preventDefault();
  		} else {
  			e.returnValue = false; // IE: http://stackoverflow.com/questions/1000597/
  		}
  
  		if (e.type === 'touchstart') {
  			img_ref.onmousedown = null;
  			img_ref.ontouchmove = image_move_event;
  			img_ref.ontouchend = function() {
  				img_ref.ontouchmove = null;
  				img_ref.ontouchend = null;
  			};
  		} else {
  			document.onmousemove = image_move_event;
  			document.onmouseup = function() {
  				document.onmousemove = null;
  				document.onmouseup = null;
  			};
  		}
  	
  		//--------------------------------------------------
  		// Record starting position
  		img_start_left = img_current_left;
  		img_start_top = img_current_top;
  	
  		origin = event_coords(e);
  	}
  	
  	function cleanMobileZoom(){
  		if(img_ref){
  			img_ref.onmousedown = null;
  			img_ref.ontouchstart = null;
  			img_ref.ontouchmove = null;
  			img_ref.ontouchend = null;
  		}
  		document.onmousemove = null;
  		document.onmouseup = null;
  		mobilePanOn=false;
  		mobileZoomInited=false;
  	}
  	
  	function initMobileZoom(){
  		//reset
  		div_half_width = null;
  		div_half_height = null;
  		div_width = null;
  		div_height = null;
  		img_orig_width = null;
  		img_orig_height = null;
  		img_zoom_width = null;
  		img_zoom_height = null;
  		img_start_left = null;
  		img_start_top = null;
  		img_current_left = null;
  		img_current_top = null;
  		zoom_level = 0;
  		zoom_levels = [];
  		zoom_level_count = [];
  		click_last = 0;
  		origin = null;
  		
  		img_ref = currentImage[0];
  		img_ref.style.cursor = 'move';
  		img_ref.onmousedown = image_move_start;
  		img_ref.ontouchstart = image_move_start;
  		
  		var div_border,
  			div_style,
  			width,
  			height,
  			button,
  			buttons,
  			name,
  			len,
  			k;
  
  		//--------------------------------------------------
  		// Wrapper size
  
  		try {
  			div_style = getComputedStyle(div_ref, '');
  			div_border = div_style.getPropertyValue('border-top-width');
  			div_half_width = div_style.getPropertyValue('width');
  			div_half_height = div_style.getPropertyValue('height');
  		} catch(e) {
  			div_border = div_ref.currentStyle.borderWidth;
  			div_half_width = div_ref.currentStyle.width;
  			div_half_height = div_ref.currentStyle.height;
  		}
  
  		div_half_width = Math.round(parseInt(div_half_width, 10) / 2);
  		div_half_height = Math.round(parseInt(div_half_height, 10) / 2);
  
  		img_orig_width = img_ref.width;
  		img_orig_height = img_ref.height;
  		//console.log('img_orig_width = ', img_orig_width);
  		//console.log('img_orig_height = ', img_orig_height);
  
  		div_width = (div_half_width * 2);
  		div_height = (div_half_height * 2);
  		//console.log('div_width = ', div_width);
  		//console.log('div_height = ', div_height);
  
  		width = img_orig_width;
  		height = img_orig_height;
  
  		zoom_levels[zoom_levels.length] = width;
  
  		while (width > div_width || height > div_height) {
  			width = (width * 0.75);
  			height = (height * 0.75);
  			zoom_levels[zoom_levels.length] = Math.round(width);
  		}
  		
  		zoom_levels.reverse(); // Yep IE5.0 does not support unshift... but I do wonder if a single reverse() is quicker than inserting at the beginning of the array.
  		//console.log(zoom_levels);
  		
  		//--------------------------------------------------
  		// Mobile phone, over zoom
  
  		if (parseInt(div_border, 10) === 5) { // img width on webkit will return width before CSS is applied
  			zoom_levels[zoom_levels.length] = Math.round(img_orig_width * 1.75);
  			zoom_levels[zoom_levels.length] = Math.round(img_orig_width * 3);
  		}
  
  		zoom_level_count = (zoom_levels.length - 1);
  
  		image_zoom(zoom_levels.length-1);
  		
  		mobilePanOn=true;
  		mobileZoomInited=true;
  	}
  				
  	//***************** end mobile pan
     
      function toggleSlideshow(){
  		  if(!componentInited) return false;
  		  if(slideshowTimeoutID) clearTimeout(slideshowTimeoutID);
  		  if(slideshowOn){
  			  slideshowToggleSrc.attr('src', 'data/icons/slideshow_play.png');
  			  slideshowOn=false;
  		  }else{
  			  slideshowToggleSrc.attr('src', 'data/icons/slideshow_pause.png');
  			  slideshowOn=true;
  			  if(!transitionOn) slideshowTimeoutID = setTimeout(nextSlide, slideshowTimeout);
  		  }
  		  return false;
  	}
  	
  	function toggleSlideshow2(state){
  		if(slideshowTimeoutID) clearTimeout(slideshowTimeoutID);
  		if(state){//start
  			slideshowToggleSrc.attr('src', 'data/icons/slideshow_pause.png');
  			slideshowOn=true;
  			if(!transitionOn) slideshowTimeoutID = setTimeout(nextSlide, slideshowTimeout);
  		}else{//stop
  			slideshowToggleSrc.attr('src', 'data/icons/slideshow_play.png');
  			slideshowOn=false;
  		}
  	}
  	
  	function swipeHandler(direction){
  		//console.log(direction);
  		if(!componentInited || mobilePanOn) return false;
  		isSwipe=true;
  		if(direction == 'right'){
  			backwardHandler();
  		}else if(direction == 'left'){
  			forwardHandler();
  		}
  		return false;
  	}
  	  
  	function nextSlide(){
  		if(imageEnlarged){//if image enlarged and slideshow on, when new slide ticks, show all elements
  			showNonPanElements2();	
  		}
  		forwardHandler();
  	}
     
     function backwardHandler(){
  	   if(!componentInited) return false;
  	   if(transitionOn) return false;
  	   transitionOn = true;
  	   enableActiveItem();
  	   _playlistManager.advanceHandler(-1);
  	   return false;	
     }
     
     function forwardHandler(){
  	    if(!componentInited) return false;
  	    if(transitionOn) return false;
  	    transitionOn = true;
  		enableActiveItem();
  	    _playlistManager.advanceHandler(1);
  		return false;
     }
     
     	function overPlaylistItem(e) {
  		if(thumbsHorizontal){
  			$(this).stop().animate({
  				width: thumbScaleWidth+'px', 
  				height: thumbScaleHeight+'px', 
  				marginTop: -marginRotationCorrection+'px'},{
  				duration: thumbSpeedOver, 
  				easing: thumbEaseOverType
  			}); 
  		}else{
  			$(this).stop().animate({
  				width: thumbScaleWidth+'px', 
  				height: thumbScaleHeight+'px', 
  				marginLeft: -marginRotationCorrection+'px'},{
  				duration: thumbSpeedOver, 
  				easing: thumbEaseOverType
  			}); 
  		}
  	}
  	
  	function outPlaylistItem(e) {
  		if(thumbsHorizontal){
  			$(this).stop().animate({width: thumbWidth+'px', height: thumbHeight+'px', marginTop: 0+'px'},
  			{duration: thumbSpeedOut, easing: thumbEaseOutType }); 
  		}else{
  			$(this).stop().animate({width: thumbWidth+'px', height: thumbHeight+'px', marginLeft: 0+'px'},
  			{duration: thumbSpeedOut, easing: thumbEaseOutType }); 
  		}
  	}
  	
  	function clickPlaylistItem(e) {
  		//console.log('clickPlaylistItem ', transitionOn);
  		if(!componentInited) return false;
  		if(transitionOn) return false;
  		
  		if (!e) var e = _window.event;
  		if(e.cancelBubble) e.cancelBubble = true;
  		else if (e.stopPropagation) e.stopPropagation();
  		
  		var currentTarget = $(e.currentTarget);
  		var id = currentTarget.attr('data-id');
  		
  		if(id == _playlistManager.getCounter()) return false;//active item
  		transitionOn = true;//after above statement!
  		
  		enableActiveItem();
  		_playlistManager.processPlaylistRequest(id);
  		
  		return false;
  	}
  	
  	function enableActiveItem() {
  		if(slideshowTimeoutID) clearTimeout(slideshowTimeoutID);
  		//console.log('enableActiveItem');
  		if(_playlistManager.getCounter()!=-1){
  			if(thumbArr[_playlistManager.getCounter()]){
  				var _item = $(thumbArr[_playlistManager.getCounter()]);
  				if(_item)_item.css('cursor', 'pointer');
  			}
  		}
  	}
  	
  	function disableActiveItem() {
  		//console.log('disableActiveItem');
  		if(_playlistManager.getCounter()!=-1){
  			if(thumbArr[_playlistManager.getCounter()]){
  				var _item = $(thumbArr[_playlistManager.getCounter()]);
  				if(_item)_item.css('cursor', 'default');
  			}
  		}
  	}
  	
  	//*********** RESIZE
  	
  	if(!componentFixedSize){
  		_window.resize(function() {
  			if(windowResizeTimeoutID) clearTimeout(windowResizeTimeoutID);
  			windowResizeTimeoutID = setTimeout(doneResizing, windowResizeTimeout);
  		});
  	}else{
  		_window.resize(function() {
  			if(windowResizeTimeoutID) clearTimeout(windowResizeTimeoutID);
  			windowResizeTimeoutID = setTimeout(centerComponent, windowResizeTimeout);
  		});
  	}
  	
  	function centerComponent(){
  		var w = _window.width(),h = _window.height(),w1 = componentWrapper.width(),h1 = componentWrapper.height();
  		if(w<=w1){
  			componentWrapper.css({
  				left:0+'px',
  				marginLeft:0+'px'
  			});
  		}else{
  			componentWrapper.css({
  				left:50+'%',
  				marginLeft:-w1/2+'px'
  			});
  		}
  		if(h<=h1){
  			componentWrapper.css({
  				top:0+'px',
  				marginTop:0+'px'
  			});
  		}else{
  			componentWrapper.css({
  				top:50+'%',
  				marginTop:-h1/2+'px'
  			});
  		}
  	}
  	
  	function makeThumbHolder(){
  		//console.log('makeThumbHolder');
  		
  		if(!imageEnlarged || elementsVisible){
  			panHolder.css({height: getComponentSize('h')+'px', width: getComponentSize('w')+'px'});
  		}else{
  			panHolder.css({height: getComponentSizeClear('h')+'px', width: getComponentSizeClear('w')+'px'});
  		}
  		thumbHolder.css({left: 0+'px', top: 0+'px'});
  		//reset
  		thumb_backward.css({width: '', height: ''});
  		thumb_forward.css({width: '', height: ''});
  		
  		if(thumbsHorizontal){
  			
  			//before we measure thumbBackwardSize
  			thumb_backward.removeClass('thumb_backward_v').addClass('thumb_backward').css({height: thumbHeight+'px'});
  			thumb_forward.removeClass('thumb_forward_v').addClass('thumb_forward').css({height: thumbHeight+'px'});
  			
  			thumbBackwardSize = thumb_backward.width();
  			thumbForwardSize = thumb_forward.width();
  			scrollDifference=thumbBackwardSize + thumbForwardSize;
  			marginRotationCorrection = thumbScaleHeight - thumbHeight;//for simulating scale up
  			allThumbsSize = playlistLength * thumbWidth;
  			
  			thumbWrapper.removeClass('thumbWrapper_v').addClass('thumbWrapper')
  			.css({top:'auto', left:0+'px', height:thumbScaleHeight+'px', width: getComponentSize('w')-scrollDifference+'px'});
  			
  			thumbHolder.css({paddingLeft:0+'px', paddingTop:marginRotationCorrection+'px', height: thumbWidth+'px'});//move thumbHolder bottom for tween up
  			
  			if(!isMobile){
  				thumbHolder.width(allThumbsSize + 7 * thumbWidth);//more than max expand width
  			}else{
  				thumbHolder.width(allThumbsSize);
  			}
  				
  			var i = 0, len = liArr.length, li, thumb;
  			for(i;i<len;i++){
  				li = $(liArr[i]).removeClass('thumbs_v').addClass('thumbs');
  				if(!isMobile){
  					thumb = $(thumbArr[i]);
  					if(thumb){
  						thumb.stop().css({width: thumbWidth+'px', height: thumbHeight+'px', marginTop: 0+'px'});//stop thumb animation, restore size
  					} 
  				}
  			}
  			
  			image_sizeToggle.removeClass('image_sizeToggle_v').addClass('image_sizeToggle');
  			
  			image_forward.removeClass('image_forward_v').addClass('image_forward');
  			
  			galleryControls.css('marginLeft', -galleryControls.width()/2+'px');
  			
  			imagePreloader.css({marginLeft: imagePreloaderOrigMarg+'px', marginTop: imagePreloaderOrigMarg- thumbHeight/2+'px'});
  			
  		}else{
  			
  			//before we measure thumbBackwardSize
  			thumb_backward.removeClass('thumb_backward').addClass('thumb_backward_v').css({width: thumbWidth+'px'});
  			thumb_forward.removeClass('thumb_forward').addClass('thumb_forward_v').css({width: thumbWidth+'px'});
  			
  			thumbBackwardSize = thumb_backward.height();
  			thumbForwardSize = thumb_forward.height();
  			scrollDifference=thumbBackwardSize + thumbForwardSize;
  			marginRotationCorrection = thumbScaleWidth - thumbWidth;//for simulating scale left
  			allThumbsSize = playlistLength * thumbHeight;
  	
  			thumbWrapper.removeClass('thumbWrapper').addClass('thumbWrapper_v')
  			.css({left:'auto', top:0+'px', width:thumbScaleWidth+'px', height: getComponentSize('h')-scrollDifference+'px'});
  			
  			thumbHolder.css({paddingTop:0+'px', paddingLeft:marginRotationCorrection+'px', width: thumbWidth+'px'});//move thumbHolder right for tween left
  		
  			if(!isMobile){
  				thumbHolder.height(allThumbsSize + 7 * thumbHeight);//more than max expand height
  			}else{
  				thumbHolder.height(allThumbsSize);
  			}
  				
  			var i = 0, len = liArr.length, li, thumb;
  			for(i;i<len;i++){
  				li = $(liArr[i]).removeClass('thumbs').addClass('thumbs_v');
  				if(!isMobile){
  					thumb = $(thumbArr[i]);
  					if(thumb){
  						thumb.stop().css({width: thumbWidth+'px', height: thumbHeight+'px', marginLeft: 0+'px'});//stop thumb animation, restore size
  					} 
  				}
  			}
  			
  			image_sizeToggle.removeClass('image_sizeToggle').addClass('image_sizeToggle_v');
  			
  			image_forward.removeClass('image_forward').addClass('image_forward_v');
  			
  			galleryControls.css('marginLeft', -(galleryControls.width()/2 + thumbWidth/2)+'px');
  			
  			imagePreloader.css({marginLeft: imagePreloaderOrigMarg - thumbWidth/2+'px', marginTop: imagePreloaderOrigMarg+'px'});
  			
  		}	
  	}
  	
  	function resizeElements(){//resizes with no thumb change
  		//console.log("resizeElements");
  		if(!imageEnlarged){
  			panHolder.css({height: getComponentSize('h')+'px', width: getComponentSize('w')+'px'});
  			thumbHolder.css({left: 0+'px', top: 0+'px'});
  		}else{
  			panHolder.css({height: getComponentSizeClear('h')+'px', width: getComponentSizeClear('w')+'px'});
  		}
  		if(thumbsHorizontal){
  			thumbWrapper.css('width',getComponentSize('w')-scrollDifference+'px');
  		}else{
  			thumbWrapper.css('height',getComponentSize('h')-scrollDifference+'px');
  		}	
  	}
  		
  	function doneResizing(){
  		//console.log("doneResizing");
  		if(componentInited){
  			
  			if(flipGallerySides){
  				var h = getComponentSizeClear('h'), w = getComponentSizeClear('w');
  				if(h < 500 || w < 500){
  					if(getComponentSizeClear('h') <= w){
  						thumbsHorizontal = false;
  					}else{
  						thumbsHorizontal = true;
  					}
  				}else{
  					thumbsHorizontal = defaultGallerySide;
  				}
  				makeThumbHolder();
  			}else{
  				resizeElements();
  			}
  			
  			if(!imageEnlarged){
  				checkImageSizeOnResize();
  			}else{
  				//center image
  				centerImage();
  				if(isMobile){
  					cleanMobileZoom();
  					initMobileZoom();
  				}
  			}
  			
  			//align image buttons
  			alignImageControls();
  			
  			if(menuExist){
  				checkMenuSize();
  				if(menuOpened){
  					alignMenu();
  				}
  			}
  			
  			checkThumbScroll();
  			
  			if(useInfo){
  				if(elementsVisible){
  					checkInfoSize();
  				}else{
  					infoResizeQue=true;
  				}
  			}
  		}else{
  			if(menuExist){
  				checkMenuSize();
  				if(menuOpened){
  					alignMenu();
  				}
  			}
  		}
  	};
  	
  	function checkMenuSize(){
  		//console.log('checkMenuSize');
  		
  		//first check height
  		var h = componentWrapper.height();
  		if(h < menuWrapperOrigH){
  			menuRowMaskerHeight = h - 2 * menuBorderWidth;
  			menuRowMaskerWidth = menuRowMaskerHeight * menuThumbRatio;
  		}else{//restore original
  			menuRowMaskerWidth = menuRowMaskerOrigWidth;
  			menuRowMaskerHeight = menuRowMaskerOrigHeight;
  		}
  		//console.log(menuRowMaskerWidth, menuRowMaskerHeight);
  		//resize all
  		allMenuRowMaskerArr.each(function(){
  			$(this).css({width:menuRowMaskerWidth+'px', height:menuRowMaskerHeight+'px'});
  		});
  		var mrh, menu_div, caption_div;
  		allMenuRowHolderArr.each(function(){
  			mrh = $(this);
  			mrh.css({width:menuRowMaskerWidth*2+'px', height:menuRowMaskerHeight+'px'});
  			menu_div = mrh.find('div[data-title=menuItemDiv]');
  			if(menu_div){
  				//resing divs with images inside
  				menu_div.css({width:menuRowMaskerWidth+'px', height:menuRowMaskerHeight+'px'});
  			}
  			caption_div = mrh.data('caption'); 
  			if(caption_div){
  				if(!isMobile){
  					//place caption below img
  					caption_div.css({width:menuRowMaskerWidth-leftCaptionPadding-rightCaptionPadding+'px', top:menuRowMaskerHeight+'px'});
  				}else{
  					//leave caption opened
  					caption_div.css({width:menuRowMaskerWidth-leftCaptionPadding-rightCaptionPadding+'px'});
  					caption_div.css({top:menuRowMaskerHeight-caption_div.outerHeight()+'px'});
  				}
  			}
  		});
  		menuHolder.css({width:currentNumberOfMenuItems * menuRowMaskerWidth+'px', height: menuRowMaskerHeight+'px'});
  		menuWrapper.css({width:currentNumberOfMenuItems * menuRowMaskerWidth + 2 * menuBorderWidth+'px', 
  						height: menuRowMaskerHeight + 2 * menuBorderWidth+'px'});
  		menuWidth = menuWrapper.width();
  		menuHeight = menuWrapper.height();
  		
  		if(!menuInited){
  			
  			menuWrapper.css({opacity: 0, display: 'block'});//show it to get size
  			
  			if(getComponentSize('w') < menuWidth){
  			
  				currentNumberOfMenuItems = Math.floor((getComponentSize('w')- 2 * menuBorderWidth) / (menuRowMaskerWidth));
  				//console.log(currentNumberOfMenuItems);
  				if(currentNumberOfMenuItems < 1) currentNumberOfMenuItems=1;
  				
  				var v = currentNumberOfMenuItems * menuRowMaskerWidth;
  				menuWrapper.css('width', v + 2 * menuBorderWidth + 'px');
  				menuHolder.css('width', v + 'px');
  				
  				menuWidth = menuWrapper.width();
  				
  				numberOfMenuItems = currentNumberOfMenuItems;//as many as fit in current layout
  				
  			}else{
  			
  				numberOfMenuItems = menuHolder.find("div[class=menuRowMasker]").size(); //all fit in current layout
  				
  			}
  			//console.log('numberOfMenuItems = ', numberOfMenuItems);
  			
  			var i=0, len=numberOfMenuItems;
  			for(i;i<len;i++){
  				menuRowMaskerArr.push(allMenuRowMaskerArr[i]);
  				menuRowHolderArr.push(allMenuRowHolderArr[i]);
  				$(allMenuRowMaskerArr[i]).css('display','block');
  			}
  			for(i;i<origNumberOfMenuItems;i++){//continue
  				$(allMenuRowMaskerArr[i]).css('display','none');
  			}
  			
  			menuWrapper.css('display', 'none');//hide it
  			
  			menuInited = true;
  			
  			loadMenuRows();//start loading menu
  		
  		}else{
  				
  			if(getComponentSize('w') < menuWidth){
  				checkMenuRows();
  			}else if(getComponentSize('w') > menuWidth){
  				if(numberOfMenuItems < origNumberOfMenuItems){
  					checkMenuRows();				
  				}
  			}
  		}
  	}
  	
  	function checkMenuRows(){
  		
  		if(!menuOpened){
  			menuWrapper.css('opacity', 0).css('display', 'block');//show it to get size
  		}
  		
  		hideMenuControls(true);
  		
  		currentNumberOfMenuItems = Math.floor((getComponentSize('w')- 2 * menuBorderWidth) / (menuRowMaskerWidth));
  		if(currentNumberOfMenuItems < 1) currentNumberOfMenuItems=1;
  		else if(currentNumberOfMenuItems > origNumberOfMenuItems) currentNumberOfMenuItems=origNumberOfMenuItems;
  		//console.log('currentNumberOfMenuItems = ', currentNumberOfMenuItems);
  		
  		var v = currentNumberOfMenuItems * menuRowMaskerWidth;
  		menuWrapper.css('width', v + 2 * menuBorderWidth + 'px');
  		menuHolder.css('width', v + 'px');
  		
  		menuWidth = menuWrapper.width();
  		
  		numberOfMenuItems = currentNumberOfMenuItems;
  		//console.log('numberOfMenuItems = ', numberOfMenuItems);
  		
  		menuRowMaskerArr=[];//empty
  		menuRowHolderArr=[];
  		
  		var i=0, len=numberOfMenuItems, menuRowHolder, menuRowMasker;
  		for(i;i<len;i++){
  			menuRowMasker = $(allMenuRowMaskerArr[i]);
  			menuRowHolder = $(allMenuRowHolderArr[i]);
  			
  			menuRowMaskerArr.push(menuRowMasker);
  			menuRowHolderArr.push(menuRowHolder);
  			
  			menuRowMasker.css('display','block');
  			menuRowHolder.empty();//empty
  		}
  		for(i;i<origNumberOfMenuItems;i++){//continue
  			$(allMenuRowMaskerArr[i]).css('display','none');
  		}
  		
  		//reset rows on beginning on every menu row change
  		menuRowCounter=0;
  		setMenuRows(0.01);
  		
  		if(!menuOpened){
  			menuWrapper.css('display', 'none');//hide it
  		}	
  	}
  	
  	function alignImageControls(){
  		var c1= getComponentSize('h')/2 - image_backward_height/2;
  		var c2= getComponentSize('h')/2 - image_forward_height/2;
  		image_backward.css('top', c1+'px');
  		image_forward.css('top', c2+'px');
  	}
  	
  	function alignMenu(){
  		var c1 = getComponentSizeClear('w') / 2 - menuWidth / 2;
  		var c2 = getComponentSizeClear('h') / 2 - menuHeight / 2;
  		menuWrapper.css('left', c1+'px');
  		menuWrapper.css('top', c2+'px');
  		
  		//align menu controls
  		//menu backward
  		var h1 = menuHeight / 2 - menu_backward.height() / 2;
  		menu_backward.css({top: h1+'px',left: menuBorderWidth+'px'});
  		//menu forward
  		var h2 = menuHeight / 2 - menu_forward.height() / 2;
  		menu_forward.css({top:h2+'px', left: menuWidth-menuBorderWidth-menu_forward.width()+'px'});
  		//menu close
  		var v3 = menuWidth / 2 -  menu_close.width() / 2;
  		menu_close.css({left: v3+'px', top: menuBorderWidth+'px'});
  		
  		//fix for mobile, sometimes captions werent aligned from bottom
  		var mrh, caption_div;
  		if(!allMenuRowHolderArr)return;
  		allMenuRowHolderArr.each(function(){
  			mrh = $(this);
  			caption_div = mrh.data('caption'); 
  			if(caption_div){
  				if(!isMobile){
  					//place caption below img
  					caption_div.css({width:menuRowMaskerWidth-leftCaptionPadding-rightCaptionPadding+'px', top:menuRowMaskerHeight+'px'});
  				}else{
  					//leave caption opened
  					caption_div.css({width:menuRowMaskerWidth-leftCaptionPadding-rightCaptionPadding+'px'});
  					caption_div.css({top:menuRowMaskerHeight-caption_div.outerHeight()+'px'});
  				}
  			}
  		});
  	}
  		
  	function centerImage(){
  		var w = currentImage.width();
  		var h = currentImage.height();
  		var x = getComponentSize('w') / 2 - w / 2;
  		var y = getComponentSize('h') / 2 - h / 2;
  		currentImage.css('left', x+'px'); 
  		currentImage.css('top', y+'px');  
  	}
  	
  	function getComponentSize(side){
  		if(thumbsHorizontal){
  			if(side=='w'){
  				return componentWrapper.width();
  			}else{
  				return thumbHeight ? componentWrapper.height()-thumbHeight : componentWrapper.height();
  			}
  		}else{//vertical thumbs
  			if(side=='w'){
  				return thumbWidth ? componentWrapper.width()-thumbWidth : componentWrapper.width();
  			}else{
  				return componentWrapper.height();
  			}
  		}
  	};
  	
  	function getComponentSizeClear(side){
  		if(side=='w'){
  			return componentWrapper.width();
  		}else{
  			return componentWrapper.height();
  		}
  	};
  	
  	//************
   
  	function navigateToUrl(){
  		if(mobilePanOn) return false;
  		if(isSwipe){
  			isSwipe=false;
  			return false;	
  		}
  		//console.log('navigateToUrl');
  		if(targetSrc=='_parent'){
  			window.location.href=linkSrc;
  		}else if(targetSrc=='_blank'){
  			var newWindow=window.open(linkSrc, targetSrc);
  		}
  	}
  	
  	function isEmpty(str) {
  	    return str.replace(/^\s+|\s+$/g, '').length == 0;
  	}
  	
  	
  	
  	
  	
  	
  	
  	
  	// ******************************** PUBLIC FUNCTIONS **************** //
  	
  	$.panGallery.toggleSlideshow = function(state) {
  		if(!componentInited) return;
  		if(imageEnlarged)return;
  		if(state == undefined){
  			toggleSlideshow();
  		}else{
  			toggleSlideshow2(state);
  		}
  	}
  	
  	$.panGallery.setSlideshowDelay = function(num) {
  		if(!componentInited) return;
  		slideshowTimeout = num*1000;
  	}
  	
  	$.panGallery.nextMedia = function() {
  		if(!componentInited) return;
  		if(imageEnlarged)return;
  		forwardHandler();
  	}
  	
  	$.panGallery.previousMedia = function() {
  		if(!componentInited) return;
  		if(imageEnlarged)return;
  		backwardHandler();
  	}
  	
  	$.panGallery.openMedia = function(value) {
  		if(!componentInited) return;
  		if(imageEnlarged)return;
  		
  		if(typeof(value) === 'number'){
  			if(value<0)value=0;
  		    else if(value>playlistLength-1)value=playlistLength-1;
  		}else if(typeof(value) === 'string'){
  			//find counter for media name
  			if(!findCounterByName(value)){
  				alert('404 page not found, check your deeplinks!');
  				if(useDeeplink)$.address.history(false);//skip invalid url
  				alert('Wrong image name!');
  				return false;
  			}
  			value=activeItem;//convert to counter			
  		}else{
  			alert('Invalid value for openMedia!');
  			return false;	
  		}
  		enableActiveItem();
  		_playlistManager.processPlaylistRequest(value);
  	}
  	
  	$.panGallery.openCategory = function(value) {
  		if(menuOpenToggle) return;
  		if(imageEnlarged)return;
  		
  		if(typeof(value) === 'number'){
  			if(value<0)value=0;
  			else if(value>categoryLength-1)value=categoryLength-1;
  		}else if(typeof(value) === 'string'){
  			//find activeCategory for category name
  			if(!findCategoryByName(value)){
  				alert('404 page not found, check your deeplinks!');
  				if(useDeeplink)$.address.history(false);//skip invalid url
  				alert('Wrong category name!');
  				return false;
  			}
  			value=activeCategory;//convert to counter			
  		}else{
  			alert('Invalid value for openCategory!');
  			return false;	
  		}
  		
  		if(value == currentCategory) return;
  		transitionOn=true;//if we click undefined first
  		activeCategory = value;
  		
  		if(lastActiveMenuItem){
  			lastActiveMenuItem.css('cursor', 'pointer');
  		}
  		if(menuDivArr[value]){
  			$(menuDivArr[value]).css('cursor', 'default');
  			lastActiveMenuItem = $(menuDivArr[value]);
  		}
  		 
  		//close menu
  		if(menuOpened) toggleMenuHandler();
  		
  		if(useDeeplink){
  			$.address.value(findAddress2(0));
  			if(!$.address.history()) $.address.history(true);//restore history
  		}else{
  			cleanCategory();
  		}
  	}
  
  
  
  	
  	}
  	
  })(jQuery);
  
  
  
  
  /**
   * jQuery.browser.mobile (http://detectmobilebrowser.com/)
   *
   * jQuery.browser.mobile will be true if the browser is a mobile device
   *
   **/
  (function(a){jQuery.browser.mobile=/android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|meego.+mobile|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera);
  