function babel(options = {}) {
  return (context, { addLoader }) =>
    addLoader({
      // setting `test` defaults here, in case there is no `context.match` data
      test: /\.(js|jsx)$/,
      use: [
        {
          loader: 'thread-loader',
          options: {
            // Keep workers alive for more effective watch mode
            ...(process.env.NODE_ENV === 'development' && { poolTimeout: Infinity }),
          },
        },
        {
          loader: 'babel-loader',
          options: Object.assign(babelLoaderOptions, options),
        },
      ],
      ...context.match,
    })
}

function babel ( options = { } ) { return ( context , { addLoader } ) => addLoader ( { test : / \.(js|jsx)$ / , use : [ { loader : 'thread-loader' , options : { ... ( process . env . NODE_ENV === 'development' && { poolTimeout : Infinity } ) , } , } , { loader : 'babel-loader' , options : Object . assign ( babelLoaderOptions , options ) , } , ] , ... context . match , } ) }

The thread-loader parallelizes code compilation, useful with babel since
it transpiles both application javascript and node_modules javascript

The thread - loader parallelizes code compilation useful with babel since it transpiles both application javascript and node_modules javascript


function imageLoader() {
  return (context, { addLoader }) =>
    addLoader({
      test: /\.(gif|ico|jpg|jpeg|png|webp)$/,
      loader: 'url-loader',
      options: {
        limit: 10000,
        name: fileNameTemplate,
      },
    })
}

function imageLoader ( ) { return ( context , { addLoader } ) => addLoader ( { test : / \.(gif|ico|jpg|jpeg|png|webp)$ / , loader : 'url-loader' , options : { limit : 10000 , name : fileNameTemplate , } , } ) }

Images smaller than 10kb are loaded as a base64 encoded url instead of file url


function csvLoader() {
  return (context, { addLoader }) =>
    addLoader({
      test: /\.csv$/,
      loader: 'csv-loader',
      options: {
        dynamicTyping: true,
        header: true,
        skipEmptyLines: true,
      },
    })
}

function csvLoader ( ) { return ( context , { addLoader } ) => addLoader ( { test : / \.csv$ / , loader : 'csv-loader' , options : { dynamicTyping : true , header : true , skipEmptyLines : true , } , } ) }

Parse .csv files with PapaParse and return it in a JSON format

Parse . csv files with PapaParse and return it in a JSON format


function cssSvgLoader() {
  return (context, { addLoader }) =>
    addLoader({
      // This needs to be different form the reactSvgLoader, otherwise it will merge
      test: /(.*)\.svg$/,
      issuer: {
        test: /\.css$/,
      },
      loader: 'url-loader',
      options: {
        limit: 10000,
        name: fileNameTemplate,
      },
    })
}

function cssSvgLoader ( ) { return ( context , { addLoader } ) => addLoader ( { test : / (.*)\.svg$ / , issuer : { test : / \.css$ / , } , loader : 'url-loader' , options : { limit : 10000 , name : fileNameTemplate , } , } ) }


function prependEntry(entry) {
  const blockFunction = (context, util) => {
    if (!context.entriesToPrepend) context.entriesToPrepend = []
    context.entriesToPrepend.unshift(entry)
    return config => config
  }
  return Object.assign(blockFunction, {
    post: prependEntryPostHook,
  })
}

function prependEntry ( entry ) { const blockFunction = ( context , util ) => { if ( ! context . entriesToPrepend ) context . entriesToPrepend = [ ] context . entriesToPrepend . unshift ( entry ) return config => config } return Object . assign ( blockFunction , { post : prependEntryPostHook , } ) }

Add entryPoint at beginning of 'entry' array

Add entryPoint at beginning of entry array


function build() {
  log.info(`Creating an optimized production build...`)
  const compiler = createWebpackCompiler(
    () => {
      log.ok(`The ${chalk.cyan(relativeAppBuildPath)} folder is ready to be deployed.`)
    },
    () => {
      log.err(`Aborting`)
      process.exit(2)
    }
  )

  return new Promise((resolve, reject) => {
    compiler.run((err, stats) => {
      if (err) {
        return reject(err)
      }

      return resolve(stats)
    })
  })
}

function build ( ) { log . info ( ` ` ) const compiler = createWebpackCompiler ( ( ) => { log . ok ( ` ${ chalk . cyan ( relativeAppBuildPath ) } ` ) } , ( ) => { log . err ( ` ` ) process . exit ( 2 ) } ) return new Promise ( ( resolve , reject ) => { compiler . run ( ( err , stats ) => { if ( err ) { return reject ( err ) } return resolve ( stats ) } ) } ) }

Create the production build and print the deployment instructions.

Create the production build and print the deployment instructions .


function mergeData (to, from) {
	    if (!from) { return to }
	    var key, toVal, fromVal;
	    var keys = Object.keys(from);
	    for (var i = 0; i < keys.length; i++) {
	      key = keys[i];
	      toVal = to[key];
	      fromVal = from[key];
	      if (!hasOwn(to, key)) {
	        set(to, key, fromVal);
	      } else if (
	        toVal !== fromVal &&
	        isPlainObject(toVal) &&
	        isPlainObject(fromVal)
	      ) {
	        mergeData(toVal, fromVal);
	      }
	    }
	    return to
	  }

function mergeData ( to , from ) { if ( ! from ) { return to } var key , toVal , fromVal ; var keys = Object . keys ( from ) ; for ( var i = 0 ; i < keys . length ; i ++ ) { key = keys [ i ] ; toVal = to [ key ] ; fromVal = from [ key ] ; if ( ! hasOwn ( to , key ) ) { set ( to , key , fromVal ) ; } else if ( toVal !== fromVal && isPlainObject ( toVal ) && isPlainObject ( fromVal ) ) { mergeData ( toVal , fromVal ) ; } } return to }

Helper that recursively merges two data objects together.

Helper that recursively merges two data objects together .


function withDefault(type) {
	  return Object.defineProperty(type, 'def', {
	    value: function value(def) {
	      if (def === undefined && !this.default) {
	        return this;
	      }

	      if (!isFunction(def) && !validateType(this, def)) {
	        warn(this._vueTypes_name + " - invalid default value: \"" + def + "\"", def);
	        return this;
	      }

	      if (isArray(def)) {
	        this.default = function () {
	          return [].concat(def);
	        };
	      } else if (isPlainObject_1(def)) {
	        this.default = function () {
	          return Object.assign({}, def);
	        };
	      } else {
	        this.default = def;
	      }

	      return this;
	    },
	    enumerable: false,
	    writable: false
	  });
	}

function
withDefault
(
type
)
{
return
Object
.
defineProperty
(
type
,
'def'
,
{
value
:
function
value
(
def
)
{
if
(
def
===
undefined
&&
!
this
.
default
)
{
return
this
;
}
if
(
!
isFunction
(
def
)
&&
!
validateType
(
this
,
def
)
)
{
warn
(
this
.
_vueTypes_name
+
" - invalid default value: \""
+
\"
+
def
,
"\""
)
;
\"
}
def
return
this
;
}
,
if
(
isArray
(
def
)
)
{
this
.
default
=
function
(
)
{
return
[
]
.
concat
(
def
)
;
}
;
}
else
if
(
isPlainObject_1
(
def
)
)
{
this
.
default
=
function
(
)
{
return
Object
.
assign
(
{
}
,
def
)
;
}
;
}
else
{
this
.
default
=
def
;
}
,
return
this
;
}
)
;
}

Adds a `def` method to the object returning a new object with passed in argument as `default` property

@param {object} type - Object to enhance
@returns {object} the passed-in prop type

Adds a def method to the object returning a new object with passed in argument as default property


function withValidate(type) {
	  return Object.defineProperty(type, 'validate', {
	    value: function value(fn) {
	      this.validator = fn.bind(this);
	      return this;
	    },
	    enumerable: false
	  });
	}

function withValidate ( type ) { return Object . defineProperty ( type , 'validate' , { value : function value ( fn ) { this . validator = fn . bind ( this ) ; return this ; } , enumerable : false } ) ; }

Adds a validate method useful to set the prop `validator` function.

@param {object} type Prop type to extend
@returns {object} the passed-in prop type

Adds a validate method useful to set the prop validator function .


function toType(name, obj, validateFn) {
	  if (validateFn === void 0) {
	    validateFn = false;
	  }

	  Object.defineProperty(obj, '_vueTypes_name', {
	    enumerable: false,
	    writable: false,
	    value: name
	  });
	  withDefault(withRequired(obj));

	  if (validateFn) {
	    withValidate(obj);
	  }

	  if (isFunction(obj.validator)) {
	    obj.validator = obj.validator.bind(obj);
	  }

	  return obj;
	}

function toType ( name , obj , validateFn ) { if ( validateFn === void 0 ) { validateFn = false ; } Object . defineProperty ( obj , '_vueTypes_name' , { enumerable : false , writable : false , value : name } ) ; withDefault ( withRequired ( obj ) ) ; if ( validateFn ) { withValidate ( obj ) ; } if ( isFunction ( obj . validator ) ) { obj . validator = obj . validator . bind ( obj ) ; } return obj ; }

Adds `isRequired` and `def` modifiers to an object

@param {string} name - Type internal name
@param {object} obj - Object to enhance
@returns {object}

Adds isRequired and def modifiers to an object


function validateType(type, value, silent) {
	  if (silent === void 0) {
	    silent = false;
	  }

	  var typeToCheck = type;
	  var valid = true;
	  var expectedType;

	  if (!isPlainObject_1(type)) {
	    typeToCheck = {
	      type: type
	    };
	  }

	  var namePrefix = typeToCheck._vueTypes_name ? typeToCheck._vueTypes_name + ' - ' : '';

	  if (hasOwn.call(typeToCheck, 'type') && typeToCheck.type !== null) {
	    if (isArray(typeToCheck.type)) {
	      valid = typeToCheck.type.some(function (type) {
	        return validateType(type, value, true);
	      });
	      expectedType = typeToCheck.type.map(function (type) {
	        return getType(type);
	      }).join(' or ');
	    } else {
	      expectedType = getType(typeToCheck);

	      if (expectedType === 'Array') {
	        valid = isArray(value);
	      } else if (expectedType === 'Object') {
	        valid = isPlainObject_1(value);
	      } else if (expectedType === 'String' || expectedType === 'Number' || expectedType === 'Boolean' || expectedType === 'Function') {
	        valid = getNativeType(value) === expectedType;
	      } else {
	        valid = value instanceof typeToCheck.type;
	      }
	    }
	  }

	  if (!valid) {
	    silent === false && warn(namePrefix + "value \"" + value + "\" should be of type \"" + expectedType + "\"");
	    return false;
	  }

	  if (hasOwn.call(typeToCheck, 'validator') && isFunction(typeToCheck.validator)) {
	    // swallow warn
	    var oldWarn;

	    if (silent) {
	      oldWarn = warn;
	      warn = noop;
	    }

	    valid = typeToCheck.validator(value);
	    oldWarn && (warn = oldWarn);
	    if (!valid && silent === false) warn(namePrefix + "custom validation failed");
	    return valid;
	  }

	  return valid;
	}

function
validateType
(
type
,
value
,
silent
)
{
if
(
silent
===
void
0
)
{
silent
=
false
;
}
var
typeToCheck
=
type
;
var
valid
=
true
;
var
expectedType
;
if
(
!
isPlainObject_1
(
type
)
)
{
typeToCheck
=
{
type
:
type
}
;
}
var
namePrefix
=
typeToCheck
.
_vueTypes_name
typeToCheck
.
_vueTypes_name
+
' - '
:
''
;
if
(
hasOwn
.
call
(
typeToCheck
,
'type'
)
&&
typeToCheck
.
type
!==
)
{
if
(
isArray
(
typeToCheck
.
type
)
)
{
valid
=
typeToCheck
.
type
.
some
(
function
(
type
)
{
return
validateType
(
type
,
value
,
true
)
;
}
)
;
expectedType
=
typeToCheck
.
type
.
map
(
function
(
type
)
{
return
getType
(
type
)
;
}
)
.
join
(
' or '
)
;
}
else
{
expectedType
=
getType
(
typeToCheck
)
;
if
(
expectedType
===
'Array'
)
{
valid
=
isArray
(
value
)
;
}
else
if
(
expectedType
===
'Object'
)
{
valid
=
isPlainObject_1
(
value
)
;
}
else
if
(
expectedType
===
'String'
||
expectedType
===
'Number'
||
expectedType
===
'Boolean'
||
expectedType
===
'Function'
)
{
valid
=
getNativeType
(
value
)
===
expectedType
;
}
else
{
valid
=
value
instanceof
typeToCheck
.
type
;
}
}
}
if
(
!
valid
)
{
silent
===
false
&&
warn
(
namePrefix
+
"value \""
+
\"
+
value
+
"\" should be of type \""
+
\"
)
;
\"
}
expectedType
"\""
}

