<commit_before>// Copyright 2014-2019, University of Colorado Boulder

/**
 * the 'Intro' screen in the Energy Forms and Changes simulation
 *
 * @author John Blanco
 * @author Martin Veillette (Berea College)
 */
define( require => {
  'use strict';

  // modules
  const BeakerType = require( 'ENERGY_FORMS_AND_CHANGES/common/model/BeakerType' );
  const BlockType = require( 'ENERGY_FORMS_AND_CHANGES/intro/model/BlockType' );
  const EFACConstants = require( 'ENERGY_FORMS_AND_CHANGES/common/EFACConstants' );
  const EFACIntroModel = require( 'ENERGY_FORMS_AND_CHANGES/intro/model/EFACIntroModel' );
  const EFACIntroScreenView = require( 'ENERGY_FORMS_AND_CHANGES/intro/view/EFACIntroScreenView' );
  const EFACQueryParameters = require( 'ENERGY_FORMS_AND_CHANGES/common/EFACQueryParameters' );
  const energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  const Image = require( 'SCENERY/nodes/Image' );
  const Property = require( 'AXON/Property' );
  const Screen = require( 'JOIST/Screen' );

  // strings
  const introString = require( 'string!ENERGY_FORMS_AND_CHANGES/intro' );

  // images
  const introScreenIcon = require( 'image!ENERGY_FORMS_AND_CHANGES/intro_screen_icon.png' );

  class EFACIntroScreen extends Screen {

    /**
     * @param {Tandem} tandem
     */
    constructor( tandem ) {

      const options = {
        name: introString,
        backgroundColorProperty: new Property( EFACConstants.FIRST_SCREEN_BACKGROUND_COLOR ),
        homeScreenIcon: new Image( introScreenIcon ),
        maxDT: EFACConstants.maxDT,
        tandem: tandem
      };

      let blocksToCreate = [];
      let beakersToCreate = [];

      // map query parameter string to element type and split by blocks vs beakers
      EFACQueryParameters.elements.forEach( elementKey => {
        if ( elementKey === EFACConstants.IRON_KEY ) {
          blocksToCreate.push( BlockType.IRON );
        }
        else if ( elementKey === EFACConstants.BRICK_KEY ) {
          blocksToCreate.push( BlockType.BRICK );
        }
        else if ( elementKey === EFACConstants.WATER_KEY ) {
          beakersToCreate.push( BeakerType.WATER );
        }
        else if ( elementKey === EFACConstants.OLIVE_OIL_KEY ) {
          beakersToCreate.push( BeakerType.OLIVE_OIL );
        }
      } );

      if( beakersToCreate.length > EFACConstants.MAX_NUMBER_OF_INTRO_BEAKERS ) {
        assert && assert( false, `Only ${EFACConstants.MAX_NUMBER_OF_INTRO_BEAKERS} beakers may be added, but \
${beakersToCreate.length} were provided: ${beakersToCreate}` );
        beakersToCreate = beakersToCreate.slice( 0, EFACConstants.MAX_NUMBER_OF_INTRO_BEAKERS );
      }

      super(
        () => new EFACIntroModel(
          blocksToCreate,
          beakersToCreate,
          tandem.createTandem( 'model' )
        ),
        model => new EFACIntroScreenView( model, tandem.createTandem( 'view' ) ),
        options
      );
    }
  }

  return energyFormsAndChanges.register( 'EFACIntroScreen', EFACIntroScreen );
} );
<commit_msg>Fix lint error, see https://github.com/phetsims/energy-forms-and-changes/issues/216<commit_after>// Copyright 2014-2019, University of Colorado Boulder

/**
 * the 'Intro' screen in the Energy Forms and Changes simulation
 *
 * @author John Blanco
 * @author Martin Veillette (Berea College)
 */
define( require => {
  'use strict';

  // modules
  const BeakerType = require( 'ENERGY_FORMS_AND_CHANGES/common/model/BeakerType' );
  const BlockType = require( 'ENERGY_FORMS_AND_CHANGES/intro/model/BlockType' );
  const EFACConstants = require( 'ENERGY_FORMS_AND_CHANGES/common/EFACConstants' );
  const EFACIntroModel = require( 'ENERGY_FORMS_AND_CHANGES/intro/model/EFACIntroModel' );
  const EFACIntroScreenView = require( 'ENERGY_FORMS_AND_CHANGES/intro/view/EFACIntroScreenView' );
  const EFACQueryParameters = require( 'ENERGY_FORMS_AND_CHANGES/common/EFACQueryParameters' );
  const energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  const Image = require( 'SCENERY/nodes/Image' );
  const Property = require( 'AXON/Property' );
  const Screen = require( 'JOIST/Screen' );

  // strings
  const introString = require( 'string!ENERGY_FORMS_AND_CHANGES/intro' );

  // images
  const introScreenIcon = require( 'image!ENERGY_FORMS_AND_CHANGES/intro_screen_icon.png' );

  class EFACIntroScreen extends Screen {

    /**
     * @param {Tandem} tandem
     */
    constructor( tandem ) {

      const options = {
        name: introString,
        backgroundColorProperty: new Property( EFACConstants.FIRST_SCREEN_BACKGROUND_COLOR ),
        homeScreenIcon: new Image( introScreenIcon ),
        maxDT: EFACConstants.maxDT,
        tandem: tandem
      };

      const blocksToCreate = [];
      let beakersToCreate = [];

      // map query parameter string to element type and split by blocks vs beakers
      EFACQueryParameters.elements.forEach( elementKey => {
        if ( elementKey === EFACConstants.IRON_KEY ) {
          blocksToCreate.push( BlockType.IRON );
        }
        else if ( elementKey === EFACConstants.BRICK_KEY ) {
          blocksToCreate.push( BlockType.BRICK );
        }
        else if ( elementKey === EFACConstants.WATER_KEY ) {
          beakersToCreate.push( BeakerType.WATER );
        }
        else if ( elementKey === EFACConstants.OLIVE_OIL_KEY ) {
          beakersToCreate.push( BeakerType.OLIVE_OIL );
        }
      } );

      if( beakersToCreate.length > EFACConstants.MAX_NUMBER_OF_INTRO_BEAKERS ) {
        assert && assert( false, `Only ${EFACConstants.MAX_NUMBER_OF_INTRO_BEAKERS} beakers may be added, but \
${beakersToCreate.length} were provided: ${beakersToCreate}` );
        beakersToCreate = beakersToCreate.slice( 0, EFACConstants.MAX_NUMBER_OF_INTRO_BEAKERS );
      }

      super(
        () => new EFACIntroModel(
          blocksToCreate,
          beakersToCreate,
          tandem.createTandem( 'model' )
        ),
        model => new EFACIntroScreenView( model, tandem.createTandem( 'view' ) ),
        options
      );
    }
  }

  return energyFormsAndChanges.register( 'EFACIntroScreen', EFACIntroScreen );
} );
<|endoftext|>


