<commit_before>/*****************************************************
*													 *
*	Author: Dinesh Vadivel							 *
*	Plugin: jquery.dropList.1.0.0.js				 *
*	Date:	20-06-2013								 *
*													 *
*													 *
*													 *
*													 *
*													 *
*													 *
*****************************************************/

(function($){
   var DropList = function(element, options)
   {
       var elem = $(element);
       var obj = this;
       var rand;
       // Merge options with defaults
       var settings = $.extend({
       	  text		: "Select your car",
          speed		: 200,

          type		: "dropdown",
          search	: false,
          multiple	: false,
          selected	: ""
       }, options || {});

       var matched, browser;
       jQuery.uaMatch = function( ua ) {
	   ua = ua.toLowerCase();
	   var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
        /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
        /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
        /(msie) ([\w.]+)/.exec( ua ) ||
        ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
        [];

		    return {
		        browser: match[ 1 ] || "",
		        version: match[ 2 ] || "0"
		    };
		};

		matched = jQuery.uaMatch( navigator.userAgent );
		browser = {};

		if ( matched.browser ) {
		    browser[ matched.browser ] = true;
		    browser.version = matched.version;
		}

		// Chrome is Webkit, but Webkit is also Safari.
		if ( browser.chrome ) {
		    browser.webkit = true;
		} else if ( browser.webkit ) {
		    browser.safari = true;
		}

		jQuery.browser = browser;

       GenerateUI(elem, settings, matched.browser);

       // Public method
       this.addhighlight = function()
       {

       };
   };

   function GenerateUI(element, options, browser)
   {
		console.log(options.ar);
		rand=Math.floor((Math.random()*9999999)+9999);

		ID=element.attr('id');
		parentID=element.parent().attr('id');
		$('#'+ID).hide();
		if(options.search==false)
		{

			if(options.selected=="")
			{
				$('#'+parentID).append('

'+options.text+'

'+options.text+'

');
			}
			else
			{
				var json=$.parseJSON( options.selected);
				var parsed=json[0];
				if(options.multiple==false)
				{
				$('#'+parentID).append('

'+parsed+'

'+options.text+'

');
				$('#dlholder_'+rand).siblings('#dlist').children('option[value='+parsed+']').attr('selected', 'selected');
				}
				else
				{	var temp='';

					$.each(json,function(key,value){

						$('#'+ID).children('option[value='+value+']').attr('selected', 'selected');
						//$('#dlholder_'+rand).siblings('#'+ID).children('option[value='+value+']').attr('selected', 'selected');
						temp+=value+',';
					});
					temp=temp.substr(0,temp.length-1);
					$("#dlholder_"+rand).children('#tempdllist').text(temp);
					$('#'+parentID).append('

'+temp+'

'+options.text+'

');

				}
			}

			$('#'+parentID).append('

');
			$('#'+parentID).append('

');
			$('#'+ID+' option').each(function(){
				$('#dldrop_'+rand).append('
'+this.value+'
');
			});

			if(options.multiple==false)
			{
				$('#dlholder_'+rand).click(function(){
					var split=this.id.split("_");
					$('.dListdrop').each(function(){
						if(this.id!="dldrop_"+split[1]&&$('#'+this.id).is(":visible"))
						{
							$("#"+this.id).slideUp();
						}
					});
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).addClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideDown( options.speed, function() {
						});
					}
					else
					{
					    $("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).removeClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {

					  	});
					}
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

					}
					else
					{
						$(this).removeClass('currentclick');
						$("#dldrop_"+split[1]+" #SelectItem").click(function(){
							selection=$(this).text();
							$('#dlholder_'+split[1]+' #dltext').text(selection);
							$('#dlholder_'+split[1]).siblings('#dlist').children('option:selected').removeAttr('selected');
							$('#dlholder_'+split[1]).siblings('#dlist').children('option[value='+selection+']').attr('selected', 'selected');
							$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {
							});
						});
					}

				});
			}
			else if(options.multiple==true)
			{
				$('#dlholder_'+rand).click(function(){

					var split=this.id.split("_");
					$('.dListdrop').each(function(){
						if(this.id!="dldrop_"+split[1]&&$('#'+this.id).is(":visible"))
						{
							$("#"+this.id).slideUp();
						}
					});
					var Stext=$("#dlholder_"+split[1]).children('#tempdllist').text();
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).addClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideDown( options.speed, function() {
						});
					}
					else
					{
					    $("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).removeClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {

					  	});
					}
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

					}
					else
					{

						if(Stext==options.text)
						{
							var items=[];
						}
						else
						{
							var items=Stext.split(',');
						}

						//var trainindIdArray =
						$(this).removeClass('currentclick');
						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).click(function(){
								var disable=$(this).hasClass('ItemAdded');
								if(disable==false)
								{
									$(this).addClass('ItemAdded');
									var selection=$(this).text();

									items.push(selection);
									$('#dlholder_'+split[1]+' #dltext').text(selection);
									$('#dlholder_'+split[1]).siblings('select').children('option:selected').removeAttr('selected');
									$.each(items,function(e,value){
										$('#dlholder_'+split[1]).siblings('select').children('option[value='+value+']').attr('selected', 'selected');
									});
									var stringme=items+"";
									$('#dlholder_'+split[1]+' #dltext').text(stringme);
									$('#dlholder_'+split[1]+' #tempdllist').text(stringme);

								}
								else
								{
									selection=$(this).text();
									$(this).removeClass('ItemAdded');
									items = jQuery.grep(items, function(value) {
									  return value != selection;
									});
									var stringme=items+"";
									$('#dlholder_'+split[1]+' #dltext').text(stringme);
									$('#dlholder_'+split[1]+' #tempdllist').text(stringme);
									$('#dlholder_'+split[1]).siblings('select').children('option[value='+selection+']').removeAttr('selected');
									if(items.length==0)
									{
										$('#dlholder_'+split[1]+' #dltext').text(options.text);
										$('#dlholder_'+split[1]+' #tempdllist').text(options.text);

									}
								}
							});

						});

					}

				});

			}

		}
		else if(options.search==true&&options.multiple==false)
		{

			$('#'+parentID).append('

<input type="text" name="searchstring" class="dlsearch" placeholder="'+options.text+'" id="dlsrch_'+rand+'">

'+options.text+'

');
			$('#'+parentID).append('

');
			$('#'+parentID).append('

');
			$('#'+ID+' option').each(function(){
				$('#dldrop_'+rand).append('
'+this.value+'
');
			});

			$("#dlsrch_"+rand).keyup(function(e){

				var split=this.id.split("_");
				$('.dListdrop').each(function(){
						if(this.id!="dldrop_"+split[1]&&$('#'+this.id).is(":visible"))
						{
							$("#"+this.id).slideUp();
						}
					});
				var filter = $(this).val(), count = 0;
				if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
				{

						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).addClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideDown( options.speed, function() {
						});
				}

				$("#dldrop_"+split[1]+" #SelectItem").each(function(){
					if ($(this).text().search(new RegExp(filter, "i")) < 0) {
		                $(this).hide();

		            } else {
		                $(this).show();
		                count++;
		            }
	            });
	            if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
				{

				}
				else
				{
						$(this).removeClass('currentclick');
						$("#dldrop_"+split[1]+" #SelectItem").click(function(){
							selection=$(this).text();

							$('#dlholder_'+split[1]+' #dltext input').val(selection);
							$('#dlholder_'+split[1]).siblings('#dlist').children('option:selected').removeAttr('selected');
							$('#dlholder_'+split[1]).siblings('#dlist').children('option[value='+selection+']').attr('selected', 'selected');
							$('#'+ID).children().removeAttr('selected');
							$('#'+ID).children('option[value='+selection+']').attr('selected', 'selected');
							$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {
							});
						});
				}
			});

			$('#dlbtn_'+rand).click(function(){
					var split=this.id.split("_");
					$('.dListdrop').each(function(){
						if(this.id!="dldrop_"+split[1]&&$('#'+this.id).is(":visible"))
						{

							$("#"+this.id).slideUp();
						}
					});

					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).addClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideDown( options.speed, function() {
						});
					}
					else
					{
					    $("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).removeClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {

					  	});
					}
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

					}
					else
					{
						$(this).removeClass('currentclick');
						$("#dldrop_"+split[1]+" #SelectItem").click(function(){
							selection=$(this).text();
							$('#dlholder_'+split[1]+' #dltext input').val(selection);
							$('#dlholder_'+split[1]).siblings('#dlist').children('option:selected').removeAttr('selected');
							$('#dlholder_'+split[1]).siblings('#dlist').children('option[value='+selection+']').attr('selected', 'selected');
							$('#'+ID).children().removeAttr('selected');
							$('#'+ID).children('option[value='+selection+']').attr('selected', 'selected');
							$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {
							});
						});
					}
			});

		}

 };

   $.fn.dropList = function(options)
   {
       return this.each(function()
       {
           var element = $(this);

           // Return early if this element already has a plugin instance
           if (element.data('dropList')) return;

           // pass options to plugin constructor
           var dropList = new DropList(this, options);

           // Store plugin object in this element's data
           element.data('dropList', dropList);
       });
   };
})(jQuery);<commit_msg>no message<commit_after>/*****************************************************
*													 *
*	Author: Dinesh Vadivel							 *
*	Plugin: jquery.dropList.1.0.0.js				 *
*	Date:	20-06-2013								 *
*													 *
*													 *
*													 *
*													 *
*													 *
*													 *
*****************************************************/

