<commit_before>/*
* jQuery dumbCrossFade
* v2.0.0
* https://github.com/kevindb/jquery-dumbcrossfade
*
* jQuery DumbCrossFade is intended to be a light-weight slide transition that enables external manipulation.
*
* Copyright 2015 Kevin Morris
* Copyright 2009 Jason Sebring
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
*/

(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define(['jquery-1.7.2'], factory);
	} else if (typeof module === 'object' && module.exports) {
		// Node/CommonJS
		module.exports = function( root, jQuery ) {
			if ( jQuery === undefined ) {
				// require('jQuery') returns a factory that requires window to
				// build a jQuery instance, we normalize how we use modules
				// that require this pattern but the window provided is a noop
				// if it's defined (how jquery works)
				if ( typeof window !== 'undefined' ) {
					jQuery = require('jquery-1.7.2');
				}
				else {
					jQuery = require('jquery-1.7.2')(root);
				}
			}
			factory(jQuery);
			return jQuery;
		};
	} else {
		// Browser globals
		factory(jQuery);
	}
}(function($) {
	$.fn.dumbCrossFade = function(settings) {

		var publicAccessorLabel = 'dumbCrossFade.publicAccessor';
		var configLabel = 'dumbCrossFade.config';

		if (typeof(this.data(publicAccessorLabel)) !== 'undefined' && this.data(publicAccessorLabel) !== null) {
			var pa = this.data(publicAccessorLabel);
			var cg = this.data(configLabel);
			var args = Array.prototype.slice.apply(arguments);
			if (args.length > 0) {
				if (typeof(args[0]) === 'object') {
					if (settings) $.extend(cg, settings);
					var args = Array.prototype.slice.apply(arguments);
					if (args.length > 1) {
						args = args.slice(1,args.length);
					} else {
						pa.start();
						return this;
					}
				}
				if (arguments.length === 1) {
					pa[arguments[0]]();
				} else if (arguments.length > 1) {
					var args = Array.prototype.slice.apply(arguments);
					args = args.slice(1,args.length);
					pa[arguments[0]].apply(this,args);
				}
			}
			return this;
		}

		var config = {
			'slideType':'slidehorizontal',
			'index':0,
			'showTime':5000,
			'transitionTime':1000,
			'doHoverPause':true,
			'maxZIndex':100,
			'slideChange':null,
			'direction':'forward',
			'fadeInOut':false
		},
		timeOut = null,
		itemArray = [],
		blockAnimation = false,
		lastIndexRequest = -1,
		$self = this
		$window = $(window),
		$body = $('body');

		if (settings) $.extend(config, settings);

		function cancelSlideShow() {
			if (timeOut !== null) { window.clearTimeout(timeOut); timeOut = null; }
		}

		function doSlideShowNow() {
			if (blockAnimation) {
				if (arguments.length > 0) {
					lastIndexRequest = arguments[0];
				}
				return;
			}
			var currentIndex = config.index;
			var nextIndex = (arguments.length > 0) ? arguments[0] : (config.index >= itemArray.length - 1) ? 0 : config.index + 1;
			if (config.direction === 'backward') {
				if (currentIndex === 0) {
					nextIndex = itemArray.length - 1;
				} else {
					nextIndex = currentIndex - 1;
				}
			}
			if (currentIndex == nextIndex) { return; }
			var $f = itemArray[currentIndex].show(),
			$n = itemArray[nextIndex];
			blockAnimation = true;
			doneF = function () {
				$f.hide();
				if (config.fadeInOut) {
					$f.css({'opacity':'1.0'});
					$n.css({'opacity':'1.0'});
				}
				blockAnimation = false;
				if (lastIndexRequest != -1) {
					doSlideShowNow(lastIndexRequest);
					lastIndexRequest = -1;
				}
			};
			$f.css('z-index',(config.maxZIndex-1)+'');
			$n.css('z-index',config.maxZIndex+'');
			switch (config.slideType) {
				case 'slidehorizontal' :
					var pos = $f.position(),
					width = $f.width(),
					adjustX = '-='+width;
					if (config.direction === 'forward') {
						$n.css({'left':(parseInt(pos.left) + width) + 'px'});
					} else {
						$n.css({'left':(parseInt(pos.left) - width) + 'px'});
						adjustX = '+='+width;
					}
					if (config.fadeInOut) {
						$n.css({'opacity':'0','display':'block'});
						$f.animate({'left':adjustX,'opacity':'0'},config.transitionTime,'swing');
						$n.animate({'left':adjustX,'opacity':'1.0'},config.transitionTime,'swing',doneF);
					} else {
						$n.show();
						$f.animate({'left':adjustX},config.transitionTime,'swing');
						$n.animate({'left':adjustX},config.transitionTime,'swing',doneF);
					}
					break;
				case 'slidevertical' :
					var pos = $f.position(),
					height = $f.height(),
					adjustY = '-='+height;
					if (config.direction === 'forward') {
						$n.css({'top':(parseInt(pos.top) + height) + 'px','display':'block'});
					} else {
						$n.css({'top':(parseInt(pos.top) - height) + 'px','display':'block'});
						adjustY = '+='+height;
					}
					if (config.fadeInOut) {
						$n.css({'opacity':'0','display':'block'});
						$f.animate({'top':adjustY,'opacity':'0'},config.transitionTime,'swing');
						$n.animate({'top':adjustY,'opacity':'1.0'},config.transitionTime,'swing',doneF);
					}
					else {
						$n.show();
						$f.animate({'top':adjustY},config.transitionTime);
						$n.animate({'top':adjustY},config.transitionTime,doneF);
					}
					break;
				case 'fade' :
					$n.fadeIn(config.transitionTime,doneF);
					break;
			}
			if (config.slideChange !== null) {
				config.slideChange(nextIndex);
			}
			config.index = nextIndex;
		}

		function doSlideShow() {
			cancelSlideShow();
			timeOut = window.setTimeout(function() {
				doSlideShowNow();
				doSlideShow();
			},config.showTime);
		}

		$self.each(function() {
			(itemArray.length === config.index) ? $(this).show() : $(this).hide();
			if (itemArray.length === 0) {
				if (config.doHoverPause) {
					$(this).parent().hover(
						function() {
							cancelSlideShow();
						},
						function() {
							cancelSlideShow();
							doSlideShow();
						}
					);
				}
			}
			itemArray[itemArray.length] = $(this);
		});

		var publicAccessor = {
			'jump' : function (index) {
				cancelSlideShow();
				doSlideShowNow(index);
				return publicAccessor;
			},
			'start' : function () {
				$self.children().hide();
				itemArray[config.index].show();
				config.direction = 'forward';
				doSlideShow();
			},
			'stop' : function () {
				cancelSlideShow();
			},
			'next' : function () {
				config.direction = 'forward';
				cancelSlideShow();
				doSlideShowNow();
			},
			'previous' : function () {
				config.direction = 'backward';
				cancelSlideShow();
				doSlideShowNow();
			}
		};

		this.data(publicAccessorLabel,publicAccessor);
		this.data(configLabel,config);

		doSlideShow();

		return this;
	};
}));
<commit_msg>Iterates to version 2.1.0<commit_after>/*
* jQuery dumbCrossFade
* v2.1.0
* https://github.com/kevindb/jquery-dumbcrossfade
*
* jQuery DumbCrossFade is intended to be a light-weight slide transition that enables external manipulation.
*
* Copyright 2015 Kevin Morris
* Copyright 2009 Jason Sebring
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
*/

