<commit_before>/* global moment, google */
(function (doc, win, $) {

  var
    eventTags = ['wizard'],
    autocomplete,
    event = {},
    environment = 'dev',
    eventsAPI = {
      dev: 'http://localhost:1989/events',
      staging: 'https://events-api.mofostaging.net/events',
      production: 'https://events-api.webmaker.org/events'
    },
    formFields = {},
    eventsFrontEnd = {
      dev: 'http://localhost:1981/events/',
      staging: 'https://events.mofostaging.net/events/',
      production: 'https://events.webmaker.org/events/'
    };

  switch (win.location.host) {
  case 'welcome.webmaker.org':
    environment = 'production';
    break;
  case 'welcome.mofostaging.net':
    environment = 'staging';
    break;
  default:
    environment = 'dev';
  }

  $('[data-href]').on('click', function () {
    window.location.hash = $(this).attr('data-href');
  });

  function findaPlace() {
    autocomplete = new win.google.maps.places.Autocomplete((doc.getElementById('address')), {
      types: ['geocode']
    });
    google.maps.event.addListener(autocomplete, 'place_changed', function () {
      updateEventAddress();
    });
  }

  function updateEventAddress() {

    var place = autocomplete.getPlace();

    event.address = place.formatted_address;
    event.latitude = place.geometry.location.B;
    event.longitude = place.geometry.location.k;
  }

  function submitForm(event) {
    event.preventDefault();

    var
      $estimatedAttendees = $('select[name="estimatedAttendees"]'),
      $address = $('#address'),
      $context = $(this);

    $('#submit-event').prop('disabled', true);

    $('input[name="beginDate"]').val(moment($('#datepicker').val(), 'MM/DD/YYYY h:mm A'));

    if ($address.val() === '') {
      handleErrors();
      return false;
    }

    if ($estimatedAttendees.find('option:selected').val() === '0') {
      handleErrors();
      return false;
    }

    $context.append('<input type="hidden" name="organizer" value="' + win.webmaker.person.email + '" />');
    $context.append('<input type="hidden" name="organizerID" value="' + win.webmaker.person.username + '" />');

    function compileInputs() {
      formFields[$(this).prop('name')] = $(this).val();
    }

    $('input[type="text"]').each(compileInputs);
    $('input[type="hidden"]').each(compileInputs);
    $('input[type="number"]').each(compileInputs);

    formFields.isEventPublic = false;
    formFields.estimatedAttendees = $estimatedAttendees.find('option:selected').val();
    formFields.tags = eventTags;

    deployPayload(JSON.stringify(formFields));
  }

  function handleErrors() {
    var
      $estimatedAttendees = $('select[name="estimatedAttendees"]'),
      $address = $('#address');

    if ($address.val() === '') {
      $address.addClass('error');
    }

    if ($estimatedAttendees.find('option:selected').val() === '0') {
      $estimatedAttendees.addClass('error');
    }
    $('#submit-event').prop('disabled', false);
  }

  function updateStep3(eventID) {
    var eventURL = eventsFrontEnd[environment] + eventID;

    $('#event-url').prop('href', eventURL).text(eventURL);

    $('#share-twitter').attr('href', 'https://twitter.com/intent/tweet?text=Check%20out%20this%20event!&url=' + encodeURIComponent(eventURL) + '&via=webmaker&related=mozilla,webmaker');
    $('#share-facebook').attr('href', 'https://www.facebook.com/sharer.php?u=' + encodeURIComponent(eventURL));

    $('#confirmed-event-location').text(formFields.address);
    $('#confirmed-event-date').text(moment(formFields.beginDate).format('LLL'));
    $('#confirmed-event-size').text($('#estimatedAttendees').find('option:selected').text());
  }

  function deployPayload(payload) {
    $.ajax(eventsAPI[environment], {
      data: payload,
      contentType: 'application/json',
      error: function () {
        $('#start-event-submission').prepend(
          '
Something went wrong with the form submission. Please wait a moment and try again.
'
        );
        $('#submit-event').prop('disabled', false);
      },
      type: 'POST',
      xhrFields: {
        withCredentials: true
      },
      success: function (data) {
        $('#step-2').fadeOut('slow').next().delay(500).fadeIn('slow');
        updateStep3(data.id);
      }
    });
  }

  function showStep2(target, isDeepLink) {
    var
      $fieldset = $('fieldset.hidden.' + target),
      eventName = $fieldset.find('.event')[0].innerHTML,
      eventIcon = $fieldset.find('.icon')[0].innerHTML,
      eventDescription = $fieldset.find('.description')[0].innerHTML;

    eventTags.push(target);

    if (isDeepLink) {
      $('#step-1').hide().next().show();
    } else {
      $('#step-1').fadeOut('slow').next().delay(500).fadeIn('slow');
    }

    $('#submit-event').prop('disabled', false);
    $fieldset.appendTo('#start-event-submission');
    $('.event-title').text(eventName);
    $('.event-description').text(eventDescription);
    $('.event-icon').addClass(eventIcon);
  }

  function setUpWizard() {
    $('#datepicker').datetimepicker({
      icons: {
        time: "fa fa-clock-o",
        date: "fa fa-calendar",
        up: "fa fa-arrow-up",
        down: "fa fa-arrow-down"
      },
      minuteStepping: 15,
      defaultDate: moment().add(1, 'months').minutes(60)
    });

    $('a[href="/auth/login"]').on('click', function (e) {
      e.preventDefault();
      win.webmaker.auth.login();
    });

    $('.eventBtn').on('click', function () {
      showStep2(this.id);
    });

    $('#submit-event').on('click', submitForm);
  }

  function init() {
    if ($('.start-page').length > 0) {
      setUpWizard();
      findaPlace();
      $('#submit.event').prop('disabled', false);
      win.webmaker.auth.on('login', function () {
        $('#sign-in-form').hide();
        $('#start-event-submission').removeClass('hidden');
      });
    }

    function setPageFromHash() {
      var hash = window.location.hash;

      // If there's a deep link jump to step 2, otherwise show step 1
      if (hash && hash !== '#/') {
        showStep2(hash.split('#/')[1], true);
      } else {
        $('#step-1').show();
        $('#step-2').hide();
      }
    }

    $(window).on('hashchange', function () {
      if (window.location.hash !== '') {
        setPageFromHash();
      }
    });

    setPageFromHash();
  }

  init();
})(document, window, jQuery);
<commit_msg>Bug 1097042 - Listen for webmaker-login-ux 'verified' events<commit_after>/* global moment, google */
(function (doc, win, $) {

  var
    eventTags = ['wizard'],
    autocomplete,
    event = {},
    environment = 'dev',
    eventsAPI = {
      dev: 'http://localhost:1989/events',
      staging: 'https://events-api.mofostaging.net/events',
      production: 'https://events-api.webmaker.org/events'
    },
    formFields = {},
    eventsFrontEnd = {
      dev: 'http://localhost:1981/events/',
      staging: 'https://events.mofostaging.net/events/',
      production: 'https://events.webmaker.org/events/'
    };

  switch (win.location.host) {
  case 'welcome.webmaker.org':
    environment = 'production';
    break;
  case 'welcome.mofostaging.net':
    environment = 'staging';
    break;
  default:
    environment = 'dev';
  }

  $('[data-href]').on('click', function () {
    window.location.hash = $(this).attr('data-href');
  });

  function findaPlace() {
    autocomplete = new win.google.maps.places.Autocomplete((doc.getElementById('address')), {
      types: ['geocode']
    });
    google.maps.event.addListener(autocomplete, 'place_changed', function () {
      updateEventAddress();
    });
  }

  function updateEventAddress() {

    var place = autocomplete.getPlace();

    event.address = place.formatted_address;
    event.latitude = place.geometry.location.B;
    event.longitude = place.geometry.location.k;
  }

  function submitForm(event) {
    event.preventDefault();

    var
      $estimatedAttendees = $('select[name="estimatedAttendees"]'),
      $address = $('#address'),
      $context = $(this);

    $('#submit-event').prop('disabled', true);

    $('input[name="beginDate"]').val(moment($('#datepicker').val(), 'MM/DD/YYYY h:mm A'));

    if ($address.val() === '') {
      handleErrors();
      return false;
    }

    if ($estimatedAttendees.find('option:selected').val() === '0') {
      handleErrors();
      return false;
    }

    $context.append('<input type="hidden" name="organizer" value="' + win.webmaker.person.email + '" />');
    $context.append('<input type="hidden" name="organizerID" value="' + win.webmaker.person.username + '" />');

    function compileInputs() {
      formFields[$(this).prop('name')] = $(this).val();
    }

    $('input[type="text"]').each(compileInputs);
    $('input[type="hidden"]').each(compileInputs);
    $('input[type="number"]').each(compileInputs);

    formFields.isEventPublic = false;
    formFields.estimatedAttendees = $estimatedAttendees.find('option:selected').val();
    formFields.tags = eventTags;

    deployPayload(JSON.stringify(formFields));
  }

  function handleErrors() {
    var
      $estimatedAttendees = $('select[name="estimatedAttendees"]'),
      $address = $('#address');

    if ($address.val() === '') {
      $address.addClass('error');
    }

    if ($estimatedAttendees.find('option:selected').val() === '0') {
      $estimatedAttendees.addClass('error');
    }
    $('#submit-event').prop('disabled', false);
  }

  function updateStep3(eventID) {
    var eventURL = eventsFrontEnd[environment] + eventID;

    $('#event-url').prop('href', eventURL).text(eventURL);

    $('#share-twitter').attr('href', 'https://twitter.com/intent/tweet?text=Check%20out%20this%20event!&url=' + encodeURIComponent(eventURL) + '&via=webmaker&related=mozilla,webmaker');
    $('#share-facebook').attr('href', 'https://www.facebook.com/sharer.php?u=' + encodeURIComponent(eventURL));

    $('#confirmed-event-location').text(formFields.address);
    $('#confirmed-event-date').text(moment(formFields.beginDate).format('LLL'));
    $('#confirmed-event-size').text($('#estimatedAttendees').find('option:selected').text());
  }

  function deployPayload(payload) {
    $.ajax(eventsAPI[environment], {
      data: payload,
      contentType: 'application/json',
      error: function () {
        $('#start-event-submission').prepend(
          '
Something went wrong with the form submission. Please wait a moment and try again.
'
        );
        $('#submit-event').prop('disabled', false);
      },
      type: 'POST',
      xhrFields: {
        withCredentials: true
      },
      success: function (data) {
        $('#step-2').fadeOut('slow').next().delay(500).fadeIn('slow');
        updateStep3(data.id);
      }
    });
  }

  function showStep2(target, isDeepLink) {
    var
      $fieldset = $('fieldset.hidden.' + target),
      eventName = $fieldset.find('.event')[0].innerHTML,
      eventIcon = $fieldset.find('.icon')[0].innerHTML,
      eventDescription = $fieldset.find('.description')[0].innerHTML;

    eventTags.push(target);

    if (isDeepLink) {
      $('#step-1').hide().next().show();
    } else {
      $('#step-1').fadeOut('slow').next().delay(500).fadeIn('slow');
    }

    $('#submit-event').prop('disabled', false);
    $fieldset.appendTo('#start-event-submission');
    $('.event-title').text(eventName);
    $('.event-description').text(eventDescription);
    $('.event-icon').addClass(eventIcon);
  }

  function setUpWizard() {
    $('#datepicker').datetimepicker({
      icons: {
        time: "fa fa-clock-o",
        date: "fa fa-calendar",
        up: "fa fa-arrow-up",
        down: "fa fa-arrow-down"
      },
      minuteStepping: 15,
      defaultDate: moment().add(1, 'months').minutes(60)
    });

    $('a[href="/auth/login"]').on('click', function (e) {
      e.preventDefault();
      win.webmaker.auth.login();
    });

    $('.eventBtn').on('click', function () {
      showStep2(this.id);
    });

    $('#submit-event').on('click', submitForm);
  }

  function loginHandler(user) {
    if (user && user.username) {
      $('#sign-in-form').hide();
      $('#start-event-submission').removeClass('hidden');
    } else {
      $('#sign-in-form').show();
      $('#start-event-submission').addClass('hidden');
    }
  }

  function init() {
    if ($('.start-page').length > 0) {
      setUpWizard();
      findaPlace();
      $('#submit.event').prop('disabled', false);

      loginHandler(win.webmaker.person);
      win.webmaker.auth.on('verified', loginHandler);
      win.webmaker.auth.on('login', loginHandler);
      win.webmaker.auth.on('logout', loginHandler);
    }

    function setPageFromHash() {
      var hash = window.location.hash;

      // If there's a deep link jump to step 2, otherwise show step 1
      if (hash && hash !== '#/') {
        showStep2(hash.split('#/')[1], true);
      } else {
        $('#step-1').show();
        $('#step-2').hide();
      }
    }

    $(window).on('hashchange', function () {
      if (window.location.hash !== '') {
        setPageFromHash();
      }
    });

    setPageFromHash();
  }

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


<commit_before>/* globals __dirname, process */
const b = require('substance-bundler')
const fork = require('substance-bundler/extensions/fork')
const install = require('substance-bundler/extensions/install')
const isInstalled = require('substance-bundler/util/isInstalled')
const path = require('path')
const fs = require('fs')
const merge = require('lodash.merge')

/*
  Guide: this is a bundler make file.
  It is similar to gulp in that you define tasks which
  you can connect by adding dependencies.

  This file has the following structure:
  - Constants:
    Put shared settings and literals here to avoid code duplication
  - Functions:
    All task implementations
  - Tasks:
    Task definitions

  Run `node make --help` to print usage information.
*/

// Constants
// ---------

const COMMON_SETTINGS = (custom) => { return merge({
  // paramaters that are passed to the rollup-commonjs-plugin
  commonjs: {
    namedExports: { 'acorn/dist/walk.js': [ 'simple', 'base' ] }
  },
  // for libraries that we want to include into the browser bundle
  // but need to be pre-bundled (see buildVendor())
  // we register a redirect to the the pre-bundled file
  alias: {
    'sanitize-html': path.join(__dirname, 'vendor/sanitize-html.min.js'),
  }
}, custom)}

const BROWSER_EXTERNALS = {
  'substance': 'window.substance',
  'substance-mini': 'window.substanceMini',
  'brace': 'window.ace',
  'd3': 'window.d3',
  'katex': 'window.katex'
}

const EXAMPLE_EXTERNALS = Object.assign({}, BROWSER_EXTERNALS, {
  'stencila': 'window.stencila'
})

const BROWSER_TEST_EXTERNALS = Object.assign({}, BROWSER_EXTERNALS, {
  'tape': 'substanceTest.test'
})

const NODEJS_EXTERNALS = Object.keys(BROWSER_EXTERNALS)

const NODEJS_TEST_EXTERNALS = NODEJS_EXTERNALS.concat('tape')

// Functions
// ---------

function copyAssets() {
  b.copy('./node_modules/font-awesome', './build/font-awesome')
  b.copy('./vendor/brace.*', './build/lib/')
  b.copy('./node_modules/d3/build/d3.min.js', './build/lib/')
  b.copy('./node_modules/katex/dist/', './build/katex')
  b.copy('./node_modules/substance/dist/substance.js*', './build/lib/')
  b.copy('./node_modules/substance-mini/dist/substance-mini.js*', './build/lib/')
}

function buildCss() {
  b.css('src/pagestyle/stencila.css', 'build/stencila.css', {
    variables: true
  })
}

/*
  Building a single Stencila lib bundle
*/
function buildStencila() {
  const browserTarget = {
    dest: 'build/stencila.js',
    format: 'umd', moduleName: 'stencila',
    // we need to specify how the resolve external modules
    globals: BROWSER_EXTERNALS
  }
  const nodejsTarget = {
    dest : 'build/stencila.cjs.js',
    format: 'cjs',
    // brace is not nodejs compatible'
    ignore: [ 'brace' ]
  }
  b.js('index.es.js', COMMON_SETTINGS({
    targets: [browserTarget, nodejsTarget],
    // Externals are not include into the bundle
    external: NODEJS_EXTERNALS,
  }))
}

function buildExamples() {
  b.copy('./examples/*/*.html', './build/')

  ;['document', 'sheet', 'dashboard'].forEach((example) => {
    b.js(`examples/${example}/app.js`, {
      dest: `build/examples/${example}/app.js`,
      format: 'umd', moduleName: `${example}Example`,
      external: EXAMPLE_EXTERNALS
    })
  })
}

function buildTests(target) {
  if (target === 'browser') {
    b.js('tests/**/*.test.js', COMMON_SETTINGS({
      dest: 'tmp/tests.js',
      format: 'umd',
      moduleName: 'tests',
      external: BROWSER_TEST_EXTERNALS
    }))
  } else if (target === 'nodejs') {
    b.js('tests/**/*.test.js', COMMON_SETTINGS({
      dest: 'tmp/tests.cjs.js',
      format: 'cjs',
      external: NODEJS_TEST_EXTERNALS
    }))
  } else if (target === 'cover') {
    // TODO: we must include the whole source code to see the real coverage
    // right now we only see the coverage on the files which
    // are actually imported by tests.
    b.js(['index.es.js', 'tests/**/*.test.js'], COMMON_SETTINGS({
      dest: 'tmp/tests.cov.js',
      format: 'cjs',
      istanbul: {
        include: ['src/**/*.js']
      },
      // brace is not nodejs compatible'
      ignore: [ 'brace' ],
      // these should be used directly from nodejs, not bundled
      external: NODEJS_TEST_EXTERNALS.concat(['stream'])
    }))
  }
}

function buildSingleTest(testFile) {
  const dest = path.join(__dirname, 'tmp', testFile)
  b.js(testFile, COMMON_SETTINGS({
    dest: dest,
    format: 'cjs',
    external: NODEJS_TEST_EXTERNALS
  }))
  return dest
}

// this is not run all the time
// we use it to pre-bundle vendor libraries,
// to speed up bundling within this project
// and to work around problems with using rollup on these projects
function buildVendor() {
  install(b, 'browserify', '^14.1.0')
  install(b, 'uglify-js-harmony', '^2.7.5')
  minifiedVendor('./node_modules/sanitize-html/index.js', 'sanitize-html', {
    exports: ['default']
  })
  minifiedVendor('./vendor/.brace.js', 'brace')
}

function minifiedVendor(src, name, opts = {}) {
  let tmp = `./vendor/${name}.js`
  let _opts = Object.assign({
    dest: tmp,
    debug: false
  })
  if (opts.exports) {
    _opts.exports = opts.exports
  }
  if (opts.standalone) {
    _opts.browserify = { standalone: name }
  }
  b.browserify(src, _opts)
  if (opts.minify !== false) {
    b.minify(tmp, {
      debug: false
    })
    b.rm(tmp)
  }
}

// we need this only temporarily, or if we need to work on an
// unpublished version of substance
function buildDeps() {
  const subsDist = path.join(__dirname, 'node_modules/substance/dist')
  if (!fs.existsSync(path.join(subsDist,'substance.js')) ||
      !fs.existsSync(path.join(subsDist, 'substance.cjs.js'))) {
    b.make('substance')
  }
}

function buildDocumentation() {
  const config = require.resolve('./docs/docs.yml')
  fork(b, "node_modules/documentation/bin/documentation", "build", "--config", config, "--output", "docs", "--format", "html")
}

function serveDocumentation() {
  const config = require.resolve('./docs/docs.yml')
  fork(b, "node_modules/documentation/bin/documentation", "serve", "--config", config, "--watch")
}

// Tasks
// -----

b.task('clean', () => {
  b.rm('build')
  b.rm('tmp')
  b.rm('coverage')
})

// This is used to generate the files in ./vendor/
b.task('vendor', buildVendor)
.describe('Creates pre-bundled files in vendor/.')

// NOTE: this will not be necessary if we depend only on npm-published libraries
// At the moment, we use substance from a git branch
b.task('deps', () => {
  buildDeps()
})

b.task('assets', () => {
  copyAssets()
})
.describe('Copies assets into build folder.')

b.task('css', () => {
  buildCss()
})
.describe('Creates a single CSS bundle.')

b.task('stencila', ['clean', 'assets', 'css'], () => {
  buildStencila()
})
.describe('Build the stencila library.')

b.task('examples', ['stencila'], () => {
  // TODO: Make all examples use the single stencila.js build, so we don't
  // need individual builds
  buildExamples()
})
.describe('Build the examples.')

b.task('test', ['clean'], () => {
  buildTests('nodejs')
  fork(b, 'node_modules/substance-test/bin/test', 'tmp/tests.cjs.js', { verbose: true })
})
.describe('Runs the tests and generates a coverage report.')

b.task('cover', ['clean'], () => {
  buildTests('cover')
  fork(b, 'node_modules/substance-test/bin/coverage', 'tmp/tests.cov.js')
})

b.task('test:browser', () => {
  buildTests('browser')
})

b.task('test:one', () => {
  let test = b.argv.f
  if (!test) {
    console.error("Usage: node make test:one -f <testfile>")
    process.exit(-1)
  }
  let builtTestFile = buildSingleTest(test)
  fork(b, 'node_modules/substance-test/bin/test', builtTestFile, { verbose: true })
})
.describe('Runs the tests and generates a coverage report.')

b.task('docs', () => {
  if (isInstalled('documentation')) {
    buildDocumentation()
  } else {
    console.error("Please run 'npm install documentation'.\nSkipping task.")
  }
})

b.task('docs:serve', () => {
  if (isInstalled('documentation')) {
    serveDocumentation()
  } else {
    console.error("Please run 'npm install documentation'.\nSkipping task.")
  }
})

b.task('default', ['deps', 'stencila', 'examples'])
.describe('[stencila, examples].')

b.serve({ static: true, route: '/', folder: 'build' })
<commit_msg>Fix nodejs bundling.<commit_after>/* globals __dirname, process */
const b = require('substance-bundler')
const fork = require('substance-bundler/extensions/fork')
const install = require('substance-bundler/extensions/install')
const isInstalled = require('substance-bundler/util/isInstalled')
const path = require('path')
const fs = require('fs')
const merge = require('lodash.merge')

/*
  Guide: this is a bundler make file.
  It is similar to gulp in that you define tasks which
  you can connect by adding dependencies.

  This file has the following structure:
  - Constants:
    Put shared settings and literals here to avoid code duplication
  - Functions:
    All task implementations
  - Tasks:
    Task definitions

  Run `node make --help` to print usage information.
*/

// Constants
// ---------

const COMMON_SETTINGS = (custom) => { return merge({
  // paramaters that are passed to the rollup-commonjs-plugin
  commonjs: {
    namedExports: { 'acorn/dist/walk.js': [ 'simple', 'base' ] }
  },
  // for libraries that we want to include into the browser bundle
  // but need to be pre-bundled (see buildVendor())
  // we register a redirect to the the pre-bundled file
  alias: {
    'sanitize-html': path.join(__dirname, 'vendor/sanitize-html.min.js'),
  }
}, custom)}

const BROWSER_EXTERNALS = {
  'substance': 'window.substance',
  'substance-mini': 'window.substanceMini',
  'brace': 'window.ace',
  'd3': 'window.d3',
  'katex': 'window.katex'
}

const EXAMPLE_EXTERNALS = Object.assign({}, BROWSER_EXTERNALS, {
  'stencila': 'window.stencila'
})

const BROWSER_TEST_EXTERNALS = Object.assign({}, BROWSER_EXTERNALS, {
  'tape': 'substanceTest.test'
})

const NODEJS_EXTERNALS = Object.keys(BROWSER_EXTERNALS)

const NODEJS_TEST_EXTERNALS = NODEJS_EXTERNALS.concat('tape')

// Functions
// ---------

function copyAssets() {
  b.copy('./node_modules/font-awesome', './build/font-awesome')
  b.copy('./vendor/brace.*', './build/lib/')
  b.copy('./node_modules/d3/build/d3.min.js', './build/lib/')
  b.copy('./node_modules/katex/dist/', './build/katex')
  b.copy('./node_modules/substance/dist/substance.js*', './build/lib/')
  b.copy('./node_modules/substance-mini/dist/substance-mini.js*', './build/lib/')
}

function buildCss() {
  b.css('src/pagestyle/stencila.css', 'build/stencila.css', {
    variables: true
  })
}

/*
  Building a single Stencila lib bundle
*/
function buildStencilaBrowser() {
  const browserTarget = {
    dest: 'build/stencila.js',
    format: 'umd', moduleName: 'stencila',
    globals: BROWSER_EXTERNALS
  }
  b.js('index.es.js', COMMON_SETTINGS({
    target: browserTarget,
    external: NODEJS_EXTERNALS
  }))
}

function buildStencilaNodeJS() {
  const nodejsTarget = {
    dest : 'build/stencila.cjs.js',
    format: 'cjs'
  }
  b.js('index.es.js', COMMON_SETTINGS({
    target: nodejsTarget,
    // brace is not nodejs compatible'
    ignore: [ 'brace' ],
    // Externals are not include into the bundle
    external: NODEJS_EXTERNALS,
  }))
}

function buildExamples() {
  b.copy('./examples/*/*.html', './build/')

  ;['document', 'sheet', 'dashboard'].forEach((example) => {
    b.js(`examples/${example}/app.js`, {
      dest: `build/examples/${example}/app.js`,
      format: 'umd', moduleName: `${example}Example`,
      external: EXAMPLE_EXTERNALS
    })
  })
}

function buildTests(target) {
  if (target === 'browser') {
    b.js('tests/**/*.test.js', COMMON_SETTINGS({
      dest: 'tmp/tests.js',
      format: 'umd',
      moduleName: 'tests',
      external: BROWSER_TEST_EXTERNALS
    }))
  } else if (target === 'nodejs') {
    b.js('tests/**/*.test.js', COMMON_SETTINGS({
      dest: 'tmp/tests.cjs.js',
      format: 'cjs',
      external: NODEJS_TEST_EXTERNALS
    }))
  } else if (target === 'cover') {
    // TODO: we must include the whole source code to see the real coverage
    // right now we only see the coverage on the files which
    // are actually imported by tests.
    b.js(['index.es.js', 'tests/**/*.test.js'], COMMON_SETTINGS({
      dest: 'tmp/tests.cov.js',
      format: 'cjs',
      istanbul: {
        include: ['src/**/*.js']
      },
      // brace is not nodejs compatible'
      ignore: [ 'brace' ],
      // these should be used directly from nodejs, not bundled
      external: NODEJS_TEST_EXTERNALS.concat(['stream'])
    }))
  }
}

function buildSingleTest(testFile) {
  const dest = path.join(__dirname, 'tmp', testFile)
  b.js(testFile, COMMON_SETTINGS({
    dest: dest,
    format: 'cjs',
    external: NODEJS_TEST_EXTERNALS
  }))
  return dest
}

// this is not run all the time
// we use it to pre-bundle vendor libraries,
// to speed up bundling within this project
// and to work around problems with using rollup on these projects
function buildVendor() {
  install(b, 'browserify', '^14.1.0')
  install(b, 'uglify-js-harmony', '^2.7.5')
  minifiedVendor('./node_modules/sanitize-html/index.js', 'sanitize-html', {
    exports: ['default']
  })
  minifiedVendor('./vendor/.brace.js', 'brace')
}

function minifiedVendor(src, name, opts = {}) {
  let tmp = `./vendor/${name}.js`
  let _opts = Object.assign({
    dest: tmp,
    debug: false
  })
  if (opts.exports) {
    _opts.exports = opts.exports
  }
  if (opts.standalone) {
    _opts.browserify = { standalone: name }
  }
  b.browserify(src, _opts)
  if (opts.minify !== false) {
    b.minify(tmp, {
      debug: false
    })
    b.rm(tmp)
  }
}

// we need this only temporarily, or if we need to work on an
// unpublished version of substance
function buildDeps() {
  const subsDist = path.join(__dirname, 'node_modules/substance/dist')
  if (!fs.existsSync(path.join(subsDist,'substance.js')) ||
      !fs.existsSync(path.join(subsDist, 'substance.cjs.js'))) {
    b.make('substance')
  }
}

function buildDocumentation() {
  const config = require.resolve('./docs/docs.yml')
  fork(b, "node_modules/documentation/bin/documentation", "build", "--config", config, "--output", "docs", "--format", "html")
}

function serveDocumentation() {
  const config = require.resolve('./docs/docs.yml')
  fork(b, "node_modules/documentation/bin/documentation", "serve", "--config", config, "--watch")
}

// Tasks
// -----

b.task('clean', () => {
  b.rm('build')
  b.rm('tmp')
  b.rm('coverage')
})

// This is used to generate the files in ./vendor/
b.task('vendor', buildVendor)
.describe('Creates pre-bundled files in vendor/.')

// NOTE: this will not be necessary if we depend only on npm-published libraries
// At the moment, we use substance from a git branch
b.task('deps', () => {
  buildDeps()
})

b.task('assets', () => {
  copyAssets()
})
.describe('Copies assets into build folder.')

b.task('css', () => {
  buildCss()
})
.describe('Creates a single CSS bundle.')

b.task('stencila', ['clean', 'assets', 'css'], () => {
  buildStencilaBrowser()
  buildStencilaNodeJS()
})
.describe('Build the stencila library.')

b.task('examples', ['stencila'], () => {
  // TODO: Make all examples use the single stencila.js build, so we don't
  // need individual builds
  buildExamples()
})
.describe('Build the examples.')

b.task('test', ['clean'], () => {
  buildTests('nodejs')
  fork(b, 'node_modules/substance-test/bin/test', 'tmp/tests.cjs.js', { verbose: true })
})
.describe('Runs the tests and generates a coverage report.')

b.task('cover', ['clean'], () => {
  buildTests('cover')
  fork(b, 'node_modules/substance-test/bin/coverage', 'tmp/tests.cov.js')
})

b.task('test:browser', () => {
  buildTests('browser')
})

b.task('test:one', () => {
  let test = b.argv.f
  if (!test) {
    console.error("Usage: node make test:one -f <testfile>")
    process.exit(-1)
  }
  let builtTestFile = buildSingleTest(test)
  fork(b, 'node_modules/substance-test/bin/test', builtTestFile, { verbose: true })
})
.describe('Runs the tests and generates a coverage report.')

b.task('docs', () => {
  if (isInstalled('documentation')) {
    buildDocumentation()
  } else {
    console.error("Please run 'npm install documentation'.\nSkipping task.")
  }
})

b.task('docs:serve', () => {
  if (isInstalled('documentation')) {
    serveDocumentation()
  } else {
    console.error("Please run 'npm install documentation'.\nSkipping task.")
  }
})

b.task('default', ['deps', 'stencila', 'examples'])
.describe('[stencila, examples].')

b.serve({ static: true, route: '/', folder: 'build' })
<|endoftext|>


<commit_before><commit_msg>scrolltop working in FF<commit_after><|endoftext|>


<commit_before>document.addEventListener('DOMContentLoaded', async () => {
	function formatNumber(number) {
		return number.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1.');
	}
	let activatedSounds = [];
	let howlerList = {};

	function toggleButton(hasSounds) {
		const button = document.getElementsByTagName('button')[0];

		if (hasSounds) {
			button.innerText = 'やめろ!!';
			button.disabled = false;
			button.removeAttribute('style');
			// Removes inline CSS but keeps stylesheet intact
		}
		else {
			button.innerText = 'No sounds available.';
			button.style.fontSize = '40px';
			button.style.backgroundColor = '#606060';
			button.style.color = '#383838';
			button.disabled = true;
		}
	}

	function loadSounds(sounds, bg = null) {
		const button = document.getElementsByTagName('button')[0];
		howlerList = {};

		const bgTheme = themes.find(g => g.backgrounds.some(gBg => gBg.filename === bg));
		if (bgTheme) sounds = sounds.filter(s => s.theme === bgTheme.name);
		else sounds = sounds.filter(s => s.theme === 'megumin');
		// If the bg is associated with a special theme, sort sounds by said theme
		// Otherwise only load default sounds (megumin-related)

		sounds = sounds.filter(s => s.source !== 'no-source' && s.displayname);
		// Only load sounds with source and displayname

		activatedSounds = sounds;

		for (const sound of sounds) {
			const sourceName = sound.source.replace(/\s/g, '-').toLowerCase();

			howlerList[sound.filename] = new Howl({
				src: `/sounds/${sound.theme}/${sourceName}/${sound.filename}.mp3`
			});
		}

		if (sounds.length > 0 && button.innerText === 'No sounds available.') toggleButton(true);
		if (!sounds.length && button.innerText === 'やめろ!!') toggleButton(false);
	}

	const counterRes = await fetch('/api/counter').then(res => res.json());
	document.getElementById('counter').innerText = formatNumber(counterRes.counter);

	const allSounds = await fetch('/api/sounds').then(res => res.json());
	let currentBackground = localStorage.getItem('background') || '';
	let specialBg = themes.map(theme => theme.name).some(thm => currentBackground.startsWith(`${thm}_`)) ? currentBackground : null;
	loadSounds(allSounds, specialBg);

	const conInfo = await fetch('/api/conInfo').then(res => res.json());

	versionsAnchor = document.querySelectorAll("a[href='/versions']")[0];
	trimmedVersion = conInfo.version.substring(0, conInfo.version.lastIndexOf('.'));
	versionsAnchor.innerText = `[ver${trimmedVersion}]`;

	const domainOrIP = document.URL.split('/')[2].split(':')[0];
	const host = conInfo.ssl ? `wss://${domainOrIP}` : `ws://${domainOrIP}:${conInfo.port}`;

	const ws = new WebSocket(host);

	ws.addEventListener('open', event => {
		ws.addEventListener('message', message => {
			let data;

			try {
				data = JSON.parse(message.data);
			}
			catch (e) {
				data = {};
			}

			specialBg = themes.map(theme => theme.name).some(grp => currentBackground.startsWith(`${grp}_`)) ? currentBackground : null;

			switch (data.type) {
				case 'counterUpdate':
					if (data.counter) document.getElementById('counter').innerText = formatNumber(data.counter);
					break;
				case 'crazyMode':
					if (localStorage.getItem('crazyMode')) howlerList[data.soundFilename].play();
					break;
				case 'notification':
					if (data.notification) document.getElementById('notification').innerText = data.notification.text;
					util.fade(document.getElementById('notification-wrapper'), data.notification.duration * 1000, 0.1);
					break;
				case 'soundModify':
					allSounds[allSounds.findIndex(snd => snd.id === data.sound.id)] = data.sound;
					loadSounds(allSounds, specialBg);
					break;
				case 'soundUpload':
					allSounds.push(data.sound);
					loadSounds(allSounds, specialBg);
					break;
				case 'soundDelete':
					allSounds.splice(allSounds.findIndex(snd => snd.id === data.sound.id), 1);
					loadSounds(allSounds, specialBg);
					break;
				default:
					break;
			}
		});

		document.getElementsByTagName('button')[0].addEventListener('click', e => {
			const sound = activatedSounds[Math.floor(Math.random() * activatedSounds.length)];
			if (sound.filename === 'realname') sound.filename = 'name';

			howlerList[sound.filename].play();

			return ws.send(JSON.stringify({ type: 'click', soundFilename: sound.filename }));
		});
	});

	document.getElementById('bg-select').addEventListener('change', e => {
		const { value } = e.target;
		currentBackground = value;
		specialBg = themes.map(theme => theme.name).some(grp => currentBackground.startsWith(`${grp}_`)) ? currentBackground : null;

		loadSounds(allSounds, specialBg);
	});

	document.getElementsByTagName('button')[0].addEventListener('keypress', e => {
		if (e.key === 'Enter') return e.preventDefault();
	});
});<commit_msg>Use "disabled" property for sure way to check<commit_after>document.addEventListener('DOMContentLoaded', async () => {
	function formatNumber(number) {
		return number.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1.');
	}
	let activatedSounds = [];
	let howlerList = {};

	function setButton(activated) {
		const button = document.getElementsByTagName('button')[0];

		if (activated) {
			button.innerText = 'やめろ!!';
			button.removeAttribute('style');
			// Removes inline CSS but keeps stylesheet intact
			button.disabled = false;
		}
		else {
			button.disabled = true;
			button.innerText = 'No sounds available.';
			button.style.fontSize = '40px';
			button.style.backgroundColor = '#606060';
			button.style.color = '#383838';
		}
	}

	function loadSounds(sounds, bg = null) {
		const button = document.getElementsByTagName('button')[0];
		howlerList = {};

		const bgTheme = themes.find(g => g.backgrounds.some(gBg => gBg.filename === bg));
		if (bgTheme) sounds = sounds.filter(s => s.theme === bgTheme.name);
		else sounds = sounds.filter(s => s.theme === 'megumin');
		// If the bg is associated with a special theme, sort sounds by said theme
		// Otherwise only load default sounds (megumin-related)

		sounds = sounds.filter(s => s.source !== 'no-source' && s.displayname);
		// Only load sounds with source and displayname

		activatedSounds = sounds;

		for (const sound of sounds) {
			const sourceName = sound.source.replace(/\s/g, '-').toLowerCase();

			howlerList[sound.filename] = new Howl({
				src: `/sounds/${sound.theme}/${sourceName}/${sound.filename}.mp3`
			});
		}

		if (sounds.length > 0 && button.disabled) setButton(true);
		if (!sounds.length && !button.disabled) setButton(false);
	}

	const counterRes = await fetch('/api/counter').then(res => res.json());
	document.getElementById('counter').innerText = formatNumber(counterRes.counter);

	const allSounds = await fetch('/api/sounds').then(res => res.json());
	let currentBackground = localStorage.getItem('background') || '';
	let specialBg = themes.map(theme => theme.name).some(thm => currentBackground.startsWith(`${thm}_`)) ? currentBackground : null;
	loadSounds(allSounds, specialBg);

	const conInfo = await fetch('/api/conInfo').then(res => res.json());

	versionsAnchor = document.querySelectorAll("a[href='/versions']")[0];
	trimmedVersion = conInfo.version.substring(0, conInfo.version.lastIndexOf('.'));
	versionsAnchor.innerText = `[ver${trimmedVersion}]`;

	const domainOrIP = document.URL.split('/')[2].split(':')[0];
	const host = conInfo.ssl ? `wss://${domainOrIP}` : `ws://${domainOrIP}:${conInfo.port}`;

	const ws = new WebSocket(host);

	ws.addEventListener('open', event => {
		ws.addEventListener('message', message => {
			let data;

			try {
				data = JSON.parse(message.data);
			}
			catch (e) {
				data = {};
			}

			specialBg = themes.map(theme => theme.name).some(grp => currentBackground.startsWith(`${grp}_`)) ? currentBackground : null;

			switch (data.type) {
				case 'counterUpdate':
					if (data.counter) document.getElementById('counter').innerText = formatNumber(data.counter);
					break;
				case 'crazyMode':
					if (localStorage.getItem('crazyMode')) howlerList[data.soundFilename].play();
					break;
				case 'notification':
					if (data.notification) document.getElementById('notification').innerText = data.notification.text;
					util.fade(document.getElementById('notification-wrapper'), data.notification.duration * 1000, 0.1);
					break;
				case 'soundModify':
					allSounds[allSounds.findIndex(snd => snd.id === data.sound.id)] = data.sound;
					loadSounds(allSounds, specialBg);
					break;
				case 'soundUpload':
					allSounds.push(data.sound);
					loadSounds(allSounds, specialBg);
					break;
				case 'soundDelete':
					allSounds.splice(allSounds.findIndex(snd => snd.id === data.sound.id), 1);
					loadSounds(allSounds, specialBg);
					break;
				default:
					break;
			}
		});

		document.getElementsByTagName('button')[0].addEventListener('click', e => {
			const sound = activatedSounds[Math.floor(Math.random() * activatedSounds.length)];
			if (sound.filename === 'realname') sound.filename = 'name';

			howlerList[sound.filename].play();

			return ws.send(JSON.stringify({ type: 'click', soundFilename: sound.filename }));
		});
	});

	document.getElementById('bg-select').addEventListener('change', e => {
		const { value } = e.target;
		currentBackground = value;
		specialBg = themes.map(theme => theme.name).some(grp => currentBackground.startsWith(`${grp}_`)) ? currentBackground : null;

		loadSounds(allSounds, specialBg);
	});

	document.getElementsByTagName('button')[0].addEventListener('keypress', e => {
		if (e.key === 'Enter') return e.preventDefault();
	});
});<|endoftext|>


<commit_before><commit_msg>Change query input on history selection.<commit_after><|endoftext|>


<commit_before>var Vector = require('./vector.js');
var Mesh = require('./mesh.js');
var Matrix = require('./matrix.js');
var Face = require('./face.js');

var math = Object.create(null);

math.Vector = Vector;
math.Vertex = Vertex;
math.Mesh = Mesh;
math.Matrix = Matrix;
math.Face = Face;

module.exports = math;<commit_msg>Remove Vertex from math module<commit_after>var Vector = require('./vector.js');
var Mesh = require('./mesh.js');
var Matrix = require('./matrix.js');
var Face = require('./face.js');

var math = Object.create(null);

math.Vector = Vector;
math.Mesh = Mesh;
math.Matrix = Matrix;
math.Face = Face;

module.exports = math;<|endoftext|>


<commit_before>Slackbot = function (options) {
};

Slackbot.post = function (channel, message) {
    var url;
    var token;

    if (!Meteor.settings.slack) {
        throw new Meteor.Error(500, 'No Slack settings provided.');
    }

    url = Meteor.settings.slack.url;
    token = Meteor.settings.slack.token;

    if (!url) {
        throw new Meteor.Error(404, 'No URL provided for Slackbot.');
    }

    if (!token) {
        throw new Meteor.Error(401, 'No token provided for Slackbot.');
    }

    if (!message && message != 0) {
        message = '';
    }

    HTTP.post(url, {
        params: {
            token: String(token),
            channel: String(channel)
        },
        data: String(message)
    });
};

<commit_msg>Introduced new options, now there are three: url, team and token. Slackbot is now a constructor and prototype object, easier to define multiple ones for multiple teams.<commit_after>Slackbot = function (options) {
    if (!options) {
        throw new Meteor.Error(400, 'Must provide options for new Slackbot remote control instance.');
    }

    if (typeof options !== 'object') {
        throw new Meteor.Error(400, 'Slackbot remote control options must be an object.');
    }

    this.team = options.team;
    this.url = options.url || 'https://'.concat(this.team).concat('.slack.com/services/hooks/slackbot');
    this.token = options.token;
};

Slackbot.prototype.postMessage = function (channel, message) {
    var url;
    var token;

    if (!Meteor.settings.slack) {
        throw new Meteor.Error(500, 'No Slack settings provided.');
    }

    url = this.url || 'https://'.concat(this.team).concat('.slack.com/services/hooks/slackbot') || Meteor.settings.slack.url;
    token = this.token || Meteor.settings.slack.token;

    if (!url) {
        throw new Meteor.Error(404, 'No URL provided for Slackbot.');
    }

    if (!token) {
        throw new Meteor.Error(401, 'No token provided for Slackbot.');
    }

    HTTP.post(url, {
        params: {
            token: String(token),
            channel: String(channel)
        },
        data: String(message || '')
    });
};

<|endoftext|>


<commit_before>/*jshint node: true */
'use strict';

/*
* Name :  Axis.js
* Module : UnitTest
* Location : /frontend/test/unit/Model
*
* History :
* Version       Date        Programmer                  Description
* =======================================================================================================================
* 0.1.2         2015-05-17  Maria Giovanna Chinellato   Fix code
*
* 0.1.1			2015-05-15	Francesco Rossetto			Fix test of Model::Axis
*
* 0.1.1			2015-05-15	Maria Giovanna Chinellato	Fix test of Model::Axis
*
* 0.1.0			2015-05-15	Francesco Rossetto			Add test of Model::Axis, describe all method
*
* 0.0.1			2015-05-15	Francesco Rossetto			Initial code
* =======================================================================================================================
*
*/

describe('Axis', function(){

	var Axis = null;

	beforeEach(angular.mock.module('app'));

	beforeEach(inject(function (_Axis_) {
		Axis = _Axis_;
	}));

	describe('Constructor', function(){

		var json = 	{
			'name' : 'asse nella manica',
			'color' : '#F0F',
			'minValue' : 0,
			'maxValue' : 100,
			'ticks' : 10,
			'scale' : 'logarithmic'
		};

		beforeEach(function(){
			Axis = new Axis(json);
			//Axis = Axis.Axis(json);
		});

		it('instance defined', function(){
			expect(Axis).toBeDefined();
		});

		it('constructor create the page with the correct name', function(){
			//var Axis2 = new Axis();
			Axis = Axis.Axis(json);
			var axisName = Axis2.getName();
			expect(axisName).toBeDefined();
			expect(axisName).toEqual('asse nella manica');
		});
		it('constructor create the page with the correct color', function(){
			var axisColor = Axis.getColor();
			expect(axisColor).toBeDefined();
			expect(axisColor).toEqual('#F0F');
		});
		it('constructor create the page with the correct minValue', function(){
			var axisMinValue = Axis.getMinValue();
			expect(axisMinValue).toBeDefined();
			expect(axisMinValue).toEqual(0);
		});
		it('constructor create the page with the correct maxValue', function(){
			var axisMaxValue = Axis.getMaxValue();
			expect(axisMaxValue).toBeDefined();
			expect(axisMaxValue).toEqual(100);
		});
		it('constructor create the page with the correct ticks', function(){
			var axisTicks = Axis.getTicks();
			expect(axisTicks).toBeDefined();
			expect(axisTicks).toEqual(10);
		});
		it('constructor create the page with the correct scale', function(){
			var axisScale = Axis.getScale();
			expect(axisScale).toBeDefined();
			expect(axisScale).toEqual('logarithmic');
		});

	});

	/*describe('updateParameters', function(){

		var json = 	{
			'name' : 'asso',
			'color' : '#AFA',
			'minValue' : 1,
			'maxValue' : 101,
			'ticks' : 10,
			'scale' : 'linear',
		};

		beforeEach(function(){
			Axis.updateParameters(json);
		});

		it('Axis updated with the correct name', function(){
			expect(Axis.getName()).toEqual('asso');
		});
		it('Axis updated with the correct color', function(){
			expect(Axis.getColor()).toEqual('#AFA');
		});
		it('Axis updated with the correct minValue', function(){
			expect(Axis.getMinValue()).toEqual(1);
		});
		it('Axis updated with the correct maxValue', function(){
			expect(Axis.getMaxValue()).toEqual(101);
		});
		it('Axis updated with the correct getTicks', function(){
			expect(Axis.getTicks()).toEqual(10);
		});
		it('Axis updated with the correct scale', function(){
			expect(Axis.getScale()).toEqual('linear');
		});

	});*/

});<commit_msg>some fixes<commit_after>/*jshint node: true */
'use strict';

/*
* Name :  Axis.js
* Module : UnitTest
* Location : /frontend/test/unit/Model
*
* History :
* Version       Date        Programmer                  Description
* =======================================================================================================================
* 0.1.2         2015-05-17  Maria Giovanna Chinellato   Fix code
*
* 0.1.1			2015-05-15	Francesco Rossetto			Fix test of Model::Axis
*
* 0.1.1			2015-05-15	Maria Giovanna Chinellato	Fix test of Model::Axis
*
* 0.1.0			2015-05-15	Francesco Rossetto			Add test of Model::Axis, describe all method
*
* 0.0.1			2015-05-15	Francesco Rossetto			Initial code
* =======================================================================================================================
*
*/

describe('Axis', function(){

	var Axis = null;

	beforeEach(angular.mock.module('app'));

	beforeEach(inject(function (_Axis_) {
		Axis = _Axis_;
	}));

	describe('Constructor', function(){

		var json = 	{
			'name' : 'asse nella manica',
			'color' : '#F0F',
			'minValue' : 0,
			'maxValue' : 100,
			'ticks' : 10,
			'scale' : 'logarithmic'
		};

		beforeEach(function(){
			Axis = new Axis(json);
			//Axis = Axis.Axis(json);
		});

		it('instance defined', function(){
			expect(Axis).toBeDefined();
		});

		it('constructor create the page with the correct name', function(){
			//var Axis2 = new Axis();
			Axis = Axis.Axis(json);
			var axisName = Axis.getName();
			expect(axisName).toBeDefined();
			expect(axisName).toEqual('asse nella manica');
		});
		it('constructor create the page with the correct color', function(){
			var axisColor = Axis.getColor();
			expect(axisColor).toBeDefined();
			expect(axisColor).toEqual('#F0F');
		});
		it('constructor create the page with the correct minValue', function(){
			var axisMinValue = Axis.getMinValue();
			expect(axisMinValue).toBeDefined();
			expect(axisMinValue).toEqual(0);
		});
		it('constructor create the page with the correct maxValue', function(){
			var axisMaxValue = Axis.getMaxValue();
			expect(axisMaxValue).toBeDefined();
			expect(axisMaxValue).toEqual(100);
		});
		it('constructor create the page with the correct ticks', function(){
			var axisTicks = Axis.getTicks();
			expect(axisTicks).toBeDefined();
			expect(axisTicks).toEqual(10);
		});
		it('constructor create the page with the correct scale', function(){
			var axisScale = Axis.getScale();
			expect(axisScale).toBeDefined();
			expect(axisScale).toEqual('logarithmic');
		});

	});

	/*describe('updateParameters', function(){

		var json = 	{
			'name' : 'asso',
			'color' : '#AFA',
			'minValue' : 1,
			'maxValue' : 101,
			'ticks' : 10,
			'scale' : 'linear',
		};

		beforeEach(function(){
			Axis.updateParameters(json);
		});

		it('Axis updated with the correct name', function(){
			expect(Axis.getName()).toEqual('asso');
		});
		it('Axis updated with the correct color', function(){
			expect(Axis.getColor()).toEqual('#AFA');
		});
		it('Axis updated with the correct minValue', function(){
			expect(Axis.getMinValue()).toEqual(1);
		});
		it('Axis updated with the correct maxValue', function(){
			expect(Axis.getMaxValue()).toEqual(101);
		});
		it('Axis updated with the correct getTicks', function(){
			expect(Axis.getTicks()).toEqual(10);
		});
		it('Axis updated with the correct scale', function(){
			expect(Axis.getScale()).toEqual('linear');
		});

	});*/

});<|endoftext|>


<commit_before>// This is an example file. Be sure to rename it to local.js and add valid credentials.
module.exports = {
  port: 1337,
  environment: "development",
  reddit: {
    clientID: "CLIENT ID GOES HERE",
    clientIDSecret: "SECRET ID GOES HERE",
    redirectURL: "http://localhost:1337/auth/reddit/callback",
    adminRefreshToken: "ADMIN REFRESH TOKEN GOES HERE"
  },
  connections: {
    "default": "mongo",
    mongo: {
      adapter: 'sails-mongo',
      host: 'localhost',
      port: 27017,
      user: '',
      password: '',
      database: 'fapp'
    }
  },
  session: {
    adapter: 'mongo',
    host: 'localhost',
    port: 27017,
    db: 'fapp',
    collection: 'sessions'
  }
};
<commit_msg>Added hook timeout, did not accidentally delete any other commits<commit_after>// This is an example file. Be sure to rename it to local.js and add valid credentials.
module.exports = {
  port: 1337,
  environment: "development",
  hookTimeout: "50000",
  reddit: {
    clientID: "CLIENT ID GOES HERE",
    clientIDSecret: "SECRET ID GOES HERE",
    redirectURL: "http://localhost:1337/auth/reddit/callback",
    adminRefreshToken: "ADMIN REFRESH TOKEN GOES HERE"
  },
  connections: {
    "default": "mongo",
    mongo: {
      adapter: 'sails-mongo',
      host: 'localhost',
      port: 27017,
      user: '',
      password: '',
      database: 'fapp'
    }
  },
  session: {
    adapter: 'mongo',
    host: 'localhost',
    port: 27017,
    db: 'fapp',
    collection: 'sessions'
  }
};
<|endoftext|>


<commit_before>export default function(request$) {
  const local$ = request$.filter((req) => !req.target || req.target === `local`)
  const session$ = request$.filter((req) => req.target === `session`)

  return {
    // For localStorage.
    local: {
      key(n) {
        // Function returning Observable of the nth key.
        return local$
          .filter((req) => req.key === localStorage.key(n))
          .map((req) => req.key)
          .startWith(localStorage.key(n))
          .distinctUntilChanged()
      },
      // Function returning Observable of item values.
      getItem(key) {
        const initialValue = localStorage.getItem(key)

        const value$ = local$
          .filter((req) => req.key === key)
          .map((req) => req.value)

        if (initialValue !== null) {
          return value$.startWith(initialValue)
        } else {
          return value$
        }
      },
    },
    // For sessionStorage.
    session: {
      // Function returning Observable of the nth key.
      key(n) {
        return session$
          .filter((req) => req.key === sessionStorage.key(n))
          .map((req) => req.key)
          .startWith(sessionStorage.key(n))
          .distinctUntilChanged()
      },
      // Function returning Observable of values.
      getItem(key) {
        const initialValue = sessionStorage.getItem(key)

        const value$ = session$
          .filter((req) => req.key === key)
          .map((req) => req.value)

        if (initialValue !== null) {
          return value$.startWith(initialValue)
        } else {
          return value$
        }
      },
    },
  }
}
<commit_msg>return null if localStorage is empty<commit_after>export default function(request$) {
  const local$ = request$.filter((req) => !req.target || req.target === `local`)
  const session$ = request$.filter((req) => req.target === `session`)

  return {
    // For localStorage.
    local: {
      key(n) {
        // Function returning Observable of the nth key.
        return local$
          .filter((req) => req.key === localStorage.key(n))
          .map((req) => req.key)
          .startWith(localStorage.key(n))
          .distinctUntilChanged()
      },
      // Function returning Observable of item values.
      getItem(key) {
        return local$
          .filter((req) => req.key === key)
          .map((req) => req.value)
          .startWith(localStorage.getItem(key))
      },
    },
    // For sessionStorage.
    session: {
      // Function returning Observable of the nth key.
      key(n) {
        return session$
          .filter((req) => req.key === sessionStorage.key(n))
          .map((req) => req.key)
          .startWith(sessionStorage.key(n))
          .distinctUntilChanged()
      },
      // Function returning Observable of values.
      getItem(key) {
        return session$
          .filter((req) => req.key === key)
          .map((req) => req.value)
          .startWith(sessionStorage.getItem(key))
      },
    },
  }
}
<|endoftext|>


<commit_before>var FILE_PATH = "/Users/pete/iMacros/Macros/jcrawler/{0}";
var REGEX_HREF = new RegExp("href=\"[^\"]+\"", "gi");
var REGEX_IMGSRC = new RegExp("src=\"[^\"]+\"", "gi");
var URL_PROFILE = "http://yahoo-mbga.jp/{0}";
var URL_GROUP = "http://yahoo-mbga.jp/group/{0}";

// Source: http://forum.iopus.com/viewtopic.php?f=11&t=5267
// Note: this may not work depending on Java version(?)
write_file = function(path, data) {
  iimDisplay("Writing file:"+path);
   try {
      var out = new java.io.BufferedWriter(new java.io.OutputStreamWriter(new java.io.FileOutputStream(new java.io.File(path)), "UTF8"));
      out.write(data);
      out.close();
      out=null;
   }
   catch(e) { //catch and report any errors
      alert(""+e);
   }
};

// Source: http://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format/4256130#4256130
String.prototype.format = function() {
  var formatted = this;
  for (var i = 0; i < arguments.length; i++) {
    var regexp = new RegExp('\\{'+i+'\\}', 'gi');
    formatted = formatted.replace(regexp, arguments[i]);
  }
  return formatted;
};

// Source: http://stackoverflow.com/questions/646628/javascript-startswith
if (typeof String.prototype.startsWith != 'function') {
  String.prototype.startsWith = function (str){
    return this.slice(0, str.length) == str;
  };
}

// Source: http://stackoverflow.com/questions/280634/endswith-in-javascript
if (typeof String.prototype.endsWith != 'function') {
  String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
  };
}

// inclusive random range
// Source: http://www.admixweb.com/2010/08/24/javascript-tip-get-a-random-number-between-two-integers/
random_range = function(from, to){
  var val = Math.floor(Math.random() * (to - from + 1) + from);
  if(val > to) { // in case Math.random() can produce 1.0 (does it?)
    val = to;
  }
  return val;
};

// Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date
function date_string(d){
 function pad(n){return n<10 ? '0'+n : n}
 return d.getUTCFullYear()+''
      + pad(d.getUTCMonth()+1)+''
      + pad(d.getUTCDate())+''
      + pad(d.getUTCHours())+''
      + pad(d.getUTCMinutes())+''
      + pad(d.getUTCSeconds())}

run = function(code, n) {
  var retcode = iimPlay("CODE: "+code);
  if(retcode != 1) {
    alert("BAD CODE:\n"+code+"\n\nretcode:"+retcode);
    return;
  }
  if(n) {
    var extract = iimGetLastExtract(n);
    if(extract == "#EANF#") return false; // "Extraction Anchor Not Found"
    return extract;
  }
};

sleep = function(seconds) { run("WAIT SECONDS="+seconds); };
visit_url = function(url) { run("URL GOTO="+url); };

save_profile = function(id, source_id) {
  var raw_demo = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof1-lay EXTRACT=HTM", 1);
  var raw_qa = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof2-lay EXTRACT=HTM", 1);
  var raw_diary = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof3-lay EXTRACT=HTM", 1);
  var raw_disc = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof4-lay EXTRACT=HTM", 1);
  var raw_greet = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof6-lay EXTRACT=HTM", 1);
  var raw_test = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof5-lay EXTRACT=HTM", 1);
  var filename = date_string(new Date())+"_"+id+"_"+source_id+"_{0}_.data";
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("demo")), raw_demo);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("qa")), raw_qa);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("diary")), raw_diary);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("disc")), raw_disc);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("greet")), raw_greet);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("test")), raw_test);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("img")), avatar_url());
};