(function($){
   var DropList = function(element, options)
   {
       var elem = $(element);
       var obj = this;
       var rand;
       // Merge options with defaults
       var settings = $.extend({
       	  text		: "Select your car",
          speed		: 200,

          type		: "dropdown",
          search	: false,
          multiple	: false,
          selected	: '["default"]'
       }, options || {});

       var matched, browser;
       jQuery.uaMatch = function( ua ) {
	   ua = ua.toLowerCase();
	   var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
        /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
        /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
        /(msie) ([\w.]+)/.exec( ua ) ||
        ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
        [];

		    return {
		        browser: match[ 1 ] || "",
		        version: match[ 2 ] || "0"
		    };
		};

		matched = jQuery.uaMatch( navigator.userAgent );
		browser = {};

		if ( matched.browser ) {
		    browser[ matched.browser ] = true;
		    browser.version = matched.version;
		}

		// Chrome is Webkit, but Webkit is also Safari.
		if ( browser.chrome ) {
		    browser.webkit = true;
		} else if ( browser.webkit ) {
		    browser.safari = true;
		}

		jQuery.browser = browser;

       GenerateUI(elem, settings, matched.browser);

       // Public method
       this.addhighlight = function()
       {

       };
   };

   function GenerateUI(element, options, browser)
   {

		rand=Math.floor((Math.random()*9999999)+9999);
		ID=element.attr('id');
		var parentID=element.parent().attr('id');

		$('#'+ID).hide();
		if(options.search==false)
		{

			if(options.selected=="")
			{

				$('#'+parentID).append('

'+options.text+'

'+options.text+'

');
			}
			else
			{
				var json=$.parseJSON(options.selected);
				var parsed=json[0];

				if(options.multiple==false)
				{

				$('#'+parentID).append('

'+parsed+'

'+options.text+'

');
				$('#dlholder_'+rand).siblings('#dlist').children('option[value='+parsed+']').attr('selected', 'selected');
				}
				else
				{
				var temp='';

					$.each(json,function(key,value){

						$('#'+ID).children('option[value='+value+']').attr('selected', 'selected');
						//$('#dlholder_'+rand).siblings('#'+ID).children('option[value='+value+']').attr('selected', 'selected');
						temp+=value+',';
					});
					temp=temp.substr(0,temp.length-1);
					$("#dlholder_"+rand).children('#tempdllist').text(temp);
					$('#'+parentID).append('

'+temp+'

'+options.text+'

');

				}
			}

			$('#'+parentID).append('

');
			$('#'+parentID).append('

');
			$('#'+ID+' option').each(function(){
				$('#dldrop_'+rand).append('
'+this.value+'
');
			});

			if(options.multiple==false)
			{
				$('#dlholder_'+rand).click(function(){
					var split=this.id.split("_");

					$('.dListdrop').each(function(){
						if(this.id!="dldrop_"+split[1]&&$('#'+this.id).is(":visible"))
						{
							$("#"+this.id).slideUp();
						}
					});
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).addClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideDown( options.speed, function() {
						});
					}
					else
					{
					    $("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).removeClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {

					  	});
					}
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

					}
					else
					{
						$(this).removeClass('currentclick');
						$("#dldrop_"+split[1]+" #SelectItem").click(function(){
							selection=$(this).text();

							$('#dlholder_'+split[1]+' #dltext').text(selection);
							$('#dlholder_'+split[1]).siblings('#dlist').children('option:selected').removeAttr('selected');
							$('#dlholder_'+split[1]).siblings('#dlist').children('option[value='+selection+']').attr('selected', 'selected');
							$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {
							});
						});
					}

				});
			}
			else if(options.multiple==true)
			{
				$('#dlholder_'+rand).click(function(){

					var split=this.id.split("_");
					$('.dListdrop').each(function(){
						if(this.id!="dldrop_"+split[1]&&$('#'+this.id).is(":visible"))
						{
							$("#"+this.id).slideUp();
						}
					});
					var Stext=$("#dlholder_"+split[1]).children('#tempdllist').text();
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).addClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideDown( options.speed, function() {
						});
					}
					else
					{
					    $("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).removeClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {

					  	});
					}
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

					}
					else
					{

						if(Stext==options.text)
						{
							var items=[];
						}
						else
						{
							var items=Stext.split(',');
						}

						//var trainindIdArray =
						$(this).removeClass('currentclick');
						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).click(function(){
								var disable=$(this).hasClass('ItemAdded');
								if(disable==false)
								{
									$(this).addClass('ItemAdded');
									var selection=$(this).text();

									items.push(selection);
									$('#dlholder_'+split[1]+' #dltext').text(selection);
									$('#dlholder_'+split[1]).siblings('select').children('option:selected').removeAttr('selected');
									$.each(items,function(e,value){
										$('#dlholder_'+split[1]).siblings('select').children('option[value='+value+']').attr('selected', 'selected');
									});
									var stringme=items+"";
									$('#dlholder_'+split[1]+' #dltext').text(stringme);
									$('#dlholder_'+split[1]+' #tempdllist').text(stringme);

								}
								else
								{
									selection=$(this).text();
									$(this).removeClass('ItemAdded');
									items = jQuery.grep(items, function(value) {
									  return value != selection;
									});
									var stringme=items+"";
									$('#dlholder_'+split[1]+' #dltext').text(stringme);
									$('#dlholder_'+split[1]+' #tempdllist').text(stringme);
									$('#dlholder_'+split[1]).siblings('select').children('option[value='+selection+']').removeAttr('selected');
									if(items.length==0)
									{
										$('#dlholder_'+split[1]+' #dltext').text(options.text);
										$('#dlholder_'+split[1]+' #tempdllist').text(options.text);

									}
								}
							});

						});

					}

				});

			}

		}
		else if(options.search==true&&options.multiple==false)
		{

			$('#'+parentID).append('

<input type="text" name="searchstring" class="dlsearch" placeholder="'+options.text+'" id="dlsrch_'+rand+'">

'+options.text+'

');
			$('#'+parentID).append('

');
			$('#'+parentID).append('

');
			$('#'+ID+' option').each(function(){
				$('#dldrop_'+rand).append('
'+this.value+'
');
			});

			$("#dlsrch_"+rand).keyup(function(e){

				var split=this.id.split("_");
				$('.dListdrop').each(function(){
						if(this.id!="dldrop_"+split[1]&&$('#'+this.id).is(":visible"))
						{
							$("#"+this.id).slideUp();
						}
					});
				var filter = $(this).val(), count = 0;
				if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
				{

						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).addClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideDown( options.speed, function() {
						});
				}

				$("#dldrop_"+split[1]+" #SelectItem").each(function(){
					if ($(this).text().search(new RegExp(filter, "i")) < 0) {
		                $(this).hide();

		            } else {
		                $(this).show();
		                count++;
		            }
	            });
	            if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
				{

				}
				else
				{
						$(this).removeClass('currentclick');
						$("#dldrop_"+split[1]+" #SelectItem").click(function(){
							selection=$(this).text();

							$('#dlholder_'+split[1]+' #dltext input').val(selection);
							$('#dlholder_'+split[1]).siblings('#dlist').children('option:selected').removeAttr('selected');
							$('#dlholder_'+split[1]).siblings('#dlist').children('option[value='+selection+']').attr('selected', 'selected');
							$('#'+ID).children().removeAttr('selected');
							$('#'+ID).children('option[value='+selection+']').attr('selected', 'selected');
							$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {
							});
						});
				}
			});

			$('#dlbtn_'+rand).click(function(){
					var split=this.id.split("_");
					$('.dListdrop').each(function(){
						if(this.id!="dldrop_"+split[1]&&$('#'+this.id).is(":visible"))
						{

							$("#"+this.id).slideUp();
						}
					});

					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

						$("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).addClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideDown( options.speed, function() {
						});
					}
					else
					{
					    $("#dldrop_"+split[1]+" #SelectItem").each(function(){
							$(this).removeClass('dlithov');
						});
						$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {

					  	});
					}
					if( $( "#dldrop_"+split[1] ).is( ":hidden" ) )
					{

					}
					else
					{
						$(this).removeClass('currentclick');
						$("#dldrop_"+split[1]+" #SelectItem").click(function(){
							selection=$(this).text();
							$('#dlholder_'+split[1]+' #dltext input').val(selection);
							$('#dlholder_'+split[1]).siblings('#dlist').children('option:selected').removeAttr('selected');
							$('#dlholder_'+split[1]).siblings('#dlist').children('option[value='+selection+']').attr('selected', 'selected');
							$('#'+ID).children().removeAttr('selected');
							$('#'+ID).children('option[value='+selection+']').attr('selected', 'selected');
							$( "#dldrop_"+split[1] ).slideUp( options.speed, function() {
							});
						});
					}
			});

		}

 };

   $.fn.dropList = function(options)
   {
       return this.each(function()
       {
           var element = $(this);

           // Return early if this element already has a plugin instance
           if (element.data('dropList')) return;

           // pass options to plugin constructor
           var dropList = new DropList(this, options);

           // Store plugin object in this element's data
           element.data('dropList', dropList);
       });
   };
})(jQuery);<|endoftext|>