(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define(['jquery-1.7.2'], factory);
	} else if (typeof module === 'object' && module.exports) {
		// Node/CommonJS
		module.exports = function( root, jQuery ) {
			if ( jQuery === undefined ) {
				// require('jQuery') returns a factory that requires window to
				// build a jQuery instance, we normalize how we use modules
				// that require this pattern but the window provided is a noop
				// if it's defined (how jquery works)
				if ( typeof window !== 'undefined' ) {
					jQuery = require('jquery-1.7.2');
				}
				else {
					jQuery = require('jquery-1.7.2')(root);
				}
			}
			factory(jQuery);
			return jQuery;
		};
	} else {
		// Browser globals
		factory(jQuery);
	}
}(function($) {
	$.fn.dumbCrossFade = function(settings) {

		var publicAccessorLabel = 'dumbCrossFade.publicAccessor';
		var configLabel = 'dumbCrossFade.config';

		if (typeof(this.data(publicAccessorLabel)) !== 'undefined' && this.data(publicAccessorLabel) !== null) {
			var pa = this.data(publicAccessorLabel);
			var cg = this.data(configLabel);
			var args = Array.prototype.slice.apply(arguments);
			if (args.length > 0) {
				if (typeof(args[0]) === 'object') {
					if (settings) $.extend(cg, settings);
					var args = Array.prototype.slice.apply(arguments);
					if (args.length > 1) {
						args = args.slice(1,args.length);
					} else {
						pa.start();
						return this;
					}
				}
				if (arguments.length === 1) {
					pa[arguments[0]]();
				} else if (arguments.length > 1) {
					var args = Array.prototype.slice.apply(arguments);
					args = args.slice(1,args.length);
					pa[arguments[0]].apply(this,args);
				}
			}
			return this;
		}

		var config = {
			'slideType':'slidehorizontal',
			'index':0,
			'showTime':5000,
			'transitionTime':1000,
			'doHoverPause':true,
			'maxZIndex':100,
			'slideChange':null,
			'direction':'forward',
			'fadeInOut':false
		},
		timeOut = null,
		itemArray = [],
		blockAnimation = false,
		lastIndexRequest = -1,
		$self = this
		$window = $(window),
		$body = $('body');

		if (settings) $.extend(config, settings);

		function cancelSlideShow() {
			if (timeOut !== null) { window.clearTimeout(timeOut); timeOut = null; }
		}

		function doSlideShowNow() {
			if (blockAnimation) {
				if (arguments.length > 0) {
					lastIndexRequest = arguments[0];
				}
				return;
			}
			var currentIndex = config.index;
			var nextIndex = (arguments.length > 0) ? arguments[0] : (config.index >= itemArray.length - 1) ? 0 : config.index + 1;
			if (config.direction === 'backward') {
				if (currentIndex === 0) {
					nextIndex = itemArray.length - 1;
				} else {
					nextIndex = currentIndex - 1;
				}
			}
			if (currentIndex == nextIndex) { return; }
			var $f = itemArray[currentIndex].show(),
			$n = itemArray[nextIndex];
			blockAnimation = true;
			doneF = function () {
				$f.hide();
				if (config.fadeInOut) {
					$f.css({'opacity':'1.0'});
					$n.css({'opacity':'1.0'});
				}
				blockAnimation = false;
				if (lastIndexRequest != -1) {
					doSlideShowNow(lastIndexRequest);
					lastIndexRequest = -1;
				}
			};
			$f.css('z-index',(config.maxZIndex-1)+'');
			$n.css('z-index',config.maxZIndex+'');
			switch (config.slideType) {
				case 'slidehorizontal' :
					var pos = $f.position(),
					width = $f.width(),
					adjustX = '-='+width;
					if (config.direction === 'forward') {
						$n.css({'left':(parseInt(pos.left) + width) + 'px'});
					} else {
						$n.css({'left':(parseInt(pos.left) - width) + 'px'});
						adjustX = '+='+width;
					}
					if (config.fadeInOut) {
						$n.css({'opacity':'0','display':'block'});
						$f.animate({'left':adjustX,'opacity':'0'},config.transitionTime,'swing');
						$n.animate({'left':adjustX,'opacity':'1.0'},config.transitionTime,'swing',doneF);
					} else {
						$n.show();
						$f.animate({'left':adjustX},config.transitionTime,'swing');
						$n.animate({'left':adjustX},config.transitionTime,'swing',doneF);
					}
					break;
				case 'slidevertical' :
					var pos = $f.position(),
					height = $f.height(),
					adjustY = '-='+height;
					if (config.direction === 'forward') {
						$n.css({'top':(parseInt(pos.top) + height) + 'px','display':'block'});
					} else {
						$n.css({'top':(parseInt(pos.top) - height) + 'px','display':'block'});
						adjustY = '+='+height;
					}
					if (config.fadeInOut) {
						$n.css({'opacity':'0','display':'block'});
						$f.animate({'top':adjustY,'opacity':'0'},config.transitionTime,'swing');
						$n.animate({'top':adjustY,'opacity':'1.0'},config.transitionTime,'swing',doneF);
					}
					else {
						$n.show();
						$f.animate({'top':adjustY},config.transitionTime);
						$n.animate({'top':adjustY},config.transitionTime,doneF);
					}
					break;
				case 'fade' :
					$n.fadeIn(config.transitionTime,doneF);
					break;
			}
			if (config.slideChange !== null) {
				config.slideChange(nextIndex);
			}
			config.index = nextIndex;
		}

		function doSlideShow() {
			cancelSlideShow();
			timeOut = window.setTimeout(function() {
				doSlideShowNow();
				doSlideShow();
			},config.showTime);
		}

		$self.each(function() {
			(itemArray.length === config.index) ? $(this).show() : $(this).hide();
			if (itemArray.length === 0) {
				if (config.doHoverPause) {
					$(this).parent().hover(
						function() {
							cancelSlideShow();
						},
						function() {
							cancelSlideShow();
							doSlideShow();
						}
					);
				}
			}
			itemArray[itemArray.length] = $(this);
		});

		var publicAccessor = {
			'jump' : function (index) {
				cancelSlideShow();
				doSlideShowNow(index);
				return publicAccessor;
			},
			'start' : function () {
				$self.children().hide();
				itemArray[config.index].show();
				config.direction = 'forward';
				doSlideShow();
			},
			'stop' : function () {
				cancelSlideShow();
			},
			'next' : function () {
				config.direction = 'forward';
				cancelSlideShow();
				doSlideShowNow();
			},
			'previous' : function () {
				config.direction = 'backward';
				cancelSlideShow();
				doSlideShowNow();
			}
		};

		this.data(publicAccessorLabel,publicAccessor);
		this.data(configLabel,config);

		doSlideShow();

		return this;
	};
}));
<|endoftext|>


<commit_before>/* global $ */

import { createLinkButton, createVideoElement } from './UiElementCreator';
import { formatFileSize } from './utils';
import { roundToHundredths, roundToTenths, formatPercentage, zeroSafeDiv } from './maths';
import { getBaqendUrl } from './SpeedKitUrlService';

/**
 * @param {string} elementId
 * @param {*} data
 * @param {{ caching: boolean }} testOptions
 */
export function displayTestResults(elementId, data, testOptions) {
  const lastVisualChange = roundToTenths((data.lastVisualChange / 1000) % 60);
  $(`.${elementId}-speedIndex`).html(`${data.speedIndex}ms`);
  $(`.${elementId}-firstMeaningfulPaint`).html(`${data.firstMeaningfulPaint}ms`);
  $(`.${elementId}-dom`).html(`${data.domLoaded}ms`);
  $(`.${elementId}-fullyLoaded`).html(`${data.fullyLoaded}ms`);
  $(`.${elementId}-lastVisualChange`).html(`${roundToHundredths(lastVisualChange)}s`);

  if (testOptions.caching) {
    $(`.${elementId}-ttfb`).html('-');
  } else {
    $(`.${elementId}-ttfb`).html(`${data.ttfb}ms`);
  }
  $('.testResults').removeClass('invisible');
}

/**
 * @param {{ caching: boolean }} testOptions
 * @param {*} result
 */
export function displayTestResultsById(testOptions, result) {
  const dataView = testOptions.caching ? 'repeatView' : 'firstView';
  const videoView = testOptions.caching ? 'videoFileRepeatView' : 'videoFileFirstView';
  const competitorResult = result.competitorTestResult;
  const speedKitResult = result.speedKitTestResult;

  $('.center-vertical').removeClass('center-vertical');
  $('.numberOfHosts').html(result.psiDomains);
  $('.numberOfRequests').html(result.psiRequests);

  // Test whether the bytes value is a string or an integer
  // (needed because the data type was switched from string to int)
  if (/^\d+$/.test(result.psiResponseSize)) {
    $('.numberOfBytes').html(formatFileSize(result.psiResponseSize, 2));
  } else {
    $('.numberOfBytes').html(result.psiResponseSize);
  }

  $('#compareContent').removeClass('hidden');
  $('#printButton').removeClass('hidden');
  $('#informationContent').removeClass('hidden');
  $('#boostWorthiness').removeClass('hidden');
  $('.infoBox').fadeOut(0);
  $('.hideOnDefault').addClass('hidden');
  $('#competitorLink').removeClass('hidden').empty();
  $('#speedKitLink').removeClass('hidden').empty();

  if (competitorResult.location.indexOf('us') !== -1) {
    $('#location_left').prop('checked', true);
  }

  $('#caching_left').prop('checked', result.caching);
  $('#mobile_right').prop('checked', !!result.mobile);

  displayTestResults('competitor', competitorResult[dataView], testOptions);
  $('#competitor').empty().append(createVideoElement('video-competitor', competitorResult[videoView].url));

  displayTestResults('speedKit', speedKitResult[dataView], testOptions);

  if (/^https/.test(competitorResult.url)) {
    $('#competitorLink').append(createLinkButton(competitorResult.url));
    $('#speedKitLink').append(createLinkButton(getBaqendUrl(competitorResult.url, result.whitelist)));
  }

  $('#speedKit').empty().append(createVideoElement('video-speedKit', speedKitResult[videoView].url));
}

/**
 * @param {Error} error
 */