<commit_before>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Assorted tests to qualify browsers by detecting features
//>>label: Support Tests
//>>group: Core
define( [  "jquery", "./jquery.mobile.core", "./jquery.mobile.media", "./jquery.mobile.support.touch", "./jquery.mobile.support.orientation" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {

// thx Modernizr
function propExists( prop ) {
	var uc_prop = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ),
		props = ( prop + " " + vendors.join( uc_prop + " " ) + uc_prop ).split( " " );

	for ( var v in props ) {
		if ( fbCSS[ props[ v ] ] !== undefined ) {
			return true;
		}
	}
}

var fakeBody = $( "" ).prependTo( "html" ),
	fbCSS = fakeBody[ 0 ].style,
	vendors = [ "Webkit", "Moz", "O" ],
	webos = "palmGetResource" in window, //only used to rule out scrollTop
	opera = window.opera,
	operamini = window.operamini && ({}).toString.call( window.operamini ) === "[object OperaMini]",
	bb = window.blackberry && !propExists( "-webkit-transform" ); //only used to rule out box shadow, as it's filled opaque on BB 5 and lower

function validStyle( prop, value, check_vend ) {
	var div = document.createElement( 'div' ),
		uc = function( txt ) {
			return txt.charAt( 0 ).toUpperCase() + txt.substr( 1 );
		},
		vend_pref = function( vend ) {
			return  "-" + vend.charAt( 0 ).toLowerCase() + vend.substr( 1 ) + "-";
		},
		check_style = function( vend ) {
			var vend_prop = vend_pref( vend ) + prop + ": " + value + ";",
				uc_vend = uc( vend ),
				propStyle = uc_vend + uc( prop );

			div.setAttribute( "style", vend_prop );

			if ( !!div.style[ propStyle ] ) {
				ret = true;
			}
		},
		check_vends = check_vend ? [ check_vend ] : vendors,
		ret;

	for( var i = 0; i < check_vends.length; i++ ) {
		check_style( check_vends[i] );
	}
	return !!ret;
}

// Thanks to Modernizr src for this test idea. `perspective` check is limited to Moz to prevent a false positive for 3D transforms on Android.
function transform3dTest() {
	var prop = "transform-3d";
	return validStyle( 'perspective', '10px', 'moz' ) || $.mobile.media( "(-" + vendors.join( "-" + prop + "),(-" ) + "-" + prop + "),(" + prop + ")" );
}

// Test for dynamic-updating base tag support ( allows us to avoid href,src attr rewriting )
function baseTagTest() {
	var fauxBase = location.protocol + "//" + location.host + location.pathname + "ui-dir/",
		base = $( "head base" ),
		fauxEle = null,
		href = "",
		link, rebase;

	if ( !base.length ) {
		base = fauxEle = $( "<base>", { "href": fauxBase }).appendTo( "head" );
	} else {
		href = base.attr( "href" );
	}

	link = $( "" ).prependTo( fakeBody );
	rebase = link[ 0 ].href;
	base[ 0 ].href = href || location.pathname;

	if ( fauxEle ) {
		fauxEle.remove();
	}
	return rebase.indexOf( fauxBase ) === 0;
}

// Thanks Modernizr
function cssPointerEventsTest() {
	var element = document.createElement( 'x' ),
		documentElement = document.documentElement,
		getComputedStyle = window.getComputedStyle,
		supports;

	if ( !( 'pointerEvents' in element.style ) ) {
		return false;
	}

	element.style.pointerEvents = 'auto';
	element.style.pointerEvents = 'x';
	documentElement.appendChild( element );
	supports = getComputedStyle &&
	getComputedStyle( element, '' ).pointerEvents === 'auto';
	documentElement.removeChild( element );
	return !!supports;
}

function boundingRect() {
	var div = document.createElement( "div" );
	return typeof div.getBoundingClientRect !== "undefined";
}

// non-UA-based IE version check by James Padolsey, modified by jdalton - from http://gist.github.com/527683
// allows for inclusion of IE 6+, including Windows Mobile 7
$.extend( $.mobile, { browser: {} } );
$.mobile.browser.ie = (function() {
	var v = 3,
		div = document.createElement( "div" ),
		a = div.all || [];

	do {
		div.innerHTML = "";
	} while( a[0] );

	return v > 4 ? v : !v;
})();

$.extend( $.support, {
	cssTransitions: "WebKitTransitionEvent" in window || validStyle( 'transition', 'height 100ms linear' ) && !opera,
	pushState: "pushState" in history && "replaceState" in history,
	mediaquery: $.mobile.media( "only all" ),
	cssPseudoElement: !!propExists( "content" ),
	touchOverflow: !!propExists( "overflowScrolling" ),
	cssTransform3d: transform3dTest(),
	boxShadow: !!propExists( "boxShadow" ) && !bb,
	scrollTop: ( "pageXOffset" in window || "scrollTop" in document.documentElement || "scrollTop" in fakeBody[ 0 ] ) && !webos && !operamini,
	dynamicBaseTag: baseTagTest(),
	cssPointerEvents: cssPointerEventsTest(),
	boundingRect: boundingRect()
});

fakeBody.remove();

// $.mobile.ajaxBlacklist is used to override ajaxEnabled on platforms that have known conflicts with hash history updates (BB5, Symbian)
// or that generally work better browsing in regular http for full page refreshes (Opera Mini)
// Note: This detection below is used as a last resort.
// We recommend only using these detection methods when all other more reliable/forward-looking approaches are not possible
var nokiaLTE7_3 = (function() {

	var ua = window.navigator.userAgent;

	//The following is an attempt to match Nokia browsers that are running Symbian/s60, with webkit, version 7.3 or older
	return ua.indexOf( "Nokia" ) > -1 &&
			( ua.indexOf( "Symbian/3" ) > -1 || ua.indexOf( "Series60/5" ) > -1 ) &&
			ua.indexOf( "AppleWebKit" ) > -1 &&
			ua.match( /(BrowserNG|NokiaBrowser)\/7\.[0-3]/ );
})();

// Support conditions that must be met in order to proceed
// default enhanced qualifications are media query support OR IE 7+

$.mobile.gradeA = function() {
	return ( $.support.mediaquery || $.mobile.browser.ie && $.mobile.browser.ie >= 7 ) && ( $.support.boundingRect || $.fn.jquery.match(/1\.[0-7+]\.[0-9+]?/) !== null );
};

$.mobile.ajaxBlacklist =
			// BlackBerry browsers, pre-webkit
			window.blackberry && !window.WebKitPoint ||
			// Opera Mini
			operamini ||
			// Symbian webkits pre 7.3
			nokiaLTE7_3;

// Lastly, this workaround is the only way we've found so far to get pre 7.3 Symbian webkit devices
// to render the stylesheets when they're referenced before this script, as we'd recommend doing.
// This simply reappends the CSS in place, which for some reason makes it apply
if ( nokiaLTE7_3 ) {
	$(function() {
		$( "head link[rel='stylesheet']" ).attr( "rel", "alternate stylesheet" ).attr( "rel", "stylesheet" );
	});
}

// For ruling out shadows via css
if ( !$.support.boxShadow ) {
	$( "html" ).addClass( "ui-mobile-nosupport-boxshadow" );
}

})( jQuery );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<commit_msg>support: Fix cssTransition test to kick out all ie versions < 10<commit_after>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Assorted tests to qualify browsers by detecting features
//>>label: Support Tests
//>>group: Core
define( [  "jquery", "./jquery.mobile.core", "./jquery.mobile.media", "./jquery.mobile.support.touch", "./jquery.mobile.support.orientation" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, undefined ) {

// thx Modernizr
function propExists( prop ) {
	var uc_prop = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ),
		props = ( prop + " " + vendors.join( uc_prop + " " ) + uc_prop ).split( " " );

	for ( var v in props ) {
		if ( fbCSS[ props[ v ] ] !== undefined ) {
			return true;
		}
	}
}

var fakeBody = $( "" ).prependTo( "html" ),
	fbCSS = fakeBody[ 0 ].style,
	vendors = [ "Webkit", "Moz", "O" ],
	webos = "palmGetResource" in window, //only used to rule out scrollTop
	opera = window.opera,
	operamini = window.operamini && ({}).toString.call( window.operamini ) === "[object OperaMini]",
	bb = window.blackberry && !propExists( "-webkit-transform" ); //only used to rule out box shadow, as it's filled opaque on BB 5 and lower

function validStyle( prop, value, check_vend ) {
	var div = document.createElement( 'div' ),
		uc = function( txt ) {
			return txt.charAt( 0 ).toUpperCase() + txt.substr( 1 );
		},
		vend_pref = function( vend ) {
			return  "-" + vend.charAt( 0 ).toLowerCase() + vend.substr( 1 ) + "-";
		},
		check_style = function( vend ) {
			var vend_prop = vend_pref( vend ) + prop + ": " + value + ";",
				uc_vend = uc( vend ),
				propStyle = uc_vend + uc( prop );

			div.setAttribute( "style", vend_prop );

			if ( !!div.style[ propStyle ] ) {
				ret = true;
			}
		},
		check_vends = check_vend ? [ check_vend ] : vendors,
		ret;

	for( var i = 0; i < check_vends.length; i++ ) {
		check_style( check_vends[i] );
	}
	return !!ret;
}

// Thanks to Modernizr src for this test idea. `perspective` check is limited to Moz to prevent a false positive for 3D transforms on Android.
function transform3dTest() {
	var prop = "transform-3d";
	return validStyle( 'perspective', '10px', 'moz' ) || $.mobile.media( "(-" + vendors.join( "-" + prop + "),(-" ) + "-" + prop + "),(" + prop + ")" );
}

// Test for dynamic-updating base tag support ( allows us to avoid href,src attr rewriting )
function baseTagTest() {
	var fauxBase = location.protocol + "//" + location.host + location.pathname + "ui-dir/",
		base = $( "head base" ),
		fauxEle = null,
		href = "",
		link, rebase;

	if ( !base.length ) {
		base = fauxEle = $( "<base>", { "href": fauxBase }).appendTo( "head" );
	} else {
		href = base.attr( "href" );
	}

	link = $( "" ).prependTo( fakeBody );
	rebase = link[ 0 ].href;
	base[ 0 ].href = href || location.pathname;

	if ( fauxEle ) {
		fauxEle.remove();
	}
	return rebase.indexOf( fauxBase ) === 0;
}

// Thanks Modernizr
function cssPointerEventsTest() {
	var element = document.createElement( 'x' ),
		documentElement = document.documentElement,
		getComputedStyle = window.getComputedStyle,
		supports;

	if ( !( 'pointerEvents' in element.style ) ) {
		return false;
	}

	element.style.pointerEvents = 'auto';
	element.style.pointerEvents = 'x';
	documentElement.appendChild( element );
	supports = getComputedStyle &&
	getComputedStyle( element, '' ).pointerEvents === 'auto';
	documentElement.removeChild( element );
	return !!supports;
}

function boundingRect() {
	var div = document.createElement( "div" );
	return typeof div.getBoundingClientRect !== "undefined";
}

// non-UA-based IE version check by James Padolsey, modified by jdalton - from http://gist.github.com/527683
// allows for inclusion of IE 6+, including Windows Mobile 7
$.extend( $.mobile, { browser: {} } );
$.mobile.browser.ie = (function() {
	var v = 3,
		div = document.createElement( "div" ),
		a = div.all || [];

	do {
		div.innerHTML = "";
	} while( a[0] );

	return v > 4 ? v : !v;
})();

$.extend( $.support, {
	cssTransitions: "WebKitTransitionEvent" in window || validStyle( 'transition', 'height 100ms linear', [ "Webkit", "Moz", "" ] ) && $.mobile.browser.ie < 10 && !opera,
	pushState: "pushState" in history && "replaceState" in history,
	mediaquery: $.mobile.media( "only all" ),
	cssPseudoElement: !!propExists( "content" ),
	touchOverflow: !!propExists( "overflowScrolling" ),
	cssTransform3d: transform3dTest(),
	boxShadow: !!propExists( "boxShadow" ) && !bb,
	scrollTop: ( "pageXOffset" in window || "scrollTop" in document.documentElement || "scrollTop" in fakeBody[ 0 ] ) && !webos && !operamini,
	dynamicBaseTag: baseTagTest(),
	cssPointerEvents: cssPointerEventsTest(),
	boundingRect: boundingRect()
});

fakeBody.remove();

// $.mobile.ajaxBlacklist is used to override ajaxEnabled on platforms that have known conflicts with hash history updates (BB5, Symbian)
// or that generally work better browsing in regular http for full page refreshes (Opera Mini)
// Note: This detection below is used as a last resort.
// We recommend only using these detection methods when all other more reliable/forward-looking approaches are not possible
var nokiaLTE7_3 = (function() {

	var ua = window.navigator.userAgent;

	//The following is an attempt to match Nokia browsers that are running Symbian/s60, with webkit, version 7.3 or older
	return ua.indexOf( "Nokia" ) > -1 &&
			( ua.indexOf( "Symbian/3" ) > -1 || ua.indexOf( "Series60/5" ) > -1 ) &&
			ua.indexOf( "AppleWebKit" ) > -1 &&
			ua.match( /(BrowserNG|NokiaBrowser)\/7\.[0-3]/ );
})();

// Support conditions that must be met in order to proceed
// default enhanced qualifications are media query support OR IE 7+

$.mobile.gradeA = function() {
	return ( $.support.mediaquery || $.mobile.browser.ie && $.mobile.browser.ie >= 7 ) && ( $.support.boundingRect || $.fn.jquery.match(/1\.[0-7+]\.[0-9+]?/) !== null );
};

$.mobile.ajaxBlacklist =
			// BlackBerry browsers, pre-webkit
			window.blackberry && !window.WebKitPoint ||
			// Opera Mini
			operamini ||
			// Symbian webkits pre 7.3
			nokiaLTE7_3;

// Lastly, this workaround is the only way we've found so far to get pre 7.3 Symbian webkit devices
// to render the stylesheets when they're referenced before this script, as we'd recommend doing.
// This simply reappends the CSS in place, which for some reason makes it apply
if ( nokiaLTE7_3 ) {
	$(function() {
		$( "head link[rel='stylesheet']" ).attr( "rel", "alternate stylesheet" ).attr( "rel", "stylesheet" );
	});
}

// For ruling out shadows via css
if ( !$.support.boxShadow ) {
	$( "html" ).addClass( "ui-mobile-nosupport-boxshadow" );
}

})( jQuery );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<|endoftext|>


<commit_before>/*
 * jQuery Plus Slider 1.4.3
 * By Jamy Golden
 * http://css-plus.com
 * @jamygolden
 *
 * Copyright 2011
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */

(function($){$.plusSlider=function(el,options){var base=this;base.$el=$(el);base.el=el;base.$el.data('plusSlider',base);base.init=function(){base.options=$.extend({},$.plusSlider.defaults,options);base.$el.addClass('plusslide-container').wrap('
');base.$wrap=base.$el.parent();base.$slides=base.$el.children();base.$wrapContainer=base.$wrap.parent();base.slideCount=base.$slides.length;base.slideIndexCount=base.slideCount-1;base.animating=false;base.wrapContainerWidth=base.$wrapContainer.width();base.wrapContainerHeight=base.$wrapContainer.height();base.currentSlideIndex=base.options.defaultSlide;base.$currentSlide=base.$slides.eq(base.currentSlideIndex);base.currentSlideWidth=base.$currentSlide.outerWidth();base.currentSlideHeight=base.$currentSlide.outerHeight();base.calculateSliderWidth=function(){for(var i=0;i<base.slideCount;i++){if(i==0)base.sliderWidth=0;base.sliderWidth+=base.$slides.eq(i).outerWidth();};};base.beginTimer=function(){base.timer=window.setInterval(function(){base.toSlide('next');},base.options.displayTime);};base.clearTimer=function(){if(base.timer){window.clearInterval(base.timer);};};base.setSliderDimensions=function(){base.wrapContainerWidth=base.$wrapContainer.width();base.sliderWidth=base.wrapContainerWidth*base.slideCount;base.currentSlideWidth=base.$currentSlide.outerWidth();base.currentSlideHeight=base.$currentSlide.outerHeight();base.$slides.width(base.wrapContainerWidth);base.$el.width(base.sliderWidth).css('left',base.$currentSlide.position().left*-1+'px');base.$wrap.width(base.wrapContainerWidth).height(base.currentSlideHeight);};base.toSlide=function(slide){if(slide==='next'||slide===''){base.currentSlideIndex+=1;}else if(slide==='prev'){base.currentSlideIndex-=1;}else{base.currentSlideIndex=slide;}if((base.options.disableLoop=='first'||base.options.disableLoop=='both'&&base.currentSlideIndex<0)||(base.options.disableLoop=='last'||base.options.disableLoop=='both'&&base.currentSlideIndex>base.slideIndexCount)){return;}if(base.currentSlideIndex>base.slideIndexCount){base.currentSlideIndex=0;}else if(base.currentSlideIndex<0){base.currentSlideIndex=base.slideIndexCount;};base.$currentSlide=base.$slides.eq(base.currentSlideIndex);base.currentSlideWidth=base.$currentSlide.width();base.currentSlideHeight=base.$currentSlide.height();if(base.options.beforeSlide&&typeof(base.options.beforeSlide)=='function')base.options.beforeSlide(base);if(base.animating==false){base.animating=true;if(base.options.onSlide&&typeof(base.options.onSlide)=='function')base.options.onSlide(base);if(base.options.sliderType=='slider'){if(base.options.createPagination){base.$sliderControls.find('li').removeClass('current').eq(base.currentSlideIndex).addClass('current');};base.$el.animate({height:base.$currentSlide.outerHeight(),left:base.$currentSlide.position().left*-1+'px'},base.options.speed,base.options.sliderEasing,function(){base.animating=false;if(base.options.afterSlide&&typeof(base.options.afterSlide)=='function')base.options.afterSlide(base);if(base.options.onEnd&&typeof(base.options.onEnd)=='function'&&base.currentSlideIndex==base.slideIndexCount)base.options.onEnd(base);});base.$wrap.animate({height:base.$currentSlide.outerHeight(),width:base.$currentSlide.outerWidth()},base.options.speed,base.options.sliderEasing);base.$slides.removeClass('current').eq(base.currentSlideIndex).addClass('current');}else{if(base.options.createPagination){base.$sliderControls.find('li').removeClass('current').eq(base.currentSlideIndex).addClass('current');};base.$slides.removeClass('current').eq(base.currentSlideIndex).addClass('current').fadeIn(base.options.speed,function(){base.$slides.not('.current').hide();base.animating=false;if(base.options.afterSlide&&typeof(base.options.afterSlide)=='function')base.options.afterSlide(base);if(base.options.onEnd&&typeof(base.options.onEnd)=='function'&&base.currentSlideIndex==base.slideIndexCount)base.options.onEnd(base);});};};if(base.options.autoSlide){base.clearTimer();base.beginTimer();};};if(base.slideCount===1){base.options.autoSlide=false;base.options.createArrows=false;base.options.createPagination=false;};if(base.options.sliderType=='fader')base.options.fullWidth=false;if(base.options.onStart&&typeof(base.options.onStart)=='function')base.options.onStart(base);base.$slides.addClass('child').eq(base.currentSlideIndex).addClass('current');base.$wrap.width(base.currentSlideWidth).height(base.currentSlideHeight);if(base.options.width)base.$wrap.width(base.options.width);if(base.options.height)base.$wrap.height(base.options.height);base.currentSlideWidth=base.$currentSlide.outerWidth();base.currentSlideHeight=base.$currentSlide.outerHeight();if(base.options.sliderType=='slider'){base.calculateSliderWidth();base.$wrap.addClass('plustype-slider').find(base.$el).width(base.sliderWidth);if(base.options.fullWidth){base.setSliderDimensions();$(window).resize(function(){base.setSliderDimensions();});};base.$slides.show();base.$el.css('left',base.$currentSlide.position().left*-1+'px');}else{base.$wrap.addClass('plustype-fader');base.$slides.eq(0).show();};if(base.options.createPagination){base.$sliderControls=$('
',{'class':'plusslider-controls'});base.options.paginationBefore?base.$sliderControls.prependTo(base.$wrap):base.$sliderControls.appendTo(base.$wrap);base.$sliderControls.wrap('
');for(var i=0;i<base.slideCount;i++){$('
',{href:'#','data-index':i,text:base.options.paginationTitle?base.$slides.eq(i).attr('data-title'):i+1}).appendTo(base.$sliderControls);};if(base.options.paginationWidth)base.$sliderControls.width(base.$sliderControls.find('li').outerWidth(true)*base.slideCount);base.$sliderControls.find('li').click(function(){var controlIndex=$(this).index();base.toSlide(controlIndex);}).eq(base.currentSlideIndex).addClass('current');};if(base.options.createArrows){$('
',{'class':'plusnav'}).prependTo(base.$wrap);base.$arrows=base.$wrap.find('.plusnav');$('
',{'class':'next',text:base.options.nextText}).prependTo(base.$arrows);$('
',{'class':'prev',text:base.options.prevText}).prependTo(base.$arrows);base.$arrows.find('.next').click(function(){base.toSlide('next');});base.$arrows.find('.prev').click(function(){base.toSlide('prev');});};if(base.options.autoSlide){base.beginTimer();if(base.options.pauseOnHover){base.$el.hover(function(){base.clearTimer();},function(){base.beginTimer();});};};if(base.options.keyboardNavigation){base.$el.click(function(){$('.active-plusslider').removeClass('active-plusslider');$(this).addClass('active-plusslider');});$(window).keyup(function(e){if(base.$el.is('.active-plusslider')){if(e.keyCode==39){base.toSlide('next');}else if(e.keyCode==37){base.toSlide('prev');};};});};};base.init();};$.plusSlider.defaults={sliderType:'slider',disableLoop:false,fullWidth:false,width:null,height:null,defaultSlide:0,displayTime:4000,sliderEasing:'linear',speed:500,autoSlide:true,keyboardNavigation:true,pauseOnHover:true,createArrows:true,nextText:'Next',prevText:'Previous',createPagination:true,paginationBefore:false,paginationWidth:false,paginationTitle:false,onStart:null,beforeSlide:null,onSlide:null,afterSlide:null,onEnd:null};$.fn.plusSlider=function(options){return this.each(function(){(new $.plusSlider(this,options));});};})(jQuery);<commit_msg>Updated min.js file<commit_after>/*
 * jQuery Plus Slider 1.4.3
 * By Jamy Golden
 * http://css-plus.com
 * @jamygolden
 *
 * Copyright 2011
 * Free to use under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 */

(function($){$.plusSlider=function(el,options){var base=this;base.$el=$(el);base.el=el;base.$el.data('plusSlider',base);base.init=function(){base.options=$.extend({},$.plusSlider.defaults,options);base.$el.addClass('plusslide-container').wrap('
');base.$wrap=base.$el.parent();base.$slides=base.$el.children();base.$wrapContainer=base.$wrap.parent();base.slideCount=base.$slides.length;base.slideIndexCount=base.slideCount-1;base.animating=false;base.wrapContainerWidth=base.$wrapContainer.width();base.wrapContainerHeight=base.$wrapContainer.height();base.currentSlideIndex=base.options.defaultSlide;base.$currentSlide=base.$slides.eq(base.currentSlideIndex);base.currentSlideWidth=base.$currentSlide.outerWidth();base.currentSlideHeight=base.$currentSlide.outerHeight();base.calculateSliderWidth=function(){for(var i=0;i<base.slideCount;i++){if(i==0)base.sliderWidth=0;base.sliderWidth+=base.$slides.eq(i).outerWidth();};};base.beginTimer=function(){base.timer=window.setInterval(function(){base.toSlide('next');},base.options.displayTime);};base.clearTimer=function(){if(base.timer){window.clearInterval(base.timer);};};base.setSliderDimensions=function(){base.wrapContainerWidth=base.$wrapContainer.width();base.sliderWidth=base.wrapContainerWidth*base.slideCount;base.currentSlideWidth=base.$currentSlide.outerWidth();base.currentSlideHeight=base.$currentSlide.outerHeight();base.$slides.width(base.wrapContainerWidth);base.$el.width(base.sliderWidth).css('left',base.$currentSlide.position().left*-1+'px');base.$wrap.width(base.wrapContainerWidth).height(base.currentSlideHeight);};base.toSlide=function(slide){if(slide==='next'||slide===''){base.currentSlideIndex+=1;}else if(slide==='prev'){base.currentSlideIndex-=1;}else{base.currentSlideIndex=slide;}if((base.options.disableLoop=='first'||base.options.disableLoop=='both'&&base.currentSlideIndex<0)||(base.options.disableLoop=='last'||base.options.disableLoop=='both'&&base.currentSlideIndex>base.slideIndexCount)){return;}if(base.currentSlideIndex>base.slideIndexCount){base.currentSlideIndex=0;}else if(base.currentSlideIndex<0){base.currentSlideIndex=base.slideIndexCount;};base.$currentSlide=base.$slides.eq(base.currentSlideIndex);base.currentSlideWidth=base.$currentSlide.width();base.currentSlideHeight=base.$currentSlide.height();if(base.options.beforeSlide&&typeof(base.options.beforeSlide)=='function')base.options.beforeSlide(base);if(base.animating==false){base.animating=true;if(base.options.onSlide&&typeof(base.options.onSlide)=='function')base.options.onSlide(base);if(base.options.sliderType=='slider'){if(base.options.createPagination){base.$sliderControls.find('li').removeClass('current').eq(base.currentSlideIndex).addClass('current');};base.$el.animate({height:base.$currentSlide.outerHeight(),left:base.$currentSlide.position().left*-1+'px'},base.options.speed,base.options.sliderEasing,function(){base.animating=false;if(base.options.afterSlide&&typeof(base.options.afterSlide)=='function')base.options.afterSlide(base);if(base.options.onEnd&&typeof(base.options.onEnd)=='function'&&base.currentSlideIndex==base.slideIndexCount)base.options.onEnd(base);});base.$wrap.animate({height:base.$currentSlide.outerHeight(),width:base.$currentSlide.outerWidth()},base.options.speed,base.options.sliderEasing);base.$slides.removeClass('current').eq(base.currentSlideIndex).addClass('current');}else{if(base.options.createPagination){base.$sliderControls.find('li').removeClass('current').eq(base.currentSlideIndex).addClass('current');};base.$slides.removeClass('current').eq(base.currentSlideIndex).addClass('current').fadeIn(base.options.speed,function(){base.$slides.not('.current').hide();base.animating=false;if(base.options.afterSlide&&typeof(base.options.afterSlide)=='function')base.options.afterSlide(base);if(base.options.onEnd&&typeof(base.options.onEnd)=='function'&&base.currentSlideIndex==base.slideIndexCount)base.options.onEnd(base);});};};if(base.options.autoSlide){base.clearTimer();base.beginTimer();};};if(base.slideCount===1){base.options.autoSlide=false;base.options.createArrows=false;base.options.createPagination=false;};if(base.options.sliderType=='fader')base.options.fullWidth=false;if(base.options.onStart&&typeof(base.options.onStart)=='function')base.options.onStart(base);base.$slides.addClass('child').eq(base.currentSlideIndex).addClass('current');base.setSliderDimensions();if(base.options.width)base.$wrap.width(base.options.width);if(base.options.height)base.$wrap.height(base.options.height);base.currentSlideWidth=base.$currentSlide.outerWidth();base.currentSlideHeight=base.$currentSlide.outerHeight();if(base.options.sliderType=='slider'){base.calculateSliderWidth();base.$wrap.addClass('plustype-slider').find(base.$el).width(base.sliderWidth);if(base.options.fullWidth){base.setSliderDimensions();$(window).resize(function(){base.setSliderDimensions();});};base.$slides.show();base.$el.css('left',base.$currentSlide.position().left*-1+'px');}else{base.$wrap.addClass('plustype-fader');base.$slides.eq(0).show();};if(base.options.createPagination){base.$sliderControls=$('
',{'class':'plusslider-controls'});base.options.paginationBefore?base.$sliderControls.prependTo(base.$wrap):base.$sliderControls.appendTo(base.$wrap);base.$sliderControls.wrap('
');for(var i=0;i<base.slideCount;i++){$('
',{href:'#','data-index':i,text:base.options.paginationTitle?base.$slides.eq(i).attr('data-title'):i+1}).appendTo(base.$sliderControls);};if(base.options.paginationWidth)base.$sliderControls.width(base.$sliderControls.find('li').outerWidth(true)*base.slideCount);base.$sliderControls.find('li').click(function(){var controlIndex=$(this).index();base.toSlide(controlIndex);}).eq(base.currentSlideIndex).addClass('current');};if(base.options.createArrows){$('
',{'class':'plusnav'}).prependTo(base.$wrap);base.$arrows=base.$wrap.find('.plusnav');$('
',{'class':'next',text:base.options.nextText}).prependTo(base.$arrows);$('
',{'class':'prev',text:base.options.prevText}).prependTo(base.$arrows);base.$arrows.find('.next').click(function(){base.toSlide('next');});base.$arrows.find('.prev').click(function(){base.toSlide('prev');});};if(base.options.autoSlide){base.beginTimer();if(base.options.pauseOnHover){base.$el.hover(function(){base.clearTimer();},function(){base.beginTimer();});};};if(base.options.keyboardNavigation){base.$el.click(function(){$('.active-plusslider').removeClass('active-plusslider');$(this).addClass('active-plusslider');});$(window).keyup(function(e){if(base.$el.is('.active-plusslider')){if(e.keyCode==39){base.toSlide('next');}else if(e.keyCode==37){base.toSlide('prev');};};});};};base.init();};$.plusSlider.defaults={sliderType:'slider',disableLoop:false,fullWidth:false,width:null,height:null,defaultSlide:0,displayTime:4000,sliderEasing:'linear',speed:500,autoSlide:true,keyboardNavigation:true,pauseOnHover:true,createArrows:true,nextText:'Next',prevText:'Previous',createPagination:true,paginationBefore:false,paginationWidth:false,paginationTitle:false,onStart:null,beforeSlide:null,onSlide:null,afterSlide:null,onEnd:null};$.fn.plusSlider=function(options){return this.each(function(){(new $.plusSlider(this,options));});};})(jQuery);<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  name: 'ModelFileDAO',
  package: 'node.dao',

  properties: [
    {
      name: 'classpath',
      factory: function() {
        return global.NODE_CLASSPATH ||
            (global.FOAM_BOOT_DIR + '/../js');
      }
    },
    {
      name: 'pending',
      factory: function() { return {}; }
    },
    {
      name: 'preload',
      factory: function() { return {}; }
    }
  ],

  methods: {
    find: function (key, sink) {
      if ( this.preload[key] ) {
        sink && sink.put && sink.put(this.preload[key]);
        delete this.preload[key];
        return;
      }

      var fileName = this.classpath + '/' + key.replace(/\./g, '/') + '.js';

      if ( this.pending[key] ) {
        this.pending[key].push(sink);
        return;
      }

      this.pending[key] = [sink];

      var old = global.__DATACALLBACK;
      try {
        global.__DATACALLBACK = this.onData;
        global.__DATACALLBACK.sourcePath = fileName;
        require(fileName);
      } catch(e) {
        sink && sink.error && sink.error('Error loading model', key, e);
      } finally {
        global.__DATACALLBACK = old;
      }
    }
  },

  listeners: [
    {
      name: 'onData',
      code: function(data, latch) {
        var work = [anop];
        var obj = JSONUtil.mapToObj(this.X, data, undefined, work);

        if ( ! obj ) {
          throw new Error("Failed to decode data: " + data);
        }
        if ( ! this.pending[obj.id] ) {
          if ( latch ) latch(obj);
          else {
            // Workaround for legacy apps that include extra models via
            // additional script tags.
            this.preload[obj.id] = obj;
          }
          return;
        }

        aseq.apply(null, work)(
          function(ret) {
            var sinks = this.pending[obj.id];
            delete this.pending[obj.id];
            for ( var i = 0; i < sinks.length ; i++ ) {
              var sink = sinks[i];
              sink && sink.put && sink.put(obj);
            }
          }.bind(this));
      }
    }
  ]
});
<commit_msg>Throw an error in ModelFileDAO if the loaded file does not contain the required model.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  name: 'ModelFileDAO',
  package: 'node.dao',

  properties: [
    {
      name: 'classpath',
      factory: function() {
        return global.NODE_CLASSPATH ||
            (global.FOAM_BOOT_DIR + '/../js');
      }
    },
    {
      name: 'pending',
      factory: function() { return {}; }
    },
    {
      name: 'preload',
      factory: function() { return {}; }
    }
  ],

  methods: {
    find: function (key, sink) {
      if ( this.preload[key] ) {
        sink && sink.put && sink.put(this.preload[key]);
        delete this.preload[key];
        return;
      }

      var fileName = this.classpath + '/' + key.replace(/\./g, '/') + '.js';

      if ( this.pending[key] ) {
        this.pending[key].push(sink);
        return;
      }

      this.pending[key] = [sink];

      var old = global.__DATACALLBACK;
      try {
        global.__DATACALLBACK = this.onData;
        global.__DATACALLBACK.sourcePath = fileName;
        this.looking_ = key;
        require(fileName);
        if ( this.looking_ ) {
          throw "Model with id: " + key + " not found in " + fileName;
        }
      } catch(e) {
        sink && sink.error && sink.error('Error loading model', key, e);
      } finally {
        global.__DATACALLBACK = old;
      }
    }
  },

  listeners: [
    {
      name: 'onData',
      code: function(data, latch) {
        var work = [anop];
        var obj = JSONUtil.mapToObj(this.X, data, undefined, work);

        if ( ! obj ) {
          throw new Error("Failed to decode data: " + data);
        }

        if ( this.looking_ === obj.id ) {
          this.looking_ = null;
        }

        if ( ! this.pending[obj.id] ) {
          if ( latch ) latch(obj);
          else {
            // Workaround for legacy apps that include extra models via
            // additional script tags.
            this.preload[obj.id] = obj;
          }
          return;
        }

        aseq.apply(null, work)(
          function(ret) {
            var sinks = this.pending[obj.id];
            delete this.pending[obj.id];
            for ( var i = 0; i < sinks.length ; i++ ) {
              var sink = sinks[i];
              sink && sink.put && sink.put(obj);
            }
          }.bind(this));
      }
    }
  ]
});
<|endoftext|>


<commit_before>'use strict';

var React = require('react');
import Autosuggest from 'react-autosuggest';
import Input from 'react-toolbox/lib/input';
var _ = require('../underscore_ext');
var {deepPureRenderMixin} = require('../react-utils');
require('./GeneSuggest.css'); // XXX rename file
var lcs = require('../lcs');

function toLCWords(str) {
	return str.toLowerCase().split(/[ \t]/);
}

function applyBias(bias, x) {
	return x > 0 ? (x - 1) * bias + 1 : 0;
}

// tag and input are ordered lists of words, from strings that have
// been normalized to lower case, and split on whitespace.
//
// We count each word match. We count multiple word matches more
// strongly than a sum of the word matches. We count ordered
// word matches more strongly than multiple word matches

var multiWordBias = 1.5,
	orderBias = 1.7;
function scoreTag(tag, input) {
	var matches =  _.intersection(tag, input),
		wordBiased = applyBias(multiWordBias, matches.length),
		ordered = matches.length > 0 ? lcs(tag, input) : 0;

	return wordBiased * applyBias(orderBias, ordered);
}

function scoreCohorts(cohortMeta, tags, weights) {
	return tags.reduce((cohorts, tag, i) => {
		var w = weights[i];
		if (w > 0) {
			cohortMeta[tag].forEach(cohort =>
				cohorts[cohort] = (cohorts[cohort] || 0) + w);
		}
		return cohorts;
	}, {});
}

// Return list of cohorts ordered by strength of match to input.
function match(cohortMeta, input) { //eslint-disable-line no-unused-vars
	var tags = Object.keys(cohortMeta),
		normInput = toLCWords(input),
		normTags = tags.map(toLCWords),
		weights = normTags.map(t => scoreTag(t, normInput)),
		cohortScores = scoreCohorts(cohortMeta, tags, weights);

	return Object.keys(cohortScores).sort((c, d) => cohortScores[d] - cohortScores[c]);
}

function scoreTag2(tag, input) {
	var matches =  _.intersection(tag, input),
		wordBiased = applyBias(multiWordBias, matches.length),
		ordered = matches.length > 0 ? lcs(tag, input) : 0;

	return {matches: matches.sort(), tag, weight: wordBiased * applyBias(orderBias, ordered)};
}

// For each set of matched input words, pick the highest-scoring match
function scoreCohorts2(cohortMeta, tags, weights) { //eslint-disable-line no-unused-vars
	var byCohort = _.groupBy(_.flatmap(cohortMeta, (cohorts, tag) =>
			cohorts.map(cohort => ({cohort, tag}))), 'cohort'),
		tagWeights = _.object(tags, weights),
		cohortWeights = _.map(byCohort, (cohortTags, cohort) => {
			var cohortTagWeights = _.pick(tagWeights, _.pluck(cohortTags, 'tag')),
				groups = _.map(_.groupBy(cohortTagWeights, 'matches'),
					weights => _.maxWith(weights, (x, y) => x.weight - y.weight)).filter(({weight}) => weight > 0);
			return {cohort, weight: _.sum(_.pluck(groups, 'weight')), groups};
		});
	return _.sortBy(cohortWeights.filter(({weight}) => weight > 0), ({weight}) => -weight);
}

// For each set of matched input words, pick the highest-scoring match,
// scale by number of matches for the set / total tag count for the cohort
function scoreCohorts3(cohortMeta, tags, weights) { //eslint-disable-line no-unused-vars
	var byCohort = _.groupBy(_.flatmap(cohortMeta, (cohorts, tag) =>
			cohorts.map(cohort => ({cohort, tag}))), 'cohort'),
		tagWeights = _.object(tags, weights),
		cohortWeights = _.map(byCohort, (cohortTags, cohort) => {
			var cohortTagWeights = _.pick(tagWeights, _.pluck(cohortTags, 'tag')),
				groups = _.map(_.groupBy(cohortTagWeights, 'matches'),
					weights => _.updateIn(_.maxWith(weights, (x, y) => x.weight - y.weight), ['weight'], w => w * weights.length / cohortTags.length)).filter(({weight}) => weight > 0);
			return {cohort, weight: _.sum(_.pluck(groups, 'weight')), groups};
		});
	return _.sortBy(cohortWeights.filter(({weight}) => weight > 0), ({weight}) => -weight);
}

// XXX
var DEBUG = false;
//var scoreFn = scoreCohorts2;
var scoreFn = scoreCohorts3;
// XXX

function matchSimplified(cohortMeta, input) {
	var tags = Object.keys(cohortMeta),
		normInput = toLCWords(input),
		normTags = tags.map(toLCWords),
		weights = normTags.map(t => scoreTag2(t, normInput));
	return scoreFn(cohortMeta, tags, weights);
}

// match by logical AND, instead of a scoring system
function matchExact(cohortMeta, input) { //eslint-disable-line no-unused-vars
	var tags = Object.keys(cohortMeta),
		normInput = toLCWords(input),
		matches = tags.filter(tag => _.contains(normInput, tag.toLowerCase()));
	return _.intersection(...matches.map(t => cohortMeta[t]));
}

// Return the start and end indices of the word in 'value'
// under the cursor position.
function currentWordPosition(value, position) {
	var li = value.slice(0, position).lastIndexOf(' '),
		i = li === -1 ? 0 : li + 1,
		lj = value.slice(position).indexOf(' '),
		j = lj === -1 ? value.length : position + lj;
	return [i, j];
}

// Return the word in 'value' under the cursor position
function currentWord(value, position) {
	var [i, j] = currentWordPosition(value, position);
	return value.slice(i, j);
}

var renderInputComponent = ({ref, onChange, ...props}) => (
	<Input
		ref={el => ref(el && el.getWrappedInstance().inputNode)}
		onChange={(value, ev) => onChange(ev)}
		label='Primary disease or Tissue of Origin'
		{...props} />);

var DiseaseSuggest = React.createClass({
	mixins: [deepPureRenderMixin],
	onSuggestionsFetchRequested({value}) {
		var position = this.refs.autosuggest.input.selectionStart,
			word = currentWord(value, position),
			lcValue = word.toLowerCase(),
			{cohortMeta} = this.props,
			tags = Object.keys(cohortMeta);
		this.setState({
			suggestions: _.filter(tags, t => t.toLowerCase().indexOf(lcValue) === 0)
		});
	},
	onSuggestionsClearRequested() {
		this.setState({suggestions: []});
	},
	getInitialState() {
		return {suggestions: [], value: ""};
	},
	onChange(ev, {newValue, method}) {
		// Don't update the value for 'up' and 'down' keys. If we do update
		// the value, it gives us an in-place view of the suggestion (pasting
		// the value into the input field), but the drawback is that it moves
		// the cursor to the end of the line. This messes up multi-word input.
		// We could try to preserve the cursor position, perhaps by passing a
		// custom input renderer. But for now, just don't update the value for
		// these events.
		if (method !== 'up' && method !== 'down') {
			this.setState({value: newValue});
		}
	},
	onSelect(ev, {suggestionValue}) {
		this.setState({value: suggestionValue});
	},
	onClear() {
		this.setState({value: ""});
	},
	onCohort(ev) {
		this.props.onSelect(ev.target.value);
	},
	shouldRenderSuggestions(value) {
		var position = this.refs.autosuggest.input.selectionStart,
			word = currentWord(value, position);
		return word.length > 0;
	},
	getSuggestionValue(suggestion) {
		var position = this.refs.autosuggest.input.selectionStart,
			value = this.refs.autosuggest.input.value,
			[i, j] = currentWordPosition(value, position);

		// splice the suggestion into the current word
		return value.slice(0, i) + suggestion + value.slice(j);
	},
	render() {
		var {onChange} = this,
			{suggestions, value} = this.state,
			{cohortMeta, cohort} = this.props,
			results = matchSimplified(cohortMeta, value);

		return (

				<Autosuggest
					ref='autosuggest'
					suggestions={suggestions}
					onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
					onSuggestionsClearRequested={this.onSuggestionsClearRequested}
					onSuggestionSelected={this.onSelect}
					getSuggestionValue={this.getSuggestionValue}
					shouldRenderSuggestions={this.shouldRenderSuggestions}
					renderSuggestion={v => {v}}
					renderInputComponent={renderInputComponent}
					inputProps={{value, onChange}}/>
				<button onClick={this.onClear}>x</button>

					{results.map(({cohort: c, weight, groups}) => (

							<input type='radio' name='cohort' value={c}
								checked={c === cohort}
								onChange={this.onCohort}/>
							{c}
							{weight.toPrecision(2)}
							{groups.map(({tag, weight}) => {tag.join(' ')} {weight.toPrecision(2)})}

))}

);
	}
});

module.exports = DiseaseSuggest;
<commit_msg>Normalize search by sqrt of cohort tags.<commit_after>'use strict';

var React = require('react');
import Autosuggest from 'react-autosuggest';
import Input from 'react-toolbox/lib/input';
var _ = require('../underscore_ext');
var {deepPureRenderMixin} = require('../react-utils');
require('./GeneSuggest.css'); // XXX rename file
var lcs = require('../lcs');

function toLCWords(str) {
	return str.toLowerCase().split(/[ \t]/);
}

function applyBias(bias, x) {
	return x > 0 ? (x - 1) * bias + 1 : 0;
}

// tag and input are ordered lists of words, from strings that have
// been normalized to lower case, and split on whitespace.
//
// We count each word match. We count multiple word matches more
// strongly than a sum of the word matches. We count ordered
// word matches more strongly than multiple word matches

var multiWordBias = 1.5,
	orderBias = 1.7;
function scoreTag(tag, input) {
	var matches =  _.intersection(tag, input),
		wordBiased = applyBias(multiWordBias, matches.length),
		ordered = matches.length > 0 ? lcs(tag, input) : 0;

	return wordBiased * applyBias(orderBias, ordered);
}

function scoreCohorts(cohortMeta, tags, weights) {
	return tags.reduce((cohorts, tag, i) => {
		var w = weights[i];
		if (w > 0) {
			cohortMeta[tag].forEach(cohort =>
				cohorts[cohort] = (cohorts[cohort] || 0) + w);
		}
		return cohorts;
	}, {});
}

// Return list of cohorts ordered by strength of match to input.
function match(cohortMeta, input) { //eslint-disable-line no-unused-vars
	var tags = Object.keys(cohortMeta),
		normInput = toLCWords(input),
		normTags = tags.map(toLCWords),
		weights = normTags.map(t => scoreTag(t, normInput)),
		cohortScores = scoreCohorts(cohortMeta, tags, weights);

	return Object.keys(cohortScores).sort((c, d) => cohortScores[d] - cohortScores[c]);
}

function scoreTag2(tag, input) {
	var matches =  _.intersection(tag, input),
		wordBiased = applyBias(multiWordBias, matches.length),
		ordered = matches.length > 0 ? lcs(tag, input) : 0;

	return {matches: matches.sort(), tag, weight: wordBiased * applyBias(orderBias, ordered)};
}

// For each set of matched input words, pick the highest-scoring match
function scoreCohorts2(cohortMeta, tags, weights) { //eslint-disable-line no-unused-vars
	var byCohort = _.groupBy(_.flatmap(cohortMeta, (cohorts, tag) =>
			cohorts.map(cohort => ({cohort, tag}))), 'cohort'),
		tagWeights = _.object(tags, weights),
		cohortWeights = _.map(byCohort, (cohortTags, cohort) => {
			var cohortTagWeights = _.pick(tagWeights, _.pluck(cohortTags, 'tag')),
				groups = _.map(_.groupBy(cohortTagWeights, 'matches'),
					weights => _.maxWith(weights, (x, y) => x.weight - y.weight)).filter(({weight}) => weight > 0);
			return {cohort, weight: _.sum(_.pluck(groups, 'weight')), groups};
		});
	return _.sortBy(cohortWeights.filter(({weight}) => weight > 0), ({weight}) => -weight);
}

// For each set of matched input words, pick the highest-scoring match,
// scale by number of matches for the set / total tag count for the cohort
function scoreCohorts3(cohortMeta, tags, weights) { //eslint-disable-line no-unused-vars
	var byCohort = _.groupBy(_.flatmap(cohortMeta, (cohorts, tag) =>
			cohorts.map(cohort => ({cohort, tag}))), 'cohort'),
		tagWeights = _.object(tags, weights),
		cohortWeights = _.map(byCohort, (cohortTags, cohort) => {
			var cohortTagWeights = _.pick(tagWeights, _.pluck(cohortTags, 'tag')),
				groups = _.map(_.groupBy(cohortTagWeights, 'matches'),
					weights => _.updateIn(_.maxWith(weights, (x, y) => x.weight - y.weight), ['weight'], w => w * weights.length / Math.sqrt(cohortTags.length))).filter(({weight}) => weight > 0);
			return {cohort, weight: _.sum(_.pluck(groups, 'weight')), groups};
		});
	return _.sortBy(cohortWeights.filter(({weight}) => weight > 0), ({weight}) => -weight);
}

// XXX
var DEBUG = false;
//var scoreFn = scoreCohorts2;
var scoreFn = scoreCohorts3;
// XXX

function matchSimplified(cohortMeta, input) {
	var tags = Object.keys(cohortMeta),
		normInput = toLCWords(input),
		normTags = tags.map(toLCWords),
		weights = normTags.map(t => scoreTag2(t, normInput));
	return scoreFn(cohortMeta, tags, weights);
}

// match by logical AND, instead of a scoring system
function matchExact(cohortMeta, input) { //eslint-disable-line no-unused-vars
	var tags = Object.keys(cohortMeta),
		normInput = toLCWords(input),
		matches = tags.filter(tag => _.contains(normInput, tag.toLowerCase()));
	return _.intersection(...matches.map(t => cohortMeta[t]));
}

// Return the start and end indices of the word in 'value'
// under the cursor position.
function currentWordPosition(value, position) {
	var li = value.slice(0, position).lastIndexOf(' '),
		i = li === -1 ? 0 : li + 1,
		lj = value.slice(position).indexOf(' '),
		j = lj === -1 ? value.length : position + lj;
	return [i, j];
}

// Return the word in 'value' under the cursor position
function currentWord(value, position) {
	var [i, j] = currentWordPosition(value, position);
	return value.slice(i, j);
}

var renderInputComponent = ({ref, onChange, ...props}) => (
	<Input
		ref={el => ref(el && el.getWrappedInstance().inputNode)}
		onChange={(value, ev) => onChange(ev)}
		label='Primary disease or Tissue of Origin'
		{...props} />);

var DiseaseSuggest = React.createClass({
	mixins: [deepPureRenderMixin],
	onSuggestionsFetchRequested({value}) {
		var position = this.refs.autosuggest.input.selectionStart,
			word = currentWord(value, position),
			lcValue = word.toLowerCase(),
			{cohortMeta} = this.props,
			tags = Object.keys(cohortMeta);
		this.setState({
			suggestions: _.filter(tags, t => t.toLowerCase().indexOf(lcValue) === 0)
		});
	},
	onSuggestionsClearRequested() {
		this.setState({suggestions: []});
	},
	getInitialState() {
		return {suggestions: [], value: ""};
	},
	onChange(ev, {newValue, method}) {
		// Don't update the value for 'up' and 'down' keys. If we do update
		// the value, it gives us an in-place view of the suggestion (pasting
		// the value into the input field), but the drawback is that it moves
		// the cursor to the end of the line. This messes up multi-word input.
		// We could try to preserve the cursor position, perhaps by passing a
		// custom input renderer. But for now, just don't update the value for
		// these events.
		if (method !== 'up' && method !== 'down') {
			this.setState({value: newValue});
		}
	},
	onSelect(ev, {suggestionValue}) {
		this.setState({value: suggestionValue});
	},
	onClear() {
		this.setState({value: ""});
	},
	onCohort(ev) {
		this.props.onSelect(ev.target.value);
	},
	shouldRenderSuggestions(value) {
		var position = this.refs.autosuggest.input.selectionStart,
			word = currentWord(value, position);
		return word.length > 0;
	},
	getSuggestionValue(suggestion) {
		var position = this.refs.autosuggest.input.selectionStart,
			value = this.refs.autosuggest.input.value,
			[i, j] = currentWordPosition(value, position);

		// splice the suggestion into the current word
		return value.slice(0, i) + suggestion + value.slice(j);
	},
	render() {
		var {onChange} = this,
			{suggestions, value} = this.state,
			{cohortMeta, cohort} = this.props,
			results = matchSimplified(cohortMeta, value);

		return (

				<Autosuggest
					ref='autosuggest'
					suggestions={suggestions}
					onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
					onSuggestionsClearRequested={this.onSuggestionsClearRequested}
					onSuggestionSelected={this.onSelect}
					getSuggestionValue={this.getSuggestionValue}
					shouldRenderSuggestions={this.shouldRenderSuggestions}
					renderSuggestion={v => {v}}
					renderInputComponent={renderInputComponent}
					inputProps={{value, onChange}}/>
				<button onClick={this.onClear}>x</button>

					{results.map(({cohort: c, weight, groups}) => (

							<input type='radio' name='cohort' value={c}
								checked={c === cohort}
								onChange={this.onCohort}/>
							{c}
							{weight.toPrecision(2)}
							{groups.map(({tag, weight}) => {tag.join(' ')} {weight.toPrecision(2)})}

))}

);
	}
});

module.exports = DiseaseSuggest;
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import { documentToHtmlString } from '@contentful/rich-text-html-renderer';

import Box from 'react/components/UI/Box';
import Text from 'react/components/UI/Text';

import { Headline, Subheadline, Description } from 'react/pages/about/components/Text';
import { GenericButtonLink as Button } from 'react/components/UI/GenericButton';
import { Table, TableSection, Column, LightColumn, ColumnHeader, Cell } from 'react/pages/about/RoadmapPage/components/Table';

const Container = styled(Box).attrs({
  mt: 9,
})``;

const Paragraph = styled(Description).attrs({
  mx: 'auto',
  my: 7,
  align: 'left',
})`
  max-width: 470px;
  width: 100%;
`;

const ContributeButton = styled(Button).attrs({
  f: 5,
  flex: 1,
  alignSelf: 'center',
})`
  background-color: ${x => x.theme.colors.state.supporter};
  border-color: ${x => x.theme.colors.state.supporter};
  color: white;

  &:hover {
    border-color: ${x => x.theme.colors.state.supporter};
    background-color: white;
    color: ${x => x.theme.colors.state.supporter};
  }
`;

export default class RoadmapPage extends PureComponent {
  static propTypes = {
    roadmap: PropTypes.shape.isRequired,
  }

  render() {
    const { roadmap } = this.props;
    const dateOptions = {
      weekday: 'long', year: 'numeric', month: 'long', day: 'numeric',
    };
    const lastUpdated = new Date(roadmap.sys.updatedAt).toLocaleDateString('en-US', dateOptions);

    return (
      <Container pb={10}>
        <Headline color="gray.bold">
          Here's where we're at.
        </Headline>

        <Paragraph>
          Welcome to the Are.na roadmap.
          Here you can see what we’ve shipped recently, what we’re building next,
          and how we’re doing as a company.
        </Paragraph>

        <Paragraph>
          By sharing this information we aim to demystify the weird and wonderful process of
          working on a mostly bootstrapped web company.
          We’re working our hardest to build a space that’s mindful,
          respectful, and accountable to our thousands of lovely members.
          We have lots of ideas for how to do a better job, as well as lots of challenges.
        </Paragraph>

        <Paragraph pb={8}>
          This is meant to be as transparent as reasonably possible.
          If there’s something you don’t see here that you’d like to know,
          just email everyone@are.na.
        </Paragraph>

        <Headline color="gray.bold">
          Become a monthly supporter
        </Headline>

        <Paragraph>
          Chip in a little extra to help Are.na develop new features and reach sustainability.
          Monthly supporters will receive regular emails from the team,
          plus a unique piece of Are.na merch.
        </Paragraph>

        <Box justifyContent="center" mt={7} mb={10} display="flex">


<commit_before>const autoNumericCurrency = {
    digitGroupSeparator: ' ',
    decimalCharacter: ',',
    minimumValue: 0,
    maximumValue: 100000000,
    currencySymbol: ' руб',
    currencySymbolPlacement: 's',
    wheelStep: 10000
}

const autoNumericArea = {
    digitGroupSeparator: ' ',
    decimalCharacter: ',',
    minimumValue: 0,
    maximumValue: 1000,
    currencySymbol: ' м3',
    currencySymbolPlacement: 's',
    wheelStep: 5
}
var isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;

$(document).ready(function() {
  function typeText2TelMobile(element){
    if (Array.isArray(element)){
      element = element.join();
    }
    if (isMobile){
      $(element).attr('type', 'tel');
    }
  };

  /* Mobile friendly manipulations are necessary
   * Because AutoNumeric has no full mobile support
   */
  window.setAutoNumericMobileFriendly = function(element, props){
    typeText2TelMobile(element);
    if ($(element).length==0){
      return;
    }
    return new AutoNumeric(element, props);
  };
  window.setAutoNumericMultipleMobileFriendly = function(elements, props){
    typeText2TelMobile(elements);
    if ($(elements).length==0){
      return;
    }
    return new AutoNumeric.multiple(elements, props);
  };

  var currencies = setAutoNumericMultipleMobileFriendly('.auto-numeric-currency', autoNumericCurrency);
  var areas = setAutoNumericMultipleMobileFriendly('.auto-numeric-area', autoNumericArea);

  autoNumericForm = $('.auto-numeric-currency, .auto-numeric-area').closest("form");
  autoNumericForm.submit(function(e){
    $(this).find('.auto-numeric-currency, .auto-numeric-area').each(function(){
       var self=$(this);
       var v = AutoNumeric.getAutoNumericElement(this).getNumber();
       if (v){
         self.val(v);
       }
   });
  })

  $(".checkbox").click(function(e) {
    $(this).parent(this).parent(this).toggleClass('active-checkbox')
  })

  $('.search_form_select-select').styler();
  window.onload = function() {
    $('.airSticky').airStickyBlock({
      debug: true, // Режим отладки, по умолчанию false
      stopBlock: '.airSticky_stop-block', // Класса контейнера, в котором находится сетка, по умолчанию .airSticky_stop-block
      offsetTop: 100 // отступ сверху
    });
  };

  function classFunction(){
    if($('body').width()<769){ $('.airSticky').removeClass('airSticky')
    }
    else{

    }
  }

  classFunction();
  $(window).resize(classFunction);

$(".toggle-mnu").click(function() {
  $(this).toggleClass("on");
  $(".menu_container").slideToggle();
  return false;
});

    // Custom JS
$('.slider_item').magnificPopup({
  type: 'image',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    mainClass: 'my-mfp-zoom-in',
    gallery:{
    enabled:true,
     }

});

    $('.documents_item').magnificPopup({
    type: 'inline',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    removalDelay: 300,
    mainClass: 'my-mfp-zoom-in',
    focus: '#popup_input'
    });

    $('.callback-link').magnificPopup({
    type: 'inline',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    removalDelay: 300,
    mainClass: 'my-mfp-zoom-in',
    focus: '#popup_input'
    });
    $('.pop_up_plan').magnificPopup({
    type: 'inline',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    removalDelay: 300,
    mainClass: 'my-mfp-zoom-in',
    focus: '#popup_input'
    });

    $('.slider_soc_prog_item').magnificPopup({
    type: 'inline',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    removalDelay: 300,
    mainClass: 'my-mfp-zoom-in',
    focus: '#popup_input'
    });

$('.popup_video').magnificPopup({
  type: 'iframe',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    mainClass: 'my-mfp-zoom-in'

});

});

<commit_msg>Change area unit in Autonumeric to m2 from m3<commit_after>const autoNumericCurrency = {
    digitGroupSeparator: ' ',
    decimalCharacter: ',',
    minimumValue: 0,
    maximumValue: 100000000,
    currencySymbol: ' руб',
    currencySymbolPlacement: 's',
    wheelStep: 10000
}

const autoNumericArea = {
    digitGroupSeparator: ' ',
    decimalCharacter: ',',
    minimumValue: 0,
    maximumValue: 1000,
    currencySymbol: ' м2',
    currencySymbolPlacement: 's',
    wheelStep: 5
}
var isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;

$(document).ready(function() {
  function typeText2TelMobile(element){
    if (Array.isArray(element)){
      element = element.join();
    }
    if (isMobile){
      $(element).attr('type', 'tel');
    }
  };

  /* Mobile friendly manipulations are necessary
   * Because AutoNumeric has no full mobile support
   */
  window.setAutoNumericMobileFriendly = function(element, props){
    typeText2TelMobile(element);
    if ($(element).length==0){
      return;
    }
    return new AutoNumeric(element, props);
  };
  window.setAutoNumericMultipleMobileFriendly = function(elements, props){
    typeText2TelMobile(elements);
    if ($(elements).length==0){
      return;
    }
    return new AutoNumeric.multiple(elements, props);
  };

  var currencies = setAutoNumericMultipleMobileFriendly('.auto-numeric-currency', autoNumericCurrency);
  var areas = setAutoNumericMultipleMobileFriendly('.auto-numeric-area', autoNumericArea);

  autoNumericForm = $('.auto-numeric-currency, .auto-numeric-area').closest("form");
  autoNumericForm.submit(function(e){
    $(this).find('.auto-numeric-currency, .auto-numeric-area').each(function(){
       var self=$(this);
       var v = AutoNumeric.getAutoNumericElement(this).getNumber();
       if (v){
         self.val(v);
       }
   });
  })

  $(".checkbox").click(function(e) {
    $(this).parent(this).parent(this).toggleClass('active-checkbox')
  })

  $('.search_form_select-select').styler();
  window.onload = function() {
    $('.airSticky').airStickyBlock({
      debug: true, // Режим отладки, по умолчанию false
      stopBlock: '.airSticky_stop-block', // Класса контейнера, в котором находится сетка, по умолчанию .airSticky_stop-block
      offsetTop: 100 // отступ сверху
    });
  };

  function classFunction(){
    if($('body').width()<769){ $('.airSticky').removeClass('airSticky')
    }
    else{

    }
  }

  classFunction();
  $(window).resize(classFunction);

$(".toggle-mnu").click(function() {
  $(this).toggleClass("on");
  $(".menu_container").slideToggle();
  return false;
});

    // Custom JS
$('.slider_item').magnificPopup({
  type: 'image',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    mainClass: 'my-mfp-zoom-in',
    gallery:{
    enabled:true,
     }

});

    $('.documents_item').magnificPopup({
    type: 'inline',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    removalDelay: 300,
    mainClass: 'my-mfp-zoom-in',
    focus: '#popup_input'
    });

    $('.callback-link').magnificPopup({
    type: 'inline',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    removalDelay: 300,
    mainClass: 'my-mfp-zoom-in',
    focus: '#popup_input'
    });
    $('.pop_up_plan').magnificPopup({
    type: 'inline',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    removalDelay: 300,
    mainClass: 'my-mfp-zoom-in',
    focus: '#popup_input'
    });

    $('.slider_soc_prog_item').magnificPopup({
    type: 'inline',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    removalDelay: 300,
    mainClass: 'my-mfp-zoom-in',
    focus: '#popup_input'
    });

$('.popup_video').magnificPopup({
  type: 'iframe',
    fixedContentPos: false,
    fixedBgPos: true,
    overflowY: 'auto',
    closeBtnInside: true,
    preloader: false,
    midClick: true,
    mainClass: 'my-mfp-zoom-in'

});

});

<|endoftext|>


<commit_before>const glob = require('glob')
const webpack = require('webpack')
const merge = require('webpack-merge')
const base = require('./webpack.base.config')
const SWPrecachePlugin = require('sw-precache-webpack-plugin')
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')

const config = merge(base, {
  entry: {
    app: './src/entry-client.js'
  },
  resolve: {
    alias: {
      'create-api': './create-api-client.js'
    }
  },
  plugins: [
    // strip dev-only code in Vue source
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
      'process.env.VUE_ENV': '"client"'
    }),
    // extract vendor chunks for better caching
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module) {
        // a module is extracted into the vendor chunk if...
        return (
          // it's inside node_modules
          /node_modules/.test(module.context) &&
          // and not a CSS file (due to extract-text-webpack-plugin limitation)
          !/\.css$/.test(module.request)
        )
      }
    }),
    // extract webpack runtime & manifest to avoid vendor chunk hash changing
    // on every build.
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest'
    }),
    new VueSSRClientPlugin()
  ]
})

if (process.env.NODE_ENV === 'production') {
  config.plugins.push(
    // auto generate service worker
    new SWPrecachePlugin({
      cacheId: 'vue-hn',
      filename: 'service-worker.js',
      dontCacheBustUrlsMatching: /./,
      staticFileGlobsIgnorePatterns: [/\.map$/, /\.json$/],
      runtimeCaching: [
        {
          urlPattern: '/',
          handler: 'networkFirst'
        },
        {
          urlPattern: /\/(top|new|show|ask|jobs)/,
          handler: 'networkFirst'
        },
        {
          urlPattern: '/item/:id',
          handler: 'networkFirst'
        },
        {
          urlPattern: '/user/:id',
          handler: 'networkFirst'
        }
      ]
    })
  )
}

module.exports = config
<commit_msg>add minify: true on SWPrecachePlugin (#198)<commit_after>const glob = require('glob')
const webpack = require('webpack')
const merge = require('webpack-merge')
const base = require('./webpack.base.config')
const SWPrecachePlugin = require('sw-precache-webpack-plugin')
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')

const config = merge(base, {
  entry: {
    app: './src/entry-client.js'
  },
  resolve: {
    alias: {
      'create-api': './create-api-client.js'
    }
  },
  plugins: [
    // strip dev-only code in Vue source
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
      'process.env.VUE_ENV': '"client"'
    }),
    // extract vendor chunks for better caching
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: function (module) {
        // a module is extracted into the vendor chunk if...
        return (
          // it's inside node_modules
          /node_modules/.test(module.context) &&
          // and not a CSS file (due to extract-text-webpack-plugin limitation)
          !/\.css$/.test(module.request)
        )
      }
    }),
    // extract webpack runtime & manifest to avoid vendor chunk hash changing
    // on every build.
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest'
    }),
    new VueSSRClientPlugin()
  ]
})