<commit_before>(function(n){var d={init:function(a){var b=n.extend({nombre:null,primerapellido:null,segundoapellido:null,dia:null,mes:null,ano:null,change:null,success:null,error:null,selfcomplete:!1},a);return this.each(function(){var a=null,h=null,f=null,l=/^([A-Z&\u00D1]{3})([0-9]{6})([0-9A-Z]{3})$/i,k=/^([A-Z&\u00D1]{4})([0-9]{6})([0-9A-Z]{3})$/i;n(this).keyup(function(){var e=d.normalizeClave(n(this).val().toUpperCase()),g=null,m=null;b.selfcomplete?/^([A-Z&\u00D1]{4})([0-9]{6})$/i.test(e)&&(b.nombre.val()&&
b.primerapellido.val()?(a=d.clave(b.nombre.val().toUpperCase(),b.primerapellido.val().toUpperCase(),b.segundoapellido.val().toUpperCase(),b.dia?b.dia.val():d.extract2("day",e),b.mes?b.mes.val():d.extract2("month",e),b.ano?b.ano.val():d.extract2("year",e)),h=d.homonimia(b.primerapellido.val().toUpperCase()+" "+b.segundoapellido.val().toUpperCase()+" "+b.nombre.val().toUpperCase()),f=d.digitoVerificador(a.substring(0,12)),e+h+f===a?(n(this).attr("value",a),b.success&&b.success.call(this,a)):(m=a,b.error&&
b.error.call(this,"Error:\n"+("La parte inicial de la clave ("+e+") no coincide con la informaci\u00f3n que se obtiened del nombre del contribuyente."),m)),b.change&&b.change.call(this,a,h,f)):b.error&&b.error.call(this,"Error:\nEs necesario, para completar autom\u00e1ticamente la clave del R.F.C. que introduzca primero el nombre y el (los) apellido(s) del contribuyente.",null)):k.test(e)?(a=d.clave(b.nombre.val().toUpperCase(),b.primerapellido.val().toUpperCase(),b.segundoapellido.val().toUpperCase(),
b.dia?b.dia.val():d.extract("day",e),b.mes?b.mes.val():d.extract("month",e),b.ano?b.ano.val():d.extract("year",e)),h=d.homonimia(b.primerapellido.val().toUpperCase()+" "+b.segundoapellido.val().toUpperCase()+" "+b.nombre.val().toUpperCase()),f=d.digitoVerificador(a.substring(0,12)),h!=d.extract("homonimia",e)&&(g="Clave diferenciadora de homonimia suministrada ("+d.extract("homonimia",e)+") no coincide con la que se obtiene de los nombres suministrados ("+h+"). La raz\u00f3n de esta discrepancia se puede deber a una incorrecta captura del nombre o apellidos del contribuyente."),
f!=d.extract("digito_verificador",e)&&(g=g+"\nDigito verificador suministrador ("+d.extract("digito_verificador",e)+") no coincide con el que se obtiene de la clave del R.F.C. ("+f+"). Posiblemente la clave del R.F.C. se esta capturando incorrectamente."),e!=a&&(g=g+"\nLa clave del R.F.C. suministrada ("+e+") no coincide con la c\u00e1lculada ("+a+")",m=a),/^([A-Z&\u00D1]{4})([0-9]{2})((0[1-9])|(1[012]))((0[1-9])|([12][0-9])|(3[01]))([1-9A-NP-Z]{2})[0-9A]$/i.test(e)||(g+="\nClave del R.F.C. no bien formada."),
b.change&&b.change.call(this,a,h,f),g?b.error&&b.error.call(this,"Error:\n"+g,m):b.success&&b.success.call(this,e)):l.test(e)&&(f=d.digitoVerificador(e.substring(0,11)),d.extract("digito_verificador",e),f!=d.extract("digito_verificador",e)&&(g="El digito verificador suministrado con la clave del R.F.C. ("+d.extract("digito_verificador",e)+") no coincide con el que se obtiene directamente del c\u00e1lculo de la clave ("+f+")",m=e.substring(0,11)+f),/^([A-Z&\u00D1]{3})([0-9]{2})((0[1-9])|(1[012]))((0[1-9])|([12][0-9])|(3[01]))([1-9A-NP-Z]{2})[0-9A]$/i.test(e)||
(g+="\nClave del R.F.C. no bien formada."),g?b.error&&b.error.call(this,"Error:\n"+g,m):b.success&&b.success.call(this,e),b.change&&b.change.call(this,a,h,f))})})},clave:function(a,b,c,h,f,l){var k=null,e=[],g=[],m=[],g=e=void 0,e=d.regla8(d.normalize(a.toUpperCase())),e=d.regla6(e),g=d.regla8(d.normalize(b.toUpperCase()));c&&(m=d.regla8(d.normalize(c.toUpperCase())));2>=g[0].length&&(k=m.length?d.regla4(e[0],g[0],m[0]):d.regla7(e[0],g[0]));0===m.length&&(k=d.regla7(e[0],g[0]));null===k&&(k=d.regla1(e[0],
g[0],m[0]));k=d.regla9(k);k+=d.regla2(h,f,l);e=d.homonimia((b+" "+c+" "+a).toUpperCase());g=d.digitoVerificador(k+e);return k+e+g},extract:function(a,b){var c=null;"year"===a?c=/\d{2}(?=(\d{4}))/:"month"===a?c=/\d{2}(?=(\w{5}$))/:"day"===a?c=/\d{2}(?=(\w{3}$))/:"homonimia"===a?c=/\w{2}(?=(\w(?=$)))/:"digito_verificador"===a&&(c=/\w(?=$)/);return c?c.exec(b)[0]:null},extract2:function(a,b){var c=b.match(/\d{2}/g);return"year"===a?c[0]:"month"===a?c[1]:"day"===a?c[2]:null},homonimia:function(a){for(var b=
{" ":0,"0":0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,"&":10,A:11,B:12,C:13,D:14,E:15,F:16,G:17,H:18,I:19,J:21,K:22,L:23,M:24,N:25,O:26,P:27,Q:28,R:29,S:32,T:33,U:34,V:35,W:36,X:37,Y:38,Z:39,"\u00d1":40,"\u00c1":11,"\u00c9":15,"\u00cd":19,"\u00d3":26,"\u00da":34},c={"0":"1",1:"2",2:"3",3:"4",4:"5",5:"6",6:"7",7:"8",8:"9",9:"A",10:"B",11:"C",12:"D",13:"E",14:"F",15:"G",16:"H",17:"I",18:"J",19:"K",20:"L",21:"M",22:"N",23:"P",24:"Q",25:"R",26:"S",27:"T",28:"U",29:"V",30:"W",31:"X",32:"Y",33:"Z"},h=0,f=0,
l=null,k=0,e=0,g=0,m=null,m=/\w|\s|&|\u00D1|\u00C1|\u00C9|\u00CD|\u00D3|\u00DA/,p=0;p<a.length;p++)l=a.charAt(p),m.test(l)&&(n.each(b,function(a,b){k=b;return l!=a}),f+=(10*h+d.decena(k))*d.decena(k),h=k%10,f+=k*h);f%=1E3;e=f%34;g=(f-e)/34;n.each(c,function(a,b){l=b;return g!=a});m=l;n.each(c,function(a,b){l=b;return e!=a});return m+l},decena:function(a){return 30<=a?3:20<=a?2:10<=a?1:0},digitoVerificador:function(a){var b={"0":0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,G:16,
H:17,I:18,J:19,K:20,L:21,M:22,N:23,"&":24,O:25,P:26,Q:27,R:28,S:29,T:30,U:31,V:32,W:33,X:34,Y:35,Z:36," ":37,"\u00d1":38},c="",d=0,f=0,l=0,l=13,k=null,k=11===a.length?" "+a:a;for(a=0;a<k.length;a++)c=k.charAt(a),n.each(b,function(a,b){d=b;return c!=a}),f+=d*l,l-=1;l=f%11;return 0==l?"0":1==l?"A":11-l},normalizeClave:function(a){return a.replace(/[ -]/g,"")},regla1:function(a,b,c){var d=b.substring(1).match(/A|E|I|O|U|\u00C1|\u00C9|\u00CD|\u00D3|\u00DA/i)[0].charAt(0);return b.charAt(0)+d+c.charAt(0)+
a.charAt(0)},regla2:function(a,b,c){1===a.length&&(a="0"+a);1===b.length&&(b="0"+b);1===c.length&&(c="0"+c);return c+b+a},regla3:function(a){var b=void 0;return b=a.match(/^CH|^LL/i)?a.charAt(0)+a.substring(2):a},regla4:function(a,b,c){return b.charAt(0)+c.charAt(0)+a.charAt(0)+a.charAt(1)},regla5:function(a,b,c){},regla6:function(a){for(var b=[],c=0;c<a.length;c++)"MARIA"===a[c]||("MAR\u00cdA"===a[c]||"JOSE"===a[c]||"JOS\u00c9"===a[c])||b.push(a[c]);return b},regla7:function(a,b){return b.charAt(0)+
b.charAt(1)+a.charAt(0)+a.charAt(1)},regla8:function(a){var b=[];a=a.split(" ");for(var c=0;c<a.length;c++)a[c].length&&!("DE"===a[c]||"DEL"===a[c]||"LA"===a[c]||"LAS"===a[c]||"LOS"===a[c]||"MC"===a[c]||"MAC"===a[c]||"MI"===a[c]||"VAN"===a[c]||"VON"===a[c]||"Y"===a[c])&&b.push(a[c]);return b},regla9:function(a){var b=void 0;return b="BUEI"===a||"BUEY"===a||"CACA"===a||"CACO"===a||"CAGA"===a||"CAGO"===a||"CAKA"===a||"COGE"===a||"COJA"===a||"COJE"===a||"COJI"===a||"COJO"===a||"CULO"===a||"FETO"===a||
"GUEY"===a||"JOTO"===a||"KACA"===a||"KACO"===a||"KAGA"===a||"KAGO"===a||"KOGE"===a||"KOJO"===a||"KAKA"===a||"KULO"===a||"MAME"===a||"MAMO"===a||"MEAR"===a||"MEON"===a||"MION"===a||"MOCO"===a||"MULA"===a||"PEDA"===a||"PEDO"===a||"PENE"===a||"PUTA"===a||"PUTO"===a||"QULO"===a||"RATA"===a||"RUIN"===a?a.charAt(0)+a.charAt(1)+a.charAt(2)+"X":a},normalize:function(a){for(var b="",c=null,h=0;h<a.length;h++){if("\u00c1"===a.charAt(h))c="A";else if("\u00c9"===a.charAt(h))c="E";else if("\u00cd"===a.charAt(h))c=
"I";else if("\u00d3"===a.charAt(h))c="O";else if("\u00da"===a.charAt(h))c="U";else if("."===a.charAt(h))continue;else if("'"===a.charAt(h))continue;else c=a.charAt(h);b+=c}return d.regla3(b)}};n.fn.rfc_tester=function(a){if(d[a])return d[a].apply(this,Array.prototype.slice.call(arguments,1));if("object"===typeof a||!a)return d.init.apply(this,arguments);n.error("El m\u00e9todo "+a+" no existe en la presente implementaci\u00f3n.")}})(jQuery);
<commit_msg>Correct date format when the year is a full year representation<commit_after>(function(n){var d={init:function(a){var b=n.extend({nombre:null,primerapellido:null,segundoapellido:null,dia:null,mes:null,ano:null,change:null,success:null,error:null,selfcomplete:!1},a);return this.each(function(){var a=null,h=null,g=null,l=/^([A-Z&\u00D1]{3})([0-9]{6})([0-9A-Z]{3})$/i,k=/^([A-Z&\u00D1]{4})([0-9]{6})([0-9A-Z]{3})$/i;n(this).keyup(function(){var e=d.normalizeClave(n(this).val().toUpperCase()),f=null,m=null;b.change&&b.change.call(this);b.selfcomplete?/^([A-Z&\u00D1]{4})([0-9]{6})$/i.test(e)&&
(b.nombre.val()&&b.primerapellido.val()?(a=d.clave(b.nombre.val().toUpperCase(),b.primerapellido.val().toUpperCase(),b.segundoapellido.val().toUpperCase(),b.dia?b.dia.val():d.extract2("day",e),b.mes?b.mes.val():d.extract2("month",e),b.ano?b.ano.val():d.extract2("year",e)),h=d.homonimia(b.primerapellido.val().toUpperCase()+" "+b.segundoapellido.val().toUpperCase()+" "+b.nombre.val().toUpperCase()),g=d.digitoVerificador(a.substring(0,12)),e+h+g===a?(n(this).attr("value",a),b.success&&b.success.call(this,
a)):(m=a,b.error&&b.error.call(this,"Error:\n"+("La parte inicial de la clave ("+e+") no coincide con la informaci\u00f3n que se obtiened del nombre del contribuyente."),m))):b.error&&b.error.call(this,"Error:\nEs necesario, para completar autom\u00e1ticamente la clave del R.F.C. que introduzca primero el nombre y el (los) apellido(s) del contribuyente.",null)):k.test(e)?(a=d.clave(b.nombre.val().toUpperCase(),b.primerapellido.val().toUpperCase(),b.segundoapellido.val().toUpperCase(),b.dia?b.dia.val():
d.extract("day",e),b.mes?b.mes.val():d.extract("month",e),b.ano?b.ano.val():d.extract("year",e)),h=d.homonimia(b.primerapellido.val().toUpperCase()+" "+b.segundoapellido.val().toUpperCase()+" "+b.nombre.val().toUpperCase()),g=d.digitoVerificador(a.substring(0,12)),h!=d.extract("homonimia",e)&&(f="Clave diferenciadora de homonimia suministrada ("+d.extract("homonimia",e)+") no coincide con la que se obtiene de los nombres suministrados ("+h+"). La raz\u00f3n de esta discrepancia se puede deber a una incorrecta captura del nombre o apellidos del contribuyente."),
g!=d.extract("digito_verificador",e)&&(f=f+"\nDigito verificador suministrador ("+d.extract("digito_verificador",e)+") no coincide con el que se obtiene de la clave del R.F.C. ("+g+"). Posiblemente la clave del R.F.C. se esta capturando incorrectamente."),e!=a&&(f=f+"\nLa clave del R.F.C. suministrada ("+e+") no coincide con la c\u00e1lculada ("+a+")",m=a),/^([A-Z&\u00D1]{4})([0-9]{2})((0[1-9])|(1[012]))((0[1-9])|([12][0-9])|(3[01]))([1-9A-NP-Z]{2})[0-9A]$/i.test(e)||(f+="\nClave del R.F.C. no bien formada."),
f?b.error&&b.error.call(this,"Error:\n"+f,m):b.success&&b.success.call(this,e)):l.test(e)&&(g=d.digitoVerificador(e.substring(0,11)),d.extract("digito_verificador",e),g!=d.extract("digito_verificador",e)&&(f="El digito verificador suministrado con la clave del R.F.C. ("+d.extract("digito_verificador",e)+") no coincide con el que se obtiene directamente del c\u00e1lculo de la clave ("+g+")",m=e.substring(0,11)+g),/^([A-Z&\u00D1]{3})([0-9]{2})((0[1-9])|(1[012]))((0[1-9])|([12][0-9])|(3[01]))([1-9A-NP-Z]{2})[0-9A]$/i.test(e)||
(f+="\nClave del R.F.C. no bien formada."),f?b.error&&b.error.call(this,"Error:\n"+f,m):b.success&&b.success.call(this,e))})})},clave:function(a,b,c,h,g,l){var k=null,e=[],f=[],m=[],f=e=void 0,e=d.regla8(d.normalize(a.toUpperCase())),e=d.regla6(e),f=d.regla8(d.normalize(b.toUpperCase()));c&&(m=d.regla8(d.normalize(c.toUpperCase())));2>=f[0].length&&(k=m.length?d.regla4(e[0],f[0],m[0]):d.regla7(e[0],f[0]));0===m.length&&(k=d.regla7(e[0],f[0]));null===k&&(k=d.regla1(e[0],f[0],m[0]));k=d.regla9(k);k+=
d.regla2(h,g,l);e=d.homonimia((b+" "+c+" "+a).toUpperCase());f=d.digitoVerificador(k+e);return k+e+f},extract:function(a,b){var c=null;"year"===a?c=/\d{2}(?=(\d{4}))/:"month"===a?c=/\d{2}(?=(\w{5}$))/:"day"===a?c=/\d{2}(?=(\w{3}$))/:"homonimia"===a?c=/\w{2}(?=(\w(?=$)))/:"digito_verificador"===a&&(c=/\w(?=$)/);return c?c.exec(b)[0]:null},extract2:function(a,b){var c=b.match(/\d{2}/g);return"year"===a?c[0]:"month"===a?c[1]:"day"===a?c[2]:null},homonimia:function(a){for(var b={" ":0,"0":0,1:1,2:2,3:3,
4:4,5:5,6:6,7:7,8:8,9:9,"&":10,A:11,B:12,C:13,D:14,E:15,F:16,G:17,H:18,I:19,J:21,K:22,L:23,M:24,N:25,O:26,P:27,Q:28,R:29,S:32,T:33,U:34,V:35,W:36,X:37,Y:38,Z:39,"\u00d1":40,"\u00c1":11,"\u00c9":15,"\u00cd":19,"\u00d3":26,"\u00da":34},c={"0":"1",1:"2",2:"3",3:"4",4:"5",5:"6",6:"7",7:"8",8:"9",9:"A",10:"B",11:"C",12:"D",13:"E",14:"F",15:"G",16:"H",17:"I",18:"J",19:"K",20:"L",21:"M",22:"N",23:"P",24:"Q",25:"R",26:"S",27:"T",28:"U",29:"V",30:"W",31:"X",32:"Y",33:"Z"},h=0,g=0,l=null,k=0,e=0,f=0,m=null,
m=/\w|\s|&|\u00D1|\u00C1|\u00C9|\u00CD|\u00D3|\u00DA/,p=0;p<a.length;p++)l=a.charAt(p),m.test(l)&&(n.each(b,function(a,b){k=b;return l!=a}),g+=(10*h+d.decena(k))*d.decena(k),h=k%10,g+=k*h);g%=1E3;e=g%34;f=(g-e)/34;n.each(c,function(a,b){l=b;return f!=a});m=l;n.each(c,function(a,b){l=b;return e!=a});return m+l},decena:function(a){return 30<=a?3:20<=a?2:10<=a?1:0},digitoVerificador:function(a){var b={"0":0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,G:16,H:17,I:18,J:19,K:20,L:21,
M:22,N:23,"&":24,O:25,P:26,Q:27,R:28,S:29,T:30,U:31,V:32,W:33,X:34,Y:35,Z:36," ":37,"\u00d1":38},c="",d=0,g=0,l=0,l=13,k=null,k=11===a.length?" "+a:a;for(a=0;a<k.length;a++)c=k.charAt(a),n.each(b,function(a,b){d=b;return c!=a}),g+=d*l,l-=1;l=g%11;return 0==l?"0":1==l?"A":11-l},normalizeClave:function(a){return a.replace(/[ -]/g,"")},regla1:function(a,b,c){var d=b.substring(1).match(/A|E|I|O|U|\u00C1|\u00C9|\u00CD|\u00D3|\u00DA/i)[0].charAt(0);return b.charAt(0)+d+c.charAt(0)+a.charAt(0)},regla2:function(a,
b,c){1===a.length&&(a="0"+a);1===b.length&&(b="0"+b);1===c.length?c="0"+c:4===c.length&&(c=c.substr(2));return c+b+a},regla3:function(a){var b=void 0;return b=a.match(/^CH|^LL/i)?a.charAt(0)+a.substring(2):a},regla4:function(a,b,c){return b.charAt(0)+c.charAt(0)+a.charAt(0)+a.charAt(1)},regla5:function(a,b,c){},regla6:function(a){for(var b=[],c=0;c<a.length;c++)"MARIA"===a[c]||("MAR\u00cdA"===a[c]||"JOSE"===a[c]||"JOS\u00c9"===a[c])||b.push(a[c]);return b},regla7:function(a,b){return b.charAt(0)+
b.charAt(1)+a.charAt(0)+a.charAt(1)},regla8:function(a){var b=[];a=a.split(" ");for(var c=0;c<a.length;c++)a[c].length&&!("DE"===a[c]||"DEL"===a[c]||"LA"===a[c]||"LAS"===a[c]||"LOS"===a[c]||"MC"===a[c]||"MAC"===a[c]||"MI"===a[c]||"VAN"===a[c]||"VON"===a[c]||"Y"===a[c])&&b.push(a[c]);return b},regla9:function(a){var b=void 0;return b="BUEI"===a||"BUEY"===a||"CACA"===a||"CACO"===a||"CAGA"===a||"CAGO"===a||"CAKA"===a||"COGE"===a||"COJA"===a||"COJE"===a||"COJI"===a||"COJO"===a||"CULO"===a||"FETO"===a||
"GUEY"===a||"JOTO"===a||"KACA"===a||"KACO"===a||"KAGA"===a||"KAGO"===a||"KOGE"===a||"KOJO"===a||"KAKA"===a||"KULO"===a||"MAME"===a||"MAMO"===a||"MEAR"===a||"MEON"===a||"MION"===a||"MOCO"===a||"MULA"===a||"PEDA"===a||"PEDO"===a||"PENE"===a||"PUTA"===a||"PUTO"===a||"QULO"===a||"RATA"===a||"RUIN"===a?a.charAt(0)+a.charAt(1)+a.charAt(2)+"X":a},normalize:function(a){for(var b="",c=null,h=0;h<a.length;h++){if("\u00c1"===a.charAt(h))c="A";else if("\u00c9"===a.charAt(h))c="E";else if("\u00cd"===a.charAt(h))c=
"I";else if("\u00d3"===a.charAt(h))c="O";else if("\u00da"===a.charAt(h))c="U";else if("."===a.charAt(h))continue;else if("'"===a.charAt(h))continue;else c=a.charAt(h);b+=c}return d.regla3(b)}};n.fn.rfc_tester=function(a){if(d[a])return d[a].apply(this,Array.prototype.slice.call(arguments,1));if("object"===typeof a||!a)return d.init.apply(this,arguments);n.error("El m\u00e9todo "+a+" no existe en la presente implementaci\u00f3n.")}})(jQuery);
<|endoftext|>


