<commit_before>'use strict';

/**
 * Module dependencies.
 */

var config = require('../config');
var R = require('ramda');
var co = require('co');

var QueueValue = require('../models/queueValue');
var Group = require('../models/group');

var converter = require('../lib/mongooseHelpers');

// Ties between the most common groups are broken
// by the smallest group being chosen first.
// Behavior is undefined if the groups are the same size.
exports.chooseGroup = function *(users, createOnNull) {
  var allQueueValues = {};
  var i;
  var userId;

  for (i = 0; i < users.length; i++) {
    userId = users[i]._id;
    allQueueValues[userId] = yield QueueValue.listByUser(userId);
  }

  var groups = {};
  var tmpGroupId;
  var maxGroup = [];
  var maxGroupCount = 0;
  var numUsers = 0;

  for (userId in allQueueValues) {
    if (allQueueValues.hasOwnProperty(userId)) {
      for (i = 0; i < allQueueValues[userId].length; i++) {
        tmpGroupId = allQueueValues[userId][i].groupId;
        if (!groups[tmpGroupId]) {
          groups[tmpGroupId] = [allQueueValues[userId][i]];
        } else {
          groups[tmpGroupId].push(allQueueValues[userId][i]);
        }
        if (groups[tmpGroupId].length > maxGroupCount) {
          maxGroupCount = groups[tmpGroupId].length;
          maxGroup = [tmpGroupId];
        } else if (groups[tmpGroupId].length === maxGroupCount) {
          maxGroup.push(tmpGroupId);
        }
      }
      numUsers++;
    }
  }

  var smallestGroup;

  if (numUsers === maxGroupCount) {
    smallestGroup = yield getSmallestGroup(maxGroup);
    if (smallestGroup) {
      yield createMissingQueueValues(smallestGroup._id, users, groups[smallestGroup._id.toString()]);
    }
    return smallestGroup;
  } else if (maxGroupCount >= config.minGroupSize &&
      maxGroupCount / numUsers >= config.minGroupPercent) {
    smallestGroup = yield getSmallestGroup(maxGroup);
    yield createMissingQueueValues(smallestGroup._id, users, groups[smallestGroup._id.toString()]);
    return smallestGroup;
  } else if (createOnNull) {

    // Create a new group because no existing group matches
    var tmpQueueValue;
    var groupId = null;
    for (i = 0; i < users.length; i++) {
      userId = users[i]._id;
      tmpQueueValue = yield QueueValue.create(userId, groupId);

      // In the case that the groupId was null, we need to reset the groupId
      // based on the newly generated one.
      groupId = tmpQueueValue.groupId;
    }
    return yield Group.create(groupId);
  }

};

exports.chooseGroupRoute = function *() {
  var users = converter.castIds(this.request.body.users);
  var group = yield exports.chooseGroup(users, true);

  // You need to wrap the response in case its null,
  // since it still needs to be JSON.
  this.body = {
    group: group
  };
};

function *getSmallestGroup(groupIds) {
  var smallestGroup;
  var smallestGroupSize = Number.MAX_SAFE_INTEGER;
  var i;
  var tmpGroupList;
  if (groupIds.length < 1) {
    return null;
  } else if (groupIds.length === 1) {
    return yield Group.get(groupIds[0]);
  } else {
    smallestGroup = null;
    for (i = 0; i < groupIds.length; i++) {
      tmpGroupList = yield QueueValue.listByGroup(groupIds[i]);
      if (tmpGroupList.length < smallestGroupSize) {
        smallestGroupSize = tmpGroupList.length;
        smallestGroup = groupIds[i];
      }
    }
    return yield Group.updateTotalUsers({
      _id: smallestGroup,
      totalUsers: smallestGroupSize
    });
  }
}

function *createMissingQueueValues(groupId, users, currentQueueValues) {
  var i;
  var j;
  var findMatch;
  var noMatch;
  var currentUserIdStrings = R.map(function(qv) {return qv.userId.toString();}, currentQueueValues);
  for (i = 0; i < users.length; i++) {
    findMatch = R.find(R.eq(users[i]._id.toString()));
    noMatch = R.pipe(findMatch, R.isNil);
    if (noMatch(currentUserIdStrings)) {
      yield QueueValue.create(users[i]._id, groupId);
    }
  }

}
<commit_msg>Remove unecessary require.<commit_after>'use strict';

/**
 * Module dependencies.
 */

var config = require('../config');
var R = require('ramda');

var QueueValue = require('../models/queueValue');
var Group = require('../models/group');

var converter = require('../lib/mongooseHelpers');

// Ties between the most common groups are broken
// by the smallest group being chosen first.
// Behavior is undefined if the groups are the same size.
exports.chooseGroup = function *(users, createOnNull) {
  var allQueueValues = {};
  var i;
  var userId;

  for (i = 0; i < users.length; i++) {
    userId = users[i]._id;
    allQueueValues[userId] = yield QueueValue.listByUser(userId);
  }

  var groups = {};
  var tmpGroupId;
  var maxGroup = [];
  var maxGroupCount = 0;
  var numUsers = 0;

  for (userId in allQueueValues) {
    if (allQueueValues.hasOwnProperty(userId)) {
      for (i = 0; i < allQueueValues[userId].length; i++) {
        tmpGroupId = allQueueValues[userId][i].groupId;
        if (!groups[tmpGroupId]) {
          groups[tmpGroupId] = [allQueueValues[userId][i]];
        } else {
          groups[tmpGroupId].push(allQueueValues[userId][i]);
        }
        if (groups[tmpGroupId].length > maxGroupCount) {
          maxGroupCount = groups[tmpGroupId].length;
          maxGroup = [tmpGroupId];
        } else if (groups[tmpGroupId].length === maxGroupCount) {
          maxGroup.push(tmpGroupId);
        }
      }
      numUsers++;
    }
  }

  var smallestGroup;

  if (numUsers === maxGroupCount) {
    smallestGroup = yield getSmallestGroup(maxGroup);
    if (smallestGroup) {
      yield createMissingQueueValues(smallestGroup._id, users, groups[smallestGroup._id.toString()]);
    }
    return smallestGroup;
  } else if (maxGroupCount >= config.minGroupSize &&
      maxGroupCount / numUsers >= config.minGroupPercent) {
    smallestGroup = yield getSmallestGroup(maxGroup);
    yield createMissingQueueValues(smallestGroup._id, users, groups[smallestGroup._id.toString()]);
    return smallestGroup;
  } else if (createOnNull) {

    // Create a new group because no existing group matches
    var tmpQueueValue;
    var groupId = null;
    for (i = 0; i < users.length; i++) {
      userId = users[i]._id;
      tmpQueueValue = yield QueueValue.create(userId, groupId);

      // In the case that the groupId was null, we need to reset the groupId
      // based on the newly generated one.
      groupId = tmpQueueValue.groupId;
    }
    return yield Group.create(groupId);
  }

};

exports.chooseGroupRoute = function *() {
  var users = converter.castIds(this.request.body.users);
  var group = yield exports.chooseGroup(users, true);

  // You need to wrap the response in case its null,
  // since it still needs to be JSON.
  this.body = {
    group: group
  };
};

function *getSmallestGroup(groupIds) {
  var smallestGroup;
  var smallestGroupSize = Number.MAX_SAFE_INTEGER;
  var i;
  var tmpGroupList;
  if (groupIds.length < 1) {
    return null;
  } else if (groupIds.length === 1) {
    return yield Group.get(groupIds[0]);
  } else {
    smallestGroup = null;
    for (i = 0; i < groupIds.length; i++) {
      tmpGroupList = yield QueueValue.listByGroup(groupIds[i]);
      if (tmpGroupList.length < smallestGroupSize) {
        smallestGroupSize = tmpGroupList.length;
        smallestGroup = groupIds[i];
      }
    }
    return yield Group.updateTotalUsers({
      _id: smallestGroup,
      totalUsers: smallestGroupSize
    });
  }
}

function *createMissingQueueValues(groupId, users, currentQueueValues) {
  var i;
  var j;
  var findMatch;
  var noMatch;
  var currentUserIdStrings = R.map(function(qv) {return qv.userId.toString();}, currentQueueValues);
  for (i = 0; i < users.length; i++) {
    findMatch = R.find(R.eq(users[i]._id.toString()));
    noMatch = R.pipe(findMatch, R.isNil);
    if (noMatch(currentUserIdStrings)) {
      yield QueueValue.create(users[i]._id, groupId);
    }
  }

}
<|endoftext|>


<commit_before>HTMLWidgets.widget({

  name: "sigma",

  type: "output",

  initialize: function(el, width, height) {

    // create our sigma object and bind it to the element
    var sig = new sigma(el.id);

    // return it as part of our instance data
    return {
      sig: sig
    };
  },

  renderValue: function(el, x, instance) {

    // parse gexf data
    var parser = new DOMParser();
    var data = parser.parseFromString(x.data, "application/xml");

    // apply settings
    for (var name in x.settings)
      instance.sig.settings(name, x.settings[name]);

    // update the sigma instance
    sigma.parsers.gexf(
      data,          // parsed gexf data
      instance.sig,  // sigma instance we created in initialize
      function() {
        // need to call refresh to reflect new settings and data
        instance.sig.refresh();
      }
    );
  },

  resize: function(el, width, height, instance) {

    // forward resize on to sigma renderers
    for (var name in instance.sig.renderers)
      console.log("this is the height:"+height+" and width" + width)
      instance.sig.renderers[name].resize(width, height);
  }
});
<commit_msg>Update sigma.js<commit_after>HTMLWidgets.widget({

  name: "sigma",

  type: "output",

  initialize: function(el, width, height) {

    // create our sigma object and bind it to the element
    var sig = new sigma(el.id);

    // return it as part of our instance data
    return {
      sig: sig
    };
  },

  renderValue: function(el, x, instance) {

    // parse gexf data
    var parser = new DOMParser();
    var data = parser.parseFromString(x.data, "application/xml");

    // apply settings
    for (var name in x.settings)
      instance.sig.settings(name, x.settings[name]);

    // update the sigma instance
    sigma.parsers.gexf(
      data,          // parsed gexf data
      instance.sig,  // sigma instance we created in initialize
      function() {
        // need to call refresh to reflect new settings and data
        instance.sig.refresh();
      }
    );
  },

  resize: function(el, width, height, instance) {

    // forward resize on to sigma renderers
    for (var name in instance.sig.renderers)
      console.log("this is the height:"+height+" and width" + width)
      instance.sig.renderers[name].resize(width, 2500);
  }
});
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var size = require('gulp-size');
var imagemin = require('gulp-imagemin');
var jshint = require('gulp-jshint');
var templateCache = require('gulp-angular-templatecache');
var minifyHtml = require('gulp-minify-html');
var minifyCss = require('gulp-minify-css');
var sass = require('gulp-sass');
var inject = require('gulp-inject');
var flatten = require('gulp-flatten');
var useref = require('gulp-useref');
var rev = require('gulp-rev');
var revReplace = require('gulp-rev-replace');
var gulpFilter = require('gulp-filter');
var replace = require('gulp-replace');
var jscs = require('gulp-jscs');
var express = require('express');
var del = require('del');
var runSequence = require('run-sequence');
var browserSync = require('browser-sync').create();
var argv = require('yargs').argv;
var stylish = require('gulp-jscs-stylish');
var karma = require('karma');

var common = require('./common');

var config = argv.config || 'production';
console.log('config: ' + config + ' (--config NAME)');

function noop() {}

