<commit_before>// Copyright 2020, University of Colorado Boulder

/**
 * Generates JS modules from resources such as images or sounds.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Jonathan Olson (PhET Interactive Simulations)
 */
'use strict';

const _ = require( 'lodash' ); // eslint-disable-line require-statement-match
const createMipmap = require( './createMipmap' );
const fs = require( 'fs' );
const grunt = require( 'grunt' );
const loadFileAsDataURI = require( '../common/loadFileAsDataURI' );
const updateCopyrightForGeneratedFile = require( './updateCopyrightForGeneratedFile' );

// disable lint in compiled files, because it increases the linting time
const HEADER = '/* eslint-disable */';

// supported image types, not case-sensitive
const IMAGE_SUFFIXES = [ '.png', '.jpg', '.cur' ];

/**
 * String replacement
 * @param {string} string - the string which will be searched
 * @param {string} search - the text to be replaced
 * @param {string} replacement - the new text
 * @returns {string}
 */
const replace = ( string, search, replacement ) => string.split( search ).join( replacement );

/**
 * Transform an image file to a JS file that loads the image.
 * @param {string} abspath - the absolute path of the image
 */
const modulifyImage = abspath => {
  const dataURI = loadFileAsDataURI( abspath );

  const contents = `${HEADER}
const img = new Image();
window.phetImages.push( img );
img.src = '${dataURI}';
export default img;
`;

  fs.writeFileSync( convertSuffix( abspath, '.js' ), contents );
};

/**
 * Transform an image file to a JS file that loads the image as a mipmap.
 * @param {string} abspath - the absolute path of the image
 */
const modulifyMipmap = async abspath => {

  // Defaults.  TODO: do we need to support non-defaults?  See https://github.com/phetsims/chipper/issues/820
  // TODO: Or do we need to support mipmaps at all?  See https://github.com/phetsims/chipper/issues/840
  const options = {
    level: 4, // maximum level
    quality: 98
  };

  const mipmaps = await createMipmap( abspath, options.level, options.quality );
  const entry = mipmaps.map( ( { width, height, url } ) => ( { width: width, height: height, url: url } ) );

  const mipmapContents = `${HEADER}
const mipmaps = ${JSON.stringify( entry, null, 2 )};
mipmaps.forEach( mipmap => {
  mipmap.img = new Image();
  window.phetImages.push( mipmap.img ); // make sure it's loaded before the sim launches
  mipmap.img.src = mipmap.url; // trigger the loading of the image for its level
  mipmap.canvas = document.createElement( 'canvas' );
  mipmap.canvas.width = mipmap.width;
  mipmap.canvas.height = mipmap.height;
  const context = mipmap.canvas.getContext( '2d' );
  mipmap.updateCanvas = function() {
    if ( mipmap.img.complete && ( typeof mipmap.img.naturalWidth === 'undefined' || mipmap.img.naturalWidth > 0 ) ) {
      context.drawImage( mipmap.img, 0, 0 );
      delete mipmap.updateCanvas;
    }
  };
} );
export default mipmaps;`;
  fs.writeFileSync( convertSuffix( abspath, '.js' ), mipmapContents );
};

/**
 * Convert .png => _png_mipmap.js, etc.
 * @param {string} abspath - the absolute path
 * @param {string} suffix - the new suffix, such as '.js'
 */
const convertSuffix = ( abspath, suffix ) => {
  const lastDotIndex = abspath.lastIndexOf( '.' );
  return abspath.substring( 0, lastDotIndex ) + '_' + abspath.substring( lastDotIndex + 1 ) + suffix;
};

/**
 * Determines the suffix from a filename, everything after the final '.'
 * @param {string} filename
 */
const getSuffix = filename => {
  const index = filename.lastIndexOf( '.' );
  return filename.substring( index );
};

/**
 * Creates a *.js file corresponding to matching resources such as images or sounds.
 * @param {string} abspath
 * @param {string} rootdir
 * @param {string} subdir
 * @param {string} filename
 */
const modulifyFile = async ( abspath, rootdir, subdir, filename ) => {

  // To the REVIEWER: Should this code be factored out?  Note that one is await and the other is not.  See https://github.com/phetsims/chipper/issues/872
  if ( subdir && ( subdir.startsWith( 'images' ) ||

                   // for brand
                   subdir.startsWith( 'phet/images' ) ||
                   subdir.startsWith( 'phet-io/images' ) ||
                   subdir.startsWith( 'adapted-from-phet/images' ) )
       && IMAGE_SUFFIXES.indexOf( getSuffix( filename ) ) >= 0 ) {
    modulifyImage( abspath );
  }

  if ( subdir && ( subdir.startsWith( 'mipmaps' ) ||

                   // for brand
                   subdir.startsWith( 'phet/mipmaps' ) ||
                   subdir.startsWith( 'phet-io/mipmaps' ) ||
                   subdir.startsWith( 'adapted-from-phet/mipmaps' ) )
       && IMAGE_SUFFIXES.indexOf( getSuffix( filename ) ) >= 0 ) {
    await modulifyMipmap( abspath );
  }

  // TODO: https://github.com/phetsims/chipper/issues/872 factor out duplicates
  if ( subdir && subdir.startsWith( 'sounds' ) ) {

    /**
     * Output supported sound formats.
     * @param {string} soundFileSuffix
     * @param {string} jsFileSuffix
     */
    const mapSounds = ( soundFileSuffix, jsFileSuffix ) => {
      if ( filename.endsWith( soundFileSuffix ) ) {
        const x = loadFileAsDataURI( abspath );

        const contents = `${HEADER}
export default {
  name: '${filename}',
  base64: '${x}'
};`;

        const outputFilename = replace( abspath, soundFileSuffix, jsFileSuffix );
        fs.writeFileSync( outputFilename, contents );
      }
    };

    mapSounds( '.mp3', '_mp3.js' );
    mapSounds( '.wav', '_wav.js' );
  }
};

/**
 * Creates the string module at js/${_.camelCase( repo )}Strings.js for repos that need it.
 * @public
 *
 * @param {string} repo
 */
const createStringModule = async repo => {
  const packageObject = grunt.file.readJSON( `../${repo}/package.json` );
  const stringModuleFile = `../${repo}/js/${_.camelCase( repo )}Strings.js`;
  const namespace = _.camelCase( repo );
  fs.writeFileSync( stringModuleFile, `// Copyright ${new Date().getFullYear()}, University of Colorado Boulder

/**
 * Auto-generated from modulify, DO NOT manually modify.
 */

import getStringModule from '../../chipper/js/getStringModule.js';
import ${namespace} from './${namespace}.js';

const ${namespace}Strings = getStringModule( '${packageObject.phet.requirejsNamespace}' );

${namespace}.register( '${namespace}Strings', ${namespace}Strings );

export default ${namespace}Strings;
` );
  await updateCopyrightForGeneratedFile( repo, stringModuleFile );
};

/**
 * Creates the namespace module at js/${_.camelCase( repo )}.js for repos that need it.
 * @public
 *
 * @param {string} repo
 */
const createNamespaceModule = async repo => {
  const namespace = _.camelCase( repo );
  const namespaceFile = `../${repo}/js/${namespace}.js`;
  fs.writeFileSync( namespaceFile, `// Copyright ${new Date().getFullYear()}, University of Colorado Boulder

/**
 * Creates the namespace for this simulation.
 */

// modules
import Namespace from '../../phet-core/js/Namespace.js';

export default new Namespace( '${namespace}' );
` );
  await updateCopyrightForGeneratedFile( repo, namespaceFile );
};

/**
 * Entry point for modulify, which transforms all of the resources in a repo to *.js files.
 * @parm {string} repo, the name of a repo, such as 'joist'
 */
module.exports = async function( repo ) {
  console.log( `modulifying ${repo}` );
  const relativeFiles = [];
  grunt.file.recurse( `../${repo}`, async ( abspath, rootdir, subdir, filename ) => {
    relativeFiles.push( { abspath: abspath, rootdir: rootdir, subdir: subdir, filename: filename } );
  } );

  for ( let i = 0; i < relativeFiles.length; i++ ) {
    const entry = relativeFiles[ i ];
    await modulifyFile( entry.abspath, entry.rootdir, entry.subdir, entry.filename );
  }

  // Create the namespace file, if it did not already exist
  const packageObject = grunt.file.readJSON( `../${repo}/package.json` );
  if ( fs.existsSync( `../${repo}/${repo}-strings_en.json` ) && packageObject.phet && packageObject.phet.requirejsNamespace ) {
    await createStringModule( repo );

    const namespace = _.camelCase( repo );
    const namespaceFile = `../${repo}/js/${namespace}.js`;
    if ( !fs.existsSync( namespaceFile ) ) {
      await createNamespaceModule( repo );
    }
  }
};<commit_msg>Remove TODOs, see https://github.com/phetsims/chipper/issues/872<commit_after>// Copyright 2020, University of Colorado Boulder

/**
 * Generates JS modules from resources such as images or sounds.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Jonathan Olson (PhET Interactive Simulations)
 */
'use strict';

const _ = require( 'lodash' ); // eslint-disable-line require-statement-match
const createMipmap = require( './createMipmap' );
const fs = require( 'fs' );
const grunt = require( 'grunt' );
const loadFileAsDataURI = require( '../common/loadFileAsDataURI' );
const updateCopyrightForGeneratedFile = require( './updateCopyrightForGeneratedFile' );

// disable lint in compiled files, because it increases the linting time
const HEADER = '/* eslint-disable */';

// supported image types, not case-sensitive
const IMAGE_SUFFIXES = [ '.png', '.jpg', '.cur' ];

/**
 * String replacement
 * @param {string} string - the string which will be searched
 * @param {string} search - the text to be replaced
 * @param {string} replacement - the new text
 * @returns {string}
 */
const replace = ( string, search, replacement ) => string.split( search ).join( replacement );

/**
 * Transform an image file to a JS file that loads the image.
 * @param {string} abspath - the absolute path of the image
 */
const modulifyImage = abspath => {
  const dataURI = loadFileAsDataURI( abspath );

  const contents = `${HEADER}
const img = new Image();
window.phetImages.push( img );
img.src = '${dataURI}';
export default img;
`;

  fs.writeFileSync( convertSuffix( abspath, '.js' ), contents );
};

/**
 * Transform an image file to a JS file that loads the image as a mipmap.
 * @param {string} abspath - the absolute path of the image
 */
const modulifyMipmap = async abspath => {

  // Defaults.  TODO: do we need to support non-defaults?  See https://github.com/phetsims/chipper/issues/820
  // TODO: Or do we need to support mipmaps at all?  See https://github.com/phetsims/chipper/issues/840
  const options = {
    level: 4, // maximum level
    quality: 98
  };

  const mipmaps = await createMipmap( abspath, options.level, options.quality );
  const entry = mipmaps.map( ( { width, height, url } ) => ( { width: width, height: height, url: url } ) );

  const mipmapContents = `${HEADER}
const mipmaps = ${JSON.stringify( entry, null, 2 )};
mipmaps.forEach( mipmap => {
  mipmap.img = new Image();
  window.phetImages.push( mipmap.img ); // make sure it's loaded before the sim launches
  mipmap.img.src = mipmap.url; // trigger the loading of the image for its level
  mipmap.canvas = document.createElement( 'canvas' );
  mipmap.canvas.width = mipmap.width;
  mipmap.canvas.height = mipmap.height;
  const context = mipmap.canvas.getContext( '2d' );
  mipmap.updateCanvas = function() {
    if ( mipmap.img.complete && ( typeof mipmap.img.naturalWidth === 'undefined' || mipmap.img.naturalWidth > 0 ) ) {
      context.drawImage( mipmap.img, 0, 0 );
      delete mipmap.updateCanvas;
    }
  };
} );
export default mipmaps;`;
  fs.writeFileSync( convertSuffix( abspath, '.js' ), mipmapContents );
};

/**
 * Convert .png => _png_mipmap.js, etc.
 * @param {string} abspath - the absolute path
 * @param {string} suffix - the new suffix, such as '.js'
 */
const convertSuffix = ( abspath, suffix ) => {
  const lastDotIndex = abspath.lastIndexOf( '.' );
  return abspath.substring( 0, lastDotIndex ) + '_' + abspath.substring( lastDotIndex + 1 ) + suffix;
};

/**
 * Determines the suffix from a filename, everything after the final '.'
 * @param {string} filename
 */