Validates a given value against a prop type object

@param {Object|*} type - Type to use for validation. Either a type object or a constructor
@param {*} value - Value to check
@param {boolean} silent - Silence warnings
@returns {boolean}


function CustomEvent(type, eventInitDict) {
        /*jshint eqnull:true */
        var event = document.createEvent(eventName);
        if (typeof type != 'string') {
          throw new Error('An event name must be provided');
        }
        if (eventName == 'Event') {
          event.initCustomEvent = initCustomEvent;
        }
        if (eventInitDict == null) {
          eventInitDict = defaultInitDict;
        }
        event.initCustomEvent(
          type,
          eventInitDict.bubbles,
          eventInitDict.cancelable,
          eventInitDict.detail
        );
        return event;
      }

function
CustomEvent
(
type
,
eventInitDict
)
{
var
event
=
document
.
createEvent
(
eventName
)
;
if
(
typeof
type
!=
'string'
)
{
throw
new
Error
(
'An event name must be provided'
)
;
}
if
(
eventName
==
'Event'
)
{
event
.
initCustomEvent
=
initCustomEvent
;
}
if
(
eventInitDict
==
)
{
eventInitDict
=
defaultInitDict
;
}
event
.
initCustomEvent
(
type
,
eventInitDict
.
bubbles
,
eventInitDict
.
cancelable
,
eventInitDict
.
detail
)
;
return
event
;
}


function initCustomEvent(
        type, bubbles, cancelable, detail
      ) {
        /*jshint validthis:true*/
        this.initEvent(type, bubbles, cancelable);
        this.detail = detail;
      }

function initCustomEvent ( type , bubbles , cancelable , detail ) { this . initEvent ( type , bubbles , cancelable ) ; this . detail = detail ; }


function cleanUpRuntimeEvents() {
            // Remove all touch events added during 'onDown' as well.
            document.removeEventListener('touchmove', onMove, getPassiveSupported() ? { passive: false } : false);
            document.removeEventListener('touchend', onUp);
            document.removeEventListener('touchcancel', stopTracking);
            document.removeEventListener('mousemove', onMove, getPassiveSupported() ? { passive: false } : false);
            document.removeEventListener('mouseup', onUp);
        }

function cleanUpRuntimeEvents ( ) { document . removeEventListener ( 'touchmove' , onMove , getPassiveSupported ( ) ? { passive : false } : false ) ; document . removeEventListener ( 'touchend' , onUp ) ; document . removeEventListener ( 'touchcancel' , stopTracking ) ; document . removeEventListener ( 'mousemove' , onMove , getPassiveSupported ( ) ? { passive : false } : false ) ; document . removeEventListener ( 'mouseup' , onUp ) ; }

Removes all events set by this instance during runtime


function addRuntimeEvents() {
            cleanUpRuntimeEvents();

            // @see https://developers.google.com/web/updates/2017/01/scrolling-intervention
            document.addEventListener('touchmove', onMove, getPassiveSupported() ? { passive: false } : false);
            document.addEventListener('touchend', onUp);
            document.addEventListener('touchcancel', stopTracking);
            document.addEventListener('mousemove', onMove, getPassiveSupported() ? { passive: false } : false);
            document.addEventListener('mouseup', onUp);
        }

function addRuntimeEvents ( ) { cleanUpRuntimeEvents ( ) ; document . addEventListener ( 'touchmove' , onMove , getPassiveSupported ( ) ? { passive : false } : false ) ; document . addEventListener ( 'touchend' , onUp ) ; document . addEventListener ( 'touchcancel' , stopTracking ) ; document . addEventListener ( 'mousemove' , onMove , getPassiveSupported ( ) ? { passive : false } : false ) ; document . addEventListener ( 'mouseup' , onUp ) ; }


function normalizeEvent(ev) {
            if (ev.type === 'touchmove' || ev.type === 'touchstart' || ev.type === 'touchend') {
                var touch = ev.targetTouches[0] || ev.changedTouches[0];
                return {
                    x: touch.clientX,
                    y: touch.clientY,
                    id: touch.identifier
                };
            } else {
                // mouse events
                return {
                    x: ev.clientX,
                    y: ev.clientY,
                    id: null
                };
            }
        }

function normalizeEvent ( ev ) { if ( ev . type === 'touchmove' || ev . type === 'touchstart' || ev . type === 'touchend' ) { var touch = ev . targetTouches [ 0 ] || ev . changedTouches [ 0 ] ; return { x : touch . clientX , y : touch . clientY , id : touch . identifier } ; } else { return { x : ev . clientX , y : ev . clientY , id : null } ; } }

Creates a custom normalized event object from touch and mouse events
@param  {Event} ev
@returns {Object} with x, y, and id properties


function onDown(ev) {
            var event = normalizeEvent(ev);
            if (!pointerActive && !paused) {
                pointerActive = true;
                decelerating = false;
                pointerId = event.id;

                pointerLastX = pointerCurrentX = event.x;
                pointerLastY = pointerCurrentY = event.y;
                trackingPoints = [];
                addTrackingPoint(pointerLastX, pointerLastY);

                addRuntimeEvents();
            }
        }

function onDown ( ev ) { var event = normalizeEvent ( ev ) ; if ( ! pointerActive && ! paused ) { pointerActive = true ; decelerating = false ; pointerId = event . id ; pointerLastX = pointerCurrentX = event . x ; pointerLastY = pointerCurrentY = event . y ; trackingPoints = [ ] ; addTrackingPoint ( pointerLastX , pointerLastY ) ; addRuntimeEvents ( ) ; } }

Initializes movement tracking
@param  {Object} ev Normalized event


function onMove(ev) {
            ev.preventDefault();
            var event = normalizeEvent(ev);

            if (pointerActive && event.id === pointerId) {
                pointerCurrentX = event.x;
                pointerCurrentY = event.y;
                addTrackingPoint(pointerLastX, pointerLastY);
                requestTick();
            }
        }

function onMove ( ev ) { ev . preventDefault ( ) ; var event = normalizeEvent ( ev ) ; if ( pointerActive && event . id === pointerId ) { pointerCurrentX = event . x ; pointerCurrentY = event . y ; addTrackingPoint ( pointerLastX , pointerLastY ) ; requestTick ( ) ; } }

Handles move events
@param  {Object} ev Normalized event


function addTrackingPoint(x, y) {
            var time = Date.now();
            while (trackingPoints.length > 0) {
                if (time - trackingPoints[0].time <= 100) {
                    break;
                }
                trackingPoints.shift();
            }

            trackingPoints.push({ x: x, y: y, time: time });
        }

function addTrackingPoint ( x , y ) { var time = Date . now ( ) ; while ( trackingPoints . length > 0 ) { if ( time - trackingPoints [ 0 ] . time <= 100 ) { break ; } trackingPoints . shift ( ) ; } trackingPoints . push ( { x : x , y : y , time : time } ) ; }

Records movement for the last 100ms
@param {number} x
@param {number} y [description]


function updateAndRender() {
            var pointerChangeX = pointerCurrentX - pointerLastX;
            var pointerChangeY = pointerCurrentY - pointerLastY;

            targetX += pointerChangeX * multiplier;
            targetY += pointerChangeY * multiplier;

            if (bounce) {
                var diff = checkBounds();
                if (diff.x !== 0) {
                    targetX -= pointerChangeX * dragOutOfBoundsMultiplier(diff.x) * multiplier;
                }
                if (diff.y !== 0) {
                    targetY -= pointerChangeY * dragOutOfBoundsMultiplier(diff.y) * multiplier;
                }
            } else {
                checkBounds(true);
            }

            callUpdateCallback();

            pointerLastX = pointerCurrentX;
            pointerLastY = pointerCurrentY;
            ticking = false;
        }

function updateAndRender ( ) { var pointerChangeX = pointerCurrentX - pointerLastX ; var pointerChangeY = pointerCurrentY - pointerLastY ; targetX += pointerChangeX * multiplier ; targetY += pointerChangeY * multiplier ; if ( bounce ) { var diff = checkBounds ( ) ; if ( diff . x !== 0 ) { targetX -= pointerChangeX * dragOutOfBoundsMultiplier ( diff . x ) * multiplier ; } if ( diff . y !== 0 ) { targetY -= pointerChangeY * dragOutOfBoundsMultiplier ( diff . y ) * multiplier ; } } else { checkBounds ( true ) ; } callUpdateCallback ( ) ; pointerLastX = pointerCurrentX ; pointerLastY = pointerCurrentY ; ticking = false ; }

Calculate new values, call update function

Calculate new values call update function


function startDecelAnim() {
            var firstPoint = trackingPoints[0];
            var lastPoint = trackingPoints[trackingPoints.length - 1];

            var xOffset = lastPoint.x - firstPoint.x;
            var yOffset = lastPoint.y - firstPoint.y;
            var timeOffset = lastPoint.time - firstPoint.time;

            var D = timeOffset / 15 / multiplier;

            decVelX = xOffset / D || 0; // prevent NaN
            decVelY = yOffset / D || 0;

            var diff = checkBounds();

            if (Math.abs(decVelX) > 1 || Math.abs(decVelY) > 1 || !diff.inBounds) {
                decelerating = true;
                requestAnimFrame(stepDecelAnim);
            }
        }

function startDecelAnim ( ) { var firstPoint = trackingPoints [ 0 ] ; var lastPoint = trackingPoints [ trackingPoints . length - 1 ] ; var xOffset = lastPoint . x - firstPoint . x ; var yOffset = lastPoint . y - firstPoint . y ; var timeOffset = lastPoint . time - firstPoint . time ; var D = timeOffset / 15 / multiplier ; decVelX = xOffset / D || 0 ; decVelY = yOffset / D || 0 ; var diff = checkBounds ( ) ; if ( Math . abs ( decVelX ) > 1 || Math . abs ( decVelY ) > 1 || ! diff . inBounds ) { decelerating = true ; requestAnimFrame ( stepDecelAnim ) ; } }

Initialize animation of values coming to a stop


function stepDecelAnim() {
            if (!decelerating) {
                return;
            }

            decVelX *= friction;
            decVelY *= friction;

            targetX += decVelX;
            targetY += decVelY;

            var diff = checkBounds();

            if (Math.abs(decVelX) > stopThreshold || Math.abs(decVelY) > stopThreshold || !diff.inBounds) {

                if (bounce) {
                    var reboundAdjust = 2.5;

                    if (diff.x !== 0) {
                        if (diff.x * decVelX <= 0) {
                            decVelX += diff.x * bounceDeceleration;
                        } else {
                            var adjust = diff.x > 0 ? reboundAdjust : -reboundAdjust;
                            decVelX = (diff.x + adjust) * bounceAcceleration;
                        }
                    }
                    if (diff.y !== 0) {
                        if (diff.y * decVelY <= 0) {
                            decVelY += diff.y * bounceDeceleration;
                        } else {
                            var adjust = diff.y > 0 ? reboundAdjust : -reboundAdjust;
                            decVelY = (diff.y + adjust) * bounceAcceleration;
                        }
                    }
                } else {
                    if (diff.x !== 0) {
                        if (diff.x > 0) {
                            targetX = boundXmin;
                        } else {
                            targetX = boundXmax;
                        }
                        decVelX = 0;
                    }
                    if (diff.y !== 0) {
                        if (diff.y > 0) {
                            targetY = boundYmin;
                        } else {
                            targetY = boundYmax;
                        }
                        decVelY = 0;
                    }
                }

                callUpdateCallback();

                requestAnimFrame(stepDecelAnim);
            } else {
                decelerating = false;
            }
        }

function stepDecelAnim ( ) { if ( ! decelerating ) { return ; } decVelX *= friction ; decVelY *= friction ; targetX += decVelX ; targetY += decVelY ; var diff = checkBounds ( ) ; if ( Math . abs ( decVelX ) > stopThreshold || Math . abs ( decVelY ) > stopThreshold || ! diff . inBounds ) { if ( bounce ) { var reboundAdjust = 2.5 ; if ( diff . x !== 0 ) { if ( diff . x * decVelX <= 0 ) { decVelX += diff . x * bounceDeceleration ; } else { var adjust = diff . x > 0 ? reboundAdjust : - reboundAdjust ; decVelX = ( diff . x + adjust ) * bounceAcceleration ; } } if ( diff . y !== 0 ) { if ( diff . y * decVelY <= 0 ) { decVelY += diff . y * bounceDeceleration ; } else { var adjust = diff . y > 0 ? reboundAdjust : - reboundAdjust ; decVelY = ( diff . y + adjust ) * bounceAcceleration ; } } } else { if ( diff . x !== 0 ) { if ( diff . x > 0 ) { targetX = boundXmin ; } else { targetX = boundXmax ; } decVelX = 0 ; } if ( diff . y !== 0 ) { if ( diff . y > 0 ) { targetY = boundYmin ; } else { targetY = boundYmax ; } decVelY = 0 ; } } callUpdateCallback ( ) ; requestAnimFrame ( stepDecelAnim ) ; } else { decelerating = false ; } }


