/*
 * Função que pode ser redeclarada na página para retornar parametros adicionais
 * para o formulário de construção da tree.
 * 
 * Se essa função retornar false, o treeSelect não será aberto.
 * 
 * Ex: return {cdForo: 100, cdVara: 123};
 */
function parametrosAdicionaisDoTreeSelect(campoId) {
	return {};
}


/*
 * saj-tree
 */
(function($) {
	
	// Truque do jQuery para faciltar o teste de variavel undefined com ===
	var undefined;

	$.saj = $.saj || {};
	
	var cacheControl = {};
	
	// Registra os handlers para clicks na árvore (abrir/fechar e selecionar/deselecionar
	$.saj.tree = function(treeSelector) {
		var tree = $(treeSelector);
		$('li:has(ul)', tree).click(openClose);
		$('li:not(has(ul))', tree).click(function(e){e.stopPropagation();});
		$('li span.checkable', tree).click(onCheckToggle);
	};
	
	$.saj.tree.isTreeSelect = function(domElement) {
		var valuesInput = $('input[name$=.values]', domElement)[0];
		var textInputPorId = $('input[id$=_selectionText]', domElement)[0];
		var textInputPorName = $('input[name$=.text]', domElement)[0];
		return valuesInput && textInputPorId && textInputPorId === textInputPorName;
	};
	
	$.saj.tree.getTreeSelectionValues = function(domElement) {
		if ($.saj.tree.isTreeSelect(domElement)) {
			return $('input[name$=.values]', domElement).val();
		}
		return '';
	};
	
	$.saj.tree.desabilitaTreeSelect = function(domElement) {
		mudarStatusHabilitado(domElement, false);
	};
	
	$.saj.tree.habilitaTreeSelect = function(domElement) {
		mudarStatusHabilitado(domElement, true);
	};
	
	$.saj.tree.focusTreeSelect = function(domElement) {
		$('input[id$=_selectionText]', domElement).focus();
	};
	
	$.saj.tree.limpaTreeSelect = function(domElement) {
		var treeSelect = null;
		var $input = $('input[name$=.values]', domElement);
		if ($input[0]) {
			var options = {campoId: $input.attr('id')};
			clearSelection(options);
		}
	};
	
	var mudarStatusHabilitado = function(domElement, habilita) {
		var $inputs = $('input[name$=.values], input[name$=.text]', domElement);
		var $botaoHabilitado = $('img.treeSelect_botaoHabilitado', domElement); 
		var $botaoDesabilitado = $('img.treeSelect_botaoDesabilitado', domElement);
		
		if (habilita) {
			$inputs.attr('disabled', false);
			$inputs.removeClass('disabled');
			$botaoDesabilitado.hide();
			$botaoHabilitado.show();
		} else {
			$inputs.attr('disabled', true);
			$inputs.addClass('disabled');
			$botaoHabilitado.hide();
			$botaoDesabilitado.show();
		}
	};
	
	// Handler para eventos que abrem o popup da árvore
	$.saj.tree.onPopupEvent = function(dataHolder) {
		var options = dataHolder.data;
		options = $.extend({}, options||{});
		options.shouldFilter = false;
		options.clearFilterBeforeCheckNodes = true;
		options.beforeInvokeTree = showPopupLoading;
		options.afterInvokeTree = showPopupTree;
		invokeTree(options);
		return false;
	};
	
	
	/**
	 * Método para executar o carregamento da tree no onload da página.
	 */
	$.saj.tree.loadInBackground = function(treeSelectId) {
		var options = {};
		options.campoId = getCampoId(treeSelectId); 
		options.url = getUrlTree(options.campoId);
		invokeTree(options);
	}
	
	/** 
	 * Auto completa o tree-select o resultado da consulta retornar somente 1 resultado.
	 * Função para ser executada quando o tree-select for obrigatório para evitar que o 
	 * usuário tenha que clicar na lupa quando só existe um único valor.
	 * @params treeSelectId
	 */
	$.saj.tree.loadIfSingleResult = function(treeSelectId) {
		var options = {};
		options.campoId = getCampoId(treeSelectId); 
		options.url = getUrlTree(options.campoId);
		options.afterInvokeTree = function (el, options){
			var $inputValue = $('#' + options.campoId);
			var $inputText = $('#' + options.campoId + '_selectionText');
			autoCompleteIfSingleResult($inputValue, $inputText, options.campoId);
		};
		invokeTree(options);
	}
	
	// Handler para eventos que abrem o popup da árvore pela mudanca do texto descritivo
	$.saj.tree.onTextPropertyChangeEvent = function(dataHolder) {
		var options = dataHolder.data;
		options = $.extend({}, options||{});
		if (this.nodeName == 'INPUT' && this.value == '') {
			updateSelectionValues(options, '');
			return;
		}
		options.afterInvokeTree = function (el, options){
			var $inputValue = $('#' + options.campoId);
			var $inputText = $('#' + options.campoId + '_selectionText');
			var result = autoCompleteIfSingleResult($inputValue, $inputText, options.campoId);
			if(result > 1){
				options.shouldFilter = false;
				options.clearFilterBeforeCheckNodes = false;
				showPopupTree(el, options);
			} else if(result == 0){
				$inputValue.val(''); 
				$inputText.val('');
				$inputText.focus();
			}
		};
		invokeTree(options);
		return false;
	};
	
	/**
	 * @return 1: autocomplete ok, <1: nenhum registro, >1: mais de um registro. 
	 */
	var autoCompleteIfSingleResult = function($inputValue, $inputText, campoId){
		var options = {campoId: campoId};
		var tree = getTree(options); 
		applyFilter(options, $inputText.val());
		var $leafs = $('li.last-filtered-child',tree);
		var length = $leafs.length;
		if(length == 1){
			var $span = $('span.node', $leafs);
			$inputValue.val($span.attr('value'));
			$inputText.val($span.html());
		}
		return length;
	};
	
	// Handler para o eventos que implicam em filtragem pelo valor do input de procura.
	$.saj.tree.onFilterEvent = function(dataHolder) {
		filter(dataHolder.data);
		return false; // Evita o submit em caso de bind no submit do form.
	};
	
	// Handler para eventos que limpam o filtro de procura.
	$.saj.tree.onClearFilterEvent = function(dataHolder) {
		clearFilter(dataHolder.data);
		return false;
	};
	
	// Limpa o filtro de procura e re-filtra a árvore para apresentar todos os nodos.
	var clearFilter = function(options) {
		var filterInput = getFilterInput(options);
		if (filterInput[0]) {
			filterInput.val('');
			filter(options);
		}
	};
	
	
	
	var showPopupLoading = function (){
		el = $('<div id="popupModalCarregando" style="weight: 600px, heigth: 472px" >');
		el.html('<b>Por favor, aguarde.</b>');		
		el.addClass('modalProcessando');
		$.saj.popupModal(el, 
				{ titulo:'SAJ', 
				altura: '472', 
				largura: '600',
				overlayCSS : {opacity: '0'},
				showOverlay: false,
				fadeIn: 0,
				fadeOut: 0,
				focusInput: true,
				ajustarParaCaberNaTela: false
			});
	}
	
	var showPopupTree = function (el, options){
		checkNodesFromTargetValue(options);
		if (options.shouldFilter) {
			var selectionTextInput = getEnabledSelectionTextInput(options);
			var description = $.trim(selectionTextInput.val());
			if (description) {
				filter(options, description);
			} else {
				getFilterInput(options).focus();
			}
		} else {
			getFilterInput(options).focus();
		}
		if($('#popupModalCarregando')[0]){
			$.saj.popupModalChangeContent(el, options);
			
		} else{
			$.saj.popupModal(el, 
					{ titulo:'SAJ', 
					altura: '472', 
					largura: '600',
					overlayCSS : {opacity: '0'},
					showOverlay: false,
					fadeIn: 0,
					fadeOut: 0,
					focusInput: true,
					ajustarParaCaberNaTela: false
				});
		}
	};
	
	
	/**
	 * Invoca o ajax para obter a tree.
	 * @params Obrigatórios: options.campoId, options.url
	 * @params Opcionais: options.afterInvokeTree, options.beforeInvokeTree
	 */
	var invokeTree = function(options){
		var parametrosAdicionais = parametrosAdicionaisDoTreeSelect(options.campoId);
		if (parametrosAdicionais === false) {
			return;
		}
		// Parametros para o POST do ajax
		options.params = {
			campoId: options.campoId
		};
		if (typeof options.beforeInvokeTree == 'function'){
			options.beforeInvokeTree();
		}
		
		// Configura para abrir o popup executando o ajax na primeira invocação ou com force-reload
		var reload = options.reload || detectReloadNeeded(options);
		// verifica se já existe a tree
		var $containerTreeDiv = $('div#divContainerTree_' + options.campoId);
		if(!$containerTreeDiv[0] || reload){
			cacheRequest(options);
			$.ajax({
				url: options.url,
				success: function(data){
					var id = 'divContainerTree_' + options.campoId;
					$containerTreeDiv = $('div#' + id);
					if(!$containerTreeDiv[0]){
						$containerTreeDiv = $("<div id=" + id + " >" );
						var body = document.body;
						$containerTreeDiv.appendTo(body);
						$containerTreeDiv.hide();
					}
					$containerTreeDiv.html(data);
					$containerTreeDiv.hide();
					if (typeof options.afterInvokeTree == 'function'){
						options.afterInvokeTree($containerTreeDiv, options);
					}
				},
				data: options.params
			});
		} else{
			if (typeof options.afterInvokeTree == 'function'){
				options.afterInvokeTree($containerTreeDiv, options);
			}
		}
	};
	
	var checkNodesFromTargetValue = function(options) {
		var tree = getTree(options);
		if (tree[0]) {
			if(options.clearFilterBeforeCheckNodes){
				clearFilter(options);
			}
			uncheckAllNodes(tree);

			var targetWS = emptyWS();
			var targetValues = getTargetInput(options).val();
			if (targetValues) {
				var values = targetValues.split(',');
				var treeId = getTreeId(options);
				var limit = values.length;
				for (var i=0; i<limit; i+=1) {
					var node = getNode(treeId, values[i]);
					targetWS = targetWS.add(node[0]);
				}
			}
			updateNodesStatusAndUpdateParents(targetWS, 'Checked');
		}
	};
	
	// Desmarca todos os nodos da árvore
	var uncheckAllNodes = function(tree) {
		$('li span.Checked, li span.Semichecked', tree).removeClass('Checked Semichecked').addClass('Unchecked');
	};
		
	// Filtra os nodos da árvore.
	// Utiliza o texto passado no argumento (se existir) ou o valor do input de procura
	var filter = function(options, text) {
		var filterInput = getFilterInput(options);
		if (filterInput[0]) {
			if (text) {
				filterInput.val(text);
			} else {
				text = filterInput.val();
			}
		}
		applyFilter(options, text);
		filterInput.focus();
	};
	
	$.saj.tree.onCloseEvent = function(dataHolder) {
		var options = dataHolder.data;
		close(options);
		afterCloseSemSalvar(options);
		return false;
	};
	
	var afterCloseSemSalvar = function(options) {
		var selectionInput = getSelectionTextInput(options);
		selectionInput.focus();
	};
	
	var close = function(options) {
		$.saj.closePopupModal();
	};
	
	$.saj.tree.onSaveSelection = function(dataHolder) {
		saveSelection(dataHolder.data);
		return false;
	};
	
	var saveSelection = function(options) {
		// Monta string com os valores selecionados separados por virgulas
		var selection = getSelectedNodes(options);
		var selectionLen = selection.length;
		var selectionStr = '';
		selection.each(function() {
			var val = this.attributes['value'].value;
			selectionStr += ',' + val;
		});
		if (selectionLen > 0) {
			selectionStr = selectionStr.substring(1);
		}
		
		// Atualiza a seleção
		updateSelectionValues(options, selectionStr);
		updateSelectionText(options, selection);
		
		close(options);
		focusNextInput(options);
	};
	
	var focusNextInput = function(options) {
		var selectionInput = getSelectionTextInput(options);
		selectionInput.focus();
		
		var inputs = $(':input:visible:enabled');
		var currentFound = false;
		var length = inputs.length;
		for (i=0; i<length; i+=1) {
			if (inputs[i] === selectionInput[0]) {
				i += 1;
				if (i < length) {
					inputs[i].focus();
				}
				break;
			}
		}
	};
	
	$.saj.tree.onClearSelection = function(dataHolder) {
		clearSelection(dataHolder.data);
	};
	
	var clearSelection = function(options) {
		// Limpa o campo target
		updateSelectionValues(options, '');
		
		// Limpa o campo descritivo
		updateSelectionText(options, emptyWS());
		
		afterCloseSemSalvar(options);
	};
	
	$.saj.tree.onSelectAll = function(dataHolder) {
		selectAll(dataHolder.data);
		return false;
	};
	
	var selectAll = function(options) {
		var nodes = getVisibleSelectableNodes(options);
		updateNodesStatusAndUpdateParents(nodes, 'Checked');
	};
	
	$.saj.tree.onSelectNone = function(dataHolder) {
		selectNone(dataHolder.data);
		return false;
	};
	
	var selectNone = function(options) {
		var nodes = getVisibleSelectableNodes(options);
		updateNodesStatusAndUpdateParents(nodes, 'Unchecked');
	};
	
	var applyFilter = function(options, termos) {
		var tree = getTree(options);
		if (tree[0]) {
			clearFilteredStyle();
			
			termos = $.trim(termos);
			if (termos.length == 0) {
				var termos = [];
			} else {
				termos = $.saj.removerAcentos(termos).toLowerCase();
				termos = termos.split(/ +/);
			}

			setDisplayStatus(tree, termos);
			decorateFilteredTree(tree);
			openLevel(tree, '*');
		}
	};
	
	var setDisplayStatus = function(tree, termos) {
		if (termos.length == 0) {
			// Otimização para arvore sem filtragem
			$('li', tree).css('display', '');
			return;
		}
		var found = false;
		var foundInChildren = false;
		var lis = tree.children('li');
		lis.each(function() {
			var liWS = $(this);
			var nodo = liWS.children('span.node')[0];
			if (nodo) {
				var val = nodo.attributes['searchValue'].value;
				if (match(val, termos)) {
					liWS.css('display', '');
					$('li', liWS).css('display', '');
					found = true;
				} else {
					foundInChildren = false;
					var ulWS = liWS.children('ul');
					if (ulWS[0]) {
						foundInChildren = setDisplayStatus(ulWS, termos);
					}
					liWS.css('display', foundInChildren ? '' : 'none');
					found = found || foundInChildren;
				}
			}
		});
		return found || foundInChildren;
	};
	
	var match = function(val, termos) {
		var lim = termos.length;
		if (lim == 0) {
			return true;
		}
		if (val == null) {
			return false;
		}

		var idx = 0;
		for (var i=0; i<lim; i+=1) {
			var termo = termos[i];
			idx = val.indexOf(termo, idx);
			if (idx < 0) {
				return false;
			}
		}
		return true;
	};
	
	var decorateFilteredTree = function(tree) {
		var lastChildren = $('li', tree).filter(':last-child');
		lastChildren.each(function() {
			var name = this.firstChild.nextSibling.innerHTML;
			if (this.style.display == 'none') {
				var parentLI = this.parentNode.parentNode;
				if (parentLI.nodeName != 'LI' || parentLI.nodeName == 'LI' && parentLI.style.display != 'none') {
					for (var sibling = this.previousSibling; sibling; sibling = sibling.previousSibling) {
						if (sibling.nodeName == 'LI' && sibling.style.display != 'none') {
							var siblingWS = $(sibling);
							if (siblingWS.hasClass('open')) {
								siblingWS.removeClass('open').addClass('last-filtered-child-open');
							} else if (siblingWS.hasClass('closed')) {
								siblingWS.removeClass('closed').addClass('last-filtered-child-closed');
							} else {
								siblingWS.addClass('last-filtered-child');
							}
							break;
						}
					}
				}
			}
		});
	};
	
	var openLevel = function(tree, value) {
		var level = parseInt(value, 10);
		if (isNaN(level)) {
			$('li.closed', tree).removeClass('closed').addClass('open');
			$('li.last-child-closed', tree).removeClass('last-child-closed').addClass('last-child-open');
		} else {
			$('li.open', tree).removeClass('open').addClass('closed');
			$('li.last-child-open', tree).removeClass('last-child-open').addClass('last-child-closed');
			var ulWS = tree;
			for (var i=0; i<level; i+=1) {
				ulWS.children('li.closed', tree).removeClass('closed').addClass('open');
				ulWS.children('li.last-child-closed', tree).removeClass('last-child-closed').addClass('last-child-open');
				ulWS = ulWS.children('li:has(ul)').children('ul');
			}
		}
	};
	
	var clearFilteredStyle = function(tree) {
		$('li.last-filtered-child-open', tree).removeClass('last-filtered-child-open').addClass('open'); 
		$('li.last-filtered-child-closed', tree).removeClass('last-filtered-child-closed').addClass('closed');
		$('li.last-filtered-child', tree).removeClass('last-filtered-child');
	};
	
	var openClose = function(e) {
		var ws = $(this);
		if (this.className.match(/last-child-/)) {
			ws.toggleClass('last-child-open');
			ws.toggleClass('last-child-closed');
		} else if (this.className.match(/last-filtered-child-/)) {
			ws.toggleClass('last-filtered-child-open');
			ws.toggleClass('last-filtered-child-closed');
		} else {
			ws.toggleClass('open');
			ws.toggleClass('closed');
		}
		e.stopPropagation();
	};
	
	var onCheckToggle = function(e) {
		var ws = $(this);
		if (!ws.hasClass('Unchecked')) {
			uncheck(ws);
		} else {
			check(ws);
		}
		e.stopPropagation();
	};
	
	var check = function(nodeWS) {
		if (nodeWS[0]) {
			var rootUl = $(nodeWS.parents('ul.root')[0]);
			var isMultiSelect = rootUl.hasClass('multiSelect');
			if (!isMultiSelect) {
				uncheckAllNodes(rootUl);
			}
			var parentLi = nodeWS.parent('li');
			var liWS = $('li:visible', parentLi).add(parentLi);
			//var parents = parentLi.parents('li').filter('ul.tree li');
			//var liParentWS = liWS.filter('li:has(ul)').add(parents);
			//var nodesWS = $('span.checkable', liParentWS);
			//nodesWS.removeClass('Checked Semichecked').addClass('Unchecked');
			
			var liFolhaWS = liWS.not('li:has(ul)');
			var spanWS = liFolhaWS.children('span.checkable');
			updateNodesStatusAndUpdateParents(spanWS, 'Checked');
		}
	};
	
	var uncheck = function(ws) {
		var spanWS = $('span.checkable', ws.parent('li'));
		updateNodesStatusAndUpdateParents(spanWS, 'Unchecked');
	};
	
	var semicheck = function(ws) {
		ws.removeClass('Checked Unchecked').addClass('Semichecked');
	};
	
	var changeNodeStatus = function(ws, status) {
		ws.removeClass(classesToRemove[status]).addClass(status);
	};
	
	var checkUncheckParents = function(ws) {
		if (ws[0]) {
			ws.each(function(){
				var thisWS = $(this);
				var liWS = thisWS.children('ul').children('li');
				var nodes = liWS.children('span.node');
				
				var hasChecked = nodes.is('.Checked');
				var hasUnchecked = nodes.is('.Unchecked');
				var hasSemichecked = nodes.is('.Semichecked');
				
				var allChecked = hasChecked && !(hasUnchecked || hasSemichecked);
				var allUnchecked = hasUnchecked && !(hasChecked || hasSemichecked);
				
				var spanWS = thisWS.children('span.node');
			    if (allChecked) {
			    	changeNodeStatus(spanWS, 'Checked');
			    } else if (allUnchecked) {
			    	changeNodeStatus(spanWS, 'Unchecked');
			    } else {
			    	changeNodeStatus(spanWS, 'Semichecked');
			    }
			});
			
			ws = ws.parent('ul').parent('li');
			checkUncheckParents(ws);
		}
	};
	
	var updateNodesStatusAndUpdateParents = function(nodes, status) {
		var parents = getParentLiParentLi(nodes);
		changeNodeStatus(nodes, status);
		checkUncheckParents(parents);
	};
	
	var classesToRemove = {
		Checked: 'Semichecked Unchecked',
		Unchecked: 'Semichecked Checked',
		Semichecked: 'Checked Unchecked'
	};
	
	var updateSelectionValues = function(options, values) {
		var targetInput = getTargetInput(options);
		targetInput.val(values);
		getTreeSelect(options).change();
	};
	
	$.saj.tree.updateSelectionText = function(options) {
		updateSelectionText(options);
	};
	
	var updateSelectionText = function(options, selection) {
		if (selection) {
			// Lê quantidade da seleção da arvore
			var selectionLen = selection.length;
		} else {
			// Lê a quantidade de selecionados do campo hidden (para evento "after submit")
			var targetInput = getTargetInput(options);
			var valores = targetInput.val().split(',');
			selectionLen = valores.length;
			if (selectionLen === 1 && valores[0].length === 0) {
				selectionLen = 0;
			}
		}
		
		// Gera a descrição da seleção
		var updateMsg = true;
		var msg = '';
		if (selectionLen === 1) {
			if (selection) {
				msg = selection.text();
			} else {
				// Não atualiza a mensagem para o evento de carregamento da página que
				// não passa o parametro selection
				updateMsg = false;
			}
		} else if (selectionLen > 1) {
			msg = selectionLen + ' Registros selecionados';
		}
		
		// Atualiza o campo de descrição
		var selectionTextInput = getSelectionTextInput(options);
		
		if (updateMsg) {
			selectionTextInput.val(msg);
		}
		
		// Atualiza o status readonly do campo descritivo
		if (selectionLen > 1) {
			selectionTextInput.attr('readonly', 'readonly').addClass('disabled');
		} else {
			selectionTextInput.removeAttr('readonly').removeClass('disabled');
		}
	};
	
	var getParentLiParentLi = function(ws) {
		return ws.parent('li').parent('ul').parent('li');
	};
	
	/**
	 * Retorna o TABLE que contem os campos input e botões de lupa e vassoura do treeSelect
	 */
	$.saj.tree.getTreeSelect = function(rowId) {
		if (rowId[0] != '#') {
			rowId = '#' + rowId;
		}
		var treeSelect = null;
		var $row = $(rowId);
		var $input = $('input[name$=.values]', $row);
		if ($input[0]) {
			treeSelect = getTreeSelect({campoId: $input.attr('id')});
		}
		return treeSelect;
	};
	
	/**
	 * Retorna o TABLE que contem os campos input e botões de lupa e vassoura do treeSelect
	 */
	var getTreeSelect = function(options) {
		return $('#' + options.campoId).parents('table.treeSelect');
	};
	
	var getTreeId = function(options) {
		return options.campoId + '_tree';
	};
	
	/**
	 * Retorna o UL raiz da árvore
	 */
	var getTree = function(options) {
		return $('#' + getTreeId(options));
	};
	
	
	/**
	 * Retorna a url para ajax da tree
	 */
	var getUrlTree = function(campoId) {
		return $('#' + campoId + '_action').attr('value')
	};
	
	
	/**
	 * Retorna o campoId do tree-select a aprtir do treeSelectId
	 */
	var getCampoId = function(treeSelectId){
		var campo = $('#' + treeSelectId + ' input[name$=.values]');
		return campo[0].id;
	};
	
	var getFilterInput = function(options) {
		return $('#' + options.campoId + '_treeSelectFilter');
	};
	
	var getTargetInput = function(options) {
		return $('#' + options.campoId);
	};
	
	$.saj.tree.getSelectionTextInput = function(options) {
		return getSelectionTextInput(options);
	};
	
	var getSelectionTextInput = function(options) {
		return $('#' + options.campoId + '_selectionText');
	};
	
	var getEnabledSelectionTextInput = function(options) {
		return getSelectionTextInput(options).not('[readonly]');
	};
	
	var getVisibleSelectableNodes = function(options) {
		var tree = getTree(options);
		return $('li:visible > span.selectable', tree);
	};
	
	var getSelectedNodes = function(options) {
		var tree = getTree(options);
		return $('li span.Checked.selectable', tree);
	};
	
	var getNode = function(treeId, id) {
		return $('#' + treeId + '_node_' + id);
	};
	
	var emptyWS = function() {
		var emptyWS = $();
		return emptyWS.not(emptyWS);
	};
	
	
	var detectReloadNeeded = function(options) {
		var oldParams = cacheControl[options.campoId];
		var optParams = options.params;
		if (oldParams) {
			var name;
			for (name in oldParams) {
				if (optParams[name] === undefined || oldParams[name] != optParams[name]) {
					return true;
				}
			}
			for (name in optParams) {
				if (oldParams[name] === undefined || optParams[name] != oldParams[name]) {
					return true;
				}
			}
			return false;
		}
		return true;
	};
	
	var cacheRequest = function(options) {
		cacheControl[options.campoId] = options.params;
	};
	
})(jQuery);