avatar_url = function() {
  var raw = run("TAG POS=1 TYPE=DIV ATTR=CLASS:lv3-ava-wrap EXTRACT=HTM", 1);
  var src = raw.match(REGEX_IMGSRC)[0]
  return src.substring(5, src.length - 1);
};

save_group = function(id) {
  var raw_meta = run("TAG POS=1 TYPE=UL ATTR=CLASS:blk-lay EXTRACT=HTM", 1);
  var raw_msg = run("TAG POS=1 TYPE=DIV ATTR=CLASS:crcltopic-lay EXTRACT=HTM", 1);
  var filename = date_string(new Date())+"_"+id+"_{0}.data";
  var path_meta = FILE_PATH.format("data/mbga/group/"+filename.format("meta"));
  var path_msg = FILE_PATH.format("data/mbga/group/"+filename.format("msg"));
  write_file(path_meta, raw_meta);
  write_file(path_msg, raw_msg);
};

extract_profiles = function(source_id) {
  var raw = run("TAG POS=1 TYPE=DIV ATTR=ID:circlemem-sec EXTRACT=HTM", 1);
  var links = raw.match(REGEX_HREF);
  links.pop(); // last link isn't a profile
  var mod_links = [];
  for(var i=0; i<links.length; i++) {
    if(i % 2 == 0)
      mod_links.push({
        type:"profile",
        id: links[i].substring(7, links[i].length - 1),
        source: source_id
      });
  }
  return mod_links;
};