function checkBounds(restrict) {
            var xDiff = 0;
            var yDiff = 0;

            if (boundXmin !== undefined && targetX < boundXmin) {
                xDiff = boundXmin - targetX;
            } else if (boundXmax !== undefined && targetX > boundXmax) {
                xDiff = boundXmax - targetX;
            }

            if (boundYmin !== undefined && targetY < boundYmin) {
                yDiff = boundYmin - targetY;
            } else if (boundYmax !== undefined && targetY > boundYmax) {
                yDiff = boundYmax - targetY;
            }

            if (restrict) {
                if (xDiff !== 0) {
                    targetX = (xDiff > 0) ? boundXmin : boundXmax;
                }
                if (yDiff !== 0) {
                    targetY = (yDiff > 0) ? boundYmin : boundYmax;
                }
            }

            return {
                x: xDiff,
                y: yDiff,
                inBounds: xDiff === 0 && yDiff === 0
            };
        }

function checkBounds ( restrict ) { var xDiff = 0 ; var yDiff = 0 ; if ( boundXmin !== undefined && targetX < boundXmin ) { xDiff = boundXmin - targetX ; } else if ( boundXmax !== undefined && targetX > boundXmax ) { xDiff = boundXmax - targetX ; } if ( boundYmin !== undefined && targetY < boundYmin ) { yDiff = boundYmin - targetY ; } else if ( boundYmax !== undefined && targetY > boundYmax ) { yDiff = boundYmax - targetY ; } if ( restrict ) { if ( xDiff !== 0 ) { targetX = ( xDiff > 0 ) ? boundXmin : boundXmax ; } if ( yDiff !== 0 ) { targetY = ( yDiff > 0 ) ? boundYmin : boundYmax ; } } return { x : xDiff , y : yDiff , inBounds : xDiff === 0 && yDiff === 0 } ; }

Determine position relative to bounds
@param {Boolean} restrict Whether to restrict target to bounds


function initCompDirs(){
  var compRoot = path.resolve(process.cwd(),'src/components'),
      compReg  = /^[A-Z]\w+$/;

  //['Button', 'Select']
  compDirs = fs.readdirSync(compRoot).filter(function(filename){
    return compReg.test(filename)
  })

  return compDirs
}

function initCompDirs ( ) { var compRoot = path . resolve ( process . cwd ( ) , 'src/components' ) , compReg = / ^[A-Z]\w+$ / ; compDirs = fs . readdirSync ( compRoot ) . filter ( function ( filename ) { return compReg . test ( filename ) } ) return compDirs }


function appendLogToFileStream(fileName, newLog, headerLineCount) {
    const filePath = path.join(__dirname, '../../', fileName)
    const oldChangelog = grunt.file.read(filePath)
      .toString()
      .split('\n');

    let wStr = fs.createWriteStream(filePath)
    /** lines used by the default header */
    let logHeader = oldChangelog.slice(0, headerLineCount);
    /** previous changelog entries */
    let prevLogs = oldChangelog.slice(headerLineCount);
    var s = new Readable;
    s.pipe(wStr);
    s.push(logHeader.join('\n') + '\n');
    s.push(newLog);
    s.push(prevLogs.join('\n'));
    s.push(null); // indicates end-of-file basically - the end of the stream)
    return wStr;
  }

function appendLogToFileStream ( fileName , newLog , headerLineCount ) { const filePath = path . join ( __dirname , '../../' , fileName ) const oldChangelog = grunt . file . read ( filePath ) . toString ( ) . split ( '\n' ) ; \n let wStr = fs . createWriteStream ( filePath ) let logHeader = oldChangelog . slice ( 0 , headerLineCount ) ; let prevLogs = oldChangelog . slice ( headerLineCount ) ; var s = new Readable ; s . pipe ( wStr ) ; s . push ( logHeader . join ( '\n' ) + \n ) ; '\n' \n s . push ( newLog ) ; }

Writes a log to a file
@param  {string} fileName  filename/path to write to
@param  {string} newLog  new Changelog entry to add
@param  {number} headerLineCount  Number of lines the header occupies


function doSeek(length, eocdrNotFoundCallback) {
				reader.readUint8Array(reader.size - length, length, function(bytes) {
					for (var i = bytes.length - EOCDR_MIN; i >= 0; i--) {
						if (bytes[i] === 0x50 && bytes[i + 1] === 0x4b && bytes[i + 2] === 0x05 && bytes[i + 3] === 0x06) {
							eocdrCallback(new DataView(bytes.buffer, i, EOCDR_MIN));
							return;
						}
					}
					eocdrNotFoundCallback();
				}, function() {
					onerror(ERR_READ);
				});
			}

function doSeek ( length , eocdrNotFoundCallback ) { reader . readUint8Array ( reader . size - length , length , function ( bytes ) { for ( var i = bytes . length - EOCDR_MIN ; i >= 0 ; i -- ) { if ( bytes [ i ] === 0x50 && bytes [ i + 1 ] === 0x4b && bytes [ i + 2 ] === 0x05 && bytes [ i + 3 ] === 0x06 ) { eocdrCallback ( new DataView ( bytes . buffer , i , EOCDR_MIN ) ) ; return ; } } eocdrNotFoundCallback ( ) ; } , function ( ) { onerror ( ERR_READ ) ; } ) ; }

seek last length bytes of file for EOCDR


function CronJob (sandbox, job) {
    /**
     * @property name - The name of the cron job
     * @property schedule - The cron schedule of the job
     * @property next_scheduled_at - The next time this job is scheduled
     */
    assign(this, job);

    /**
     * @property claims - The claims embedded in the Webtask's token
     */
    if (job.token) {
        this.claims = Decode(job.token);
    }
    else {
        this.claims = {
            jtn: job.name,
            ten: this.container,
        };
    }

    /**
     * @property sandbox - The {@see Sandbox} instance used to create this Webtask instance
     */
    this.sandbox = sandbox;

    /**
     * @property url - The public url that can be used to invoke webtask that the cron job runs
     */
    Object.defineProperty(this, 'url', {
        enumerable: true,
        get: function () {
            return this.sandbox.url + '/api/run/' + this.container + '/' + this.name;
        }
    });
}

function CronJob ( sandbox , job ) { assign ( this , job ) ; if ( job . token ) { this . claims = Decode ( job . token ) ; } else { this . claims = { jtn : job . name , ten : this . container , } ; } this . sandbox = sandbox ; Object . defineProperty ( this , 'url' , { enumerable : true , get : function ( ) { return this . sandbox . url + '/api/run/' + this . container + '/' + this . name ; } } ) ; }

Creates an object representing a CronJob

@constructor


function Sandbox (options) {
    var securityVersion = 'v1';

    this.url = options.url;
    this.container = options.container;
    this.token = options.token;
    this.onBeforeRequest = []
        .concat(options.onBeforeRequest)
        .filter(hook => typeof hook === 'function');

    try {
        var typ = Decode(options.token, { header: true }).typ;

        if (typ && typ.toLowerCase() === 'jwt') {
            securityVersion = 'v2';
        }
    } catch (_) {
        // Ignore jwt decoding failures and assume v1 opaque token
    }

    this.securityVersion = securityVersion;
}

function Sandbox ( options ) { var securityVersion = 'v1' ; this . url = options . url ; this . container = options . container ; this . token = options . token ; this . onBeforeRequest = [ ] . concat ( options . onBeforeRequest ) . filter ( hook => typeof hook === 'function' ) ; try { var typ = Decode ( options . token , { header : true } ) . typ ; if ( typ && typ . toLowerCase ( ) === 'jwt' ) { securityVersion = 'v2' ; } } catch ( _ ) { } this . securityVersion = securityVersion ; }

Creates an object representing a user's webtask.io credentials