export function verifyWarningMessage(error) {
  if (error) {
    $('#warningMessage').text(() => {
      switch (error.message) {
        case 'Too many requests':
          return 'You reached the maximum number of running tests. Please wait at least one ' +
            'minute until you start further tests!';
        case 'Baqend app detected':
          return 'Your website already uses baqend´s technology. Please choose another website ' +
            'to be tested!';
        case 'Low served rate':
          return 'The number of resources served by the Speed Kit is quite low. Choose some of the suggested ' +
            'domains to improve the test result.';
        case 'Bad result':
          return 'It looks like some fine-tuning or configuration is required to measure your site. Please contact our ' +
            'web performance experts for further information and assistance!';
        case 'Show FMC':
          return 'Because your website uses a lot of asynchronous resources, we replaced the speed index metric ' +
            'by the first meaningful paint!';
        default:
          return 'While running the test an error occurred. Please retry the test or contact our ' +
            'web performance experts for further information and assistance!';
      }
    });

    $('#warningAlert').removeClass('hidden');
  }
}

/**
 * @param {*} competitorData
 * @param {*} speedKitData
 */
export function isSpeedIndexSatisfactory(competitorData, speedKitData) {
  if (competitorData.speedIndex > 0 && speedKitData.speedIndex > 0) {
    const speedIndexFactor = roundToHundredths(competitorData.speedIndex / speedKitData.speedIndex);
    return speedIndexFactor > 1.2;
  }
  return false;
}

/**
 * @param {*} competitorData
 * @param {*} speedKitData
 */
export function isFMPSatisfactory(competitorData, speedKitData) {
  if (competitorData.firstMeaningfulPaint > 0 && speedKitData.firstMeaningfulPaint > 0) {
    const firstMeaningfulPaintFactor =
      roundToHundredths(competitorData.firstMeaningfulPaint / speedKitData.firstMeaningfulPaint);
    return firstMeaningfulPaintFactor > 1.2;
  }
  return false;
}

/**
 * @param {*} data
 * @return {string}
 */
export function calculateServedRequests(data) {
  const totalRequests = data.requests || 0;

  const cacheHits = data.hits.hit || 0;
  const cacheMisses = data.hits.miss || 0;
  const otherRequests = data.hits.other || 0;

  // eslint-disable-next-line no-console
  console.log(`hit: ${cacheHits} miss: ${cacheMisses} other: ${otherRequests} total: ${totalRequests}`);

  const servedFactor = (totalRequests - otherRequests) / totalRequests;
  return formatPercentage(servedFactor);
}

/**
 * @param {*} speedKitData
 */
export function isServedRateSatisfactory(speedKitData) {
  return calculateServedRequests(speedKitData) >= 30;
}

/**
 * @param {number} competitorValue
 * @param {number} speedKitValue
 */
export function calculateFactor(competitorValue, speedKitValue) {
  return roundToHundredths(zeroSafeDiv(competitorValue, speedKitValue));
}

/**
 * @param {*} competitorValue
 * @param {*} speedKitValue
 */
export function calculateRevenueBoost(competitorValue, speedKitValue) {
  const factor = calculateFactor(competitorValue, speedKitValue);
  $('.boostValue').text(factor);

  const publisherRevenue = Math.round(((competitorValue - speedKitValue) / (19000 - 5000)) * 100);
  $('.publisherRevenue').text(`${publisherRevenue}%`);

  const eCommerceRevenue = Math.round((competitorValue - speedKitValue) * 0.01);
  $('.eCommerceRevenue').text(`${eCommerceRevenue}%`);
}

/**
 * @param {*} competitor A data view of the competitor's page results.
 * @param {*} speedKit A data view of Speed Kit's page results.
 * @param {{ caching: boolean }} testOptions
 */
export function calculateFactors(competitor, speedKit, testOptions) {
  const fasterStr = factor => `${factor}x ${factor > 1 ? 'Faster' : ''}`;

  const props = {
    speedIndex: $('.speedIndex-factor'),
    firstMeaningfulPaint: $('.firstMeaningfulPaint-factor'),
    domLoaded: $('.dom-factor'),
    fullyLoaded: $('.fullyLoaded-factor'),
    lastVisualChange: $('.lastVisualChange-factor'),
  };

  Object.entries(props).forEach(([key, $element]) => {
    const factor = calculateFactor(competitor[key], speedKit[key]);
    $element.html(fasterStr(factor));
  });

  if (!testOptions.caching) {
    const ttfbFactor = calculateFactor(competitor.ttfb, speedKit.ttfb);
    $('.ttfb-factor').html(fasterStr(ttfbFactor));
  } else {
    $('.ttfb-factor').html('');
  }
}
<commit_msg>Fix language in TestResultHandler<commit_after>/* global $ */

import { createLinkButton, createVideoElement } from './UiElementCreator';
import { formatFileSize } from './utils';
import { roundToHundredths, roundToTenths, formatPercentage, zeroSafeDiv } from './maths';
import { getBaqendUrl } from './SpeedKitUrlService';

/**
 * @param {string} elementId
 * @param {*} data
 * @param {{ caching: boolean }} testOptions
 */
export function displayTestResults(elementId, data, testOptions) {
  const lastVisualChange = roundToTenths((data.lastVisualChange / 1000) % 60);
  $(`.${elementId}-speedIndex`).html(`${data.speedIndex}ms`);
  $(`.${elementId}-firstMeaningfulPaint`).html(`${data.firstMeaningfulPaint}ms`);
  $(`.${elementId}-dom`).html(`${data.domLoaded}ms`);
  $(`.${elementId}-fullyLoaded`).html(`${data.fullyLoaded}ms`);
  $(`.${elementId}-lastVisualChange`).html(`${roundToHundredths(lastVisualChange)}s`);

  if (testOptions.caching) {
    $(`.${elementId}-ttfb`).html('-');
  } else {
    $(`.${elementId}-ttfb`).html(`${data.ttfb}ms`);
  }
  $('.testResults').removeClass('invisible');
}

/**
 * @param {{ caching: boolean }} testOptions
 * @param {*} result
 */
export function displayTestResultsById(testOptions, result) {
  const dataView = testOptions.caching ? 'repeatView' : 'firstView';
  const videoView = testOptions.caching ? 'videoFileRepeatView' : 'videoFileFirstView';
  const competitorResult = result.competitorTestResult;
  const speedKitResult = result.speedKitTestResult;

  $('.center-vertical').removeClass('center-vertical');
  $('.numberOfHosts').html(result.psiDomains);
  $('.numberOfRequests').html(result.psiRequests);

  // Test whether the bytes value is a string or an integer
  // (needed because the data type was switched from string to int)
  if (/^\d+$/.test(result.psiResponseSize)) {
    $('.numberOfBytes').html(formatFileSize(result.psiResponseSize, 2));
  } else {
    $('.numberOfBytes').html(result.psiResponseSize);
  }

  $('#compareContent').removeClass('hidden');
  $('#printButton').removeClass('hidden');
  $('#informationContent').removeClass('hidden');
  $('#boostWorthiness').removeClass('hidden');
  $('.infoBox').fadeOut(0);
  $('.hideOnDefault').addClass('hidden');
  $('#competitorLink').removeClass('hidden').empty();
  $('#speedKitLink').removeClass('hidden').empty();

  if (competitorResult.location.indexOf('us') !== -1) {
    $('#location_left').prop('checked', true);
  }

  $('#caching_left').prop('checked', result.caching);
  $('#mobile_right').prop('checked', !!result.mobile);

  displayTestResults('competitor', competitorResult[dataView], testOptions);
  $('#competitor').empty().append(createVideoElement('video-competitor', competitorResult[videoView].url));

  displayTestResults('speedKit', speedKitResult[dataView], testOptions);

  if (/^https/.test(competitorResult.url)) {
    $('#competitorLink').append(createLinkButton(competitorResult.url));
    $('#speedKitLink').append(createLinkButton(getBaqendUrl(competitorResult.url, result.whitelist)));
  }

  $('#speedKit').empty().append(createVideoElement('video-speedKit', speedKitResult[videoView].url));
}

/**
 * @param {Error} error
 */
export function verifyWarningMessage(error) {
  if (error) {
    $('#warningMessage').text(() => {
      switch (error.message) {
        case 'Too many requests':
          return 'You reached the maximum number of running tests. Please wait at least one ' +
            'minute until you start further tests!';
        case 'Baqend app detected':
          return 'Your website already uses Baqend’s technology. Please choose another website ' +
            'to be tested!';
        case 'Low served rate':
          return 'The amount of resources served by Speed Kit is quite low. Choose some of the suggested ' +
            'domains to improve the test result.';
        case 'Bad result':
          return 'It looks like some fine tuning or configuration is required to measure your site. Please contact our ' +
            'web performance experts for further information and assistance!';
        case 'Show FMC':
          return 'Because your website uses a lot of asynchronous resources, we replaced the speed index metric ' +
            'by the first meaningful paint!';
        default:
          return 'An error occurred while running the test. Please try the test again or contact our ' +
            'web performance experts for further information and assistance!';
      }
    });

    $('#warningAlert').removeClass('hidden');
  }
}