<commit_before>const { isFunction, isString, omit } = require('lodash');

const Attachment = require('./attachment');
const Errors = require('./errors');
const SchemaVersion = require('./schema_version');

const GROUP = 'group';
const PRIVATE = 'private';

// Schema version history
//
// Version 0
//   - Schema initialized
// Version 1
//   - Attachments: Auto-orient JPEG attachments using EXIF `Orientation` data.
// Version 2
//   - Attachments: Sanitize Unicode order override characters.
// Version 3
//   - Attachments: Write attachment data to disk and store relative path to it.

const INITIAL_SCHEMA_VERSION = 0;

// Increment this version number every time we add a message schema upgrade
// step. This will allow us to retroactively upgrade existing messages. As we
// add more upgrade steps, we could design a pipeline that does this
// incrementally, e.g. from version 0 / unknown -> 1, 1 --> 2, etc., similar to
// how we do database migrations:
exports.CURRENT_SCHEMA_VERSION = 3;

// Public API
exports.GROUP = GROUP;
exports.PRIVATE = PRIVATE;

// Placeholder until we have stronger preconditions:
exports.isValid = () =>
  true;

// Schema
exports.initializeSchemaVersion = (message) => {
  const isInitialized = SchemaVersion.isValid(message.schemaVersion) &&
    message.schemaVersion >= 1;
  if (isInitialized) {
    return message;
  }

  const numAttachments = Array.isArray(message.attachments)
    ? message.attachments.length
    : 0;
  const hasAttachments = numAttachments > 0;
  if (!hasAttachments) {
    return Object.assign(
      {},
      message,
      { schemaVersion: INITIAL_SCHEMA_VERSION }
    );
  }

  // All attachments should have the same schema version, so we just pick
  // the first one:
  const firstAttachment = message.attachments[0];
  const inheritedSchemaVersion = SchemaVersion.isValid(firstAttachment.schemaVersion)
    ? firstAttachment.schemaVersion
    : INITIAL_SCHEMA_VERSION;
  const messageWithInitialSchema = Object.assign(
    {},
    message,
    {
      schemaVersion: inheritedSchemaVersion,
      attachments: message.attachments.map(Attachment.removeSchemaVersion),
    }
  );

  return messageWithInitialSchema;
};

// Middleware
// type UpgradeStep = (Message, Context) -> Promise Message

// SchemaVersion -> UpgradeStep -> UpgradeStep
exports._withSchemaVersion = (schemaVersion, upgrade) => {
  if (!SchemaVersion.isValid(schemaVersion)) {
    throw new TypeError('"schemaVersion" is invalid');
  }
  if (!isFunction(upgrade)) {
    throw new TypeError('"upgrade" must be a function');
  }

  return async (message, context) => {
    if (!exports.isValid(message)) {
      console.log('Message._withSchemaVersion: Invalid input message:', message);
      return message;
    }

    const isAlreadyUpgraded = message.schemaVersion >= schemaVersion;
    if (isAlreadyUpgraded) {
      return message;
    }

    const expectedVersion = schemaVersion - 1;
    const hasExpectedVersion = message.schemaVersion === expectedVersion;
    if (!hasExpectedVersion) {
      console.log(
        'WARNING: Message._withSchemaVersion: Unexpected version:',
        `Expected message to have version ${expectedVersion},`,
        `but got ${message.schemaVersion}.`,
        message
      );
      return message;
    }

    let upgradedMessage;
    try {
      upgradedMessage = await upgrade(message, context);
    } catch (error) {
      console.log(
        'Message._withSchemaVersion: error:',
        Errors.toLogFormat(error)
      );
      return message;
    }

    if (!exports.isValid(upgradedMessage)) {
      console.log(
        'Message._withSchemaVersion: Invalid upgraded message:',
        upgradedMessage
      );
      return message;
    }

    return Object.assign(
      {},
      upgradedMessage,
      { schemaVersion }
    );
  };
};

// Public API
//      _mapAttachments :: (Attachment -> Promise Attachment) ->
//                         (Message, Context) ->
//                         Promise Message
exports._mapAttachments = upgradeAttachment => async (message, context) => {
  const upgradeWithContext = attachment =>
    upgradeAttachment(attachment, context);
  const attachments = await Promise.all(message.attachments.map(upgradeWithContext));
  return Object.assign({}, message, { attachments });
};

const toVersion0 = async message =>
  exports.initializeSchemaVersion(message);

const toVersion1 = exports._withSchemaVersion(
  1,
  exports._mapAttachments(Attachment.autoOrientJPEG)
);
const toVersion2 = exports._withSchemaVersion(
  2,
  exports._mapAttachments(Attachment.replaceUnicodeOrderOverrides)
);
const toVersion3 = exports._withSchemaVersion(
  3,
  exports._mapAttachments(Attachment.migrateDataToFileSystem)
);

// UpgradeStep
exports.upgradeSchema = async (message, { writeNewAttachmentData } = {}) => {
  if (!isFunction(writeNewAttachmentData)) {
    throw new TypeError('`context.writeNewAttachmentData` is required');
  }

  return toVersion3(
    await toVersion2(await toVersion1(await toVersion0(message))),
    { writeNewAttachmentData }
  );
};

exports.createAttachmentLoader = (loadAttachmentData) => {
  if (!isFunction(loadAttachmentData)) {
    throw new TypeError('`loadAttachmentData` is required');
  }

  return async message => (Object.assign({}, message, {
    attachments: await Promise.all(message.attachments.map(loadAttachmentData)),
  }));
};

//      createAttachmentDataWriter :: (RelativePath -> IO Unit)
//                                    Message ->
//                                    IO (Promise Message)
exports.createAttachmentDataWriter = (writeExistingAttachmentData) => {
  if (!isFunction(writeExistingAttachmentData)) {
    throw new TypeError('"writeExistingAttachmentData" must be a function');
  }

  return async (rawMessage) => {
    if (!exports.isValid(rawMessage)) {
      throw new TypeError('"rawMessage" is not valid');
    }

    const message = exports.initializeSchemaVersion(rawMessage);

    const { attachments } = message;
    const hasAttachments = attachments && attachments.length > 0;
    if (!hasAttachments) {
      return message;
    }

    const lastVersionWithAttachmentDataInMemory = 2;
    const willHaveAttachmentsSavedOnFileSystemDuringUpgrade =
      message.schemaVersion <= lastVersionWithAttachmentDataInMemory;
    if (willHaveAttachmentsSavedOnFileSystemDuringUpgrade) {
      return message;
    }

    attachments.forEach((attachment) => {
      if (!Attachment.hasData(attachment)) {
        throw new TypeError('"attachment.data" is required during message import');
      }

      if (!isString(attachment.path)) {
        throw new TypeError('"attachment.path" is required during message import');
      }
    });

    const messageWithoutAttachmentData = Object.assign({}, message, {
      attachments: await Promise.all(attachments.map(async (attachment) => {
        await writeExistingAttachmentData(attachment);
        return omit(attachment, ['data']);
      })),
    });

    return messageWithoutAttachmentData;
  };
};
<commit_msg>Rename `willHaveAttachmentsSavedOnFileSystemDuringUpgrade`<commit_after>const { isFunction, isString, omit } = require('lodash');

const Attachment = require('./attachment');
const Errors = require('./errors');
const SchemaVersion = require('./schema_version');

const GROUP = 'group';
const PRIVATE = 'private';

// Schema version history
//
// Version 0
//   - Schema initialized
// Version 1
//   - Attachments: Auto-orient JPEG attachments using EXIF `Orientation` data.
// Version 2
//   - Attachments: Sanitize Unicode order override characters.
// Version 3
//   - Attachments: Write attachment data to disk and store relative path to it.

