// Avoid `console` errors in browsers that lack a console.
(function() {
	var method;
	var noop = function () {};
	var methods = [
		'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
		'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
		'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
		'timeline', 'timelineEnd', 'timeStamp', 'trace', 'warn'
	];
	var length = methods.length;
	var console = (window.console = window.console || {});

	while (length--) {
		method = methods[length];

		// Only stub undefined methods.
		if (!console[method]) {
			console[method] = noop;
		}
	}
}());



	//Affiche un message 'message' de type 'type' pendant 'timeout' secondes
	$.message = function (type,message,timeout){
		$.toast({ type: type, content: message, timeout: timeout });
	}

	//Permet  les notifications types toast sans dépendance de librairie/css/html 
	$.toast = function (options) {
		var defaults = {
			title: null,
			content: '',
			type: 'info',
			timeout: 3000
		};
		var o = $.extend(defaults, options);
		var css = "word-wrap:break-word;color:#ffffff;display:none;border-radius:1px;margin-bottom:10px;text-align:center;width:100%;box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);position:relative;";
		var types = {
	        error: { css: "background:#dc2626;", icon: 'fas fa-exclamation-triangle' },
	        warning: { css: "background:#ffc107;color:#212529;", icon: 'fas fa-exclamation-circle' },
	        info: { css: "background:#2AA7EA;", icon: 'fas fa-info-circle' },
	        success: { css: "background:#28a745;", icon: 'fas fa-check' },
		}
		css += types[o.type].css;
		o.icon = types[o.type].icon;

		if ($('.toastContainer').length == 0)
			$('body').append('<div class="toastContainer" style="z-index:1100;position:fixed;right:15px;top:65px;width:350px;"></div>');

		var popupContainer = $('.toastContainer');

		var popup = $('<div style="' + css + '" class="noPrint toast-'+o.type+'"><i class="toastRemove fas fa-times" style="position:absolute;top:5px;right:5px;display:none;cursor:pointer;" onclick="$(this).parent().remove();"; style="position:absolute;top:5px;right:5px;cursor:pointer;"></i><h1 class="toastTitle" style="margin:0;padding:10px;"></h1><i class="toastIcon" style="display:inline-block;vertical-align:top;width:30px;font-size:20px;margin:15px 0;"></i><p style="display: inline-block;margin-top: 10px;padding:0 10px 0 10px;width:300px;" class="toastContent"></p><div style="clear:both;"></div></div>');
		$(popupContainer).append(popup);
		if (o.title) $('.toastTitle', popup).html(o.title);
		$('.toastIcon', popup).attr('class', o.icon);

		if (!o.title) $('.toastTitle', popup).remove();

		$('.toastContent', popup).html(o.content);
		popup.fadeIn();
		
		if (o.timeout != 0) {
			setTimeout(function () { popup.fadeOut(); }, o.timeout);
		} else {
			popup.find('.toastRemove').show();
		}
	}
	
	$.page = function(element){
		var path = window.location.pathname.split('/') ;

		path = path[path.length-1];
		path = path.replace('.php','');

		return path;
	}

	$.getForm= function(element){
		return $(element).getForm();
	}
	
	$.setForm= function(element,data){
		var o = {};
		var obj = $(element);
		$('input,select,textarea',obj).each(function(i,element){
				
			if(element.id!=null && element.id!=""){
				 
				if(data[element.id]!=null){
					if($(element).attr("type")=='checkbox' || $(element).attr("type")=='radio'){
						$(element).prop("checked",data[element.id]==1 || data[element.id]=='true' ?true:false);
					} else {
						$(element).val(data[element.id]);
					}
				}

			}
		});
		return o;
	}

	//Gestion des tableaux pour le formData
	$.form_data =  function(formData, key,values){
		var hasFile = false;
		if(values instanceof File ) hasFile = true;
		
        if( typeof values == 'object' && !(values instanceof File) ){
            for(subkey in values)
				if($.form_data(formData,key + '[' + subkey + ']',values[subkey])) hasFile = true;
        }else{
            formData.append(key, values);
        }
	    return hasFile;
	}

	$.action = function(data,success,error,progress) {
		var formData = new FormData();
		var defaultSuccess = data.defaultSuccess !== undefined ? data.defaultSuccess : true;
		// if(data.defaultSuccess !== undefined) delete data.defaultSuccess;

		//hasFile determine si un fichier uploadé se trouve dans le tableau des data
		// Si c'est le cas, il envois les données en multipart, sinon il les envoie en json classique.
		var hasFile = false;
		$.each(data, function(key, value){
			if($.form_data(formData,key, value) == true) hasFile = true;
		});

		var request = {
			url : 'action.php',
			method : 'POST',
			success: function(response){
				if(response && !response.error){
					if(success!=null)success(response);
				} else {
					var errorMessage = 'ERREUR : '+"\n"+response.error;
					if(response.trace) errorMessage += "\n<div style='font-size:10px;max-height:200px;overflow:auto;text-align:left;'>"+response.trace+"</div>";
					if(defaultSuccess) $.message('error',errorMessage,0);
					if(error!=null) error(response);
				}
			},
			error : function(response){
				if(response.status == 200 && $.localhost() ){
					$('body').append('<div class="debugFrame" style="box-shadow: 0px 0px 10px rgba(0,0,0,0.5);z-index: 10001;padding: 5px;position: fixed;left: 0;top: 0;width: 40%;min-height: 100%;border-right: 2px solid #ff3b00;background: rgba(210, 222, 255, 0.9);overflow-y: auto;height: 100%;"><h3>Action debug</h3> <i style="position:absolute; right:10px; top:10px;font-size:1.5em;" onclick="$(this).parent().remove()" class="fas fa-times pointer"></i>'+response.responseText+'</div>');
				} else {
					if(response.readyState == 0 && error==null) return;
					if(error!=null)
						error(response); 
					else
						$.message('error','Erreur indefinie, merci de contacter un administrateur',0);
				}
			},
			xhr: function()
			{
				var xhr = new window.XMLHttpRequest();
				xhr.upload.addEventListener("progress", function(evt){
					if (evt.lengthComputable) {
					var percentComplete = (evt.loaded / evt.total) * 100;
					percentComplete = Math.round(percentComplete * 100) / 100;
					if(progress) progress(percentComplete,'upload');
					}
				}, false);

				xhr.addEventListener("progress", function(evt){
					if (evt.lengthComputable) {
					var percentComplete = evt.loaded / evt.total;
					if(progress) progress(percentComplete,'download');
					}
				}, false);
				return xhr;
			}
		};

		if(!hasFile){
			request.data = data;
		}else{
			request.data = formData;
			request.processData = false;
			request.contentType = false;
		}

		$.ajax(request);
	}
	
	$.localhost = function(){
		return (document.location.hostname=='127.0.0.1' || document.location.hostname=='localhost');
	}
	
	
	$.hashData = function(name){

		var page = window.location.hash.substring(1);

		page += "&"+window.location.search.substring(1);

		data = {};
		if(page!='' && page!= null){
			options = page.split('&');
			var data = {};
			for(var key in options){
				infos = options[key].split('=');
				data[infos[0]] = infos[1];
			}
		}
		if(name == null) return data;
		if(typeof name === "object"){
			data = name;
			hashstring = '';
			for(var key in data)
				hashstring+= "&"+key+"="+data[key];
			hashstring = hashstring.substring(1);
			window.location.hash = hashstring;
			return;
		}

		return typeof data[name] == "undefined" ? '':data[name];
	}


	$.urlParam = function (name,value) {
		var parameters = window.location.href.match(/[\\?&]([^&#]*)=([^&#]*)/g);
		var data = {};
		for (var key in parameters) {
			var couple = parameters[key].substring(1, parameters[key].length).split('=');
			data[couple[0]] = couple[1];
		}
		if(name == null) return data;
		if (value == null) 
			return data[name] ? data[name] : null;
		if (value != false) data[name] = value;
		var url = '?';
		for (var key in data) {
			if (value == false && key == name) continue;
			url += key + '=' + data[key]+'&';
		}
		window.history.pushState('', document.title, url.substring(0, url.length-1));
	}

	
$.fn.extend({

	toJson : function(){
	   return $.getForm(this);
	},

	getForm :  function(){
		var o = {};
		var obj = $(this);
		for(var key in obj.data()){
			if(key!="action" &&  key != "id") continue;
			o[key] = obj.attr('data-'+key);
		}
		
		$('input,select,textarea',obj).each(function(i,element){
				 if(element.id!=null && element.id!=""){
					if($(element).attr("type")=='checkbox' || $(element).attr("type")=='radio'){
						o[element.id] = ($(element).is(':checked')?1:0);
					}else{
						o[element.id] = $(element).val();
					}
				 }
		});

		return o;
	},

	upload: function (options) {
		
		//var options = $.extend(defaults, options);
		return this.each(function () {
			var o = options;

			var droppedFiles = false;
			var div = $(this);
			var data = div.data();
			data.html =!div.attr('data-label') ? '': div.attr('data-label');
			data.label = data.html;
			div.html('');
			var o = $.extend(o, data);
			
			if(o.readonly == false){
				var form = $('<form class="box" method="post" action="' + o.action + '" enctype="multipart/form-data"><input type="file" name="'+(o.fileName?o.fileName:div.attr('id'))+'[]"  multiple /></form>');
				div.append(form);
			   
				var input = form.find('input[type="file"]');

				var zone = $('<div>' + o.label + '</div>');
				div.append(zone);

				//test if dnd is enabled n browser
				var div = document.createElement('div');
				var dragAndDropEnabled = (('draggable' in div) || ('ondragstart' in div && 'ondrop' in div)) && 'FormData' in window && 'FileReader' in window;

				//set elements styles
				input.attr('style', "width: 0.1px;height: 0.1px;opacity: 0;overflow: hidden; position: absolute;z-index: -1");
				zone.css('cursor', "pointer");

				//set events
				zone
				   .on('click', function (e) {
					   form.find('input[type="file"]').trigger('click');
					   e.preventDefault();
					   e.stopPropagation();
				   })
				   .on('drag dragstart dragend dragover dragenter dragleave drop', function (e) {
					   e.preventDefault();
					   e.stopPropagation();
				   })
				  .on('dragover dragenter', function () {
					  if (o.hover) form.addClass(o.hover);
				  })
				  .on('dragleave dragend drop', function () {
					  if (o.hover) form.removeClass(o.hover);
				  })
				  .on('drop', function (e) {
					  droppedFiles = e.originalEvent.dataTransfer.files;
					  form.trigger('submit');
				  });
				input.on('change', function (e) {
					form.trigger('submit');
				});

				form.on('submit', function (e) {
					 if (o.start) o.start();
					
					if (dragAndDropEnabled) {

							e.preventDefault();
							var ajaxData = new FormData();
							if (droppedFiles) {
								
								$.each(droppedFiles, function (i, file) {
									var ext = file.name.split('.');
									ext = ext.pop();
									
									if(o.allowed && $.inArray(ext.toLowerCase(),o.allowed.split(','))===-1){
										$.message('error','Extension fichier '+ext+' non permise (autorisé:'+o.allowed+')',0);
										return;
									}
									if(o.size && file.size > o.size){
										$.message('error','Taille fichier '+file.size+' octets trop grande (autorisé:'+o.size+' octets)',0);
										return;
									}
									ajaxData.append(input.attr('name'), file);
								});
							}else{
								ajaxData = new FormData(form.get(0));
								
								for(var key in $('input',form).get(0).files){
									var file = $('input',form).get(0).files[key];
									if(file.name==null || typeof file !='object') continue;
									var ext = file.name.split('.');
									
									ext = ext.pop();
								
									if(o.allowed && $.inArray(ext.toLowerCase(),o.allowed.split(','))===-1){
										$.message('error','Extension fichier '+ext+' non permise (autorisé:'+o.allowed+')',0);
										$('input',form).val();
										return;
									}
									if(o.size && file.size > o.size){
										$.message('error','Taille fichier '+file.size+' octets trop grande (autorisé:'+o.size+' octets)',0);
										$('input',form).val();
										return;
									}
								}
							}

							if (o.addData){
								var addionalData = o.addData();
								for(var k in addionalData){
									ajaxData.append(k, addionalData[k]);
								}
							}
							droppedFiles = null;

							$.ajax({
								url: form.attr('action'),
								type: form.attr('method'),
								data: ajaxData,
								dataType: 'json',
								cache: false,
								contentType: false,
								processData: false,
								complete: function (data) {
									
									if (o.complete) o.complete(data.responseJSON);
								},
								success: function (data) {
									
									if (o.success) o.success(data);
								},
								error: function (data) {
									if (o.error) o.error(data);
								}
							});
					} else {
						var iframeName = 'uploadiframe' + new Date().getTime();
						iframe = $('<iframe name="' + iframeName + '" style="display: none;"></iframe>');

						$('body').append(iframe);
						form.attr('target', iframeName);

						iframe.one('load', function () {
							var data = JSON.parse(iframe.contents().find('body').text());
							if (!data.success) alert(data.error);
							form.removeAttr('target');
							iframe.remove();
							 if (o.complete) o.complete();
						});
					}
				});
			}
		});
	},

	clear: function (){
		return this.each(function() {
			var obj = $(this);
			obj.find('input,select,textarea').val('');
		});
	},

	addLine: function (rows){
		
		return this.each(function() {
			
			var obj = $(this);
			var model = null;
			var container = null;
			
			if(obj.prop("tagName") == 'UL'){
				container = obj;
				model = container.find('li:first-child');
				container.find('li:visible').remove();
			}else if(obj.prop("tagName") == 'TABLE'){
				container = obj.find('tbody');
				model = container.find('tr:first-child');
				container.find('tr:visible').remove();
			}else{
				container = obj;
				childName = container.children().get(0).nodeName;
				model = container.find(childName+':first-child');
				container.find(childName+':visible:not(.nofill)').remove();
			}
			var tpl = model.get(0).outerHTML;
			
			//fix jquery backslahes break
			tpl = tpl.replace(/{{##/g,'{{/').replace(/{{\/(.*)}}=""/g,'{{/$1}}');
		
			//fix images url not found on template
			tpl = tpl.replace(/(<img\s[^>]*\s)(data-src)/g,'$1src');
			
			for(var key in rows){
				var line = $(Mustache.render(tpl,rows[key]));
				container.append(line);
				line.show();
			}
				
			
		});
	},

	fill: function (option,callback,progress){
		
		return this.each(function() {
			
			var obj = $(this); 
			var model = null;
			var container = null;
			option = $.extend({showItems:true},option);
			var preloader = null;
			if(option.preloader){
				var preloader = $(option.preloader);
				preloader.css('position','absolute');
				preloader.css('left',(obj.offset().left+obj.width()/2)+'px');
				preloader.css('top',(obj.offset().top+30)+'px');
				$('body').append(preloader);
				
			}
			
			if(obj.prop("tagName") == 'UL'){
				container = obj;
				model = container.find('li:first-child');
				container.children('li:visible').remove();
			} else if(obj.prop("tagName") == 'TABLE'){
				container = obj.find('tbody');
				model = container.find('tr:first-child');
				container.children('tr:visible').remove();
			} else if(obj.prop("tagName") == "SELECT"){
				container = obj;
				model = container.find('option[value*="{{"]');
				if(model.length==0) model = $('<option class="hidden" value="{{value}}">{{label}}</option>');
				container.find('option:not([value*="{{"])').remove();
			} else{
				container = obj;
				childName = container.children().get(0).nodeName;
				model = container.find(childName+':first-child');
				container.find(childName+':visible:not(.nofill)').remove();
			}
			var tpl = model.get(0).outerHTML;
			
			//fix jquery backslashes break
			tpl = tpl.replace(/{{##/g,'{{/').replace(/{{\/(.*)}}=""/g,'{{/$1}}');
		
			//fix images url not found on template
			tpl = tpl.replace(/(<img\s[^>]*\s?)(data-src)/g,'$1src');

			var pagination = obj.nextAll('.pagination').length ? obj.nextAll('.pagination') : obj.parent().nextAll('.pagination');
			if(pagination.length!=0) option.page = $('li.active',pagination).attr('data-value');
			
			tpl = tpl.replace(/(data-style)/g, 'style');

			$.action(option,function(r){

				for(var key in r.rows){
					var line = $(Mustache.render(tpl,r.rows[key]));
					container.append(line);

					if(option.showItems){
						line.show().removeClass('hidden');
					}
					

				}
				if(r.pagination){
					
					var template = pagination.find('li:not(:visible)').get(0).outerHTML;
					$('li:not(.hidden)',pagination).remove();
					for(i=0;i<r.pagination.pages;i++){
						var li = $(Mustache.render(template,{value:i,label:i+1}));
						li.show().removeClass('hidden');
						pagination.append(li);
					}
					pagination.find('li:not(.hidden)').eq(r.pagination.current).addClass('active');
					if(r.pagination.pages>1) 
						pagination.find('.page-item:not(.hidden):first .page-link').css('border-radius','0.25rem 0 0 0.25rem');
					else
						pagination.find('.page-item:not(.hidden):first .page-link').css('border-radius','0.25rem 0.25rem 0.25rem 0.25rem');
				}
				if(preloader) preloader.remove();
				if(callback!=null)callback(r);
			},null,function(percent,type){
				if(progress) progress(percent,type);
			});
        });
	},
	
	filters: function (option){
	            
		var obj = $(this);
		var box = obj.next('.filter-box');
		var formData = {
			keyword : $('.filter-keyword',box).val()
		};
		formData.advanced = [], formData.multiple = [], formData.custom = {};
		$('.filterRow:visible',box).each(function(i,row){
			
			var row = $(row);
			if(row.find('.filter-column').val()=='') return;
			var filter = {
				join : row.find('.filter-join').val(),
				column : row.find('.filter-column').val(),
				type : row.find('.filter-column option:selected').attr('data-filter-type'),
				operator : {},
				value : {}
			}

			if ($('.filter-value-block',row).length > 1) {
				$('.filter-value-block',row).each(function(j,block){
					var block = $(block);
					filter.operator[j] = block.find('.filter-operator').val();
					filter.value[j] = block.find('.filter-value').last().val();
				});
				formData.multiple.push(filter);
			} else {
				filter.operator = row.find('.filter-operator').val();
				values = row.find('.filter-value');
				if(values.length > 1){
					filter.value = [];
					for(var j=0; j<values.length; ++j){
						filter.value.push(values.eq(j).val());
					}
					values.eq(j).attr('data-custom') == 'true' ? formData.custom[filter.column] = filter : formData.advanced.push(filter);
				} else {
					filter.value = values.val();
					values.last().attr('data-custom') == 'true' ? formData.custom[filter.column] = filter : formData.advanced.push(filter);
				} 
			}
		});
		return formData;
	},

	enter: function (option){
        return this.each(function() {
			var obj = $(this);
			obj.keydown(function(event){
			if(event.keyCode == 13){
				option();
				return false;
			}
			});
			
        });
	},

	sortable_table: function (option){

		if(option=='get'){
			var obj = $(this);
			var response = {};
			obj.find('thead th[data-sortable]').each(function(i,th){
				var th = $(th);
				
				if(th.attr('data-sort') && th.attr('data-sort')!=""){
					response = {
						sort : th.attr('data-sort'),
						sortable : th.attr('data-sortable')
					};
				}
			});
			return response;
		}

        return this.each(function() {
			var obj = $(this);
			obj.find('thead th[data-sortable]').click(function(){
				var th = $(this);
				var data = th.data();
				if(!data.sort || data.sort==''){
					data.sort = 'asc'
				}else if(data.sort == 'asc'){
					data.sort ='desc'
				}else{
					data.sort = '';
				}
				obj.find('thead th').removeClass('sort-asc').removeClass('sort-desc').removeAttr('data-sort');
				if(data.sort!='') th.addClass('sort-'+data.sort);
				th.attr('data-sort',data.sort);
				if(option.onSort) option.onSort();
			});
			
		});
	},
	autocomplete: function(o){
		return this.each(function() {
			var obj = $(this);
			obj.attr('autocomplete','off');
			var option = obj.data();
			option = $.extend(option,o);
			
			obj.typeahead({ 
				items: 5,
				minLength: 2,
				fitToElement: false,
				autoSelect : false,
				selectOnBlur : false,
				displayText : function(item){
					return (o.skin) ? o.skin(item) : item.name || item;
				},
				source: function(keyword, response){
					$.action({
						action: option.action,
						keyword: obj.val(),
						data: o.data
					},function(r){
						if(r.rows != null)
							response(r.rows);
					});
				},
				highlighter: function(item){
					if(o.highlight) {
						return o.highlight(item)
					}
					else {
						var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
					    return item.replace(new RegExp('('+query+')', 'ig'), function($1, match){
					        return '<strong>'+match+'</strong>';
					    });
					}
				},
				matcher: function(r){
					if(obj.val() == r.name)
						if(o.onClick)
							o.onClick(r,obj);
					return '<div>'+r.name+'</div>';
				},
				afterSelect: function(item) {
					obj.data('selected',true);
					if(o.onClick) o.onClick(item,obj);
					obj.trigger("change");
				}
			}).blur(function(){
				if(o.onBlur) o.onBlur(obj);
			});

			obj.data('typeahead').next =  function (event) {
	            var active = this.$menu.find('.active').removeClass('active');
	            var next = active.next();
	            if (!next.length) {
	                next = $(this.$menu.find($(this.options.item || this.theme.item).prop('tagName'))[0]);
	            }
	            while (next.hasClass('divider') || next.hasClass('dropdown-header')) {
	                next = next.next();
	            }
	            next.addClass('active');
	            var newVal = this.updater(next.data('value'));
	            this.$element.val(newVal.name || newVal);
        	};
        	obj.data('typeahead').prev =  function (event) {
				var active = this.$menu.find('.active').removeClass('active');
	            var prev = active.prev();
	            if (!prev.length){
	                prev = this.$menu.find($(this.options.item || this.theme.item).prop('tagName')).last();
	            }
	            while (prev.hasClass('divider') || prev.hasClass('dropdown-header')) {
	                prev = prev.prev();
	            }
	            prev.addClass('active');
	            var newVal = this.updater(prev.data('value'));
	            if (this.changeInputOnMove) this.$element.val(newVal.name || newVal);
        	};
		});
	},
	location: function (options){
		return this.each(function() {
			try{
				//var options = $.extend({},options);
				var obj = $(this);
				obj.attr('autocomplete','off');

				var data = $('#algolia').data();

				var placesAutocomplete = places({
				    appId:  data.api,
				    apiKey:  data.key,
				    container: obj.get(0)
				});
				placesAutocomplete.on('change', function(e) { 
					var m = /[0-9]*/m.exec(e.suggestion.name)
					var infos = {
						latitude: e.suggestion.latlng.lat,
						longitude : e.suggestion.lng,
						types : e.suggestion.type,
						number : '',
						street : e.suggestion.name,
						city : e.suggestion.city,
						country : e.suggestion.country,
						code : e.suggestion.postcode,
						picture : '',
						map : ''
					};
					if(m && m.length > 0 ) infos.number  = m[0] ;
					infos.address = (infos.street && infos.street.length && infos.number && infos.number.length) ? infos.number+' '+infos.street : (infos.street ? infos.street : '');
					if(options.select) options.select(infos);
				});
			}catch(e){
				console.warn('Composant Location en erreur, désactivé :'+e);
			}
		});
	},
	date: function (){
		return this.each(function() {

			var obj = $(this);
			obj.on('paste', function(e){
				is_valid_date(e.originalEvent.clipboardData.getData('Text')) ? obj.val("") : e.preventDefault();
			});
			obj.datepicker({
				dateFormat: "dd/mm/yy",
				dayNames: ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"],
				dayNamesMin: ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"],
				dayNamesShort: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"],
				monthNames: ["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Aout","Septembre","Octobre","Novembre","Décembre"],
				monthNamesShort: ["Jan","Fév","Mars","Avr","Mai","Juin","Juil","Aout","Sept","Oct","Nov","Déc"],
				firstDay: 1,
				changeMonth: true,
				yearRange: "-100:+0",
				changeYear: true,
				onSelect: function(dateText, inst) {
					$(this).trigger("blur");
				}
			}).keypress(function(event){
				var length = $(this).val().length;
				if(length == 2 || length == 5) $(this).val($(this).val()+'/');
			}).blur(function(event){
				$(this).removeClass('border border-danger')
				if($(this).val()=='') return;
				var segments = $(this).val().split('/');
				if(segments.length!=3) return;
				if(segments[0] > 31 || segments[1] > 12) $(this).addClass('border border-danger');
			}).attr('maxlength','10');
			
			obj.attr("placeholder","jj/mm/aaaa");
			obj.attr('pattern',"[0-9/]{10}");
			obj.attr("title","Format jj/mm/aaaa");
		});
	},
	hour: function (){
		return this.each(function() {
			var obj = $(this);
			var step = obj.attr('data-step');
			obj.on('paste', function(e){
				is_valid_hour(e.originalEvent.clipboardData.getData('Text')) ? obj.val("") : e.preventDefault();
			});
			obj.timepicker({
				disableAlphaInput: true,
				timeFormat: 'H:i',
				scrollDefault: 'now',
				'step': is_numeric(step) && step>0 ? obj.attr('data-step') : 1
			});
			obj.attr("placeholder","hh:mm");
			obj.attr('pattern',"[0-9:]{5}");
			obj.attr('title',"Format hh:mm");
		});
	},
	raiseNumber: function(from,to) {
		return this.each(function(){
			var obj = $(this);
			obj.text(from);

			var interval = 800 / (to - from);

			var interval = setInterval(function(){
				var number = parseFloat(obj.text());
				if(number>=to) {
					clearInterval(interval);
					return;
				}
				obj.text(number+1);
			},interval);
		});
	}
});