@constructor
@param {Object} options - Options used to configure the profile
@param {String} options.url - The url of the webtask cluster where code will run
@param {String} options.container - The name of the container in which code will run
@param {String} options.token - The JWT (see: http://jwt.io) issued by webtask.io that grants rights to run code in the indicated container
@param {String} [options.onBeforeRequest] - An array of hook functions to be invoked with a prepared request

Creates an object representing a user s webtask . io credentials


function Webtask (sandbox, token, options) {
    if (!options) options = {};

    if (sandbox.securityVersion === 'v1') {
        try {
            /**
             * @property claims - The claims embedded in the Webtask's token
             */
            this.claims = Decode(token);

            /**
             * @property token - The token associated with this webtask
             */
            this.token = token;
        }
        catch (_) {
            throw new Error('token must be a valid JWT');
        }
    }

    if (sandbox.securityVersion === 'v2') {
        if (typeof options.name !== 'string') {
            throw new Error('name must be a valid string');
        }

        this.claims = {
            jtn: options.name,
            ten: options.container || sandbox.container,
        }
    }

    /**
     * @property sandbox - The {@see Sandbox} instance used to create this Webtask instance
     */
    this.sandbox = sandbox;

    /**
     * @property meta - The metadata associated with this webtask
     */
    this.meta = options.meta || {};

    /**
     * @property secrets - The secrets associated with this webtask if `decrypt=true`
     */
    this.secrets = options.secrets;

    /**
     * @property code - The code associated with this webtask if `fetch_code=true`
     */
    this.code = options.code;

    /**
     * @property container - The container name in which the webtask will run
     */
    Object.defineProperty(this, 'container', {
        enumerable: true,
        get: function () {
            return options.container || this.sandbox.container;
        }
    });

    /**
     * @property url - The public url that can be used to invoke this webtask
     */
    Object.defineProperty(this, 'url', {
        enumerable: true,
        get: function () {
            var url = options.webtask_url;
            if (!url) {
                if (this.claims.host) {
                   var surl = Url.parse(this.sandbox.url);
                   url = surl.protocol + '//' + this.claims.host + (surl.port ? (':' + surl.port) : '') + '/' + this.sandbox.container;
                }
                else {
                   url = this.sandbox.url + '/api/run/' + this.sandbox.container;
                }

                if (this.claims.jtn) url += '/' + this.claims.jtn;
                else url += '?key=' + this.token;
            }

            return url;
        }
    });
}

function
Webtask
(
sandbox
,
token
,
options
)
{
if
(
!
options
)
options
=
{
}
;
if
(
sandbox
.
securityVersion
===
'v1'
)
{
try
{
this
.
claims
=
Decode
(
token
)
;
this
.
token
=
token
;
}
catch
(
_
)
{
throw
new
Error
(
'token must be a valid JWT'
)
;
}
}
if
(
sandbox
.
securityVersion
===
'v2'
)
{
if
(
typeof
options
.
name
!==
'string'
)
{
throw
new
Error
(
'name must be a valid string'
)
;
}
this
.
claims
=
{
jtn
:
options
.
name
,
ten
:
options
.
container
||
sandbox
.
container
,
}
}
this
.
sandbox
=
sandbox
;
this
.
meta
=
options
.
meta
||
{
}
;
this
.
secrets
=
options
.
secrets
;
this
.
code
=
options
.
code
;
Object
.
defineProperty
(
this
,
'container'
,
{
enumerable
:
true
,
get
:
function
(
)
{
return
options
.
container
||
this
.
sandbox
.
container
;
}
}
)
;
Object
.
defineProperty
(
this
,
'url'
,
{
enumerable
:
true
,
get
:
function
(
)
{
var
url
=
options
.
webtask_url
;
if
(
!
url
)
{
if
(
this
.
claims
.
host
)
{
var
surl
=
Url
.
parse
(
this
.
sandbox
.
url
)
;
url
=
surl
.
protocol
+
'//'
+
this
.
claims
.
host
+
(
surl
.
port
(
':'
+
surl
.
port
)
:
''
)
+
'/'
+
this
.
sandbox
.
container
;
}
else
{
url
=
this
.
sandbox
.
url
+
'/api/run/'
+
this
.
sandbox
.
container
;
}
if
(
this
.
claims
.
jtn
)
url
+=
'/'
+
this
.
claims
.
jtn
;
else
url
+=
'?key='
+
this
.
token
;
}
return
url
;
}
}
)
;
}

Creates an object representing a Webtask

@constructor


function wrappedPromise(executor) {
    if (!(this instanceof wrappedPromise)) {
      return Promise(executor);
    }

    if (typeof executor !== 'function') {
      return new Promise(executor);
    }

    var context, args;
    var promise = new Promise(wrappedExecutor);
    promise.__proto__ = wrappedPromise.prototype;

    try {
      executor.apply(context, args);
    } catch (err) {
      args[1](err);
    }

    return promise;

    function wrappedExecutor(resolve, reject) {
      context = this;
      args = [wrappedResolve, wrappedReject];

      // These wrappers create a function that can be passed a function and an argument to
      // call as a continuation from the resolve or reject.
      function wrappedResolve(val) {
        ensureAslWrapper(promise, false);
        return resolve(val);
      }

      function wrappedReject(val) {
        ensureAslWrapper(promise, false);
        return reject(val);
      }
    }
  }

function wrappedPromise ( executor ) { if ( ! ( this instanceof wrappedPromise ) ) { return Promise ( executor ) ; } if ( typeof executor !== 'function' ) { return new Promise ( executor ) ; } var context , args ; var promise = new Promise ( wrappedExecutor ) ; promise . __proto__ = wrappedPromise . prototype ; try { executor . apply ( context , args ) ; } catch ( err ) { args [ 1 ] ( err ) ; } return promise ; function wrappedExecutor ( resolve , reject ) { context = this ; args = [ wrappedResolve , wrappedReject ] ; function wrappedResolve ( val ) { ensureAslWrapper ( promise , false ) ; return resolve ( val ) ; } function wrappedReject ( val ) { ensureAslWrapper ( promise , false ) ; return reject ( val ) ; } } }

Updates to this class should also be applied to the the ES6 version in es6-wrapped-promise.js.

Updates to this class should also be applied to the the ES6 version in es6 - wrapped - promise . js .


function union(dest, added) {
  var destLength = dest.length;
  var addedLength = added.length;
  var returned = [];

  if (destLength === 0 && addedLength === 0) return returned;

  for (var j  = 0; j < destLength; j++) returned[j] = dest[j];

  if (addedLength === 0) return returned;

  for (var i = 0; i < addedLength; i++) {
    var missing = true;
    for (j = 0; j < destLength; j++) {
      if (dest[j].uid === added[i].uid) {
        missing = false;
        break;
      }
    }
    if (missing) returned.push(added[i]);
  }

  return returned;
}

function union ( dest , added ) { var destLength = dest . length ; var addedLength = added . length ; var returned = [ ] ; if ( destLength === 0 && addedLength === 0 ) return returned ; for ( var j = 0 ; j < destLength ; j ++ ) returned [ j ] = dest [ j ] ; if ( addedLength === 0 ) return returned ; for ( var i = 0 ; i < addedLength ; i ++ ) { var missing = true ; for ( j = 0 ; j < destLength ; j ++ ) { if ( dest [ j ] . uid === added [ i ] . uid ) { missing = false ; break ; } } if ( missing ) returned . push ( added [ i ] ) ; } return returned ; }

Simple helper function that's probably faster than using Array
filter methods and can be inlined.

Simple helper function that s probably faster than using Array filter methods and can be inlined .


function simpleWrap(original, list, length) {
  inAsyncTick = true;
  for (var i = 0; i < length; ++i) {
    var listener = list[i];
    if (listener.create) listener.create(listener.data);
  }
  inAsyncTick = false;

  // still need to make sure nested async calls are made in the context
  // of the listeners active at their creation
  return function () {
    listenerStack.push(listeners);
    listeners = union(list, listeners);

    var returned = original.apply(this, arguments);

    listeners = listenerStack.pop();

    return returned;
  };
}

function simpleWrap ( original , list , length ) { inAsyncTick = true ; for ( var i = 0 ; i < length ; ++ i ) { var listener = list [ i ] ; if ( listener . create ) listener . create ( listener . data ) ; } inAsyncTick = false ; return function ( ) { listenerStack . push ( listeners ) ; listeners = union ( list , listeners ) ; var returned = original . apply ( this , arguments ) ; listeners = listenerStack . pop ( ) ; return returned ; } ; }

for performance in the case where there are no handlers, just the listener

for performance in the case where there are no handlers just the listener


function wrapCallback(original) {
  var length = listeners.length;

  // no context to capture, so avoid closure creation
  if (length === 0) return original;

  // capture the active listeners as of when the wrapped function was called
  var list = listeners.slice();

  for (var i = 0; i < length; ++i) {
    if (list[i].flags > 0) return asyncWrap(original, list, length);
  }

  return simpleWrap(original, list, length);
}

function wrapCallback ( original ) { var length = listeners . length ; if ( length === 0 ) return original ; var list = listeners . slice ( ) ; for ( var i = 0 ; i < length ; ++ i ) { if ( list [ i ] . flags > 0 ) return asyncWrap ( original , list , length ) ; } return simpleWrap ( original , list , length ) ; }

Called each time an asynchronous function that's been monkeypatched in
index.js is called. If there are no listeners, return the function
unwrapped.  If there are any asyncListeners and any of them have callbacks,
pass them off to asyncWrap for later use, otherwise just call the listener.

Called each time an asynchronous function that s been monkeypatched in index . js is called . If there are no listeners return the function unwrapped . If there are any asyncListeners and any of them have callbacks pass them off to asyncWrap for later use otherwise just call the listener .


function (dir, options, internal) {

    // Parse arguments.
    options = options || largest.options;

    // Get all file stats in parallel.
    return fs.readdirAsync(dir)
    .then (function (files) {
        var paths = _.map(files, function (file) { return path.join(dir, file); });
        return Promise.all(_.map(paths, function (path) { return fs.statAsync(path); }))
        .then(function (stats) { return [paths, stats]; });
    })

    // Build up a list of possible candidates, recursing into subfolders if requested.
    .spread(function (paths, stats) {
        return Promise.all(
            _.map(stats, function (stat, i) {
                if (stat.isFile()) return Promise.resolve({ path: paths[i], size: stat.size, searched: 1 });
                return options.recurse ? largest(paths[i], options, true) : Promise.resolve(null);
            })
        );
    })

    // Choose the best candidate.
    .then(function (candidates) {
        return _(candidates)
        .compact()
        .reduce(function (best, cand) {
            if (cand.size > best.size) var temp = cand, cand = best, best = temp;
            best.searched += cand.searched;
            return best;
        });
    })

    // Add a preview if requested (but skip if this is an internal step in a recursive search).
    .then(function (result) {
        if (result && options.preview && !internal) {
            var fd_;
            return fs.openAsync(result.path, 'r')
            .then(function (fd) {
                fd_ = fd;
                var buffer = new Buffer(40);
                return fs.readAsync(fd, buffer, 0, 40, 0);
            })
            .spread(function (bytesRead, buffer) {
                result.preview = buffer.toString('utf-8', 0, bytesRead);
                return fs.closeAsync(fd_);
            })
            .then(function () {
                return result;
            });
        } else {
            return result; // Return without adding preview.
        }
    });
}

function ( dir , options , internal ) { options = options || largest . options ; return fs . readdirAsync ( dir ) . then ( function ( files ) { var paths = _ . map ( files , function ( file ) { return path . join ( dir , file ) ; } ) ; return Promise . all ( _ . map ( paths , function ( path ) { return fs . statAsync ( path ) ; } ) ) . then ( function ( stats ) { return [ paths , stats ] ; } ) ; } ) . spread ( function ( paths , stats ) { return Promise . all ( _ . map ( stats , function ( stat , i ) { if ( stat . isFile ( ) ) return Promise . resolve ( { path : paths [ i ] , size : stat . size , searched : 1 } ) ; return options . recurse ? largest ( paths [ i ] , options , true ) : Promise . resolve ( null ) ; } ) ) ; } ) . then ( function ( candidates ) { return _ ( candidates ) . compact ( ) . reduce ( function ( best , cand ) { if ( cand . size > best . size ) var temp = cand , cand = best , best = temp ; best . searched += cand . searched ; return best ; } ) ; } ) . then ( function ( result ) { if ( result && options . preview && ! internal ) { var fd_ ; return fs . openAsync ( result . path , 'r' ) . then ( function ( fd ) { fd_ = fd ; var buffer = new Buffer ( 40 ) ; return fs . readAsync ( fd , buffer , 0 , 40 , 0 ) ; } ) . spread ( function ( bytesRead , buffer ) { result . preview = buffer . toString ( 'utf-8' , 0 , bytesRead ) ; return fs . closeAsync ( fd_ ) ; } ) . then ( function ( ) { return result ; } ) ; } else { return result ; } } ) ; }

Finds the largest file in the given directory, optionally performing a recursive search.
@param {string} dir - the directory to search.
@param {object?} options - optional settings: { recurse?: boolean; preview?: boolean }.
@returns {object?} null if no files found, otherwise an object of the form
{ path: string; size: number; preview?: string, searched: number; }

Finds the largest file in the given directory optionally performing a recursive search .


function makeAsyncFunc(config) {
    // Validate the specified configuration
    config.validate();
    // Create an async function tailored to the given options.
    var result = function async(bodyFunc) {
        // Create a semaphore for limiting top-level concurrency, if specified in options.
        var semaphore = config.maxConcurrency ? new Semaphore(config.maxConcurrency) : Semaphore.unlimited;
        // Choose and run the appropriate function factory based on whether the result should be iterable.
        var makeFunc = config.isIterable ? makeAsyncIterator : makeAsyncNonIterator;
        var result = makeFunc(bodyFunc, config, semaphore);
        // Ensure the suspendable function's arity matches that of the function it wraps.
        var arity = bodyFunc.length;
        if (config.acceptsCallback)
            ++arity;
        result = makeFuncWithArity(result, arity);
        return result;
    };
    // Add the mod() function, and return the result.
    result.mod = makeModFunc(config);
    return result;
}

function makeAsyncFunc ( config ) { config . validate ( ) ; var result = function async ( bodyFunc ) { var semaphore = config . maxConcurrency ? new Semaphore ( config . maxConcurrency ) : Semaphore . unlimited ; var makeFunc = config . isIterable ? makeAsyncIterator : makeAsyncNonIterator ; var result = makeFunc ( bodyFunc , config , semaphore ) ; var arity = bodyFunc . length ; if ( config . acceptsCallback ) ++ arity ; result = makeFuncWithArity ( result , arity ) ; return result ; } ; result . mod = makeModFunc ( config ) ; return result ; }

Function for creating a specific variant of the async function.

Function for creating a specific variant of the async function .


function makeAsyncIterator(bodyFunc, config, semaphore) {
    // Return a function that returns an iterator.
    return function iterable() {
        // Capture the initial arguments used to start the iterator, as an array.
        var startupArgs = new Array(arguments.length + 1); // Reserve 0th arg for the yield function.
        for (var i = 0, len = arguments.length; i < len; ++i)
            startupArgs[i + 1] = arguments[i];
        // Create a yield() function tailored for this iterator.
        var yield_ = function (expr) {
            // Ensure this function is executing inside a fiber.
            if (!Fiber.current) {
                throw new Error('await functions, yield functions, and value-returning suspendable ' +
                    'functions may only be called from inside a suspendable function. ');
            }
            // Notify waiters of the next result, then suspend the iterator.
            if (runContext.callback)
                runContext.callback(null, { value: expr, done: false });
            if (runContext.resolver)
                runContext.resolver.resolve({ value: expr, done: false });
            Fiber.yield();
        };
        // Insert the yield function as the first argument when starting the iterator.
        startupArgs[0] = yield_;
        // Create the iterator.
        var runContext = new RunContext(bodyFunc, this, startupArgs);
        var iterator = new AsyncIterator(runContext, semaphore, config.returnValue, config.acceptsCallback);
        // Wrap the given bodyFunc to properly complete the iteration.
        runContext.wrapped = function () {
            var len = arguments.length, args = new Array(len);
            for (var i = 0; i < len; ++i)
                args[i] = arguments[i];
            bodyFunc.apply(this, args);
            iterator.destroy();
            return { done: true };
        };
        // Return the iterator.
        return iterator;
    };
}

Function for creating iterable suspendable functions.

Function for creating iterable suspendable functions .


function makeAsyncNonIterator(bodyFunc, config, semaphore) {
    // Return a function that executes fn in a fiber and returns a promise of fn's result.
    return function nonIterable() {
        // Get all the arguments passed in, as an array.
        var argsAsArray = new Array(arguments.length);
        for (var i = 0; i < argsAsArray.length; ++i)
            argsAsArray[i] = arguments[i];
        // Remove concurrency restrictions for nested calls, to avoid race conditions.
        if (FiberMgr.isExecutingInFiber())
            this._semaphore = Semaphore.unlimited;
        // Configure the run context.
        var runContext = new RunContext(bodyFunc, this, argsAsArray, function () { return semaphore.leave(); });
        if (config.returnValue !== Config.NONE) {
            var resolver = defer();
            runContext.resolver = resolver;
        }
        if (config.acceptsCallback && argsAsArray.length && _.isFunction(argsAsArray[argsAsArray.length - 1])) {
            var callback = argsAsArray.pop();
            runContext.callback = callback;
        }
        // Execute bodyFunc to completion in a coroutine. For thunks, this is a lazy operation.
        if (config.returnValue === Config.THUNK) {
            var thunk = function (done) {
                if (done)
                    resolver.promise.then(function (val) { return done(null, val); }, function (err) { return done(err); });
                semaphore.enter(function () { return FiberMgr.create().run(runContext); });
            };
        }
        else {
            semaphore.enter(function () { return FiberMgr.create().run(runContext); });
        }
        // Return the appropriate value.
        switch (config.returnValue) {
            case Config.PROMISE: return resolver.promise;
            case Config.THUNK: return thunk;
            case Config.RESULT: return await(resolver.promise);
            case Config.NONE: return;
        }
    };
}

function makeAsyncNonIterator ( bodyFunc , config , semaphore ) { return function nonIterable ( ) { var argsAsArray = new Array ( arguments . length ) ; for ( var i = 0 ; i < argsAsArray . length ; ++ i ) argsAsArray [ i ] = arguments [ i ] ; if ( FiberMgr . isExecutingInFiber ( ) ) this . _semaphore = Semaphore . unlimited ; var runContext = new RunContext ( bodyFunc , this , argsAsArray , function ( ) { return semaphore . leave ( ) ; } ) ; if ( config . returnValue !== Config . NONE ) { var resolver = defer ( ) ; runContext . resolver = resolver ; } if ( config . acceptsCallback && argsAsArray . length && _ . isFunction ( argsAsArray [ argsAsArray . length - 1 ] ) ) { var callback = argsAsArray . pop ( ) ; runContext . callback = callback ; } if ( config . returnValue === Config . THUNK ) { var thunk = function ( done ) { if ( done ) resolver . promise . then ( function ( val ) { return done ( null , val ) ; } , function ( err ) { return done ( err ) ; } ) ; semaphore . enter ( function ( ) { return FiberMgr . create ( ) . run ( runContext ) ; } ) ; } ; } else { semaphore . enter ( function ( ) { return FiberMgr . create ( ) . run ( runContext ) ; } ) ; } switch ( config . returnValue ) { case Config . PROMISE : return resolver . promise ; case Config . THUNK : return thunk ; case Config . RESULT : return await ( resolver . promise ) ; case Config . NONE : return ; } } ; }

Function for creating non-iterable suspendable functions.

Function for creating non - iterable suspendable functions .


function traverseClone(o, visitor) {
    var result;
    if (_.isArray(o)) {
        var len = o.length;
        result = new Array(len);
        for (var i = 0; i < len; ++i) {
            result[i] = traverseClone(o[i], visitor);
            visitor(result, i);
        }
    }
    else if (_.isPlainObject(o)) {
        result = {};
        for (var key in o) {
            if (o.hasOwnProperty(key)) {
                result[key] = traverseClone(o[key], visitor);
                visitor(result, key);
            }
        }
    }
    else {
        result = o;
    }
    return result;
}

function traverseClone ( o , visitor ) { var result ; if ( _ . isArray ( o ) ) { var len = o . length ; result = new Array ( len ) ; for ( var i = 0 ; i < len ; ++ i ) { result [ i ] = traverseClone ( o [ i ] , visitor ) ; visitor ( result , i ) ; } } else if ( _ . isPlainObject ( o ) ) { result = { } ; for ( var key in o ) { if ( o . hasOwnProperty ( key ) ) { result [ key ] = traverseClone ( o [ key ] , visitor ) ; visitor ( result , key ) ; } } } else { result = o ; } return result ; }


function thunkToPromise(thunk) {
    return new Promise(function (resolve, reject) {
        var callback = function (err, val) { return (err ? reject(err) : resolve(val)); };
        thunk(callback);
    });
}

function thunkToPromise ( thunk ) { return new Promise ( function ( resolve , reject ) { var callback = function ( err , val ) { return ( err ? reject ( err ) : resolve ( val ) ) ; } ; thunk ( callback ) ; } ) ; }


function (dir) {
    var files = fs.readdirSync(dir);

    // Get all file stats in parallel.
    var paths = _.map(files, function (file) { return path.join(dir, file); });
    var stats = _.map(paths, function (path) { return fs.statSync(path); });

    // Count the files.
    return _.filter(stats, function (stat) { return stat.isFile(); }).length;
}

function ( dir ) { var files = fs . readdirSync ( dir ) ; var paths = _ . map ( files , function ( file ) { return path . join ( dir , file ) ; } ) ; var stats = _ . map ( paths , function ( path ) { return fs . statSync ( path ) ; } ) ; return _ . filter ( stats , function ( stat ) { return stat . isFile ( ) ; } ) . length ; }

Returns the number of files in the given directory.

Returns the number of files in the given directory .


async function scopedCopyIndex(client, sourceIndex, targetIndex) {
  const { taskID } = await client.copyIndex(
    sourceIndex.indexName,
    targetIndex.indexName,
    ['settings', 'synonyms', 'rules']
  );
  return targetIndex.waitTask(taskID);
}

async function scopedCopyIndex ( client , sourceIndex , targetIndex ) { const { taskID } = await client . copyIndex ( sourceIndex . indexName , targetIndex . indexName , [ 'settings' , 'synonyms' , 'rules' ] ) ; return targetIndex . waitTask ( taskID ) ; }

Copy the settings, synonyms, and rules of the source index to the target index
@param client
@param sourceIndex
@param targetIndex
@return {Promise}

Copy the settings synonyms and rules of the source index to the target index


async function moveIndex(client, sourceIndex, targetIndex) {
  const { taskID } = await client.moveIndex(
    sourceIndex.indexName,
    targetIndex.indexName
  );
  return targetIndex.waitTask(taskID);
}

async function moveIndex ( client , sourceIndex , targetIndex ) { const { taskID } = await client . moveIndex ( sourceIndex . indexName , targetIndex . indexName ) ; return targetIndex . waitTask ( taskID ) ; }

moves the source index to the target index
@param client
@param sourceIndex
@param targetIndex
@return {Promise}


async function indexExists(index) {
  try {
    const { nbHits } = await index.search();
    return nbHits > 0;
  } catch (e) {
    return false;
  }
}

async function indexExists ( index ) { try { const { nbHits } = await index . search ( ) ; return nbHits > 0 ; } catch ( e ) { return false ; } }

Does an Algolia index exist already

@param index


function loadModule(moduleName) {
  var module = modules[moduleName];

  if (module !== undefined) {
    return module;
  }

  // This uses a switch for static require analysis
  switch (moduleName) {
    case 'charset':
      module = require('./lib/charset');
      break;
    case 'encoding':
      module = require('./lib/encoding');
      break;
    case 'language':
      module = require('./lib/language');
      break;
    case 'mediaType':
      module = require('./lib/mediaType');
      break;
    default:
      throw new Error('Cannot find module \'' + moduleName + '\'');
  }

  // Store to prevent invoking require()
  modules[moduleName] = module;

  return module;
}

function
loadModule
(
moduleName
)
{
var
module
=
modules
[
moduleName
]
;
if
(
module
!==
undefined
)
{
return
module
;
}
switch
(
moduleName
)
{
case
'charset'
:
module
=
require
(
'./lib/charset'
)
;
break
;
case
'encoding'
:
module
=
require
(
'./lib/encoding'
)
;
break
;
case
'language'
:
module
=
require
(
'./lib/language'
)
;
break
;
case
'mediaType'
:
module
=
require
(
'./lib/mediaType'
)
;
break
;
default
:
throw
new
Error
(
'Cannot find module \''
+
\'
+
moduleName
)
;
}
'\''
\'
}


function parseAcceptLanguage(accept) {
  var accepts = accept.split(',');

  for (var i = 0, j = 0; i < accepts.length; i++) {
    var language = parseLanguage(accepts[i].trim(), i);

    if (language) {
      accepts[j++] = language;
    }
  }

  // trim accepts
  accepts.length = j;

  return accepts;
}

function parseAcceptLanguage ( accept ) { var accepts = accept . split ( ',' ) ; for ( var i = 0 , j = 0 ; i < accepts . length ; i ++ ) { var language = parseLanguage ( accepts [ i ] . trim ( ) , i ) ; if ( language ) { accepts [ j ++ ] = language ; } } accepts . length = j ; return accepts ; }

Parse the Accept-Language header.
@private


function parseLanguage(str, i) {
  var match = simpleLanguageRegExp.exec(str);
  if (!match) return null;

  var prefix = match[1],
    suffix = match[2],
    full = prefix;

  if (suffix) full += "-" + suffix;

  var q = 1;
  if (match[3]) {
    var params = match[3].split(';')
    for (var j = 0; j < params.length; j++) {
      var p = params[j].split('=');
      if (p[0] === 'q') q = parseFloat(p[1]);
    }
  }

  return {
    prefix: prefix,
    suffix: suffix,
    q: q,
    i: i,
    full: full
  };
}

function parseLanguage ( str , i ) { var match = simpleLanguageRegExp . exec ( str ) ; if ( ! match ) return null ; var prefix = match [ 1 ] , suffix = match [ 2 ] , full = prefix ; if ( suffix ) full += "-" + suffix ; var q = 1 ; if ( match [ 3 ] ) { var params = match [ 3 ] . split ( ';' ) for ( var j = 0 ; j < params . length ; j ++ ) { var p = params [ j ] . split ( '=' ) ; if ( p [ 0 ] === 'q' ) q = parseFloat ( p [ 1 ] ) ; } } return { prefix : prefix , suffix : suffix , q : q , i : i , full : full } ; }

Parse a language from the Accept-Language header.
@private

Parse a language from the Accept - Language header .


function getLanguagePriority(language, accepted, index) {
  var priority = {o: -1, q: 0, s: 0};

  for (var i = 0; i < accepted.length; i++) {
    var spec = specify(language, accepted[i], index);

    if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
      priority = spec;
    }
  }

  return priority;
}