const INITIAL_SCHEMA_VERSION = 0;

// Increment this version number every time we add a message schema upgrade
// step. This will allow us to retroactively upgrade existing messages. As we
// add more upgrade steps, we could design a pipeline that does this
// incrementally, e.g. from version 0 / unknown -> 1, 1 --> 2, etc., similar to
// how we do database migrations:
exports.CURRENT_SCHEMA_VERSION = 3;

// Public API
exports.GROUP = GROUP;
exports.PRIVATE = PRIVATE;

// Placeholder until we have stronger preconditions:
exports.isValid = () =>
  true;

// Schema
exports.initializeSchemaVersion = (message) => {
  const isInitialized = SchemaVersion.isValid(message.schemaVersion) &&
    message.schemaVersion >= 1;
  if (isInitialized) {
    return message;
  }

  const numAttachments = Array.isArray(message.attachments)
    ? message.attachments.length
    : 0;
  const hasAttachments = numAttachments > 0;
  if (!hasAttachments) {
    return Object.assign(
      {},
      message,
      { schemaVersion: INITIAL_SCHEMA_VERSION }
    );
  }

  // All attachments should have the same schema version, so we just pick
  // the first one:
  const firstAttachment = message.attachments[0];
  const inheritedSchemaVersion = SchemaVersion.isValid(firstAttachment.schemaVersion)
    ? firstAttachment.schemaVersion
    : INITIAL_SCHEMA_VERSION;
  const messageWithInitialSchema = Object.assign(
    {},
    message,
    {
      schemaVersion: inheritedSchemaVersion,
      attachments: message.attachments.map(Attachment.removeSchemaVersion),
    }
  );

  return messageWithInitialSchema;
};

// Middleware
// type UpgradeStep = (Message, Context) -> Promise Message

// SchemaVersion -> UpgradeStep -> UpgradeStep
exports._withSchemaVersion = (schemaVersion, upgrade) => {
  if (!SchemaVersion.isValid(schemaVersion)) {
    throw new TypeError('"schemaVersion" is invalid');
  }
  if (!isFunction(upgrade)) {
    throw new TypeError('"upgrade" must be a function');
  }

  return async (message, context) => {
    if (!exports.isValid(message)) {
      console.log('Message._withSchemaVersion: Invalid input message:', message);
      return message;
    }

    const isAlreadyUpgraded = message.schemaVersion >= schemaVersion;
    if (isAlreadyUpgraded) {
      return message;
    }

    const expectedVersion = schemaVersion - 1;
    const hasExpectedVersion = message.schemaVersion === expectedVersion;
    if (!hasExpectedVersion) {
      console.log(
        'WARNING: Message._withSchemaVersion: Unexpected version:',
        `Expected message to have version ${expectedVersion},`,
        `but got ${message.schemaVersion}.`,
        message
      );
      return message;
    }

    let upgradedMessage;
    try {
      upgradedMessage = await upgrade(message, context);
    } catch (error) {
      console.log(
        'Message._withSchemaVersion: error:',
        Errors.toLogFormat(error)
      );
      return message;
    }

    if (!exports.isValid(upgradedMessage)) {
      console.log(
        'Message._withSchemaVersion: Invalid upgraded message:',
        upgradedMessage
      );
      return message;
    }

    return Object.assign(
      {},
      upgradedMessage,
      { schemaVersion }
    );
  };
};

// Public API
//      _mapAttachments :: (Attachment -> Promise Attachment) ->
//                         (Message, Context) ->
//                         Promise Message
exports._mapAttachments = upgradeAttachment => async (message, context) => {
  const upgradeWithContext = attachment =>
    upgradeAttachment(attachment, context);
  const attachments = await Promise.all(message.attachments.map(upgradeWithContext));
  return Object.assign({}, message, { attachments });
};

const toVersion0 = async message =>
  exports.initializeSchemaVersion(message);

const toVersion1 = exports._withSchemaVersion(
  1,
  exports._mapAttachments(Attachment.autoOrientJPEG)
);
const toVersion2 = exports._withSchemaVersion(
  2,
  exports._mapAttachments(Attachment.replaceUnicodeOrderOverrides)
);
const toVersion3 = exports._withSchemaVersion(
  3,
  exports._mapAttachments(Attachment.migrateDataToFileSystem)
);

// UpgradeStep
exports.upgradeSchema = async (message, { writeNewAttachmentData } = {}) => {
  if (!isFunction(writeNewAttachmentData)) {
    throw new TypeError('`context.writeNewAttachmentData` is required');
  }

  return toVersion3(
    await toVersion2(await toVersion1(await toVersion0(message))),
    { writeNewAttachmentData }
  );
};

exports.createAttachmentLoader = (loadAttachmentData) => {
  if (!isFunction(loadAttachmentData)) {
    throw new TypeError('`loadAttachmentData` is required');
  }

  return async message => (Object.assign({}, message, {
    attachments: await Promise.all(message.attachments.map(loadAttachmentData)),
  }));
};

//      createAttachmentDataWriter :: (RelativePath -> IO Unit)
//                                    Message ->
//                                    IO (Promise Message)
exports.createAttachmentDataWriter = (writeExistingAttachmentData) => {
  if (!isFunction(writeExistingAttachmentData)) {
    throw new TypeError('"writeExistingAttachmentData" must be a function');
  }

  return async (rawMessage) => {
    if (!exports.isValid(rawMessage)) {
      throw new TypeError('"rawMessage" is not valid');
    }

    const message = exports.initializeSchemaVersion(rawMessage);

    const { attachments } = message;
    const hasAttachments = attachments && attachments.length > 0;
    if (!hasAttachments) {
      return message;
    }

    const lastVersionWithAttachmentDataInMemory = 2;
    const willAttachmentsGoToFileSystemOnUpgrade =
      message.schemaVersion <= lastVersionWithAttachmentDataInMemory;
    if (willAttachmentsGoToFileSystemOnUpgrade) {
      return message;
    }

    attachments.forEach((attachment) => {
      if (!Attachment.hasData(attachment)) {
        throw new TypeError('"attachment.data" is required during message import');
      }

      if (!isString(attachment.path)) {
        throw new TypeError('"attachment.path" is required during message import');
      }
    });

    const messageWithoutAttachmentData = Object.assign({}, message, {
      attachments: await Promise.all(attachments.map(async (attachment) => {
        await writeExistingAttachmentData(attachment);
        return omit(attachment, ['data']);
      })),
    });

    return messageWithoutAttachmentData;
  };
};
<|endoftext|>