extract_groups = function() {
  var raw = run("TAG POS=1 TYPE=DIV ATTR=ID:circleentry-sec EXTRACT=HTM", 1);
  var links = raw.match(REGEX_HREF);
  links.pop(); // last link isn't a group link
  var mod_links = [];
  for(var i=0; i<links.length; i++) {
    if(i % 2 == 0)
      mod_links.push({
        type:"group",
        id: links[i].substring(13, links[i].length - 1)
      });
  }
  return mod_links;
};

main = function() {
  // randomly generated valid group IDs using random number generator
  // note: mgba seems to have skipped IDs from ~2,000,000 to ~30,000,000
  var seed_nodes = [
    {type: "group", id: "30704159"}
    , {type: "group", id: "1901844"}
    , {type: "group", id: "30945349"} // example of no threads
    , {type: "group", id: "487069"}
    , {type: "group", id: "1719377"} // example of single thread
  ];
  var queue = [];
  queue = queue.concat(seed_nodes);
  var visited_groups = [];
  var visited_profiles = [];
  while(queue.length > 0 && visited_groups.length < 500){
    var item = queue.shift();
    if(item.type === "profile") {
      if(visited_profiles.indexOf(item.id) >= 0) continue;
      visit_url(URL_PROFILE.format(item.id));
      save_profile(item.id);
      visited_profiles.push(item.id);
      queue = queue.concat(extract_groups());
    }
    else {
      if(visited_groups.indexOf(item.id) >= 0) continue;
      visit_url(URL_GROUP.format(item.id));
      save_group(item.id);
      visited_groups.push(item.id);
      queue = queue.concat(extract_profiles(item.id));
    }
    sleep(random_range(3, 8));
  }
};