/**
 * @param {*} competitorData
 * @param {*} speedKitData
 */
export function isSpeedIndexSatisfactory(competitorData, speedKitData) {
  if (competitorData.speedIndex > 0 && speedKitData.speedIndex > 0) {
    const speedIndexFactor = roundToHundredths(competitorData.speedIndex / speedKitData.speedIndex);
    return speedIndexFactor > 1.2;
  }
  return false;
}

/**
 * @param {*} competitorData
 * @param {*} speedKitData
 */
export function isFMPSatisfactory(competitorData, speedKitData) {
  if (competitorData.firstMeaningfulPaint > 0 && speedKitData.firstMeaningfulPaint > 0) {
    const firstMeaningfulPaintFactor =
      roundToHundredths(competitorData.firstMeaningfulPaint / speedKitData.firstMeaningfulPaint);
    return firstMeaningfulPaintFactor > 1.2;
  }
  return false;
}

/**
 * @param {*} data
 * @return {string}
 */
export function calculateServedRequests(data) {
  const totalRequests = data.requests || 0;

  const cacheHits = data.hits.hit || 0;
  const cacheMisses = data.hits.miss || 0;
  const otherRequests = data.hits.other || 0;

  // eslint-disable-next-line no-console
  console.log(`hit: ${cacheHits} miss: ${cacheMisses} other: ${otherRequests} total: ${totalRequests}`);

  const servedFactor = (totalRequests - otherRequests) / totalRequests;
  return formatPercentage(servedFactor);
}

/**
 * @param {*} speedKitData
 */
export function isServedRateSatisfactory(speedKitData) {
  return calculateServedRequests(speedKitData) >= 30;
}

/**
 * @param {number} competitorValue
 * @param {number} speedKitValue
 */
export function calculateFactor(competitorValue, speedKitValue) {
  return roundToHundredths(zeroSafeDiv(competitorValue, speedKitValue));
}

/**
 * @param {*} competitorValue
 * @param {*} speedKitValue
 */
export function calculateRevenueBoost(competitorValue, speedKitValue) {
  const factor = calculateFactor(competitorValue, speedKitValue);
  $('.boostValue').text(factor);

  const publisherRevenue = Math.round(((competitorValue - speedKitValue) / (19000 - 5000)) * 100);
  $('.publisherRevenue').text(`${publisherRevenue}%`);

  const eCommerceRevenue = Math.round((competitorValue - speedKitValue) * 0.01);
  $('.eCommerceRevenue').text(`${eCommerceRevenue}%`);
}

/**
 * @param {*} competitor A data view of the competitor's page results.
 * @param {*} speedKit A data view of Speed Kit's page results.
 * @param {{ caching: boolean }} testOptions
 */
export function calculateFactors(competitor, speedKit, testOptions) {
  const fasterStr = factor => `${factor}x ${factor > 1 ? 'Faster' : ''}`;

  const props = {
    speedIndex: $('.speedIndex-factor'),
    firstMeaningfulPaint: $('.firstMeaningfulPaint-factor'),
    domLoaded: $('.dom-factor'),
    fullyLoaded: $('.fullyLoaded-factor'),
    lastVisualChange: $('.lastVisualChange-factor'),
  };

  Object.entries(props).forEach(([key, $element]) => {
    const factor = calculateFactor(competitor[key], speedKit[key]);
    $element.html(fasterStr(factor));
  });

  if (!testOptions.caching) {
    const ttfbFactor = calculateFactor(competitor.ttfb, speedKit.ttfb);
    $('.ttfb-factor').html(fasterStr(ttfbFactor));
  } else {
    $('.ttfb-factor').html('');
  }
}
<|endoftext|>


<commit_before>/*global define, require */
/*jslint white: true*/
define([
    'bluebird'
], function (Promise) {
    'use strict';

    function factory(config) {
        var services = {};
        function addService(serviceName, serviceDef) {
            services[serviceName] = {
                config: serviceDef
            };
        }
        function loadService(name) {
            return new Promise(function (resolve) {
                var service = services[name],
                    moduleName = service.config.module;
                if (!moduleName) {
                    moduleName = 'kb_appServices_' + name;
                    var paths = {},
                        path = services[name].config.path || 'app/services/' + name;
                    paths[moduleName] = path;
                    require.config({
                        paths: paths
                    });
                } else {
                    console.log('appServiceManager: have a module already.');
                    console.log(moduleName);
                }
                require([moduleName], function (serviceFactory) {
                    var serviceInstance = serviceFactory.make(services[name].config);
                    services[name].instance = serviceInstance;
                    resolve();
                });
            });
        }
        function loadServices() {
            var all = Object.keys(services).map(function (name) {
                return loadService(name);
            });
            return Promise.all(all);
        }
        function startServices() {
            var all = Object.keys(services).map(function (name) {
                return Promise.try(function () {
                    var service = services[name].instance;
                    if (!service) {
                        console.warn('Warning: no service started for ' + name);
                        throw new Error('No service started for ' + name);
                    }
                    if (!service.start) {
                        console.warn('Warning: no start method for ' + name);
                        return;
                    }
                    return Promise.try(function () {
                        return service.start();
                    });
                })
//                    .catch(function (err) {
//                        console.error('Error starting service ' + name);
//                        console.error('err');
//                        reject(err);
//                    });

            });
            return Promise.all(all);
        }
        function stopServices() {
            var all = Object.keys(services).map(function (name) {
                return new Promise(function (resolve) {
                    var service = services[name];
                    if (service && service.instance && service.instance.stop) {
                        return service.instance.stop()
                            .then(function () {
                                resolve();
                            });
                    }
                });
            });
            return Promise.all(all);
        }
        function hasService(name) {
            if (!services[name]) {
                return false;
            }
            return true;
        }
        function getService(name) {
            var service = services[name];
            if (!service) {
                throw {
                    name: 'UndefinedService',
                    message: 'The requested service "' + name + '" has not been registered.',
                    suggestion: 'This is a system configuration issue. The requested service should be installed or the client code programmed to check for its existence first (with hasService)'
                };
            }
            return service.instance;
        }

        function dumpServices() {
            return services;
        }

        return {
            addService: addService,
            getService: getService,
            loadService: loadService,
            hasService: hasService,
            loadServices: loadServices,
            startServices: startServices,
            stopServices: stopServices,
            dumpServices: dumpServices
        };
    }

    return {
        make: function (config) {
            return factory(config);
        }
    };
});<commit_msg>log -> warn<commit_after>/*global define, require */
/*jslint white: true*/
define([
    'bluebird'
], function (Promise) {
    'use strict';

    function factory(config) {
        var services = {};
        function addService(serviceName, serviceDef) {
            services[serviceName] = {
                config: serviceDef
            };
        }
        function loadService(name) {
            return new Promise(function (resolve) {
                var service = services[name],
                    moduleName = service.config.module;
                if (!moduleName) {
                    moduleName = 'kb_appServices_' + name;
                    var paths = {},
                        path = services[name].config.path || 'app/services/' + name;
                    paths[moduleName] = path;
                    require.config({
                        paths: paths
                    });
                } else {
                    console.warn('appServiceManager: have a module already.');
                    console.warn(moduleName);
                }
                require([moduleName], function (serviceFactory) {
                    var serviceInstance = serviceFactory.make(services[name].config);
                    services[name].instance = serviceInstance;
                    resolve();
                });
            });
        }
        function loadServices() {
            var all = Object.keys(services).map(function (name) {
                return loadService(name);
            });
            return Promise.all(all);
        }
        function startServices() {
            var all = Object.keys(services).map(function (name) {
                return Promise.try(function () {
                    var service = services[name].instance;
                    if (!service) {
                        console.warn('Warning: no service started for ' + name);
                        throw new Error('No service started for ' + name);
                    }
                    if (!service.start) {
                        console.warn('Warning: no start method for ' + name);
                        return;
                    }
                    return Promise.try(function () {
                        return service.start();
                    });
                })
//                    .catch(function (err) {
//                        console.error('Error starting service ' + name);
//                        console.error('err');
//                        reject(err);
//                    });

            });
            return Promise.all(all);
        }
        function stopServices() {
            var all = Object.keys(services).map(function (name) {
                return new Promise(function (resolve) {
                    var service = services[name];
                    if (service && service.instance && service.instance.stop) {
                        return service.instance.stop()
                            .then(function () {
                                resolve();
                            });
                    }
                });
            });
            return Promise.all(all);
        }
        function hasService(name) {
            if (!services[name]) {
                return false;
            }
            return true;
        }
        function getService(name) {
            var service = services[name];
            if (!service) {
                throw {
                    name: 'UndefinedService',
                    message: 'The requested service "' + name + '" has not been registered.',
                    suggestion: 'This is a system configuration issue. The requested service should be installed or the client code programmed to check for its existence first (with hasService)'
                };
            }
            return service.instance;
        }

        function dumpServices() {
            return services;
        }

        return {
            addService: addService,
            getService: getService,
            loadService: loadService,
            hasService: hasService,
            loadServices: loadServices,
            startServices: startServices,
            stopServices: stopServices,
            dumpServices: dumpServices
        };
    }

    return {
        make: function (config) {
            return factory(config);
        }
    };
});<|endoftext|>


