<commit_before>/**
 * jquery.textareaHighlighter.js 0.2.1
 * jQuery plugin for highlighting text in textarea.
 *
 * alexandre.kirillov@gmail.com
 * MIT license. http://opensource.org/licenses/MIT
 */
;(function ( $, window, document, undefined ) {
    "use strict";

    /**
     *
     * PLUGIN CORE
     *
     */
    var pluginName = "textareaHighlighter",
        defaults = {
            matches: [
                // {'className': '', 'words': []}
            ],
            maxlength: -1,
            maxlengthWarning: '',
            maxlengthElement: null,
            isCustomeCss: false,
            debug: false
        };

    // constructor
    function Plugin ( element, options ) {
        this.element   = element;
        this.$element  = $(this.element);
        this.settings  = $.extend( {}, defaults, this.$element.data(), options );
        this._defaults = defaults;
        this._name     = pluginName;

        // check if plugin was initialized on the element.
        if ( this.$element.data(pluginName) ) { return; }
        this.$element.data(pluginName, true);

        this.style = {};
        this.$wrapDiv       = $(document.createElement('div')).addClass('textarea-highlighter-wrap');
        this.$backgroundDiv = $(document.createElement('div'));

        this.init();
    }

    Plugin.prototype = {
        init: function() {

            var _this          = this,
                $this          = this.$element,
                style          = this.style,
                settings       = this.settings,
                $wrapDiv       = this.$wrapDiv,
                $backgroundDiv = this.$backgroundDiv;

            _this.updateStyle();

            $this
                .data('highlighterTimerId', -1)
                // Bind events
                .on('scroll', function(){
                    $backgroundDiv.scrollTop( $this.scrollTop() );
                })
                .on('textarea.highlighter.update', function(){
                    _this.updateStyle();
                })
                .on('change keydown keyup paste', function(e){
                    // if arrow keys, don't do anything
                    if (/(37|38|39|40)/.test(e.keyCode)) { return true; }

                    // check for last update, this is for performace
                    if ($this.data('highlighterTimerId') !== -1) {
                        clearTimeout( $this.data('highlighterTimerId') );
                        $this.data('highlighterTimerId', -1);
                    }

                    var changeId = setTimeout(function(){
                        var textareaText = $(document.createElement('div')).text( $this.val() ).html(),
                            key, ruleTextList, matchText, spanText, matchTextList = [],
                            notOverMaxText = '', overMaxText ='',
                            i, imax, j, jmax, maxSize;

                        if (0 < settings.maxlength) {
                            // check for max length
                            if ( settings.maxlength < $this.val().length) {
                                matchText = $this.val().slice( settings.maxlength, settings.maxlength + $this.val().length - 1 );
                                overMaxText = ''+ matchText +'';

                            }
                            // update maxlength
                            if (settings.maxlengthElement !== null) {
                                maxSize = settings.maxlength - $this.val().length;
                                if (maxSize < 0) {
                                    if (! settings.maxlengthElement.hasClass( settings.maxlengthWarning )) {
                                        settings.maxlengthElement.addClass( settings.maxlengthWarning );
                                    }
                                }
                                else {
                                    if (settings.maxlengthElement.hasClass( settings.maxlengthWarning )) {
                                        settings.maxlengthElement.removeClass( settings.maxlengthWarning );
                                    }
                                }
                                // update max length
                                settings.maxlengthElement.text( maxSize );
                            }

                            notOverMaxText = $this.val().slice( 0, settings.maxlength );
                        }
                        else {
                            notOverMaxText = textareaText;
                        }

                        // check for matching words
                        for (i = 0, imax = settings.matches.length; i < imax; i++) {
                            for (j = 0, jmax = settings.matches[i].words.length; j < jmax; j++) {
                                // get word to match
                                matchText = settings.matches[i].words[j];
                                // check if word exists in input text
                                if( notOverMaxText.indexOf( matchText ) !== -1 ){
                                    matchTextList.push( matchText );
                                    spanText = ''+ matchText +'';
                                    notOverMaxText = notOverMaxText.replace( new RegExp( _escapeRegExp( matchText ), 'g'), spanText );
                                }
                            }
                        }

                        // update background div content
                        $backgroundDiv.html( notOverMaxText + overMaxText );
                        // trigger update event
                        $this.trigger('textarea.highlighter.update', {'textList': matchTextList});
                    }, 30);

                    $this.data('highlighterTimerId', changeId);
                });

            // insert backgroundDiv
            $this.wrap( $wrapDiv ).before( $backgroundDiv );
            // do initial check for input
            $this.trigger('keydown');
        },
        updateStyle: function(){
            var _this    = this,
                $this    = this.$element,
                settings = this.settings,
                style    = this.style;

            // textarea style
            this.style = {
                // background   : this.$element.css('background'),
                paddingTop   : parseInt( $this.css('padding-top'), 10 ),
                paddingRight : parseInt( $this.css('padding-right'), 10 ),
                paddingBottom: parseInt( $this.css('padding-bottom'), 10 ),
                paddingLeft  : parseInt( $this.css('padding-left'), 10 ),
            };

            // Hack for firefox, some how width needs to be 2px smallet then the textarea
            // and padding-left needs to be added 1px
            if( browser.firefox ){
                style.paddingRight += 1;
                style.paddingLeft += 1;
            }
            if( browser.iphone ){
                style.paddingRight += 3;
                style.paddingLeft += 3;
            }

            this.$wrapDiv.css({
                'position'     : 'relative',
                'word-wrap'    : 'break-word',
                'word-break'   : 'break-all',
                'margin'       : 0
            });
            this.$backgroundDiv.addClass('background-div').addClass( $this.attr('class') ).css({
                'height'        : '100%',
                'color'         : ( settings.debug ) ? '#f00' : 'transparent',
                // 'background'    : ( settings.debug ) ? '#fee' : style.background,
                // 'padding-top'   : style.paddingTop,
                // 'padding-right' : style.paddingRight,
                // 'padding-bottom': style.paddingBottom,
                // 'padding-left'  : style.paddingLeft,
                'position'      : 'absolute',
                'overflow'      : 'auto',
                'margin'        : '0'
            });
            if (! settings.isCustomeCss) {
                this.$backgroundDiv.css({
                    'padding-top'   : style.paddingTop,
                    'padding-right' : style.paddingRight,
                    'padding-bottom': style.paddingBottom,
                    'padding-left'  : style.paddingLeft,
                    'box-sizing'    : 'border-box',
                    'border-color'  : 'transparent'
                });
            }

            $this.css({
                'color'     : ( settings.debug ) ? 'rgba(0,0,0,0.5)' : 'inherit',
                'position'  : 'relative',
                'background': 'transparent'
            });
        }
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[ pluginName ] = function ( options ) {
        return this.each(function(i) {
            if ( ! $.data( this, "plugin_" + pluginName ) ) {
                $.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
            }
        });
    };

    /**
     *
     * HELPER FUNCTIONS
     *
     */
    var _escapeRegExp = function(str){
        return str.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
    };
    // get curretn bworser type
    var browser = (function(){
        var userAgent = navigator.userAgent,
            msie    = /(msie|trident)/i.test( userAgent ),
            chrome  = /chrome/i.test( userAgent ),
            firefox = /firefox/i.test( userAgent ),
            safari  = /safari/i.test( userAgent ) && !chrome,
            iphone  = /iphone/i.test( userAgent );

        if( msie ){ return { msie: true }; }
        if( chrome ){ return { chrome: true }; }
        if( firefox ){ return { firefox: true }; }
        if( iphone ){ return { iphone: true }; }
        if( safari ){ return { safari: true }; }

        return {
            msie   : false,
            chrome : false,
            firefox: false,
            safari : false,
            iphone : false
        };
    }());

})( jQuery, window, document );<commit_msg>refactoring, create an input check function<commit_after>/**
 * jquery.textareaHighlighter.js 0.2.1
 * jQuery plugin for highlighting text in textarea.
 *
 * alexandre.kirillov@gmail.com
 * MIT license. http://opensource.org/licenses/MIT
 */
;(function ( $, window, document, undefined ) {
    "use strict";

    /**
     *
     * PLUGIN CORE
     *
     */
    var pluginName = "textareaHighlighter",
        defaults = {
            matches: [
                // {'className': '', 'words': []}
            ],
            maxlength: -1,
            maxlengthWarning: '',
            maxlengthElement: null,
            isCustomeCss: false,
            debug: false
        };

    // constructor
    function Plugin ( element, options ) {
        this.element   = element;
        this.$element  = $(this.element);
        this.settings  = $.extend( {}, defaults, this.$element.data(), options );
        this._defaults = defaults;
        this._name     = pluginName;

        // check if plugin was initialized on the element.
        if ( this.$element.data(pluginName) ) { return; }
        this.$element.data(pluginName, true);

        this.style = {};
        this.$wrapDiv       = $(document.createElement('div')).addClass('textarea-highlighter-wrap');
        this.$backgroundDiv = $(document.createElement('div'));

        this.init();
    }

    Plugin.prototype = {
        init: function() {

            var _this          = this,
                $this          = this.$element,
                style          = this.style,
                settings       = this.settings,
                $wrapDiv       = this.$wrapDiv,
                $backgroundDiv = this.$backgroundDiv;

            _this.updateStyle();

            $this
                .data('highlighterTimerId', -1)
                // Bind events
                .on('scroll', function(){
                    $backgroundDiv.scrollTop( $this.scrollTop() );
                })
                .on('textarea.highlighter.update', function(){
                    _this.updateStyle();
                })
                .on('change keydown keyup paste', function(e){
                    _this.change(e);
                });

            // insert backgroundDiv
            $this.wrap( $wrapDiv ).before( $backgroundDiv );
            // do initial check for input
            _this.change({});
        },
        updateStyle: function(){
            var _this    = this,
                $this    = this.$element,
                settings = this.settings,
                style    = this.style;

            // textarea style
            this.style = {
                // background   : this.$element.css('background'),
                paddingTop   : parseInt( $this.css('padding-top'), 10 ),
                paddingRight : parseInt( $this.css('padding-right'), 10 ),
                paddingBottom: parseInt( $this.css('padding-bottom'), 10 ),
                paddingLeft  : parseInt( $this.css('padding-left'), 10 ),
            };

            // Hack for firefox, some how width needs to be 2px smallet then the textarea
            // and padding-left needs to be added 1px
            if( browser.firefox ){
                style.paddingRight += 1;
                style.paddingLeft += 1;
            }
            if( browser.iphone ){
                style.paddingRight += 3;
                style.paddingLeft += 3;
            }

            this.$wrapDiv.css({
                'position'     : 'relative',
                'word-wrap'    : 'break-word',
                'word-break'   : 'break-all',
                'margin'       : 0
            });
            this.$backgroundDiv.addClass('background-div').addClass( $this.attr('class') ).css({
                'height'        : '100%',
                'color'         : ( settings.debug ) ? '#f00' : 'transparent',
                // 'background'    : ( settings.debug ) ? '#fee' : style.background,
                // 'padding-top'   : style.paddingTop,
                // 'padding-right' : style.paddingRight,
                // 'padding-bottom': style.paddingBottom,
                // 'padding-left'  : style.paddingLeft,
                'position'      : 'absolute',
                'overflow'      : 'auto',
                'margin'        : '0'
            });
            if (! settings.isCustomeCss) {
                this.$backgroundDiv.css({
                    'padding-top'   : style.paddingTop,
                    'padding-right' : style.paddingRight,
                    'padding-bottom': style.paddingBottom,
                    'padding-left'  : style.paddingLeft,
                    'box-sizing'    : 'border-box',
                    'border-color'  : 'transparent'
                });
            }

            $this.css({
                'color'     : ( settings.debug ) ? 'rgba(0,0,0,0.5)' : 'inherit',
                'position'  : 'relative',
                'background': 'transparent'
            });
        },
        change: function(e){
            var _this = this;
            // if arrow keys, don't do anything
            if (/(37|38|39|40)/.test(e.keyCode)) { return true; }

            // check for last update, this is for performace
            if (_this.$element.data('highlighterTimerId') !== -1) {
                clearTimeout( _this.$element.data('highlighterTimerId') );
                _this.$element.data('highlighterTimerId', -1);
            }

            var changeId = setTimeout(function(){
                var textareaText = $(document.createElement('div')).text( _this.$element.val() ).html(),
                    key, ruleTextList, matchText, spanText, matchTextList = [],
                    notOverMaxText = '', overMaxText ='',
                    i, imax, j, jmax, maxSize;

                if (0 < _this.settings.maxlength) {
                    // check for max length
                    if ( _this.settings.maxlength < _this.$element.val().length) {
                        matchText = _this.$element.val().slice( _this.settings.maxlength, _this.settings.maxlength + _this.$element.val().length - 1 );
                        overMaxText = ''+ matchText +'';

                    }
                    // update text max length
                    if (_this.settings.maxlengthElement !== null) {
                        maxSize = _this.settings.maxlength - _this.$element.val().length;
                        if (maxSize < 0) {
                            if (! _this.settings.maxlengthElement.hasClass( _this.settings.maxlengthWarning )) {
                                _this.settings.maxlengthElement.addClass( _this.settings.maxlengthWarning );
                            }
                        }
                        else {
                            if (_this.settings.maxlengthElement.hasClass( _this.settings.maxlengthWarning )) {
                                _this.settings.maxlengthElement.removeClass( _this.settings.maxlengthWarning );
                            }
                        }
                        // update max length
                        _this.settings.maxlengthElement.text( maxSize );
                    }

                    notOverMaxText = _this.$element.val().slice( 0, _this.settings.maxlength );
                }
                else {
                    notOverMaxText = textareaText;
                }

                // check for matching words
                for (i = 0, imax = _this.settings.matches.length; i < imax; i++) {
                    for (j = 0, jmax = _this.settings.matches[i].words.length; j < jmax; j++) {
                        // get word to match
                        matchText = _this.settings.matches[i].words[j];
                        // check if word exists in input text
                        if( notOverMaxText.indexOf( matchText ) !== -1 ){
                            matchTextList.push( matchText );
                            spanText = ''+ matchText +'';
                            notOverMaxText = notOverMaxText.replace( new RegExp( _escapeRegExp( matchText ), 'g'), spanText );
                        }
                    }
                }

                // update background div content
                _this.$backgroundDiv.html( notOverMaxText + overMaxText );
                // trigger update event
                _this.$element.trigger('textarea.highlighter.update', {'textList': matchTextList});
            }, 30);

            _this.$element.data('highlighterTimerId', changeId);
        }
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[ pluginName ] = function ( options ) {
        return this.each(function(i) {
            if ( ! $.data( this, "plugin_" + pluginName ) ) {
                $.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
            }
        });
    };

    /**
     *
     * HELPER FUNCTIONS
     *
     */
    var _escapeRegExp = function(str){
        return str.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
    };
    // get curretn bworser type
    var browser = (function(){
        var userAgent = navigator.userAgent,
            msie    = /(msie|trident)/i.test( userAgent ),
            chrome  = /chrome/i.test( userAgent ),
            firefox = /firefox/i.test( userAgent ),
            safari  = /safari/i.test( userAgent ) && !chrome,
            iphone  = /iphone/i.test( userAgent );

        if( msie ){ return { msie: true }; }
        if( chrome ){ return { chrome: true }; }
        if( firefox ){ return { firefox: true }; }
        if( iphone ){ return { iphone: true }; }
        if( safari ){ return { safari: true }; }

        return {
            msie   : false,
            chrome : false,
            firefox: false,
            safari : false,
            iphone : false
        };
    }());

})( jQuery, window, document );<|endoftext|>


<commit_before>const scale = 1000000000; //Allows us to avoid floating point rounding errors

function point(centreX, centreY, label) {

  myPoint = drawing.append("circle")
  .style("stroke", "none") // Do not draw the line
  .style("fill", "none")   // Do not fill
  .attr("class", "point")  //Assign the "point" class so we can later grab/filter it
  .attr("r", 0)            //radius = 0
  .attr("cx", centreX)
  .attr("cy", centreY)
  .attr("label", label)    //This is optional.
  ;                        //It follows geometry textbooks

  return myPoint
}

function circle(centrePoint, radius, colour){
  // Simply draws a circle. Returns an object such as "circle1 = new circle(A, 50)"
  if (typeof colour == 'undefined'){
    colour = "black";
  }

  myCircle = drawing.append("circle")
  .style("stroke", colour)
  .style("fill", "none")
  .attr("r", radius)
  .attr("cx", centrePoint.attr("cx"))
  .attr("cy", centrePoint.attr("cy"))
  .attr("label", "Circle".concat(centrePoint.attr("label"))) //This returns "CircleA" if point A has a label of "A"
  ;

  return myCircle;
}

function circleFilled (centrePoint, radius, colour){
  // Simply draws a circle. Returns an object such as "circle1 = new circleFilled(A, 50)"
  if (typeof colour == 'undefined'){
    colour = "black";
  }

  myFilledCircle = drawing.append("circle")
  .style("stroke", "none")
  .style("fill", colour)
  .attr("r", radius)
  .attr("cx", centrePoint.attr("cx"))
  .attr("cy", centrePoint.attr("cy"))
  .attr("label", "Circle".concat(centrePoint.attr("label"))) //This returns "CircleA" if point A has a label of "A"
  ;

  return myFilledCircle;
}

function lineFromTwoPoints( A, B, strokeWidth, colour ) {
  //Draws a line from two points, and returns the line
  if (typeof colour == 'undefined'){
    colour = "rgb(0,0,50)";
  }
  if (typeof strokeWidth == 'undefined'){
    strokeWidth = 1; //This is the default anyway
  }

  var myLine = drawing.append("svg:line")
  //x to the left
  .attr("x1", A.attr("cx"))
  .attr("y1", A.attr("cy"))
  .attr("x2", B.attr("cx"))
  .attr("y2", B.attr("cy"))
  .attr("stroke-width", strokeWidth)
  .style("stroke", colour);

  return myLine;
}

function circle(centrePoint, radius, colour){
  // Simply draws a circle. Returns an object such as "circle1 = new circle(A, 50)"
  if (typeof colour == 'undefined'){
    colour = "black";
  }

  myCircle = drawing.append("circle")
  .style("stroke", colour)
  .style("fill", "none")
  .attr("r", radius)
  .attr("cx", centrePoint.attr("cx"))
  .attr("cy", centrePoint.attr("cy"))
  .attr("label", "Circle".concat(centrePoint.attr("label"))) //This returns "CircleA" if point A has a label of "A"
  ;

  return myCircle;
}

function circleFilled (centrePoint, radius, colour){
  // Simply draws a circle. Returns an object such as "circle1 = new circleFilled(A, 50)"
  if (typeof colour == 'undefined'){
    colour = "black";
  }

  myFilledCircle = drawing.append("circle")
  .style("stroke", "none")
  .style("fill", colour)
  .attr("r", radius)
  .attr("cx", centrePoint.attr("cx"))
  .attr("cy", centrePoint.attr("cy"))
  .attr("label", "Circle".concat(centrePoint.attr("label"))) //This returns "CircleA" if point A has a label of "A"
  ;

  return myFilledCircle;
}
<commit_msg>Removed duplicate circle functions<commit_after>const scale = 1000000000; //Allows us to avoid floating point rounding errors

function point(centreX, centreY, label) {

  myPoint = drawing.append("circle")
  .style("stroke", "none") // Do not draw the line
  .style("fill", "none")   // Do not fill
  .attr("class", "point")  //Assign the "point" class so we can later grab/filter it
  .attr("r", 0)            //radius = 0
  .attr("cx", centreX)
  .attr("cy", centreY)
  .attr("label", label)    //This is optional.
  ;                        //It follows geometry textbooks

  return myPoint
}

function circle(centrePoint, radius, colour){
  // Simply draws a circle. Returns an object such as "circle1 = new circle(A, 50)"
  if (typeof colour == 'undefined'){
    colour = "black";
  }

  myCircle = drawing.append("circle")
  .style("stroke", colour)
  .style("fill", "none")
  .attr("r", radius)
  .attr("cx", centrePoint.attr("cx"))
  .attr("cy", centrePoint.attr("cy"))
  .attr("label", "Circle".concat(centrePoint.attr("label"))) //This returns "CircleA" if point A has a label of "A"
  ;

  return myCircle;
}

function circleFilled (centrePoint, radius, colour){
  // Simply draws a circle. Returns an object such as "circle1 = new circleFilled(A, 50)"
  if (typeof colour == 'undefined'){
    colour = "black";
  }

  myFilledCircle = drawing.append("circle")
  .style("stroke", "none")
  .style("fill", colour)
  .attr("r", radius)
  .attr("cx", centrePoint.attr("cx"))
  .attr("cy", centrePoint.attr("cy"))
  .attr("label", "Circle".concat(centrePoint.attr("label"))) //This returns "CircleA" if point A has a label of "A"
  ;

  return myFilledCircle;
}

function lineFromTwoPoints( A, B, strokeWidth, colour ) {
  //Draws a line from two points, and returns the line
  if (typeof colour == 'undefined'){
    colour = "rgb(0,0,50)";
  }
  if (typeof strokeWidth == 'undefined'){
    strokeWidth = 1; //This is the default anyway
  }

  var myLine = drawing.append("svg:line")
  //x to the left
  .attr("x1", A.attr("cx"))
  .attr("y1", A.attr("cy"))
  .attr("x2", B.attr("cx"))
  .attr("y2", B.attr("cy"))
  .attr("stroke-width", strokeWidth)
  .style("stroke", colour);

  return myLine;
}
<|endoftext|>


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

/**
 * Main entry point for the 'Graphing Quadratics' sim.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var DecimalsScreen = require( 'GRAPHING_QUADRATICS/decimals/DecimalsScreen' );
  var IntegersScreen = require( 'GRAPHING_QUADRATICS/integers/IntegersScreen' );
  var Sim = require( 'JOIST/Sim' );
  var SimLauncher = require( 'JOIST/SimLauncher' );
  var VertexFormScreen = require( 'GRAPHING_QUADRATICS/vertexform/VertexFormScreen' );

  // strings
  var title = require( 'string!GRAPHING_QUADRATICS/graphing-quadratics.name' );

  var screens = [ new IntegersScreen(), new DecimalsScreen(), new VertexFormScreen() ];

  var options = {
    credits: {
      leadDesign: 'Karina K. R. Hensberry',
      softwareDevelopment: 'Chris Malley',
      team: 'Mike Dubson, Patricia Loeblein, Ariel Paul, Kathy Perkins'
    }
  };

  // Appending '?dev' to the URL will enable developer-only features.
  if ( phet.phetcommon.getQueryParameter( 'dev' ) ) {
    options = _.extend( {
      // add dev-specific options here
      showHomeScreen: false,
      screenIndex: 0
    }, options );
  }

  SimLauncher.launch( function() {
    var sim = new Sim( title, screens, options );
    sim.start();
  } );
} );<commit_msg>phetsims/joist#211 remove screenIndex from @pixelzoom sims<commit_after>// Copyright 2002-2014, University of Colorado Boulder

/**
 * Main entry point for the 'Graphing Quadratics' sim.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var DecimalsScreen = require( 'GRAPHING_QUADRATICS/decimals/DecimalsScreen' );
  var IntegersScreen = require( 'GRAPHING_QUADRATICS/integers/IntegersScreen' );
  var Sim = require( 'JOIST/Sim' );
  var SimLauncher = require( 'JOIST/SimLauncher' );
  var VertexFormScreen = require( 'GRAPHING_QUADRATICS/vertexform/VertexFormScreen' );

  // strings
  var title = require( 'string!GRAPHING_QUADRATICS/graphing-quadratics.name' );

  var screens = [ new IntegersScreen(), new DecimalsScreen(), new VertexFormScreen() ];

  var options = {
    credits: {
      leadDesign: 'Karina K. R. Hensberry',
      softwareDevelopment: 'Chris Malley',
      team: 'Mike Dubson, Patricia Loeblein, Ariel Paul, Kathy Perkins'
    }
  };

  SimLauncher.launch( function() {
    var sim = new Sim( title, screens, options );
    sim.start();
  } );
} );<|endoftext|>


<commit_before>//= require vendor/jquery
//= require vendor/custom.modernizr
//= require vendor/shuffleelements
//= require vendor/fittext

//= require foundation/foundation
//= require foundation/foundation.joyride
//= require foundation/foundation.cookie
//= require foundation/foundation.alerts
//= require foundation/foundation.interchange
//= require foundation/foundation.magellan
//= require foundation/foundation.tooltips
//= require foundation/foundation.placeholder
//= require foundation/foundation.reveal
//= require foundation/foundation.clearing
//= require foundation/foundation.orbit
//= require foundation/foundation.dropdown
//= require foundation/foundation.forms
//= require foundation/foundation.topbar
//= require foundation/foundation.section
//= require_self

function equalizeBoxHeights() {
	$('.boxHeightContainer').each(function() {
		$('.boxHeightColumn', this).css("min-height", 0);

		var highestBox = null;

		$('.boxHeightColumn', this).each(function() {
			if($(this).height() > $(highestBox).height())
				highestBox = $(this);
		});

		var highestOrigSize = $(highestBox).height();

		$('.boxHeightColumn', this).css("min-height", $(highestBox).height() +
			(parseInt($(highestBox).css('padding-top').replace("px", "")) +
			 parseInt($(highestBox).css('padding-bottom').replace("px", ""))));
		$(highestBox).css("min-height", highestOrigSize);
	});
}

$(document).foundation();

$(document).ready(function() {
	equalizeBoxHeights();
	$("#titleText").fitText(1.1, { maxFontSize: '60px' });
	$("#subtitleText").fitText(2.8, { minFontSize: '0px', maxFontSize: '27px' });
	$('.members .memberBox').shuffle();
});

$(window).resize(function() {
	equalizeBoxHeights();
});

<commit_msg>optimized box-height javascript<commit_after>//= require vendor/jquery
//= require vendor/custom.modernizr
//= require vendor/shuffleelements
//= require vendor/fittext

//= require foundation/foundation
//= require foundation/foundation.joyride
//= require foundation/foundation.cookie
//= require foundation/foundation.alerts
//= require foundation/foundation.interchange
//= require foundation/foundation.magellan
//= require foundation/foundation.tooltips
//= require foundation/foundation.placeholder
//= require foundation/foundation.reveal
//= require foundation/foundation.clearing
//= require foundation/foundation.orbit
//= require foundation/foundation.dropdown
//= require foundation/foundation.forms
//= require foundation/foundation.topbar
//= require foundation/foundation.section
//= require_self

//function equalizeBoxHeights() {
//	$('.boxHeightContainer').each(function() {
//		$('.boxHeightColumn', this).css("min-height", 0);
//
//		var highestBox = null;

//		$('.boxHeightColumn', this).each(function() {
//			if($(this).height() > $(highestBox).height())
//				highestBox = $(this);
//		});

//		var highestOrigSize = $(highestBox).height();

//		$('.boxHeightColumn', this).css("min-height", $(highestBox).height() +
//			(parseInt($(highestBox).css('padding-top').replace("px", "")) +
//			 parseInt($(highestBox).css('padding-bottom').replace("px", ""))));
//		$(highestBox).css("min-height", highestOrigSize);
//	});
//}

function equalizeBoxHeights() {
	$('.boxHeightContainer').each(function() {
		$('.boxHeightColumn', this).css("height", "");

		var highestBox = null;

		$('.boxHeightColumn', this).each(function() {
			if($(this).height() > $(highestBox).height())
				highestBox = $(this);
		});

		$('.boxHeightColumn', this).css("height", $(highestBox).height() +
			(parseInt($(highestBox).css('padding-top').replace("px", "")) +
			 parseInt($(highestBox).css('padding-bottom').replace("px", ""))));
	});
}

$(document).foundation();

$(document).ready(function() {
	$("#titleText").fitText(1.1, { maxFontSize: '60px' });
	$("#subtitleText").fitText(2.8, { minFontSize: '0px', maxFontSize: '27px' });
	$('.members .memberBox').shuffle();
});

$(window).load(function() {
	equalizeBoxHeights();
});

$(window).resize(function() {
	equalizeBoxHeights();
});

<|endoftext|>


<commit_before>
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Page change transition core
//>>label: Transition Core
//>>group: Transitions
//>>css: ../css/themes/default/jquery.mobile.theme.css, ../css/structure/jquery.mobile.transitions.css

define( [ "jquery", "./jquery.mobile.core" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, window, undefined ) {

var createHandler = function( sequential ){

	// Default to sequential
	if( sequential === undefined ){
		sequential = true;
	}

	return function( name, reverse, $to, $from ) {

		var deferred = new $.Deferred(),
			reverseClass = reverse ? " reverse" : "",
			active	= $.mobile.urlHistory.getActive(),
			toScroll = active.lastScroll || $.mobile.defaultHomeScroll,
			screenHeight = $.mobile.getScreenHeight(),
			maxTransitionOverride = $.mobile.maxTransitionWidth !== false && $( window ).width() > $.mobile.maxTransitionWidth,
			none = !$.support.cssTransitions || maxTransitionOverride || !name || name === "none",
			toggleViewportClass = function(){
				$.mobile.pageContainer.toggleClass( "ui-mobile-viewport-transitioning viewport-" + name );
			},
			cleanFrom = function(){
				$from
					.removeClass( $.mobile.activePageClass + " out in reverse " + name )
					.height( "" );
			},
			startOut = function(){
				// if it's not sequential, call the doneOut transition to start the TO page animating in simultaneously
				if( !sequential ){
					doneOut();
				}
				else {
					$from.animationComplete( doneOut );
				}

				// Set the from page's height and start it transitioning out
				// Note: setting an explicit height helps eliminate tiling in the transitions
				$from
					.height( screenHeight + $(window ).scrollTop() )
					.addClass( name + " out" + reverseClass );
			},

			doneOut = function() {

				if ( $from && sequential ) {
					cleanFrom();
				}

				startIn();
			},

			startIn = function(){

				$to.addClass( $.mobile.activePageClass );

				// Send focus to page as it is now display: block
				$.mobile.focusPage( $to );

				// Set to page height
				$to.height( screenHeight + toScroll );

				// By using scrollTo instead of silentScroll, we can keep things better in order
				window.scrollTo( 0, toScroll );

				if( !none ){
					$to.animationComplete( doneIn );
				}

				$to.addClass( name + " in" + reverseClass );

				if( none ){
					doneIn();
				}

			},

			doneIn = function() {

				if ( !sequential ) {

					if( $from ){
						cleanFrom();
					}
				}

				$to
					.removeClass( "out in reverse " + name )
					.height( "" );

				toggleViewportClass();

				// In some browsers (iOS5), 3D transitions block the ability to scroll to the desired location during transition
				// This ensures we jump to that spot after the fact, if we aren't there already.
				if( $( window ).scrollTop() !== toScroll ){
					window.scrollTo( 0, toScroll );
				}

				deferred.resolve( name, reverse, $to, $from, true );
			};

		toggleViewportClass();

		if ( $from && !none ) {
			startOut();
		}
		else {
			doneOut();
		}

		return deferred.promise();
	};
}

// generate the handlers from the above
var sequentialHandler = createHandler(),
	simultaneousHandler = createHandler( false );

// Make our transition handler the public default.
$.mobile.defaultTransitionHandler = sequentialHandler;

//transition handler dictionary for 3rd party transitions
$.mobile.transitionHandlers = {
	"default": $.mobile.defaultTransitionHandler,
	"sequential": sequentialHandler,
	"simultaneous": simultaneousHandler
};

$.mobile.transitionFallbacks = {};

})( jQuery, this );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");<commit_msg>since we're not using silentScroll, manually disable scrollstart listening during scroll to match its behavior<commit_after>
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Page change transition core
//>>label: Transition Core
//>>group: Transitions
//>>css: ../css/themes/default/jquery.mobile.theme.css, ../css/structure/jquery.mobile.transitions.css

define( [ "jquery", "./jquery.mobile.core" ], function( $ ) {
//>>excludeEnd("jqmBuildExclude");
(function( $, window, undefined ) {

var createHandler = function( sequential ){

	// Default to sequential
	if( sequential === undefined ){
		sequential = true;
	}

	return function( name, reverse, $to, $from ) {

		var deferred = new $.Deferred(),
			reverseClass = reverse ? " reverse" : "",
			active	= $.mobile.urlHistory.getActive(),
			toScroll = active.lastScroll || $.mobile.defaultHomeScroll,
			screenHeight = $.mobile.getScreenHeight(),
			maxTransitionOverride = $.mobile.maxTransitionWidth !== false && $( window ).width() > $.mobile.maxTransitionWidth,
			none = !$.support.cssTransitions || maxTransitionOverride || !name || name === "none",
			toggleViewportClass = function(){
				$.mobile.pageContainer.toggleClass( "ui-mobile-viewport-transitioning viewport-" + name );
			},
			scrollPage = function(){
				// By using scrollTo instead of silentScroll, we can keep things better in order
				// Just to be precautios, disable scrollstart listening like silentScroll would
				$.event.special.scrollstart.enabled = false;

				window.scrollTo( 0, toScroll );

				// reenable scrollstart listening like silentScroll would
				setTimeout(function() {
					$.event.special.scrollstart.enabled = true;
				}, 150 );
			},
			cleanFrom = function(){
				$from
					.removeClass( $.mobile.activePageClass + " out in reverse " + name )
					.height( "" );
			},
			startOut = function(){
				// if it's not sequential, call the doneOut transition to start the TO page animating in simultaneously
				if( !sequential ){
					doneOut();
				}
				else {
					$from.animationComplete( doneOut );
				}

				// Set the from page's height and start it transitioning out
				// Note: setting an explicit height helps eliminate tiling in the transitions
				$from
					.height( screenHeight + $(window ).scrollTop() )
					.addClass( name + " out" + reverseClass );
			},

			doneOut = function() {

				if ( $from && sequential ) {
					cleanFrom();
				}

				startIn();
			},

			startIn = function(){

				$to.addClass( $.mobile.activePageClass );

				// Send focus to page as it is now display: block
				$.mobile.focusPage( $to );

				// Set to page height
				$to.height( screenHeight + toScroll );

				scrollPage();

				if( !none ){
					$to.animationComplete( doneIn );
				}

				$to.addClass( name + " in" + reverseClass );

				if( none ){
					doneIn();
				}

			},

			doneIn = function() {

				if ( !sequential ) {

					if( $from ){
						cleanFrom();
					}
				}

				$to
					.removeClass( "out in reverse " + name )
					.height( "" );

				toggleViewportClass();

				// In some browsers (iOS5), 3D transitions block the ability to scroll to the desired location during transition
				// This ensures we jump to that spot after the fact, if we aren't there already.
				if( $( window ).scrollTop() !== toScroll ){
					scrollPage();
				}

				deferred.resolve( name, reverse, $to, $from, true );
			};

		toggleViewportClass();

		if ( $from && !none ) {
			startOut();
		}
		else {
			doneOut();
		}

		return deferred.promise();
	};
}

// generate the handlers from the above
var sequentialHandler = createHandler(),
	simultaneousHandler = createHandler( false );

// Make our transition handler the public default.
$.mobile.defaultTransitionHandler = sequentialHandler;

//transition handler dictionary for 3rd party transitions
$.mobile.transitionHandlers = {
	"default": $.mobile.defaultTransitionHandler,
	"sequential": sequentialHandler,
	"simultaneous": simultaneousHandler
};

$.mobile.transitionFallbacks = {};

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


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

const MIME = require('./mime');
const { arrayBufferToBlob, blobToArrayBuffer, dataURLToBlob } = require('blob-util');
const { autoOrientImage } = require('../auto_orient_image');
const { migrateDataToFileSystem } = require('./attachment/migrate_data_to_file_system');

// // Incoming message attachment fields
// {
//   id: string
//   contentType: MIMEType
//   data: ArrayBuffer
//   digest: ArrayBuffer
//   fileName: string | null
//   flags: null
//   key: ArrayBuffer
//   size: integer
//   thumbnail: ArrayBuffer
// }

// // Outgoing message attachment fields
// {
//   contentType: MIMEType
//   data: ArrayBuffer
//   fileName: string
//   size: integer
// }

// Returns true if `rawAttachment` is a valid attachment based on our current schema.
// Over time, we can expand this definition to become more narrow, e.g. require certain
// fields, etc.
exports.isValid = (rawAttachment) => {
  // NOTE: We cannot use `_.isPlainObject` because `rawAttachment` is
  // deserialized by protobuf:
  if (!rawAttachment) {
    return false;
  }

  return true;
};

// Upgrade steps
exports.autoOrientJPEG = async (attachment) => {
  if (!MIME.isJPEG(attachment.contentType)) {
    return attachment;
  }

  const dataBlob = await arrayBufferToBlob(attachment.data, attachment.contentType);
  const newDataBlob = await dataURLToBlob(await autoOrientImage(dataBlob));
  const newDataArrayBuffer = await blobToArrayBuffer(newDataBlob);

  // IMPORTANT: We overwrite the existing `data` `ArrayBuffer` losing the original
  // image data. Ideally, we’d preserve the original image data for users who want to
  // retain it but due to reports of data loss, we don’t want to overburden IndexedDB
  // by potentially doubling stored image data.
  // See: https://github.com/signalapp/Signal-Desktop/issues/1589
  const newAttachment = Object.assign({}, attachment, {
    data: newDataArrayBuffer,
    size: newDataArrayBuffer.byteLength,
  });

  // `digest` is no longer valid for auto-oriented image data, so we discard it:
  delete newAttachment.digest;

  return newAttachment;
};

const UNICODE_LEFT_TO_RIGHT_OVERRIDE = '\u202D';
const UNICODE_RIGHT_TO_LEFT_OVERRIDE = '\u202E';
const UNICODE_REPLACEMENT_CHARACTER = '\uFFFD';
const INVALID_CHARACTERS_PATTERN = new RegExp(
  `[${UNICODE_LEFT_TO_RIGHT_OVERRIDE}${UNICODE_RIGHT_TO_LEFT_OVERRIDE}]`,
  'g'
);
// NOTE: Expose synchronous version to do property-based testing using `testcheck`,
// which currently doesn’t support async testing:
// https://github.com/leebyron/testcheck-js/issues/45
exports._replaceUnicodeOrderOverridesSync = (attachment) => {
  if (!isString(attachment.fileName)) {
    return attachment;
  }

  const normalizedFilename = attachment.fileName.replace(
    INVALID_CHARACTERS_PATTERN,
    UNICODE_REPLACEMENT_CHARACTER
  );
  const newAttachment = Object.assign({}, attachment, {
    fileName: normalizedFilename,
  });

  return newAttachment;
};

exports.replaceUnicodeOrderOverrides = async attachment =>
  exports._replaceUnicodeOrderOverridesSync(attachment);

exports.removeSchemaVersion = (attachment) => {
  if (!exports.isValid(attachment)) {
    console.log('Attachment.removeSchemaVersion: Invalid input attachment:', attachment);
    return attachment;
  }

  const attachmentWithoutSchemaVersion = Object.assign({}, attachment);
  delete attachmentWithoutSchemaVersion.schemaVersion;
  return attachmentWithoutSchemaVersion;
};

exports.migrateDataToFileSystem = migrateDataToFileSystem;

//      hasData :: Attachment -> Boolean
exports.hasData = attachment =>
  attachment.data instanceof ArrayBuffer || ArrayBuffer.isView(attachment.data);

//      loadData :: (RelativePath -> IO (Promise ArrayBuffer))
//                  Attachment ->
//                  IO (Promise Attachment)
exports.loadData = (readAttachmentData) => {
  if (!isFunction(readAttachmentData)) {
    throw new TypeError("'readAttachmentData' must be a function");
  }

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

    const isAlreadyLoaded = exports.hasData(attachment);
    if (isAlreadyLoaded) {
      return attachment;
    }

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

    const data = await readAttachmentData(attachment.path);
    return Object.assign({}, attachment, { data });
  };
};

//      deleteData :: (RelativePath -> IO Unit)
//                    Attachment ->
//                    IO Unit
exports.deleteData = (deleteAttachmentData) => {
  if (!isFunction(deleteAttachmentData)) {
    throw new TypeError("'deleteAttachmentData' must be a function");
  }

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

    const hasDataInMemory = exports.hasData(attachment);
    if (hasDataInMemory) {
      return;
    }

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

    await deleteAttachmentData(attachment.path);
  };
};
<commit_msg>Use `is` instead of Lodash `is*`<commit_after>const is = require('@sindresorhus/is');

const MIME = require('./mime');
const { arrayBufferToBlob, blobToArrayBuffer, dataURLToBlob } = require('blob-util');
const { autoOrientImage } = require('../auto_orient_image');
const { migrateDataToFileSystem } = require('./attachment/migrate_data_to_file_system');

// // Incoming message attachment fields
// {
//   id: string
//   contentType: MIMEType
//   data: ArrayBuffer
//   digest: ArrayBuffer
//   fileName: string | null
//   flags: null
//   key: ArrayBuffer
//   size: integer
//   thumbnail: ArrayBuffer
// }

// // Outgoing message attachment fields
// {
//   contentType: MIMEType
//   data: ArrayBuffer
//   fileName: string
//   size: integer
// }

// Returns true if `rawAttachment` is a valid attachment based on our current schema.
// Over time, we can expand this definition to become more narrow, e.g. require certain
// fields, etc.
exports.isValid = (rawAttachment) => {
  // NOTE: We cannot use `_.isPlainObject` because `rawAttachment` is
  // deserialized by protobuf:
  if (!rawAttachment) {
    return false;
  }

  return true;
};

// Upgrade steps
exports.autoOrientJPEG = async (attachment) => {
  if (!MIME.isJPEG(attachment.contentType)) {
    return attachment;
  }

  const dataBlob = await arrayBufferToBlob(attachment.data, attachment.contentType);
  const newDataBlob = await dataURLToBlob(await autoOrientImage(dataBlob));
  const newDataArrayBuffer = await blobToArrayBuffer(newDataBlob);

  // IMPORTANT: We overwrite the existing `data` `ArrayBuffer` losing the original
  // image data. Ideally, we’d preserve the original image data for users who want to
  // retain it but due to reports of data loss, we don’t want to overburden IndexedDB
  // by potentially doubling stored image data.
  // See: https://github.com/signalapp/Signal-Desktop/issues/1589
  const newAttachment = Object.assign({}, attachment, {
    data: newDataArrayBuffer,
    size: newDataArrayBuffer.byteLength,
  });

  // `digest` is no longer valid for auto-oriented image data, so we discard it:
  delete newAttachment.digest;

  return newAttachment;
};

const UNICODE_LEFT_TO_RIGHT_OVERRIDE = '\u202D';
const UNICODE_RIGHT_TO_LEFT_OVERRIDE = '\u202E';
const UNICODE_REPLACEMENT_CHARACTER = '\uFFFD';
const INVALID_CHARACTERS_PATTERN = new RegExp(
  `[${UNICODE_LEFT_TO_RIGHT_OVERRIDE}${UNICODE_RIGHT_TO_LEFT_OVERRIDE}]`,
  'g'
);
// NOTE: Expose synchronous version to do property-based testing using `testcheck`,
// which currently doesn’t support async testing:
// https://github.com/leebyron/testcheck-js/issues/45
exports._replaceUnicodeOrderOverridesSync = (attachment) => {
  if (!is.string(attachment.fileName)) {
    return attachment;
  }

  const normalizedFilename = attachment.fileName.replace(
    INVALID_CHARACTERS_PATTERN,
    UNICODE_REPLACEMENT_CHARACTER
  );
  const newAttachment = Object.assign({}, attachment, {
    fileName: normalizedFilename,
  });

  return newAttachment;
};

exports.replaceUnicodeOrderOverrides = async attachment =>
  exports._replaceUnicodeOrderOverridesSync(attachment);

exports.removeSchemaVersion = (attachment) => {
  if (!exports.isValid(attachment)) {
    console.log('Attachment.removeSchemaVersion: Invalid input attachment:', attachment);
    return attachment;
  }

  const attachmentWithoutSchemaVersion = Object.assign({}, attachment);
  delete attachmentWithoutSchemaVersion.schemaVersion;
  return attachmentWithoutSchemaVersion;
};

exports.migrateDataToFileSystem = migrateDataToFileSystem;

//      hasData :: Attachment -> Boolean
exports.hasData = attachment =>
  attachment.data instanceof ArrayBuffer || ArrayBuffer.isView(attachment.data);

//      loadData :: (RelativePath -> IO (Promise ArrayBuffer))
//                  Attachment ->
//                  IO (Promise Attachment)
exports.loadData = (readAttachmentData) => {
  if (!is.function(readAttachmentData)) {
    throw new TypeError("'readAttachmentData' must be a function");
  }

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

    const isAlreadyLoaded = exports.hasData(attachment);
    if (isAlreadyLoaded) {
      return attachment;
    }

    if (!is.string(attachment.path)) {
      throw new TypeError("'attachment.path' is required");
    }

    const data = await readAttachmentData(attachment.path);
    return Object.assign({}, attachment, { data });
  };
};

//      deleteData :: (RelativePath -> IO Unit)
//                    Attachment ->
//                    IO Unit
exports.deleteData = (deleteAttachmentData) => {
  if (!is.function(deleteAttachmentData)) {
    throw new TypeError("'deleteAttachmentData' must be a function");
  }

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

    const hasDataInMemory = exports.hasData(attachment);
    if (hasDataInMemory) {
      return;
    }

    if (!is.string(attachment.path)) {
      throw new TypeError("'attachment.path' is required");
    }

    await deleteAttachmentData(attachment.path);
  };
};
<|endoftext|>


<commit_before>Agenda = require('agenda');
var Mongo = require('../db/mongo.js');
var Addic7ed = require('../libs/addic7ed.js');
var Conf = require('../conf.js');
var Main = require('../main.js');
var TvMaze = require('../libs/tvMaze.js');

var pendingShowInterval = '1 month';
var intervalSchedule = '*/15 * * * *'; //every 15 minutes
//var intervalSchedule = '1 minute'; //test
var connectionString;
var usable = false;
var agenda = null;

exports.startAgenda = function(){
    Mongo.getMongoConnection().db.collection('agendaJobs', function (err, collection) {
        collection.update({}, {
            $set: {nextRunAt: new Date()}
        }, {multi: true}, function (error, numUnlocked) {
            if (error) console.log("Error: " + error);
        });
    });

    Mongo.getMongoConnection().db.collection('agendaJobs', function (err, collection) {
        collection.find(function (error, cursor) {
            if (error){
                console.log("Error: " + error);
            }else{
                cursor.forEach(function(job) {
                    cancelJob(job.name);
                    var tokens = job.name.split("_");
                    Mongo.Alert.findOne({ show_name: tokens[0], language: tokens[1] }, function (err, jobAlert) {
                        activateStoredSchedules(jobAlert, Main.getBotInstance(), new Date(job.nextRunAt) <= new Date());
                        // scheduleFunctionInterval(job.name, intervalSchedule, jobAlert, function (jobInterval, doneJobInterval) {
                        //     Addic7ed.addic7edGetSubtitleAlert(jobAlert, jobInterval, Main.getBotInstance(), doneJobInterval);},
                        //         { hasToBeRemoved: false });
                    });
                });
            }
        });
    });
}

var scheduleFunctionGivenTime = function (jobName, date, alert, func, data) {
    var agenda = new Agenda({ mongo: Mongo.getMongoConnection() });
    data = (typeof data !== 'undefined') ? data : {};
    agenda.define(jobName, function (job, done) {
        job.alert = alert;
        func(job, done);
    });
    agenda.on("ready", function () {
        agenda.schedule(formatDate(date), jobName, data);
        //agenda.schedule(new Date(Date.now() + 5000), jobName, data); //test
        agenda.start();
        console.log("Job %s scheduled with nextRunAt %s", jobName, date);
    })
    agenda.on('complete', function (job) {
        console.log('Job %s finished', job.attrs.name);
        agenda.cancel({ name: job.attrs.name }, function (err, numRemoved) {
            console.log("%s jobs removed named %s", numRemoved, job.attrs.name);
        });
    });
}

var scheduleFunctionInterval = function (jobName, interval, alert, func, data) {
    var agenda = new Agenda({ mongo: Mongo.getMongoConnection() });
    data = data || {};
    agenda.define(jobName, function (job1, done2) {
        job1.alert = alert;
        func(job1, done2);
    });
    agenda.on("ready", function () {
        agenda.every(interval, jobName, data);
        agenda.start();
    });
    agenda.on('complete', function (job) {
        console.log('Job %s finished', job.attrs.name);
        if (job.attrs.data.hasToBeRemoved) {
            var getShowPromise = TvMaze.getShowInfosById(job.alert.showId);
            getShowPromise.then(function (show) {
                const nextEpisodeLink = show._links.nextepisode.href;
                if (show.status != 'Running') {
                    Mongo.deleteAlert(job.alert._id.toString());
                    Mongo.deleteAlertFromAllUsers(job.alert);
                    agenda.cancel({ name: job.attrs.name }, function (err, numRemoved) {
                        console.log("Removed %s jobs with name %s", numRemoved, job.attrs.name);
                    });
                } else {
                    if (nextEpisodeLink) {
                        var nextEpisodePromise = TvMaze.getNextEpisodeInformation(nextEpisodeLink);
                        nextEpisodePromise.then(function (nextEp) {
                            console.log("RE_ASSIGNING NEXTRUNB AL JOB: ", nextEp.airdate);
                            // job.alert.nextepisode_airdate = nextEp.airdate;
                            // activateStoredSchedules(job.alert, Main.getBotInstance(), false);
                            updateNextRunDate(job, nextEp.airdate);
                        });
                    } else {
                        bot.sendMessage(userDoc.chatId, Common.noNextEpisodeYetMessage);
                        // TODO Job Pending task su trello (#29)
                    }
                }
            });
        }
    });
}

var formatDate = function (date) {
    // starts at 00.00 of airDate
    if(!date) return new Date();
    return new Date(date + " 00:00:00");
}

var activateStoredSchedules = function (alert, bot, outdated) {
    var date = outdated ? formatDate() : alert.nextepisode_airdate;
    scheduleFunctionGivenTime(alert.show_name + '_' + alert.language + '_giventime', date, alert, function (jobDate, doneJobDate) {
        scheduleFunctionInterval(alert.show_name + '_' + alert.language + '_interval', intervalSchedule, alert, function (jobInterval, doneJobInterval) {
            Addic7ed.addic7edGetSubtitleAlert(alert, jobInterval, bot, doneJobInterval);
        }, { hasToBeRemoved: false });
        doneJobDate();
    });
}

var updateNextRunDate = function (job, newDate) {
    job.nextRunAt = formatDate(newDate);
    job.save(function (err) {
        if (!err)
            console.log("Job %s nextRunAt successfully edited to %s", job.attrs.name, formatDate(newDate));
    });
}

var cancelJob = function (jobName) {
    var agenda = new Agenda({ mongo: Mongo.getMongoConnection() });
    agenda.cancel({ name: jobName }, function (err, numRemoved) {
        console.log("Removed %s jobs with name %s", numRemoved, jobName);
    });
}

exports.formatDate = formatDate;
exports.activateStoredSchedules = activateStoredSchedules;
exports.scheduleFunctionGivenTime = scheduleFunctionGivenTime;
exports.scheduleFunctionInterval = scheduleFunctionInterval;
exports.updateNextRunDate = updateNextRunDate;
exports.cancelJob = cancelJob;<commit_msg>added defaultLockTime<commit_after>Agenda = require('agenda');
var Mongo = require('../db/mongo.js');
var Addic7ed = require('../libs/addic7ed.js');
var Conf = require('../conf.js');
var Main = require('../main.js');
var TvMaze = require('../libs/tvMaze.js');

var pendingShowInterval = '1 month';
var intervalSchedule = '*/15 * * * *'; //every 15 minutes
//var intervalSchedule = '1 minute'; //test
var connectionString;
var usable = false;
var agenda = null;

exports.startAgenda = function(){
    Mongo.getMongoConnection().db.collection('agendaJobs', function (err, collection) {
        collection.update({}, {
            $set: {nextRunAt: new Date()}
        }, {multi: true}, function (error, numUnlocked) {
            if (error) console.log("Error: " + error);
        });
    });

    Mongo.getMongoConnection().db.collection('agendaJobs', function (err, collection) {
        collection.find(function (error, cursor) {
            if (error){
                console.log("Error: " + error);
            }else{
                cursor.forEach(function(job) {
                    cancelJob(job.name);
                    var tokens = job.name.split("_");
                    Mongo.Alert.findOne({ show_name: tokens[0], language: tokens[1] }, function (err, jobAlert) {
                        activateStoredSchedules(jobAlert, Main.getBotInstance(), new Date(job.nextRunAt) <= new Date());
                        // scheduleFunctionInterval(job.name, intervalSchedule, jobAlert, function (jobInterval, doneJobInterval) {
                        //     Addic7ed.addic7edGetSubtitleAlert(jobAlert, jobInterval, Main.getBotInstance(), doneJobInterval);},
                        //         { hasToBeRemoved: false });
                    });
                });
            }
        });
    });
}

var scheduleFunctionGivenTime = function (jobName, date, alert, func, data) {
    var agenda = new Agenda({ mongo: Mongo.getMongoConnection() });
    agenda.defaultLockLifetime(1000*60*1000);
    data = (typeof data !== 'undefined') ? data : {};
    agenda.define(jobName, function (job, done) {
        job.alert = alert;
        func(job, done);
    });
    agenda.on("ready", function () {
        agenda.schedule(formatDate(date), jobName, data);
        //agenda.schedule(new Date(Date.now() + 5000), jobName, data); //test
        agenda.start();
        console.log("Job %s scheduled with nextRunAt %s", jobName, date);
    })
    agenda.on('complete', function (job) {
        console.log('Job %s finished', job.attrs.name);
        agenda.cancel({ name: job.attrs.name }, function (err, numRemoved) {
            console.log("%s jobs removed named %s", numRemoved, job.attrs.name);
        });
    });
}

var scheduleFunctionInterval = function (jobName, interval, alert, func, data) {
    var agenda = new Agenda({ mongo: Mongo.getMongoConnection() });
    agenda.defaultLockLifetime(1000*60*1000);
    data = data || {};
    agenda.define(jobName, function (job1, done2) {
        job1.alert = alert;
        func(job1, done2);
    });
    agenda.on("ready", function () {
        agenda.every(interval, jobName, data);
        agenda.start();
    });
    agenda.on('complete', function (job) {
        console.log('Job %s finished', job.attrs.name);
        if (job.attrs.data.hasToBeRemoved) {
            var getShowPromise = TvMaze.getShowInfosById(job.alert.showId);
            getShowPromise.then(function (show) {
                const nextEpisodeLink = show._links.nextepisode.href;
                if (show.status != 'Running') {
                    Mongo.deleteAlert(job.alert._id.toString());
                    Mongo.deleteAlertFromAllUsers(job.alert);
                    agenda.cancel({ name: job.attrs.name }, function (err, numRemoved) {
                        console.log("Removed %s jobs with name %s", numRemoved, job.attrs.name);
                    });
                } else {
                    if (nextEpisodeLink) {
                        var nextEpisodePromise = TvMaze.getNextEpisodeInformation(nextEpisodeLink);
                        nextEpisodePromise.then(function (nextEp) {
                            console.log("RE_ASSIGNING NEXTRUNB AL JOB: ", nextEp.airdate);
                            // job.alert.nextepisode_airdate = nextEp.airdate;
                            // activateStoredSchedules(job.alert, Main.getBotInstance(), false);
                            updateNextRunDate(job, nextEp.airdate);
                        });
                    } else {
                        bot.sendMessage(userDoc.chatId, Common.noNextEpisodeYetMessage);
                        // TODO Job Pending task su trello (#29)
                    }
                }
            });
        }
    });
}

var formatDate = function (date) {
    // starts at 00.00 of airDate
    if(!date) return new Date();
    return new Date(date + " 00:00:00");
}

var activateStoredSchedules = function (alert, bot, outdated) {
    var date = outdated ? formatDate() : alert.nextepisode_airdate;
    scheduleFunctionGivenTime(alert.show_name + '_' + alert.language + '_giventime', date, alert, function (jobDate, doneJobDate) {
        scheduleFunctionInterval(alert.show_name + '_' + alert.language + '_interval', intervalSchedule, alert, function (jobInterval, doneJobInterval) {
            Addic7ed.addic7edGetSubtitleAlert(alert, jobInterval, bot, doneJobInterval);
        }, { hasToBeRemoved: false });
        doneJobDate();
    });
}

var updateNextRunDate = function (job, newDate) {
    job.nextRunAt = formatDate(newDate);
    job.save(function (err) {
        if (!err)
            console.log("Job %s nextRunAt successfully edited to %s", job.attrs.name, formatDate(newDate));
    });
}

var cancelJob = function (jobName) {
    var agenda = new Agenda({ mongo: Mongo.getMongoConnection() });
    agenda.cancel({ name: jobName }, function (err, numRemoved) {
        console.log("Removed %s jobs with name %s", numRemoved, jobName);
    });
}

exports.formatDate = formatDate;
exports.activateStoredSchedules = activateStoredSchedules;
exports.scheduleFunctionGivenTime = scheduleFunctionGivenTime;
exports.scheduleFunctionInterval = scheduleFunctionInterval;
exports.updateNextRunDate = updateNextRunDate;
exports.cancelJob = cancelJob;<|endoftext|>


<commit_before>var drilldownProps = {
    sources: [{
        locator: null,
        singleLineFieldName: "LH_ADDRESS",
        outFields: ["*"],
        name: "LH 5.3 LLPG",
        maxResults: 250
    }],
};

describe("A set of tests for the Drilldown widget", function () {
    var _Drilldown, widget, server,
        loadWidget = function (done) {
            require(["app/Drilldown", "app/Locators/LLPGLocator", "esri/SpatialReference", "esri/dijit/Search"], function (DrillDown, LLPGLocator, SpatialReference) {
                var llpgLocator = new LLPGLocator("http://testserver/LocatorHub/arcgis/rest/services/FAKELOCATOR/ADDRESS/GeocodeServer");
                llpgLocator.setOutSpatialReference(new SpatialReference({ wkid: 27700 }));
                drilldownProps.sources[0].locator = llpgLocator;

                widget = new DrillDown(drilldownProps, 'widget');

                _Drilldown = DrillDown;

                widget.startup();
                done();
            });
        };

    var setupSinon = function () {
        server = sinon.fakeServer.create();
        server.autoRespond = true;
        server.autoRespondAfter = 257;
        server.respondImmediately = true;

        server.respondWith("http://testserver/LocatorHub/arcgis/rest/info?f=json", [
            200,
            {
                "Content-Type": "application/json"
            },
            JSON.stringify("")
        ]);

        server.respondWith("GET", "http://testserver/LocatorHub/arcgis/rest/services/FAKELOCATOR/ADDRESS/GeocodeServer/findAddressCandidates?LH_ADDRESS=EH8%208AS&f=json&outSR=%7B%22wkid%22%3A4326%7D&outFields=*&maxLocations=250&callback=dojo.io.script.jsonp_dojoIoScript1._jsonpCallback", [
            200,
            {
                "Content-Type": "application/json"
            },
            JSON.stringify(postcodeResults)
        ]);
    };

    beforeEach(function (done) {
        loadWidget(done);
    });

    afterEach(function () {
        if (widget) {
            widget.clear();
            widget.destroy();
            widget = null;
        }
        if (server) {
            server.restore();
        }
    });

    it("should not be null", function (done) {
        expect(widget).not.toEqual(null);
        done();
    });

    it("should provide _isNullOrEmpty function", function (done) {
        expect(widget._isNullOrEmpty(null)).toEqual(true);
        done();
    });

    it("should clear the list of picklists", function (done) {
        var destroyFunc = function() {
            return true;
        };
        widget._titleGroups.push({ destroy: destroyFunc }, { destroy: destroyFunc });

        widget._clearPicklist();
        expect(widget._titleGroups.length).toEqual(0);

        done();
    });

    it("should search for an address and return a picklist", function (done) {
        //setupSinon();
        var searchStub = sinon.stub(widget, "search", function () {
            var res = this._hydrateResults(postcodeResults);
            this._buildPickListUi([res]);
        });
        widget.search("EH8 8AS")

        expect(widget._titleGroups.length).toEqual(1);
        done();
    });

    it("should clear the results of a search", function (done) {
        //setupSinon();

        var searchStub = sinon.stub(widget, "search", function () {
            var res = this._hydrateResults(postcodeResults);
            this._buildPickListUi([res]);
        });

        widget.search("EH8 8AS")

        expect(widget._titleGroups.length).toEqual(1);

        widget.clear();

        expect(widget._titleGroups.length).toEqual(0);

        done();
    });

    it("should handle no results", function (done) {
        widget.search("")
        expect(widget._titleGroups.length).toEqual(0);
        widget.clear();
        expect(widget._titleGroups.length).toEqual(0);

        var searchStub = sinon.stub(widget, "search", function () {
            var res = { PickListItems: []};
            this._buildPickListUi([res]);
        });
        widget.search("")
        expect(widget._titleGroups.length).toEqual(1);
        done();
    });

    it("should handle a single result", function (done) {
        var searchStub = sinon.stub(widget, "search", function () {
            var res = this._hydrateResults(singleResult);
            this._buildPickListUi([res]);
        });

        widget.search("7 Harrison Road")

        expect(widget._titleGroups.length).toEqual(1);
        widget.clear();

        done();
    });

    it("should handle a single level with multiple result", function (done) {
        var searchStub = sinon.stub(widget, "search", function () {
            var res = this._hydrateResults(singleLevelMulti);
            this._buildPickListUi([res]);
        });

        widget.search("1 Harrison Road")

        expect(widget._titleGroups.length).toEqual(1);
        widget.clear();

        done();
    });
});<commit_msg>Fix broken unit test<commit_after>var drilldownProps = {
    sources: [{
        locator: null,
        singleLineFieldName: "LH_ADDRESS",
        outFields: ["*"],
        name: "LH 5.3 LLPG",
        maxResults: 250
    }],
};

describe("A set of tests for the Drilldown widget", function () {
    var _Drilldown, widget, server,
        loadWidget = function (done) {
            require(["app/Drilldown", "app/Locators/LLPGLocator", "esri/SpatialReference", "esri/dijit/Search"], function (DrillDown, LLPGLocator, SpatialReference) {
                var llpgLocator = new LLPGLocator("http://testserver/LocatorHub/arcgis/rest/services/FAKELOCATOR/ADDRESS/GeocodeServer");
                llpgLocator.setOutSpatialReference(new SpatialReference({ wkid: 27700 }));
                drilldownProps.sources[0].locator = llpgLocator;

                widget = new DrillDown(drilldownProps, 'widget');

                _Drilldown = DrillDown;

                widget.startup();
                done();
            });
        };

    var setupSinon = function () {
        server = sinon.fakeServer.create();
        server.autoRespond = true;
        server.autoRespondAfter = 257;
        server.respondImmediately = true;

        server.respondWith("http://testserver/LocatorHub/arcgis/rest/info?f=json", [
            200,
            {
                "Content-Type": "application/json"
            },
            JSON.stringify("")
        ]);

        server.respondWith("GET", "http://testserver/LocatorHub/arcgis/rest/services/FAKELOCATOR/ADDRESS/GeocodeServer/findAddressCandidates?LH_ADDRESS=EH8%208AS&f=json&outSR=%7B%22wkid%22%3A4326%7D&outFields=*&maxLocations=250&callback=dojo.io.script.jsonp_dojoIoScript1._jsonpCallback", [
            200,
            {
                "Content-Type": "application/json"
            },
            JSON.stringify(postcodeResults)
        ]);
    };

    beforeEach(function (done) {
        loadWidget(done);
    });

    afterEach(function () {
        if (widget) {
            widget.clear();
            widget.destroy();
            widget = null;
        }
        if (server) {
            server.restore();
        }
    });

    it("should not be null", function (done) {
        expect(widget).not.toEqual(null);
        done();
    });

    it("should provide _isNullOrEmpty function", function (done) {
        expect(widget._isNullOrEmpty(null)).toEqual(true);
        done();
    });

    it("should clear the list of picklists", function (done) {
        var destroyFunc = function() {
            return true;
        };
        widget._titleGroups.push({ destroy: destroyFunc }, { destroy: destroyFunc });

        widget._clearPicklist();
        expect(widget._titleGroups.length).toEqual(0);

        done();
    });

    it("should search for an address and return a picklist", function (done) {
        //setupSinon();
        var searchStub = sinon.stub(widget, "search", function () {
            var res = this._hydrateResults(postcodeResults);
            this._buildPickListUi([res]);
        });
        widget.search("EH8 8AS")

        expect(widget._titleGroups.length).toEqual(1);
        done();
    });

    it("should clear the results of a search", function (done) {
        //setupSinon();

        var searchStub = sinon.stub(widget, "search", function () {
            var res = this._hydrateResults(postcodeResults);
            this._buildPickListUi([res]);
        });

        widget.search("EH8 8AS")

        expect(widget._titleGroups.length).toEqual(1);

        widget.clear();

        expect(widget._titleGroups.length).toEqual(0);

        done();
    });

    it("should handle no results", function (done) {
        widget.search("")
        expect(widget._titleGroups.length).toEqual(0);
        widget.clear();
        expect(widget._titleGroups.length).toEqual(0);

        var searchStub = sinon.stub(widget, "search", function () {
            var res = { PickListItems: []};
            this._buildPickListUi([res]);
        });
        widget.search("")
        expect(widget._titleGroups.length).toEqual(0);
        done();
    });

    it("should handle a single result", function (done) {
        var searchStub = sinon.stub(widget, "search", function () {
            var res = this._hydrateResults(singleResult);
            this._buildPickListUi([res]);
        });

        widget.search("7 Harrison Road")

        expect(widget._titleGroups.length).toEqual(1);
        widget.clear();

        done();
    });

    it("should handle a single level with multiple result", function (done) {
        var searchStub = sinon.stub(widget, "search", function () {
            var res = this._hydrateResults(singleLevelMulti);
            this._buildPickListUi([res]);
        });

        widget.search("1 Harrison Road")

        expect(widget._titleGroups.length).toEqual(1);
        widget.clear();

        done();
    });
});<|endoftext|>


<commit_before>'use strict';

var path = require('path');

var rootPath = {
  dev: path.resolve(__dirname, '../../'),
  tmp: path.resolve(__dirname, '../../.tmp/'),
  theme: path.resolve(__dirname, '../../../')
};

module.exports = {
  tmp: {
    css: path.resolve(rootPath.tmp, './assets/css'),
    sass: path.resolve(rootPath.tmp, './assets/sass'),
    js: path.resolve(rootPath.tmp, './assets/js'),
    images: path.resolve(rootPath.tmp, './assets/images'),
    svg: path.resolve(rootPath.tmp, './assets/svg'),
    fonts: path.resolve(rootPath.tmp, './assets/fonts')
  },
  dev: {
    css: path.resolve(rootPath.dev, './assets/css'),
    sass: path.resolve(rootPath.dev, './assets/sass'),
    js: path.resolve(rootPath.dev, './assets/js'),
    images: path.resolve(rootPath.dev, './assets/images'),
    svg: path.resolve(rootPath.dev, './assets/svg'),
    fonts: path.resolve(rootPath.dev, './assets/fonts')
  },
  theme: {
    css: path.resolve(rootPath.theme, './assets/stylesheets'),
    fonts: path.resolve(rootPath.theme, './assets/fonts'),
    images: path.resolve(rootPath.theme, './assets/images'),
    js: path.resolve(rootPath.theme, './assets/scripts'),
    svg: path.resolve(rootPath.theme, './assets/images/svg')
  }
};
<commit_msg>Added assets and self paths for each location to paths.<commit_after>'use strict';

var path = require('path');

var rootPath = {
  dev: path.resolve(__dirname, '../../'),
  tmp: path.resolve(__dirname, '../../.tmp/'),
  theme: path.resolve(__dirname, '../../../')
};

module.exports = {
  tmp: {
    _self: path.resolve(rootPath.tmp, './'),
    assets: path.resolve(rootPath.tmp, './assets'),
    css: path.resolve(rootPath.tmp, './assets/css'),
    sass: path.resolve(rootPath.tmp, './assets/sass'),
    js: path.resolve(rootPath.tmp, './assets/js'),
    images: path.resolve(rootPath.tmp, './assets/images'),
    svg: path.resolve(rootPath.tmp, './assets/svg'),
    fonts: path.resolve(rootPath.tmp, './assets/fonts')
  },
  dev: {
    _self: path.resolve(rootPath.dev, './'),
    assets: path.resolve(rootPath.dev, './assets'),
    css: path.resolve(rootPath.dev, './assets/css'),
    sass: path.resolve(rootPath.dev, './assets/sass'),
    js: path.resolve(rootPath.dev, './assets/js'),
    images: path.resolve(rootPath.dev, './assets/images'),
    svg: path.resolve(rootPath.dev, './assets/svg'),
    fonts: path.resolve(rootPath.dev, './assets/fonts')
  },
  theme: {
    _self: path.resolve(rootPath.theme, './'),
    assets: path.resolve(rootPath.theme, './assets'),
    css: path.resolve(rootPath.theme, './assets/stylesheets'),
    fonts: path.resolve(rootPath.theme, './assets/fonts'),
    images: path.resolve(rootPath.theme, './assets/images'),
    js: path.resolve(rootPath.theme, './assets/scripts'),
    svg: path.resolve(rootPath.theme, './assets/images/svg')
  }
};
<|endoftext|>


<commit_before>var path = require('path');
var pkg = require('../package.json');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var bannerPack = new webpack.BannerPlugin({
  banner:
    'Quill Editor v' + pkg.version + '\n' +
    'https://quilljs.com/\n' +
    'Copyright (c) 2014, Jason Chen\n' +
    'Copyright (c) 2013, salesforce.com',
  entryOnly: true
});
var constantPack = new webpack.DefinePlugin({
  QUILL_VERSION: JSON.stringify(pkg.version)
});

var source = [
  'quill.js',
  'core.js',
  'blots',
  'core',
  'formats',
  'modules',
  'test',
  'themes',
  'ui'
].map(function(file) {
  return path.resolve(__dirname, '..', file);
});

module.exports = function(env) {
  let config = {
    context: path.resolve(__dirname, '..'),
    entry: {
      'quill.js': ['./quill.js'],
      'quill.core.js': ['./core.js'],
      'quill.core': './assets/core.styl',
      'quill.bubble': './assets/bubble.styl',
      'quill.snow': './assets/snow.styl',
      'unit.js': './test/unit.js'
    },
    output: {
      filename: '[name]',
      library: 'Quill',
      libraryTarget: 'umd',
      path: path.resolve(__dirname, '../dist/')
    },
    resolve: {
      alias: {
        'parchment': path.resolve(__dirname, '../node_modules/parchment/src/parchment')
      },
      extensions: ['.js', '.styl', '.ts']
    },
    module: {
      rules: [{
        test: /\.js$/,
        use: ['eslint-loader'],
        include: source,
        enforce: 'pre'
      }, {
        test: /\.ts$/,
        use: [{
          loader: 'ts-loader',
          options: {
            compilerOptions: {
              declaration: false,
              target: 'es5',
              module: 'commonjs'
            },
            transpileOnly: true
          }
        }]
      }, {
        test: /\.styl$/,
        include: [
          path.resolve(__dirname, '../assets')
        ],
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            'css-loader',
            'stylus-loader'
          ]
        })
      }, {
        test: /\.svg$/,
        include: [
          path.resolve(__dirname, '../assets/icons')
        ],
        use: [{
          loader: 'html-loader',
          options: {
            minimize: true
          }
        }]
      }, {
        test: /\.js$/,
        include: source,
        use: [{
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }]
      }],
      noParse: [
        /\/node_modules\/clone\/clone\.js$/,
        /\/node_modules\/eventemitter3\/index\.js$/,
        /\/node_modules\/extend\/index\.js$/
      ]
    },
    plugins: [
      bannerPack,
      constantPack,
      new ExtractTextPlugin({
        filename: '[name].css',
        allChunks: true
      })
    ],
    devServer: {
      contentBase: path.resolve(__dirname, '../dist'),
      hot: false,
      port: process.env.npm_package_config_ports_webpack,
      stats: 'minimal'
    }
  };

  if (env && env.dev) {
    config.module.rules = config.module.rules.slice(1);   // Remove linter
    config.module.rules[3].use[0].options = {
      plugins: ['transform-es2015-modules-commonjs']
    };
  }

  if (env && env.minimize) {
    config.entry = {
      'quill.min.js': './quill.js'
    };
    config.plugins.push(
      new webpack.optimize.UglifyJsPlugin({
        sourceMap: true
      })
    );
    config.devtool = 'source-map';
  }

  if (env && env.coverage) {
    config.module.rules[4].use[0].options = {
      plugins: ['istanbul', 'transform-es2015-modules-commonjs']
    };
  }

  return config;
};
<commit_msg>fix webpack dev server<commit_after>var path = require('path');
var pkg = require('../package.json');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var bannerPack = new webpack.BannerPlugin({
  banner:
    'Quill Editor v' + pkg.version + '\n' +
    'https://quilljs.com/\n' +
    'Copyright (c) 2014, Jason Chen\n' +
    'Copyright (c) 2013, salesforce.com',
  entryOnly: true
});
var constantPack = new webpack.DefinePlugin({
  QUILL_VERSION: JSON.stringify(pkg.version)
});