if (process.env.NODE_ENV === 'production') {
  config.plugins.push(
    // auto generate service worker
    new SWPrecachePlugin({
      cacheId: 'vue-hn',
      filename: 'service-worker.js',
      minify: true,
      dontCacheBustUrlsMatching: /./,
      staticFileGlobsIgnorePatterns: [/\.map$/, /\.json$/],
      runtimeCaching: [
        {
          urlPattern: '/',
          handler: 'networkFirst'
        },
        {
          urlPattern: /\/(top|new|show|ask|jobs)/,
          handler: 'networkFirst'
        },
        {
          urlPattern: '/item/:id',
          handler: 'networkFirst'
        },
        {
          urlPattern: '/user/:id',
          handler: 'networkFirst'
        }
      ]
    })
  )
}

module.exports = config
<|endoftext|>


<commit_before>#!/usr/bin/env node

// maintainer note - update this manually when doing new releases:
var version = '0.26.0'

var fs = require('fs')
var os = require('os')
var path = require('path')
var extract = require('extract-zip')
var download = require('electron-download')

var platform = os.platform()

function onerror (err) {
  throw err
}

var paths = {
  darwin: path.join(__dirname, './dist/Electron.app/Contents/MacOS/Electron'),
  linux: path.join(__dirname, './dist/electron'),
  win32: path.join(__dirname, './dist/electron.exe')
}