const getSuffix = filename => {
  const index = filename.lastIndexOf( '.' );
  return filename.substring( index );
};

/**
 * Creates a *.js file corresponding to matching resources such as images or sounds.
 * @param {string} abspath
 * @param {string} rootdir
 * @param {string} subdir
 * @param {string} filename
 */
const modulifyFile = async ( abspath, rootdir, subdir, filename ) => {

  if ( subdir && ( subdir.startsWith( 'images' ) ||

                   // for brand
                   subdir.startsWith( 'phet/images' ) ||
                   subdir.startsWith( 'phet-io/images' ) ||
                   subdir.startsWith( 'adapted-from-phet/images' ) )
       && IMAGE_SUFFIXES.indexOf( getSuffix( filename ) ) >= 0 ) {
    modulifyImage( abspath );
  }

  if ( subdir && ( subdir.startsWith( 'mipmaps' ) ||

                   // for brand
                   subdir.startsWith( 'phet/mipmaps' ) ||
                   subdir.startsWith( 'phet-io/mipmaps' ) ||
                   subdir.startsWith( 'adapted-from-phet/mipmaps' ) )
       && IMAGE_SUFFIXES.indexOf( getSuffix( filename ) ) >= 0 ) {
    await modulifyMipmap( abspath );
  }

  if ( subdir && subdir.startsWith( 'sounds' ) ) {

    /**
     * Output supported sound formats.
     * @param {string} soundFileSuffix
     * @param {string} jsFileSuffix
     */
    const mapSounds = ( soundFileSuffix, jsFileSuffix ) => {
      if ( filename.endsWith( soundFileSuffix ) ) {
        const x = loadFileAsDataURI( abspath );

        const contents = `${HEADER}
export default {
  name: '${filename}',
  base64: '${x}'
};`;

        const outputFilename = replace( abspath, soundFileSuffix, jsFileSuffix );
        fs.writeFileSync( outputFilename, contents );
      }
    };

    mapSounds( '.mp3', '_mp3.js' );
    mapSounds( '.wav', '_wav.js' );
  }
};

/**
 * Creates the string module at js/${_.camelCase( repo )}Strings.js for repos that need it.
 * @public
 *
 * @param {string} repo
 */
const createStringModule = async repo => {
  const packageObject = grunt.file.readJSON( `../${repo}/package.json` );
  const stringModuleFile = `../${repo}/js/${_.camelCase( repo )}Strings.js`;
  const namespace = _.camelCase( repo );
  fs.writeFileSync( stringModuleFile, `// Copyright ${new Date().getFullYear()}, University of Colorado Boulder

/**
 * Auto-generated from modulify, DO NOT manually modify.
 */

import getStringModule from '../../chipper/js/getStringModule.js';
import ${namespace} from './${namespace}.js';

const ${namespace}Strings = getStringModule( '${packageObject.phet.requirejsNamespace}' );

${namespace}.register( '${namespace}Strings', ${namespace}Strings );

export default ${namespace}Strings;
` );
  await updateCopyrightForGeneratedFile( repo, stringModuleFile );
};

/**
 * Creates the namespace module at js/${_.camelCase( repo )}.js for repos that need it.
 * @public
 *
 * @param {string} repo
 */
const createNamespaceModule = async repo => {
  const namespace = _.camelCase( repo );
  const namespaceFile = `../${repo}/js/${namespace}.js`;
  fs.writeFileSync( namespaceFile, `// Copyright ${new Date().getFullYear()}, University of Colorado Boulder

/**
 * Creates the namespace for this simulation.
 */

// modules
import Namespace from '../../phet-core/js/Namespace.js';

export default new Namespace( '${namespace}' );
` );
  await updateCopyrightForGeneratedFile( repo, namespaceFile );
};

/**
 * Entry point for modulify, which transforms all of the resources in a repo to *.js files.
 * @parm {string} repo, the name of a repo, such as 'joist'
 */
module.exports = async function( repo ) {
  console.log( `modulifying ${repo}` );
  const relativeFiles = [];
  grunt.file.recurse( `../${repo}`, async ( abspath, rootdir, subdir, filename ) => {
    relativeFiles.push( { abspath: abspath, rootdir: rootdir, subdir: subdir, filename: filename } );
  } );

  for ( let i = 0; i < relativeFiles.length; i++ ) {
    const entry = relativeFiles[ i ];
    await modulifyFile( entry.abspath, entry.rootdir, entry.subdir, entry.filename );
  }

  // Create the namespace file, if it did not already exist
  const packageObject = grunt.file.readJSON( `../${repo}/package.json` );
  if ( fs.existsSync( `../${repo}/${repo}-strings_en.json` ) && packageObject.phet && packageObject.phet.requirejsNamespace ) {
    await createStringModule( repo );

    const namespace = _.camelCase( repo );
    const namespaceFile = `../${repo}/js/${namespace}.js`;
    if ( !fs.existsSync( namespaceFile ) ) {
      await createNamespaceModule( repo );
    }
  }
};<|endoftext|>


<commit_before>app.directive('ngEnter', function() {
    return function(scope, element, attrs) {
        element.bind("keydown keypress", function(event) {
            if(event.which === 13) {
                scope.$apply(function(){
                    scope.$eval(attrs.ngEnter, {'event': event});
                });

                event.preventDefault();
            }
        });
    };
});

app.directive('scroll', function() {
    return function(scope, element, attrs) {
        var e = element[0];
        scope.$watch(function() {
            console.log('lol');
            e.scrollTop = e.scrollHeight;
        });
    };
});

app.directive('error', function() {
    return function(scope, element, attrs) {

        if(!attrs.ngSrc)
            element.attr("src", attrs.error);

        element.on("error", function() {
            element.attr("src", attrs.error);
        })
    };
});

app.directive("animate", [function() {
    return function (scope, element, attr) {

        var apply = function() {
            element.removeClass("animate");
            if(attr.hasOwnProperty("hide"))
                element.addClass("ng-hide");
        }

        element.on("webkitAnimationEnd oanimationend msAnimationEnd animationend", apply);

        element.on("transitionend webkitTransitionEnd", apply)

        scope.$watch(attr.animate, function(nv, ov) {
            if(!nv) return;
            element.addClass("animate");
        })
    }
}]);

app.directive("raw", [function() {
    return function(scope, element, attr) {
        var cancel = scope.$watch(attr.raw, function(nv) {
            element.html(nv);
        })
    }
}])

app.directive("contactPicture", function() {
    return function(scope, element, attr) {
        var cancel = scope.$watch(attr.contactPicture, function(nv) {
            var contact = scope.contacts[nv];
            if(contact == undefined) return;
            element.attr("src", scope.contacts[nv].picture);
            cancel();
        })
    }
});<commit_msg>Fixed scroll lag<commit_after>app.directive('ngEnter', function() {
    return function(scope, element, attrs) {
        element.bind("keydown keypress", function(event) {
            if(event.which === 13) {
                scope.$apply(function(){
                    scope.$eval(attrs.ngEnter, {'event': event});
                });

                event.preventDefault();
            }
        });
    };
});

app.directive('scroll', ["$timeout", function($timeout) {
    return function(scope, element, attrs) {
        var e = element[0];
        scope.$watch(attrs.scroll, function() {
            console.log('lol');
            $timeout(function() {
                e.scrollTop = e.scrollHeight;
            }, 1);
        });
    };
}]);

app.directive('error', function() {
    return function(scope, element, attrs) {

        if(!attrs.ngSrc)
            element.attr("src", attrs.error);

        element.on("error", function() {
            element.attr("src", attrs.error);
        })
    };
});

app.directive("animate", [function() {
    return function (scope, element, attr) {

        var apply = function() {
            element.removeClass("animate");
            if(attr.hasOwnProperty("hide"))
                element.addClass("ng-hide");
        }

        element.on("webkitAnimationEnd oanimationend msAnimationEnd animationend", apply);

        element.on("transitionend webkitTransitionEnd", apply)

        scope.$watch(attr.animate, function(nv, ov) {
            if(!nv) return;
            element.addClass("animate");
        })
    }
}]);

app.directive("raw", [function() {
    return function(scope, element, attr) {
        var cancel = scope.$watch(attr.raw, function(nv) {
            element.html(nv);
        })
    }
}])

app.directive("contactPicture", function() {
    return function(scope, element, attr) {
        var cancel = scope.$watch(attr.contactPicture, function(nv) {
            var contact = scope.contacts[nv];
            if(contact == undefined) return;
            element.attr("src", scope.contacts[nv].picture);
            cancel();
        })
    }
});<|endoftext|>