function getLanguagePriority ( language , accepted , index ) { var priority = { o : - 1 , q : 0 , s : 0 } ; for ( var i = 0 ; i < accepted . length ; i ++ ) { var spec = specify ( language , accepted [ i ] , index ) ; if ( spec && ( priority . s - spec . s || priority . q - spec . q || priority . o - spec . o ) < 0 ) { priority = spec ; } } return priority ; }

Get the priority of a language.
@private


function specify(language, spec, index) {
  var p = parseLanguage(language)
  if (!p) return null;
  var s = 0;
  if(spec.full.toLowerCase() === p.full.toLowerCase()){
    s |= 4;
  } else if (spec.prefix.toLowerCase() === p.full.toLowerCase()) {
    s |= 2;
  } else if (spec.full.toLowerCase() === p.prefix.toLowerCase()) {
    s |= 1;
  } else if (spec.full !== '*' ) {
    return null
  }

  return {
    i: index,
    o: spec.i,
    q: spec.q,
    s: s
  }
}

function specify ( language , spec , index ) { var p = parseLanguage ( language ) if ( ! p ) return null ; var s = 0 ; if ( spec . full . toLowerCase ( ) === p . full . toLowerCase ( ) ) { s |= 4 ; } else if ( spec . prefix . toLowerCase ( ) === p . full . toLowerCase ( ) ) { s |= 2 ; } else if ( spec . full . toLowerCase ( ) === p . prefix . toLowerCase ( ) ) { s |= 1 ; } else if ( spec . full !== '*' ) { return null } return { i : index , o : spec . i , q : spec . q , s : s } }

Get the specificity of the language.
@private


function preferredLanguages(accept, provided) {
  // RFC 2616 sec 14.4: no header = *
  var accepts = parseAcceptLanguage(accept === undefined ? '*' : accept || '');

  if (!provided) {
    // sorted list of all languages
    return accepts
      .filter(isQuality)
      .sort(compareSpecs)
      .map(getFullLanguage);
  }

  var priorities = provided.map(function getPriority(type, index) {
    return getLanguagePriority(type, accepts, index);
  });

  // sorted list of accepted languages
  return priorities.filter(isQuality).sort(compareSpecs).map(function getLanguage(priority) {
    return provided[priorities.indexOf(priority)];
  });
}