<commit_before>__$__.CallTreeNetwork = {};

__$__.CallTreeNetwork.data = {
    nodes: [],
    edges: []
};
__$__.CallTreeNetwork.container = document.getElementById('callTree');
__$__.CallTreeNetwork.options = {
    nodes: {
        color: 'skyblue'
    },
    edges: {
        color: 'skyblue'
    },
    layout: {
        hierarchical: {
            direction: 'UD',
            sortMethod: 'directed'
        }
    },
    interaction: {dragNodes: false},
    physics: {
        enabled: false
    }
};

__$__.CallTreeNetwork.draw = function() {
    __$__.CallTreeNetwork.data = {
        nodes: [],
        edges: []
    };
    __$__.CallTreeNetwork.constructData(__$__.CallTree.rootNode, __$__.CallTreeNetwork.data);
    __$__.CallTreeNetwork.network.setData(__$__.CallTreeNetwork.data);
    __$__.CallTreeNetwork.coloringCurrentSpecifiedContext();
};

__$__.CallTreeNetwork.constructData = function(node, network) {
    let contextSensitiveID = node.getContextSensitiveID();
    network.nodes.push({
        label: node.getDisplayedLabel(),
        id: contextSensitiveID
    });

    node.children.forEach(child => {
        let childContextSensitiveID = child.getContextSensitiveID();
        network.edges.push({
            from: contextSensitiveID,
            to: childContextSensitiveID
        });
        __$__.CallTreeNetwork.constructData(child, network);
    });
};

__$__.CallTreeNetwork.coloringCurrentSpecifiedContext = function() {
    let shouldHighlight_map = {};
    Object.entries(__$__.Context.SpecifiedContext).forEach(entry => {
        shouldHighlight_map[entry[1]] = entry[0];
    });
    Object.keys(__$__.CallTreeNetwork.network.body.data.nodes._data).forEach(nodeId => {
        if (shouldHighlight_map[nodeId]) {
            __$__.CallTreeNetwork.network.body.data.nodes.update({
                id: nodeId,
                color: 'red'
            });
        } else {
            __$__.CallTreeNetwork.network.body.data.nodes.update({
                id: nodeId,
                color: 'skyblue'
            });
        }
    })
};

__$__.CallTreeNetwork.network = new vis.Network(__$__.CallTreeNetwork.container, __$__.CallTreeNetwork.data, __$__.CallTreeNetwork.options);
<commit_msg>make the call-tree network double-clickable which specifies context.<commit_after>__$__.CallTreeNetwork = {};

__$__.CallTreeNetwork.data = {
    nodes: [],
    edges: []
};
__$__.CallTreeNetwork.container = document.getElementById('callTree');
__$__.CallTreeNetwork.options = {
    nodes: {
        color: 'skyblue'
    },
    edges: {
        color: 'skyblue'
    },
    layout: {
        hierarchical: {
            direction: 'UD',
            sortMethod: 'directed'
        }
    },
    interaction: {dragNodes: false},
    physics: {
        enabled: false
    }
};

__$__.CallTreeNetwork.draw = function() {
    __$__.CallTreeNetwork.data = {
        nodes: [],
        edges: []
    };
    __$__.CallTreeNetwork.constructData(__$__.CallTree.rootNode, __$__.CallTreeNetwork.data);
    __$__.CallTreeNetwork.network.setData(__$__.CallTreeNetwork.data);
    __$__.CallTreeNetwork.coloringCurrentSpecifiedContext();
};

__$__.CallTreeNetwork.constructData = function(node, network) {
    let contextSensitiveID = node.getContextSensitiveID();
    let data = {
        label: node.getDisplayedLabel(),
        id: contextSensitiveID
    };
    if (node.constructor.name === 'Loop' || node.constructor.name === 'Function') {
        data.loopLabel = node.label;
    }
    network.nodes.push(data);

    node.children.forEach(child => {
        let childContextSensitiveID = child.getContextSensitiveID();
        network.edges.push({
            from: contextSensitiveID,
            to: childContextSensitiveID
        });
        __$__.CallTreeNetwork.constructData(child, network);
    });
};

__$__.CallTreeNetwork.coloringCurrentSpecifiedContext = function() {
    let shouldHighlight_map = {};
    Object.entries(__$__.Context.SpecifiedContext).forEach(entry => {
        shouldHighlight_map[entry[1]] = entry[0];
    });
    Object.keys(__$__.CallTreeNetwork.network.body.data.nodes._data).forEach(nodeId => {
        if (shouldHighlight_map[nodeId]) {
            __$__.CallTreeNetwork.network.body.data.nodes.update({
                id: nodeId,
                color: 'red'
            });
        } else {
            __$__.CallTreeNetwork.network.body.data.nodes.update({
                id: nodeId,
                color: 'skyblue'
            });
        }
    })
};

__$__.CallTreeNetwork.click = function(param) {
    if (param.nodes.length > 0) {
        let clickedNodeId = param.nodes[0];
        let nodeData = __$__.CallTreeNetwork.network.body.data.nodes._data[clickedNodeId];
        if (nodeData.loopLabel) {
            console.log(clickedNodeId, nodeData);
            __$__.Context.SpecifiedContext[nodeData.loopLabel] = clickedNodeId;

            __$__.Context.SwitchViewMode(true);
            __$__.Context.Draw();
            __$__.CallTreeNetwork.coloringCurrentSpecifiedContext();
        }
    }
};

__$__.CallTreeNetwork.network = new vis.Network(__$__.CallTreeNetwork.container, __$__.CallTreeNetwork.data, __$__.CallTreeNetwork.options);
__$__.CallTreeNetwork.network.on('doubleClick', __$__.CallTreeNetwork.click);
<|endoftext|>


<commit_before>'use strict';

import * as Phaser from 'phaser';

class Satellite extends Phaser.Sprite {
    // ##############################################
    // # Constructor ################################
    // ##############################################
    constructor(planet, options) {
        super(planet.game, options.center.x || 0, options.center.y || 0);

        this.options = {
            altitude:  options.altitude  || 50,
            center:    options.center    || new Phaser.Point(0, 0),
            clockwise: options.clockwise || true,

            offset:    Math.random() * Math.PI * 2,
            velocity:  1 / Math.pow(options.altitude - planet.options.radius, 1.1) * 10 * (options.clockwise ? 1 : -1)
        };

        this.planet = planet;

        let graphics = new Phaser.Graphics(this.x, this.y);
        graphics.lineStyle(0);
        graphics.beginFill(0xdddddd);
        graphics.drawCircle(0, 0, 5);
        graphics.endFill();

        this.texture = graphics.generateTexture();

        this.inShadow = false;
    }

    // ##############################################

    update() {
        let val = this.game.time * this.options.velocity + this.options.offset;

        this.position.set(
            this.planet.group.x + this.options.altitude * Math.sin(val),
            this.planet.group.y + this.options.altitude * Math.cos(val)
        );
    }

    // ##############################################
}

export default Satellite;<commit_msg>Made the satellites velocity more plausible<commit_after>'use strict';

import * as Phaser from 'phaser';

class Satellite extends Phaser.Sprite {
    // ##############################################
    // # Constructor ################################
    // ##############################################
    constructor(planet, options) {
        super(planet.game, options.center.x || 0, options.center.y || 0);

        this.options = {
            altitude:  options.altitude  || 50,
            center:    options.center    || new Phaser.Point(0, 0),
            clockwise: options.clockwise || true,

            offset:    Math.random() * Math.PI * 2,
            velocity:  1 / Math.pow(options.altitude - planet.options.radius + 500, 1.5) * 1000 * (options.clockwise ? 1 : -0.5)
        };

        this.planet = planet;

        let graphics = new Phaser.Graphics(this.x, this.y);
        graphics.lineStyle(0);
        graphics.beginFill(0xdddddd);
        graphics.drawCircle(0, 0, 5);
        graphics.endFill();

        this.texture = graphics.generateTexture();

        this.inShadow = false;
    }

    // ##############################################

    update() {
        let val = this.game.time * this.options.velocity + this.options.offset;

        this.position.set(
            this.planet.group.x + this.options.altitude * Math.sin(val),
            this.planet.group.y + this.options.altitude * Math.cos(val)
        );
    }

    // ##############################################
}

export default Satellite;<|endoftext|>


<commit_before>import React from 'react';
import { Link } from 'react-router';
import ImmutablePropTypes from 'react-immutable-proptypes';

import NavTab from './ui/NavTab';

import TripleoOwlSvg from '../../img/tripleo-owl.svg';

export default class NavBar extends React.Component {
  logout(e) {
    e.preventDefault();
    this.props.onLogout();
  }