<commit_before>M.User = M.Class.extend({

	initialize : function (store) {

		// set vars
		this.store = store;

		// init file objects
		this.initFiles();

		this._listen();
	},

	_listen : function () {
		// M.Mixin.Events.on('closeMenuTabs',   this._onCloseMenuTabs, this);
	},

	initFiles : function () {

		// get files
		var files = this.store.files;
		this._files = {};
		if (!files) return;

		// create
		files.forEach(function (file) {
			this._files[file.uuid] = new M.Model.File(file);
		}, this);
	},

	isPublic : function () {
		return this.store.uuid == 'mapic-public';
	},

	isContact : function () {
		if (!app.Account) return console.error('too early!');
		if (this.getUuid() == app.Account.getUuid()) return;

		var isContact = _.includes(app.Account.getContactListUuids(), this.getUuid());

		return isContact;
	},

	getContactListUuids : function () {
		var uuids = [];
		this.getContactList().forEach(function (c) {
			uuids.push(c.uuid);
		});
		return uuids;
	},

	getContactList : function ()  {
		return this.store.contact_list;
	},

	sendContactRequest : function (user) {

		var options = {
			contact : user.getUuid()
		};

		app.api.requestContact(options, function (err, response) {
			if (err) {
				return app.feedback.setError({
					title : 'Something went wrong',
					description : err
				});
			}
			// set feedback
			app.feedback.setMessage({
				title : 'Friend request sent'
				// description : description
			});
		});

	},

	inviteToProjects : function (options) {

		var userUuid = this.getUuid();
		var userName = this.getFullName();
		var num = options.edit.length + options.read.length;

		var invites = {
			edit : options.edit,
			read : options.read,
			user : userUuid
		};

		// send to server
		app.api.inviteToProjects(invites, function (err, response) {
			if (err) {
				return app.feedback.setError({
					title : 'Something went wrong',
					description : err
				});
			}
			var result = M.parse(response);

			// set feedback
			app.feedback.setMessage({
				title : 'Project invites sent!',
				description : userName + ' has been invited to ' + num + ' projects'
			});

			// update locally
			result.projects.forEach(function (projectAccess) {
				var project = app.Projects[projectAccess.project];
				project.store.access = projectAccess.access;
			});

		}.bind(this));

	},

	getFiles : function () {
		return this._files;
	},

	getFileStore : function (fileUuid) {
		var file = _.find(this.store.files, function (f) {
			return f.uuid == fileUuid;
		});
		return file;
	},

	getFile : function (fileUuid) {
		return this._files[fileUuid]; // return object
	},

	getUsername : function () {
		return this.store.username;
	},

	setFile : function (file) {
		this.store.files.push(file);
		this._files[file.uuid] = new M.Model.File(file);
		return this._files[file.uuid];
	},

	removeFile : function (fileUuid) {
		// var fileUuid = file.file_id;
		var r = _.remove(this.store.files, function (f) {
			return f.uuid ==fileUuid;
		});

		this._files[fileUuid] = null;
		delete this._files[fileUuid];

	},

	// set functions
	setLastName : function (value) {
		this.store.lastName = value;
		this.save('lastName');
	},

	setFirstName : function (value) {
		this.store.firstName = value;
		this.save('firstName');
	},

	setCompany : function (value) {
		this.store.company = value;
		this.save('company');
	},

	setPosition : function (value) {
		this.store.position = value;
		this.save('position');
	},

	setPhone : function (value) {
		this.store.phone = value;
		this.save('phone');
	},

	setMobile : function (value) {
		this.store.mobile = value;
		this.save('mobile');
	},

	setEmail : function (value) {
		this.store.local.email = value;
		this.save('local.email');
	},

	setKey : function (key, value) {
		if (key == 'lastName' ) return this.setLastName(value);
		if (key == 'firstName') return this.setFirstName(value);
		if (key == 'company'  ) return this.setCompany(value);
		if (key == 'position' ) return this.setPosition(value);
		if (key == 'mobile'   ) return this.setMobile(value);
		if (key == 'phone'    ) return this.setPhone(value);
		if (key == 'email'    ) return this.setEmail(value);
	},

	// save
	save : function (key) {

		// set fields
		var json = {};
		json[field] = this.store[field];
		json.uuid = this.store.uuid;

		// save to server
		this._save(json);

		// // clear timer
		// if (this._saveTimer) clearTimeout(this._saveTimer);

		// // save changes on timeout
		// var that = this;
		// this._saveTimer = setTimeout(function () {

		// 	// find changes
		// 	var changes = that._findChanges();

		// 	// return if no changes
		// 	if (!changes) return;

		// 	that._save(changes);

		// }, 1000);       // don't save more than every goddamed second

	},

	_save : function (changes) {
		if (app.activeProject) changes.project = app.activeProject.getUuid(); // for edit_user access, may need project...
		app.api.updateUser(changes, function (err, result) {
			if (err) console.error('err', err);

			result = M.parse(result);

			if (result.error) {
				console.error('something went worng', result);
			} else {
				M.Mixin.Events.fire('userUpdated', { detail : {
					userId : changes.uuid
				}});
			}
		}.bind(this));
	},

	attachToApp : function () {
		app.Users[this.getUuid()] = this;
	},

	deleteUser : function (context, callback) {

		// delete in local store
		delete app.Users[this.store.uuid];

		// delete on server
		var uuid = this.store.uuid;
		var json = JSON.stringify({
			uuid : uuid
		});

		// post              path          data           callback        context of cb
		app.api.deleteUser(json, context[callback]);

	},

	// get functions
	getKey : function (key) {
		return this.store[key];
	},

	getFirstName : function () {
		return this.store.firstName;
	},

	getLastName : function () {
		return this.store.lastName;
	},

	getFullName : function () {
		return this.store.firstName + ' ' + this.store.lastName;
	},

	getName : function () {
		return this.getFullName();
	},

	getCompany : function () {
		return this.store.company;
	},

	getPosition : function () {
		return this.store.position;
	},

	getPhone : function () {
		return this.store.phone;
	},

	getMobile : function () {
		return this.store.mobile;
	},

	getEmail : function () {
		return this.store.local.email;
	},

	getToken : function () {
		return this.store.token;
	},

	getUuid : function () {
		return this.store.uuid;
	},

	// find changes to user.store for saving to server. works for two levels deep // todo: refactor, move to class?
	// hacky for realz! no good!!
	_findChanges : function () {
		var clone   = _.cloneDeep(this.store);
		var last    = _.cloneDeep(this.lastSaved);
		var changes = [];
		for (c in clone) {
			if (_.isObject(clone[c])) {
				var a = clone[c];
				for (b in a) {
					var d = a[b];
					equal = _.isEqual(clone[c][b], last[c][b]);
					if (!equal) {
						var change = {};
						change[c] = {};
						change[c][b] = clone[c][b];
						changes.push(change);
					}
				}
			} else {
				var equal = _.isEqual(clone[c], last[c]);
				if (!equal) {
					var change = {};
					change[c] = clone[c];
					changes.push(change);
				}
			}
		}
		if (changes.length == 0) return false; // return false if no changes
		var json = {};
		changes.forEach(function (change) {
			for (c in change) { json[c] = change[c]; }
		}, this);
		json.uuid = this.getUuid();
		this.lastSaved = _.cloneDeep(this.store);  // update lastSaved
		return json;
	},

	logout : function () {

		// confirm
		if (!confirm('Are you sure you want to log out?')) return;

		this._logout();
	},

	_logout : function () {

		// slack monitor
		// app.Socket.sendUserEvent({
		//     	user : app.Account.getFullName(),
		//     	event : 'logged out.',
		//     	description : '',
		//     	timestamp : Date.now()
		// });

		app.log('logout', {
			category : 'Users'
		});

		// redirect to logout
		window.location.href = app.options.servers.portal + 'logout';
	},

	isSuper : function () {
		return this.store.access.super;
		// return this.store.access.account_type == 'super';
	}

});<commit_msg>fix public@mapic.io dupes<commit_after>M.User = M.Class.extend({

	initialize : function (store) {

		// set vars
		this.store = store;

		// init file objects
		this.initFiles();

		this._listen();
	},

	_listen : function () {
		// M.Mixin.Events.on('closeMenuTabs',   this._onCloseMenuTabs, this);
	},

	initFiles : function () {

		// get files
		var files = this.store.files;
		this._files = {};
		if (!files) return;

		// create
		files.forEach(function (file) {
			this._files[file.uuid] = new M.Model.File(file);
		}, this);
	},

	isPublic : function () {
		return this.store.local.email = 'public@mapic.io';
		// return this.store.uuid == 'mapic-public';
	},

	isContact : function () {
		if (!app.Account) return console.error('too early!');
		if (this.getUuid() == app.Account.getUuid()) return;

		var isContact = _.includes(app.Account.getContactListUuids(), this.getUuid());

		return isContact;
	},

	getContactListUuids : function () {
		var uuids = [];
		this.getContactList().forEach(function (c) {
			uuids.push(c.uuid);
		});
		return uuids;
	},

	getContactList : function ()  {
		return this.store.contact_list;
	},

	sendContactRequest : function (user) {

		var options = {
			contact : user.getUuid()
		};

		app.api.requestContact(options, function (err, response) {
			if (err) {
				return app.feedback.setError({
					title : 'Something went wrong',
					description : err
				});
			}
			// set feedback
			app.feedback.setMessage({
				title : 'Friend request sent'
				// description : description
			});
		});

	},

	inviteToProjects : function (options) {

		var userUuid = this.getUuid();
		var userName = this.getFullName();
		var num = options.edit.length + options.read.length;

		var invites = {
			edit : options.edit,
			read : options.read,
			user : userUuid
		};

		// send to server
		app.api.inviteToProjects(invites, function (err, response) {
			if (err) {
				return app.feedback.setError({
					title : 'Something went wrong',
					description : err
				});
			}
			var result = M.parse(response);

			// set feedback
			app.feedback.setMessage({
				title : 'Project invites sent!',
				description : userName + ' has been invited to ' + num + ' projects'
			});

			// update locally
			result.projects.forEach(function (projectAccess) {
				var project = app.Projects[projectAccess.project];
				project.store.access = projectAccess.access;
			});

		}.bind(this));

	},

	getFiles : function () {
		return this._files;
	},

	getFileStore : function (fileUuid) {
		var file = _.find(this.store.files, function (f) {
			return f.uuid == fileUuid;
		});
		return file;
	},

	getFile : function (fileUuid) {
		return this._files[fileUuid]; // return object
	},

	getUsername : function () {
		return this.store.username;
	},

	setFile : function (file) {
		this.store.files.push(file);
		this._files[file.uuid] = new M.Model.File(file);
		return this._files[file.uuid];
	},

	removeFile : function (fileUuid) {
		// var fileUuid = file.file_id;
		var r = _.remove(this.store.files, function (f) {
			return f.uuid ==fileUuid;
		});

		this._files[fileUuid] = null;
		delete this._files[fileUuid];

	},

	// set functions
	setLastName : function (value) {
		this.store.lastName = value;
		this.save('lastName');
	},

	setFirstName : function (value) {
		this.store.firstName = value;
		this.save('firstName');
	},

	setCompany : function (value) {
		this.store.company = value;
		this.save('company');
	},

	setPosition : function (value) {
		this.store.position = value;
		this.save('position');
	},

	setPhone : function (value) {
		this.store.phone = value;
		this.save('phone');
	},

	setMobile : function (value) {
		this.store.mobile = value;
		this.save('mobile');
	},

	setEmail : function (value) {
		this.store.local.email = value;
		this.save('local.email');
	},

	setKey : function (key, value) {
		if (key == 'lastName' ) return this.setLastName(value);
		if (key == 'firstName') return this.setFirstName(value);
		if (key == 'company'  ) return this.setCompany(value);
		if (key == 'position' ) return this.setPosition(value);
		if (key == 'mobile'   ) return this.setMobile(value);
		if (key == 'phone'    ) return this.setPhone(value);
		if (key == 'email'    ) return this.setEmail(value);
	},

	// save
	save : function (key) {

		// set fields
		var json = {};
		json[field] = this.store[field];
		json.uuid = this.store.uuid;

		// save to server
		this._save(json);

		// // clear timer
		// if (this._saveTimer) clearTimeout(this._saveTimer);

		// // save changes on timeout
		// var that = this;
		// this._saveTimer = setTimeout(function () {

		// 	// find changes
		// 	var changes = that._findChanges();

		// 	// return if no changes
		// 	if (!changes) return;

		// 	that._save(changes);

		// }, 1000);       // don't save more than every goddamed second

	},

	_save : function (changes) {
		if (app.activeProject) changes.project = app.activeProject.getUuid(); // for edit_user access, may need project...
		app.api.updateUser(changes, function (err, result) {
			if (err) console.error('err', err);

			result = M.parse(result);

			if (result.error) {
				console.error('something went worng', result);
			} else {
				M.Mixin.Events.fire('userUpdated', { detail : {
					userId : changes.uuid
				}});
			}
		}.bind(this));
	},

	attachToApp : function () {
		app.Users[this.getUuid()] = this;
	},

	deleteUser : function (context, callback) {

		// delete in local store
		delete app.Users[this.store.uuid];

		// delete on server
		var uuid = this.store.uuid;
		var json = JSON.stringify({
			uuid : uuid
		});

		// post              path          data           callback        context of cb
		app.api.deleteUser(json, context[callback]);

	},

	// get functions
	getKey : function (key) {
		return this.store[key];
	},

	getFirstName : function () {
		return this.store.firstName;
	},

	getLastName : function () {
		return this.store.lastName;
	},

	getFullName : function () {
		return this.store.firstName + ' ' + this.store.lastName;
	},

	getName : function () {
		return this.getFullName();
	},

	getCompany : function () {
		return this.store.company;
	},

	getPosition : function () {
		return this.store.position;
	},

	getPhone : function () {
		return this.store.phone;
	},

	getMobile : function () {
		return this.store.mobile;
	},

	getEmail : function () {
		return this.store.local.email;
	},

	getToken : function () {
		return this.store.token;
	},

	getUuid : function () {
		return this.store.uuid;
	},

	// find changes to user.store for saving to server. works for two levels deep // todo: refactor, move to class?
	// hacky for realz! no good!!
	_findChanges : function () {
		var clone   = _.cloneDeep(this.store);
		var last    = _.cloneDeep(this.lastSaved);
		var changes = [];
		for (c in clone) {
			if (_.isObject(clone[c])) {
				var a = clone[c];
				for (b in a) {
					var d = a[b];
					equal = _.isEqual(clone[c][b], last[c][b]);
					if (!equal) {
						var change = {};
						change[c] = {};
						change[c][b] = clone[c][b];
						changes.push(change);
					}
				}
			} else {
				var equal = _.isEqual(clone[c], last[c]);
				if (!equal) {
					var change = {};
					change[c] = clone[c];
					changes.push(change);
				}
			}
		}
		if (changes.length == 0) return false; // return false if no changes
		var json = {};
		changes.forEach(function (change) {
			for (c in change) { json[c] = change[c]; }
		}, this);
		json.uuid = this.getUuid();
		this.lastSaved = _.cloneDeep(this.store);  // update lastSaved
		return json;
	},

	logout : function () {

		// confirm
		if (!confirm('Are you sure you want to log out?')) return;

		this._logout();
	},

	_logout : function () {

		// slack monitor
		// app.Socket.sendUserEvent({
		//     	user : app.Account.getFullName(),
		//     	event : 'logged out.',
		//     	description : '',
		//     	timestamp : Date.now()
		// });

		app.log('logout', {
			category : 'Users'
		});

		// redirect to logout
		window.location.href = app.options.servers.portal + 'logout';
	},

	isSuper : function () {
		return this.store.access.super;
		// return this.store.access.account_type == 'super';
	}

});<|endoftext|>