function preferredLanguages ( accept , provided ) { var accepts = parseAcceptLanguage ( accept === undefined ? '*' : accept || '' ) ; if ( ! provided ) { return accepts . filter ( isQuality ) . sort ( compareSpecs ) . map ( getFullLanguage ) ; } var priorities = provided . map ( function getPriority ( type , index ) { return getLanguagePriority ( type , accepts , index ) ; } ) ; return priorities . filter ( isQuality ) . sort ( compareSpecs ) . map ( function getLanguage ( priority ) { return provided [ priorities . indexOf ( priority ) ] ; } ) ; }

Get the preferred languages from an Accept-Language header.
@public

Get the preferred languages from an Accept - Language header .


function compareSpecs(a, b) {
  return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
}

function compareSpecs ( a , b ) { return ( b . q - a . q ) || ( b . s - a . s ) || ( a . o - b . o ) || ( a . i - b . i ) || 0 ; }


function parseAcceptCharset(accept) {
  var accepts = accept.split(',');

  for (var i = 0, j = 0; i < accepts.length; i++) {
    var charset = parseCharset(accepts[i].trim(), i);

    if (charset) {
      accepts[j++] = charset;
    }
  }

  // trim accepts
  accepts.length = j;

  return accepts;
}

function parseAcceptCharset ( accept ) { var accepts = accept . split ( ',' ) ; for ( var i = 0 , j = 0 ; i < accepts . length ; i ++ ) { var charset = parseCharset ( accepts [ i ] . trim ( ) , i ) ; if ( charset ) { accepts [ j ++ ] = charset ; } } accepts . length = j ; return accepts ; }

Parse the Accept-Charset header.
@private


function parseCharset(str, i) {
  var match = simpleCharsetRegExp.exec(str);
  if (!match) return null;

  var charset = match[1];
  var q = 1;
  if (match[2]) {
    var params = match[2].split(';')
    for (var j = 0; j < params.length; j++) {
      var p = params[j].trim().split('=');
      if (p[0] === 'q') {
        q = parseFloat(p[1]);
        break;
      }
    }
  }

  return {
    charset: charset,
    q: q,
    i: i
  };
}

function parseCharset ( str , i ) { var match = simpleCharsetRegExp . exec ( str ) ; if ( ! match ) return null ; var charset = match [ 1 ] ; var q = 1 ; if ( match [ 2 ] ) { var params = match [ 2 ] . split ( ';' ) for ( var j = 0 ; j < params . length ; j ++ ) { var p = params [ j ] . trim ( ) . split ( '=' ) ; if ( p [ 0 ] === 'q' ) { q = parseFloat ( p [ 1 ] ) ; break ; } } } return { charset : charset , q : q , i : i } ; }

Parse a charset from the Accept-Charset header.
@private

Parse a charset from the Accept - Charset header .


function getCharsetPriority(charset, accepted, index) {
  var priority = {o: -1, q: 0, s: 0};

  for (var i = 0; i < accepted.length; i++) {
    var spec = specify(charset, accepted[i], index);

    if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
      priority = spec;
    }
  }

  return priority;
}

function getCharsetPriority ( charset , accepted , index ) { var priority = { o : - 1 , q : 0 , s : 0 } ; for ( var i = 0 ; i < accepted . length ; i ++ ) { var spec = specify ( charset , accepted [ i ] , index ) ; if ( spec && ( priority . s - spec . s || priority . q - spec . q || priority . o - spec . o ) < 0 ) { priority = spec ; } } return priority ; }


function specify(charset, spec, index) {
  var s = 0;
  if(spec.charset.toLowerCase() === charset.toLowerCase()){
    s |= 1;
  } else if (spec.charset !== '*' ) {
    return null
  }

  return {
    i: index,
    o: spec.i,
    q: spec.q,
    s: s
  }
}

function specify ( charset , spec , index ) { var s = 0 ; if ( spec . charset . toLowerCase ( ) === charset . toLowerCase ( ) ) { s |= 1 ; } else if ( spec . charset !== '*' ) { return null } return { i : index , o : spec . i , q : spec . q , s : s } }

Get the specificity of the charset.
@private


function preferredCharsets(accept, provided) {
  // RFC 2616 sec 14.2: no header = *
  var accepts = parseAcceptCharset(accept === undefined ? '*' : accept || '');

  if (!provided) {
    // sorted list of all charsets
    return accepts
      .filter(isQuality)
      .sort(compareSpecs)
      .map(getFullCharset);
  }

  var priorities = provided.map(function getPriority(type, index) {
    return getCharsetPriority(type, accepts, index);
  });

  // sorted list of accepted charsets
  return priorities.filter(isQuality).sort(compareSpecs).map(function getCharset(priority) {
    return provided[priorities.indexOf(priority)];
  });
}

function preferredCharsets ( accept , provided ) { var accepts = parseAcceptCharset ( accept === undefined ? '*' : accept || '' ) ; if ( ! provided ) { return accepts . filter ( isQuality ) . sort ( compareSpecs ) . map ( getFullCharset ) ; } var priorities = provided . map ( function getPriority ( type , index ) { return getCharsetPriority ( type , accepts , index ) ; } ) ; return priorities . filter ( isQuality ) . sort ( compareSpecs ) . map ( function getCharset ( priority ) { return provided [ priorities . indexOf ( priority ) ] ; } ) ; }

Get the preferred charsets from an Accept-Charset header.
@public

Get the preferred charsets from an Accept - Charset header .


function parseEncoding(str, i) {
  var match = simpleEncodingRegExp.exec(str);
  if (!match) return null;

  var encoding = match[1];
  var q = 1;
  if (match[2]) {
    var params = match[2].split(';');
    for (var j = 0; j < params.length; j++) {
      var p = params[j].trim().split('=');
      if (p[0] === 'q') {
        q = parseFloat(p[1]);
        break;
      }
    }
  }

  return {
    encoding: encoding,
    q: q,
    i: i
  };
}

function parseEncoding ( str , i ) { var match = simpleEncodingRegExp . exec ( str ) ; if ( ! match ) return null ; var encoding = match [ 1 ] ; var q = 1 ; if ( match [ 2 ] ) { var params = match [ 2 ] . split ( ';' ) ; for ( var j = 0 ; j < params . length ; j ++ ) { var p = params [ j ] . trim ( ) . split ( '=' ) ; if ( p [ 0 ] === 'q' ) { q = parseFloat ( p [ 1 ] ) ; break ; } } } return { encoding : encoding , q : q , i : i } ; }

Parse an encoding from the Accept-Encoding header.
@private

Parse an encoding from the Accept - Encoding header .


function getEncodingPriority(encoding, accepted, index) {
  var priority = {o: -1, q: 0, s: 0};

  for (var i = 0; i < accepted.length; i++) {
    var spec = specify(encoding, accepted[i], index);

    if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
      priority = spec;
    }
  }

  return priority;
}

function getEncodingPriority ( encoding , accepted , index ) { var priority = { o : - 1 , q : 0 , s : 0 } ; for ( var i = 0 ; i < accepted . length ; i ++ ) { var spec = specify ( encoding , accepted [ i ] , index ) ; if ( spec && ( priority . s - spec . s || priority . q - spec . q || priority . o - spec . o ) < 0 ) { priority = spec ; } } return priority ; }

Get the priority of an encoding.
@private


function preferredEncodings(accept, provided) {
  var accepts = parseAcceptEncoding(accept || '');

  if (!provided) {
    // sorted list of all encodings
    return accepts
      .filter(isQuality)
      .sort(compareSpecs)
      .map(getFullEncoding);
  }

  var priorities = provided.map(function getPriority(type, index) {
    return getEncodingPriority(type, accepts, index);
  });

  // sorted list of accepted encodings
  return priorities.filter(isQuality).sort(compareSpecs).map(function getEncoding(priority) {
    return provided[priorities.indexOf(priority)];
  });
}

function preferredEncodings ( accept , provided ) { var accepts = parseAcceptEncoding ( accept || '' ) ; if ( ! provided ) { return accepts . filter ( isQuality ) . sort ( compareSpecs ) . map ( getFullEncoding ) ; } var priorities = provided . map ( function getPriority ( type , index ) { return getEncodingPriority ( type , accepts , index ) ; } ) ; return priorities . filter ( isQuality ) . sort ( compareSpecs ) . map ( function getEncoding ( priority ) { return provided [ priorities . indexOf ( priority ) ] ; } ) ; }

Get the preferred encodings from an Accept-Encoding header.
@public

Get the preferred encodings from an Accept - Encoding header .


function parseAccept(accept) {
  var accepts = splitMediaTypes(accept);

  for (var i = 0, j = 0; i < accepts.length; i++) {
    var mediaType = parseMediaType(accepts[i].trim(), i);

    if (mediaType) {
      accepts[j++] = mediaType;
    }
  }

  // trim accepts
  accepts.length = j;

  return accepts;
}

function parseAccept ( accept ) { var accepts = splitMediaTypes ( accept ) ; for ( var i = 0 , j = 0 ; i < accepts . length ; i ++ ) { var mediaType = parseMediaType ( accepts [ i ] . trim ( ) , i ) ; if ( mediaType ) { accepts [ j ++ ] = mediaType ; } } accepts . length = j ; return accepts ; }


function parseMediaType(str, i) {
  var match = simpleMediaTypeRegExp.exec(str);
  if (!match) return null;

  var params = Object.create(null);
  var q = 1;
  var subtype = match[2];
  var type = match[1];

  if (match[3]) {
    var kvps = splitParameters(match[3]).map(splitKeyValuePair);

    for (var j = 0; j < kvps.length; j++) {
      var pair = kvps[j];
      var key = pair[0].toLowerCase();
      var val = pair[1];

      // get the value, unwrapping quotes
      var value = val && val[0] === '"' && val[val.length - 1] === '"'
        ? val.substr(1, val.length - 2)
        : val;

      if (key === 'q') {
        q = parseFloat(value);
        break;
      }

      // store parameter
      params[key] = value;
    }
  }

  return {
    type: type,
    subtype: subtype,
    params: params,
    q: q,
    i: i
  };
}

function parseMediaType ( str , i ) { var match = simpleMediaTypeRegExp . exec ( str ) ; if ( ! match ) return null ; var params = Object . create ( null ) ; var q = 1 ; var subtype = match [ 2 ] ; var type = match [ 1 ] ; if ( match [ 3 ] ) { var kvps = splitParameters ( match [ 3 ] ) . map ( splitKeyValuePair ) ; for ( var j = 0 ; j < kvps . length ; j ++ ) { var pair = kvps [ j ] ; var key = pair [ 0 ] . toLowerCase ( ) ; var val = pair [ 1 ] ; var value = val && val [ 0 ] === '"' && val [ val . length - 1 ] === '"' ? val . substr ( 1 , val . length - 2 ) : val ; if ( key === 'q' ) { q = parseFloat ( value ) ; break ; } params [ key ] = value ; } } return { type : type , subtype : subtype , params : params , q : q , i : i } ; }

Parse a media type from the Accept header.
@private

Parse a media type from the Accept header .


function getMediaTypePriority(type, accepted, index) {
  var priority = {o: -1, q: 0, s: 0};

  for (var i = 0; i < accepted.length; i++) {
    var spec = specify(type, accepted[i], index);

    if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
      priority = spec;
    }
  }

  return priority;
}

function getMediaTypePriority ( type , accepted , index ) { var priority = { o : - 1 , q : 0 , s : 0 } ; for ( var i = 0 ; i < accepted . length ; i ++ ) { var spec = specify ( type , accepted [ i ] , index ) ; if ( spec && ( priority . s - spec . s || priority . q - spec . q || priority . o - spec . o ) < 0 ) { priority = spec ; } } return priority ; }

Get the priority of a media type.
@private


function specify(type, spec, index) {
  var p = parseMediaType(type);
  var s = 0;

  if (!p) {
    return null;
  }

  if(spec.type.toLowerCase() == p.type.toLowerCase()) {
    s |= 4
  } else if(spec.type != '*') {
    return null;
  }

  if(spec.subtype.toLowerCase() == p.subtype.toLowerCase()) {
    s |= 2
  } else if(spec.subtype != '*') {
    return null;
  }

  var keys = Object.keys(spec.params);
  if (keys.length > 0) {
    if (keys.every(function (k) {
      return spec.params[k] == '*' || (spec.params[k] || '').toLowerCase() == (p.params[k] || '').toLowerCase();
    })) {
      s |= 1
    } else {
      return null
    }
  }

  return {
    i: index,
    o: spec.i,
    q: spec.q,
    s: s,
  }
}