main();<commit_msg>woops - pass item.source<commit_after>var FILE_PATH = "/Users/pete/iMacros/Macros/jcrawler/{0}";
var REGEX_HREF = new RegExp("href=\"[^\"]+\"", "gi");
var REGEX_IMGSRC = new RegExp("src=\"[^\"]+\"", "gi");
var URL_PROFILE = "http://yahoo-mbga.jp/{0}";
var URL_GROUP = "http://yahoo-mbga.jp/group/{0}";

// Source: http://forum.iopus.com/viewtopic.php?f=11&t=5267
// Note: this may not work depending on Java version(?)
write_file = function(path, data) {
  iimDisplay("Writing file:"+path);
   try {
      var out = new java.io.BufferedWriter(new java.io.OutputStreamWriter(new java.io.FileOutputStream(new java.io.File(path)), "UTF8"));
      out.write(data);
      out.close();
      out=null;
   }
   catch(e) { //catch and report any errors
      alert(""+e);
   }
};

// Source: http://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format/4256130#4256130
String.prototype.format = function() {
  var formatted = this;
  for (var i = 0; i < arguments.length; i++) {
    var regexp = new RegExp('\\{'+i+'\\}', 'gi');
    formatted = formatted.replace(regexp, arguments[i]);
  }
  return formatted;
};