<commit_before>;(function()
{
	// Insert page footer element.
	document.write(
		'
'
		+	'
Copyright © 2013-2014 Evothings AB
'
		+ '
')

	// When browsing documentation online we call a script
	// to rewrite links to work with the website layout.
	var protocol = window.location.protocol
	if (protocol != 'file:')
	{
		document.write(
			'<scr'+'ipt type="text/javascript" '
			+	'src="http://www.evothings.com/doc/doc-links.js" ></scr'+'ipt>')
	}
})()
<commit_msg>Updated a comment.<commit_after>;(function()
{
	// Insert page footer element.
	document.write(
		'
'
		+	'
Copyright © 2013-2014 Evothings AB
'
		+ '
')

	// When browsing documentation online we call this script to
	// to rewrite links to work inside an iframe (currently an iframe
	// is not used, this is kept just in case, the logic that detects
	// the iframe is in doc-links.js).
	var protocol = window.location.protocol
	if (protocol != 'file:')
	{
		document.write(
			'<scr'+'ipt type="text/javascript" '
			+	'src="http://www.evothings.com/doc/doc-links.js" ></scr'+'ipt>')
	}
})()
<|endoftext|>


<commit_before>$(window).scroll(function() {
    // get current scroll top in px, add window height and
    // check if this is greater than the document height minus 300
    if ($(window).scrollTop() + $(window).height() >= $(document).height() - 300) {
        loadMoreContent();
	masonry_gallery();
    }
});

function loadMoreContent() {
    // there should be a button, which leads to next posts
    var next = $("a.next").first();
    var paginationnav = $("div.paginationnav").first();
    next.each(function(key, value) {
        var url = $(value).attr('href');
        // remove paginationnav, so we can't load multiple times
        next.remove();
        // adding a temp. dom object to load the next page
        var list = $("

");
        // call load method and get the div.post-list node
        list.load(url + " div.post-list", function(response, status, xhr) {
            // check if we doesn't get any error
            if ( status != "error" ) {
                // copy all childrens of our temp container to the real container
                // note: jQuery load will copy the div.post-list node as well,
                // so use the childrens and move them
                var container = $("div.post-list");
                list.children("div.post-list").children().each(
                    function(key, value){
                        container.append(value);
                    }
                );
            }
        });
	paginationnav.load(url + " div.paginationnav");
    });

}

/* ********* WINDOW LOAD ********** */
$(window).load(function() {
    masonry_actu()
    var paginationnav = $("div.paginationnav").first();
    paginationnav.hide();
});

function masonry_actu()
{

  function masonryBlocks(){
  $(function(){
      var $masonry_actu = $('.actu.masonry-actu.post-list').first();
      if ( $masonry_actu.length > 0 ) {
	$masonry_actu.isotope({
	  itemSelector: '.actu-item',
	  masonry: {
	    columnWidth: 2
	  }
	});
      }
    });
  }

}
<commit_msg>fix js call<commit_after>$(window).scroll(function() {
    // get current scroll top in px, add window height and
    // check if this is greater than the document height minus 300
    if ($(window).scrollTop() + $(window).height() >= $(document).height() - 300) {
        loadMoreContent();
	masonry_actu();
    }
});

function loadMoreContent() {
    // there should be a button, which leads to next posts
    var next = $("a.next").first();
    var paginationnav = $("div.paginationnav").first();
    next.each(function(key, value) {
        var url = $(value).attr('href');
        // remove paginationnav, so we can't load multiple times
        next.remove();
        // adding a temp. dom object to load the next page
        var list = $("

");
        // call load method and get the div.post-list node
        list.load(url + " div.post-list", function(response, status, xhr) {
            // check if we doesn't get any error
            if ( status != "error" ) {
                // copy all childrens of our temp container to the real container
                // note: jQuery load will copy the div.post-list node as well,
                // so use the childrens and move them
                var container = $("div.post-list");
                list.children("div.post-list").children().each(
                    function(key, value){
                        container.append(value);
                    }
                );
            }
        });
	paginationnav.load(url + " div.paginationnav");
    });

}

/* ********* WINDOW LOAD ********** */
$(window).load(function() {
    masonry_actu();
    var paginationnav = $("div.paginationnav").first();
    paginationnav.hide();
});

function masonry_actu()
{

  function masonryBlocks(){
  $(function(){
      var $masonry_actu = $('.actu.masonry-actu.post-list').first();
      if ( $masonry_actu.length > 0 ) {
	$masonry_actu.isotope({
	  itemSelector: '.actu-item',
	  masonry: {
	    columnWidth: 2
	  }
	});
      }
    });
  }

}
<|endoftext|>


<commit_before><commit_msg>Event propogation halted before 'event' constant is reasigned<commit_after><|endoftext|>


<commit_before>/*
 * jquery.spinner
 * https://github.com/vsn4ik/jquery.spinner
 * Copyright Vasilii A., 2015–2018
 * Copyright xixilive, 2013–2015
 * Licensed under the MIT license
 */

'use strict';

(function(factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module
    define(['jquery'], factory);
  } else if (typeof exports === 'object') {
    // Node/CommonJS
    module.exports = factory(require('jquery'));
  } else {
    // Browser globals
    factory(jQuery);
  }
})(function($) {
  var spinningTimer;
  var Spinner;
  var Spinning = function($element, options) {
    this.$el = $element;
    this.options = $.extend({}, Spinning.rules.defaults, Spinning.rules[options.rule] || {}, options);
    this.min = Number(this.options.min) || 0;
    this.max = Number(this.options.max) || 0;

    this.$el.on({
      'focus.spinner': $.proxy(function(e) {
        e.preventDefault();
        $(document).trigger('mouseup.spinner');
        this.oldValue = this.value();
      }, this),
      'change.spinner': $.proxy(function(e) {
        e.preventDefault();
        this.value(this.$el.val());
      }, this),
      'keydown.spinner': $.proxy(function(e) {
        var dir = {
          38: 'up',
          40: 'down'
        }[e.which];

        if (dir) {
          e.preventDefault();
          this.spin(dir);
        }
      }, this)
    });

    //init input value
    this.oldValue = this.value();
    this.value(this.$el.val());
    return this;
  };

  Spinning.rules = {
    defaults: { min: null, max: null, step: 1, precision: 0 },
    currency: { min: 0.00, max: null, step: 0.01, precision: 2 },
    quantity: { min: 1, max: 999, step: 1, precision: 0 },
    percent:  { min: 1, max: 100, step: 1, precision: 0 },
    month:    { min: 1, max: 12, step: 1, precision: 0 },
    day:      { min: 1, max: 31, step: 1, precision: 0 },
    hour:     { min: 0, max: 23, step: 1, precision: 0 },
    minute:   { min: 1, max: 59, step: 1, precision: 0 },
    second:   { min: 1, max: 59, step: 1, precision: 0 }
  };

  Spinning.prototype = {
    spin: function(dir) {
      if (this.$el.prop('disabled')) {
        return;
      }

      this.oldValue = this.value();
      var step = $.isFunction(this.options.step) ? this.options.step.call(this, dir) : this.options.step;
      var multipler = dir === 'up' ? 1 : -1;

      this.value(this.oldValue + Number(step) * multipler);
    },

    value: function(v) {
      if (v === null || v === undefined) {
        return this.numeric(this.$el.val());
      }
      v = this.numeric(v);

      var valid = this.validate(v);
      if (valid !== 0) {
        v = (valid === -1) ? this.min : this.max;
      }
      this.$el.val(v.toFixed(this.options.precision));

      if (this.oldValue !== this.value()) {
        // changing.spinner
        this.$el.trigger('changing.spinner', [this.value(), this.oldValue]);

        // lazy changed.spinner
        clearTimeout(spinningTimer);
        spinningTimer = setTimeout($.proxy(function() {
          this.$el.trigger('changed.spinner', [this.value(), this.oldValue]);
        }, this), Spinner.delay);
      }
    },

    numeric: function(v) {
      v = this.options.precision > 0 ? parseFloat(v, 10) : parseInt(v, 10);

      // If the variable is a number
      if (isFinite(v)) {
        return v;
      }

      return v || this.options.min || 0;
    },

    validate: function(val) {
      if (this.options.min !== null && val < this.min) {
        return -1;
      }

      if (this.options.max !== null && val > this.max) {
        return 1;
      }

      return 0;
    }
  };

  Spinner = function(element, options) {
    this.$el = $(element);
    this.$spinning = this.$el.find('[data-spin="spinner"]');

    if (this.$spinning.length === 0) {
      this.$spinning = this.$el.find(':input[type="text"]');
    }

    options = $.extend({}, options, this.$spinning.data());

    this.spinning = new Spinning(this.$spinning, options);

    this.$el
      .on('click.spinner', '[data-spin="up"], [data-spin="down"]', $.proxy(this, 'spin'))
      .on('mousedown.spinner', '[data-spin="up"], [data-spin="down"]', $.proxy(this, 'spin'));

    $(document).on('mouseup.spinner', $.proxy(function() {
      clearTimeout(this.spinTimeout);
      clearInterval(this.spinInterval);
    }, this));

    if (options.delay) {
      this.delay(options.delay);
    }

    if (options.changed) {
      this.changed(options.changed);
    }

    if (options.changing) {
      this.changing(options.changing);
    }
  };

  Spinner.delay = 500;

  Spinner.prototype = {
    constructor: Spinner,

    spin: function(e) {
      var dir = $(e.currentTarget).data('spin');

      switch (e.type) {
        case 'click':
          e.preventDefault();
          this.spinning.spin(dir);
          break;
        case 'mousedown':
          if (e.which === 1) {
            this.spinTimeout = setTimeout($.proxy(this, 'beginSpin', dir), 300);
          }
          break;
      }
    },

    delay: function(ms) {
      var delay = Number(ms);

      if (delay >= 0) {
        this.constructor.delay = delay + 100;
      }
    },

    value: function() {
      return this.spinning.value();
    },

    changed: function(fn) {
      this.bindHandler('changed.spinner', fn);
    },

    changing: function(fn) {
      this.bindHandler('changing.spinner', fn);
    },

    bindHandler: function(t, fn) {
      if ($.isFunction(fn)) {
        this.$spinning.on(t, fn);
      } else {
        this.$spinning.off(t);
      }
    },

    beginSpin: function(dir) {
      this.spinInterval = setInterval($.proxy(this.spinning, 'spin', dir), 100);
    }
  };

  var old = $.fn.spinner;

  $.fn.spinner = function(options, value) {
    return this.each(function() {
      var data = $.data(this, 'spinner');

      if (!data) {
        data = new Spinner(this, options);

        $.data(this, 'spinner', data);
      }
      if (options === 'delay' || options === 'changed' || options === 'changing') {
        data[options](value);
      } else if (options === 'step' && value) {
        data.spinning.step = value;
      } else if (options === 'spin' && value) {
        data.spinning.spin(value);
      }
    });
  };

  $.fn.spinner.Constructor = Spinner;
  $.fn.spinner.noConflict = function() {
    $.fn.spinner = old;
    return this;
  };

  $(function() {
    $('[data-trigger="spinner"]').spinner();
  });

  return $.fn.spinner;
});
<commit_msg>Moved spinningTimer to Spinning scope instead of global (shared) scope<commit_after>/*
 * jquery.spinner
 * https://github.com/vsn4ik/jquery.spinner
 * Copyright Vasilii A., 2015–2018
 * Copyright xixilive, 2013–2015
 * Licensed under the MIT license
 */

'use strict';

(function(factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module
    define(['jquery'], factory);
  } else if (typeof exports === 'object') {
    // Node/CommonJS
    module.exports = factory(require('jquery'));
  } else {
    // Browser globals
    factory(jQuery);
  }
})(function($) {
  var Spinner;
  var Spinning = function($element, options) {
    this.$el = $element;
    this.options = $.extend({}, Spinning.rules.defaults, Spinning.rules[options.rule] || {}, options);
    this.min = Number(this.options.min) || 0;
    this.max = Number(this.options.max) || 0;
    this.spinningTimer = null;

    this.$el.on({
      'focus.spinner': $.proxy(function(e) {
        e.preventDefault();
        $(document).trigger('mouseup.spinner');
        this.oldValue = this.value();
      }, this),
      'change.spinner': $.proxy(function(e) {
        e.preventDefault();
        this.value(this.$el.val());
      }, this),
      'keydown.spinner': $.proxy(function(e) {
        var dir = {
          38: 'up',
          40: 'down'
        }[e.which];

        if (dir) {
          e.preventDefault();
          this.spin(dir);
        }
      }, this)
    });

    //init input value
    this.oldValue = this.value();
    this.value(this.$el.val());
    return this;
  };

  Spinning.rules = {
    defaults: { min: null, max: null, step: 1, precision: 0 },
    currency: { min: 0.00, max: null, step: 0.01, precision: 2 },
    quantity: { min: 1, max: 999, step: 1, precision: 0 },
    percent:  { min: 1, max: 100, step: 1, precision: 0 },
    month:    { min: 1, max: 12, step: 1, precision: 0 },
    day:      { min: 1, max: 31, step: 1, precision: 0 },
    hour:     { min: 0, max: 23, step: 1, precision: 0 },
    minute:   { min: 1, max: 59, step: 1, precision: 0 },
    second:   { min: 1, max: 59, step: 1, precision: 0 }
  };

  Spinning.prototype = {
    spin: function(dir) {
      if (this.$el.prop('disabled')) {
        return;
      }

      this.oldValue = this.value();
      var step = $.isFunction(this.options.step) ? this.options.step.call(this, dir) : this.options.step;
      var multipler = dir === 'up' ? 1 : -1;

      this.value(this.oldValue + Number(step) * multipler);
    },

    value: function(v) {
      if (v === null || v === undefined) {
        return this.numeric(this.$el.val());
      }
      v = this.numeric(v);

      var valid = this.validate(v);
      if (valid !== 0) {
        v = (valid === -1) ? this.min : this.max;
      }
      this.$el.val(v.toFixed(this.options.precision));

      if (this.oldValue !== this.value()) {
        // changing.spinner
        this.$el.trigger('changing.spinner', [this.value(), this.oldValue]);

        // lazy changed.spinner
        clearTimeout(this.spinningTimer);
        this.spinningTimer = setTimeout($.proxy(function() {
          this.$el.trigger('changed.spinner', [this.value(), this.oldValue]);
        }, this), Spinner.delay);
      }
    },

    numeric: function(v) {
      v = this.options.precision > 0 ? parseFloat(v, 10) : parseInt(v, 10);

      // If the variable is a number
      if (isFinite(v)) {
        return v;
      }

      return v || this.options.min || 0;
    },

    validate: function(val) {
      if (this.options.min !== null && val < this.min) {
        return -1;
      }

      if (this.options.max !== null && val > this.max) {
        return 1;
      }

      return 0;
    }
  };

  Spinner = function(element, options) {
    this.$el = $(element);
    this.$spinning = this.$el.find('[data-spin="spinner"]');

    if (this.$spinning.length === 0) {
      this.$spinning = this.$el.find(':input[type="text"]');
    }

    options = $.extend({}, options, this.$spinning.data());

    this.spinning = new Spinning(this.$spinning, options);

    this.$el
      .on('click.spinner', '[data-spin="up"], [data-spin="down"]', $.proxy(this, 'spin'))
      .on('mousedown.spinner', '[data-spin="up"], [data-spin="down"]', $.proxy(this, 'spin'));

    $(document).on('mouseup.spinner', $.proxy(function() {
      clearTimeout(this.spinTimeout);
      clearInterval(this.spinInterval);
    }, this));

    if (options.delay) {
      this.delay(options.delay);
    }

    if (options.changed) {
      this.changed(options.changed);
    }

    if (options.changing) {
      this.changing(options.changing);
    }
  };

  Spinner.delay = 500;

  Spinner.prototype = {
    constructor: Spinner,

    spin: function(e) {
      var dir = $(e.currentTarget).data('spin');

      switch (e.type) {
        case 'click':
          e.preventDefault();
          this.spinning.spin(dir);
          break;
        case 'mousedown':
          if (e.which === 1) {
            this.spinTimeout = setTimeout($.proxy(this, 'beginSpin', dir), 300);
          }
          break;
      }
    },

    delay: function(ms) {
      var delay = Number(ms);

      if (delay >= 0) {
        this.constructor.delay = delay + 100;
      }
    },

    value: function() {
      return this.spinning.value();
    },

    changed: function(fn) {
      this.bindHandler('changed.spinner', fn);
    },

    changing: function(fn) {
      this.bindHandler('changing.spinner', fn);
    },

    bindHandler: function(t, fn) {
      if ($.isFunction(fn)) {
        this.$spinning.on(t, fn);
      } else {
        this.$spinning.off(t);
      }
    },

    beginSpin: function(dir) {
      this.spinInterval = setInterval($.proxy(this.spinning, 'spin', dir), 100);
    }
  };

  var old = $.fn.spinner;

  $.fn.spinner = function(options, value) {
    return this.each(function() {
      var data = $.data(this, 'spinner');

      if (!data) {
        data = new Spinner(this, options);

        $.data(this, 'spinner', data);
      }
      if (options === 'delay' || options === 'changed' || options === 'changing') {
        data[options](value);
      } else if (options === 'step' && value) {
        data.spinning.step = value;
      } else if (options === 'spin' && value) {
        data.spinning.spin(value);
      }
    });
  };

  $.fn.spinner.Constructor = Spinner;
  $.fn.spinner.noConflict = function() {
    $.fn.spinner = old;
    return this;
  };

  $(function() {
    $('[data-trigger="spinner"]').spinner();
  });

  return $.fn.spinner;
});
<|endoftext|>


<commit_before>'use strict';

angular
  .module('fireideaz')

  .controller('MainCtrl', ['$scope', '$filter', '$window', 'Utils', 'Auth',
  '$rootScope', 'FirebaseService', 'ModalService', 'VoteService',
    function ($scope, $filter, $window, utils, auth, $rootScope, firebaseService, modalService, voteService) {
      $scope.loading = true;
      $scope.messageTypes = utils.messageTypes;
      $scope.utils = utils;
      $scope.newBoard = {
        name: ''
      };
      $scope.userId = $window.location.hash.substring(1) || '';
      $scope.sortField = '$id';
      $scope.selectedType = 1;
      $scope.import = {
        data : [],
        mapping : []
      };

      $scope.closeAllModals = function(){
        modalService.closeAll();
      };

      $scope.getNumberOfVotesOnMessage = function(userId, messageId) {
        return new Array(voteService.returnNumberOfVotesOnMessage(userId, messageId));
      };

      $scope.droppedEvent = function(dragEl, dropEl) {
        var drag = $('#' + dragEl);
        var drop = $('#' + dropEl);
        var dragMessageRef = firebaseService.getMessageRef($scope.userId, drag.attr('messageId'));

        dragMessageRef.once('value', function() {
          dragMessageRef.update({
            type: {
              id: drop.data('column-id')
            }
          });
        });
      };

      function getBoardAndMessages(userData) {
        $scope.userId = $window.location.hash.substring(1) || '499sm';

        var messagesRef = firebaseService.getMessagesRef($scope.userId);
        var board = firebaseService.getBoardRef($scope.userId);

        board.on('value', function(board) {
          $scope.board = board.val();
          $scope.maxVotes = board.val().max_votes ? board.val().max_votes : 6;
          $scope.boardId = $rootScope.boardId = board.val().boardId;
          $scope.boardContext = $rootScope.boardContext = board.val().boardContext;
        });

        $scope.boardRef = board;
        $scope.messagesRef = messagesRef;
        $scope.userUid = userData.uid;
        $scope.messages = firebaseService.newFirebaseArray(messagesRef);
        $scope.loading = false;
      }

      if ($scope.userId !== '') {
        auth.logUser($scope.userId, getBoardAndMessages);
      } else {
        $scope.loading = false;
      }

      $scope.isColumnSelected = function(type) {
        return parseInt($scope.selectedType) === parseInt(type);
      };

      $scope.getSortOrder = function() {
        return $scope.sortField === 'votes' ? true : false;
      };

      $scope.saveMessage = function(message) {
        message.creating = false;
        $scope.messages.$save(message);
      };

      $scope.vote = function(messageKey, votes) {
        if(voteService.isAbleToVote($scope.userId, $scope.maxVotes, $scope.messages)) {
          $scope.messagesRef.child(messageKey).update({
            votes: votes + 1,
            date: firebaseService.getServerTimestamp()
          });

          voteService.increaseMessageVotes($scope.userId, messageKey);
        }
      };

      $scope.unvote = function(messageKey, votes) {
        if(voteService.canUnvoteMessage($scope.userId, messageKey)) {
          var newVotes = (votes >= 1) ? votes - 1 : 0;

          $scope.messagesRef.child(messageKey).update({
            votes: newVotes,
            date: firebaseService.getServerTimestamp()
          });

          voteService.decreaseMessageVotes($scope.userId, messageKey);
        }
      };

      function redirectToBoard() {
        window.location.href = window.location.origin +
          window.location.pathname + '#' + $scope.userId;
      }

      $scope.isBoardNameInvalid = function() {
        return !$scope.newBoard.name;
      };

      $scope.createNewBoard = function() {
        $scope.loading = true;
        modalService.closeAll();
        $scope.userId = utils.createUserId();

        var callback = function(userData) {
          var board = firebaseService.getBoardRef($scope.userId);
          board.set({
            boardId: $scope.newBoard.name,
            date_created: new Date().toString(),
            columns: $scope.messageTypes,
            user_id: userData.uid,
            max_votes: $scope.newBoard.max_votes || 6
          }, function(error) {
             if (error) {
                $scope.loading = false;
             } else {
                redirectToBoard();
             }
          });

          $scope.newBoard.name = '';
        };

        auth.createUserAndLog($scope.userId, callback);
      };

      $scope.changeBoardContext = function() {
        $scope.boardRef.update({
          boardContext: $scope.boardContext
        });
      };

      $scope.changeBoardName = function(newBoardName) {
        $scope.boardRef.update({
          boardId: newBoardName
        });
        modalService.closeAll();
      };

      $scope.addNewColumn = function(name) {
        $scope.board.columns.push({
          value: name,
          id: utils.getNextId($scope.board)
        });

        var boardColumns = firebaseService.getBoardColumns($scope.userId);
        boardColumns.set(utils.toObject($scope.board.columns));

        modalService.closeAll();
      };

      $scope.changeColumnName = function(id, newName) {
        $scope.board.columns[id - 1] = {
          value: newName,
          id: id
        };

        var boardColumns = firebaseService.getBoardColumns($scope.userId);
        boardColumns.set(utils.toObject($scope.board.columns));

        modalService.closeAll();
      };

      $scope.deleteColumn = function(column) {
        $scope.board.columns = $scope.board.columns.filter(function(_column) {
            return _column.id !== column.id;
        });

        var boardColumns = firebaseService.getBoardColumns($scope.userId);
        boardColumns.set(utils.toObject($scope.board.columns));
        modalService.closeAll();
      };

      $scope.deleteMessage = function(message) {
        $scope.messages.$remove(message);
        modalService.closeAll();
      };

      function addMessageCallback(message) {
        var id = message.key;
        angular.element($('#' + id)).scope().isEditing = true;
        $('#' + id).find('textarea').focus();
      }

      $scope.addNewMessage = function(type) {
        $scope.messages.$add({
          text: '',
          creating: true,
          user_id: $scope.userUid,
          type: {
            id: type.id
          },
          date: firebaseService.getServerTimestamp(),
          votes: 0
        }).then(addMessageCallback);
      };

      $scope.deleteCards = function() {
        $($scope.messages).each(function(index, message) {
          $scope.messages.$remove(message);
        });

        modalService.closeAll();
      };

      $scope.getBoardText = function() {
        if ($scope.board) {
          var clipboard = '';

          $($scope.board.columns).each(function(index, column) {
            if (index === 0) {
              clipboard += '' + column.value + '
';
            } else {
              clipboard += '
' + column.value + '
';
            }
            var filteredArray = $filter('orderBy')($scope.messages,
              $scope.sortField,
              $scope.getSortOrder());

            $(filteredArray).each(function(index2, message) {
              if (message.type.id === column.id) {
                clipboard += '- ' + message.text + ' (' + message.votes + ' votes)
';
              }
            });
          });

          return clipboard;
        } else return '';
      };

      $scope.submitImportFile = function (file) {
        $scope.cleanImportData ();
        if (file) {
          if (file.size === 0){
            $scope.import.error = 'The file you are trying to import seems to be  empty';
            return;
          }
          /* globals Papa */
          Papa.parse(file, {
            complete: function(results) {
              if (results.data.length > 0){
                $scope.import.data = results.data;
                $scope.board.columns.forEach (function (column){
                  $scope.import.mapping.push({mapFrom:'-1', mapTo:column.id, name: column.value});
                });
                if (results.errors.length > 0)
                   $scope.import.error = results.errors[0].message;
                $scope.$apply();
              }
            }
          });
        }
      };

       $scope.importMessages = function (){
         var data = $scope.import.data;
         var mapping = $scope.import.mapping;
         for (var importIndex = 1; importIndex < data.length; importIndex++ )
         {
           for (var mappingIndex = 0; mappingIndex < mapping.length; mappingIndex++)
           {
             var mapFrom = mapping[mappingIndex].mapFrom;
             var mapTo = mapping[mappingIndex].mapTo;
             if (mapFrom === -1)
              continue;

             var cardText = data[importIndex][mapFrom];
             if (cardText)
             {
                $scope.messages.$add({
                text: cardText,
                user_id: $scope.userUid,
                type: {
                  id: mapTo
                },
                date: firebaseService.getServerTimestamp(),
                votes: 0});
             }
           }
         }
         $scope.closeAllModals();
       };

      $scope.cleanImportData = function (){
        $scope.import.data = [];
        $scope.import.mapping = [];
        $scope.import.error = '';
      };

      $scope.submitOnEnter = function(event, method, data){
        if (event.keyCode === 13) {
          switch (method){
            case 'createNewBoard':
                if (!$scope.isBoardNameInvalid()) {
                  $scope.createNewBoard();
                }
                break;
            case 'addNewColumn':
                if (data) {
                  $scope.addNewColumn(data);
                  $scope.newColumn = '';
                }
                break;
          }
        }
      };

      $scope.incrementMaxVotes = function() {
        $scope.boardRef.update({
          max_votes: $scope.maxVotes + 1
        });
      };

      $scope.decrementMaxVotes = function() {
        $scope.boardRef.update({
          max_votes: Math.min(Math.max($scope.maxVotes - 1, 1), 100)
        });
      };

      angular.element($window).bind('hashchange', function() {
        $scope.loading = true;
        $scope.userId = $window.location.hash.substring(1) || '';
        auth.logUser($scope.userId, getBoardAndMessages);
      });
    }
  ]);
<commit_msg>[#179] redirect to homepage if board is null<commit_after>'use strict';

angular
  .module('fireideaz')

  .controller('MainCtrl', ['$scope', '$filter', '$window', 'Utils', 'Auth',
  '$rootScope', 'FirebaseService', 'ModalService', 'VoteService',
    function ($scope, $filter, $window, utils, auth, $rootScope, firebaseService, modalService, voteService) {
      $scope.loading = true;
      $scope.messageTypes = utils.messageTypes;
      $scope.utils = utils;
      $scope.newBoard = {
        name: ''
      };
      $scope.userId = $window.location.hash.substring(1) || '';
      $scope.sortField = '$id';
      $scope.selectedType = 1;
      $scope.import = {
        data : [],
        mapping : []
      };

      $scope.closeAllModals = function(){
        modalService.closeAll();
      };

      $scope.getNumberOfVotesOnMessage = function(userId, messageId) {
        return new Array(voteService.returnNumberOfVotesOnMessage(userId, messageId));
      };

      $scope.droppedEvent = function(dragEl, dropEl) {
        var drag = $('#' + dragEl);
        var drop = $('#' + dropEl);
        var dragMessageRef = firebaseService.getMessageRef($scope.userId, drag.attr('messageId'));

        dragMessageRef.once('value', function() {
          dragMessageRef.update({
            type: {
              id: drop.data('column-id')
            }
          });
        });
      };

      function getBoardAndMessages(userData) {
        $scope.userId = $window.location.hash.substring(1) || '499sm';

        var messagesRef = firebaseService.getMessagesRef($scope.userId);
        var board = firebaseService.getBoardRef($scope.userId);

        board.on('value', function(board) {
          if (board.val() === null) {
            window.location.hash = '';
            location.reload();
          }

          $scope.board = board.val();
          $scope.maxVotes = board.val().max_votes ? board.val().max_votes : 6;
          $scope.boardId = $rootScope.boardId = board.val().boardId;
          $scope.boardContext = $rootScope.boardContext = board.val().boardContext;
        });

        $scope.boardRef = board;
        $scope.messagesRef = messagesRef;
        $scope.userUid = userData.uid;
        $scope.messages = firebaseService.newFirebaseArray(messagesRef);
        $scope.loading = false;
      }

      if ($scope.userId !== '') {
        auth.logUser($scope.userId, getBoardAndMessages);
      } else {
        $scope.loading = false;
      }

      $scope.isColumnSelected = function(type) {
        return parseInt($scope.selectedType) === parseInt(type);
      };

      $scope.getSortOrder = function() {
        return $scope.sortField === 'votes' ? true : false;
      };

      $scope.saveMessage = function(message) {
        message.creating = false;
        $scope.messages.$save(message);
      };

      $scope.vote = function(messageKey, votes) {
        if(voteService.isAbleToVote($scope.userId, $scope.maxVotes, $scope.messages)) {
          $scope.messagesRef.child(messageKey).update({
            votes: votes + 1,
            date: firebaseService.getServerTimestamp()
          });

          voteService.increaseMessageVotes($scope.userId, messageKey);
        }
      };

      $scope.unvote = function(messageKey, votes) {
        if(voteService.canUnvoteMessage($scope.userId, messageKey)) {
          var newVotes = (votes >= 1) ? votes - 1 : 0;

          $scope.messagesRef.child(messageKey).update({
            votes: newVotes,
            date: firebaseService.getServerTimestamp()
          });

          voteService.decreaseMessageVotes($scope.userId, messageKey);
        }
      };

      function redirectToBoard() {
        window.location.href = window.location.origin +
          window.location.pathname + '#' + $scope.userId;
      }

      $scope.isBoardNameInvalid = function() {
        return !$scope.newBoard.name;
      };

      $scope.createNewBoard = function() {
        $scope.loading = true;
        modalService.closeAll();
        $scope.userId = utils.createUserId();

        var callback = function(userData) {
          var board = firebaseService.getBoardRef($scope.userId);
          board.set({
            boardId: $scope.newBoard.name,
            date_created: new Date().toString(),
            columns: $scope.messageTypes,
            user_id: userData.uid,
            max_votes: $scope.newBoard.max_votes || 6
          }, function(error) {
             if (error) {
                $scope.loading = false;
             } else {
                redirectToBoard();
             }
          });

          $scope.newBoard.name = '';
        };

        auth.createUserAndLog($scope.userId, callback);
      };

      $scope.changeBoardContext = function() {
        $scope.boardRef.update({
          boardContext: $scope.boardContext
        });
      };

      $scope.changeBoardName = function(newBoardName) {
        $scope.boardRef.update({
          boardId: newBoardName
        });
        modalService.closeAll();
      };

      $scope.addNewColumn = function(name) {
        $scope.board.columns.push({
          value: name,
          id: utils.getNextId($scope.board)
        });

        var boardColumns = firebaseService.getBoardColumns($scope.userId);
        boardColumns.set(utils.toObject($scope.board.columns));

        modalService.closeAll();
      };

      $scope.changeColumnName = function(id, newName) {
        $scope.board.columns[id - 1] = {
          value: newName,
          id: id
        };

        var boardColumns = firebaseService.getBoardColumns($scope.userId);
        boardColumns.set(utils.toObject($scope.board.columns));

        modalService.closeAll();
      };

      $scope.deleteColumn = function(column) {
        $scope.board.columns = $scope.board.columns.filter(function(_column) {
            return _column.id !== column.id;
        });

        var boardColumns = firebaseService.getBoardColumns($scope.userId);
        boardColumns.set(utils.toObject($scope.board.columns));
        modalService.closeAll();
      };

      $scope.deleteMessage = function(message) {
        $scope.messages.$remove(message);
        modalService.closeAll();
      };

      function addMessageCallback(message) {
        var id = message.key;
        angular.element($('#' + id)).scope().isEditing = true;
        $('#' + id).find('textarea').focus();
      }

      $scope.addNewMessage = function(type) {
        $scope.messages.$add({
          text: '',
          creating: true,
          user_id: $scope.userUid,
          type: {
            id: type.id
          },
          date: firebaseService.getServerTimestamp(),
          votes: 0
        }).then(addMessageCallback);
      };

      $scope.deleteCards = function() {
        $($scope.messages).each(function(index, message) {
          $scope.messages.$remove(message);
        });

        modalService.closeAll();
      };

      $scope.getBoardText = function() {
        if ($scope.board) {
          var clipboard = '';

          $($scope.board.columns).each(function(index, column) {
            if (index === 0) {
              clipboard += '' + column.value + '
';
            } else {
              clipboard += '
' + column.value + '
';
            }
            var filteredArray = $filter('orderBy')($scope.messages,
              $scope.sortField,
              $scope.getSortOrder());

            $(filteredArray).each(function(index2, message) {
              if (message.type.id === column.id) {
                clipboard += '- ' + message.text + ' (' + message.votes + ' votes)
';
              }
            });
          });

          return clipboard;
        } else return '';
      };

      $scope.submitImportFile = function (file) {
        $scope.cleanImportData ();
        if (file) {
          if (file.size === 0){
            $scope.import.error = 'The file you are trying to import seems to be  empty';
            return;
          }
          /* globals Papa */
          Papa.parse(file, {
            complete: function(results) {
              if (results.data.length > 0){
                $scope.import.data = results.data;
                $scope.board.columns.forEach (function (column){
                  $scope.import.mapping.push({mapFrom:'-1', mapTo:column.id, name: column.value});
                });
                if (results.errors.length > 0)
                   $scope.import.error = results.errors[0].message;
                $scope.$apply();
              }
            }
          });
        }
      };

       $scope.importMessages = function (){
         var data = $scope.import.data;
         var mapping = $scope.import.mapping;
         for (var importIndex = 1; importIndex < data.length; importIndex++ )
         {
           for (var mappingIndex = 0; mappingIndex < mapping.length; mappingIndex++)
           {
             var mapFrom = mapping[mappingIndex].mapFrom;
             var mapTo = mapping[mappingIndex].mapTo;
             if (mapFrom === -1)
              continue;

             var cardText = data[importIndex][mapFrom];
             if (cardText)
             {
                $scope.messages.$add({
                text: cardText,
                user_id: $scope.userUid,
                type: {
                  id: mapTo
                },
                date: firebaseService.getServerTimestamp(),
                votes: 0});
             }
           }
         }
         $scope.closeAllModals();
       };

      $scope.cleanImportData = function (){
        $scope.import.data = [];
        $scope.import.mapping = [];
        $scope.import.error = '';
      };

      $scope.submitOnEnter = function(event, method, data){
        if (event.keyCode === 13) {
          switch (method){
            case 'createNewBoard':
                if (!$scope.isBoardNameInvalid()) {
                  $scope.createNewBoard();
                }
                break;
            case 'addNewColumn':
                if (data) {
                  $scope.addNewColumn(data);
                  $scope.newColumn = '';
                }
                break;
          }
        }
      };

      $scope.incrementMaxVotes = function() {
        $scope.boardRef.update({
          max_votes: $scope.maxVotes + 1
        });
      };

      $scope.decrementMaxVotes = function() {
        $scope.boardRef.update({
          max_votes: Math.min(Math.max($scope.maxVotes - 1, 1), 100)
        });
      };

      angular.element($window).bind('hashchange', function() {
        $scope.loading = true;
        $scope.userId = $window.location.hash.substring(1) || '';
        auth.logUser($scope.userId, getBoardAndMessages);
      });
    }
  ]);
<|endoftext|>


<commit_before>import { scene, camera, renderer } from './common/scene';
import { setEvents } from './common/setEvents';
import { convertToXYZ, getEventCenter, geodecoder, getPoint } from './common/geoHelpers';
import { mapTexture } from './common/mapTexture';
import { getTween, memoize } from './common/utils';
import topojson from 'topojson';
import THREE from 'THREE';
import d3 from 'd3';

d3.json('data/world.json', function (err, data) {
  var currentCountry, overlay, currentPoint;

  var segments = 155; // number of vertices. Higher = better mouse accuracy

  // Setup cache for country textures
  var countries = topojson.feature(data, data.objects.countries);
  var geo = geodecoder(countries.features);

  var textureCache = memoize(function (cntryID, color) {
    var country = geo.find(cntryID);
    return mapTexture(country, color);
  });

  let pointGeometry = new THREE.SphereGeometry(1, 10, 10);
  let pointMaterial = new THREE.MeshPhongMaterial({color: 'red'});

  // Base globe with blue "water"
  let blueMaterial = new THREE.MeshPhongMaterial({color: '#2B3B59', transparent: true});
  let sphere = new THREE.SphereGeometry(200, segments, segments);
  let baseGlobe = new THREE.Mesh(sphere, blueMaterial);
  baseGlobe.rotation.y = Math.PI;
  baseGlobe.addEventListener('click', onGlobeClick);
  baseGlobe.addEventListener('mousemove', onGlobeMousemove);

  // add base map layer with all countries
  let worldTexture = mapTexture(countries, '#647089');
  let mapMaterial  = new THREE.MeshPhongMaterial({map: worldTexture, transparent: true});
  var baseMap = new THREE.Mesh(new THREE.SphereGeometry(200, segments, segments), mapMaterial);
  baseMap.rotation.y = Math.PI;

  // add base map layer with all countries
  let wireMaterial  = new THREE.MeshPhongMaterial({wireframe: true, transparent: true});
  var wireFrame = new THREE.Mesh(new THREE.SphereGeometry(201, segments, segments), wireMaterial);
  wireFrame.rotation.y = Math.PI;

  // create a container node and add the two meshes
  var root = new THREE.Object3D();
  root.scale.set(3, 3, 3);
  root.add(baseGlobe);
  root.add(baseMap);
  root.add(wireFrame);
  scene.add(root);

  function onGlobeClick(event) {

    // Get pointc, convert to latitude/longitude
    var latlng = getEventCenter.call(this, event);

    // Get new camera position
    var temp = new THREE.Mesh();
    temp.position.copy(convertToXYZ(latlng, 900));
    temp.lookAt(root.position);
    temp.rotateY(Math.PI);

    for (let key in temp.rotation) {
      if (temp.rotation[key] - camera.rotation[key] > Math.PI) {
        temp.rotation[key] -= Math.PI * 2;
      } else if (camera.rotation[key] - temp.rotation[key] > Math.PI) {
        temp.rotation[key] += Math.PI * 2;
      }
    }

    var tweenPos = getTween.call(camera, 'position', temp.position);
    d3.timer(tweenPos);

    var tweenRot = getTween.call(camera, 'rotation', temp.rotation);
    d3.timer(tweenRot);
  }

  function onGlobeMousemove(event) {
    var map, material;

    // Get pointc, convert to latitude/longitude
    var latlng = getEventCenter.call(this, event);

    // Look for country at that latitude/longitude
    var country = geo.search(latlng[0], latlng[1]);

    if (currentPoint) {
      wireFrame.remove(currentPoint);
    }
    currentPoint = new THREE.Mesh(pointGeometry, pointMaterial);
    currentPoint.position.copy(getPoint.call(this, event));
    wireFrame.add(currentPoint);

    if (country !== null && country.code !== currentCountry) {

      // Track the current country displayed
      currentCountry = country.code;

      // Update the html
      d3.select("#msg").html(country.code);

       // Overlay the selected country
      map = textureCache(country.code, 'grey');

      material = new THREE.MeshPhongMaterial({map: map, transparent: true});
      if (!overlay) {
        overlay = new THREE.Mesh(new THREE.SphereGeometry(201, 40, 40), material);
        overlay.rotation.y = Math.PI;
        root.add(overlay);
      } else {
        overlay.material = material;
      }
    }
  }

  setEvents(camera, [baseGlobe], 'click');
  setEvents(camera, [baseGlobe], 'mousemove', 10);
});

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();
<commit_msg>edit comments<commit_after>import { scene, camera, renderer } from './common/scene';
import { setEvents } from './common/setEvents';
import { convertToXYZ, getEventCenter, geodecoder, getPoint } from './common/geoHelpers';
import { mapTexture } from './common/mapTexture';
import { getTween, memoize } from './common/utils';
import topojson from 'topojson';
import THREE from 'THREE';
import d3 from 'd3';

d3.json('data/world.json', function (err, data) {
  var currentCountry, overlay, currentPoint;

  var segments = 155; // number of vertices. Higher = better mouse accuracy

  // Setup cache for country textures
  var countries = topojson.feature(data, data.objects.countries);
  var geo = geodecoder(countries.features);

  var textureCache = memoize(function (cntryID, color) {
    var country = geo.find(cntryID);
    return mapTexture(country, color);
  });

  // Geometry/material for the point that follows cursor
  let pointGeometry = new THREE.SphereGeometry(1, 10, 10);
  let pointMaterial = new THREE.MeshPhongMaterial({color: 'red'});

  // Base globe with grey "water" material
  let blueMaterial = new THREE.MeshPhongMaterial({color: '#2B3B59', transparent: true});
  let sphere = new THREE.SphereGeometry(200, segments, segments);
  let baseGlobe = new THREE.Mesh(sphere, blueMaterial);
  baseGlobe.rotation.y = Math.PI;
  baseGlobe.addEventListener('click', onGlobeClick);
  baseGlobe.addEventListener('mousemove', onGlobeMousemove);

  // add base map layer with all countries
  let worldTexture = mapTexture(countries, '#647089');
  let mapMaterial  = new THREE.MeshPhongMaterial({map: worldTexture, transparent: true});
  var baseMap = new THREE.Mesh(new THREE.SphereGeometry(200, segments, segments), mapMaterial);
  baseMap.rotation.y = Math.PI;

  // add base map layer with all countries
  let wireMaterial  = new THREE.MeshPhongMaterial({wireframe: true, transparent: true});
  var wireFrame = new THREE.Mesh(new THREE.SphereGeometry(201, segments, segments), wireMaterial);
  wireFrame.rotation.y = Math.PI;

  // create a container node and add the two meshes
  var root = new THREE.Object3D();
  root.scale.set(3, 3, 3);
  root.add(baseGlobe);
  root.add(baseMap);
  root.add(wireFrame);
  scene.add(root);

  function onGlobeClick(event) {

    // Get pointc, convert to latitude/longitude
    var latlng = getEventCenter.call(this, event);

    // Get new camera position
    var temp = new THREE.Mesh();
    temp.position.copy(convertToXYZ(latlng, 900));
    temp.lookAt(root.position);
    temp.rotateY(Math.PI);

    for (let key in temp.rotation) {
      if (temp.rotation[key] - camera.rotation[key] > Math.PI) {
        temp.rotation[key] -= Math.PI * 2;
      } else if (camera.rotation[key] - temp.rotation[key] > Math.PI) {
        temp.rotation[key] += Math.PI * 2;
      }
    }

    var tweenPos = getTween.call(camera, 'position', temp.position);
    d3.timer(tweenPos);

    var tweenRot = getTween.call(camera, 'rotation', temp.rotation);
    d3.timer(tweenRot);
  }

  function onGlobeMousemove(event) {
    var map, material;

    // Get pointc, convert to latitude/longitude
    var latlng = getEventCenter.call(this, event);

    // Look for country at that latitude/longitude
    var country = geo.search(latlng[0], latlng[1]);

    if (currentPoint) {
      wireFrame.remove(currentPoint);
    }
    currentPoint = new THREE.Mesh(pointGeometry, pointMaterial);
    currentPoint.position.copy(getPoint.call(this, event));
    wireFrame.add(currentPoint);

    if (country !== null && country.code !== currentCountry) {

      // Track the current country displayed
      currentCountry = country.code;

      // Update the html
      d3.select("#msg").html(country.code);

       // Overlay the selected country
      map = textureCache(country.code, 'grey');

      material = new THREE.MeshPhongMaterial({map: map, transparent: true});
      if (!overlay) {
        overlay = new THREE.Mesh(new THREE.SphereGeometry(201, 40, 40), material);
        overlay.rotation.y = Math.PI;
        root.add(overlay);
      } else {
        overlay.material = material;
      }
    }
  }

  setEvents(camera, [baseGlobe], 'click');
  setEvents(camera, [baseGlobe], 'mousemove', 10);
});

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();
<|endoftext|>


<commit_before>
/*****************************************************************/
/* Creating custom markers and forms                             */

//add marker
var marker = L.marker([48.853, 2.3835], {title:'Musée Jesaispasquoi'}).addTo(map);
//add popup on marker
marker.bindPopup("Hello world!
I am a popup.");

//add marker
var marker2 = L.marker([48.852, 2.389], {title:'Show interface'}).addTo(map);
//add popup on marker
marker2.bindPopup("I'm showing the interface ! ");

var fastfoodIcon = L.icon({
            iconUrl: 'img/fastfood.png',
            iconSize: [32, 37],
            iconAnchor: [16, 37],
            popupAnchor: [0, -28]
        });

var herosIcon = L.icon({
            iconUrl: 'img/digsby.png',
            iconSize: [32, 37],
            iconAnchor: [16, 25],
            popupAnchor: [0, -28]
        });

var heros = L.marker([48.83478, 2.3679], {title:'Heros', icon:herosIcon, draggable: true}).addTo(map);

/* Generating circle around the heros */

var circle = L.circle(heros.getLatLng(), 700, {
    color: 'red',
    fillColor: '#f03',
    fillOpacity: 0.5
}).addTo(map);<commit_msg>Detection perimeter<commit_after>
/*****************************************************************/
/* Creating custom markers and forms                             */

//add marker
var marker = L.marker([48.853, 2.3835], {title:'Musée Jesaispasquoi'}).addTo(map);
//add popup on marker
marker.bindPopup("Hello world!
I am a popup.");

//add marker
var marker2 = L.marker([48.852, 2.389], {
    title:'Show interface'

});

//add popup on marker
marker2.bindPopup("I'm showing the interface ! ");

var fastfoodIcon = L.icon({
            iconUrl: 'img/fastfood.png',
            iconSize: [32, 37],
            iconAnchor: [16, 37],
            popupAnchor: [0, -28]
        });

var herosIcon = L.icon({
            iconUrl: 'img/digsby.png',
            iconSize: [32, 37],
            iconAnchor: [16, 25],
            popupAnchor: [0, -28]
        });

var heros = L.marker([48.83478, 2.3679], {title:'Heros', icon:herosIcon, draggable: true}).addTo(map);

console.log('marker2:' + marker2);
console.log('herosLat: ' + heros.getLatLng());
var distance = marker2.getLatLng().distanceTo(heros.getLatLng());
console.log('distance: ' + distance);

heros.on('drag',(function(e){
    var distance = marker2.getLatLng().distanceTo(heros.getLatLng());
    if (distance < 700) {
         marker2.addTo(map);
     }
}));

/* Generating circle around the heros */

var circle = L.circle(heros.getLatLng(), 700, {
    color: 'red',
    fillColor: '#f03',
    fillOpacity: 0.5
}).addTo(map);<|endoftext|>


<commit_before>/*eslint strict: [2, "function"], camelcase: 0 */
/*eslint-env browser */
/*global define: false */

define(['crosshairs', 'tooltip', 'util', 'vgcanvas', 'd3', 'jquery', 'underscore_ext', 'static-interval-tree', 'annotationColor', 'metadataStub', 'layoutPlot'
	], function (crosshairs, tooltip, util, vgcanvas, d3, $, _, intervalTree, annotationColor, metadataStub, layoutPlot) {
	'use strict';

	var {pxTransformFlatmap} = layoutPlot;
	var annotationFeatures = _.object(_.flatmap(annotationColor.colorSettings, (feats, dsID) =>
		_.map(feats, ({color}, feature) => [`${dsID}__${feature}`, {
			color: color,
			get: (a, v) => _.get_in(a, [`${dsID}__${feature}`, [v.chr, v.start, v.end, v.reference, v.alt].join('__')])
		}])
	 ));

	// Group by consecutive matches, perserving order.
	function groupByConsec(sortedArray, prop, ctx) {
		var cb = _.iteratee(prop, ctx);
		var last = {}, current; // init 'last' with a sentinel, !== to everything
		return _.reduce(sortedArray, (acc, el) => {
			var key = cb(el);
			if (key !== last) {
				current = [];
				last = key;
				acc.push(current);
			}
			current.push(el);
			return acc;
		}, []);
	}

	// Group by, returning groups in sorted order. Scales O(n) vs.
	// sort's O(n log n), if the number of values is much smaller than
	// the number of elements.
	function sortByGroup(arr, keyfn) {
		var grouped = _.groupBy(arr, keyfn);
		return _.map(_.sortBy(_.keys(grouped), _.identity),
				k => grouped[k]);
	}

	function drawImpactPx(vg, width, pixPerRow, radius, color, variants) {
		var ctx = vg.context(),
			varByImp = groupByConsec(variants, v => v.group);

		_.each(varByImp, vars => {
			ctx.beginPath(); // halos
			_.each(vars, v => {
				var padding = Math.max(0, radius - (v.xEnd-v.xStart + 1) / 2.0);
				ctx.moveTo(v.xStart - padding, v.y);
				ctx.lineTo(v.xEnd + padding, v.y);
			});
			ctx.lineWidth = pixPerRow;
			ctx.strokeStyle = color(vars[0].group);
			ctx.stroke();

			if (pixPerRow>2){ // centers when there is enough vertical room for each sample
				ctx.beginPath();
				_.each(vars, v => {
					ctx.moveTo(v.xStart, v.y);
					ctx.lineTo(v.xEnd, v.y);
				});
				ctx.lineWidth = pixPerRow / 8;
				ctx.strokeStyle = 'black';
				ctx.stroke();
			}
		});
	}

	function push(arr, v) {
		arr.push(v);
		return arr;
	}

	function drawBackground(vg, width, height, sparsePad, pixPerRow, values) {
		var ctx = vg.context(),
			drawWidth = width - sparsePad * 2,
			[stripes] = _.reduce(
				groupByConsec(values, v => !!v.vals),
				([acc, sum], g) =>
					[g[0].vals ? acc : push(acc, [sum, g.length]), sum + g.length],
				[[], 0]);

		vg.smoothing(false);
		vg.box(0, 0, width, height, 'white'); // white background

		ctx.beginPath();                      // grey for missing data
		_.each(stripes, ([offset, len]) =>
			ctx.rect(
				sparsePad,
				(offset * pixPerRow) + sparsePad,
				drawWidth,
				pixPerRow * len
		));
		ctx.fillStyle = 'grey';
		ctx.fill();
	}

	var colorStr = c =>
		'rgba(' + c.r + ', ' + c.g + ', ' + c.b + ', ' + c.a.toString() + ')';

	var unknownEffect = 0,
		impact = {
			Nonsense_Mutation: 3,
			frameshift_variant: 3,
			stop_gained: 3,
			splice_acceptor_variant: 3,
			splice_donor_variant: 3,
			Splice_Site: 3,
			Frame_Shift_Del: 3,
			Frame_Shift_Ins: 3,

			splice_region_variant: 2,
			missense: 2,
			non_coding_exon_variant: 2,
			missense_variant: 2,
			Missense_Mutation: 2,
			exon_variant: 2,
			RNA: 2,
			Indel: 2,
			start_lost: 2,
			start_gained: 2,
			De_novo_Start_OutOfFrame: 2,
			Translation_Start_Site: 2,
			De_novo_Start_InFrame: 2,
			stop_lost: 2,
			Nonstop_Mutation: 2,
			initiator_codon_variant: 2,
			"5_prime_UTR_premature_start_codon_gain_variant": 2,
			disruptive_inframe_deletion: 2,
			inframe_deletion: 2,
			inframe_insertion: 2,
			In_Frame_Del: 2,
			In_Frame_Ins: 2,

			synonymous_variant: 1,
			"5_prime_UTR_variant": 1,
			"3_prime_UTR_variant": 1,
			"5'Flank": 1,
			"3'Flank": 1,
			"3'UTR": 1,
			"5'UTR": 1,
			Silent: 1,
			stop_retained_variant: 1,
			upstream_gene_variant: 1,
			downstream_gene_variant: 1,
			intron_variant: 1,
			Intron: 1,
			intergenic_region: 1,
			IGR: 1,

			"others": 0
		},
		round = Math.round,
		saveUndef = f => v => v === undefined ? v : f(v),
		decimateFreq = saveUndef(v => round(v * 31) / 32), // reduce to 32 vals
		colors = {
			category_25: [
				{r: 255, g: 127, b: 14, a: 1},  // orange #ff7f0e
				{r: 44, g: 160, b: 44, a: 1},  // green #2ca02c
				{r: 31, g: 119, b: 180, a: 1}, // blue #1f77b4
				{r: 214, g: 39, b: 40, a: 1}  // red #d62728
			],
			af: {r: 255, g: 0, b: 0},
			grey: {r: 128, g: 128, b: 128, a: 1}
		},
		features = _.merge(annotationFeatures, {
			impact: {
				get: (a, v) => impact[v.effect] || (v.effect ? unknownEffect: undefined),
				color: v => colorStr(_.isUndefined(v) ? colors.grey: colors.category_25[v])
			},
			dna_vaf: {
				get: (a, v) => _.isUndefined(v.dna_vaf) || _.isNull(v.dna_vaf) ? undefined : decimateFreq(v.dna_vaf),
				color: v => colorStr(_.isUndefined(v) ? colors.grey :
					_.assoc(colors.af, 'a', v))
			},
			rna_vaf: {
				get: (a, v) => _.isUndefined(v.dna_vaf) || _.isNull(v.rna_vaf) ? undefined : decimateFreq(v.rna_vaf),
				color: v => colorStr(_.isUndefined(v) ? colors.grey :
					_.assoc(colors.af, 'a', v))
			}
		}),
		reduce = _.reduce,
		widgets = {},
		aWidget = {

			destroy: function () {
				this.sub.dispose();
				delete widgets[this.id];
			},

			draw: function (vg) {
				var {radius, pixPerRow, canvasWidth, canvasHeight,
						values, sparsePad, feature} = this,
					minppr = Math.max(pixPerRow, 2);

				drawBackground(vg, canvasWidth, canvasHeight, sparsePad, pixPerRow, values);
				drawImpactPx(vg, canvasWidth, minppr,
						radius, features[feature].color, this.nodes);
			},

			closestNode: function (x, y) {
				var cutoffX = this.radius,
					cutoffY = this.pixPerRow / 2.0,
					min = Number.POSITIVE_INFINITY,
					distance;

				return reduce(this.nodes, function (closest, n) {
					if ( (Math.abs(y-n.y) < cutoffY) && (x > n.xStart -cutoffX) && (x<n.xEnd +cutoffX)) {
						distance = Math.pow( (y-n.y), 2) + Math.pow( (x - (n.xStart+n.xEnd) / 2.0), 2);
						if (distance < min) {
							min = distance;
							return n;
						} else {
							return closest;
						}
					}
					else {
						return closest;
					}
				}, undefined);
			},

			formatAf: function (af) {
				if (af === 'NA' || af === '' || af === undefined || af === null) {
					return 'NA';
				} else {
					return Math.round(af * 100) + '%';
				}
			},

			plotCoords: function (ev) {
				var offset,
					x = ev.offsetX,
					y = ev.offsetY;
				if (x === undefined) { // fix up for firefox
					offset = util.eventOffset(ev);
					x = offset.x;
					y = offset.y;
				}
				return { x: x, y: y };
			},

			mousing: function (ev) {
				var pos, posText, posURL,
					ga4ghVarURL,
					node,
					coords,
					row,
					rows = [],
					mode = 'genesets',
					dnaAf,
					rnaAf,
					sampleIndex,
					ws = ev.data.plotData.ws,
					tip = {
						ev: ev,
						el: '#nav',
						my: 'top',
						at: 'top',
						mode: mode,
						valWidth: '22em'
					};
				if (tooltip.frozen()) {
					return;
				}
				coords = this.plotCoords(ev);
				node = this.closestNode(coords.x, coords.y);
				if (node) {
					pos = node.data.chr + ':' +
						util.addCommas(node.data.start) + '-' +
						util.addCommas(node.data.end);
					dnaAf = this.formatAf(node.data.dna_vaf);
					rnaAf = this.formatAf(node.data.rna_vaf);
					posURL = "http://genome.ucsc.edu/cgi-bin/hgTracks?db=hg19&position="+encodeURIComponent(pos); // hg19 is hard coded, we do not check
					posText = 'hg19 ' + pos;  // hg19 is hard coded, we do not check

					// ga4gh BRCA1 and BRCA2 hard-coded section here
					if (this.gene ==="BRCA1" || this.gene === "BRCA2"){
						ga4ghVarURL = "../datapages/?ga4gh=1&referenceName="+
							node.data.chr.substring(3, node.data.chr.length)+
							"&start="+node.data.start+"&end="+ node.data.end +
							"&ref="+node.data.reference +
							"&alt="+node.data.alt +
							"&gene="+ this.gene;
					}

					//effect, gene
					row = [ { val: (node.data.effect ? node.data.effect+", ":'')  +
							this.gene +  (node.data.amino_acid ? ' (' + node.data.amino_acid + ')':'')}];
					rows.push(row);

					// chromosomal coordinate, ref-> alt
					row = [ { val: posText, url: posURL}];
					if (node.data.reference && node.data.alt){
						row.push({ val: node.data.reference + ' to ' + node.data.alt});
					}
					rows.push(row);

					if (dnaAf !== "NA"){
						rows.push([{ label: 'DNA variant allele freq',  val: dnaAf}]);
					}
					if (rnaAf !== "NA"){
						rows.push([{ label: 'RNA variant allele freq', val: rnaAf}]);
					}
					if (ga4ghVarURL){
						rows.push([{ val: 'GA4GH Annotations', url: ga4ghVarURL}]);
					}
					tip.sampleID = node.data.sample;
					tip.rows = rows;
				} else {
					sampleIndex = Math.floor((coords.y * ws.zoomCount / ws.height) + ws.zoomIndex);
					tip.sampleID = ev.data.plotData.samples[sampleIndex];
				}
				tooltip.mousing(tip);
			},

			mupitClick: function () {
				var positions = _.unique(_.map(this.nodes, function (n) {
						return n.data.chr + ':' + (n.data.start).toString();
					})).join(','),
					url = "http://mupit.icm.jhu.edu/?gm="+positions;

				window.open(url);
			},

			receiveData: function (data) {
				// XXX It's not clear if this.values is useful. We no longer draw by iterating over
				// the variants indexed by sample. It's currently used to draw background, do tooltip,
				// and maybe more. Should deprecated it if we don't need it.
				var drawValues = data.slice(this.zoomIndex, this.zoomIndex + this.zoomCount);
				this.values = _.map(drawValues, (obj, i) => _.assoc(obj, 'index', i));
				this.render();
			},

			receiveAnnData: function (annData){
				var annValues = {};
				Object.keys(annData).map(function (key){
					var [, dataset, field] = key.split("__"),
						feature = [dataset, field].join("__"),
						order = annotationColor.colorSettings[dataset][field].order;

					annValues[feature] = {};
					if (annData[key].length){
						annData[key].map(function (val){
							if (val.info[field] && val.info[field].length>0){
								var values = val.info[field][0].split(/[,]/);
								val.alternateBases.map(function (alt, i){
									var chrom = val.referenceName.substring(0, 3)==="chr"? val.referenceName: "chr"+ val.referenceName,
										id = [chrom, val.start, val.end, val.referenceBases, alt].join("__"),
										value;
									if (val.alternateBases.length === values.length){
										value = _.max(values[i].split(/[|-]/), f=> order[f]);
									} else {
										value = _.max(_.flatten(values.map(v=> v.split(/[|-]/))), f => order[f]);
									}
									if (annValues[feature][id]){
										annValues[feature][id] = _.max([value, annValues[feature][id]], f=>order[f]);
									} else {
										annValues[feature][id] = value;
									}
								});
							}
						});
					}
				});
				this.annValues = annValues;
			},

			findNodes: function () {
				var {layout, index, samples} = this.options,
					{pixPerRow, sparsePad, zoomIndex, zoomCount, feature, annValues} = this,
					sindex = _.object(samples.slice(zoomIndex, zoomIndex + zoomCount),
								_.range(samples.length)),
					group = features[feature].get,
					minSize = ([s, e]) => [s, e - s < 1 ? s + 1 : e],
					// sortfn is about 2x faster than sortBy, for large sets of variants
					sortfn = (coll, keyfn) => _.flatten(sortByGroup(coll, keyfn), true);
				return sortfn(pxTransformFlatmap(layout, (toPx, [start, end]) => {
					var variants = _.filter(
						intervalTree.matches(index, {start: start, end: end}),
						v => _.has(sindex, v.sample));
					return _.map(variants, v => {
						var [pstart, pend] = minSize(toPx([v.start, v.end]));
						return {
							xStart: pstart,
							xEnd: pend,
							y: sindex[v.sample] * pixPerRow + (pixPerRow / 2) + sparsePad,
						   group: group(annValues, v),                                   // needed for sort, before drawing.
						   data: v
						};
					});
				}), v => v.group);
			},

			drawLegend: function () {
				var myColors,
					c,
					rgba,
					labels,
					groups,
					align,
					topBorderIndex;
				if (this.feature === 'impact') {
					myColors = _.map(colors[this.color], function (c) {
						return 'rgb(' + c.r + ',' + c.g + ',' + c.b + ')';
					});
					groups = _.groupBy(_.pairs(impact), ([, imp]) => imp);
					labels = _.map(_.range(_.keys(groups).length), i => _.pluck(groups[i], 0).join(', '));

					align = 'left';
				} else if (this.feature ==="dna_vaf" || this.feature ==="rna_vaf") { // feature is one of allele frequencies
					c = colors.af;
					rgba = 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',';
					myColors = [
						rgba + '0)',
						rgba + '0.5)',
						rgba + '1)'
					];
					labels = ['0%', '50%', '100%'];
					align = 'center';
					topBorderIndex = 3;
				} else {
					var [dataset, feature] = this.feature.split("__"),
						md = _.find(metadataStub.variantSets, ds => ds.id === dataset).metadata,
						info = _.find(md, ds => ds.key === ('INFO.'+feature)).info,
						colorFn = annotationColor.colorSettings[dataset][feature].color;

					labels = annotationColor.colorSettings[dataset][feature].filter.map(value => info[value]);
					myColors = annotationColor.colorSettings[dataset][feature].filter.map(value=>colorFn(value));
				}
				myColors.unshift('rgb(255,255,255)');
				labels.unshift('no mutation');
				this.columnUi.drawLegend(myColors, labels, align, '', 'mutationVector', topBorderIndex);
			},

			render: function () {
//				var start = performance.now();
				this.pixPerRow = (this.height - (this.sparsePad * 2))  / this.values.length;
				this.canvasHeight = this.height; // TODO init elsewhere
				this.d2 = this.vg.context();
				this.nodes = this.findNodes();
				this.drawLegend();

				this.draw(this.vg);
//				var end = performance.now();
//				console.log('full run', end - start);
			},

			initialize: function (options) {
				var self = this;

				_.bindAll.apply(_, [this].concat(_.functions(this)));
				//_(this).bindAll();
				this.vg = options.vg;
				this.columnUi = options.columnUi;
				this.dataset = options.dataset;
				this.gene = options.gene;
				this.feature = options.feature;
				this.color = options.color;
				this.canvasWidth = options.width;
				this.height = options.height;
				this.zoomCount = options.zoomCount;
				this.zoomIndex = options.zoomIndex;
				this.sparsePad = options.sparsePad;
				this.radius = options.radius;
				this.point = options.point;
				this.refHeight = options.refHeight;
				this.columnUi.$sparsePad.height(0);
				this.options = options;

				var {baseLen, pxLen} = options.layout;
				// XXX There's something wrong here. E.g. if the exons have
				// 1px spacing, this would be off. pxLen is the wrong metric.
				this.offset = (_.get_in(this, ['options', 'xzoom', 'index']) || 0) *
					pxLen / baseLen;

				// bindings
				this.sub = this.columnUi.crosshairs.mousingStream.subscribe(function (ev) {
					ev.data = { plotData: self.columnUi.plotData };
					self.mousing(ev);
				});

				this.receiveAnnData(options.annData);
				this.receiveData(options.data);
				this.render();
			}
		};

	function create(id, options) {
		var w = Object.create(aWidget);
		w.id = id;
		w.initialize(options);
		return w;
	}

	function evalMut(refGene, mut) {
		var geneInfo = refGene[mut.gene];
		return {
			impact: features.impact.get(null, mut),
			right: (geneInfo.strand === '+') ?
		            mut.start - geneInfo.txStart :
		            geneInfo.txStart - mut.start
		};
	}

	function cmpMut(mut1, mut2) {
		if (mut1.impact !== mut2.impact) {
			if (mut1.impact === undefined){
				return 1;
			} else if (mut2.impact === undefined) {
				return -1;
			} else {
				return mut2.impact - mut1.impact; // high impact sorts first
			}
		}

		return mut1.right - mut2.right;       // low coord sorts first
	}

	return {
		mupitClick: function (id) {
			if (widgets[id]) {
				widgets[id].mupitClick();
			}
		},

		rowOrder: function (row1, row2, refGene) {
			var row1a, row2a;
			if (!row1.length && !row2.length) {
				return 0;
			}
			if (!row1.length) {                   // has mutations sorts first
				return 1;
			}
			if (!row2.length) {
				return -1;                        // has mutations sorts first
			}

			// Native map is a lot faster than _.map. Need an es5 polyfill, or
			// perhaps lodash, or ramda.
			row1a = row1.map(m => evalMut(refGene, m));
			row2a = row2.map(m => evalMut(refGene, m));

			return cmpMut(_.maxWith(row1a, cmpMut), _.maxWith(row2a, cmpMut));
		},

		show: function (id, options) {
			if (widgets[id]) {
				widgets[id].destroy();
			}
			widgets[id] = create(id, options);
			return widgets[id];
		}
	};
});
<commit_msg>Drop mutationVector file.<commit_after><|endoftext|>


<commit_before>/*
 * noko50-deleter.js
 *
 * Hides posts on noko50 pages
 *
 * Usage:
 *   $config['additional_javascript'][] = 'js/jquery.min.js';
 *   $config['additional_javascript'][] = 'js/settings.js';
 *   $config['additional_javascript'][] = 'js/noko50-deleter.js';
 *
 */

onready(function(){
    if (settings.noko50clear) {
        var noko50clear = function () {
            if (window.location.pathname.split("+").pop() == '50.html')
                while ($(".post.reply").length > 50)
                    $(".post.reply:first").next('br').andSelf().remove();
        };
        noko50clear();
        // allow to work with auto-reload.js, etc.
        $(document).bind('new_post', function (e, post) {
            noko50clear();
        });
    }
});<commit_msg>noko50-deleter.js: keep exactly 50 posts in +50 version<commit_after>/*
 * noko50-deleter.js
 *
 * Hides posts on noko50 pages
 *
 * Usage:
 *   $config['additional_javascript'][] = 'js/jquery.min.js';
 *   $config['additional_javascript'][] = 'js/settings.js';
 *   $config['additional_javascript'][] = 'js/noko50-deleter.js';
 *
 */

onready(function(){
    if (settings.noko50clear) {
        // Pass new posts number to clear function
        // because it's called before new posts are appended to document.
        var noko50clear = function (newPosts) {
            if (window.location.pathname.split("+").pop() == '50.html')
                while ($(".post.reply").length + newPosts > 50)
                    $(".post.reply:first").next('br').andSelf().remove();
        };
        noko50clear(0);
        // allow to work with auto-reload.js, etc.
        $(document).bind('new_post', function (e, post) {
            noko50clear(post.length);
        });
    }
});<|endoftext|>


<commit_before>// Onsen UI SystemJS config

var angular2onsenui = '';

if (window._isLocalDev) {
  angular2onsenui = '../../OnsenUI/bindings/angular2';
} else if (window._onsNightlyBuild) {
  angular2onsenui = 'https://crossorigin.me/https://circleci.com/api/v1/project/OnsenUI/OnsenUI/latest/artifacts/0/$CIRCLE_ARTIFACTS/angula2-onsenui';
} else {
  angular2onsenui = 'https://unpkg.com/angular2-onsenui' + (window._onsAngular2LibVersion ? ('@' + window._onsAngular2LibVersion) : '');
}

var libVersion = window._angular2LibVersion;

System.config({
  map: {
    'angular2-onsenui': angular2onsenui + '/dist/bundles/angular2-onsenui.umd.js' + (window._onsNightlyBuild ? '?branch=master&filter=successful' : ''),
    '@angular/core': `https://unpkg.com/@angular/core@${libVersion}/bundles/core.umd.min.js`,
    '@angular/compiler': `https://unpkg.com/@angular/compiler@${libVersion}/bundles/compiler.umd.min.js`,
    '@angular/common': `https://unpkg.com/@angular/common@${libVersion}/bundles/common.umd.min.js`,
    '@angular/forms': `https://unpkg.com/@angular/forms@${libVersion}/bundles/forms.umd.min.js`,
    '@angular/platform-browser': `https://unpkg.com/@angular/platform-browser@${libVersion}/bundles/platform-browser.umd.min.js`,
    '@angular/platform-browser-dynamic': `https://unpkg.com/@angular/platform-browser-dynamic@${libVersion}/bundles/platform-browser-dynamic.umd.min.js`,
    'rxjs': 'https://unpkg.com/rxjs@5.0.0-beta.11',
    'process': 'https://unpkg.com/process@0.11.9'
  },
  packages: {
    'angular2-onsenui': {
      format: 'cjs',
    },
    'core-js': {
      main: 'index.js',
      format: 'cjs'
    },
    'typescript': {
      format: 'cjs'
    },
    'app': {
      defaultExtension: 'ts',
      format: 'esm'
    }
  },
  meta: {
    'inline': {
      loader: 'inline-loader'
    }
  },
  transpiler: 'typescript',
  typescriptOptions: {
    'emitDecoratorMetadata': true
  }
});

System.amdDefine('inline-loader', [], function() {
  return {
    fetch: function() {
      return new Promise(function(resolve, reject) {
        if (document.readyState === 'complete') {
          load();
        } else {
          window.onload = load;
        }

        function load() {
          var target = document.querySelector('script[type="text/typescript"]');

          if (target) {
            resolve(target.textContent);
          } else {
            reject('Error: inline-loader fail.');
          }
        }
      });
    }
  };
});

System.import('inline');

<commit_msg>Replace `angula` with `angular`.<commit_after>// Onsen UI SystemJS config

var angular2onsenui = '';

if (window._isLocalDev) {
  angular2onsenui = '../../OnsenUI/bindings/angular2';
} else if (window._onsNightlyBuild) {
  angular2onsenui = 'https://crossorigin.me/https://circleci.com/api/v1/project/OnsenUI/OnsenUI/latest/artifacts/0/$CIRCLE_ARTIFACTS/angular2-onsenui';
} else {
  angular2onsenui = 'https://unpkg.com/angular2-onsenui' + (window._onsAngular2LibVersion ? ('@' + window._onsAngular2LibVersion) : '');
}

var libVersion = window._angular2LibVersion;

System.config({
  map: {
    'angular2-onsenui': angular2onsenui + '/dist/bundles/angular2-onsenui.umd.js' + (window._onsNightlyBuild ? '?branch=master&filter=successful' : ''),
    '@angular/core': `https://unpkg.com/@angular/core@${libVersion}/bundles/core.umd.min.js`,
    '@angular/compiler': `https://unpkg.com/@angular/compiler@${libVersion}/bundles/compiler.umd.min.js`,
    '@angular/common': `https://unpkg.com/@angular/common@${libVersion}/bundles/common.umd.min.js`,
    '@angular/forms': `https://unpkg.com/@angular/forms@${libVersion}/bundles/forms.umd.min.js`,
    '@angular/platform-browser': `https://unpkg.com/@angular/platform-browser@${libVersion}/bundles/platform-browser.umd.min.js`,
    '@angular/platform-browser-dynamic': `https://unpkg.com/@angular/platform-browser-dynamic@${libVersion}/bundles/platform-browser-dynamic.umd.min.js`,
    'rxjs': 'https://unpkg.com/rxjs@5.0.0-beta.11',
    'process': 'https://unpkg.com/process@0.11.9'
  },
  packages: {
    'angular2-onsenui': {
      format: 'cjs',
    },
    'core-js': {
      main: 'index.js',
      format: 'cjs'
    },
    'typescript': {
      format: 'cjs'
    },
    'app': {
      defaultExtension: 'ts',
      format: 'esm'
    }
  },
  meta: {
    'inline': {
      loader: 'inline-loader'
    }
  },
  transpiler: 'typescript',
  typescriptOptions: {
    'emitDecoratorMetadata': true
  }
});

System.amdDefine('inline-loader', [], function() {
  return {
    fetch: function() {
      return new Promise(function(resolve, reject) {
        if (document.readyState === 'complete') {
          load();
        } else {
          window.onload = load;
        }

        function load() {
          var target = document.querySelector('script[type="text/typescript"]');

          if (target) {
            resolve(target.textContent);
          } else {
            reject('Error: inline-loader fail.');
          }
        }
      });
    }
  };
});

System.import('inline');

<|endoftext|>


<commit_before>// Example dep

export function log(msg) {
  console.log(msg)
}
<commit_msg>fix minimal-jquery lint errors<commit_after>// Example dep

export function log (msg) {
  console.log(msg)
}
<|endoftext|>


<commit_before>import React from 'react';
import {Card, DatePicker, Button} from 'belle';

export default React.createClass({

  _resetValue() {
    this.refs.calendar1.resetValue();
  },

  _renderDay(day) {
    const date = day.getDate();
    return (

        🎁{ date }

    );
  },

  render() {
    const selectedDate = new Date();
    selectedDate.setDate(selectedDate.getDate() + 5);

    const minDate = new Date();
    minDate.setDate(10);

    const maxDate = new Date();
    maxDate.setDate(20);

    return (

ComboBox

        <Card>

Default Calendar Example

            <DatePicker ref="calendar1"/>

          <Button onClick={ this._resetValue }>Reset Date</Button>

DatePicker with min & max

            <DatePicker defaultValue={ selectedDate }
                        min={ minDate }
                        max={ maxDate } />

Disabled Calendar Example

            <DatePicker defaultValue={ selectedDate } disabled/>

Calendar without showing other months dates Example

            <DatePicker showOtherMonthDate={ false } defaultValue={ selectedDate }/>

Read-Only active Calendar Example

            <DatePicker defaultValue={ selectedDate }
                        readOnly/>

Special renderDay

            <DatePicker defaultValue={ selectedDate }
                        renderDay={ this._renderDay }/>

Calendar in dutch french !!!

            <DatePicker defaultValue={ selectedDate } locale="fr"/>

Calendar in dutch arabic !!!

            <DatePicker defaultValue={ selectedDate } locale="ar"/>

Calendar in dutch hebrew !!!

            <DatePicker defaultValue={ selectedDate }
                        locale="he"/>

        </Card>

    );
  },
});
<commit_msg>feat(DatePicker): testing a small example<commit_after>import React from 'react';
import {Card, DatePicker, Button} from 'belle';

export default React.createClass({

  _resetValue() {
    this.refs.calendar1.resetValue();
  },

  _renderDay(day) {
    const date = day.getDate();
    return (

        🎁{ date }

    );
  },

  _onMouseDown(event) {
    event.stopPropagation();
  },

  render() {
    const selectedDate = new Date();
    selectedDate.setDate(selectedDate.getDate() + 5);

    const minDate = new Date();
    minDate.setDate(10);

    const maxDate = new Date();
    maxDate.setDate(20);

    return (

ComboBox

        <Card>

Default Calendar Example

            <DatePicker ref="calendar1"/>

          <Button onClick={ this._resetValue }>Reset Date</Button>

DatePicker with min & max

            <DatePicker defaultValue={ selectedDate }
                        min={ minDate }
                        max={ maxDate } />

Disabled Calendar Example

            <DatePicker defaultValue={ selectedDate } disabled/>

Calendar without showing other months dates Example

            <DatePicker showOtherMonthDate={ false } defaultValue={ selectedDate }/>

Read-Only active Calendar Example

            <DatePicker defaultValue={ selectedDate }
                        readOnly/>

Special renderDay

            <DatePicker defaultValue={ selectedDate }
                        renderDay={ this._renderDay }/>

Calendar in dutch french !!!

            <DatePicker defaultValue={ selectedDate } locale="fr"/>

Calendar in dutch arabic !!!

            <DatePicker defaultValue={ selectedDate } locale="ar"/>

Calendar in dutch hebrew !!!

            <DatePicker defaultValue={ selectedDate }
                        locale="he"/>

        </Card>

    );
  },
});
<|endoftext|>