function specify ( type , spec , index ) { var p = parseMediaType ( type ) ; var s = 0 ; if ( ! p ) { return null ; } if ( spec . type . toLowerCase ( ) == p . type . toLowerCase ( ) ) { s |= 4 } else if ( spec . type != '*' ) { return null ; } if ( spec . subtype . toLowerCase ( ) == p . subtype . toLowerCase ( ) ) { s |= 2 } else if ( spec . subtype != '*' ) { return null ; } var keys = Object . keys ( spec . params ) ; if ( keys . length > 0 ) { if ( keys . every ( function ( k ) { return spec . params [ k ] == '*' || ( spec . params [ k ] || '' ) . toLowerCase ( ) == ( p . params [ k ] || '' ) . toLowerCase ( ) ; } ) ) { s |= 1 } else { return null } } return { i : index , o : spec . i , q : spec . q , s : s , } }

Get the specificity of the media type.
@private


function preferredMediaTypes(accept, provided) {
  // RFC 2616 sec 14.2: no header = */*
  var accepts = parseAccept(accept === undefined ? '*/*' : accept || '');

  if (!provided) {
    // sorted list of all types
    return accepts
      .filter(isQuality)
      .sort(compareSpecs)
      .map(getFullType);
  }

  var priorities = provided.map(function getPriority(type, index) {
    return getMediaTypePriority(type, accepts, index);
  });

  // sorted list of accepted types
  return priorities.filter(isQuality).sort(compareSpecs).map(function getType(priority) {
    return provided[priorities.indexOf(priority)];
  });
}

function preferredMediaTypes ( accept , provided ) { var accepts = parseAccept ( accept === undefined ? '*/*' : accept || '' ) ; if ( ! provided ) { return accepts . filter ( isQuality ) . sort ( compareSpecs ) . map ( getFullType ) ; } var priorities = provided . map ( function getPriority ( type , index ) { return getMediaTypePriority ( type , accepts , index ) ; } ) ; return priorities . filter ( isQuality ) . sort ( compareSpecs ) . map ( function getType ( priority ) { return provided [ priorities . indexOf ( priority ) ] ; } ) ; }

Get the preferred media types from an Accept header.
@public

Get the preferred media types from an Accept header .


function quoteCount(string) {
  var count = 0;
  var index = 0;

  while ((index = string.indexOf('"', index)) !== -1) {
    count++;
    index++;
  }

  return count;
}

function quoteCount ( string ) { var count = 0 ; var index = 0 ; while ( ( index = string . indexOf ( '"' , index ) ) !== - 1 ) { count ++ ; index ++ ; } return count ; }

Count the number of quotes in a string.
@private

Count the number of quotes in a string .


function splitKeyValuePair(str) {
  var index = str.indexOf('=');
  var key;
  var val;

  if (index === -1) {
    key = str;
  } else {
    key = str.substr(0, index);
    val = str.substr(index + 1);
  }

  return [key, val];
}

function splitKeyValuePair ( str ) { var index = str . indexOf ( '=' ) ; var key ; var val ; if ( index === - 1 ) { key = str ; } else { key = str . substr ( 0 , index ) ; val = str . substr ( index + 1 ) ; } return [ key , val ] ; }


function splitMediaTypes(accept) {
  var accepts = accept.split(',');

  for (var i = 1, j = 0; i < accepts.length; i++) {
    if (quoteCount(accepts[j]) % 2 == 0) {
      accepts[++j] = accepts[i];
    } else {
      accepts[j] += ',' + accepts[i];
    }
  }

  // trim accepts
  accepts.length = j + 1;

  return accepts;
}

function splitMediaTypes ( accept ) { var accepts = accept . split ( ',' ) ; for ( var i = 1 , j = 0 ; i < accepts . length ; i ++ ) { if ( quoteCount ( accepts [ j ] ) % 2 == 0 ) { accepts [ ++ j ] = accepts [ i ] ; } else { accepts [ j ] += ',' + accepts [ i ] ; } } accepts . length = j + 1 ; return accepts ; }

Split an Accept header into media types.
@private

Split an Accept header into media types .


function splitParameters(str) {
  var parameters = str.split(';');

  for (var i = 1, j = 0; i < parameters.length; i++) {
    if (quoteCount(parameters[j]) % 2 == 0) {
      parameters[++j] = parameters[i];
    } else {
      parameters[j] += ';' + parameters[i];
    }
  }

  // trim parameters
  parameters.length = j + 1;

  for (var i = 0; i < parameters.length; i++) {
    parameters[i] = parameters[i].trim();
  }

  return parameters;
}

function splitParameters ( str ) { var parameters = str . split ( ';' ) ; for ( var i = 1 , j = 0 ; i < parameters . length ; i ++ ) { if ( quoteCount ( parameters [ j ] ) % 2 == 0 ) { parameters [ ++ j ] = parameters [ i ] ; } else { parameters [ j ] += ';' + parameters [ i ] ; } } parameters . length = j + 1 ; for ( var i = 0 ; i < parameters . length ; i ++ ) { parameters [ i ] = parameters [ i ] . trim ( ) ; } return parameters ; }


function loadWebpackConfig () {
  var webpackConfig = require('./webpack.config.js');
  webpackConfig.devtool = 'inline-source-map';
  webpackConfig.module.preLoaders = [
    {
      test: /\.jsx?$/,
      include: path.resolve('lib'),
      loader: 'isparta'
    }
  ];
  return webpackConfig;
}

function loadWebpackConfig ( ) { var webpackConfig = require ( './webpack.config.js' ) ; webpackConfig . devtool = 'inline-source-map' ; webpackConfig . module . preLoaders = [ { test : / \.jsx?$ / , include : path . resolve ( 'lib' ) , loader : 'isparta' } ] ; return webpackConfig ; }

Loads configuration while ensuring sounce-map is enabled

Loads configuration while ensuring sounce - map is enabled


function assign (obj, keyPath, value) {
  const lastKeyIndex = keyPath.length - 1

  for (let i = 0; i < lastKeyIndex; ++i) {
    const key = keyPath[i]
    if (!(key in obj)) obj[key] = {}
    obj = obj[key]
  }

  obj[keyPath[lastKeyIndex]] = value
}

function assign ( obj , keyPath , value ) { const lastKeyIndex = keyPath . length - 1 for ( let i = 0 ; i < lastKeyIndex ; ++ i ) { const key = keyPath [ i ] if ( ! ( key in obj ) ) obj [ key ] = { } obj = obj [ key ] } obj [ keyPath [ lastKeyIndex ] ] = value }

assigns values to an object, creating keys in
`keyPath` if they don't exist yet.
@param {object} obj - The object to assign values to
@param {array} keyPath - The path to assign in object [a,b] => obj.a.b
@param {any} value - The value to assign to the object

assigns values to an object creating keys in keyPath if they don t exist yet .


function getFilterString(selectedValues) {
	if (selectedValues && Object.keys(selectedValues).length) {
		return Object
			// take all selectedValues
			.entries(selectedValues)
			// filter out filter components having some value
			.filter(([, componentValues]) =>
				filterComponents.includes(componentValues.componentType)
					// in case of an array filter out empty array values as well
					&& (
						(componentValues.value && componentValues.value.length)
						// also consider range values in the shape { start, end }
						|| componentValues.value.start || componentValues.value.end
					))
			// parse each filter value
			.map(([componentId, componentValues]) => parseFilterValue(componentId, componentValues))
			// return as a string separated with comma
			.join();
	}
	return null;
}

function getFilterString ( selectedValues ) { if ( selectedValues && Object . keys ( selectedValues ) . length ) { return Object . entries ( selectedValues ) . filter ( ( [ , componentValues ] ) => filterComponents . includes ( componentValues . componentType ) && ( ( componentValues . value && componentValues . value . length ) || componentValues . value . start || componentValues . value . end ) ) . map ( ( [ componentId , componentValues ] ) => parseFilterValue ( componentId , componentValues ) ) . join ( ) ; } return null ; }

transforms the selectedValues from store into the X-Search-Filters string for analytics

transforms the selectedValues from store into the X - Search - Filters string for analytics


function evaluatePage(page, fn) {
	var args =  Array.prototype.slice.call(arguments, 2);
	return this.ready.then(function() {
		var stack;
		page = page || this.page;
		var res = HorsemanPromise.fromCallback(function(done) {
				// Wrap fn to be able to catch exceptions and reject Promise
				stack = HorsemanPromise.reject(new Error('See next line'));
				return page.evaluate(function evaluatePage(fnstr, args) {
					try {
						var fn;
						eval('fn = ' + fnstr);

						var res = fn.apply(this, args); // Call fn with args
						return { res: res };
					} catch (err) {
						return { err: err, iserr: err instanceof Error };
					}
				}, fn.toString(), args, done);
			})
			.then(function handleErrback(args) {
				return stack.catch(function(err) {
					if (args.err) {
						if (args.iserr) {
							var stack = err.stack.split('\n').slice(1);
							// Append Node stack to Phantom stack
							args.err.stack += '\n' + stack.join('\n');
						}
						return HorsemanPromise.reject(args.err);
					}
					return args.res;
				});
			});
		stack.catch(function() {});
		return res;
	});
}

function
evaluatePage
(
page
,
fn
)
{
var
args
=
Array
.
prototype
.
slice
.
call
(
arguments
,
2
)
;
return
this
.
ready
.
then
(
function
(
)
{
var
stack
;
page
=
page
||
this
.
page
;
var
res
=
HorsemanPromise
.
fromCallback
(
function
(
done
)
{
stack
=
HorsemanPromise
.
reject
(
new
Error
(
'See next line'
)
)
;
return
page
.
evaluate
(
function
evaluatePage
(
fnstr
,
args
)
{
try
{
var
fn
;
eval
(
'fn = '
+
fnstr
)
;
var
res
=
fn
.
apply
(
this
,
args
)
;
return
{
res
:
res
}
;
}
catch
(
err
)
{
return
{
err
:
err
,
iserr
:
err
instanceof
Error
}
;
}
}
,
fn
.
toString
(
)
,
args
,
done
)
;
}
)
.
then
(
function
handleErrback
(
args
)
{
return
stack
.
catch
(
function
(
err
)
{
if
(
args
.
err
)
{
if
(
args
.
iserr
)
{
var
stack
=
err
.
stack
.
split
(
'\n'
)
.
\n
slice
;
(
1
)
}
args
.
err
.
stack
+=
'\n'
+
\n
;
}
stack
.
join
(
'\n'
)
}
)
;
}
)
;
\n
return
HorsemanPromise
.
reject
(
args
.
err
)
;
}
)
;
}

Evaluates a function on the given page.
@this Horseman
@param {Page} page
@param {function} fn
@param {...*} [arguments]

Evaluates a function on the given page .


function waitForPage(page, optsOrFn) {
	var self = this;
	var args, value, fname, timeout = self.options.timeout, fn;

	if(typeof optsOrFn === "function"){
			fn = optsOrFn;
			args = Array.prototype.slice.call(arguments);
			value = args.pop();
			fname = fn.name || '<anonymous>';
	} else if(typeof optsOrFn === "object"){
			fn = optsOrFn.fn;
			args = [page, fn].concat(optsOrFn.args || []);
			value = optsOrFn.value;
			fname = fn.name || '<anonymous>';
			if(optsOrFn.timeout){
				timeout = optsOrFn.timeout;
			}
	}

	debug.apply(debug, ['.waitFor()', fname].concat(args.slice(2)));
	return this.ready.then(function() {
		return new HorsemanPromise(function(resolve, reject) {
			var start = Date.now();
			var checkInterval = setInterval(function waitForCheck() {
				var _page = page || self.page;
				var diff = Date.now() - start;
				if (diff > timeout) {
					clearInterval(checkInterval);
					debug('.waitFor() timed out');
					if (typeof _page.onTimeout === 'function') {
						_page.onTimeout('waitFor');
					}
					reject(new TimeoutError(
							'timeout during .waitFor() after ' + diff + ' ms'));
				} else {
					return evaluatePage.apply(self, args)
						.tap(function(res) {
							debugv('.waitFor() iteration',
									fname,
									res,
									diff,
									self.id
							);
						})
						.then(function(res) {
							if (res === value) {
								debug('.waitFor() completed successfully');
								clearInterval(checkInterval);
								resolve();
							}
						})
						.catch(function(err) {
							clearInterval(checkInterval);
							reject(err);
						});
				}
			}, self.options.interval);
		});
	});
}