// Source: http://stackoverflow.com/questions/646628/javascript-startswith
if (typeof String.prototype.startsWith != 'function') {
  String.prototype.startsWith = function (str){
    return this.slice(0, str.length) == str;
  };
}

// Source: http://stackoverflow.com/questions/280634/endswith-in-javascript
if (typeof String.prototype.endsWith != 'function') {
  String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
  };
}

// inclusive random range
// Source: http://www.admixweb.com/2010/08/24/javascript-tip-get-a-random-number-between-two-integers/
random_range = function(from, to){
  var val = Math.floor(Math.random() * (to - from + 1) + from);
  if(val > to) { // in case Math.random() can produce 1.0 (does it?)
    val = to;
  }
  return val;
};

// Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date
function date_string(d){
 function pad(n){return n<10 ? '0'+n : n}
 return d.getUTCFullYear()+''
      + pad(d.getUTCMonth()+1)+''
      + pad(d.getUTCDate())+''
      + pad(d.getUTCHours())+''
      + pad(d.getUTCMinutes())+''
      + pad(d.getUTCSeconds())}

run = function(code, n) {
  var retcode = iimPlay("CODE: "+code);
  if(retcode != 1) {
    alert("BAD CODE:\n"+code+"\n\nretcode:"+retcode);
    return;
  }
  if(n) {
    var extract = iimGetLastExtract(n);
    if(extract == "#EANF#") return false; // "Extraction Anchor Not Found"
    return extract;
  }
};