<commit_before>define(function(require) {
	var registerSuite = require('intern!object'),
		assert = require('intern/chai!assert');

	require('js/tests/support/exports.js');

	registerSuite({
		name: 'Routes',

		uri: {
			get: function() {
				assert.isObject(Wee.routes.uri(),
					'URI was not retrieved successfully'
				);

				assert.isFalse(Wee.routes.uri().history,
					'URI was not retrieved successfully'
				);
			},

			'set string': function() {
				Wee.routes.uri('/test/page');

				assert.strictEqual(Wee.routes.uri().path, '/test/page',
					'URI string was not set successfully'
				);
			},

			'set object': function() {
				Wee.routes.uri({
				    hash: 'uri',
				    path: '/js/routes',
				    history: true,
				    query: {
				        success: 'yes'
				    }
				});

				assert.strictEqual(Wee.routes.uri().hash, 'uri',
					'URI object was not set successfully'
				);

				assert.strictEqual(Wee.routes.uri().path, '/js/routes',
					'URI object was not set successfully'
				);

				assert.isTrue(Wee.routes.uri().history,
					'URI object was not set successfully'
				);

				assert.isObject(Wee.routes.uri().query,
					'URI object was not set successfully'
				);

				assert.isObject(Wee.routes.uri(),
					'URI object was not set successfully'
				);
			}
		},

		segments: {
			'get all': function() {
				assert.include(Wee.routes.segments(), 'test',
					'No segments were returned successfully'
				);
				assert.include(Wee.routes.segments(), 'page',
					'No segments were returned successfully'
				);
				assert.isArray(Wee.routes.segments(),
					'Segments did not return an array'
				);
			},

			'get single': function() {
				assert.strictEqual(Wee.routes.segments(0), 'test',
					'Single segment not retrieved successfully'
				);
				assert.strictEqual(Wee.routes.segments(1), 'page',
					'Single segment not retrieved successfully'
				);
				assert.strictEqual(Wee.routes.segments(2), '',
					'Single segment not retrieved successfully'
				);
			}
		},

		map: {
			set: function() {
				Wee.routes.map({
				    '$any': 'common',
				    'script': {
				        'routes': function() {

				        }
				    }
				});

				assert.isObject(Wee.routes.map());
			}
		},

		run: {
			simple: function() {
				// TODO: Complete
				Wee.routes.map({
					'$any': function() {
						return 'any';
					}
				});

				assert.strictEqual(Wee.routes.run(), undefined,
					'Any route executed successfully.'
				);
			},

			advanced: function() {
				// TODO: Complete
				Wee.routes.run({
					path: '/test/route',
					routes: {
						test: {
							route: function() {
								assert.ok(true, true,
									'Specific route not executed successfully.'
								);
							}
						}
					}
				});
			}
		}
	});
});<commit_msg>Add additional coverage for routes<commit_after>define(function(require) {
	var registerSuite = require('intern!object'),
		assert = require('intern/chai!assert');

	require('js/tests/support/exports.js');

	registerSuite({
		name: 'Routes',

		afterEach: function() {
			$.set('test', false);
			$.set('test2', false);
		},

		uri: {
			get: function() {
				assert.isObject(Wee.routes.uri(),
					'URI was not retrieved successfully'
				);

				assert.isFalse(Wee.routes.uri().history,
					'URI was not retrieved successfully'
				);
			},

			'set string': function() {
				Wee.routes.uri('/test/page');

				assert.strictEqual(Wee.routes.uri().path, '/test/page',
					'URI string was not set successfully'
				);
			},

			'set object': function() {
				Wee.routes.uri({
				    hash: 'uri',
				    path: '/js/routes',
				    history: true,
				    query: {
				        success: 'yes'
				    }
				});

				assert.strictEqual(Wee.routes.uri().hash, 'uri',
					'URI object was not set successfully'
				);

				assert.strictEqual(Wee.routes.uri().path, '/js/routes',
					'URI object was not set successfully'
				);

				assert.isTrue(Wee.routes.uri().history,
					'URI object was not set successfully'
				);

				assert.isObject(Wee.routes.uri().query,
					'URI object was not set successfully'
				);

				assert.isObject(Wee.routes.uri(),
					'URI object was not set successfully'
				);
			}
		},

		segments: {
			'get all': function() {
				assert.include(Wee.routes.segments(), 'test',
					'No segments were returned successfully'
				);
				assert.include(Wee.routes.segments(), 'page',
					'No segments were returned successfully'
				);
				assert.isArray(Wee.routes.segments(),
					'Segments did not return an array'
				);
			},

			'get single': function() {
				assert.strictEqual(Wee.routes.segments(0), 'test',
					'Single segment not retrieved successfully'
				);
				assert.strictEqual(Wee.routes.segments(1), 'page',
					'Single segment not retrieved successfully'
				);
				assert.strictEqual(Wee.routes.segments(2), '',
					'Single segment not retrieved successfully'
				);
			}
		},

		map: {
			set: function() {
				var routes = Wee.routes.map({
				    '$any': 'common',
				    'script': {
				        'routes': function() {
							return 'test';
				        }
				    }
				});

				assert.isObject(Wee.routes.map());

				assert.strictEqual(routes.script.routes(), 'test',
					'Route function was not executed successfully'
				);
			}
		},

		run: {
			simple: function() {
				Wee.routes.map({
					'$any': function() {
						$.set('test', true);
					},
					'$root': function() {
						$.set('test2', true);
					}
				});

				Wee.routes.run({
					path: '/'
				});

				assert.isTrue($.get('test'),
					'$any was not evaulated correctly'
				);

				assert.isTrue($.get('test2'),
					'$root was not evaulated correctly'
				);
			},

			advanced: function() {
				Wee.routes.run({
					path: '/test/route',
					routes: {
						test: {
							route: function() {
								assert.ok(true, true,
									'Specific route not executed successfully.'
								);
							}
						}
					}
				});

				Wee.routes.map({
					'$root': function() {
						$.set('test', true);
					}
				}, true);

				assert.isTrue($.get('test'),
					'Routes were not initialized'
				);
			}
		},

		addFilter: function() {
			Wee.routes.addFilter('isInternal', function(seg) {
				return ['admin', 'protected'].indexOf(seg) > -1;
			});

			Wee.fn.make('testController', {
				init: function() {
					$.set('test', true);
				}
			});

			Wee.routes.map({
				'$isInternal:eval': 'testController'
			});

			Wee.routes.run({
				path: '/admin'
			});

			assert.isTrue($.get('test'),
				'Route filter was not executed correctly'
			);
		},

		once: function() {
			var i = 0;

			Wee.routes.map({
				'$any:once': function() {
					i++;
				}
			});

			Wee.routes.run({
				path: '/'
			});

			Wee.routes.run({
				path: '/'
			});

			assert.strictEqual(i, 1,
				'Route was executed twice despite being instructed to execute once'
			);
		},

		controller: function() {
			Wee.fn.make('testController', {
				init: function() {
					$.set('test', true);
				},
				test: function() {
					$.set('test2', true);
				}
			});

			Wee.routes.map({
				'$any': [
					'testController:init',
					'testController:test'
				]
			});

			Wee.routes.run();

			assert.strictEqual($.get('test'), true,
				'Init method was not executed successfully'
			);

			assert.strictEqual($.get('test2'), true,
				'Method was not executed successfully'
			);
		},
	});
});<|endoftext|>


<commit_before>// ==========================================================================
// Project:   SproutCore Statechart - Hierarchical State Machine Library
// Copyright: ©2009 Sprout Systems, Inc. and contributors.
//            Portions ©2009 Apple, Inc. All rights reserved.
// License:   Licened under MIT license (see license.js)
// ==========================================================================

SC.mixin(SC.Object.prototype,
/** SC.Object.prototype */ {

  /**
    Specifies which object property stores the intial state of the
    hierachical state machine.

    @type String
  */
  initialStateKey: 'initial',

  /** @private
    Initializes an object's hierarchical state machine.

    @returns {SC.Object} the initialized object
  */
  initStatechart: function() {
    var initialStateKey = this.get('initialStateKey') ;
    var stateKey = this.get('stateKey') ;
    var path = SC._DISPATCH_PATH ;
    var initial, substate, handlerKey, superstateKey, res, idx, ixd2 ;

    this._sc_state_depth = 0 ; // used by logging code...

    // debugger ;

    initial = this[stateKey] = this[initialStateKey] ;
    if (!initial) return this ; // fast path -- this object does not use HSMs

    // okay, does the initial state have superstates? If so, we need to
    // enter them first...
    superstateKey = this[initial].superstateKey ;
    if (superstateKey !== undefined) {
      idx = 0 ;
      while (superstateKey) {
        path[++idx] = superstateKey ;
        superstateKey = this[superstateKey].superstateKey ;
      }
    }

    do {
      this._sc_statechart_enter(path[idx]) ;
    } while ((--idx) > 0)

    // now enter the initial state
    this._sc_statechart_enter(this[stateKey]) ;

    // debugger;

    // initialize the initial states's substates
    while (this._sc_statechart_init(this[stateKey]) === SC.EVT_TRANSITION_RES) {
      substate = this[stateKey] ;

      // enter the target of the transition (a substate)
      idx = 0 ;

      // walk the state hierarchy until we find our target state, storing
      // state keys along the way
      while (initial !== substate) {
        superstateKey = this[substate].superstateKey ;
        if (superstateKey === undefined) break ;
        else {
          substate = path[++idx]= superstateKey ;
        }
      }

      // don't re-enter the initial state
      --idx ;

      // now enter the target's substates in top-down order...
      do {
        this._sc_statechart_enter(path[idx]) ;
      } while ((--idx) > 0)

      // and finally enter the target itself
      if (idx === 0) this._sc_statechart_enter(this[stateKey]) ;

      // the loop continues to apply any default transitions as substates
      // are entered...
    }

    return this ;
  }

});<commit_msg>update to use StatechartDebugger when present<commit_after>// ==========================================================================
// Project:   SproutCore Statechart - Hierarchical State Machine Library
// Copyright: ©2009 Sprout Systems, Inc. and contributors.
//            Portions ©2009 Apple, Inc. All rights reserved.
// License:   Licened under MIT license (see license.js)
// ==========================================================================

SC.mixin(SC.Object.prototype,
/** SC.Object.prototype */ {

  /**
    Specifies which object property stores the intial state of the
    hierachical state machine.

    @type String
  */
  initialStateKey: 'initial',

  /** @private
    Initializes an object's hierarchical state machine.

    @returns {SC.Object} the initialized object
  */
  initStatechart: function() {
    var initialStateKey = this.get('initialStateKey') ;
    var stateKey = this.get('stateKey') ;
    var path = SC._DISPATCH_PATH ;
    var initial, substate, handlerKey, superstateKey, res, idx, ixd2 ;

    this._sc_state_depth = 0 ; // used by logging code...

    // debugger ;

    initial = this[stateKey] = this[initialStateKey] ;
    if (!initial) return this ; // fast path -- this object does not use HSMs

    // okay, does the initial state have superstates? If so, we need to
    // enter them first...
    superstateKey = this[initial].superstateKey ;
    if (superstateKey !== undefined) {
      idx = 0 ;
      while (superstateKey) {
        path[++idx] = superstateKey ;
        superstateKey = this[superstateKey].superstateKey ;
      }
    }

    do {
      this._sc_statechart_enter(path[idx]) ;
    } while ((--idx) > 0)

    // now enter the initial state
    this._sc_statechart_enter(this[stateKey]) ;

    // debugger;

    // initialize the initial states's substates
    while (this._sc_statechart_init(this[stateKey]) === SC.EVT_TRANSITION_RES) {
      substate = this[stateKey] ;

      // enter the target of the transition (a substate)
      idx = 0 ;

      // walk the state hierarchy until we find our target state, storing
      // state keys along the way
      while (initial !== substate) {
        superstateKey = this[substate].superstateKey ;
        if (superstateKey === undefined) break ;
        else {
          substate = path[++idx]= superstateKey ;
        }
      }

      // don't re-enter the initial state
      --idx ;

      // now enter the target's substates in top-down order...
      do {
        this._sc_statechart_enter(path[idx]) ;
      } while ((--idx) > 0)

      // and finally enter the target itself
      if (idx === 0) this._sc_statechart_enter(this[stateKey]) ;

      // the loop continues to apply any default transitions as substates
      // are entered...
    }

    // add to the global list of statecharts...
    if (StatechartDebugger) {
      StatechartDebugger.statecharts.pushObject(this) ;
    }

    return this ;
  },

  destroyStatechart: function() {
    if (StatechartDebugger) {
      StatechartDebugger.statecharts.removeObject(this) ;
    }
  }

});<|endoftext|>


<commit_before>// Browsers to run on Sauce Labs

var daily = {
    sl_win7_ie9: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '9.0'
    },
    sl_win7_ie10: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '10.0'
    },
    sl_win7_ie11: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '11.0'
    },
    sl_win8_0_ie10: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 8',
        version: '10.0'
    },
    sl_win8_1_ie11: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 8.1',
        version: '11.0'
    },
    sl_ipad_8_2: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '8.2'
    }
};

var weekly = {
    sl_winXP_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Windows XP',
        version: '43.0'
    },
    sl_winXP_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Windows XP',
        version: '38.0'
    },

    sl_win7_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Windows 7',
        version: '43.0'
    },
    sl_win7_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Windows 7',
        version: '38.0'
    },

    sl_win8_0_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Windows 8',
        version: '43.0'
    },
    sl_win8_0_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Windows 8',
        version: '38.0'
    },

    sl_win8_1_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Windows 8.1',
        version: '43.0'
    },
    sl_win8_1_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Windows 8.1',
        version: '38.0'
    },

    sl_mac10_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'OSX 10.10',
        version: '43.0'
    },
    sl_mac10_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'OSX 10.10',
        version: '38.0'
    },
    sl_mac10_safari: {
        base: 'SauceLabs',
        browserName: 'safari',
        platform: 'OS X 10.10',
        version: '8.0'
    },

    sl_linux_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Linux',
        version: '43.0'
    },
    sl_linux_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Linux',
        version: '38.0'
    },
    sl_linux_opera: {
        base: 'SauceLabs',
        browserName: 'opera',
        platform: 'Linux',
        version: '12.15'
    },

    sl_ipad_8_1: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '8.1'
    },
    sl_ipad_8_0: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '8.0'
    },

    sl_android_5_1: {
        base: 'SauceLabs',
        browserName: 'Android',
        platform: 'Linux',
        version: '5.1',
        deviceName: 'Android Emulator',
        deviceOrientation: 'portrait'
    }
};