  render() {
    return (

          <button type="button" className="navbar-toggle collapsed"
                  data-toggle="collapse" data-target="#tripleo-navbar-collapse"
                  aria-expanded="false">
            Toggle navigation

          </button>
          <Link className="navbar-brand" to="/" id="NavBar__indexLink">

          </Link>

                {this.props.user.get('username')}

Logout

            <NavTab to="/deployment-plan" id="NavBar__deploymentPlanTab">Deployment Plan</NavTab>
            <NavTab to="/nodes" id="NavBar__nodesTab">Nodes</NavTab>

    );
  }
}
NavBar.propTypes = {
  onLogout: React.PropTypes.func.isRequired,
  user: ImmutablePropTypes.map
};
<commit_msg>Add i18n strings to the navigation bar<commit_after>import { defineMessages, FormattedMessage } from 'react-intl';
import React from 'react';
import { Link } from 'react-router';
import ImmutablePropTypes from 'react-immutable-proptypes';

import NavTab from './ui/NavTab';

import TripleoOwlSvg from '../../img/tripleo-owl.svg';

const messages = defineMessages({
  toggleNavigation: {
    id: 'NavBar.toggleNavigation',
    defaultMessage: 'Toggle navigation'
  },
  logoutLink: {
    id: 'NavBar.logoutLink',
    defaultMessage: 'Logout'
  },
  deploymentPlanTab: {
    id: 'NavBar.deploymentPlanTab',
    defaultMessage: 'Deployment Plan'
  },
  nodesTab: {
    id: 'Navbar.nodesTab',
    defaultMessage: 'Nodes'
  }
});

export default class NavBar extends React.Component {
  logout(e) {
    e.preventDefault();
    this.props.onLogout();
  }

  render() {
    return (

          <button type="button" className="navbar-toggle collapsed"
                  data-toggle="collapse" data-target="#tripleo-navbar-collapse"
                  aria-expanded="false">

              <FormattedMessage {...messages.toggleNavigation}/>

          </button>
          <Link className="navbar-brand" to="/" id="NavBar__indexLink">

          </Link>

                {this.props.user.get('username')}

                <FormattedMessage {...messages.logoutLink}/>

            <NavTab to="/deployment-plan" id="NavBar__deploymentPlanTab">
              <FormattedMessage {...messages.deploymentPlanTab}/>
            </NavTab>
            <NavTab to="/nodes" id="NavBar__nodesTab">
              <FormattedMessage {...messages.nodesTab}/>
            </NavTab>

    );
  }
}
NavBar.propTypes = {
  onLogout: React.PropTypes.func.isRequired,
  user: ImmutablePropTypes.map
};
<|endoftext|>


<commit_before>
const defaultTheme = {
	background: 0x000000,
	hud: {
		text: 0xff0000,
		progress: 0x00ff00,
		bezel: 0x888888,
		widgetSize: 40,
		scale: {
			bar1: 0xffffff,
			bar2: 0xff0000,
		},
		compass: {
			top1: 0xb03a14,
			top2: 0x1ab4e5,
			bottom1: 0x581d0a,
			bottom2: 0x0c536a
		},
		ahi: {
			sky: 0x106f8d,
			earth: 0x802100,
			bar: 0xffff00,
			marks: 0xffffff
		},
		cursor: 0xffff00
	},
	box: {
		bounding: 0xffffff,
		select: 0x0000ff,
		highlight: 0xff0000
	},
	routes: {
		active: 0xffff00,
		adjacent: 0xff0000,
		default: 0x888888
	},
	stations: {
		entrances: {
			text: 0xffffff
		},
		junctions: {
			text: 0xffff00,
			marker: 0xffff00
		},
		default: {
			text: 0xffffff,
			marker: 0xff0000
		}
	},
	shading: {
		single: 0xffffff,
		cursor: 0xffff00,
		cursorBase: 0x888888,
		unselected: 0x444444
	},
	popup: {
		text: 0xffffff,
		border: 0xffffff,
		background: 0x222222
	}
};

export { defaultTheme };<commit_msg>remove test setting<commit_after>
const defaultTheme = {
	background: 0x000000,
	hud: {
		text: 0xffffff,
		progress: 0x00ff00,
		bezel: 0x888888,
		widgetSize: 40,
		scale: {
			bar1: 0xffffff,
			bar2: 0xff0000,
		},
		compass: {
			top1: 0xb03a14,
			top2: 0x1ab4e5,
			bottom1: 0x581d0a,
			bottom2: 0x0c536a
		},
		ahi: {
			sky: 0x106f8d,
			earth: 0x802100,
			bar: 0xffff00,
			marks: 0xffffff
		},
		cursor: 0xffff00
	},
	box: {
		bounding: 0xffffff,
		select: 0x0000ff,
		highlight: 0xff0000
	},
	routes: {
		active: 0xffff00,
		adjacent: 0xff0000,
		default: 0x888888
	},
	stations: {
		entrances: {
			text: 0xffffff
		},
		junctions: {
			text: 0xffff00,
			marker: 0xffff00
		},
		default: {
			text: 0xffffff,
			marker: 0xff0000
		}
	},
	shading: {
		single: 0xffffff,
		cursor: 0xffff00,
		cursorBase: 0x888888,
		unselected: 0x444444
	},
	popup: {
		text: 0xffffff,
		border: 0xffffff,
		background: 0x222222
	}
};

export { defaultTheme };<|endoftext|>


<commit_before>/**
 * Moovie: an advanced HTML5 video player for MooTools.
 * @copyright 2010 Colin Aarts
 * @license MIT
 */
import SRTCue from './SRTCue.js';

const WebSRT = {};

/**
 * Parses SRT (.srt) files.
 * @type {Class}
 */
WebSRT.Parser = new Class({
    // @todo implement EventTarget
    initialize: function () {
        this.oncue = Function.from();
        this.onflush = Function.from();
        this.onparsingerror = Function.from();
        this.buffer = '';
        this.cues = [];
    },

    computeSeconds: function (hours, minutes, seconds, milliseconds) {
        hours = hours.toInt() * 3600;
        minutes = minutes.toInt() * 60;
        seconds = seconds.toInt();
        milliseconds = milliseconds.toInt() / 1000;

        return hours + minutes + seconds + milliseconds;
    },

    // Timestamp must take the form of [hours]:[minutes]:[seconds],[milliseconds]
    parseTimeStamp: function (input) {
        const matches = input.match(/^(\d{2}):(\d{2}):(\d{2}),(\d{3})/);

        if (!matches) {
            return null;
        }

        return this.computeSeconds(matches[1], matches[2], matches[3], matches[4]);
    },

    parse: function (data) {
        this.buffer = this.buffer + data;
    },

    flush: function () {
        const rawCues = this.buffer.replace(/\r?\n/gm, '\n').trim().split('\n\n');

        rawCues.each((rawCueBlock) => {
            const cueLines = rawCueBlock.split('\n');
            const cueid = cueLines.shift();
            const cuetc = cueLines.shift().split(' --> ');
            const cueobj = new SRTCue(
                this.parseTimeStamp(cuetc[0]),
                this.parseTimeStamp(cuetc[1]),
                cueLines.join('\n')
            );

            cueobj.id = cueid;
            this.oncue(cueobj);
        });

        this.onflush();
    }
});

export default WebSRT;
<commit_msg>refactor: Remove dependence on MooTools class<commit_after>/**
 * Moovie: an advanced HTML5 video player for MooTools.
 * @copyright 2010 Colin Aarts
 * @license MIT
 */
import SRTCue from './SRTCue.js';

/**
 * Parses SRT (.srt) files.
 * @todo Make parser extend EventTarget.
 */
export class Parser {
    constructor() {
        this.oncue = Function.from();
        this.onflush = Function.from();
        this.onparsingerror = Function.from();
        this.buffer = '';
        this.cues = [];
    }

    parse(data) {
        this.buffer = this.buffer + data;
    }

    flush() {
        const rawCues = this.buffer.replace(/\r?\n/gm, '\n').trim().split('\n\n');

        rawCues.each((rawCueBlock) => {
            const cueLines = rawCueBlock.split('\n');
            const cueid = cueLines.shift();
            const cuetc = cueLines.shift().split(' --> ');
            const cueobj = new SRTCue(
                this.parseTimeStamp(cuetc[0]),
                this.parseTimeStamp(cuetc[1]),
                cueLines.join('\n')
            );

            cueobj.id = cueid;
            this.oncue(cueobj);
        });

        this.onflush();
    }

    /**
     * Timestamp must take the form of [hours]:[minutes]:[seconds],[milliseconds]
     */
    parseTimeStamp(input) {
        const matches = input.match(/^(\d{2}):(\d{2}):(\d{2}),(\d{3})/);

        if (!matches) {
            return null;
        }

        return this.computeSeconds(matches[1], matches[2], matches[3], matches[4]);
    }