sleep = function(seconds) { run("WAIT SECONDS="+seconds); };
visit_url = function(url) { run("URL GOTO="+url); };

save_profile = function(id, source_id) {
  var raw_demo = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof1-lay EXTRACT=HTM", 1);
  var raw_qa = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof2-lay EXTRACT=HTM", 1);
  var raw_diary = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof3-lay EXTRACT=HTM", 1);
  var raw_disc = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof4-lay EXTRACT=HTM", 1);
  var raw_greet = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof6-lay EXTRACT=HTM", 1);
  var raw_test = run("TAG POS=1 TYPE=DIV ATTR=CLASS:prof5-lay EXTRACT=HTM", 1);
  var filename = date_string(new Date())+"_"+id+"_"+source_id+"_{0}_.data";
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("demo")), raw_demo);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("qa")), raw_qa);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("diary")), raw_diary);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("disc")), raw_disc);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("greet")), raw_greet);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("test")), raw_test);
  write_file(FILE_PATH.format("data/mbga/person/"+filename.format("img")), avatar_url());
};

avatar_url = function() {
  var raw = run("TAG POS=1 TYPE=DIV ATTR=CLASS:lv3-ava-wrap EXTRACT=HTM", 1);
  var src = raw.match(REGEX_IMGSRC)[0]
  return src.substring(5, src.length - 1);
};