gulp.task('clean', function() {
  return del(['dist', '.tmp']);
});

gulp.task('inject', ['sass', 'scripts'], function() {
  var appStyles = gulp.src('.tmp/serve/css/**/*.css', {read: false});
  var appScripts = gulp.src(common.JS, {read: false});
  var configScript = gulp.src('src/app/config/' + config + '.js');
  var vendorScripts = gulp.src(common.JS_VENDOR, {read: false});
  var vendorStyles = gulp.src(common.CSS_VENDOR, {read: false});
  var ieScripts = gulp.src(common.JS_IE, {read: false});

  return gulp.src('src/index.html')
    .pipe(inject(appStyles, {name: 'app', ignorePath: ['src', '.tmp/serve']}))
    .pipe(inject(appScripts, {name: 'app', ignorePath: ['src', '.tmp/serve']}))
    .pipe(inject(configScript, {name: 'config', ignorePath: ['src']}))
    .pipe(inject(vendorScripts, {name: 'vendor'}))
    .pipe(inject(vendorStyles, {name: 'vendor'}))
    .pipe(inject(ieScripts, {name: 'ie'}))
    .pipe(gulp.dest('.tmp/serve'))
    .pipe(browserSync.reload({stream: true}));
});

gulp.task('sass', function() {
  return gulp.src('src/sass/**/*.scss')
    .pipe(sass({
      includePaths: ['bower_components/bootstrap-sass/assets/stylesheets'],
      style: 'expanded'
    }))
    .pipe(gulp.dest('.tmp/serve/css'))
    .pipe(browserSync.reload({stream: true}));
});

gulp.task('scripts', function() {
  return gulp.src('src/app/**/*.js')
    .pipe(jshint())
    .pipe(jscs())
    .on('error', noop) // continue despite linting errors
    .pipe(stylish.combineWithHintResults())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(browserSync.reload({stream: true}));
});

gulp.task('html', ['inject', 'templates'], function() {
  var templates = gulp.src('.tmp/templates/*.js', {read: false});

  var assets = useref.assets();

  var jsFilter = gulpFilter('**/*.js', {restore: true});
  var cssFilter = gulpFilter('**/*.css', {restore: true});
  var htmlFilter = gulpFilter('*.html', {restore: true});

  return gulp.src('.tmp/serve/index.html')
    .pipe(inject(templates, {name: 'templates', ignorePath: '.tmp/templates'}))
    .pipe(assets)
    .pipe(rev())
    .pipe(jsFilter)
    .pipe(uglify())
    .pipe(jsFilter.restore)
    .pipe(cssFilter)
    .pipe(replace('/bower_components/bootstrap-sass/assets/fonts/bootstrap/', '../fonts/'))
    .pipe(replace('"images/', '"../images/'))
    .pipe(minifyCss({compatibility: 'ie8'}))
    .pipe(cssFilter.restore)
    .pipe(assets.restore())
    .pipe(useref())
    .pipe(revReplace())
    .pipe(htmlFilter)
    .pipe(minifyHtml({
      empty: true,
      spare: true,
      quotes: true,
      conditionals: true
    }))
    .pipe(htmlFilter.restore)
    .pipe(gulp.dest('dist'));
});

gulp.task('templates', function() {
  return gulp.src('src/app/**/*.html')
    .pipe(minifyHtml({
      empty: true,
      spare: true,
      quotes: true,
      conditionals: true
    }))
    .pipe(templateCache({
      root: 'app/',
      module: 'radar',
      filename: 'templates.js'
    }))
    .pipe(gulp.dest('.tmp/templates'));
});