    computeSeconds(hours, minutes, seconds, milliseconds) {
        hours = hours.toInt() * 3600;
        minutes = minutes.toInt() * 60;
        seconds = seconds.toInt();
        milliseconds = milliseconds.toInt() / 1000;

        return hours + minutes + seconds + milliseconds;
    }
}

export default { Parser };
<|endoftext|>


<commit_before>/* This contains the data parser function
This uses the sprintf.js found here https://github.com/alexei/sprintf.js*/

/*
FACTORY
*/
gsatf.factory("gsatfFactory", function() {
    var factory = {};
    var table = {
        title: "",
        headers: [],
        body: [],
        footnotes: []
    };

    var tableHtml = "";

    // declare css variables
    var css = {
        trTitle: "trTitle",
        trBreak: "trBreak",
        tdTitle: "tdTitle", //font-weight:bold; (apparently not in the specs)
        tdCenter: "tdCenter",
        tdSubhead: "tdSubhead",
        tdAll: "tdAll",
        nCols: 0, // updated in script
        nRows: 0
    };

    factory.getTable = function() {
        return table;
    };

    factory.extractData = function(data) {
        var isFilled = function(x) { return x !== ""; };
        var isNotComment = function(x) { return (x[0] != "#" && x.slice(0,2) != "//"); };
        var reFootnoteInc = /\*\d+/; //inclusive
        var reFoodnoteExc = /\*(\d+)/; //exclusive

        // split each row into an array
        data = data.split(/\n/);

        // clear empty rows at end and comments
        data = data.filter(isFilled).filter(isNotComment);

        // split rows into cells & strip empty cells from "title rows" (rows where only the first cell is populated)
        for (i = 0; i < data.length; i++) {
            data[i] = data[i].split(/\t/);
            data_filter = data[i].filter(isFilled);
            // if there's only one non-empty cell AND its the first cell in the array
            if (data_filter.length == 1 && data_filter[0] == data[i][0]) {
                data[i] = data_filter;
            }
        }

        // find max row length (= num of cols) - note: slice() effectively creates a copy of data, so the sorting doesn't affect the table
        css.nCols = data.slice().sort(function (a, b) { return b.length - a.length; })[0].length;

        // Create Title (or empty placeholder)
        // one element in first row indicates that its a built-in title
        if (data[0].length == 1) {
            table.title = data.shift()[0];
        // more than one element indicates that its the headers; less than one is likely an error
        } else {
            table.title += "Title 1.";
        }

        // Get headers
        table.headers = data.shift();

        // iterate through remaining rows, and push into table.body
        for (var i = 0; i < data.length; i++) {
            table.body.push(data[i]);
        }
    } // function extractData

    factory.parseData = function(information) {

        //del = cellDelimiter;

        // Declare other variables
        //var data = angular.element(document.getElementById('textbox')).value; //$("#textBox").val();
        var data = information;

        //var table = '
';
        //var table = '
';
        tableHtml = '
';
        var isFilled = function(x) { return x !== ""; };
        var isNotComment = function(x) { return (x[0] != "#" && x.slice(0,2) != "//"); };
        var reFootnoteInc = /\*\d+/; //inclusive
        var reFoodnoteExc = /\*(\d+)/; //exclusive

        // split each row into an array
        data = data.split(/\n/);

        // clear empty rows at end
        //while (data[data.length - 1] == "") { data.pop(); };
        data = data.filter(isFilled).filter(isNotComment);

        // split rows into cells & strip empty cells from "title rows" (rows where only the first cell is populated)
        for (i = 0; i < data.length; i++) {
            data[i] = data[i].split(/\t/);
            data_filter = data[i].filter(isFilled);
            // if there's only one non-empty cell AND its the first cell in the array
            if (data_filter.length == 1 && data_filter[0] == data[i][0]) {
                data[i] = data_filter;
            }
        }

        // find max row length (= num of cols) - note: slice() effectively creates a copy of data, so the sorting doesn't affect the table
        css.nCols = data.slice().sort(function (a, b) { return b.length - a.length; })[0].length;

        // Create Title (or empty placeholder)
        // one element in first row indicates that its a built-in title
        if (data[0].length == 1) {
            tableHtml += getTitle(data.shift()[0], css);
        // more than one element indicates that its the headers; less than one is likely an error
        } else {
            tableHtml += getTitle("Title 1.", css);
        }

        // Get headers
        tableHtml += getHeaders(data.shift(), css);
        data.unshift("", "");

        // iterate through remaining rows, and process
        for (var i = 2; i < data.length; i++) {
            var row = data[i];
            tableHtml += "
";

            // if its not the first or last line of the table...
            if ( i != data.length - 1 ) {

                if (row.length == 1) {
                    var id = i < 10 ? "0" + i.toString() + "00" : i.toString();
                    tableHtml += sprintf("", id, css.nCols, css.tdSubhead);
                    tableHtml += row[0] + "
";
                    continue;
                }

                for (var j = 0; j < row.length; j++) {
                    var I = i < 10 ? "0"+i.toString() : i.toString();
                    var J = j < 10 ? "0"+j.toString() : j.toString();
                    tableHtml += sprintf("%s	", I+J, css.tdAll, row[j]);
                }

            } else {
                for (var j = 0; j < row.length; j++) {
                    var I = i < 10 ? "0"+i.toString() : i.toString();
                    var J = j < 10 ? "0"+j.toString() : j.toString();
                    tableHtml += sprintf("%s	", I+J, css.tdAll, css.trBreak, row[j]);
                }
            }

            tableHtml += "
";
        }

        tableHtml += "
";

        return table;

    }; // function parseData

    function getTitle() {
        // set up html for first row
        var head = sprintf("
", css);
        var tail = "
";
        return head + "{{ table.title }}" + tail;
    }

    function getHeaders() {

        var reDimension = /\(.*\)/;

        var headers = "
";

        for (var j = 0; j < table.headers.length; j++) {
            var id = j < 10 ? "010" + j.toString() : "01" + j.toString();
            if ( reDimension.test(table.headers[j]) ) {
                // For some reason, this if statement is running twice.  Check out the console
                console.log(reDimension);
                console.log(table.headers[j].match(reDimension)[0]);
                console.log(table.headers[j])
                table.headers[j] = table.headers[j].replace(reDimension, "
" + table.headers[j].match(reDimension)[0]);
                console.log(table.headers[j])
            }

            headers += sprintf("", id, css.tdCenter, css.trBreak);
            headers += sprintf("{{ table.headers[%i] }}	", j, j);
        }
        return headers + "
";

    }

    function getBody() {
        var data = table.body;
        var bodyHtml = "";

        // iterate through remaining rows, and process
        for (var i = 0; i < table.body.length; i++) {
            var row = table.body[i];
            bodyHtml += "
";

            // if its not the first or last line of the table...
            if ( i != table.body.length - 1 ) {

                if (table.body[i].length == 1) {
                    var id = i < 10 ? "0" + i.toString() + "00" : i.toString();
                    bodyHtml += sprintf("", id, css.nCols, css.tdSubhead, i);
                    bodyHtml += "{{ table.body[" + i + "][0] }}" + "
";
                    continue;
                }

                for (var j = 0; j < table.body[i].length; j++) {
                    var I = i < 10 ? "0"+i.toString() : i.toString();
                    var J = j < 10 ? "0"+j.toString() : j.toString();
                    bodyHtml += sprintf("%s	", I+J, css.tdAll, i, j, "{{ table.body[" + i + "][" + j + "] }}");
                }

            } else {
                for (var j = 0; j < table.body[i].length; j++) {
                    var I = i < 10 ? "0"+i.toString() : i.toString();
                    var J = j < 10 ? "0"+j.toString() : j.toString();
                    bodyHtml += sprintf("%s	", I+J, css.tdAll, css.trBreak, i, j, "{{ table.body[" + i + "][" + j + "] }}");
                }
            }

            bodyHtml += "
";
        }

        return bodyHtml;
    }

    function getFootnotes() {
        var html = "";

        return html;
    }

    factory.buildHtml = function() {
        tableHtml = '
';
        tableHtml += getTitle();
        tableHtml += getHeaders();
        tableHtml += getBody();
        tableHtml += getFootnotes();
        tableHtml += "
";
        return tableHtml;
    }

    return factory;
});
<commit_msg>got subheadings to split onto second line<commit_after>/* This contains the data parser function
This uses the sprintf.js found here https://github.com/alexei/sprintf.js*/

/*
FACTORY
*/
gsatf.factory("gsatfFactory", function() {
    var factory = {};
    var table = {
        title: "",
        headers: [[],[],[],[]],
        body: [],
        footnotes: []
    };

    var tableHtml = "";

    // declare css variables
    var css = {
        trTitle: "trTitle",
        trBreak: "trBreak",
        tdTitle: "tdTitle", //font-weight:bold; (apparently not in the specs)
        center: "center",
        left: "left",
        right: "right",
        tdSubhead: "tdSubhead",
        tdBody: "tdBody",
        nCols: 0, // updated in script
        nRows: 1
    };

    factory.getTable = function() {
        return table;
    };

    factory.extractData = function(data) {
        var isFilled = function(x) { return x !== ""; };
        var isNotComment = function(x) { return (x[0] != "#" && x.slice(0,2) != "//"); };
        var reFootnoteInc = /\*\d+/; //inclusive
        var reFoodnoteExc = /\*(\d+)/; //exclusive
        var reSubhead = /\[.*\]/;
        var reDimension = /(\(.*\))/;

        // split each row into an array
        data = data.split(/\n/);

        // clear empty rows at end and comments
        data = data.filter(isFilled).filter(isNotComment);

        // split rows into cells & strip empty cells from "title rows" (rows where only the first cell is populated)
        for (i = 0; i < data.length; i++) {
            data[i] = data[i].split(/\t/);
            data_filter = data[i].filter(isFilled);
            // if there's only one non-empty cell AND its the first cell in the array
            if (data_filter.length == 1 && data_filter[0] == data[i][0]) {
                data[i] = data_filter;
            }
        }

        // find max row length (= num of cols) - note: slice() effectively creates a copy of data, so the sorting doesn't affect the table
        css.nCols = data.slice().sort(function (a, b) { return b.length - a.length; })[0].length;

        // Create Title (or empty placeholder)
        // one element in first row indicates that its a built-in title
        if (data[0].length == 1) {
            table.title = data.shift()[0];
        // more than one element indicates that its the headers; less than one is likely an error
        } else {
            table.title += "Title 1.";
        }

        // Get headers row
        var headers = data.shift();

        // split headers into the title and any corresponding dimensions
        for (var j = 0; j < headers.length; j++) {
            // test the heading for subheads
            if ( reSubhead.test(headers[j]) ) {
                table.headers[0][j] = headers[j].slice(0, headers[j].search(reSubhead));
                table.headers[2][j] = headers[j].match(reSubhead)[0];
                css.nRows = 2;
            } else {
                table.headers[0][j] = headers[j];
            }

            // test the heading for dimensions
            if ( reDimension.test(headers[j]) ) {
                table.headers[1][j] = table.headers[0][j].match(reDimension)[0];
                table.headers[0][j] = table.headers[0][j].slice(0, headers[j].search(reDimension));
            }

            // test the subhead for dimensions
            if ( reDimension.test(table.headers[2][j]) ) {
                table.headers[3][j] = table.headers[2][j].match(reDimension)[0];
                table.headers[2][j] = table.headers[2][j].slice(0, table.headers[2][j].search(reDimension));
            }

        }

        // The remaining data is the body
        table.body = data;

    } // function extractData

    /* buildHtml returns a string of the html table
    the contents are retrieved from the table variable
    which is filled when the extractData function is called
    */
    factory.buildHtml = function() {
        tableHtml = '
';
        tableHtml += getTitle();
        tableHtml += getHeaders();
        tableHtml += getBody();
        tableHtml += getFootnotes();
        tableHtml += "
";
        return tableHtml;
    }

    function getTitle() {
        // set up html for first row
        var head = sprintf("
", css);
        var tail = "
";
        return head + "{{ table.title }}" + tail;
    }

    function getHeaders() {

        var reDimension = /\(.*\)/;

        // begin the header row
        var headers = "
";

        // iterate through headings
        for (var j = 0; j < table.headers[0].length; j++) {
            var id = j < 10 ? "010" + j.toString() : "01" + j.toString();

            // if there are subheadings
            if (table.headers[2][j] !== undefined) {
                // no rowspan
                headers += sprintf("", id, css.center, css.trBreak);
            } else {
                // yes rowspan
                headers += sprintf("", css.nRows, id, css.center, css.trBreak);
            }

            // add editable text into cell
            headers += sprintf("{{ table.headers[0][%i] }}", j, j);

            // if there is a corresponding dimension for the header, print it on a separate line
            if (table.headers[1][j] !== undefined ) {
                headers += sprintf("
{{ table.headers[1][%i] }}", j, j);
            }

            // if there are subheadings
            if (table.headers[2][j] !== undefined) {

                // add second row (subheading)
                headers += "
";
                headers += sprintf("", css);
                headers += sprintf("{{ table.headers[2][%i] }}", j, j);

                // if there is a corresponding dimension for the subheader, print it on a separate line
                if (table.headers[3][j] !== undefined ) {
                    headers += sprintf("
{{ table.headers[3][%i] }}", j, j);
                }

                headers += "
";
            }

            // end the header cell
            headers += "	";

        }

        return headers + "
";

    }

    function getBody() {
        var data = table.body;
        var bodyHtml = "";

        // iterate through remaining rows, and process
        for (var i = 0; i < table.body.length; i++) {
            var row = table.body[i];
            bodyHtml += "
";

            // if its not the first or last line of the table...
            if ( i != table.body.length - 1 ) {

                if (table.body[i].length == 1) {
                    var id = i < 10 ? "0" + i.toString() + "00" : i.toString();
                    bodyHtml += sprintf("", id, css.nCols, css.tdSubhead, i);
                    bodyHtml += "{{ table.body[" + i + "][0] }}" + "
";
                    continue;
                }

                for (var j = 0; j < table.body[i].length; j++) {
                    var I = i < 10 ? "0"+i.toString() : i.toString();
                    var J = j < 10 ? "0"+j.toString() : j.toString();
                    bodyHtml += sprintf("%s	", I+J, css.tdBody, css.center, i, j, "{{ table.body[" + i + "][" + j + "] }}");
                }

            } else {
                for (var j = 0; j < table.body[i].length; j++) {
                    var I = i < 10 ? "0"+i.toString() : i.toString();
                    var J = j < 10 ? "0"+j.toString() : j.toString();
                    bodyHtml += sprintf("%s	", I+J, css.tdBody, css.center, css.trBreak, i, j, "{{ table.body[" + i + "][" + j + "] }}");
                }
            }

            bodyHtml += "
";
        }

        return bodyHtml;
    }

    function getFootnotes() {
        var html = "";

        return html;
    }

    return factory;
});

/*
factory.parseData = function(information) {

        //del = cellDelimiter;

        // Declare other variables
        //var data = angular.element(document.getElementById('textbox')).value; //$("#textBox").val();
        var data = information;

        //var table = '
';
        //var table = '
';
        tableHtml = '
';
        var isFilled = function(x) { return x !== ""; };
        var isNotComment = function(x) { return (x[0] != "#" && x.slice(0,2) != "//"); };
        var reFootnoteInc = /\*\d+/; //inclusive
        var reFoodnoteExc = /\*(\d+)/; //exclusive

        // split each row into an array
        data = data.split(/\n/);

        // clear empty rows at end
        //while (data[data.length - 1] == "") { data.pop(); };
        data = data.filter(isFilled).filter(isNotComment);

        // split rows into cells & strip empty cells from "title rows" (rows where only the first cell is populated)
        for (i = 0; i < data.length; i++) {
            data[i] = data[i].split(/\t/);
            data_filter = data[i].filter(isFilled);
            // if there's only one non-empty cell AND its the first cell in the array
            if (data_filter.length == 1 && data_filter[0] == data[i][0]) {
                data[i] = data_filter;
            }
        }

        // find max row length (= num of cols) - note: slice() effectively creates a copy of data, so the sorting doesn't affect the table
        css.nCols = data.slice().sort(function (a, b) { return b.length - a.length; })[0].length;

        // Create Title (or empty placeholder)
        // one element in first row indicates that its a built-in title
        if (data[0].length == 1) {
            tableHtml += getTitle(data.shift()[0], css);
        // more than one element indicates that its the headers; less than one is likely an error
        } else {
            tableHtml += getTitle("Title 1.", css);
        }

        // Get headers
        tableHtml += getHeaders(data.shift(), css);
        data.unshift("", "");

        // iterate through remaining rows, and process
        for (var i = 2; i < data.length; i++) {
            var row = data[i];
            tableHtml += "
";

            // if its not the first or last line of the table...
            if ( i != data.length - 1 ) {

                if (row.length == 1) {
                    var id = i < 10 ? "0" + i.toString() + "00" : i.toString();
                    tableHtml += sprintf("", id, css.nCols, css.tdSubhead);
                    tableHtml += row[0] + "
";
                    continue;
                }

                for (var j = 0; j < row.length; j++) {
                    var I = i < 10 ? "0"+i.toString() : i.toString();
                    var J = j < 10 ? "0"+j.toString() : j.toString();
                    tableHtml += sprintf("%s	", I+J, css.tdBody, row[j]);
                }

            } else {
                for (var j = 0; j < row.length; j++) {
                    var I = i < 10 ? "0"+i.toString() : i.toString();
                    var J = j < 10 ? "0"+j.toString() : j.toString();
                    tableHtml += sprintf("%s	", I+J, css.tdBody, css.trBreak, row[j]);
                }
            }

            tableHtml += "
";
        }

        tableHtml += "
";

        return table;

    }; // function parseData
    */<|endoftext|>