save_group = function(id) {
  var raw_meta = run("TAG POS=1 TYPE=UL ATTR=CLASS:blk-lay EXTRACT=HTM", 1);
  var raw_msg = run("TAG POS=1 TYPE=DIV ATTR=CLASS:crcltopic-lay EXTRACT=HTM", 1);
  var filename = date_string(new Date())+"_"+id+"_{0}.data";
  var path_meta = FILE_PATH.format("data/mbga/group/"+filename.format("meta"));
  var path_msg = FILE_PATH.format("data/mbga/group/"+filename.format("msg"));
  write_file(path_meta, raw_meta);
  write_file(path_msg, raw_msg);
};

extract_profiles = function(source_id) {
  var raw = run("TAG POS=1 TYPE=DIV ATTR=ID:circlemem-sec EXTRACT=HTM", 1);
  var links = raw.match(REGEX_HREF);
  links.pop(); // last link isn't a profile
  var mod_links = [];
  for(var i=0; i<links.length; i++) {
    if(i % 2 == 0)
      mod_links.push({
        type:"profile",
        id: links[i].substring(7, links[i].length - 1),
        source: source_id
      });
  }
  return mod_links;
};

extract_groups = function() {
  var raw = run("TAG POS=1 TYPE=DIV ATTR=ID:circleentry-sec EXTRACT=HTM", 1);
  var links = raw.match(REGEX_HREF);
  links.pop(); // last link isn't a group link
  var mod_links = [];
  for(var i=0; i<links.length; i++) {
    if(i % 2 == 0)
      mod_links.push({
        type:"group",
        id: links[i].substring(13, links[i].length - 1)
      });
  }
  return mod_links;
};

main = function() {
  // randomly generated valid group IDs using random number generator
  // note: mgba seems to have skipped IDs from ~2,000,000 to ~30,000,000
  var seed_nodes = [
    {type: "group", id: "30704159"}
    , {type: "group", id: "1901844"}
    , {type: "group", id: "30945349"} // example of no threads
    , {type: "group", id: "487069"}
    , {type: "group", id: "1719377"} // example of single thread
  ];
  var queue = [];
  queue = queue.concat(seed_nodes);
  var visited_groups = [];
  var visited_profiles = [];
  while(queue.length > 0 && visited_groups.length < 500){
    var item = queue.shift();
    if(item.type === "profile") {
      if(visited_profiles.indexOf(item.id) >= 0) continue;
      visit_url(URL_PROFILE.format(item.id));
      save_profile(item.id, item.source);
      visited_profiles.push(item.id);
      queue = queue.concat(extract_groups());
    }
    else {
      if(visited_groups.indexOf(item.id) >= 0) continue;
      visit_url(URL_GROUP.format(item.id));
      save_group(item.id);
      visited_groups.push(item.id);
      queue = queue.concat(extract_profiles(item.id));
    }
    sleep(random_range(3, 8));
  }
};

main();<|endoftext|>


<commit_before>/**
 * Plugin used to scroll Handsontable by selecting a cell and dragging outside of visible viewport
 * @constructor
 */
function DragToScroll() {
  this.boundaries = null;
  this.callback = null;
}

/**
 * @param boundaries {Object} compatible with getBoundingClientRect
 */
DragToScroll.prototype.setBoundaries = function (boundaries) {
  this.boundaries = boundaries;
};

/**
 * @param callback {Function}
 */
DragToScroll.prototype.setCallback = function (callback) {
  this.callback = callback;
};

/**
 * Check if mouse position (x, y) is outside of the viewport
 * @param x
 * @param y
 */
DragToScroll.prototype.check = function (x, y) {
  var diffX = 0;
  var diffY = 0;

  if (y < this.boundaries.top) {
    //y is less than top
    diffY = y - this.boundaries.top;
  }
  else if (y > this.boundaries.bottom) {
    //y is more than bottom
    diffY = y - this.boundaries.bottom;
  }

  if (x < this.boundaries.left) {
    //x is less than left
    diffX = x - this.boundaries.left;
  }
  else if (x > this.boundaries.right) {
    //x is more than right
    diffX = x - this.boundaries.right;
  }

  this.callback(diffX, diffY);
};

var listening = false;
var dragToScroll;
var instance;

if (typeof Handsontable !== 'undefined') {
  var setupListening = function (instance) {
    var scrollHandler = instance.view.wt.wtScrollbars.vertical.scrollHandler; //native scroll
    dragToScroll = new DragToScroll();
    if (scrollHandler === window) {
      //not much we can do currently
      return;
    }
    else if (scrollHandler) {
      dragToScroll.setBoundaries(scrollHandler.getBoundingClientRect());
    }
    else {
      dragToScroll.setBoundaries(instance.$table[0].getBoundingClientRect());
    }

    dragToScroll.setCallback(function (scrollX, scrollY) {
      if (scrollX < 0) {
        if (scrollHandler) {
          scrollHandler.scrollLeft -= 50;
        }
        else {
          instance.view.wt.scrollHorizontal(-1).draw();
        }
      }
      else if (scrollX > 0) {
        if (scrollHandler) {
          scrollHandler.scrollLeft += 50;
        }
        else {
          instance.view.wt.scrollHorizontal(1).draw();
        }
      }

      if (scrollY < 0) {
        if (scrollHandler) {
          scrollHandler.scrollTop -= 20;
        }
        else {
          instance.view.wt.scrollVertical(-1).draw();
        }
      }
      else if (scrollY > 0) {
        if (scrollHandler) {
          scrollHandler.scrollTop += 20;
        }
        else {
          instance.view.wt.scrollVertical(1).draw();
        }
      }
    });

    listening = true;
  };

  Handsontable.hooks.add('afterInit', function () {
    $(document).on('mouseup.' + this.guid, function () {
      listening = false;
    });

    $(document).on('mousemove.' + this.guid, function (event) {
      if (listening) {
        dragToScroll.check(event.clientX, event.clientY);
      }
    });
  });

  Handsontable.hooks.add('destroy', function () {
    $(document).off('.' + this.guid);
  });

  Handsontable.hooks.add('afterOnCellMouseDown', function () {
    setupListening(this);
  });

  Handsontable.hooks.add('afterOnCellCornerMouseDown', function () {
    setupListening(this);
  });

  Handsontable.plugins.DragToScroll = DragToScroll;
}
<commit_msg>bugfix: destroy did not work<commit_after>/**
 * Plugin used to scroll Handsontable by selecting a cell and dragging outside of visible viewport
 * @constructor
 */
function DragToScroll() {
  this.boundaries = null;
  this.callback = null;
}

/**
 * @param boundaries {Object} compatible with getBoundingClientRect
 */
DragToScroll.prototype.setBoundaries = function (boundaries) {
  this.boundaries = boundaries;
};

/**
 * @param callback {Function}
 */
DragToScroll.prototype.setCallback = function (callback) {
  this.callback = callback;
};

/**
 * Check if mouse position (x, y) is outside of the viewport
 * @param x
 * @param y
 */
DragToScroll.prototype.check = function (x, y) {
  var diffX = 0;
  var diffY = 0;

  if (y < this.boundaries.top) {
    //y is less than top
    diffY = y - this.boundaries.top;
  }
  else if (y > this.boundaries.bottom) {
    //y is more than bottom
    diffY = y - this.boundaries.bottom;
  }

  if (x < this.boundaries.left) {
    //x is less than left
    diffX = x - this.boundaries.left;
  }
  else if (x > this.boundaries.right) {
    //x is more than right
    diffX = x - this.boundaries.right;
  }

  this.callback(diffX, diffY);
};

var dragToScroll;
var instance;

if (typeof Handsontable !== 'undefined') {
  var setupListening = function (instance) {
    instance.dragToScrollListening = false;
    var scrollHandler = instance.view.wt.wtScrollbars.vertical.scrollHandler; //native scroll
    dragToScroll = new DragToScroll();
    if (scrollHandler === window) {
      //not much we can do currently
      return;
    }
    else if (scrollHandler) {
      dragToScroll.setBoundaries(scrollHandler.getBoundingClientRect());
    }
    else {
      dragToScroll.setBoundaries(instance.$table[0].getBoundingClientRect());
    }

    dragToScroll.setCallback(function (scrollX, scrollY) {
      if (scrollX < 0) {
        if (scrollHandler) {
          scrollHandler.scrollLeft -= 50;
        }
        else {
          instance.view.wt.scrollHorizontal(-1).draw();
        }
      }
      else if (scrollX > 0) {
        if (scrollHandler) {
          scrollHandler.scrollLeft += 50;
        }
        else {
          instance.view.wt.scrollHorizontal(1).draw();
        }
      }

      if (scrollY < 0) {
        if (scrollHandler) {
          scrollHandler.scrollTop -= 20;
        }
        else {
          instance.view.wt.scrollVertical(-1).draw();
        }
      }
      else if (scrollY > 0) {
        if (scrollHandler) {
          scrollHandler.scrollTop += 20;
        }
        else {
          instance.view.wt.scrollVertical(1).draw();
        }
      }
    });

    instance.dragToScrollListening = true;
  };

  Handsontable.hooks.add('afterInit', function () {
    var instance = this;

    $(document).on('mouseup.' + this.guid, function () {
      instance.dragToScrollListening = false;
    });

    $(document).on('mousemove.' + this.guid, function (event) {
      if (instance.dragToScrollListening) {
        dragToScroll.check(event.clientX, event.clientY);
      }
    });
  });

  Handsontable.hooks.add('afterDestroy', function () {
    $(document).off('.' + this.guid);
  });

  Handsontable.hooks.add('afterOnCellMouseDown', function () {
    setupListening(this);
  });

  Handsontable.hooks.add('afterOnCellCornerMouseDown', function () {
    setupListening(this);
  });

  Handsontable.plugins.DragToScroll = DragToScroll;
}
<|endoftext|>