var source = [
  'quill.js',
  'core.js',
  'blots',
  'core',
  'formats',
  'modules',
  'test',
  'themes',
  'ui'
].map(function(file) {
  return path.resolve(__dirname, '..', file);
});

module.exports = function(env) {
  let config = {
    context: path.resolve(__dirname, '..'),
    entry: {
      'quill.js': ['./quill.js'],
      'quill.core.js': ['./core.js'],
      'quill.core': './assets/core.styl',
      'quill.bubble': './assets/bubble.styl',
      'quill.snow': './assets/snow.styl',
      'unit.js': './test/unit.js'
    },
    output: {
      filename: '[name]',
      library: 'Quill',
      libraryTarget: 'umd',
      path: path.resolve(__dirname, '../dist/')
    },
    resolve: {
      alias: {
        'parchment': path.resolve(__dirname, '../node_modules/parchment/src/parchment')
      },
      extensions: ['.js', '.styl', '.ts']
    },
    module: {
      rules: [{
        test: /\.js$/,
        use: ['eslint-loader'],
        include: source,
        enforce: 'pre'
      }, {
        test: /\.ts$/,
        use: [{
          loader: 'ts-loader',
          options: {
            compilerOptions: {
              declaration: false,
              target: 'es5',
              module: 'commonjs'
            },
            transpileOnly: true
          }
        }]
      }, {
        test: /\.styl$/,
        include: [
          path.resolve(__dirname, '../assets')
        ],
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            'css-loader',
            'stylus-loader'
          ]
        })
      }, {
        test: /\.svg$/,
        include: [
          path.resolve(__dirname, '../assets/icons')
        ],
        use: [{
          loader: 'html-loader',
          options: {
            minimize: true
          }
        }]
      }, {
        test: /\.js$/,
        include: source,
        use: [{
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }]
      }],
      noParse: [
        /\/node_modules\/clone\/clone\.js$/,
        /\/node_modules\/eventemitter3\/index\.js$/,
        /\/node_modules\/extend\/index\.js$/
      ]
    },
    plugins: [
      bannerPack,
      constantPack,
      new ExtractTextPlugin({
        filename: '[name].css',
        allChunks: true
      })
    ],
    devServer: {
      contentBase: path.resolve(__dirname, '../dist'),
      hot: false,
      port: process.env.npm_package_config_ports_webpack,
      stats: 'minimal',
      disableHostCheck: true
    }
  };

  if (env && env.dev) {
    config.module.rules = config.module.rules.slice(1);   // Remove linter
    config.module.rules[3].use[0].options = {
      plugins: ['transform-es2015-modules-commonjs']
    };
  }

  if (env && env.minimize) {
    config.entry = {
      'quill.min.js': './quill.js'
    };
    config.plugins.push(
      new webpack.optimize.UglifyJsPlugin({
        sourceMap: true
      })
    );
    config.devtool = 'source-map';
  }

  if (env && env.coverage) {
    config.module.rules[4].use[0].options = {
      plugins: ['istanbul', 'transform-es2015-modules-commonjs']
    };
  }

  return config;
};
<|endoftext|>