if (!paths[platform]) throw new Error('Unknown platform: ' + platform)

// downloads if not cached
download({version: version}, extractFile)

// unzips and makes path.txt point at the correct executable
function extractFile (err, zipPath) {
  if (err) return onerror(err)
  fs.writeFile(path.join(__dirname, 'path.txt'), paths[platform], function (err) {
    if (err) return onerror(err)
    extract(zipPath, {dir: path.join(__dirname, 'dist')}, function (err) {
      if (err) return onerror(err)
    })
  })
}
<commit_msg>- update electron shell to 0.26.1<commit_after>#!/usr/bin/env node

// maintainer note - update this manually when doing new releases:
var version = '0.26.1'

var fs = require('fs')
var os = require('os')
var path = require('path')
var extract = require('extract-zip')
var download = require('electron-download')

var platform = os.platform()

function onerror (err) {
  throw err
}

var paths = {
  darwin: path.join(__dirname, './dist/Electron.app/Contents/MacOS/Electron'),
  linux: path.join(__dirname, './dist/electron'),
  win32: path.join(__dirname, './dist/electron.exe')
}

if (!paths[platform]) throw new Error('Unknown platform: ' + platform)

// downloads if not cached
download({version: version}, extractFile)

// unzips and makes path.txt point at the correct executable
function extractFile (err, zipPath) {
  if (err) return onerror(err)
  fs.writeFile(path.join(__dirname, 'path.txt'), paths[platform], function (err) {
    if (err) return onerror(err)
    extract(zipPath, {dir: path.join(__dirname, 'dist')}, function (err) {
      if (err) return onerror(err)
    })
  })
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

// maintainer note - x.y.z-ab version in package.json -> x.y.z
var version = require('./package').version.replace(/-.*/, '')

var fs = require('fs')
var os = require('os')
var path = require('path')
var extract = require('extract-zip')
var download = require('electron-download')

var installedVersion = null
try {
  installedVersion = fs.readFileSync(path.join(__dirname, 'dist', 'version'), 'utf-8').replace(/^v/, '')
} catch (err) {
  // do nothing
}

var platform = os.platform()

function onerror (err) {
  throw err
}

var paths = {
  darwin: 'dist/Electron.app/Contents/MacOS/Electron',
  freebsd: 'dist/electron',
  linux: 'dist/electron',
  win32: 'dist/electron.exe'
}

if (!paths[platform]) throw new Error('Unknown platform: ' + platform)

if (installedVersion === version && fs.existsSync(path.join(__dirname, paths[platform]))) {
  process.exit(0)
}

// downloads if not cached
download({version: version, arch: process.env.npm_config_arch}, extractFile)

// unzips and makes path.txt point at the correct executable
function extractFile (err, zipPath) {
  if (err) return onerror(err)
  fs.writeFile(path.join(__dirname, 'path.txt'), paths[platform], function (err) {
    if (err) return onerror(err)
    extract(zipPath, {dir: path.join(__dirname, 'dist')}, function (err) {
      if (err) return onerror(err)
    })
  })
}
<commit_msg>Allow specifying StrictSSL in the NPM config file<commit_after>#!/usr/bin/env node

// maintainer note - x.y.z-ab version in package.json -> x.y.z
var version = require('./package').version.replace(/-.*/, '')

var fs = require('fs')
var os = require('os')
var path = require('path')
var extract = require('extract-zip')
var download = require('electron-download')

var installedVersion = null
try {
  installedVersion = fs.readFileSync(path.join(__dirname, 'dist', 'version'), 'utf-8').replace(/^v/, '')
} catch (err) {
  // do nothing
}

var platform = os.platform()

function onerror (err) {
  throw err
}

var paths = {
  darwin: 'dist/Electron.app/Contents/MacOS/Electron',
  freebsd: 'dist/electron',
  linux: 'dist/electron',
  win32: 'dist/electron.exe'
}

if (!paths[platform]) throw new Error('Unknown platform: ' + platform)

if (installedVersion === version && fs.existsSync(path.join(__dirname, paths[platform]))) {
  process.exit(0)
}

// downloads if not cached
download({version: version, arch: process.env.npm_config_arch, strictSSL: process.env.npm_config_strict_ssl}, extractFile)

// unzips and makes path.txt point at the correct executable
function extractFile (err, zipPath) {
  if (err) return onerror(err)
  fs.writeFile(path.join(__dirname, 'path.txt'), paths[platform], function (err) {
    if (err) return onerror(err)
    extract(zipPath, {dir: path.join(__dirname, 'dist')}, function (err) {
      if (err) return onerror(err)
    })
  })
}
<|endoftext|>


<commit_before>'use strict';
var scene, camera, renderer;

var CONSTANTS = Object.freeze({
 INNER_RADIUS: 200,
 OUTER_RADIUS: 300,
 BLOCK_HEIGHT: 50,
 SEGMENT_COUNT: 12,
 LINE_HEIGHT: 50
});

var MATERIALS = Object.freeze({
  RED: new THREE.MeshPhongMaterial({
    color: 0xcc0015,
    emissive: 0x402030,
    side: THREE.DoubleSide,
    shading: THREE.FlatShading
  }),
  BLUE: new THREE.MeshPhongMaterial({
    color: 0x156289,
    emissive: 0x072534,
    side: THREE.DoubleSide,
    shading: THREE.FlatShading
  }),
  GREEN: new THREE.MeshPhongMaterial({
    color: 0x158950,
    emissive: 0x078820,
    side: THREE.DoubleSide,
    shading: THREE.FlatShading
  })
});

var model = {
  blocks: [ // A 2D matrix of CONSTANTS.SEGMENT_COUNT long rows
    [
      undefined,
      undefined,
      {
        material: MATERIALS.RED
      },
      {
        material: MATERIALS.BLUE
      },
      undefined,
      {
        material: MATERIALS.BLUE
      }
    ],
    [
      undefined,
      undefined,
      {
        material: MATERIALS.GREEN
      }
    ]
  ]
};

document.onkeypress = function(event) {
  switch (event.code) {
    case 'KeyW':
      console.warn('ROTATE not implemented');
      break;
    case 'KeyA':
      rotateBoard('left');
      break;
    case 'KeyS':
      console.warn('DROP not implemented');
      break;
    case 'KeyD':
      rotateBoard('right');
      break;
  }
};

var sliceAngle = Math.PI*2 / CONSTANTS.SEGMENT_COUNT;

function rotateBoard(direction) {
  switch (direction) {
    case 'left':
      scene.rotation.z += sliceAngle;
      break;
    case 'right':
      scene.rotation.z -= sliceAngle;
      break;
    default:
      console.error('unknown direction ',direction);
  }
}
//TODO: describe geometry
// 8 points total, 4-4 on outer and inner rectangular face
function constructSliceGeometry(lineIndex, segmentIndex) {
  var points = [];

  var angle1 = sliceAngle * segmentIndex;
  var angle2 = sliceAngle * (segmentIndex + 1);

  var x0_outer = Math.cos(angle1) * CONSTANTS.OUTER_RADIUS;
  var y0_outer = Math.sin(angle1) * CONSTANTS.OUTER_RADIUS;

  var x1_outer = Math.cos(angle2) * CONSTANTS.OUTER_RADIUS;
  var y1_outer = Math.sin(angle2) * CONSTANTS.OUTER_RADIUS;

  var x0_inner = Math.cos(angle1) * CONSTANTS.INNER_RADIUS;
  var y0_inner = Math.sin(angle1) * CONSTANTS.INNER_RADIUS;

  var x1_inner = Math.cos(angle2) * CONSTANTS.INNER_RADIUS;
  var y1_inner = Math.sin(angle2) * CONSTANTS.INNER_RADIUS;

  var z0 = lineIndex*CONSTANTS.LINE_HEIGHT;
  var z1 = (lineIndex+1)*CONSTANTS.LINE_HEIGHT;

  points.push( new THREE.Vector3(x0_outer, y0_outer, z0) );
  points.push( new THREE.Vector3(x1_outer, y1_outer, z0) );
  points.push( new THREE.Vector3(x0_inner, y0_inner, z0) );
  points.push( new THREE.Vector3(x1_inner, y1_inner, z0) );

  points.push( new THREE.Vector3(x0_outer, y0_outer, z1) );
  points.push( new THREE.Vector3(x1_outer, y1_outer, z1) );
  points.push( new THREE.Vector3(x0_inner, y0_inner, z1) );
  points.push( new THREE.Vector3(x1_inner, y1_inner, z1) );

  return new THREE.ConvexGeometry(points);
}

function init() {
  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
  camera.position.z = 1000;

  for(var rowIndex = 0; rowIndex < model.blocks.length; rowIndex++){
    for(var colIndex = 0; colIndex < model.blocks[rowIndex].length; colIndex++){
      var block = model.blocks[rowIndex][colIndex];
      if (block) {
        var geometry = constructSliceGeometry(rowIndex, colIndex);
        var mesh = new THREE.Mesh( geometry, block.material );
        mesh.position.set( 0, 0, 0 );
        scene.add( mesh );
      }
    }
  }

  var lights = [];
  lights[ 0 ] = new THREE.PointLight( 0xffffff );
  lights[ 1 ] = new THREE.PointLight( 0xffffff );
  lights[ 2 ] = new THREE.PointLight( 0xffffff );

  lights[ 0 ].position.set( 0, 500, 0 );
  lights[ 1 ].position.set( 200, 500, 200 );
  lights[ 2 ].position.set( -200, -500, -200 );

  scene.add( lights[ 0 ] );
  scene.add( lights[ 1 ] );
  scene.add( lights[ 2 ] );

  // X red, Y green, Z blue
  scene.add( new THREE.AxisHelper( 150 ) );

  renderer = new THREE.WebGLRenderer();
  renderer.setSize( window.innerWidth, window.innerHeight );

  var orbit = new THREE.OrbitControls( camera, renderer.domElement );
	orbit.enableZoom = false;

  document.getElementById('main-renderer-target').appendChild( renderer.domElement );
}

function animate() {
  requestAnimationFrame( animate );

  scene.rotation.z += 0.001;

  renderer.render( scene, camera );
}

init();
animate();<commit_msg>add single free block and drop mechanic<commit_after>'use strict';
var scene, camera, renderer;

var CONSTANTS = Object.freeze({
 INNER_RADIUS: 200,
 OUTER_RADIUS: 300,
 BLOCK_HEIGHT: 50,
 SEGMENT_COUNT: 12,
 NEW_BLOCK_ROW: 9,
 NEW_BLOCK_COL: 0,
 LINE_HEIGHT: 50
});

function getRandomInt(min, max) { // both ends inclusive
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

var MATERIALS = Object.freeze({
  RED: new THREE.MeshPhongMaterial({
    color: 0xcc0015,
    emissive: 0x402030,
    side: THREE.DoubleSide,
    shading: THREE.FlatShading
  }),
  BLUE: new THREE.MeshPhongMaterial({
    color: 0x156289,
    emissive: 0x072534,
    side: THREE.DoubleSide,
    shading: THREE.FlatShading
  }),
  GREEN: new THREE.MeshPhongMaterial({
    color: 0x158950,
    emissive: 0x078820,
    side: THREE.DoubleSide,
    shading: THREE.FlatShading
  })
});

function getRandomMaterial(){
  var materialKeys = Object.keys(MATERIALS);
  var randomKey = materialKeys[getRandomInt(0,materialKeys.length-1)];
  return MATERIALS[randomKey];
}

var freeBlockPosition = {
  row: CONSTANTS.NEW_BLOCK_ROW,
  col: CONSTANTS.NEW_BLOCK_COL
};

function addNewBlock(){
  var startRow = CONSTANTS.NEW_BLOCK_ROW;
  var startCol = CONSTANTS.NEW_BLOCK_COL;
  var block = {
    material: getRandomMaterial()
  };

  //TODO: assert empty
  model.blocks[startRow][startCol] = block;
  regenerateMeshes();
}

var model = {
  blocks: [ // A 2D matrix of CONSTANTS.SEGMENT_COUNT long rows
    [ // row 0
      undefined,
      undefined,
      {
        material: MATERIALS.RED
      },
      {
        material: MATERIALS.BLUE
      },
      undefined,
      {
        material: MATERIALS.BLUE
      }
    ],
    [ // row 1
      undefined,
      undefined,
      {
        material: MATERIALS.GREEN
      }
    ],
    [], // r2
    [], // r3
    [], // r4
    [], // r5
    [], // r6
    [], // r7
    [], // r8,
    []  // r9
  ]
};

document.onkeypress = function(event) {
  switch (event.code) {
    case 'KeyW':
      console.warn('ROTATE not implemented');
      break;
    case 'KeyA':
      rotateBoard('left');
      break;
    case 'KeyS':
      dropByOne();
      // TODO: add collision detection and merging of freeblock+blocks
      break;
    case 'KeyD':
      rotateBoard('right');
      break;
  }
};

// TODO: clear up board and blocks terminology
function dropByOne() {
  // get block
  var freeBlock = model.blocks[freeBlockPosition.row][freeBlockPosition.col];
  // remove from board
  delete model.blocks[freeBlockPosition.row][freeBlockPosition.col];
  // drop position by one row
  freeBlockPosition.row -= 1;
  // add to model in new position -- TODO: this might be a good place for collision detection
  model.blocks[freeBlockPosition.row][freeBlockPosition.col] = freeBlock;

  regenerateMeshes();
}

var sliceAngle = Math.PI*2 / CONSTANTS.SEGMENT_COUNT;

function rotateBoard(direction) {
  switch (direction) {
    case 'left':
      scene.rotation.z += sliceAngle;
      break;
    case 'right':
      scene.rotation.z -= sliceAngle;
      break;
    default:
      console.error('unknown direction ',direction);
  }
}
//TODO: describe geometry
// 8 points total, 4-4 on outer and inner rectangular face
function constructSliceGeometry(lineIndex, segmentIndex) {
  var points = [];

  var angle1 = sliceAngle * segmentIndex;
  var angle2 = sliceAngle * (segmentIndex + 1);

  var x0_outer = Math.cos(angle1) * CONSTANTS.OUTER_RADIUS;
  var y0_outer = Math.sin(angle1) * CONSTANTS.OUTER_RADIUS;

  var x1_outer = Math.cos(angle2) * CONSTANTS.OUTER_RADIUS;
  var y1_outer = Math.sin(angle2) * CONSTANTS.OUTER_RADIUS;

  var x0_inner = Math.cos(angle1) * CONSTANTS.INNER_RADIUS;
  var y0_inner = Math.sin(angle1) * CONSTANTS.INNER_RADIUS;

  var x1_inner = Math.cos(angle2) * CONSTANTS.INNER_RADIUS;
  var y1_inner = Math.sin(angle2) * CONSTANTS.INNER_RADIUS;

  var z0 = lineIndex*CONSTANTS.LINE_HEIGHT;
  var z1 = (lineIndex+1)*CONSTANTS.LINE_HEIGHT;

  points.push( new THREE.Vector3(x0_outer, y0_outer, z0) );
  points.push( new THREE.Vector3(x1_outer, y1_outer, z0) );
  points.push( new THREE.Vector3(x0_inner, y0_inner, z0) );
  points.push( new THREE.Vector3(x1_inner, y1_inner, z0) );

  points.push( new THREE.Vector3(x0_outer, y0_outer, z1) );
  points.push( new THREE.Vector3(x1_outer, y1_outer, z1) );
  points.push( new THREE.Vector3(x0_inner, y0_inner, z1) );
  points.push( new THREE.Vector3(x1_inner, y1_inner, z1) );

  return new THREE.ConvexGeometry(points);
}

var currentMeshes = [];

// This is far from optimal (we could probably just move the meshes, or only regenerate those that changed), but it'll do for now.
function regenerateMeshes() {
  console.log('regenerating meshes. Current model:',model.blocks);

  currentMeshes.forEach(function(mesh){
    scene.remove(mesh);
  });
  currentMeshes = [];

  for(var rowIndex = 0; rowIndex < model.blocks.length; rowIndex++){
    for(var colIndex = 0; colIndex < model.blocks[rowIndex].length; colIndex++){
      var block = model.blocks[rowIndex][colIndex];
      if (block) {
        console.log('adding mesh at ',rowIndex,colIndex);
        var geometry = constructSliceGeometry(rowIndex, colIndex);
        var mesh = new THREE.Mesh( geometry, block.material );
        mesh.position.set( 0, 0, 0 );
        currentMeshes.push( mesh );
      }
    }
  }

  currentMeshes.forEach(function(mesh){
    scene.add(mesh);
  });
}

function init() { // TODO: extract constants
  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
  camera.position.z = 400;
  camera.position.y = -1000;

  regenerateMeshes();

  var lights = [];
  lights[ 0 ] = new THREE.PointLight( 0xffffff );
  lights[ 1 ] = new THREE.PointLight( 0xffffff );
  lights[ 2 ] = new THREE.PointLight( 0xffffff );

  lights[ 0 ].position.set( 0, 500, 0 );
  lights[ 1 ].position.set( 200, 500, 200 );
  lights[ 2 ].position.set( -200, -500, -200 );

  scene.add( lights[ 0 ] );
  scene.add( lights[ 1 ] );
  scene.add( lights[ 2 ] );

  // X red, Y green, Z blue
  scene.add( new THREE.AxisHelper( 150 ) );

  renderer = new THREE.WebGLRenderer();
  renderer.setSize( window.innerWidth, window.innerHeight );

  var orbit = new THREE.OrbitControls( camera, renderer.domElement );
	orbit.enableZoom = false;

  document.getElementById('main-renderer-target').appendChild( renderer.domElement );
}

function animate() {
  requestAnimationFrame( animate );

  scene.rotation.z += 0.001;

  renderer.render( scene, camera );
}

init();
animate();
addNewBlock();
<|endoftext|>