<commit_before>'use strict';

const electron = require('electron');
const app = electron.app;
const shell = electron.shell;

// when we start there is no appName yet, hardcode it for now
const appName = 'snapcraft.io';

const Template = [
    {
        label: appName,
        role: 'window',
        submenu: [
            {
                label: `Quit`,
                accelerator: 'CmdorCtrl+Q',
                role: 'close'
            }
        ]
    },
    {
        label: 'Edit',
        submenu: [
            {
                label: 'Cut',
                accelerator: 'CmdOrCtrl+X',
                role: 'cut'
            },
            {
                label: 'Copy',
                accelerator: 'CmdOrCtrl+C',
                role: 'copy'
            },
            {
                label: 'Paste',
                accelerator: 'CmdOrCtrl+V',
                role: 'paste'
            },
            {
                label: 'Select All',
                accelerator: 'CmdOrCtrl+A',
                role: 'selectall'
            }
        ]
    },
    {
        label: 'Go',
        submenu: [
            {
                label: 'Back',
                accelerator: 'Alt+Left',
                click() {
                    app.BrowserWindow.getFocusedWindow().webContents.goBack();
                }
            },
            {
                label: 'Forward',
                accelerator: 'Alt+Right',
                click() {
                    app.BrowserWindow.getFocusedWindow().webContents.goForward();
                }
            },
            {
                type: 'separator'
            },
            {
                label: 'Reload',
                accelerator: 'CmdOrCtrl+R',
                role: 'reload'
            }
        ]
    },
    {
        label: 'Help',
        role: 'help',
        submenu: [
            {
                label: `https://snapcraft.io`,
                accelerator: 'CmdOrCtrl+H',
                click() {
                    shell.openExternal('https://snapcraft.io');
                }
            }
        ]
    }
];

module.exports = electron.Menu.buildFromTemplate(Template);
<commit_msg>whoops, fix an issue with the alt+right/left handling<commit_after>'use strict';

const electron = require('electron');
const app = electron;
const shell = electron.shell;

// when we start there is no appName yet, hardcode it for now
const appName = 'snapcraft.io';

const Template = [
    {
        label: appName,
        role: 'window',
        submenu: [
            {
                label: `Quit`,
                accelerator: 'CmdorCtrl+Q',
                role: 'close'
            }
        ]
    },
    {
        label: 'Edit',
        submenu: [
            {
                label: 'Cut',
                accelerator: 'CmdOrCtrl+X',
                role: 'cut'
            },
            {
                label: 'Copy',
                accelerator: 'CmdOrCtrl+C',
                role: 'copy'
            },
            {
                label: 'Paste',
                accelerator: 'CmdOrCtrl+V',
                role: 'paste'
            },
            {
                label: 'Select All',
                accelerator: 'CmdOrCtrl+A',
                role: 'selectall'
            }
        ]
    },
    {
        label: 'Go',
        submenu: [
            {
                label: 'Back',
                accelerator: 'Alt+Left',
                click() {
                    app.BrowserWindow.getFocusedWindow().webContents.goBack();
                }
            },
            {
                label: 'Forward',
                accelerator: 'Alt+Right',
                click() {
                    app.BrowserWindow.getFocusedWindow().webContents.goForward();
                }
            },
            {
                type: 'separator'
            },
            {
                label: 'Reload',
                accelerator: 'CmdOrCtrl+R',
                role: 'reload'
            }
        ]
    },
    {
        label: 'Help',
        role: 'help',
        submenu: [
            {
                label: `https://snapcraft.io`,
                accelerator: 'CmdOrCtrl+H',
                click() {
                    shell.openExternal('https://snapcraft.io');
                }
            }
        ]
    }
];

module.exports = electron.Menu.buildFromTemplate(Template);
<|endoftext|>


<commit_before>import * as utilities from '../../libs/utilities'
import scrapers from '../../scrapers/manifest'

// Basic module information
export const meta = {
    type:         'playerStat',
    subWhitelist: ['testingground4bots', 'rugbyunion']
}

// Used to determine if this module has been summond by the reddit comment
export function trigger(comment){
    return  comment.body.indexOf('!playerstats') > -1
}

// Breaks the comment down into all the data the handler will need to do it's job
export function command(comment){
    // Cut the comment up into modifiers
    let commandParts = comment.body.trim().split(/\s+/g)
    // Find where our command starts
    let commandIndex = commandParts.indexOf('!playerstats')

    console.log(commandIndex, commandParts);

    return {
        meta,
        data:      {
            'firstName':   commandParts[commandIndex+1],
            'lastName':    commandParts[commandIndex+2],
            'team':        commandParts.slice(commandIndex+3)
        }
    }
}

// The action taken if the module is triggered
export function handler(command, comment){
    //console.log('Handling player stat request', command)
    scrapers.statbunker.doSearch(`${command.data.firstName} ${command.data.lastName}`).then( results => {
        // Dont need to do anything else
        if( results.length === 0 ){
            console.log(`No results from search for ${command.data.firstName} ${command.data.lastName}`)
            comment.reply(`No results from search for ${command.data.firstName} ${command.data.lastName}. Please check spelling or [read here](https://github.com/deadlysyntax/stat_of_the_union) for more info`)
            return
        }
        // Try to find the player and get their id
        let result      = results[0]
        let playerID    = result.split('player_id=')[1]
        //
        scrapers.statbunker.getPlayerStats(playerID).then( response => {
            //
            let tableString = ''
            //console.log(command.data.team.join(' ').toLowerCase(), response);
            let stats = response.filter(team => {
                return team.type === command.data.team.join(' ').toLowerCase()
            })
            if( typeof stats[0] !== 'undefined' ){
                tableString  = utilities.convertListDataToMarkdownTable(stats[0].data, `${utilities.capitalize(command.data.firstName+' '+command.data.lastName)} | ${utilities.capitalize(stats[0].type) }`) // use to lowercase to normalize
            } else {
                console.log('Team not found')
                comment.reply('Unable to find the team info unfortunately, please check spelling or [read here](https://github.com/deadlysyntax/stat_of_the_union) for more info')
                return
            }
            // Success
            if( tableString !== null && tableString !== '' ){
                console.log('commented')
                comment.reply(tableString+ '\n ****** \n Please PM me with ideas, feedback, bot suggestions, qualms or just a bloody good story.')
            } else {
                console.log('Stats Not found')
                comment.reply('Unable to find any stats unfortunately, please check spelling or [read here](https://github.com/deadlysyntax/stat_of_the_union) for more info')
            }

        }).catch((error) => {
            comment.reply('Unable to find any stats unfortunately, this is my problem and I\'ve told my human to sort it out.')
            console.log(error);
        })
    }).catch((error) => {
        comment.reply('Unable to find any stats unfortunately, this is my problem and I\'ve told my human to sort it out.')
        console.log(error);
    })

    //comment.reply(`Retrieving stats for ${command.data.firstName} ${command.data.lastName} for ${command.data.year} ${command.data.competition.join(' ')}`)
    return null
}
<commit_msg>fix parenthesis bug<commit_after>import * as utilities from '../../libs/utilities'
import scrapers from '../../scrapers/manifest'

// Basic module information
export const meta = {
    type:         'playerStat',
    subWhitelist: ['testingground4bots', 'rugbyunion']
}

// Used to determine if this module has been summond by the reddit comment
export function trigger(comment){
    return  comment.body.indexOf('!playerstats') > -1
}

// Breaks the comment down into all the data the handler will need to do it's job
export function command(comment){
    // Cut the comment up into modifiers
    let commandParts = comment.body.trim().split(/\s+/g)
    // Find where our command starts
    let commandIndex = commandParts.indexOf('!playerstats')

    console.log(commandIndex, commandParts);

    return {
        meta,
        data:      {
            'firstName':   commandParts[commandIndex+1],
            'lastName':    commandParts[commandIndex+2],
            'team':        commandParts.slice(commandIndex+3)
        }
    }
}

// The action taken if the module is triggered
export function handler(command, comment){
    //console.log('Handling player stat request', command)
    scrapers.statbunker.doSearch(`${command.data.firstName} ${command.data.lastName}`).then( results => {
        // Dont need to do anything else
        if( results.length === 0 ){
            console.log(`No results from search for ${command.data.firstName} ${command.data.lastName}`)
            comment.reply(`No results from search for ${command.data.firstName} ${command.data.lastName}. Please check spelling or [read here](https://github.com/deadlysyntax/stat_of_the_union) for more info`)
            return
        }
        // Try to find the player and get their id
        let result      = results[0]
        let playerID    = result.split('player_id=')[1]
        //
        scrapers.statbunker.getPlayerStats(playerID).then( response => {
            //
            let tableString = ''
            //console.log(command.data.team.join(' ').toLowerCase(), response);
            let stats = response.filter(team => {
                return team.type === command.data.team.join(' ').toLowerCase()
            })
            if( typeof stats[0] !== 'undefined' ){
                tableString  = utilities.convertListDataToMarkdownTable(stats[0].data, `${utilities.capitalize(command.data.firstName+' '+command.data.lastName)} | ${utilities.capitalize(stats[0].type) }`) // use to lowercase to normalize
            } else {
                console.log('Team not found')
                comment.reply(`Unable to find stats for ${utilities.capitalize(command.data.firstName+' '+command.data.lastName)} at this team unfortunately, please check spelling or [read here](https://github.com/deadlysyntax/stat_of_the_union) for more info`)
                return
            }
            // Success
            if( tableString !== null && tableString !== '' ){
                console.log('commented')
                comment.reply(tableString+ '\n ****** \n Please PM me with ideas, feedback, bot suggestions, qualms or just a bloody good story.')
            } else {
                console.log('Stats Not found')
                comment.reply('Unable to find any stats unfortunately, please check spelling or [read here](https://github.com/deadlysyntax/stat_of_the_union) for more info')
            }

        }).catch((error) => {
            comment.reply('Unable to find any stats unfortunately, this is my problem and I\'ve told my human to sort it out.')
            console.log(error);
        })
    }).catch((error) => {
        comment.reply('Unable to find any stats unfortunately, this is my problem and I\'ve told my human to sort it out.')
        console.log(error);
    })

    //comment.reply(`Retrieving stats for ${command.data.firstName} ${command.data.lastName} for ${command.data.year} ${command.data.competition.join(' ')}`)
    return null
}
<|endoftext|>