gulp.task('fonts', function() {
  return gulp.src(common.FONTS_VENDOR)
    .pipe(flatten())
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('images', function() {
  return gulp.src(common.IMAGES)
    .pipe(imagemin({optimizationLevel: 3}))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('size', function() {
  return gulp.src('dist/**/*')
    .pipe(size({showFiles: true}));
});

// TODO watch:dist
gulp.task('watch', function() {
  gulp.watch('src/app/**/*.js', function(event) {
    if (event.type === 'changed') {
      gulp.start('scripts');
    } else {
      gulp.start('inject');
    }
  });

  gulp.watch('src/app/**/*.html', function(event) {
    browserSync.reload(event.path);
  });

  gulp.watch('src/sass/**/*.scss', function(event) {
    if (event.type === 'changed') {
      gulp.start('sass');
    } else {
      gulp.start('inject');
    }
  });

  gulp.watch('src/index.html', ['inject']);
});

gulp.task('browser-sync', function() {
  browserSync.init({
    proxy: 'http://localhost:8082',
    open: false
  });
});

gulp.task('express', function () {
  var app = express();

  app.use(express.static('.tmp/serve'));
  app.use(express.static('src'));
  app.use('/bower_components', express.static('bower_components'));

  app.get('/', function(req, res) {
    res.sendFile('.tmp/serve/index.html');
  });

  app.listen(8082);
});

gulp.task('express:dist', function () {
  var app = express();

  app.use(express.static('dist'));

  app.get('/', function(req, res) {
    res.sendFile('dist/index.html');
  });

  app.listen(8081);
});

gulp.task('lint', function() {
  return gulp.src('src/app/**/*.js')
    .pipe(jshint())
    .pipe(jscs())
    .pipe(stylish.combineWithHintResults())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('test', function(cb) {
  new karma.Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true,
    browsers: ['PhantomJS'],
    reporters: ['dots']
  }, cb).start();
});

gulp.task('coverage', function(cb) {
  new karma.Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true,
    browsers: ['PhantomJS'],
    reporters: ['dots', 'coverage']
  }, cb).start();
});

gulp.task('sauce-labs', function(cb) {
  new karma.Server({
    configFile: __dirname + '/sauce-labs.conf.js',
    singleRun: true
  }, cb).start();
});

gulp.task('build', function(cb) {
  runSequence('inject', cb);
});

gulp.task('build:dist', function(cb) {
  runSequence(
    'clean',
    ['html', 'fonts', 'images'],
    'size',
    cb
  );
});

gulp.task('serve', function(cb) {
  runSequence('build', ['watch', 'browser-sync', 'express'], cb);
});

gulp.task('serve:dist', function(cb) {
  runSequence('build:dist', 'express:dist', cb);
});

gulp.task('default', ['serve']);
<commit_msg>Run build before watch<commit_after>'use strict';

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var size = require('gulp-size');
var imagemin = require('gulp-imagemin');
var jshint = require('gulp-jshint');
var templateCache = require('gulp-angular-templatecache');
var minifyHtml = require('gulp-minify-html');
var minifyCss = require('gulp-minify-css');
var sass = require('gulp-sass');
var inject = require('gulp-inject');
var flatten = require('gulp-flatten');
var useref = require('gulp-useref');
var rev = require('gulp-rev');
var revReplace = require('gulp-rev-replace');
var gulpFilter = require('gulp-filter');
var replace = require('gulp-replace');
var jscs = require('gulp-jscs');
var express = require('express');
var del = require('del');
var runSequence = require('run-sequence');
var browserSync = require('browser-sync').create();
var argv = require('yargs').argv;
var stylish = require('gulp-jscs-stylish');
var karma = require('karma');

var common = require('./common');

var config = argv.config || 'production';
console.log('config: ' + config + ' (--config NAME)');

function noop() {}

gulp.task('clean', function() {
  return del(['dist', '.tmp']);
});

gulp.task('inject', ['sass', 'scripts'], function() {
  var appStyles = gulp.src('.tmp/serve/css/**/*.css', {read: false});
  var appScripts = gulp.src(common.JS, {read: false});
  var configScript = gulp.src('src/app/config/' + config + '.js');
  var vendorScripts = gulp.src(common.JS_VENDOR, {read: false});
  var vendorStyles = gulp.src(common.CSS_VENDOR, {read: false});
  var ieScripts = gulp.src(common.JS_IE, {read: false});

  return gulp.src('src/index.html')
    .pipe(inject(appStyles, {name: 'app', ignorePath: ['src', '.tmp/serve']}))
    .pipe(inject(appScripts, {name: 'app', ignorePath: ['src', '.tmp/serve']}))
    .pipe(inject(configScript, {name: 'config', ignorePath: ['src']}))
    .pipe(inject(vendorScripts, {name: 'vendor'}))
    .pipe(inject(vendorStyles, {name: 'vendor'}))
    .pipe(inject(ieScripts, {name: 'ie'}))
    .pipe(gulp.dest('.tmp/serve'))
    .pipe(browserSync.reload({stream: true}));
});

gulp.task('sass', function() {
  return gulp.src('src/sass/**/*.scss')
    .pipe(sass({
      includePaths: ['bower_components/bootstrap-sass/assets/stylesheets'],
      style: 'expanded'
    }))
    .pipe(gulp.dest('.tmp/serve/css'))
    .pipe(browserSync.reload({stream: true}));
});

gulp.task('scripts', function() {
  return gulp.src('src/app/**/*.js')
    .pipe(jshint())
    .pipe(jscs())
    .on('error', noop) // continue despite linting errors
    .pipe(stylish.combineWithHintResults())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(browserSync.reload({stream: true}));
});

gulp.task('html', ['inject', 'templates'], function() {
  var templates = gulp.src('.tmp/templates/*.js', {read: false});

  var assets = useref.assets();

  var jsFilter = gulpFilter('**/*.js', {restore: true});
  var cssFilter = gulpFilter('**/*.css', {restore: true});
  var htmlFilter = gulpFilter('*.html', {restore: true});

  return gulp.src('.tmp/serve/index.html')
    .pipe(inject(templates, {name: 'templates', ignorePath: '.tmp/templates'}))
    .pipe(assets)
    .pipe(rev())
    .pipe(jsFilter)
    .pipe(uglify())
    .pipe(jsFilter.restore)
    .pipe(cssFilter)
    .pipe(replace('/bower_components/bootstrap-sass/assets/fonts/bootstrap/', '../fonts/'))
    .pipe(replace('"images/', '"../images/'))
    .pipe(minifyCss({compatibility: 'ie8'}))
    .pipe(cssFilter.restore)
    .pipe(assets.restore())
    .pipe(useref())
    .pipe(revReplace())
    .pipe(htmlFilter)
    .pipe(minifyHtml({
      empty: true,
      spare: true,
      quotes: true,
      conditionals: true
    }))
    .pipe(htmlFilter.restore)
    .pipe(gulp.dest('dist'));
});

gulp.task('templates', function() {
  return gulp.src('src/app/**/*.html')
    .pipe(minifyHtml({
      empty: true,
      spare: true,
      quotes: true,
      conditionals: true
    }))
    .pipe(templateCache({
      root: 'app/',
      module: 'radar',
      filename: 'templates.js'
    }))
    .pipe(gulp.dest('.tmp/templates'));
});

gulp.task('fonts', function() {
  return gulp.src(common.FONTS_VENDOR)
    .pipe(flatten())
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('images', function() {
  return gulp.src(common.IMAGES)
    .pipe(imagemin({optimizationLevel: 3}))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('size', function() {
  return gulp.src('dist/**/*')
    .pipe(size({showFiles: true}));
});

// TODO watch:dist
gulp.task('watch', ['build'], function() {
  gulp.watch('src/app/**/*.js', function(event) {
    if (event.type === 'changed') {
      gulp.start('scripts');
    } else {
      gulp.start('inject');
    }
  });

  gulp.watch('src/app/**/*.html', function(event) {
    browserSync.reload(event.path);
  });

  gulp.watch('src/sass/**/*.scss', function(event) {
    if (event.type === 'changed') {
      gulp.start('sass');
    } else {
      gulp.start('inject');
    }
  });

  gulp.watch('src/index.html', ['inject']);
});

gulp.task('browser-sync', function() {
  browserSync.init({
    proxy: 'http://localhost:8082',
    open: false
  });
});

gulp.task('express', function () {
  var app = express();

  app.use(express.static('.tmp/serve'));
  app.use(express.static('src'));
  app.use('/bower_components', express.static('bower_components'));

  app.get('/', function(req, res) {
    res.sendFile('.tmp/serve/index.html');
  });

  app.listen(8082);
});

gulp.task('express:dist', function () {
  var app = express();

  app.use(express.static('dist'));

  app.get('/', function(req, res) {
    res.sendFile('dist/index.html');
  });

  app.listen(8081);
});

gulp.task('lint', function() {
  return gulp.src('src/app/**/*.js')
    .pipe(jshint())
    .pipe(jscs())
    .pipe(stylish.combineWithHintResults())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

gulp.task('test', function(cb) {
  new karma.Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true,
    browsers: ['PhantomJS'],
    reporters: ['dots']
  }, cb).start();
});

gulp.task('coverage', function(cb) {
  new karma.Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true,
    browsers: ['PhantomJS'],
    reporters: ['dots', 'coverage']
  }, cb).start();
});

gulp.task('sauce-labs', function(cb) {
  new karma.Server({
    configFile: __dirname + '/sauce-labs.conf.js',
    singleRun: true
  }, cb).start();
});

gulp.task('build', function(cb) {
  runSequence('inject', cb);
});

gulp.task('build:dist', function(cb) {
  runSequence(
    'clean',
    ['html', 'fonts', 'images'],
    'size',
    cb
  );
});

gulp.task('serve', function(cb) {
  runSequence('build', ['watch', 'browser-sync', 'express'], cb);
});

gulp.task('serve:dist', function(cb) {
  runSequence('build:dist', 'express:dist', cb);
});

gulp.task('default', ['serve']);
<|endoftext|>


<commit_before>Maths.floatToString = function ( v ) {
    return  "" + ( Math.floor( v * 10 ) / 10 );
};<commit_msg>Fixed for floatToString<commit_after>Maths.floatToString = function ( value, precision ) {
    var power = Math.pow( 10, precision || 0 );
    return String( Math.round( value * power ) / power );
};<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';

import {
  Text,
  View,
  Image,
  Animated,
  ScrollView
} from 'react-native';

import { Icon, List, ListItem } from 'react-native-elements';

import { USER, FACEBOOK_LIST, SLACK_LIST, GENERIC_LIST, SCREEN_WIDTH, SCREEN_HEIGHT, DEFAULT_WINDOW_MULTIPLIER, DEFAULT_NAVBAR_HEIGHT } from './constants';

import styles from './styles';

const ScrollViewPropTypes = ScrollView.propTypes;

export default class ParallaxScrollView extends Component {
  constructor() {
    super();

    this.state = {
      scrollY: new Animated.Value(0)
    };
  }

  scrollTo(where) {
    const { scroll } = this.refs;
    if (!scroll) return;
    scroll.scrollTo(where);
  }

  renderBackground() {
    var { windowHeight, backgroundSource } = this.props;
    var { scrollY } = this.state;
    if (!windowHeight || !backgroundSource) {
      return null;
    }

    return (
      <Animated.Image
        style={[
          styles.background,
          {
            height: windowHeight,
            transform: [
              {
                translateY: scrollY.interpolate({
                  inputRange: [-windowHeight, 0, windowHeight],
                  outputRange: [windowHeight / 2, 0, -windowHeight / 3]
                })
              },
              {
                scale: scrollY.interpolate({
                  inputRange: [-windowHeight, 0, windowHeight],
                  outputRange: [2, 1, 1]
                })
              }
            ]
          }
        ]}
        source={backgroundSource}
      >
      </Animated.Image>
    );
  }

  renderHeaderView() {
    const { windowHeight, backgroundSource, userImage, userName, userTitle, navBarHeight } = this.props;
    const { scrollY } = this.state;
    if (!windowHeight || !backgroundSource) {
      return null;
    }

    const newNavBarHeight = navBarHeight || DEFAULT_NAVBAR_HEIGHT;
    const newWindowHeight = windowHeight - newNavBarHeight;

    return (
      <Animated.View
        style={{
          opacity: scrollY.interpolate({
            inputRange: [-windowHeight, 0, windowHeight * DEFAULT_WINDOW_MULTIPLIER + newNavBarHeight],
            outputRange: [1, 1, 0]
          })
        }}
      >
        <View style={{height: newWindowHeight, justifyContent: 'center', alignItems: 'center'}}>
          {this.props.headerView ||
            (
              <View>
                <View
                  style={styles.avatarView}
                >
                  <Image source={{uri: userImage || USER.image}} style={{height: 120, width: 120, borderRadius: 60}} />
                </View>
                <View style={{paddingVertical: 10}}>
                  <Text style={{textAlign: 'center', fontSize: 22, color: 'white', paddingBottom: 5}}>{userName || USER.name}</Text>
                  <Text style={{textAlign: 'center', fontSize: 17, color: 'rgba(247,247, 250, 1)', paddingBottom: 5}}>{userTitle || USER.title}</Text>
                </View>
              </View>
            )
          }
        </View>
      </Animated.View>
    );
  }

  renderNavBarTitle() {
    const { windowHeight, backgroundSource, navBarTitleColor, navBarTitleComponent } = this.props;
    const { scrollY } = this.state;
    if (!windowHeight || !backgroundSource) {
      return null;
    }

    return (
      <Animated.View
        style={{
          opacity: scrollY.interpolate({
            inputRange: [-windowHeight, windowHeight * DEFAULT_WINDOW_MULTIPLIER, windowHeight * 0.8],
            outputRange: [0, 0, 1]
          })
        }}
      >
        {navBarTitleComponent ||
        <Text style={{ fontSize: 18, fontWeight: '600', color: navBarTitleColor || 'white' }}>
          {this.props.navBarTitle || USER.name}
        </Text>}
      </Animated.View>
    );
  }

  rendernavBar() {
    const {
      windowHeight, backgroundSource, leftIcon,
      rightIcon, leftIconOnPress, rightIconOnPress, navBarColor, navBarHeight, leftIconUnderlayColor, rightIconUnderlayColor
    } = this.props;
    const { scrollY } = this.state;
    if (!windowHeight || !backgroundSource) {
      return null;
    }

    const newNavBarHeight = navBarHeight || DEFAULT_NAVBAR_HEIGHT;

    if(this.props.navBarView)
    {
        return (
          <Animated.View
            style={{
              height: newNavBarHeight,
              width: SCREEN_WIDTH,
              flexDirection: 'row',
              backgroundColor: scrollY.interpolate({
                inputRange: [-windowHeight, windowHeight * DEFAULT_WINDOW_MULTIPLIER, windowHeight * 0.8],
                outputRange: ['transparent', 'transparent', navBarColor || 'rgba(0, 0, 0, 1.0)'],
                extrapolate: 'clamp'
              })
            }}
          >
          {this.props.navBarView}
          </Animated.View>
        );
    }
    else
    {
        return (
          <Animated.View
            style={{
              height: newNavBarHeight,
              width: SCREEN_WIDTH,
              flexDirection: 'row',
              backgroundColor: scrollY.interpolate({
                inputRange: [-windowHeight, windowHeight * DEFAULT_WINDOW_MULTIPLIER, windowHeight * 0.8],
                outputRange: ['transparent', 'transparent', navBarColor || 'rgba(0, 0, 0, 1.0)']
              })
            }}
          >
          {leftIcon &&
            <View
              style={{
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center'
              }}
            >
              <Icon
                name={leftIcon && leftIcon.name || 'menu'}
                type={leftIcon && leftIcon.type || 'simple-line-icon'}
                color={leftIcon && leftIcon.color || 'white'}
                size={leftIcon && leftIcon.size || 23}
                onPress={leftIconOnPress}
                underlayColor={leftIconUnderlayColor || 'transparent'}
              />
            </View>
          }
            <View
              style={{
                flex: 5,
                justifyContent: 'center',
                alignItems: 'center',
                alignSelf: 'center'
              }}
            >
              {this.renderNavBarTitle()}
            </View>
          {rightIcon &&
            <View
              style={{
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center'
              }}
            >
              <Icon
                name={rightIcon && rightIcon.name || 'present'}
                type={rightIcon && rightIcon.type || 'simple-line-icon'}
                color={rightIcon && rightIcon.color || 'white'}
                size={rightIcon && rightIcon.size || 23}
                onPress={rightIconOnPress}
                underlayColor={rightIconUnderlayColor || 'transparent'}
              />
            </View>
          }
          </Animated.View>
        );
    }
  }

  renderTodoListContent() {
    return (
      <View style={styles.listView}>
        <List>
        {
          FACEBOOK_LIST.map((item, index) => (
            <ListItem
              key={index}
              onPress={() => console.log('List item pressed')}
              title={item.title}
              leftIcon={{name: item.icon}} />
          ))
        }
        </List>
        <List>
        {
          SLACK_LIST.map((item, index) => (
            <ListItem
              key={index}
              onPress={() => console.log('List item pressed')}
              title={item.title}
              leftIcon={{name: item.icon}} />
          ))
        }
        </List>
        <List>
        {
          GENERIC_LIST.map((item, index) => (
            <ListItem
              key={index}
              onPress={() => console.log('List item pressed')}
              title={item.title}
              leftIcon={{name: item.icon}} />
          ))
        }
        </List>
        <List containerStyle={{marginBottom: 15}}>
          <ListItem
            key={1}
            hideChevron={true}
            onPress={() => console.log('Logout Pressed')}
            title='LOGOUT'
            titleStyle={styles.logoutText}
            icon={{name: ''}} />
        </List>
      </View>
    );
  }

  render() {
    const { style, ...props } = this.props;

    return (
      <View style={[styles.container, style]}>
        {this.renderBackground()}
        {this.rendernavBar()}
        <ScrollView ref='scroll'
          ref={component => {
            this._scrollView = component;
          }}
          {...props}
          style={styles.scrollView}
          onScroll={Animated.event([
            { nativeEvent: { contentOffset: { y: this.state.scrollY } } }
          ])}
          scrollEventThrottle={16}
        >
          {this.renderHeaderView()}
          <View style={[styles.content, props.scrollableViewStyle]}>
            {this.props.children || this.renderTodoListContent()}
          </View>
        </ScrollView>
      </View>
    );
  }
}

ParallaxScrollView.defaultProps = {
  backgroundSource: {uri: 'http://i.imgur.com/6Iej2c3.png'},
  windowHeight: SCREEN_HEIGHT * DEFAULT_WINDOW_MULTIPLIER,
  leftIconOnPress: () => console.log('Left icon pressed'),
  rightIconOnPress: () => console.log('Right icon pressed')
};

ParallaxScrollView.propTypes = {
  ...ScrollViewPropTypes,
  backgroundSource: PropTypes.object,
  windowHeight: PropTypes.number,
  navBarTitle: PropTypes.string,
  navBarTitleColor: PropTypes.string,
  navBarTitleComponent: PropTypes.node,
  navBarColor: PropTypes.string,
  userImage: PropTypes.string,
  userName: PropTypes.string,
  userTitle: PropTypes.string,
  headerView: PropTypes.node,
  leftIcon: PropTypes.object,
  rightIcon: PropTypes.object
};<commit_msg>Fixed mistake: the ref for the internal scrollview was already defined.<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';

import {
  Text,
  View,
  Image,
  Animated,
  ScrollView
} from 'react-native';

import { Icon, List, ListItem } from 'react-native-elements';

import { USER, FACEBOOK_LIST, SLACK_LIST, GENERIC_LIST, SCREEN_WIDTH, SCREEN_HEIGHT, DEFAULT_WINDOW_MULTIPLIER, DEFAULT_NAVBAR_HEIGHT } from './constants';

import styles from './styles';

const ScrollViewPropTypes = ScrollView.propTypes;

export default class ParallaxScrollView extends Component {
  constructor() {
    super();

    this.state = {
      scrollY: new Animated.Value(0)
    };
  }

  scrollTo(where) {
    if (!this._scrollView) return;
    this._scrollView.scrollTo(where);
  }

  renderBackground() {
    var { windowHeight, backgroundSource } = this.props;
    var { scrollY } = this.state;
    if (!windowHeight || !backgroundSource) {
      return null;
    }

    return (
      <Animated.Image
        style={[
          styles.background,
          {
            height: windowHeight,
            transform: [
              {
                translateY: scrollY.interpolate({
                  inputRange: [-windowHeight, 0, windowHeight],
                  outputRange: [windowHeight / 2, 0, -windowHeight / 3]
                })
              },
              {
                scale: scrollY.interpolate({
                  inputRange: [-windowHeight, 0, windowHeight],
                  outputRange: [2, 1, 1]
                })
              }
            ]
          }
        ]}
        source={backgroundSource}
      >
      </Animated.Image>
    );
  }

  renderHeaderView() {
    const { windowHeight, backgroundSource, userImage, userName, userTitle, navBarHeight } = this.props;
    const { scrollY } = this.state;
    if (!windowHeight || !backgroundSource) {
      return null;
    }

    const newNavBarHeight = navBarHeight || DEFAULT_NAVBAR_HEIGHT;
    const newWindowHeight = windowHeight - newNavBarHeight;

    return (
      <Animated.View
        style={{
          opacity: scrollY.interpolate({
            inputRange: [-windowHeight, 0, windowHeight * DEFAULT_WINDOW_MULTIPLIER + newNavBarHeight],
            outputRange: [1, 1, 0]
          })
        }}
      >
        <View style={{height: newWindowHeight, justifyContent: 'center', alignItems: 'center'}}>
          {this.props.headerView ||
            (
              <View>
                <View
                  style={styles.avatarView}
                >
                  <Image source={{uri: userImage || USER.image}} style={{height: 120, width: 120, borderRadius: 60}} />
                </View>
                <View style={{paddingVertical: 10}}>
                  <Text style={{textAlign: 'center', fontSize: 22, color: 'white', paddingBottom: 5}}>{userName || USER.name}</Text>
                  <Text style={{textAlign: 'center', fontSize: 17, color: 'rgba(247,247, 250, 1)', paddingBottom: 5}}>{userTitle || USER.title}</Text>
                </View>
              </View>
            )
          }
        </View>
      </Animated.View>
    );
  }

  renderNavBarTitle() {
    const { windowHeight, backgroundSource, navBarTitleColor, navBarTitleComponent } = this.props;
    const { scrollY } = this.state;
    if (!windowHeight || !backgroundSource) {
      return null;
    }

    return (
      <Animated.View
        style={{
          opacity: scrollY.interpolate({
            inputRange: [-windowHeight, windowHeight * DEFAULT_WINDOW_MULTIPLIER, windowHeight * 0.8],
            outputRange: [0, 0, 1]
          })
        }}
      >
        {navBarTitleComponent ||
        <Text style={{ fontSize: 18, fontWeight: '600', color: navBarTitleColor || 'white' }}>
          {this.props.navBarTitle || USER.name}
        </Text>}
      </Animated.View>
    );
  }

  rendernavBar() {
    const {
      windowHeight, backgroundSource, leftIcon,
      rightIcon, leftIconOnPress, rightIconOnPress, navBarColor, navBarHeight, leftIconUnderlayColor, rightIconUnderlayColor
    } = this.props;
    const { scrollY } = this.state;
    if (!windowHeight || !backgroundSource) {
      return null;
    }

    const newNavBarHeight = navBarHeight || DEFAULT_NAVBAR_HEIGHT;

    if(this.props.navBarView)
    {
        return (
          <Animated.View
            style={{
              height: newNavBarHeight,
              width: SCREEN_WIDTH,
              flexDirection: 'row',
              backgroundColor: scrollY.interpolate({
                inputRange: [-windowHeight, windowHeight * DEFAULT_WINDOW_MULTIPLIER, windowHeight * 0.8],
                outputRange: ['transparent', 'transparent', navBarColor || 'rgba(0, 0, 0, 1.0)'],
                extrapolate: 'clamp'
              })
            }}
          >
          {this.props.navBarView}
          </Animated.View>
        );
    }
    else
    {
        return (
          <Animated.View
            style={{
              height: newNavBarHeight,
              width: SCREEN_WIDTH,
              flexDirection: 'row',
              backgroundColor: scrollY.interpolate({
                inputRange: [-windowHeight, windowHeight * DEFAULT_WINDOW_MULTIPLIER, windowHeight * 0.8],
                outputRange: ['transparent', 'transparent', navBarColor || 'rgba(0, 0, 0, 1.0)']
              })
            }}
          >
          {leftIcon &&
            <View
              style={{
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center'
              }}
            >
              <Icon
                name={leftIcon && leftIcon.name || 'menu'}
                type={leftIcon && leftIcon.type || 'simple-line-icon'}
                color={leftIcon && leftIcon.color || 'white'}
                size={leftIcon && leftIcon.size || 23}
                onPress={leftIconOnPress}
                underlayColor={leftIconUnderlayColor || 'transparent'}
              />
            </View>
          }
            <View
              style={{
                flex: 5,
                justifyContent: 'center',
                alignItems: 'center',
                alignSelf: 'center'
              }}
            >
              {this.renderNavBarTitle()}
            </View>
          {rightIcon &&
            <View
              style={{
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center'
              }}
            >
              <Icon
                name={rightIcon && rightIcon.name || 'present'}
                type={rightIcon && rightIcon.type || 'simple-line-icon'}
                color={rightIcon && rightIcon.color || 'white'}
                size={rightIcon && rightIcon.size || 23}
                onPress={rightIconOnPress}
                underlayColor={rightIconUnderlayColor || 'transparent'}
              />
            </View>
          }
          </Animated.View>
        );
    }
  }

  renderTodoListContent() {
    return (
      <View style={styles.listView}>
        <List>
        {
          FACEBOOK_LIST.map((item, index) => (
            <ListItem
              key={index}
              onPress={() => console.log('List item pressed')}
              title={item.title}
              leftIcon={{name: item.icon}} />
          ))
        }
        </List>
        <List>
        {
          SLACK_LIST.map((item, index) => (
            <ListItem
              key={index}
              onPress={() => console.log('List item pressed')}
              title={item.title}
              leftIcon={{name: item.icon}} />
          ))
        }
        </List>
        <List>
        {
          GENERIC_LIST.map((item, index) => (
            <ListItem
              key={index}
              onPress={() => console.log('List item pressed')}
              title={item.title}
              leftIcon={{name: item.icon}} />
          ))
        }
        </List>
        <List containerStyle={{marginBottom: 15}}>
          <ListItem
            key={1}
            hideChevron={true}
            onPress={() => console.log('Logout Pressed')}
            title='LOGOUT'
            titleStyle={styles.logoutText}
            icon={{name: ''}} />
        </List>
      </View>
    );
  }

  render() {
    const { style, ...props } = this.props;

    return (
      <View style={[styles.container, style]}>
        {this.renderBackground()}
        {this.rendernavBar()}
        <ScrollView
          ref={component => {
            this._scrollView = component;
          }}
          {...props}
          style={styles.scrollView}
          onScroll={Animated.event([
            { nativeEvent: { contentOffset: { y: this.state.scrollY } } }
          ])}
          scrollEventThrottle={16}
        >
          {this.renderHeaderView()}
          <View style={[styles.content, props.scrollableViewStyle]}>
            {this.props.children || this.renderTodoListContent()}
          </View>
        </ScrollView>
      </View>
    );
  }
}

ParallaxScrollView.defaultProps = {
  backgroundSource: {uri: 'http://i.imgur.com/6Iej2c3.png'},
  windowHeight: SCREEN_HEIGHT * DEFAULT_WINDOW_MULTIPLIER,
  leftIconOnPress: () => console.log('Left icon pressed'),
  rightIconOnPress: () => console.log('Right icon pressed')
};

ParallaxScrollView.propTypes = {
  ...ScrollViewPropTypes,
  backgroundSource: PropTypes.object,
  windowHeight: PropTypes.number,
  navBarTitle: PropTypes.string,
  navBarTitleColor: PropTypes.string,
  navBarTitleComponent: PropTypes.node,
  navBarColor: PropTypes.string,
  userImage: PropTypes.string,
  userName: PropTypes.string,
  userTitle: PropTypes.string,
  headerView: PropTypes.node,
  leftIcon: PropTypes.object,
  rightIcon: PropTypes.object
};<|endoftext|>


<commit_before>require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core')
const DragDrop = require('@uppy/drag-drop')
const XHRUpload = require('@uppy/xhr-upload')
const ProgressBar = require('@uppy/progress-bar')

const uppyi18n = new Uppy({
  id: 'uppyi18n',
  debug: true,
  autoProceed: true
})

uppyi18n
  .use(DragDrop, {
    target: '#uppyi18n',
    locale: {
      strings: {
        dropHereOr: 'Перенесите файлы сюда или %{browse}',
        browse: 'выберите'
      }
    }
  })
  .use(ProgressBar, { target: '#uppyi18n-progress' })
  .use(XHRUpload, { endpoint: 'https://api2.transloadit.com' })
<commit_msg>switch to xhr-server.herokuapp.com endpoint<commit_after>require('es6-promise/auto')
require('whatwg-fetch')
const Uppy = require('@uppy/core')
const DragDrop = require('@uppy/drag-drop')
const XHRUpload = require('@uppy/xhr-upload')
const ProgressBar = require('@uppy/progress-bar')

const uppyi18n = new Uppy({
  id: 'uppyi18n',
  debug: true,
  autoProceed: true
})

uppyi18n
  .use(DragDrop, {
    target: '#uppyi18n',
    locale: {
      strings: {
        dropHereOr: 'Перенесите файлы сюда или %{browse}',
        browse: 'выберите'
      }
    }
  })
  .use(ProgressBar, { target: '#uppyi18n-progress' })
  .use(XHRUpload, { endpoint: 'https://xhr-server.herokuapp.com/upload' })
<|endoftext|>


<commit_before>const header = `
// Type definitions for Tabris.js \${VERSION}
/// <reference path="console.d.ts" />
/// <reference path="localStorage.d.ts" />
/// <reference path="timer.d.ts" />
/// <reference path="whatwg-fetch.d.ts" />
/// <reference path="Event.d.ts" />
/// <reference path="XMLHttpRequest.d.ts" />
/// <reference path="ObjectAssign.d.ts" />

type Partial<T> = {
  [P in keyof T]?: T[P];
};

export as namespace tabris;

`.trim();

module.exports = function(grunt) {

  grunt.registerTask('generate-tsd', () => {
    let defs = readJsonDefs();
    let tsd = createTypeDefs(defs).replace(/\${VERSION}/g, grunt.config('version'));
    grunt.file.write('build/tabris/tabris.d.ts', tsd);
  });

  function readJsonDefs() {
    let defs = {};
    let doc = grunt.config('doc');
    let files = grunt.file.expand(doc.api);
    files.forEach((file) => {
      let json = grunt.file.readJSON(file);
      json.file = file;
      defs[json.type] = json;
    });
    return defs;
  }

  function createTypeDefs(defs) {
    let result = new Text();
    result.append(header);
    result.append('');
    result.append(grunt.file.read(grunt.config('doc').typings));
    result.append('');
    Object.keys(defs).forEach((name) => {
      addInheritedEvents(defs, defs[name]);
      createTypeDef(result, defs[name]);
    });
    result.append('');
    return result.toString();
  }

  function addInheritedEvents(defs, def) {
    if (def.extends) {
      if (!(def.extends in defs)) {
        throw new Error('Super type not found for ' + def.type);
      }
      addInheritedEvents(defs, def.extends);
      def.events = Object.assign({}, defs[def.extends].events || {}, def.events);
    }
  }

  function createTypeDef(result, def) {
    result.append('// ' + def.type);
    result.append('');
    addPropertyInterface(result, def);
    result.append('');
    addClass(result, def);
    addInstance(result, def);
    result.append('');
  }

  function addInstance(result, def) {
    if (def.object) {
      result.append('');
      result.append(`declare let ${def.object}: ${def.type};`);
    }
  }

  function addClass(result, def) {
    result.append(createDoc(def));
    addClassDef(result, def);
    result.indent++;
    addConstructor(result, def);
    addMethods(result, def);
    addReadonlyProperties(result, def);
    addPropertyApi(result, def);
    result.indent--;
    result.append('}');
  }

  function addConstructor(result, def) {
    result.append('');
    result.append(`constructor(properties?: ${def.type}Properties);`);
  }

  function addClassDef(result, def) {
    result.append(`interface ${def.type} extends _${def.type}Properties {}`);
    let str = 'export class ' + def.type;
    if (def.extends) {
      str += ' extends ' + def.extends;
    }
    result.append(str + ' {');
  }

  function addPropertyInterface(result, def) {
    result.append(createPropertyInterfaceDef(def));
    result.indent++;
    Object.keys(def.properties || {}).filter(name => !def.properties[name].readonly).sort().forEach((name) => {
      result.append('');
      result.append(createProperty(name, def.properties[name]));
    });
    result.indent--;
    result.append('}');
    result.append(`type ${def.type}Properties = Partial<_${def.type}Properties>`);
  }

  function createPropertyInterfaceDef(def) {
    let str = 'interface _' + def.type + 'Properties';
    if (def.extends) {
      str += ' extends _' + def.extends + 'Properties';
    }
    return str + ' {';
  }

  function addMethods(result, def) {
    if (def.methods) {
      Object.keys(def.methods).sort().forEach((name) => {
        if (!Array.isArray(def.methods[name])) {
          throw new Error('method definition not an array', def.type, name);
        }
        def.methods[name].forEach((method) => {
          result.append('');
          result.append(createMethod(name, method));
        });
      });
    }
  }

  function addReadonlyProperties(result, def) {
    if (def.properties) {
      Object.keys(def.properties || {}).filter(name => def.properties[name].readonly).sort().forEach((name) => {
        result.append('');
        result.append(createProperty(name, def.properties[name]));
      });
    }
  }

  function addPropertyApi(result, def) {
    if (def.properties) {
      result.append('');
      result.append(createComment([
        'Gets the current value of the given *property*.',
        '@param property'
      ]));
      result.append('get(property: string): any;');
      result.append('');
      result.append(createComment([
        'Sets the given property. Supports chaining.',
        '@param property',
        '@param value'
      ]));
      result.append('set(property: string, value: any): this;');
      result.append('');
      result.append(createComment([
        'Sets all key-value pairs in the properties object as widget properties. Supports chaining.',
        '@param properties'
      ]));
      result.append(`set(properties: ${def.type}Properties): this;`);
    }
  }

  function createProperty(name, def) {
    let result = [];
    result.push(createDoc(def));
    let values = [];
    (def.values || []).sort().forEach((value) => {
      values.push(`"${value}"`);
    });
    let valuesType = (values || []).join(' | ');
    result.push(`${def.readonly ? 'readonly ' : ''}${name}: ${valuesType || def.type};`);
    return result.join('\n');
  }

  function createMethod(name, def) {
    let result = [];
    result.push(createDoc(def));
    result.push(`${name}(${createParamList(def.parameters)}): ${def.returns || 'void'};`);
    return result.join('\n');
  }

  function createParamList(parameters) {
    return parameters.map(param => `${param.name}${param.optional ? '?' : ''}: ${param.type}`).join(', ');
  }

  function createDoc(def) {
    if (!def.description && !def.static && !def.provisional) {
      return;
    }
    let result = [];
    if (def.description) {
      splitIntoLines(def.description, 100).forEach((line) => {
        result.push(line);
      });
    }
    if (def.parameters) {
      createParamAnnotations(def.parameters).forEach((line) => {
        result.push(line);
      });
    }
    if (def.deprecated) {
      let message = typeof def.deprecated === 'string' ? `'${def.deprecated}'` : '';
      result.push(`@deprecated(${message})`);
    }
    if (def.static) {
      result.push('@static');
    }
    if (def.provisional) {
      result.push('@provisional');
    }
    return createComment(result);
  }

  function createComment(comment) {
    return ['/**'].concat(comment.map(line => ' * ' + line), ' */').join('\n');
  }
  function createParamAnnotations(params) {
    return params.map(param => `@param ${param.name} ${param.description || ''}`);
  }

  function splitIntoLines(text, maxlen) {
    if (typeof text !== 'string') {
      throw new Error('not a string: ' + text);
    }
    let linesIn = text.split('\n');
    let linesOut = [];
    for (let lineIn of linesIn) {
      let lineOut = '';
      let words = lineIn.split(' ');
      for (let word of words) {
        if (lineOut.length + word.length > maxlen) {
          linesOut.push(lineOut);
          lineOut = '';
        }
        if (lineOut.length > 0) {
          lineOut += ' ';
        }
        lineOut += word;
      }
      if (lineOut.length > 0) {
        linesOut.push(lineOut);
      }
    }
    return linesOut;
  }

  class Text {

    constructor() {
      this.lines = [];
      this.indent = 0;
    }

    append() {
      Array.prototype.forEach.call(arguments, (arg) => {
        let lines = typeof arg === 'string' ? arg.split('\n') : arg;
        for (let line of lines) {
          this.lines.push(this._indentLine(line));
        }
      }, this);
    }

    toString() {
      return this.lines.join('\n');
    }

    _indentLine(line) {
      return line.length > 0 ? '  '.repeat(this.indent) + line : line;
    }

  }

};

<commit_msg>[TypeScript] only generate property interfaces for NativeObjects <commit_after>const header = `
// Type definitions for Tabris.js \${VERSION}
/// <reference path="console.d.ts" />
/// <reference path="localStorage.d.ts" />
/// <reference path="timer.d.ts" />
/// <reference path="whatwg-fetch.d.ts" />
/// <reference path="Event.d.ts" />
/// <reference path="XMLHttpRequest.d.ts" />
/// <reference path="ObjectAssign.d.ts" />

type Partial<T> = {
  [P in keyof T]?: T[P];
};

export as namespace tabris;

`.trim();

module.exports = function(grunt) {

  grunt.registerTask('generate-tsd', () => {
    let defs = readJsonDefs();
    let tsd = createTypeDefs(defs).replace(/\${VERSION}/g, grunt.config('version'));
    grunt.file.write('build/tabris/tabris.d.ts', tsd);
  });

  function readJsonDefs() {
    let defs = {};
    let doc = grunt.config('doc');
    let files = grunt.file.expand(doc.api);
    files.forEach((file) => {
      let json = grunt.file.readJSON(file);
      json.file = file;
      defs[json.type] = json;
    });
    return defs;
  }

  function createTypeDefs(defs) {
    let result = new Text();
    result.append(header);
    result.append('');
    result.append(grunt.file.read(grunt.config('doc').typings));
    result.append('');
    Object.keys(defs).forEach((name) => {
      defs[name].isNativeObject = isNativeObject(defs, defs[name]);
      createTypeDef(result, defs[name]);
    });
    result.append('');
    return result.toString();
  }

  function isNativeObject(defs, def) {
    return def && (def.type === 'NativeObject' || isNativeObject(defs, defs[def.extends]));
  }

  function createTypeDef(result, def) {
    result.append('// ' + def.type);
    if (def.isNativeObject) {
      result.append('');
      addPropertyInterface(result, def);
    }
    result.append('');
    addClass(result, def);
    addInstance(result, def);
    result.append('');
  }

  function addInstance(result, def) {
    if (def.object) {
      result.append('');
      result.append(`declare let ${def.object}: ${def.type};`);
    }
  }

  function addClass(result, def) {
    result.append(createDoc(def));
    addClassDef(result, def);
    result.indent++;
    addConstructor(result, def);
    addMethods(result, def);
    let propertiesFilter = def.isNativeObject ? prop => prop.readonly : () => true;
    addProperties(result, def, propertiesFilter);
    if (def.isNativeObject) {
      addPropertyApi(result, def);
    }
    result.indent--;
    result.append('}');
  }

  function addConstructor(result, def) {
    result.append('');
    let str = def.isNativeObject ? `properties?: ${def.type}Properties` : '';
    result.append('constructor(' + str + ');');
  }

  function addClassDef(result, def) {
    if (def.isNativeObject) {
      result.append(`interface ${def.type} extends _${def.type}Properties {}`);
    }
    let str = 'export class ' + def.type;
    if (def.extends) {
      str += ' extends ' + def.extends;
    }
    result.append(str + ' {');
  }

  function addPropertyInterface(result, def) {
    result.append(createPropertyInterfaceDef(def));
    result.indent++;
    addProperties(result, def, prop => !prop.readonly);
    result.indent--;
    result.append('}');
    result.append(`type ${def.type}Properties = Partial<_${def.type}Properties>`);
  }

  function createPropertyInterfaceDef(def) {
    let str = 'interface _' + def.type + 'Properties';
    if (def.extends) {
      str += ' extends _' + def.extends + 'Properties';
    }
    return str + ' {';
  }

  function addMethods(result, def) {
    if (def.methods) {
      Object.keys(def.methods).sort().forEach((name) => {
        if (!Array.isArray(def.methods[name])) {
          throw new Error('method definition not an array', def.type, name);
        }
        def.methods[name].forEach((method) => {
          result.append('');
          result.append(createMethod(name, method));
        });
      });
    }
  }

  function addProperties(result, def, filter) {
    if (def.properties) {
      let propertiesFilter = filter ? name => filter(def.properties[name]) : () => true;
      Object.keys(def.properties || {}).filter(propertiesFilter).sort().forEach((name) => {
        result.append('');
        result.append(createProperty(name, def.properties[name]));
      });
    }
  }

  function addPropertyApi(result, def) {
    if (def.properties) {
      result.append('');
      result.append(createComment([
        'Gets the current value of the given *property*.',
        '@param property'
      ]));
      result.append('get(property: string): any;');
      result.append('');
      result.append(createComment([
        'Sets the given property. Supports chaining.',
        '@param property',
        '@param value'
      ]));
      result.append('set(property: string, value: any): this;');
      result.append('');
      result.append(createComment([
        'Sets all key-value pairs in the properties object as widget properties. Supports chaining.',
        '@param properties'
      ]));
      result.append(`set(properties: ${def.type}Properties): this;`);
    }
  }

  function createProperty(name, def) {
    let result = [];
    result.push(createDoc(def));
    let values = [];
    (def.values || []).sort().forEach((value) => {
      values.push(`"${value}"`);
    });
    let valuesType = (values || []).join(' | ');
    result.push(`${def.readonly ? 'readonly ' : ''}${name}: ${valuesType || def.type};`);
    return result.join('\n');
  }

  function createMethod(name, def) {
    let result = [];
    result.push(createDoc(def));
    result.push(`${name}(${createParamList(def.parameters)}): ${def.returns || 'void'};`);
    return result.join('\n');
  }

  function createParamList(parameters) {
    return parameters.map(param => `${param.name}${param.optional ? '?' : ''}: ${param.type}`).join(', ');
  }

  function createDoc(def) {
    if (!def.description && !def.static && !def.provisional) {
      return;
    }
    let result = [];
    if (def.description) {
      splitIntoLines(def.description, 100).forEach((line) => {
        result.push(line);
      });
    }
    if (def.parameters) {
      createParamAnnotations(def.parameters).forEach((line) => {
        result.push(line);
      });
    }
    if (def.deprecated) {
      let message = typeof def.deprecated === 'string' ? `'${def.deprecated}'` : '';
      result.push(`@deprecated(${message})`);
    }
    if (def.static) {
      result.push('@static');
    }
    if (def.provisional) {
      result.push('@provisional');
    }
    return createComment(result);
  }

  function createComment(comment) {
    return ['/**'].concat(comment.map(line => ' * ' + line), ' */').join('\n');
  }
  function createParamAnnotations(params) {
    return params.map(param => `@param ${param.name} ${param.description || ''}`);
  }

  function splitIntoLines(text, maxlen) {
    if (typeof text !== 'string') {
      throw new Error('not a string: ' + text);
    }
    let linesIn = text.split('\n');
    let linesOut = [];
    for (let lineIn of linesIn) {
      let lineOut = '';
      let words = lineIn.split(' ');
      for (let word of words) {
        if (lineOut.length + word.length > maxlen) {
          linesOut.push(lineOut);
          lineOut = '';
        }
        if (lineOut.length > 0) {
          lineOut += ' ';
        }
        lineOut += word;
      }
      if (lineOut.length > 0) {
        linesOut.push(lineOut);
      }
    }
    return linesOut;
  }

  class Text {

    constructor() {
      this.lines = [];
      this.indent = 0;
    }

    append() {
      Array.prototype.forEach.call(arguments, (arg) => {
        let lines = typeof arg === 'string' ? arg.split('\n') : arg;
        for (let line of lines) {
          this.lines.push(this._indentLine(line));
        }
      }, this);
    }

    toString() {
      return this.lines.join('\n');
    }

    _indentLine(line) {
      return line.length > 0 ? '  '.repeat(this.indent) + line : line;
    }

  }

};

<|endoftext|>


<commit_before>/* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */

//
// Dalliance Genome Explorer
// (c) Thomas Down 2006-2010
//
// domui.js: SVG UI components
//

"use strict";

if (typeof(require) !== 'undefined') {
    var browser = require('./cbrowser');
    var Browser = browser.Browser;

    var utils = require('./utils');
    var makeElement = utils.makeElement;
    var removeChildren = utils.removeChildren;
}

Browser.prototype.removeAllPopups = function() {
    for (var pi = 0; pi < this.popups.length; ++pi) {
        var popup = this.popups[pi];
        if (popup.onClose) {
            try {
                popup.onClose();
            } catch (ex) {
                console.log(ex);
            }
        }
        this.hPopupHolder.removeChild(popup.component);
    }
    this.popups = [];
}

Browser.prototype.makeTooltip = function(ele, text)
{
    ele.title = text;
}

Browser.prototype.popit = function(ev, name, ele, opts)
{
    var thisB = this;
    if (!opts)
        opts = {};
    if (!ev)
        ev = {};

    var width = opts.width || 200;

    var mx, my;

    if (ev.clientX) {
        var mx =  ev.clientX, my = ev.clientY;
    } else {
        mx = 500; my= 50;
    }
    mx +=  document.documentElement.scrollLeft || document.body.scrollLeft;
    my +=  document.documentElement.scrollTop || document.body.scrollTop;
    var winWidth = window.innerWidth;

    var top = my;
    var left = Math.min(mx - (width/2) - 4, (winWidth - width - 30));

    var popup = makeElement('div');
    popup.className = 'popover fade ' + (ev.clientX ? 'bottom ' : '') + 'in';
    popup.style.display = 'block';
    popup.style.position = 'absolute';
    popup.style.top = '' + top + 'px';
    popup.style.left = '' + left + 'px';
    popup.style.width = width + 'px';
    if (width > 276) {
        // HACK Bootstrappification...
        popup.style.maxWidth = width + 'px';
    }

    popup.appendChild(makeElement('div', null, {className: 'arrow'}));

    if (name) {
        var closeButton = makeElement('button', '', {className: 'close'});
        closeButton.innerHTML = '×'

        closeButton.addEventListener('mouseover', function(ev) {
            closeButton.style.color = 'red';
        }, false);
        closeButton.addEventListener('mouseout', function(ev) {
            closeButton.style.color = 'black';
        }, false);
        closeButton.addEventListener('click', function(ev) {
            ev.preventDefault(); ev.stopPropagation();
            thisB.removeAllPopups();
        }, false);
        var tbar = makeElement('h4', [makeElement('span', name, null, {maxWidth: '200px'}), closeButton], {/*className: 'popover-title' */}, {paddingLeft: '10px', paddingRight: '10px'});

        if ( !opts.disableDrag ) {
            var dragOX, dragOY;
            var moveHandler, upHandler;
            moveHandler = function(ev) {
                ev.stopPropagation(); ev.preventDefault();
                left = left + (ev.clientX - dragOX);
                if (left < 8) {
                    left = 8;
                } if (left > (winWidth - width - 32)) {
                    left = (winWidth - width - 26);
                }
                top = top + (ev.clientY - dragOY);
                top = Math.max(10, top);
                popup.style.top = '' + top + 'px';
                popup.style.left = '' + Math.min(left, (winWidth - width - 10)) + 'px';
                dragOX = ev.clientX; dragOY = ev.clientY;
            }
            upHandler = function(ev) {
                ev.stopPropagation(); ev.preventDefault();
                window.removeEventListener('mousemove', moveHandler, false);
                window.removeEventListener('mouseup', upHandler, false);
            }
            tbar.addEventListener('mousedown', function(ev) {
                ev.preventDefault(); ev.stopPropagation();
                dragOX = ev.clientX; dragOY = ev.clientY;
                window.addEventListener('mousemove', moveHandler, false);
                window.addEventListener('mouseup', upHandler, false);
            }, false);
        }

        popup.appendChild(tbar);
    }

    popup.appendChild(makeElement('div', ele, {className: 'popover-content'}, {
        padding: '0px'
    }));
    this.hPopupHolder.appendChild(popup);

    this.popups.push({
        component: popup,
        onClose: opts.onClose
    });
}

function makeTreeTableSection(title, content, visible) {

    var ttButton = makeElement('i');
    function update() {
        if (visible) {
            ttButton.className = 'fa fa-caret-down';
            content.style.display = 'table';
        } else {
            ttButton.className = 'fa fa-caret-right';
            content.style.display = 'none';
        }
    }
    update();

    var showHide = function(ev) {
        ev.preventDefault(); ev.stopPropagation();
        visible = !visible;
        update();
    };

    ttButton.addEventListener('click', showHide, false);

    var heading = makeElement('h6', [ttButton, ' ', title], {}, {display: 'block', background: 'gray', color: 'white', width: '100%', padding: '5px 2px', margin: '0px'});
    heading.addEventListener('click', showHide, false);

    return makeElement('div', [heading, content], {});
}

if (typeof(module) !== 'undefined') {
    module.exports = {
        makeTreeTableSection: makeTreeTableSection
    };
}
<commit_msg>Set the cursor of hub group headings to be a hand<commit_after>/* -*- mode: javascript; c-basic-offset: 4; indent-tabs-mode: nil -*- */

//
// Dalliance Genome Explorer
// (c) Thomas Down 2006-2010
//
// domui.js: SVG UI components
//

"use strict";

if (typeof(require) !== 'undefined') {
    var browser = require('./cbrowser');
    var Browser = browser.Browser;

    var utils = require('./utils');
    var makeElement = utils.makeElement;
    var removeChildren = utils.removeChildren;
}

Browser.prototype.removeAllPopups = function() {
    for (var pi = 0; pi < this.popups.length; ++pi) {
        var popup = this.popups[pi];
        if (popup.onClose) {
            try {
                popup.onClose();
            } catch (ex) {
                console.log(ex);
            }
        }
        this.hPopupHolder.removeChild(popup.component);
    }
    this.popups = [];
}

Browser.prototype.makeTooltip = function(ele, text)
{
    ele.title = text;
}

Browser.prototype.popit = function(ev, name, ele, opts)
{
    var thisB = this;
    if (!opts)
        opts = {};
    if (!ev)
        ev = {};

    var width = opts.width || 200;

    var mx, my;

    if (ev.clientX) {
        var mx =  ev.clientX, my = ev.clientY;
    } else {
        mx = 500; my= 50;
    }
    mx +=  document.documentElement.scrollLeft || document.body.scrollLeft;
    my +=  document.documentElement.scrollTop || document.body.scrollTop;
    var winWidth = window.innerWidth;

    var top = my;
    var left = Math.min(mx - (width/2) - 4, (winWidth - width - 30));

    var popup = makeElement('div');
    popup.className = 'popover fade ' + (ev.clientX ? 'bottom ' : '') + 'in';
    popup.style.display = 'block';
    popup.style.position = 'absolute';
    popup.style.top = '' + top + 'px';
    popup.style.left = '' + left + 'px';
    popup.style.width = width + 'px';
    if (width > 276) {
        // HACK Bootstrappification...
        popup.style.maxWidth = width + 'px';
    }

    popup.appendChild(makeElement('div', null, {className: 'arrow'}));

    if (name) {
        var closeButton = makeElement('button', '', {className: 'close'});
        closeButton.innerHTML = '×'

        closeButton.addEventListener('mouseover', function(ev) {
            closeButton.style.color = 'red';
        }, false);
        closeButton.addEventListener('mouseout', function(ev) {
            closeButton.style.color = 'black';
        }, false);
        closeButton.addEventListener('click', function(ev) {
            ev.preventDefault(); ev.stopPropagation();
            thisB.removeAllPopups();
        }, false);
        var tbar = makeElement('h4', [makeElement('span', name, null, {maxWidth: '200px'}), closeButton], {/*className: 'popover-title' */}, {paddingLeft: '10px', paddingRight: '10px'});

        if ( !opts.disableDrag ) {
            var dragOX, dragOY;
            var moveHandler, upHandler;
            moveHandler = function(ev) {
                ev.stopPropagation(); ev.preventDefault();
                left = left + (ev.clientX - dragOX);
                if (left < 8) {
                    left = 8;
                } if (left > (winWidth - width - 32)) {
                    left = (winWidth - width - 26);
                }
                top = top + (ev.clientY - dragOY);
                top = Math.max(10, top);
                popup.style.top = '' + top + 'px';
                popup.style.left = '' + Math.min(left, (winWidth - width - 10)) + 'px';
                dragOX = ev.clientX; dragOY = ev.clientY;
            }
            upHandler = function(ev) {
                ev.stopPropagation(); ev.preventDefault();
                window.removeEventListener('mousemove', moveHandler, false);
                window.removeEventListener('mouseup', upHandler, false);
            }
            tbar.addEventListener('mousedown', function(ev) {
                ev.preventDefault(); ev.stopPropagation();
                dragOX = ev.clientX; dragOY = ev.clientY;
                window.addEventListener('mousemove', moveHandler, false);
                window.addEventListener('mouseup', upHandler, false);
            }, false);
        }

        popup.appendChild(tbar);
    }

    popup.appendChild(makeElement('div', ele, {className: 'popover-content'}, {
        padding: '0px'
    }));
    this.hPopupHolder.appendChild(popup);

    this.popups.push({
        component: popup,
        onClose: opts.onClose
    });
}

function makeTreeTableSection(title, content, visible) {

    var ttButton = makeElement('i');
    function update() {
        if (visible) {
            ttButton.className = 'fa fa-caret-down';
            content.style.display = 'table';
        } else {
            ttButton.className = 'fa fa-caret-right';
            content.style.display = 'none';
        }
    }
    update();

    var showHide = function(ev) {
        ev.preventDefault(); ev.stopPropagation();
        visible = !visible;
        update();
    };

    ttButton.addEventListener('click', showHide, false);

    var heading = makeElement('h6', [ttButton, ' ', title], {}, {display: 'block', background: 'gray', color: 'white', width: '100%', padding: '5px 2px', margin: '0px', cursor: 'pointer'});
    heading.addEventListener('click', showHide, false);

    return makeElement('div', [heading, content], {});
}

if (typeof(module) !== 'undefined') {
    module.exports = {
        makeTreeTableSection: makeTreeTableSection
    };
}
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var util = require('util');
var async = require('async');
var events = require('events');

var Location = require('./Location');

/**
 * A delivery quote.
 *
 * @param quote_id string The ID of the quote.
 * @param estimated_at integer Unix timestamp of the time this quote was generated.
 * @param start_time integer Unix timestamp of the start of the delivery window.
 * @param end_time integer Unix timestamp of the end of the delivery window.
 * @param fee float The fee of the delivery.
 * @param currency_code string The currency code of the delivery fee. The currency code follows the ISO 4217 standard.
 * @param pickup_eta integer The eta to pickup for this quote in minutes. Only applies to ondemand deliveries.
 * @param dropoff_eta integer The eta to dropoff for this quote in minutes. Only applies to ondemand deliveries.
 *
 */
function Quote(options) {
    var self = this;
    events.EventEmitter.call(self);

    this.quote_id = options.quote_id;
    this.start_time = new Date(parseInt(options.start_time,10)*1000);
    this.end_time = new Date(parseInt(options.start_time,10)*1000);
    this.fee = parseFloat(options.fee);
    this.currency_code = options.currency_code;

    if (options.pickup_eta) this.pickup_eta = parseInt(options.pickup_eta, 10);
    if (options.dropoff_eta) this.dropoff_eta = parseInt(options.dropoff_eta, 10);

    this.pickup_date = this.pickup_eta ? new Date(Date.now() + this.pickup_eta*60*1000) : null;
    this.dropoff_date = this.dropoff_eta ? new Date(Date.now() + this.dropoff_eta*60*1000) : null;
}
util.inherits(Quote, events.EventEmitter);

module.exports = Quote;
<commit_msg>Update Quote.js (#15)<commit_after>'use strict';

var _ = require('lodash');
var util = require('util');
var async = require('async');
var events = require('events');

var Location = require('./Location');

/**
 * A delivery quote.
 *
 * @param quote_id string The ID of the quote.
 * @param estimated_at integer Unix timestamp of the time this quote was generated.
 * @param start_time integer Unix timestamp of the start of the delivery window.
 * @param end_time integer Unix timestamp of the end of the delivery window.
 * @param fee float The fee of the delivery.
 * @param currency_code string The currency code of the delivery fee. The currency code follows the ISO 4217 standard.
 * @param pickup_eta integer The eta to pickup for this quote in minutes. Only applies to ondemand deliveries.
 * @param dropoff_eta integer The eta to dropoff for this quote in minutes. Only applies to ondemand deliveries.
 *
 */
function Quote(options) {
    var self = this;
    events.EventEmitter.call(self);

    this.quote_id = options.quote_id;
    this.start_time = new Date(parseInt(options.start_time,10)*1000);
    this.end_time = new Date(parseInt(options.end_time,10)*1000);
    this.fee = parseFloat(options.fee);
    this.currency_code = options.currency_code;

    if (options.pickup_eta) this.pickup_eta = parseInt(options.pickup_eta, 10);
    if (options.dropoff_eta) this.dropoff_eta = parseInt(options.dropoff_eta, 10);

    this.pickup_date = this.pickup_eta ? new Date(Date.now() + this.pickup_eta*60*1000) : null;
    this.dropoff_date = this.dropoff_eta ? new Date(Date.now() + this.dropoff_eta*60*1000) : null;
}
util.inherits(Quote, events.EventEmitter);

module.exports = Quote;
<|endoftext|>


<commit_before>var http = require('http');

exports.createManifest = function(projectId, callbackFunction)
{
	// Create a HTTP GET request with the ProjectID as a parameter
	var requestOpts = {
		host: "projects.scratch.mit.edu",
		path: "/internalapi/project/" + projectId + "/get/"
	};

	// Create a function that parses the responses from the HTTP request
	var responseCallback = function (response) {
		var str = "";

		// If there's data, add that chunk to the current store
		response.on('data', function (chunk) {
			str += chunk;
		});

		// If there's no more data, we can generate the manifest.
		response.on('end', function() {
			generateManifest(str, callbackFunction);
		});

		// If there's an error, call the callback function with an error parameter
		response.on('error', callbackFunction);
	}

	// Create and send the request
	http.request(requestOpts, responseCallback).end();
}

generateManifest = function(manifestData, callbackFunction)
{
	// Parse manifestData into JSON
	try
	{
		manifestData = JSON.parse(manifestData);
	} catch (err) {
		callbackFunction("Not a valid scratch file.");
	}

	var manifest;

	// Create a list for manifest files to see if they're already existing in the manifest
	// Therefore we don't include duplicate files in the manifest.
	var manifestFiles = [];

	// Create the manifest with an initial, constant, set of data
	manifest = "CACHE MANIFEST\n# Version 1\n\n# Automatically Generated From the Scratch API\n\nCACHE";

	// Add the project's root files to the manifest list
	manifest += getFileList(manifestData, manifestFiles);

	// Now add the each project's child to the manifest list
	for(var childIndex in manifestData.children)
	{
		manifest += getFileList(manifestData.children[childIndex], manifestFiles);
	}

	// Execute the callback function with the manifest data.
	callbackFunction(manifest);
}

// Creates a file list based off the manifestData supplied. Looks for costumes and sounds.
getFileList = function(manifestData, manifestFiles)
{
	var manifest = "";

	// If the pen layer exists, and the file isn't in the manifest add that.
	if(manifestData.penLayerMD5 && manifestFiles.indexOf(manifestData.penLayerMD5) === -1)
	{
		manifest += "\nasset/" + manifestData.penLayerMD5;

		manifestFiles.push(manifestData.penLayerMD5);
	}

	for(var soundIndex in manifestData.sounds)
	{
		// Current sound being worked on
		var sound = manifestData.sounds[soundIndex];

		// Check to see if file exists. If it doesn't, add it. Otherwise, continue.
		if(manifestFiles.indexOf(sound.md5) === -1)
		{
			manifest += "\nasset/" + sound.md5;

			manifestFiles.push(sound.md5);
		}
	}

	// And the costumes
	for(var costumeIndex in manifestData.costumes)
	{
		// Current costume being worked on
		var costume = manifestData.costumes[costumeIndex];

		// Check to see if file exists. If it doesn't, add it. Otherwise, continue.
		if(manifestFiles.indexOf(costume.baseLayerMD5) === -1)
		{
			manifest += "\nasset/" + costume.baseLayerMD5;

			manifestFiles.push(costume.baseLayerMD5);
		}
	}

	return manifest;
}<commit_msg>Changed the path for assets so that it works.<commit_after>var http = require('http');

exports.createManifest = function(projectId, callbackFunction)
{
	// Create a HTTP GET request with the ProjectID as a parameter
	var requestOpts = {
		host: "projects.scratch.mit.edu",
		path: "/internalapi/project/" + projectId + "/get/"
	};

	// Create a function that parses the responses from the HTTP request
	var responseCallback = function (response) {
		var str = "";

		// If there's data, add that chunk to the current store
		response.on('data', function (chunk) {
			str += chunk;
		});

		// If there's no more data, we can generate the manifest.
		response.on('end', function() {
			generateManifest(str, callbackFunction);
		});

		// If there's an error, call the callback function with an error parameter
		response.on('error', callbackFunction);
	}

	// Create and send the request
	http.request(requestOpts, responseCallback).end();
}

generateManifest = function(manifestData, callbackFunction)
{
	// Parse manifestData into JSON
	try
	{
		manifestData = JSON.parse(manifestData);
	} catch (err) {
		callbackFunction("Not a valid scratch file.");
	}

	var manifest;

	// Create a list for manifest files to see if they're already existing in the manifest
	// Therefore we don't include duplicate files in the manifest.
	var manifestFiles = [];

	// Create the manifest with an initial, constant, set of data
	manifest = "CACHE MANIFEST\n# Version 1\n\n# Automatically Generated From the Scratch API\n\nCACHE";

	// Add the project's root files to the manifest list
	manifest += getFileList(manifestData, manifestFiles);

	// Now add the each project's child to the manifest list
	for(var childIndex in manifestData.children)
	{
		manifest += getFileList(manifestData.children[childIndex], manifestFiles);
	}

	// Execute the callback function with the manifest data.
	callbackFunction(manifest);
}

// Creates a file list based off the manifestData supplied. Looks for costumes and sounds.
getFileList = function(manifestData, manifestFiles)
{
	var manifest = "";

	// If the pen layer exists, and the file isn't in the manifest add that.
	if(manifestData.penLayerMD5 && manifestFiles.indexOf(manifestData.penLayerMD5) === -1)
	{
		manifest += "\nasset/" + manifestData.penLayerMD5 + "/get/";

		manifestFiles.push(manifestData.penLayerMD5);
	}

	for(var soundIndex in manifestData.sounds)
	{
		// Current sound being worked on
		var sound = manifestData.sounds[soundIndex];

		// Check to see if file exists. If it doesn't, add it. Otherwise, continue.
		if(manifestFiles.indexOf(sound.md5) === -1)
		{
			manifest += "\nasset/" + sound.md5 + "/get/";

			manifestFiles.push(sound.md5);
		}
	}

	// And the costumes
	for(var costumeIndex in manifestData.costumes)
	{
		// Current costume being worked on
		var costume = manifestData.costumes[costumeIndex];

		// Check to see if file exists. If it doesn't, add it. Otherwise, continue.
		if(manifestFiles.indexOf(costume.baseLayerMD5) === -1)
		{
			manifest += "\nasset/" + costume.baseLayerMD5 + "/get/";

			manifestFiles.push(costume.baseLayerMD5);
		}
	}

	return manifest;
}<|endoftext|>


<commit_before>/**
 *
 *
 * @author fuyg
 * @date  2014-12-16
 */
define(function (require) {
    var TRIM = require('../core/str/trim'),
        STARTS_WITH = require('../core/str/startsWith'),
        _ = require('../core/underscore'),
        /**
         * @param {String} line
         * @return {Integer} level >= 1
         *
         */
        countListLevel = function (line) {
            // \s 空格
            // \t 制表符
            // \xA0 non-breaking spaces
            // \u3000中文空格
            var matched = /^[\s\t\xA0\u3000]+/.exec(line),
                index,
                len,
                counter = 0,
                oneChar;

            if (!matched) {
                return 1;
            }

            matched = matched[0];
            len = matched.length;
            for (index = 0; index < len; index++) {
                oneChar = matched.charAt(index);
                if (oneChar === '\t') {
                    counter += 4;
                } else {
                    counter += 1;
                }
            }

            counter = Math.ceil(counter / 4) + 1;

            return counter < 1 ? 1 : counter;
        },
        /**
         * @param {String} content
         * @param {Array<Object>} parts
         * @return {Array<Object>}
         */
        concatUrl= function (content, parts) {
            var arrContent = [],
                start = 0,
                endText;

            _.each(parts, function (part) {
                var text = content.substring(start, part.index),
                    link = '' +
                        _.escape(part.text) +  '';
                if (text && text.length) {
                    arrContent.push({
                        content: text,
                        plain: true
                    });
                }

                arrContent.push({
                    content: link,
                    plain: false
                });

                start = part.index + part.size;
            });

            endText = content.substring(start);

            if (endText && endText.length) {
                arrContent.push({
                    content: endText,
                    plain: true
                });
            }

            if (arrContent && arrContent.length) {
                return arrContent;
            }

            return [{
                content: content,
                plain: true
            }];

        },
        /**
         * @param {String} text
         * @return {Array}
         */
        parseUrl = function (text) {
            text = text + '';
            /*jshint maxlen: 100*/
            var urlReg = /(https?:\/\/|www\.|ssh:\/\/|ftp:\/\/)[a-z0-9&_+\-\?\/\.=\#,:@]+/ig,
                matched,
                arrMatched,
                url;

            arrMatched = [];

            matched = urlReg.exec(text);
            while (matched) {
                url = matched[0];
                arrMatched.push({
                    index: matched.index,
                    size: url.length,
                    text: url,
                    full: STARTS_WITH(url.toLowerCase(), 'www.') ?
                        ('http://' + url) : url
                });
                matched = urlReg.exec(text);
            }

            if (arrMatched && arrMatched.length) {
                return concatUrl(text, arrMatched);
            }

            return [{
                content: text,
                plain: true
            }];
        },
        parseMail = function (text) {
            text = text + '';
            /*jshint maxlen: 100*/
            var mailReg = /[a-z0-9_+\-\.]+@[a-z0-9_+\-\.]+/ig,
                matched,
                arrMatched,
                address;

            arrMatched = [];

            matched = mailReg.exec(text);
            while (matched) {
                address = matched[0];
                arrMatched.push({
                    index: matched.index,
                    size: address.length,
                    text: address,
                    full: 'mailto:' + address

                });
                matched = mailReg.exec(text);
            }

            if (arrMatched && arrMatched.length) {
                return concatUrl(text, arrMatched);
            }

            return [{
                content: text,
                plain: true
            }];
        },
        /**
         * @param {Array<Object>} arrContent
         * @param {Function} partParser
         * @return {Array<Object>}
         */
        parseInline = function (arrContent, partParser) {
            arrContent = _.flatten(arrContent);

            var newArrContent = [];

            _.each(arrContent, function (contentObj) {
                if (!contentObj || !contentObj.content) {
                    return;
                }
                if (contentObj.plain) {
                    newArrContent.push(partParser(contentObj.content));
                } else {
                    newArrContent.push(contentObj);
                }
            });

            newArrContent = _.flatten(newArrContent);

            return newArrContent;
        };

    return {
        /**
         * @param {String} line
         * @return {Array<Object>} {content: 'string', plain: 'boolean'}
         */
        blankLine: function (line) {
            var trimmed = TRIM(line);

            if (!trimmed) {
                return [{
                    content: '
',
                    plain: false
                }];
            }
        },
        horizotalLine: function (line) {
            var reg = /^\s*-{3,}\s*$/;

            if (reg.test(line)) {
                return [{
                    content: '
',
                    plain: false
                }];
            }
        },
        inline: function (line) {
            line = line + '';

            var arrContent = [{
                    content: line,
                    plain: true
                }];

            arrContent = parseInline(arrContent, parseUrl);
            arrContent = parseInline(arrContent, parseMail);

            return arrContent;
        },
        /**
         * @param {String} line
         * @param {Boolean} [_orderList = true]
         * @return {Array<Object>} {content: 'string', plain: 'boolean'}
         */
        orderList: function (line, _orderList) {

            _orderList = _orderList !== false;

            var that = this,
                trimmed = TRIM(line),
                signReg = _orderList? /\d+\.?\s+/ : /[-*]\s+/,
                matched = signReg.exec(trimmed),
                matchedText,
                arrContent,
                level,
                textContent,
                parsed;

            if (!matched) {
                return;
            }

            level = countListLevel(line);

            arrContent = [{
                content: '
',
                plain: false,
                level: level,
                orderList: _orderList
            }];

            matchedText = matched[0];
            textContent = trimmed.substring(matchedText.length);

            parsed = that.inline(textContent);

            if (parsed) {
                arrContent.push(parsed);
            } else {
                arrContent.push({
                    content: textContent,
                    plain: true
                });
            }

            arrContent.push({
                content: '
',
                plain: false
            });

            return _.flatten(arrContent);
        },
        unorderList: function (line) {
            var that = this;
            return that.orderList(line, false);
        }

    };
});
<commit_msg>        modified:   src/htmlize/parse.js - remove unwanted jshint<commit_after>/**
 *
 *
 * @author fuyg
 * @date  2014-12-16
 */
define(function (require) {
    var TRIM = require('../core/str/trim'),
        STARTS_WITH = require('../core/str/startsWith'),
        _ = require('../core/underscore'),
        /**
         * @param {String} line
         * @return {Integer} level >= 1
         *
         */
        countListLevel = function (line) {
            // \s 空格
            // \t 制表符
            // \xA0 non-breaking spaces
            // \u3000中文空格
            var matched = /^[\s\t\xA0\u3000]+/.exec(line),
                index,
                len,
                counter = 0,
                oneChar;

            if (!matched) {
                return 1;
            }

            matched = matched[0];
            len = matched.length;
            for (index = 0; index < len; index++) {
                oneChar = matched.charAt(index);
                if (oneChar === '\t') {
                    counter += 4;
                } else {
                    counter += 1;
                }
            }

            counter = Math.ceil(counter / 4) + 1;

            return counter < 1 ? 1 : counter;
        },
        /**
         * @param {String} content
         * @param {Array<Object>} parts
         * @return {Array<Object>}
         */
        concatUrl= function (content, parts) {
            var arrContent = [],
                start = 0,
                endText;

            _.each(parts, function (part) {
                var text = content.substring(start, part.index),
                    link = '' +
                        _.escape(part.text) +  '';
                if (text && text.length) {
                    arrContent.push({
                        content: text,
                        plain: true
                    });
                }

                arrContent.push({
                    content: link,
                    plain: false
                });

                start = part.index + part.size;
            });

            endText = content.substring(start);

            if (endText && endText.length) {
                arrContent.push({
                    content: endText,
                    plain: true
                });
            }

            if (arrContent && arrContent.length) {
                return arrContent;
            }

            return [{
                content: content,
                plain: true
            }];

        },
        /**
         * @param {String} text
         * @return {Array}
         */
        parseUrl = function (text) {
            text = text + '';
            /*jshint maxlen: 100*/
            var urlReg = /(https?:\/\/|www\.|ssh:\/\/|ftp:\/\/)[a-z0-9&_+\-\?\/\.=\#,:@]+/ig,
                matched,
                arrMatched,
                url;

            arrMatched = [];

            matched = urlReg.exec(text);
            while (matched) {
                url = matched[0];
                arrMatched.push({
                    index: matched.index,
                    size: url.length,
                    text: url,
                    full: STARTS_WITH(url.toLowerCase(), 'www.') ?
                        ('http://' + url) : url
                });
                matched = urlReg.exec(text);
            }

            if (arrMatched && arrMatched.length) {
                return concatUrl(text, arrMatched);
            }

            return [{
                content: text,
                plain: true
            }];
        },
        parseMail = function (text) {
            text = text + '';
            var mailReg = /[a-z0-9_+\-\.]+@[a-z0-9_+\-\.]+/ig,
                matched,
                arrMatched,
                address;

            arrMatched = [];

            matched = mailReg.exec(text);
            while (matched) {
                address = matched[0];
                arrMatched.push({
                    index: matched.index,
                    size: address.length,
                    text: address,
                    full: 'mailto:' + address

                });
                matched = mailReg.exec(text);
            }

            if (arrMatched && arrMatched.length) {
                return concatUrl(text, arrMatched);
            }

            return [{
                content: text,
                plain: true
            }];
        },
        /**
         * @param {Array<Object>} arrContent
         * @param {Function} partParser
         * @return {Array<Object>}
         */
        parseInline = function (arrContent, partParser) {
            arrContent = _.flatten(arrContent);

            var newArrContent = [];

            _.each(arrContent, function (contentObj) {
                if (!contentObj || !contentObj.content) {
                    return;
                }
                if (contentObj.plain) {
                    newArrContent.push(partParser(contentObj.content));
                } else {
                    newArrContent.push(contentObj);
                }
            });

            newArrContent = _.flatten(newArrContent);

            return newArrContent;
        };

    return {
        /**
         * @param {String} line
         * @return {Array<Object>} {content: 'string', plain: 'boolean'}
         */
        blankLine: function (line) {
            var trimmed = TRIM(line);

            if (!trimmed) {
                return [{
                    content: '
',
                    plain: false
                }];
            }
        },
        horizotalLine: function (line) {
            var reg = /^\s*-{3,}\s*$/;

            if (reg.test(line)) {
                return [{
                    content: '
',
                    plain: false
                }];
            }
        },
        inline: function (line) {
            line = line + '';

            var arrContent = [{
                    content: line,
                    plain: true
                }];

            arrContent = parseInline(arrContent, parseUrl);
            arrContent = parseInline(arrContent, parseMail);

            return arrContent;
        },
        /**
         * @param {String} line
         * @param {Boolean} [_orderList = true]
         * @return {Array<Object>} {content: 'string', plain: 'boolean'}
         */
        orderList: function (line, _orderList) {

            _orderList = _orderList !== false;

            var that = this,
                trimmed = TRIM(line),
                signReg = _orderList? /\d+\.?\s+/ : /[-*]\s+/,
                matched = signReg.exec(trimmed),
                matchedText,
                arrContent,
                level,
                textContent,
                parsed;

            if (!matched) {
                return;
            }

            level = countListLevel(line);

            arrContent = [{
                content: '
',
                plain: false,
                level: level,
                orderList: _orderList
            }];

            matchedText = matched[0];
            textContent = trimmed.substring(matchedText.length);

            parsed = that.inline(textContent);

            if (parsed) {
                arrContent.push(parsed);
            } else {
                arrContent.push({
                    content: textContent,
                    plain: true
                });
            }

            arrContent.push({
                content: '
',
                plain: false
            });

            return _.flatten(arrContent);
        },
        unorderList: function (line) {
            var that = this;
            return that.orderList(line, false);
        }

    };
});
<|endoftext|>