var manual = {
    sl_mac9_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'OSX 10.9',
        version: '43.0'
    },
    sl_mac9_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'OSX 10.9',
        version: '38.0'
    },
    sl_mac9_safari: {
        base: 'SauceLabs',
        browserName: 'safari',
        platform: 'OS X 10.9',
        version: '7.0'
    },

    sl_ipad_7_1: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '7.1'
    },
    sl_ipad_7_0: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '7.0'
    },

    sl_android_5_0: {
        base: 'SauceLabs',
        browserName: 'Android',
        platform: 'Linux',
        version: '5.0',
        deviceName: 'Android Emulator',
        deviceOrientation: 'portrait'
    },
    sl_android_4_4: {
        base: 'SauceLabs',
        browserName: 'Android',
        platform: 'Linux',
        version: '4.4',
        deviceName: 'Android Emulator',
        deviceOrientation: 'portrait'
    }
};

exports.daily = daily;
exports.weekly = weekly;
exports.manual = manual;<commit_msg>Update launcher configuration according to new requirements from ICOS<commit_after>// Browsers to run on Sauce Labs

var daily = {
    sl_winXP_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Windows XP',
        version: '43.0'
    },
    sl_winXP_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Windows XP',
        version: '39.0'
    },

    sl_win7_ie9: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '9.0'
    },
    sl_win7_ie10: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '10.0'
    },
    sl_win7_ie11: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '11.0'
    },
    sl_win7_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Windows 7',
        version: '43.0'
    },
    sl_win7_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Windows 7',
        version: '39.0'
    },

    sl_win8_0_ie10: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 8',
        version: '10.0'
    },
    sl_win8_0_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Windows 8',
        version: '43.0'
    },
    sl_win8_0_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Windows 8',
        version: '39.0'
    },

    sl_win8_1_ie11: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 8.1',
        version: '11.0'
    },
    sl_win8_1_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Windows 8.1',
        version: '43.0'
    },
    sl_win8_1_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Windows 8.1',
        version: '39.0'
    },

    sl_ipad_8_2: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '8.2'
    }
};

var weekly = {
    sl_mac10_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'OSX 10.10',
        version: '43.0'
    },
    sl_mac10_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'OSX 10.10',
        version: '39.0'
    },
    sl_mac10_safari: {
        base: 'SauceLabs',
        browserName: 'safari',
        platform: 'OS X 10.10',
        version: '8.0'
    },

    sl_linux_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'Linux',
        version: '43.0'
    },
    sl_linux_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'Linux',
        version: '39.0'
    },
    sl_linux_opera: {
        base: 'SauceLabs',
        browserName: 'opera',
        platform: 'Linux',
        version: '12.15'
    },

    sl_ipad_8_1: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '8.1'
    },
    sl_ipad_8_0: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '8.0'
    },

    sl_android_5_1: {
        base: 'SauceLabs',
        browserName: 'Android',
        platform: 'Linux',
        version: '5.1',
        deviceName: 'Android Emulator',
        deviceOrientation: 'portrait'
    }
};

var manual = {
    sl_mac9_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        platform: 'OSX 10.9',
        version: '43.0'
    },
    sl_mac9_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox',
        platform: 'OSX 10.9',
        version: '39.0'
    },
    sl_mac9_safari: {
        base: 'SauceLabs',
        browserName: 'safari',
        platform: 'OS X 10.9',
        version: '7.0'
    },

    sl_ipad_7_1: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '7.1'
    },
    sl_ipad_7_0: {
        base: 'SauceLabs',
        browserName: 'Safari',
        appiumVersion: '1.4.7',
        deviceName: 'iPad Simulator',
        deviceOrientation: 'portrait',
        platformName: 'iOS',
        platformVersion: '7.0'
    },

    sl_android_5_0: {
        base: 'SauceLabs',
        browserName: 'Android',
        platform: 'Linux',
        version: '5.0',
        deviceName: 'Android Emulator',
        deviceOrientation: 'portrait'
    },
    sl_android_4_4: {
        base: 'SauceLabs',
        browserName: 'Android',
        platform: 'Linux',
        version: '4.4',
        deviceName: 'Android Emulator',
        deviceOrientation: 'portrait'
    }
};

exports.daily = daily;
exports.weekly = weekly;
exports.manual = manual;<|endoftext|>


<commit_before>import Ember from 'ember';
import ResetScrollPositionMixin from 'frontend/mixins/reset-scroll-position';
import RSVP from 'rsvp';

export default Ember.Route.extend(ResetScrollPositionMixin, {
  model() {
    return RSVP.hash({
      markers: this.store.findAll('chart-data/geo/marker'),
      geojson: Ember.$.get('http://localhost:3000/chart_data/geo/geojson')
    });
  }
});
<commit_msg>parameterize backend host<commit_after>import Ember from 'ember';
import ResetScrollPositionMixin from 'frontend/mixins/reset-scroll-position';
import RSVP from 'rsvp';

export default Ember.Route.extend(ResetScrollPositionMixin, {
  model() {
    const host = this.store.adapterFor('chart-data/geo/marker').get('host');
    return RSVP.hash({
      markers: this.store.findAll('chart-data/geo/marker'),
      geojson: Ember.$.get(`${host}/chart_data/geo/geojson`)
    });
  }
});
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

THREE.OBJExporter = function () {};

THREE.OBJExporter.prototype = {

	constructor: THREE.OBJExporter,

	parse: function ( object ) {

		var output = '';

		var indexVertex = 0;
		var indexVertexUvs = 0;
		var indexNormals = 0;

		var faceVertexKeys = [ "a", "b", "c" ];

		var parseMesh = function ( mesh ) {

			var nbVertex = 0;
			var nbVertexUvs = 0;
			var nbNormals = 0;

			var geometry = mesh.geometry;

			if ( geometry instanceof THREE.BufferGeometry ) {

				geometry = new THREE.Geometry().fromBufferGeometry( geometry );

			}

			if ( geometry instanceof THREE.Geometry ) {

				output += 'o ' + mesh.name + '\n';

				var vertices = geometry.vertices;

				for ( var i = 0, l = vertices.length; i < l; i ++ ) {

					var vertex = vertices[ i ].clone();
					vertex.applyMatrix4( mesh.matrixWorld );

					output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';

					nbVertex ++;

				}

				// uvs

				var faces = geometry.faces;
				var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
				var hasVertexUvs = faces.length === faceVertexUvs.length;

				if ( hasVertexUvs ) {

					for ( var i = 0, l = faceVertexUvs.length; i < l; i ++ ) {

						var vertexUvs = faceVertexUvs[ i ];

						for ( var j = 0, jl = vertexUvs.length; j < jl; j ++ ) {

							var uv = vertexUvs[ j ];

							output += 'vt ' + uv.x + ' ' + uv.y + '\n';

							nbVertexUvs ++;

						}

					}

				}

				// normals

				var normalMatrixWorld = new THREE.Matrix3();
				normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );

				for ( var i = 0, l = faces.length; i < l; i ++ ) {

					var face = faces[ i ];
					var vertexNormals = face.vertexNormals;

					if ( vertexNormals.length === 3 ) {

						for ( var j = 0, jl = vertexNormals.length; j < jl; j ++ ) {

							var normal = vertexNormals[ j ].clone();
							normal.applyMatrix3( normalMatrixWorld );

							output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';

							nbNormals ++;

						}

					} else {

						var normal = face.normal.clone();
						normal.applyMatrix3( normalMatrixWorld );

						for ( var j = 0; j < 3; j ++ ) {

							output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';

							nbNormals ++;

						}

					}

				}

				// faces

				for ( var i = 0, j = 1, l = faces.length; i < l; i ++, j += 3 ) {

					var face = faces[ i ];
					var indices = [];

					for ( var m = 0; m < 3; m ++ ) {

					    indices[ m ] = ( indexVertex + face[ faceVertexKeys[ m ] ] + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j + m + 1 ) : '' ) + '/' + ( indexNormals + j + m + 1 );

					}

					output += 'f ' + indices.join( ' ' ) + "\n";

				}

			} else {

				console.warn( 'THREE.OBJExporter.parseMesh(): geometry type unsupported', mesh );

			}

			// update index
			indexVertex += nbVertex;
			indexVertexUvs += nbVertexUvs;
			indexNormals += nbNormals;

		};

		object.traverse( function ( child ) {

			if ( child instanceof THREE.Mesh ) parseMesh( child );

		} );

		return output;

	}

};
<commit_msg>Move `vertices` outside of the faces loop<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

THREE.OBJExporter = function () {};

THREE.OBJExporter.prototype = {

	constructor: THREE.OBJExporter,

	parse: function ( object ) {

		var output = '';

		var indexVertex = 0;
		var indexVertexUvs = 0;
		var indexNormals = 0;

		var faceVertexKeys = [ "a", "b", "c" ];

		var parseMesh = function ( mesh ) {

			var nbVertex = 0;
			var nbVertexUvs = 0;
			var nbNormals = 0;

			var geometry = mesh.geometry;

			if ( geometry instanceof THREE.BufferGeometry ) {

				geometry = new THREE.Geometry().fromBufferGeometry( geometry );

			}

			if ( geometry instanceof THREE.Geometry ) {

				output += 'o ' + mesh.name + '\n';

				var vertices = geometry.vertices;

				for ( var i = 0, l = vertices.length; i < l; i ++ ) {

					var vertex = vertices[ i ].clone();
					vertex.applyMatrix4( mesh.matrixWorld );

					output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';

					nbVertex ++;

				}

				// uvs

				var faces = geometry.faces;
				var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
				var hasVertexUvs = faces.length === faceVertexUvs.length;

				if ( hasVertexUvs ) {

					for ( var i = 0, l = faceVertexUvs.length; i < l; i ++ ) {

						var vertexUvs = faceVertexUvs[ i ];

						for ( var j = 0, jl = vertexUvs.length; j < jl; j ++ ) {

							var uv = vertexUvs[ j ];

							output += 'vt ' + uv.x + ' ' + uv.y + '\n';

							nbVertexUvs ++;

						}

					}

				}

				// normals

				var normalMatrixWorld = new THREE.Matrix3();
				normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );

				for ( var i = 0, l = faces.length; i < l; i ++ ) {

					var face = faces[ i ];
					var vertexNormals = face.vertexNormals;

					if ( vertexNormals.length === 3 ) {

						for ( var j = 0, jl = vertexNormals.length; j < jl; j ++ ) {

							var normal = vertexNormals[ j ].clone();
							normal.applyMatrix3( normalMatrixWorld );

							output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';

							nbNormals ++;

						}

					} else {

						var normal = face.normal.clone();
						normal.applyMatrix3( normalMatrixWorld );

						for ( var j = 0; j < 3; j ++ ) {

							output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';

							nbNormals ++;

						}

					}

				}

				// faces
				var indices = [];

				for ( var i = 0, j = 1, l = faces.length; i < l; i ++, j += 3 ) {

					var face = faces[ i ];

					for ( var m = 0; m < 3; m ++ ) {

					    indices[ m ] = ( indexVertex + face[ faceVertexKeys[ m ] ] + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j + m + 1 ) : '' ) + '/' + ( indexNormals + j + m + 1 );

					}

					output += 'f ' + indices.join( ' ' ) + "\n";

				}

			} else {

				console.warn( 'THREE.OBJExporter.parseMesh(): geometry type unsupported', mesh );

			}

			// update index
			indexVertex += nbVertex;
			indexVertexUvs += nbVertexUvs;
			indexNormals += nbNormals;

		};

		object.traverse( function ( child ) {

			if ( child instanceof THREE.Mesh ) parseMesh( child );

		} );

		return output;

	}

};
<|endoftext|>