function
waitForPage
(
page
,
optsOrFn
)
{
var
self
=
this
;
var
args
,
value
,
fname
,
timeout
=
self
.
options
.
timeout
,
fn
;
if
(
typeof
optsOrFn
===
"function"
)
{
fn
=
optsOrFn
;
args
=
Array
.
prototype
.
slice
.
call
(
arguments
)
;
value
=
args
.
pop
(
)
;
fname
=
fn
.
name
||
'<anonymous>'
;
}
else
if
(
typeof
optsOrFn
===
"object"
)
{
fn
=
optsOrFn
.
fn
;
args
=
[
page
,
fn
]
.
concat
(
optsOrFn
.
args
||
[
]
)
;
value
=
optsOrFn
.
value
;
fname
=
fn
.
name
||
'<anonymous>'
;
if
(
optsOrFn
.
timeout
)
{
timeout
=
optsOrFn
.
timeout
;
}
}
debug
.
apply
(
debug
,
[
'.waitFor()'
,
fname
]
.
concat
(
args
.
slice
(
2
)
)
)
;
return
this
.
ready
.
then
(
function
(
)
{
return
new
HorsemanPromise
(
function
(
resolve
,
reject
)
{
var
start
=
Date
.
now
(
)
;
var
checkInterval
=
setInterval
(
function
waitForCheck
(
)
{
var
_page
=
page
||
self
.
page
;
var
diff
=
Date
.
now
(
)
start
;
if
(
diff
>
timeout
)
{
clearInterval
(
checkInterval
)
;
debug
(
'.waitFor() timed out'
)
;
if
(
typeof
_page
.
onTimeout
===
'function'
)
{
_page
.
onTimeout
(
'waitFor'
)
;
}
reject
(
new
TimeoutError
(
'timeout during .waitFor() after '
+
diff
+
' ms'
)
)
;
}
else
{
return
evaluatePage
.
apply
(
self
,
args
)
.
tap
(
function
(
res
)
{
debugv
(
'.waitFor() iteration'
,
fname
,
res
,
diff
,
self
.
id
)
;
}
)
.
then
(
function
(
res
)
{
if
(
res
===
value
)
{
debug
(
'.waitFor() completed successfully'
)
;
clearInterval
(
checkInterval
)
;
resolve
(
)
;
}
}
)
.
catch
(
function
(
err
)
{
clearInterval
(
checkInterval
)
;
reject
(
err
)
;
}
)
;
}
}
,
self
.
options
.
interval
)
;
}
)
;
}
)
;
}

Waits for a function to evaluate to a given value on the given page
@param {Page | undefined} page
@param {function | object} optsOrFn - If optsOrFn is a function, use the classic signature waitForPage(page, fn, arg1, arg2, value), If arg is an object, use waitForPage(page, options)
@param {array} optsOrFn.args - arguments of fn
@param {function} optsOrFn.fn - function to evaluate
@param {*} optsOrFn.value - expected value of function
@param {number} [optsOrFn.timeout=null] - timeout in ms
@param {...*} [arguments]
@param {*} value
@emits Horseman#TimeoutError


function Horseman(options) {
	this.ready = false;
	if (!(this instanceof Horseman)) { return new Horseman(options); }
	this.options = defaults(clone(options) || {}, DEFAULTS);

	this.id = ++instanceId;
	debug('.setup() creating phantom instance %s', this.id);

	var phantomOptions = {
		'load-images': this.options.loadImages,
		'ssl-protocol': this.options.sslProtocol
	};

	if (typeof this.options.ignoreSSLErrors !== 'undefined') {
		phantomOptions['ignore-ssl-errors'] = this.options.ignoreSSLErrors;
	}
	if (typeof this.options.webSecurity !== 'undefined') {
		phantomOptions['web-security'] = this.options.webSecurity;
	}
	if (typeof this.options.proxy !== 'undefined') {
		phantomOptions.proxy = this.options.proxy;
	}
	if (typeof this.options.proxyType !== 'undefined') {
		phantomOptions['proxy-type'] = this.options.proxyType;
	}
	if (typeof this.options.proxyAuth !== 'undefined') {
		phantomOptions['proxy-auth'] = this.options.proxyAuth;
	}
	if (typeof this.options.diskCache !== 'undefined') {
		phantomOptions['disk-cache'] = this.options.diskCache;
	}
	if (typeof this.options.diskCachePath !== 'undefined') {
		phantomOptions['disk-cache-path'] = this.options.diskCachePath;
	}
	if (typeof this.options.cookiesFile !== 'undefined') {
		phantomOptions['cookies-file'] = this.options.cookiesFile;
	}

	if (this.options.debugPort) {
		phantomOptions['remote-debugger-port'] = this.options.debugPort;
		phantomOptions['remote-debugger-autorun'] = 'no';
		if (this.options.debugAutorun !== false) {
			phantomOptions['remote-debugger-autorun'] = 'yes';
		}
	}

	Object.keys(this.options.phantomOptions || {}).forEach(function (key) {
		if (typeof phantomOptions[key] !== 'undefined') {
			debug('Horseman option ' + key + ' overridden by phantomOptions');
		}
		phantomOptions[key] = this.options.phantomOptions[key];
	}.bind(this));

	var instantiationOptions = {
		parameters: phantomOptions
	};

	if (typeof this.options.phantomPath !== 'undefined') {
		instantiationOptions['path'] = this.options.phantomPath;
	}

	// Store the url that was requested for the current url
	this.targetUrl = null;

	// Store the HTTP status code for resources requested.
	this.responses = {};

	this.tabs = [];
	this.onTabCreated = noop;
	this.onTabClosed = noop;

	this.ready = prepare(this, instantiationOptions);
}

function
Horseman
(
options
)
{
this
.
ready
=
false
;
if
(
!
(
this
instanceof
Horseman
)
)
{
return
new
Horseman
(
options
)
;
}
this
.
options
=
defaults
(
clone
(
options
)
||
{
}
,
DEFAULTS
)
;
this
.
id
=
++
instanceId
;
debug
(
'.setup() creating phantom instance %s'
,
this
.
id
)
;
var
phantomOptions
=
{
'load-images'
:
this
.
options
.
loadImages
,
'ssl-protocol'
:
this
.
options
.
sslProtocol
}
;
if
(
typeof
this
.
options
.
ignoreSSLErrors
!==
'undefined'
)
{
phantomOptions
[
'ignore-ssl-errors'
]
=
this
.
options
.
ignoreSSLErrors
;
}
if
(
typeof
this
.
options
.
webSecurity
!==
'undefined'
)
{
phantomOptions
[
'web-security'
]
=
this
.
options
.
webSecurity
;
}
if
(
typeof
this
.
options
.
proxy
!==
'undefined'
)
{
phantomOptions
.
proxy
=
this
.
options
.
proxy
;
}
if
(
typeof
this
.
options
.
proxyType
!==
'undefined'
)
{
phantomOptions
[
'proxy-type'
]
=
this
.
options
.
proxyType
;
}
if
(
typeof
this
.
options
.
proxyAuth
!==
'undefined'
)
{
phantomOptions
[
'proxy-auth'
]
=
this
.
options
.
proxyAuth
;
}
if
(
typeof
this
.
options
.
diskCache
!==
'undefined'
)
{
phantomOptions
[
'disk-cache'
]
=
this
.
options
.
diskCache
;
}
if
(
typeof
this
.
options
.
diskCachePath
!==
'undefined'
)
{
phantomOptions
[
'disk-cache-path'
]
=
this
.
options
.
diskCachePath
;
}
if
(
typeof
this
.
options
.
cookiesFile
!==
'undefined'
)
{
phantomOptions
[
'cookies-file'
]
=
this
.
options
.
cookiesFile
;
}
if
(
this
.
options
.
debugPort
)
{
phantomOptions
[
'remote-debugger-port'
]
=
this
.
options
.
debugPort
;
phantomOptions
[
'remote-debugger-autorun'
]
=
'no'
;
if
(
this
.
options
.
debugAutorun
!==
false
)
{
phantomOptions
[
'remote-debugger-autorun'
]
=
'yes'
;
}
}
Object
.
keys
(
this
.
options
.
phantomOptions
||
{
}
)
.
forEach
(
function
(
key
)
{
if
(
typeof
phantomOptions
[
key
]
!==
'undefined'
)
{
debug
(
'Horseman option '
+
key
+
' overridden by phantomOptions'
)
;
}
phantomOptions
[
key
]
=
this
.
options
.
phantomOptions
[
key
]
;
}
.
bind
(
this
)
)
;
var
instantiationOptions
=
{
parameters
:
phantomOptions
}
;
if
(
typeof
this
.
options
.
phantomPath
!==
'undefined'
)
{
instantiationOptions
[
'path'
]
=
this
.
options
.
phantomPath
;
}
this
.
targetUrl
=
;
this
.
responses
=
{
}
;
this
.
tabs
=
[
]
;
this
.
onTabCreated
=
noop
;
this
.
onTabClosed
=
noop
;
this
.
ready
=
prepare
(
this
,
instantiationOptions
)
;
}


function getColors (image, cb) {
	var data = [];

	var img = createImage(image);

	var promise = new Promise(function (resolve) {
		img.onload = function () {
			var canvas = document.createElement('canvas');
			canvas.width = img.width;
			canvas.height = img.height;
			canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);

			var ctx = canvas.getContext('2d');

			var imageData = ctx.getImageData(0, 0, img.width, 1).data;

			for (var i = 0; i < img.width; i++) {
				data.push([imageData[i*4]/255, imageData[i*4+1]/255, imageData[i*4+2]/255]);
			}

			resolve(data);
		};
	});

	return promise;
}

function getColors ( image , cb ) { var data = [ ] ; var img = createImage ( image ) ; var promise = new Promise ( function ( resolve ) { img . onload = function ( ) { var canvas = document . createElement ( 'canvas' ) ; canvas . width = img . width ; canvas . height = img . height ; canvas . getContext ( '2d' ) . drawImage ( img , 0 , 0 , img . width , img . height ) ; var ctx = canvas . getContext ( '2d' ) ; var imageData = ctx . getImageData ( 0 , 0 , img . width , 1 ) . data ; for ( var i = 0 ; i < img . width ; i ++ ) { data . push ( [ imageData [ i * 4 ] / 255 , imageData [ i * 4 + 1 ] / 255 , imageData [ i * 4 + 2 ] / 255 ] ) ; } resolve ( data ) ; } ; } ) ; return promise ; }


function createCubehelix (steps, opts) {
	var data = [];

	for (var i = 0; i < steps; i++ ){
		data.push(cubehelix.rgb(i/steps, opts).map((v) => v/255));
	}

	return data;
}

function createCubehelix ( steps , opts ) { var data = [ ] ; for ( var i = 0 ; i < steps ; i ++ ) { data . push ( cubehelix . rgb ( i / steps , opts ) . map ( ( v ) => v / 255 ) ) ; } return data ; }


function toImageData (colors) {
	return colors.map((color) => color.map((v) => v*255).concat(255))
	.reduce((prev, curr) => prev.concat(curr));
}

function toImageData ( colors ) { return colors . map ( ( color ) => color . map ( ( v ) => v * 255 ) . concat ( 255 ) ) . reduce ( ( prev , curr ) => prev . concat ( curr ) ) ; }


function compress (colors, factor) {
	var data = [];

	var len = (colors.length) / factor;
	var step = (colors.length-1) / len;

	for (var i = 0; i < colors.length; i+= step) {
		data.push(colors[i|0]);
	}

	return data;
}

function compress ( colors , factor ) { var data = [ ] ; var len = ( colors . length ) / factor ; var step = ( colors . length - 1 ) / len ; for ( var i = 0 ; i < colors . length ; i += step ) { data . push ( colors [ i | 0 ] ) ; } return data ; }

return interpolated imagedata with only each @factor pixel left


function toColormap (data) {
	var stops = [];

	for (var i = 0; i < data.length; i++) {
		stops.push({
			index: Math.round(i * 100 / (data.length - 1)) / 100,
			rgb: data[i].map((v) => Math.round(v*255))
		});
	}

	return stops;
}

function toColormap ( data ) { var stops = [ ] ; for ( var i = 0 ; i < data . length ; i ++ ) { stops . push ( { index : Math . round ( i * 100 / ( data . length - 1 ) ) / 100 , rgb : data [ i ] . map ( ( v ) => Math . round ( v * 255 ) ) } ) ; } return stops ; }


function startDownload(src, storageFile) {
    var uri = Windows.Foundation.Uri(src);
    var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
    var download = downloader.createDownload(uri, storageFile);
    return download.startAsync();
}

function startDownload ( src , storageFile ) { var uri = Windows . Foundation . Uri ( src ) ; var downloader = new Windows . Networking . BackgroundTransfer . BackgroundDownloader ( ) ; var download = downloader . createDownload ( uri , storageFile ) ; return download . startAsync ( ) ; }

this can throw exceptions, callers responsibility

this can throw exceptions callers responsibility