<commit_before>const { isGit } = require('./isGit');
const { gitCheck } = require('./gitCheck');

const processDirectory = (stat, options) => {
  if (!stat || !stat.file) {
    return Promise.resolve(false);
  }
  let pathString = stat.file;

  if (!stat.stat.isDirectory()) {
    options.debug(stat.file, false);
    return Promise.resolve(false);
  }

  options.debug(stat.file);

  return Promise.resolve()
    .catch((e) => Promise.resolve(false))
    .then(() => isGit(pathString))
    .then((isDirGit) => {
      return !isDirGit
        ? new Promise((resolve) => {
            const gitStatus = options.C.emptyGitStatus;
            options.debug(stat.file, gitStatus);
            if (!options.showGitOnly) {
              options.insert(pathString, gitStatus);
              return resolve(true);
            }
            return resolve(false);
          })
        : gitCheck(pathString).then((gitStatus) => {
            gitStatus.git = true;
            options.debug(stat.file, gitStatus);
            options.insert(pathString, gitStatus);
            return Promise.resolve(true);
          });
    });
};

const processDirectories = (stats, opts) =>
  Promise.all(stats.map((status) => processDirectory(status, opts)));

module.exports = {
  processDirectory: processDirectories,
};
<commit_msg>breakdown-process-directory<commit_after>const { isGit } = require('./isGit');
const { gitCheck } = require('./gitCheck');

const processNonGitDir = (stat, options) =>
  new Promise((resolve) => {
    const gitStatus = options.C.emptyGitStatus;
    options.debug(stat.file, gitStatus);
    if (!options.showGitOnly) {
      options.insert(stat.file, gitStatus);
      return resolve(true);
    }
    return resolve(false);
  });

const processGitDir = (stat, options) =>
  gitCheck(stat.file).then((gitStatus) => {
    gitStatus.git = true;
    options.debug(stat.file, gitStatus);
    options.insert(stat.file, gitStatus);
    return Promise.resolve(true);
  });

const processDirectory = (stat, options) => {
  if (!stat || !stat.file) {
    return Promise.resolve(false);
  }

  if (!stat.stat.isDirectory()) {
    options.debug(stat.file, false);
    return Promise.resolve(false);
  }

  options.debug(stat.file);

  return Promise.resolve()
    .catch((e) => Promise.resolve(false))
    .then(() => isGit(stat.file))
    .then((isDirGit) =>
      !isDirGit ? processNonGitDir(stat, options) : processGitDir(stat, options)
    );
};

const processDirectories = (stats, opts) =>
  Promise.all(stats.map((status) => processDirectory(status, opts)));

module.exports = {
  processDirectory: processDirectories,
};
<|endoftext|>


<commit_before>/**
 * concern.js
 *
 * !concern
 * Toggles whether the bot should interrupt charged conversations
 * with an unhelpful message.
 */
var isEmotional = require('emotional_alert')
var nox = false
var colors = require('irc').colors
var verbose = false // TODO: cvar

module.exports = {
  commands: {
    sentiment: {
      help: 'Runs a phrase through very nuanced sentiment analysis',
      command: (bot, msg) => {
        let result = isEmotional(msg.body)
        if (result.bayes) {
          let percentage = (result.bayes.proba * 100).toFixed(2)
          return [
            result.bayes.prediction,
            colors.wrap('light_gray', `(${percentage}%)`)
          ].join(' ')
        }
        return 'no sentiment found'
      }
    },
    rawconcern: {
      help: 'Runs a phrase through the emotional alert system',
      command: (bot, msg) => {
        return JSON.stringify(isEmotional(msg.body))
      }
    },
    concern: {
      help: 'Toggles announcements of concern',
      command: function () {
        if (!nox) {
          nox = true
          return 'adopting air of unconcern'
        }
        nox = false
        return 'concerning myself with matters'
      }
    }
  },
  events: {
    message: function (bot, nick, to, text) {
      if (!nox) {
        var x = isEmotional(text)
        if (x.emotional) {
          if (x.winner) {
            var adj = {
              0: '',
              1: 'slightly ',
              2: 'rather ',
              3: 'quite ',
              4: 'very ',
              5: 'extremely ',
              6: 'copiously ',
              7: 'agonizingly '
            }
            x.adj = adj[x.emotional] === undefined ? 'a tad ' : adj[x.emotional]
            switch (x.winner) {
              case 'anger':
                x.hwinner = 'angry'
                break
              case 'stress':
                x.hwinner = 'stressed'
                break
              case 'sad':
                /* falls through */
              default:
                x.hwinner = x.winner
            }

            bot.shout(to, nick + ': you seem ' + x.adj + x.hwinner + ' (score: ' + x.emotional + ')')
          } else if (verbose) { // danger phrase
            bot.shout(to, nick + ': that is a worrying thing to say')
          }
        }
      }
    }
  }
}
<commit_msg>Alias !rawconcern and !rawsentiment<commit_after>/**
 * concern.js
 *
 * !concern
 * Toggles whether the bot should interrupt charged conversations
 * with an unhelpful message.
 */
var isEmotional = require('emotional_alert')
var nox = false
var colors = require('irc').colors
var verbose = false // TODO: cvar

module.exports = {
  commands: {
    sentiment: {
      help: 'Runs a phrase through very nuanced sentiment analysis',
      command: (bot, msg) => {
        let result = isEmotional(msg.body)
        if (result.bayes) {
          let percentage = (result.bayes.proba * 100).toFixed(2)
          return [
            result.bayes.prediction,
            colors.wrap('light_gray', `(${percentage}%)`)
          ].join(' ')
        }
        return 'no sentiment found'
      }
    },
    rawconcern: {
      aliases: [ 'rawsentiment' ],
      help: 'Runs a phrase through the emotional alert system',
      command: (bot, msg) => {
        return JSON.stringify(isEmotional(msg.body))
      }
    },
    concern: {
      help: 'Toggles announcements of concern',
      command: function () {
        if (!nox) {
          nox = true
          return 'adopting air of unconcern'
        }
        nox = false
        return 'concerning myself with matters'
      }
    }
  },
  events: {
    message: function (bot, nick, to, text) {
      if (!nox) {
        var x = isEmotional(text)
        if (x.emotional) {
          if (x.winner) {
            var adj = {
              0: '',
              1: 'slightly ',
              2: 'rather ',
              3: 'quite ',
              4: 'very ',
              5: 'extremely ',
              6: 'copiously ',
              7: 'agonizingly '
            }
            x.adj = adj[x.emotional] === undefined ? 'a tad ' : adj[x.emotional]
            switch (x.winner) {
              case 'anger':
                x.hwinner = 'angry'
                break
              case 'stress':
                x.hwinner = 'stressed'
                break
              case 'sad':
                /* falls through */
              default:
                x.hwinner = x.winner
            }

            bot.shout(to, nick + ': you seem ' + x.adj + x.hwinner + ' (score: ' + x.emotional + ')')
          } else if (verbose) { // danger phrase
            bot.shout(to, nick + ': that is a worrying thing to say')
          }
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

const bl             = require('bl')
    , split2         = require('split2')
    , list           = require('list-stream')
    , fs             = require('fs')
    , path           = require('path')
    , chalk          = require('chalk')
    , pkgtoId        = require('pkg-to-id')
    , commitStream   = require('commit-stream')
    , gitexec        = require('gitexec')
    , commitToOutput = require('./commit-to-output')
    , groupCommits   = require('./group-commits')
    , collectCommitLabels = require('./collect-commit-labels')

    , argv           = require('minimist')(process.argv.slice(2))

    , quiet          = argv.quiet || argv.q
    , simple         = argv.simple || argv.s

    , pkg            = require('./package.json')
    , debug          = require('debug')(pkg.name)

    , pkgFile        = path.join(process.cwd(), 'package.json')
    , pkgData        = fs.existsSync(pkgFile) ? require(pkgFile) : {}
    , pkgId          = pkgtoId(pkgData)

    , ghId           = {
          user: argv._[0] || pkgId.user || 'nodejs'
        , name: argv._[1] || stripScope(pkgId.name) || 'node'
      }

const gitcmd         = 'git log --pretty=full --since="{{sincecmd}}" --until="{{untilcmd}}"'
    , commitdatecmd  = '$(git show -s --format=%cd `{{refcmd}}`)'
    , untilcmd       = ''
    , refcmd         = argv.a || argv.all ? 'git rev-list --max-parents=0 HEAD' : 'git rev-list --max-count=1 {{ref}}'
    , defaultRef     = '--tags=v*.*.* 2> /dev/null ' +
        '|| git rev-list --max-count=1 --tags=*.*.* 2> /dev/null ' +
        '|| git rev-list --max-count=1 HEAD'

debug(ghId)

function stripScope (name) {
  return name[0] === '@' && name.indexOf('/') > 0 ? name.split('/')[1] : name
}

function replace (s, m) {
  Object.keys(m).forEach(function (k) {
    s = s.replace(new RegExp('\\{\\{' + k + '\\}\\}', 'g'), m[k])
  })
  return s
}

function organiseCommits (list) {
  if (argv['start-ref'])
    return list
  else if (argv.a || argv.all)
    return list

  // filter commits to those _before_ 'working on ...'
  var started = false
  return list.filter(function (commit) {
    if (started)
      return false

    if ((/working on v?[\d\.]+/i).test(commit.summary))
      started = true
    else if ((/^v?[\d\.]+$/).test(commit.summary))
      started = true

    return !started
  })
}

function printCommits (list) {
  var out = list.join('\n') + '\n'

  if (!process.stdout.isTTY)
    out = chalk.stripColor(out)

  process.stdout.write(out)
}

function onCommitList (err, list) {
  if (err)
    throw err

  list = organiseCommits(list)

  collectCommitLabels(list, function (err) {
    if (err)
      throw err

    if (argv.group)
      list = groupCommits(list)

    list = list.map(function (commit) {
      return commitToOutput(commit, simple, ghId)
    })

    if (!quiet)
      printCommits(list)
  })
}

var _startrefcmd = replace(refcmd, { ref: argv['start-ref'] || defaultRef })
  , _endrefcmd   = argv['end-ref'] && replace(refcmd, { ref: argv['end-ref'] })
  , _sincecmd    = replace(commitdatecmd, { refcmd: _startrefcmd })
  , _untilcmd    = argv['end-ref'] ? replace(commitdatecmd, { refcmd: _endrefcmd }) : untilcmd
  , _gitcmd      = replace(gitcmd, { sincecmd: _sincecmd, untilcmd: _untilcmd })

debug('%s', _startrefcmd)
debug('%s', _endrefcmd)
debug('%s', _sincecmd)
debug('%s', _untilcmd)
debug('%s', _gitcmd)

gitexec.exec(process.cwd(), _gitcmd)
  .pipe(split2())
  .pipe(commitStream(ghId.user, ghId.name))
  .pipe(list.obj(onCommitList))
<commit_msg>fix bug with stripScope not having a `name` to deal with<commit_after>#!/usr/bin/env node

const bl             = require('bl')
    , split2         = require('split2')
    , list           = require('list-stream')
    , fs             = require('fs')
    , path           = require('path')
    , chalk          = require('chalk')
    , pkgtoId        = require('pkg-to-id')
    , commitStream   = require('commit-stream')
    , gitexec        = require('gitexec')
    , commitToOutput = require('./commit-to-output')
    , groupCommits   = require('./group-commits')
    , collectCommitLabels = require('./collect-commit-labels')

    , argv           = require('minimist')(process.argv.slice(2))

    , quiet          = argv.quiet || argv.q
    , simple         = argv.simple || argv.s

    , pkg            = require('./package.json')
    , debug          = require('debug')(pkg.name)

    , pkgFile        = path.join(process.cwd(), 'package.json')
    , pkgData        = fs.existsSync(pkgFile) ? require(pkgFile) : {}
    , pkgId          = pkgtoId(pkgData)

    , ghId           = {
          user: argv._[0] || pkgId.user || 'nodejs'
        , name: argv._[1] || (pkgId.name && stripScope(pkgId.name)) || 'node'
      }

const gitcmd         = 'git log --pretty=full --since="{{sincecmd}}" --until="{{untilcmd}}"'
    , commitdatecmd  = '$(git show -s --format=%cd `{{refcmd}}`)'
    , untilcmd       = ''
    , refcmd         = argv.a || argv.all ? 'git rev-list --max-parents=0 HEAD' : 'git rev-list --max-count=1 {{ref}}'
    , defaultRef     = '--tags=v*.*.* 2> /dev/null ' +
        '|| git rev-list --max-count=1 --tags=*.*.* 2> /dev/null ' +
        '|| git rev-list --max-count=1 HEAD'

debug(ghId)

function stripScope (name) {
  return name[0] === '@' && name.indexOf('/') > 0 ? name.split('/')[1] : name
}

function replace (s, m) {
  Object.keys(m).forEach(function (k) {
    s = s.replace(new RegExp('\\{\\{' + k + '\\}\\}', 'g'), m[k])
  })
  return s
}

function organiseCommits (list) {
  if (argv['start-ref'])
    return list
  else if (argv.a || argv.all)
    return list

  // filter commits to those _before_ 'working on ...'
  var started = false
  return list.filter(function (commit) {
    if (started)
      return false

    if ((/working on v?[\d\.]+/i).test(commit.summary))
      started = true
    else if ((/^v?[\d\.]+$/).test(commit.summary))
      started = true

    return !started
  })
}

function printCommits (list) {
  var out = list.join('\n') + '\n'

  if (!process.stdout.isTTY)
    out = chalk.stripColor(out)

  process.stdout.write(out)
}

function onCommitList (err, list) {
  if (err)
    throw err

  list = organiseCommits(list)

  collectCommitLabels(list, function (err) {
    if (err)
      throw err

    if (argv.group)
      list = groupCommits(list)

    list = list.map(function (commit) {
      return commitToOutput(commit, simple, ghId)
    })

    if (!quiet)
      printCommits(list)
  })
}

var _startrefcmd = replace(refcmd, { ref: argv['start-ref'] || defaultRef })
  , _endrefcmd   = argv['end-ref'] && replace(refcmd, { ref: argv['end-ref'] })
  , _sincecmd    = replace(commitdatecmd, { refcmd: _startrefcmd })
  , _untilcmd    = argv['end-ref'] ? replace(commitdatecmd, { refcmd: _endrefcmd }) : untilcmd
  , _gitcmd      = replace(gitcmd, { sincecmd: _sincecmd, untilcmd: _untilcmd })

debug('%s', _startrefcmd)
debug('%s', _endrefcmd)
debug('%s', _sincecmd)
debug('%s', _untilcmd)
debug('%s', _gitcmd)

gitexec.exec(process.cwd(), _gitcmd)
  .pipe(split2())
  .pipe(commitStream(ghId.user, ghId.name))
  .pipe(list.obj(onCommitList))
<|endoftext|>


<commit_before>var util = require('../src/util/seeds');

exports.seed = function(knex, Promise) {
  const cities = {};

  return knex('cities').select('*')
  .then(rows => {
    rows.forEach(city => {
      cities[city.name] = city.id;
    });
  })
  .then(() => util.insertOrUpdate(knex, 'radios', {
    id: 1,
    name: 'Rakkauden Wappuradio',
    city_id: cities['Tampere'],
    // stream: 'http://stream.wappuradio.fi/wappuradio.mp3',
    stream: null,
    website: 'https://wappuradio.fi/',
  }))
  .then(() => util.insertOrUpdate(knex, 'radios', {
    id: 2,
    name: 'Radiodiodi',
    city_id: cities['Otaniemi'],
    stream: 'http://virta.radiodiodi.fi/',
    website: 'https://radiodiodi.fi/',
  }));
}
<commit_msg>Corrected stream url<commit_after>var util = require('../src/util/seeds');

exports.seed = function(knex, Promise) {
  const cities = {};

  return knex('cities').select('*')
  .then(rows => {
    rows.forEach(city => {
      cities[city.name] = city.id;
    });
  })
  .then(() => util.insertOrUpdate(knex, 'radios', {
    id: 1,
    name: 'Rakkauden Wappuradio',
    city_id: cities['Tampere'],
    // stream: 'http://stream.wappuradio.fi/wappuradio.mp3',
    stream: null,
    website: 'https://wappuradio.fi/',
  }))
  .then(() => util.insertOrUpdate(knex, 'radios', {
    id: 2,
    name: 'Radiodiodi',
    city_id: cities['Otaniemi'],
    stream: 'http://virta.radiodiodi.fi/stream.mp3',
    website: 'https://radiodiodi.fi/',
  }));
}
<|endoftext|>


<commit_before>/**
  window.BMP.BIC

  The Blink Intelligent Client

  @module BIC
*/
define(function (require) {
  'use strict';

  // foreign modules

  var $ = require('jquery');
  var _ = require('underscore');
  var Backbone = require('backbone');
  var Promise = require('bic/promise');

  // local modules

  var InteractionCollection = require('bic/collection/interactions');
  var DataSuitcaseCollection = require('bic/collection/datasuitcases');
  var FormCollection = require('bic/collection/forms');
  var PendingCollection = require('bic/collection/pending');
  var FormRecordsCollection = require('bic/collection/form-records');
  var StarsCollection = require('bic/collection/stars');

  var c = require('bic/console');
  var facade = require('bic/facade');
  var API = require('bic/api');
  var metaStore = require('bic/store-meta');
  var loadForms = require('bic/promise-forms');

  // this module

  var singleton, Application;

  require('jquerymobile');

  /**
    The Blink Intelligent Client

    @class
    @alias window.BMP.BIC
  */
  Application = Backbone.Model.extend({

    idAttribute: '_id',

    /**
     * @property {string} _id - The Answer space id
     * @property {string} siteName - The site name
     * @property {string} loginStatus - If the user is logged in or logged out
     * @property {boolean} displayErrorSummary - controls the error summary display
     * @property {string} defaultTransition - 'fade'. See http://api.jquerymobile.com/1.3/global-config/
     * @property {string} recordNotFoundMessage - A Message to display to the user when a requested record is not found on the server.
     */
    defaults: {
      _id: window.BMP.BIC.siteVars.answerSpace.toLowerCase(),
      loginStatus: '',
      displayErrorSummary: true,
      siteName: '',

      homeScreen: null,
      homeInteraction: null,

      defaultTransition: 'fade',
      recordNotFoundMessage: 'The requested record does not exist'

    },

    /**
      Takes a user to an interaction.

      @param {string} interactionPath The url path to the interaction,
      relative to the answer space. A falsy value will take you to home.
      A preceeding slash can be ommitted

      @example
Both of these will take you to the same place.

      window.BMP.BIC.goToInteraction('shops/review/add_review');
      window.BMP.BIC.goToInteraction('/shops/review/add_review');
    */
    goToInteraction: function (interactionPath) {
      var answerSpace = this.get('siteName') || '';

      interactionPath = _.compact((interactionPath || '').split('/'));
      if (!interactionPath.length || interactionPath[0].toLowerCase() !== answerSpace.toLowerCase()) {
        interactionPath.unshift(answerSpace);
      }

      $.mobile.changePage('/' + interactionPath.join('/'));
    },

    hasHomeInteraction: function () {
      var app = this;
      if (app.has('homeScreen') && app.get('homeScreen') !== false && app.has('homeInteraction')) {
        return true;
      }
      return false;
    },

    collections: function () {
      var app = this;

      if (this.collections._promise) {
        // return a cached promise when possible
        return this.collections._promise;
      }

      this.collections._promise = new Promise(function (resolve, reject) {
        app.interactions = app.interactions || new InteractionCollection();
        app.datasuitcases = app.datasuitcases || new DataSuitcaseCollection();
        app.forms = app.forms || new FormCollection();
        app.stars = app.stars || new StarsCollection();
        app.formRecords = app.formRecords || new FormRecordsCollection();

        // prime models / collections with previous persisted data
        Promise.all([
          // loading these causes storage detection results to be finalised
          app.interactions.datastore().load(),
          app.datasuitcases.datastore().load(),
          app.forms.datastore().load(),
          app.stars.datastore().load(),
          app.formRecords.datastore().load()
        ])
        .then(function () {
          // now it is safe to use .hasStorage()
          if (app.hasStorage()) {
            // enable the pending queue
            app.pending = app.pending || new PendingCollection();
            return app.pending.datastore().load();
          }
          return Promise.resolve();
        })
        .then(resolve, reject);
      });

      return this.collections._promise;
    },

    setup: function () {
      var app = this;

      facade.subscribe('applicationModel', 'loggedIn', function () {
        app.set('loginStatus', 'LOGGED IN');
        app.trigger('loginProcessed');
      });

      facade.subscribe('applicationModel', 'loggedOut', function () {
        app.set('loginStatus', 'LOGGED OUT');
        app.trigger('loginProcessed');
      });

      c.log('app.setup(): done');
      return Promise.resolve();
    },

    populate: function () {
      var app = this;
      if (!(navigator.onLine || BMP.BlinkGap.isHere())) {
        c.debug('app.populate(): quit early');
        return Promise.resolve();
      }

      return app.collections()
        .then(null, function () {
          return null;
        })
        .then(function () {
          if (app.get('username')) {
            return Promise.resolve(API.getAnswerSpaceMap(app.get('username')));
          }
          return Promise.resolve(API.getAnswerSpaceMap());
        })
        .then(
          function (data) {
            if (data && typeof data === 'string') {
              try {
                data = JSON.parse(data);
              } catch (err) {
                /* eslint-disable no-console */
                console.error('unable to parse answerSpace map');
                console.error(err);
                /* eslint-enable no-console */
              }
            }
            return Promise.all(_.compact(_.map(data, function (value, key) {
              var model;
              model = value.pertinent;
              if (!model) {
                return null; // e.g. "map" property of GetConfig XHR JSON
              }
              model.dbid = key;
              if (key.substr(0, 1) === 'c' || key.substr(0, 1) === 'i') {
                model._id = model.name.toLowerCase();
                app.interactions.add(model, {merge: true});
                return model._id;
              }
              if (key.substr(0, 1) === 'a') {
                model._id = window.BMP.BIC.siteVars.answerSpace.toLowerCase();
                return new Promise(function (resolve) {
                  app.interactions.add(model, {merge: true});
                  app.set(model);
                  resolve(window.BMP.BIC.siteVars.answerSpace.toLowerCase());
                });
              }
            })));
          }
       )
        .then(
          function (interactions) {
            return Promise.all(
              _.map(
                _.reject(app.interactions.models, function (model) {
                  return _.contains(interactions, model.id);
                }
             ),
              function (model) {
                if (!app.hasStorage()) {
                  app.interactions.remove(model);
                  return Promise.resolve();
                }
                return new Promise(function (resolve, reject) {
                  model.destroy({
                    success: resolve,
                    error: reject
                  });
                });
              }
           ));
          }
       )
        .then(
          function () {
            loadForms();
            app.forms.whenUpdated();
            app.retrieveDataSuitcasesForInteractions();
            c.log('app.populate(): done');
            c.debug('app.populate(): interactions.length: ' + app.interactions.length);
            if (!app.hasStorage()) {
              return Promise.resolve();
            }
            return app.interactions.save();
          }
       );
    },

    retrieveDataSuitcasesForInteractions: function () {
      var app = this;
      return Promise.all(
        _.map(_.compact(_.uniq(app.interactions.pluck('xml'))),
        function (element) {
          return new Promise(function (resolve) { // args.[1] 'reject'
            if (!app.datasuitcases.get(element)) {
              app.datasuitcases.add({_id: element});
              app.datasuitcases.get(element).populate().then(resolve, resolve);
            } else {
              app.datasuitcases.get(element).populate().then(resolve, resolve);
            }
          });
        })
     )
      .then(function () {
        return app.datasuitcases.save();
      });
    },

    whenPopulated: function () {
      var me = this;
      return new Promise(function (resolve, reject) {
        me.collections().then(function () {
          var timeout;
          if (me.interactions.length) {
            c.info('app.whenPopulated(): done');
            resolve();
          } else {
            me.interactions.once('add', function () {
              clearTimeout(timeout);
              c.info('app.whenPopulated(): done');
              resolve();
            });
            timeout = setTimeout(function () {
              c.error('app.whenPopulated(): timeout');
              reject(new Error('whenPopulated timed out after 20 seconds'));
            }, 20e3);
          }
        }, function () {
          c.error('app.whenPopulated(): #collections() error');
          reject(new Error('whenPopulated failed due to collections'));
        });
      });
    },

    checkLoginStatus: function () {
      // false
      var app = this;

      return new Promise(function (resolve) {
        API.getLoginStatus().then(function (data) {
          var status = data.status || data;

          if (status = 'LOGGED IN' && data.username) {
            app.set({username: data.username});
          } else {
            app.unset('username');
          }
          if (app.get('loginStatus') !== status) {
            app.populate().then(function () {
              app.set({loginStatus: status});
              resolve();
            });
          } else {
            resolve();
          }
        });
      });
    },

    initialRender: function () {
      var app = this;

      $.mobile.defaultPageTransition = app.get('defaultTransition');
      $.mobile.changePage($.mobile.path.parseLocation().href, {
        changeHash: false,
        reloadPage: true,
        transition: 'fade'
      });
      $(document).one('pageshow', function () {
        $('#temp').remove();
      });
    },

    hasStorage: function () {
      var col = this.interactions;
      if (col && col.data && col.data.ready && col.data.hasStorage) {
        return col.data.hasStorage();
      }
      c.warn('hasStorage() called before detection complete');
      return false;
    }

  });

  singleton = new Application();

  if (window.BMP.BIC) {
    $.extend(singleton, window.BMP.BIC);
  }

  singleton.history = { length: 0 };

  window.onpopstate = function () {
    singleton.history.length += 1;
  };

  singleton.meta = metaStore;

  singleton.views = {
    FormControls: null,
    FormList: null,
    FormErrorSummary: null,
    FormPending: null
  };

  return singleton;
});
<commit_msg>BIC-217 Login doesn't allow access to interactions for up to 30 seconds<commit_after>/**
  window.BMP.BIC

  The Blink Intelligent Client

  @module BIC
*/
define(function (require) {
  'use strict';

  // foreign modules

  var $ = require('jquery');
  var _ = require('underscore');
  var Backbone = require('backbone');
  var Promise = require('bic/promise');

  // local modules

  var InteractionCollection = require('bic/collection/interactions');
  var DataSuitcaseCollection = require('bic/collection/datasuitcases');
  var FormCollection = require('bic/collection/forms');
  var PendingCollection = require('bic/collection/pending');
  var FormRecordsCollection = require('bic/collection/form-records');
  var StarsCollection = require('bic/collection/stars');

  var c = require('bic/console');
  var facade = require('bic/facade');
  var API = require('bic/api');
  var metaStore = require('bic/store-meta');
  var loadForms = require('bic/promise-forms');

  // this module

  var singleton, Application;

  require('jquerymobile');

  /**
    The Blink Intelligent Client

    @class
    @alias window.BMP.BIC
  */
  Application = Backbone.Model.extend({

    idAttribute: '_id',

    /**
     * @property {string} _id - The Answer space id
     * @property {string} siteName - The site name
     * @property {string} loginStatus - If the user is logged in or logged out
     * @property {boolean} displayErrorSummary - controls the error summary display
     * @property {string} defaultTransition - 'fade'. See http://api.jquerymobile.com/1.3/global-config/
     * @property {string} recordNotFoundMessage - A Message to display to the user when a requested record is not found on the server.
     */
    defaults: {
      _id: window.BMP.BIC.siteVars.answerSpace.toLowerCase(),
      loginStatus: '',
      displayErrorSummary: true,
      siteName: '',

      homeScreen: null,
      homeInteraction: null,

      defaultTransition: 'fade',
      recordNotFoundMessage: 'The requested record does not exist'

    },

    /**
      Takes a user to an interaction.

      @param {string} interactionPath The url path to the interaction,
      relative to the answer space. A falsy value will take you to home.
      A preceeding slash can be ommitted

      @example
Both of these will take you to the same place.

      window.BMP.BIC.goToInteraction('shops/review/add_review');
      window.BMP.BIC.goToInteraction('/shops/review/add_review');
    */
    goToInteraction: function (interactionPath) {
      var answerSpace = this.get('siteName') || '';

      interactionPath = _.compact((interactionPath || '').split('/'));
      if (!interactionPath.length || interactionPath[0].toLowerCase() !== answerSpace.toLowerCase()) {
        interactionPath.unshift(answerSpace);
      }

      $.mobile.changePage('/' + interactionPath.join('/'));
    },

    hasHomeInteraction: function () {
      var app = this;
      if (app.has('homeScreen') && app.get('homeScreen') !== false && app.has('homeInteraction')) {
        return true;
      }
      return false;
    },

    collections: function () {
      var app = this;

      if (this.collections._promise) {
        // return a cached promise when possible
        return this.collections._promise;
      }

      this.collections._promise = new Promise(function (resolve, reject) {
        app.interactions = app.interactions || new InteractionCollection();
        app.datasuitcases = app.datasuitcases || new DataSuitcaseCollection();
        app.forms = app.forms || new FormCollection();
        app.stars = app.stars || new StarsCollection();
        app.formRecords = app.formRecords || new FormRecordsCollection();

        // prime models / collections with previous persisted data
        Promise.all([
          // loading these causes storage detection results to be finalised
          app.interactions.datastore().load(),
          app.datasuitcases.datastore().load(),
          app.forms.datastore().load(),
          app.stars.datastore().load(),
          app.formRecords.datastore().load()
        ])
        .then(function () {
          // now it is safe to use .hasStorage()
          if (app.hasStorage()) {
            // enable the pending queue
            app.pending = app.pending || new PendingCollection();
            return app.pending.datastore().load();
          }
          return Promise.resolve();
        })
        .then(resolve, reject);
      });

      return this.collections._promise;
    },

    setup: function () {
      var app = this;

      facade.subscribe('applicationModel', 'loggedIn', function () {
        app.set('loginStatus', 'LOGGED IN');
        app.trigger('loginProcessed');
      });

      facade.subscribe('applicationModel', 'loggedOut', function () {
        app.set('loginStatus', 'LOGGED OUT');
        app.trigger('loginProcessed');
      });

      c.log('app.setup(): done');
      return Promise.resolve();
    },

    populate: function () {
      var app = this;
      if (!(navigator.onLine || BMP.BlinkGap.isHere())) {
        c.debug('app.populate(): quit early');
        return Promise.resolve();
      }

      return app.collections()
        .then(null, function () {
          return null;
        })
        .then(function () {
          if (app.get('username')) {
            return Promise.resolve(API.getAnswerSpaceMap(app.get('username')));
          }
          return Promise.resolve(API.getAnswerSpaceMap());
        })
        .then(
          function (data) {
            if (data && typeof data === 'string') {
              try {
                data = JSON.parse(data);
              } catch (err) {
                /* eslint-disable no-console */
                console.error('unable to parse answerSpace map');
                console.error(err);
                /* eslint-enable no-console */
              }
            }
            return Promise.all(_.compact(_.map(data, function (value, key) {
              var model;
              model = value.pertinent;
              if (!model) {
                return null; // e.g. "map" property of GetConfig XHR JSON
              }
              model.dbid = key;
              if (key.substr(0, 1) === 'c' || key.substr(0, 1) === 'i') {
                model._id = model.name.toLowerCase();
                app.interactions.add(model, {merge: true});
                return model._id;
              }
              if (key.substr(0, 1) === 'a') {
                model._id = window.BMP.BIC.siteVars.answerSpace.toLowerCase();
                return new Promise(function (resolve) {
                  app.interactions.add(model, {merge: true});
                  app.set(model);
                  resolve(window.BMP.BIC.siteVars.answerSpace.toLowerCase());
                });
              }
            })));
          }
       )
        .then(
          function (interactions) {
            return Promise.all(
              _.map(
                _.reject(app.interactions.models, function (model) {
                  return _.contains(interactions, model.id);
                }
             ),
              function (model) {
                if (!app.hasStorage()) {
                  app.interactions.remove(model);
                  return Promise.resolve();
                }
                return new Promise(function (resolve, reject) {
                  model.destroy({
                    success: resolve,
                    error: reject
                  });
                });
              }
           ));
          }
       )
        .then(
          function () {
            loadForms();
            app.forms.whenUpdated();
            app.retrieveDataSuitcasesForInteractions();
            c.log('app.populate(): done');
            c.debug('app.populate(): interactions.length: ' + app.interactions.length);
            if (!app.hasStorage()) {
              return Promise.resolve();
            }
            return app.interactions.save();
          }
       );
    },

    retrieveDataSuitcasesForInteractions: function () {
      var app = this;
      return Promise.all(
        _.map(_.compact(_.uniq(app.interactions.pluck('xml'))),
        function (element) {
          return new Promise(function (resolve) { // args.[1] 'reject'
            if (!app.datasuitcases.get(element)) {
              app.datasuitcases.add({_id: element});
              app.datasuitcases.get(element).populate().then(resolve, resolve);
            } else {
              app.datasuitcases.get(element).populate().then(resolve, resolve);
            }
          });
        })
     )
      .then(function () {
        return app.datasuitcases.save();
      });
    },

    whenPopulated: function () {
      var me = this;
      return new Promise(function (resolve, reject) {
        me.collections().then(function () {
          var timeout;
          if (me.interactions.length) {
            c.info('app.whenPopulated(): done');
            resolve();
          } else {
            me.interactions.once('add', function () {
              clearTimeout(timeout);
              c.info('app.whenPopulated(): done');
              resolve();
            });
            timeout = setTimeout(function () {
              c.error('app.whenPopulated(): timeout');
              reject(new Error('whenPopulated timed out after 20 seconds'));
            }, 20e3);
          }
        }, function () {
          c.error('app.whenPopulated(): #collections() error');
          reject(new Error('whenPopulated failed due to collections'));
        });
      });
    },

    checkLoginStatus: function () {
      // false
      var app = this;

      return new Promise(function (resolve) {
        API.getLoginStatus().then(function (data) {
          var status = data.status || data;

          if (status === 'LOGGED IN' && data.username) {
            app.set({username: data.username});
          } else {
            app.unset('username');
          }
          if (app.get('loginStatus') !== status) {
            app.populate().then(function () {
              app.set({loginStatus: status});
              resolve();
            });
          } else {
            resolve();
          }
        });
      });
    },

    initialRender: function () {
      var app = this;

      $.mobile.defaultPageTransition = app.get('defaultTransition');
      $.mobile.changePage($.mobile.path.parseLocation().href, {
        changeHash: false,
        reloadPage: true,
        transition: 'fade'
      });
      $(document).one('pageshow', function () {
        $('#temp').remove();
      });
    },

    hasStorage: function () {
      var col = this.interactions;
      if (col && col.data && col.data.ready && col.data.hasStorage) {
        return col.data.hasStorage();
      }
      c.warn('hasStorage() called before detection complete');
      return false;
    }

  });

  singleton = new Application();

  if (window.BMP.BIC) {
    $.extend(singleton, window.BMP.BIC);
  }

  singleton.history = { length: 0 };

  window.onpopstate = function () {
    singleton.history.length += 1;
  };

  singleton.meta = metaStore;

  singleton.views = {
    FormControls: null,
    FormList: null,
    FormErrorSummary: null,
    FormPending: null
  };

  return singleton;
});
<|endoftext|>


<commit_before>$(document).ready(function() {
    generateButtons();

    $('#letters button').click(function() {
        console.log($(this).attr('value'));
    });
});

function generateButtons() {
    var snippet = "";

    for (var i = 0; i < 26; i++) {
        snippet += '<button type="button" class="btn btn-default" value="' + String.fromCharCode(65 + i) + '">' + String.fromCharCode(65 + i) + '</button>'
    }

    $('#letters').html(snippet);
}<commit_msg>Added guess method.<commit_after>var word = "BUTT";

$(document).ready(function() {
    generateButtons();

    $('#letters button').click(function() {
        var guess = $(this).attr('value');

        guessLetter(guess);
    });
});

function generateButtons() {
    var snippet = "";

    for (var i = 0; i < 26; i++) {
        snippet += '<button type="button" class="btn btn-default" value="' + String.fromCharCode(65 + i) + '">' + String.fromCharCode(65 + i) + '</button>'
    }

    $('#letters').html(snippet);
};

function guessLetter(guess) {
    if (word.indexOf(guess) !== -1) {
        console.log(true);
    } else {

    }
};<|endoftext|>


<commit_before>/**
 * Base URL utilities for the Ajax.org Cloud IDE
 *
 * Access via require("c9/urls").
 *
 * @copyright 2015, Ajax.org B.V.
 */

var plugin = module.exports = main;
var assert = require("assert");

plugin.consumes = ["error.logger"];
plugin.provides = ["urls"];

var errorLogger = mockErrorLogger;

function main(options, imports, register) {
    errorLogger = imports["error.logger"];

    register(null, {
        urls: plugin
    });
}

/**
 * Get a desired base URL, given some context.
 *
 * @param req                             The current request object or URL
 * @param {String} sourceUrlPattern       The source URL pattern, e.g. https://ide.$DOMAIN
 * @param {String} [targetBaseUrlPattern] The target URL pattern, e.g. https://$DOMAIN
 */
plugin.getBaseUrl = function(req, sourceBaseUrlPattern, targetBaseUrlPattern) {
    var sourceHost = req.headers && req.headers.host || req.host || req;
    var sourceHostMatcher = sourceBaseUrlPattern
        .replace(/^https?:\/\//, "")
        .replace(/\/.*/, "")
        .replace("$DOMAIN", "([^/]+)");
    var hostMatch = sourceHost.match(sourceHostMatcher);
    if (!hostMatch) {
        errorLogger.log(new Error("Could not construct URL: request host "
            + sourceHost + " should match " + sourceBaseUrlPattern));
        return replaceDomain(targetBaseUrlPattern || sourceBaseUrlPattern, "c9.io")
            .replace(/\/$/, "");
    }

    return replaceDomain(targetBaseUrlPattern || sourceBaseUrlPattern, hostMatch[1])
        .replace(/\/$/, "");;
};

plugin.replaceDomains = function(settings, domains) {
    domains = Array.isArray(domains) ? domains : domains.split(",");
    var primaryDomain = domains[0];
    settings.domains = domains;
    settings.primaryDomain = replaceDomain(settings.primaryDomain || "$DOMAIN", primaryDomain);
    settings.primaryBaseUrl = replaceDomain(settings.primaryBaseUrl || "https://$DOMAIN", primaryDomain);
    for (var s in settings) {
        if (!settings[s])
            continue;
        if (settings[s].baseUrl)
            settings[s].baseUrl = replaceDomain(settings[s].baseUrl, primaryDomain);
        if (settings[s].primaryBaseUrl)
            settings[s].primaryBaseUrl = replaceDomain(settings[s].primaryBaseUrl, primaryDomain);
        if (settings[s].baseUrls) {
            assert(settings[s].baseUrls.length === 1);
            settings[s].baseUrls = domains.map(function(d) {
                return replaceDomain(settings[s].baseUrls[0], d);
            });
        }
    }
};

function replaceDomain(url, domain) {
    return url.replace("$DOMAIN", domain);
}

function mockErrorLogger() {}
mockErrorLogger.log = function(err) {
    console.error(err.stack);
};
plugin.mockErrorLogger = mockErrorLogger;
<commit_msg>Make profile client multi-domain aware<commit_after>/**
 * Base URL utilities for the Ajax.org Cloud IDE
 *
 * Access via require("c9/urls").
 *
 * @copyright 2015, Ajax.org B.V.
 */

var plugin = module.exports = main;
var assert = require("assert");

plugin.consumes = ["error.logger"];
plugin.provides = ["urls"];

var errorLogger = mockErrorLogger;

function main(options, imports, register) {
    errorLogger = imports["error.logger"];

    register(null, {
        urls: plugin
    });
}

/**
 * Get a desired base URL, given some context.
 *
 * @param req                             The current request object or URL
 * @param {String} sourceUrlPattern       The source URL pattern, e.g. https://ide.$DOMAIN
 * @param {String} [targetBaseUrlPattern] The target URL pattern, e.g. https://$DOMAIN
 */
plugin.getBaseUrl = function(req, sourceBaseUrlPattern, targetBaseUrlPattern) {
    var sourceHost = req.headers && req.headers.host
        || req.host
        || req.url && req.url.replace(/^https?:\/\/([^/]*).*/, "$1")
        || req;
    var sourceHostMatcher = sourceBaseUrlPattern
        .replace(/^https?:\/\//, "")
        .replace(/\/.*/, "")
        .replace("$DOMAIN", "([^/]+)");
    var hostMatch = sourceHost.match(sourceHostMatcher);
    if (!hostMatch) {
        errorLogger.log(new Error("Could not construct URL: request host "
            + sourceHost + " should match " + sourceBaseUrlPattern));
        return replaceDomain(targetBaseUrlPattern || sourceBaseUrlPattern, "c9.io")
            .replace(/\/$/, "");
    }

    return replaceDomain(targetBaseUrlPattern || sourceBaseUrlPattern, hostMatch[1])
        .replace(/\/$/, "");;
};

plugin.replaceDomains = function(settings, domains) {
    domains = Array.isArray(domains) ? domains : domains.split(",");
    var primaryDomain = domains[0];
    settings.domains = domains;
    settings.primaryDomain = replaceDomain(settings.primaryDomain || "$DOMAIN", primaryDomain);
    settings.primaryBaseUrl = replaceDomain(settings.primaryBaseUrl || "https://$DOMAIN", primaryDomain);
    for (var s in settings) {
        if (!settings[s])
            continue;
        if (settings[s].baseUrl)
            settings[s].baseUrl = replaceDomain(settings[s].baseUrl, primaryDomain);
        if (settings[s].primaryBaseUrl)
            settings[s].primaryBaseUrl = replaceDomain(settings[s].primaryBaseUrl, primaryDomain);
        if (settings[s].baseUrls) {
            assert(settings[s].baseUrls.length === 1);
            settings[s].baseUrls = domains.map(function(d) {
                return replaceDomain(settings[s].baseUrls[0], d);
            });
        }
    }
};

function replaceDomain(url, domain) {
    return url.replace("$DOMAIN", domain);
}

function mockErrorLogger() {}
mockErrorLogger.log = function(err) {
    console.error(err.stack);
};
plugin.mockErrorLogger = mockErrorLogger;
<|endoftext|>


<commit_before>/*************************************************************************************************
 * Copyright 2015 MajorLabel -- This file is a part of MajorLabel coreBOS Customizations.
 * Licensed under the vtiger CRM Public License Version 1.1 (the "License"); you may not use this
 * file except in compliance with the License. You can redistribute it and/or modify it
 * under the terms of the License. MajorLabel reserves all rights not expressly
 * granted by the License. coreBOS distributed by MajorLabel is distributed in
 * the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Unless required by
 * applicable law or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT ANY WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing
 * permissions and limitations under the License. You may obtain a copy of the License
 * at <http://corebos.org/documentation/doku.php?id=en:devel:vpl11>
*************************************************************************************************
*  Author       : MajorLabel, Guido Goluke
*************************************************************************************************/

jQuery(window).load(function(){

	// Function to save the values obtained from the first run
	var saveFirstRun = function() {
		jQuery.ajax({
			type: "POST",
			data:	{
				'clientID'		:	jQuery('input#clientID').val(),
				'clientsecret'	:	jQuery('input#clientsecret').val(),
				'countryurl'	:	jQuery('input#countryurl').val(),
				'firstrunsave'	:	true
			},
			success: alert('Settings Saved')
		});
	}

	jQuery('#saveFirstRun').click(function(){
		saveFirstRun();
	});

	// Function to save ALL values in the normal settings screen
	var saveCreds = function() {
		jQuery.ajax({
			type: "POST",
			data:	{
				'division'		:	jQuery('input#division').val(),
				'clientID'		:	jQuery('input#clientID').val(),
				'clientsecret'	:	jQuery('input#clientsecret').val(),
				'returnurl'		:	jQuery('input#returnurl').val(),
				'authurl'		:	jQuery('input#authurl').val(),
				'tokenurl'		:	jQuery('input#tokenurl').val(),
				'apiurl'		:	jQuery('input#apiurl').val(),
				'save'			:	true
			},
			success: alert('Settings Saved')
		});
	}

	jQuery('#savesettings').click(function(){
		saveCreds();
	});

	// Function to autofill the division field
	function getDivision() {
		return jQuery.ajax({
			url		:	'index.php?module=ExactOnline&action=ExactOnlineAjax&file=getDivision',
			success	:	function(data) {
				jQuery('#division').val(data);
			}
		});
	}

	jQuery('#getdivision').click(function(){
		getDivision();
	});

	// Some jQuery to control the panel slides on the first run
	jQuery('#firstrunnext').click(function(){
		jQuery('#firstrunpanelscontainer').animate({
			'left'	:	'-=900'
		});
	});
	jQuery('#firstrunprev').click(function(){
		jQuery('#firstrunpanelscontainer').animate({
			'left'	:	'+=900'
		});
	});

	// Make the division input border red to get attention for the fact
	// That it needs to be filled if it's empty
	setInterval(divisionBorderRed(), 500);

	function divisionBorderRed(){
		if (jQuery('input#division').val() == '') {
			jQuery('input#division').css('border','1px solid red');
		}
	}

	// Function to reload the first run, effectively setting the
	// 'refreshedtime' in the exact settings table to 0 (zero)
	var reloadFirstRun = function() {
		jQuery.ajax({
			type: "POST",
			data:	{
				'reloadfirstrun'	:	true
			},
			success: alert('First Run Reset, please reload this page.')
		});
	}

	jQuery('#reloadfirstrun').click(function(){
		reloadFirstRun();
	});

});
<commit_msg>No need for a separate file to get division, just add a<commit_after>/*************************************************************************************************
 * Copyright 2015 MajorLabel -- This file is a part of MajorLabel coreBOS Customizations.
 * Licensed under the vtiger CRM Public License Version 1.1 (the "License"); you may not use this
 * file except in compliance with the License. You can redistribute it and/or modify it
 * under the terms of the License. MajorLabel reserves all rights not expressly
 * granted by the License. coreBOS distributed by MajorLabel is distributed in
 * the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Unless required by
 * applicable law or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT ANY WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing
 * permissions and limitations under the License. You may obtain a copy of the License
 * at <http://corebos.org/documentation/doku.php?id=en:devel:vpl11>
*************************************************************************************************
*  Author       : MajorLabel, Guido Goluke
*************************************************************************************************/

jQuery(window).load(function(){

	// Function to save the values obtained from the first run
	var saveFirstRun = function() {
		jQuery.ajax({
			type: "POST",
			data:	{
				'clientID'		:	jQuery('input#clientID').val(),
				'clientsecret'	:	jQuery('input#clientsecret').val(),
				'countryurl'	:	jQuery('input#countryurl').val(),
				'firstrunsave'	:	true
			},
			success: alert('Settings Saved')
		});
	}

	jQuery('#saveFirstRun').click(function(){
		saveFirstRun();
	});

	// Function to save ALL values in the normal settings screen
	var saveCreds = function() {
		jQuery.ajax({
			type: "POST",
			data:	{
				'division'		:	jQuery('input#division').val(),
				'clientID'		:	jQuery('input#clientID').val(),
				'clientsecret'	:	jQuery('input#clientsecret').val(),
				'returnurl'		:	jQuery('input#returnurl').val(),
				'authurl'		:	jQuery('input#authurl').val(),
				'tokenurl'		:	jQuery('input#tokenurl').val(),
				'apiurl'		:	jQuery('input#apiurl').val(),
				'save'			:	true
			},
			success: alert('Settings Saved')
		});
	}

	jQuery('#savesettings').click(function(){
		saveCreds();
	});

	// Function to autofill the division field
	function getDivision() {
		return jQuery.ajax({
			url		:	'index.php?module=ExactOnline&action=ExactOnlineAjax&file=handleAPI&getdivision=1',
			success	:	function(data) {
				jQuery('#division').val(data);
			}
		});
	}

	jQuery('#getdivision').click(function(){
		getDivision();
	});

	// Some jQuery to control the panel slides on the first run
	jQuery('#firstrunnext').click(function(){
		jQuery('#firstrunpanelscontainer').animate({
			'left'	:	'-=900'
		});
	});
	jQuery('#firstrunprev').click(function(){
		jQuery('#firstrunpanelscontainer').animate({
			'left'	:	'+=900'
		});
	});

	// Make the division input border red to get attention for the fact
	// That it needs to be filled if it's empty
	setInterval(divisionBorderRed(), 500);

	function divisionBorderRed(){
		if (jQuery('input#division').val() == '') {
			jQuery('input#division').css('border','1px solid red');
		}
	}

	// Function to reload the first run, effectively setting the
	// 'refreshedtime' in the exact settings table to 0 (zero)
	var reloadFirstRun = function() {
		jQuery.ajax({
			type: "POST",
			data:	{
				'reloadfirstrun'	:	true
			},
			success: alert('First Run Reset, please reload this page.')
		});
	}

	jQuery('#reloadfirstrun').click(function(){
		reloadFirstRun();
	});

});
<|endoftext|>


<commit_before>export default version => `

`;
<commit_msg>using mutation observer instead of polling<commit_after>export default version => `

`;
<|endoftext|>


<commit_before>/**
 *
 * LanguageSelector
 *
 */

import React from 'react'
import PropTypes from 'prop-types'
import SelectField from 'material-ui/SelectField'
import MenuItem from 'material-ui/MenuItem'
import { injectIntl, intlShape } from 'react-intl'
import messages from './messages'

const LanguageSelector = (props) => {
  const { formatMessage } = props.intl
  const handleChange = (event, index, value) => {
    props.onChange(value)
  }

  const showOriginal = (original) => (props.shortOption ? '' : `${original} - `)

  return (
    <SelectField
      style={{ textAlign: 'left', width: '330px', maxWidth: '98%' }}
      maxHeight={400}
      value={props.value}
      onChange={handleChange}
      floatingLabelText={props.showToolTip && 'Choose your language'}
    >
      <MenuItem
        value={'es'}
        primaryText={`${showOriginal('Español')}${formatMessage(
          messages.spanish
        )}`}
      />
      <MenuItem
        value={'en'}
        primaryText={`${showOriginal('English')}${formatMessage(
          messages.english
        )}`}
      />
      <MenuItem
        value={'fr'}
        primaryText={`${showOriginal('Français')}${formatMessage(
          messages.french
        )}`}
      />
      <MenuItem
        value={'de'}
        primaryText={`${showOriginal('Deutsche')}${formatMessage(
          messages.german
        )}`}
      />
      <MenuItem
        value={'hr'}
        primaryText={`${showOriginal('Hrvatski')}${formatMessage(
          messages.croatian
        )}`}
      />
      <MenuItem
        value={'it'}
        primaryText={`${showOriginal('Italiano')}${formatMessage(
          messages.italian
        )}`}
      />
      <MenuItem
        value={'bg'}
        primaryText={`${showOriginal('български')}${formatMessage(
          messages.bulgarian
        )}`}
      />
      <MenuItem
        value={'pl'}
        primaryText={`${showOriginal('Polskie')}${formatMessage(
          messages.polish
        )}`}
      />
      <MenuItem
        value={'pt'}
        primaryText={`${showOriginal('Português')}${formatMessage(
          messages.portuguese
        )}`}
      />
      <MenuItem
        value={'br'}
        primaryText={`${showOriginal('Português do Brasil')}${formatMessage(
          messages.brazilian
        )}`}
      />
      <MenuItem
        value={'ro'}
        primaryText={`${showOriginal('Română')}${formatMessage(
          messages.romanian
        )}`}
      />
      <MenuItem
        value={'ru'}
        primaryText={`${showOriginal('Pусский')}${formatMessage(
          messages.russian
        )}`}
      />
      <MenuItem
        value={'ar'}
        primaryText={`${showOriginal('عربى')}${formatMessage(messages.arabic)}`}
      />
      <MenuItem
        value={'zh'}
        primaryText={`${showOriginal('简体中文')}${formatMessage(
          messages.chineseSimplified
        )}`}
      />
      <MenuItem
        value={'ga'}
        primaryText={`${showOriginal('Galego')}${formatMessage(
          messages.galician
        )}`}
      />
      <MenuItem
        value={'ca'}
        primaryText={`${showOriginal('Català')}${formatMessage(
          messages.catalan
        )}`}
      />
      <MenuItem
        value={'eu'}
        primaryText={`${showOriginal('Euskal')}${formatMessage(
          messages.basque
        )}`}
      />

      <MenuItem
        value={'val'}
        primaryText={`${showOriginal('Valencia')}${formatMessage(
          messages.valencian
        )}`}
      />
    </SelectField>
  )
}

LanguageSelector.propTypes = {
  intl: intlShape.isRequired,
  onChange: PropTypes.func,
  value: PropTypes.string,
  shortOption: PropTypes.bool,
  showToolTip: PropTypes.bool
}

export default injectIntl(LanguageSelector)
<commit_msg>change locales codes<commit_after>/**
 *
 * LanguageSelector
 *
 */

import React from 'react'
import PropTypes from 'prop-types'
import SelectField from 'material-ui/SelectField'
import MenuItem from 'material-ui/MenuItem'
import { injectIntl, intlShape } from 'react-intl'
import messages from './messages'

const LanguageSelector = (props) => {
  const { formatMessage } = props.intl
  const handleChange = (event, index, value) => {
    props.onChange(value)
  }

  const showOriginal = (original) => (props.shortOption ? '' : `${original} - `)

  return (
    <SelectField
      style={{ textAlign: 'left', width: '330px', maxWidth: '98%' }}
      maxHeight={400}
      value={props.value}
      onChange={handleChange}
      floatingLabelText={props.showToolTip && 'Choose your language'}
    >
      <MenuItem
        value={'es'}
        primaryText={`${showOriginal('Español')}${formatMessage(
          messages.spanish
        )}`}
      />
      <MenuItem
        value={'en'}
        primaryText={`${showOriginal('English')}${formatMessage(
          messages.english
        )}`}
      />
      <MenuItem
        value={'fr'}
        primaryText={`${showOriginal('Français')}${formatMessage(
          messages.french
        )}`}
      />
      <MenuItem
        value={'de'}
        primaryText={`${showOriginal('Deutsche')}${formatMessage(
          messages.german
        )}`}
      />
      <MenuItem
        value={'hr'}
        primaryText={`${showOriginal('Hrvatski')}${formatMessage(
          messages.croatian
        )}`}
      />
      <MenuItem
        value={'it'}
        primaryText={`${showOriginal('Italiano')}${formatMessage(
          messages.italian
        )}`}
      />
      <MenuItem
        value={'bg'}
        primaryText={`${showOriginal('български')}${formatMessage(
          messages.bulgarian
        )}`}
      />
      <MenuItem
        value={'pl'}
        primaryText={`${showOriginal('Polskie')}${formatMessage(
          messages.polish
        )}`}
      />
      <MenuItem
        value={'pt'}
        primaryText={`${showOriginal('Português')}${formatMessage(
          messages.portuguese
        )}`}
      />
      <MenuItem
        value={'br'}
        primaryText={`${showOriginal('Português do Brasil')}${formatMessage(
          messages.brazilian
        )}`}
      />
      <MenuItem
        value={'ro'}
        primaryText={`${showOriginal('Română')}${formatMessage(
          messages.romanian
        )}`}
      />
      <MenuItem
        value={'ru'}
        primaryText={`${showOriginal('Pусский')}${formatMessage(
          messages.russian
        )}`}
      />
      <MenuItem
        value={'ar'}
        primaryText={`${showOriginal('عربى')}${formatMessage(messages.arabic)}`}
      />
      <MenuItem
        value={'zh'}
        primaryText={`${showOriginal('简体中文')}${formatMessage(
          messages.chineseSimplified
        )}`}
      />
      <MenuItem
        value={'gl'}
        primaryText={`${showOriginal('Galego')}${formatMessage(
          messages.galician
        )}`}
      />
      <MenuItem
        value={'ca'}
        primaryText={`${showOriginal('Català')}${formatMessage(
          messages.catalan
        )}`}
      />
      <MenuItem
        value={'eu'}
        primaryText={`${showOriginal('Euskal')}${formatMessage(
          messages.basque
        )}`}
      />

      <MenuItem
        value={'val'}
        primaryText={`${showOriginal('Valencia')}${formatMessage(
          messages.valencian
        )}`}
      />
    </SelectField>
  )
}

LanguageSelector.propTypes = {
  intl: intlShape.isRequired,
  onChange: PropTypes.func,
  value: PropTypes.string,
  shortOption: PropTypes.bool,
  showToolTip: PropTypes.bool
}

export default injectIntl(LanguageSelector)
<|endoftext|>


<commit_before>var spawn = require('child_process').spawn,
  exec = require('child_process').exec,
  uuid = require('node-uuid'),
  path = require('path'),
  fs = require('fs'),
  Promise = require('bluebird'),
  sys = require('sys');

var PC2BIM = module.exports = function() {
  //this.session = session;
};

PC2BIM.prototype.extract = function(filename) {
  return new Promise(function(resolve, reject) {
    console.log('[PC2BIM::convert] input file: ' + filename);

    // docker run --rm -v /duraark-storage:/duraark-storage ubo/pc2bim pc2bim
    //    --input /duraark-storage/files/Nygade_Scan1001.e57
    //    --output /duraark-storage/files/Nygade_Scan1001_RECONSTRUCTED_DOCKER.ifc
    var outputfile = filename.slice(0, -4) + '_RECONSTRUCTED.ifc',
      errorText = '';

    console.log('[PC2BIM::convert] about to run:\n ' + 'docker run --rm -v /duraark-storage:/duraark-storage ubo/pc2bim pc2bim --input ' + filename + ' --output ' + outputfile);

    var executable = spawn('docker', ['run', '--rm', '-v', '/duraark-storage:/duraark-storage', 'ubo/pc2bim77', 'pc2bim', '--input', filename, '--output', outputfile]);
    // var executable = spawn('docker', 'run', '--rm', 'hello-world');
    // var executable = spawn('docker');

    executable.stdout.on('data', function(data) {
      console.log(data.toString());
    });

    executable.stderr.on('data', function(data) {
      console.log('ERROR: ' + data.toString());
      errorText += data.toString();
    });

    executable.on('close', function(code) {
      // console.log('[PC2BIM-binding] child process exited with code ' + code);

      if (code === 0) {
        console.log('[PC2BIM-binding] successfully finished');
        resolve({
          input: filename,
          output: outputfile,
          error: null
        });
      } else {
        console.log('[PC2BIM-binding] finished with error code: ' + code);
        reject({
          input: filename,
          output: null,
          error: errorText
        });
      }
    });
  });
};
<commit_msg>fixed call to 'pc2bim'<commit_after>var spawn = require('child_process').spawn,
  exec = require('child_process').exec,
  uuid = require('node-uuid'),
  path = require('path'),
  fs = require('fs'),
  Promise = require('bluebird'),
  sys = require('sys');

var PC2BIM = module.exports = function() {
  //this.session = session;
};

PC2BIM.prototype.extract = function(filename) {
  return new Promise(function(resolve, reject) {
    console.log('[PC2BIM::convert] input file: ' + filename);

    // docker run --rm -v /duraark-storage:/duraark-storage ubo/pc2bim pc2bim
    //    --input /duraark-storage/files/Nygade_Scan1001.e57
    //    --output /duraark-storage/files/Nygade_Scan1001_RECONSTRUCTED_DOCKER.ifc
    var outputfile = filename.slice(0, -4) + '_RECONSTRUCTED.ifc',
      errorText = '';

    console.log('[PC2BIM::convert] about to run:\n ' + 'docker run --rm -v /duraark-storage:/duraark-storage ubo/pc2bim pc2bim --input ' + filename + ' --output ' + outputfile);

    var executable = spawn('docker', ['run', '--rm', '-v', '/duraark-storage:/duraark-storage', 'ubo/pc2bim', 'pc2bim', '--input', filename, '--output', outputfile]);
    // var executable = spawn('docker', 'run', '--rm', 'hello-world');
    // var executable = spawn('docker');

    executable.stdout.on('data', function(data) {
      console.log(data.toString());
    });

    executable.stderr.on('data', function(data) {
      console.log('ERROR: ' + data.toString());
      errorText += data.toString();
    });

    executable.on('close', function(code) {
      // console.log('[PC2BIM-binding] child process exited with code ' + code);

      if (code === 0) {
        console.log('[PC2BIM-binding] successfully finished');
        resolve({
          input: filename,
          output: outputfile,
          error: null
        });
      } else {
        console.log('[PC2BIM-binding] finished with error code: ' + code);
        reject({
          input: filename,
          output: null,
          error: errorText
        });
      }
    });
  });
};
<|endoftext|>


<commit_before>"use strict";

const Course = require('course');

// IO proxies
const ioutils = require('ioutils');
const json_io = ioutils.json_io;
const fs_io = ioutils.fs_io;
const http_io = ioutils.http_io;

// Utilities
const utils = require('utils');
const html2document = utils.html2document;
const html2text = utils.html2text;

// The Catalog

var Catalog = function(depts, courses, term) {
	// Index courses into the catalog object
	this.courses = {};
	this.sections = {};
	this.term = term;
	for (var dept in depts) {
		this.courses[dept] = {name:depts[dept]};
	}
	courses.forEach((course) => {
		// Index courses by code
		let dept = course.dept;
		if (!this.courses[dept]) {
			console.warn(`Dept ${dept} not indexed!`);
			this.courses[dept] = {name: dept};
		}
		this.courses[dept][course.number] = course;

		// Index sections by CRN
		for (var type in course.sections) {
			course.sections[type].forEach((section) => {
				this.sections[section.crn] = section;
			});
		}
	});

	return this;
};

Catalog.prototype.getCourse = function(code) {
	var code = Catalog.parseCourseCode(code);
	if (!code || !this.courses[code.dept] || !this.courses[code.dept][code.number]) {
		return null;
	}
	return this.courses[code.dept][code.number];
}

Catalog.prototype.update = function(code) {
	return new Promise((resolve, reject) => {
		code = Catalog.parseCourseCode(code);
		if (!code) {
			reject("Invalid course code");
			return;
		}
		// TODO: embed base urls into data
		Course.fromURL("https://courses.illinois.edu/schedule/"+this.term+"/"+code.dept+"/"+code.number).then(((course) => {
			this.courses[code.dept][code.number] = course;
			if (this.storage) {
				this.storage.setItem(`${code.dept}_${code.number}`, JSON.stringify(course));
			}
			resolve(course);
		}).bind(this), (err) => {
			console.error(err);
			reject(err);
		});
	});
}

// Dump to filesystem/localstorage
Catalog.prototype.save = function(storage) {
	if (!storage) {
		if (!this.storage) {
			return false;
		}
		storage = this.storage;
	}
	let index = [], dept_index = {};
	for (var dept_code in this.courses) {
		let dept = this.courses[dept_code];
		for (var idx in dept) {
			if (idx == 'name') {
				dept_index[dept_code] = dept[idx];
			} else {
				let course = dept[idx], filename = `${dept_code}_${course.number}`;
				index.push(filename);
				storage.setItem(filename, JSON.stringify(course));
			}
		}
	}
	storage.setItem("index", JSON.stringify(index));
	storage.setItem("depts", JSON.stringify(dept_index));
	storage.setItem("meta", JSON.stringify({term: this.term}));
}

// Online-fetch utilities
let getTerm = function(term, io, cb) {
	return new Promise((resolve, reject) => {
		io.getItem('schedule/'+term).then((val) => {
			let table = html2document(val).querySelector("table#term-dt tbody");
			if (!table) {
				throw `Cannot get dept list for term ${term}`;
			}

			var depts = {}, dept_list = [], courses = [], ptr = 0;

			var dept_promise = Promise.resolve();

			table.querySelectorAll("tr").forEach((dept) => {
				let tds = dept.querySelectorAll('td');
				if (tds.length != 2) {
					if (cb.console)
					var console = cb.console;
					console.warn(`Unexpected td length for ${dept}`);
					return;
				}
				let	dept_code = tds[0].innerText.trim().toUpperCase(),
					dept_name = tds[1].innerText.trim(),
					dept_link = dept.querySelector('a').getAttribute('href');
				if (!dept_link) {
					if (cb.console)
						var console = cb.console;
					console.warn(`No link to ${dept_code}, skipping...`);
					return
				}
				depts[dept_code] = dept_name;
				dept_list.push({dept_name, dept_link});

				dept_promise = dept_promise.then(() => {
					if (cb) cb.console.log("Loading courses for "+dept_list[ptr].dept_name+"...");
					return getCoursesForDept(dept_list[ptr].dept_link, io);
				}).then((val) => {
					courses = courses.concat(val);
					ptr++;
					if(cb) cb.completeOne();
				}, (err) => {
					if (cb.console)
						var console = cb.console;
					console.warn(`Course fetch failed for ${dept_list[ptr].dept_name}`);
					console.warn(err);
					ptr++;
				});
			});
			if(cb) cb.setTaskCount(dept_list.length);

			dept_promise.then(() => {
				resolve({courses, depts});
			});
		}).catch((err) => {
			reject(err);
		});
	});
};

let getCoursesForDept = function(url, io) {
	return new Promise((resolve, reject) => {
		io.getItem(url).then((val) => {
			let table = html2document(val).querySelector('table#default-dt tbody');
			// var q = [[],[],[],[]], ptr = 0; // 4 Concurrent connections
			// var promises = [Promise.resolve(), Promise.resolve(), Promise.resolve(), Promise.resolve()];
			// q.io = io;
			var courses = [];
			table.querySelectorAll("tr").forEach((trow) => {
				var code, title;
				[code, title] = trow.querySelectorAll("td");
				code = code.innerText.trim();
				title = title.innerText.trim();
				courses.push(Course.templateFromCode(code, title));
			});
			resolve(courses);
			/*
			table.querySelectorAll('a').forEach((item) => {
				q[ptr].push(item.getAttribute('href'));

				promises[ptr] = promises[ptr].then( ( (i)=>{
					return Course.fromURL(q[i].pop(), io);
				} ).bind(this, ptr) );
				promises[ptr] = promises[ptr].then((fetched_course) => {
					courses.push(fetched_course);
				}, (err) => {
					console.warn("Cannot process course");
					console.warn(err);
				});

				++ptr;
				ptr%=4;
			});
			Promise.all(promises).then(() => {
				// console.log(`Fetched ${courses.length} courses for ${url}`);
				resolve(courses);
			});
			*/
		});
	});
}

// Initialization class methods

Catalog.fromTerm = function(term, baseURL, cb) {
	if (!baseURL) {
		baseURL = "https://courses.illinois.edu/";
	}
	if (!term) {
		term = "DEFAULT/DEFAULT";
	}
	var io = new http_io(baseURL);
	return new Promise((resolve, reject) => {
		getTerm(term, io, cb).then((val) => {
			try {
				var catalog = new Catalog(val.depts, val.courses, term);
				// catalog.resolveDependencies();
				resolve(catalog);
			} catch(e) {
				reject(e);
			}
		}, (err) => {
			reject(err);
		});
	});
};

Catalog.fromStorage = function(storage) {
	if (!storage) {
		throw "Storage object unavailable";
	}
	let index = JSON.parse(storage.getItem('index'));
	let depts = JSON.parse(storage.getItem('depts'));
	let meta = JSON.parse(storage.getItem('meta'));
	var courses = [];
	index.forEach((file) => {
		let data = JSON.parse(storage.getItem(file));
		courses.push(new Course(data));
	});

	let catalog = new Catalog(depts, courses, meta.term);
	catalog.storage = storage;
	return catalog;
}

Catalog.fromLocalStorage = Catalog.fromStorage.bind({}, window.localStorage);

Catalog.fromDirectory = function(dirname) {
	return Catalog.fromStorage(new fs_io(dirname));
}

// Utility methods

Catalog.parseCourseCode = function(courseid) {
	try {
		var number = parseInt(/\d+/.exec(courseid)[0]);
		if (number < 100) {
			throw "Course number too low";
		}
		var dept = /[A-Za-z]*/.exec(courseid)[0].toUpperCase();
		return {dept, number};
	} catch(e) {
		return null;
	}
}

Catalog.getDefaultTerm = function() {
	return Promise.resolve().then(() => {
		var io = new http_io("https://courses.illinois.edu/schedule");
		return io.getItem("DEFAULT/DEFAULT").then((data) => {
			var doc = html2document(data);
			var term = doc.querySelector("h1").innerText;
			term = term.trim().toLowerCase();
			return term.replace(/(\w+) (\d+)/, "$2/$1");
		});
	});
}

module.exports = Catalog;
window.Catalog = Catalog;
<commit_msg>Catalog section indexing improvements<commit_after>"use strict";

const Course = require('course');

// IO proxies
const ioutils = require('ioutils');
const json_io = ioutils.json_io;
const fs_io = ioutils.fs_io;
const http_io = ioutils.http_io;

// Utilities
const utils = require('utils');
const html2document = utils.html2document;
const html2text = utils.html2text;

// The Catalog

var Catalog = function(depts, courses, term) {
	// Index courses into the catalog object
	this.courses = {};
	this.sections = {};
	this.term = term;
	for (var dept in depts) {
		this.courses[dept] = {name:depts[dept]};
	}
	courses.forEach((course) => {
		// Index courses by code
		let dept = course.dept;
		if (!this.courses[dept]) {
			console.warn(`Dept ${dept} not indexed!`);
			this.courses[dept] = {name: dept};
		}
		this.courses[dept][course.number] = course;

		// Index sections by CRN
		for (var type in course.sections) {
			course.sections[type].forEach((section) => {
				this.sections[section.crn] = section;
				section.course = course;
			});
		}
	});

	return this;
};

Catalog.prototype.getCourse = function(code) {
	var code = Catalog.parseCourseCode(code);
	if (!code || !this.courses[code.dept] || !this.courses[code.dept][code.number]) {
		return null;
	}
	return this.courses[code.dept][code.number];
}

Catalog.prototype.update = function(code) {
	return new Promise((resolve, reject) => {
		code = Catalog.parseCourseCode(code);
		if (!code) {
			reject("Invalid course code");
			return;
		}
		// TODO: embed base urls into data
		Course.fromURL("https://courses.illinois.edu/schedule/"+this.term+"/"+code.dept+"/"+code.number).then(((course) => {
			this.courses[code.dept][code.number] = course;
			if (this.storage) {
				this.storage.setItem(`${code.dept}_${code.number}`, JSON.stringify(course));
			}
			for (var type in course.sections) {
				course.sections[type].forEach((section) => {
					this.sections[section.crn] = section;
					section.course = course;
				});
			}
			resolve(course);
		}).bind(this), (err) => {
			console.error(err);
			reject(err);
		});
	});
}

// Dump to filesystem/localstorage
Catalog.prototype.save = function(storage) {
	if (!storage) {
		if (!this.storage) {
			return false;
		}
		storage = this.storage;
	}
	let index = [], dept_index = {};
	for (var dept_code in this.courses) {
		let dept = this.courses[dept_code];
		for (var idx in dept) {
			if (idx == 'name') {
				dept_index[dept_code] = dept[idx];
			} else {
				let course = dept[idx], filename = `${dept_code}_${course.number}`;
				index.push(filename);
				storage.setItem(filename, JSON.stringify(course));
			}
		}
	}
	storage.setItem("index", JSON.stringify(index));
	storage.setItem("depts", JSON.stringify(dept_index));
	storage.setItem("meta", JSON.stringify({term: this.term}));
}

// Online-fetch utilities
let getTerm = function(term, io, cb) {
	return new Promise((resolve, reject) => {
		io.getItem('schedule/'+term).then((val) => {
			let table = html2document(val).querySelector("table#term-dt tbody");
			if (!table) {
				throw `Cannot get dept list for term ${term}`;
			}

			var depts = {}, dept_list = [], courses = [], ptr = 0;

			var dept_promise = Promise.resolve();

			table.querySelectorAll("tr").forEach((dept) => {
				let tds = dept.querySelectorAll('td');
				if (tds.length != 2) {
					if (cb.console)
					var console = cb.console;
					console.warn(`Unexpected td length for ${dept}`);
					return;
				}
				let	dept_code = tds[0].innerText.trim().toUpperCase(),
					dept_name = tds[1].innerText.trim(),
					dept_link = dept.querySelector('a').getAttribute('href');
				if (!dept_link) {
					if (cb.console)
						var console = cb.console;
					console.warn(`No link to ${dept_code}, skipping...`);
					return
				}
				depts[dept_code] = dept_name;
				dept_list.push({dept_name, dept_link});

				dept_promise = dept_promise.then(() => {
					if (cb) cb.console.log("Loading courses for "+dept_list[ptr].dept_name+"...");
					return getCoursesForDept(dept_list[ptr].dept_link, io);
				}).then((val) => {
					courses = courses.concat(val);
					ptr++;
					if(cb) cb.completeOne();
				}, (err) => {
					if (cb.console)
						var console = cb.console;
					console.warn(`Course fetch failed for ${dept_list[ptr].dept_name}`);
					console.warn(err);
					ptr++;
				});
			});
			if(cb) cb.setTaskCount(dept_list.length);

			dept_promise.then(() => {
				resolve({courses, depts});
			});
		}).catch((err) => {
			reject(err);
		});
	});
};

let getCoursesForDept = function(url, io) {
	return new Promise((resolve, reject) => {
		io.getItem(url).then((val) => {
			let table = html2document(val).querySelector('table#default-dt tbody');
			// var q = [[],[],[],[]], ptr = 0; // 4 Concurrent connections
			// var promises = [Promise.resolve(), Promise.resolve(), Promise.resolve(), Promise.resolve()];
			// q.io = io;
			var courses = [];
			table.querySelectorAll("tr").forEach((trow) => {
				var code, title;
				[code, title] = trow.querySelectorAll("td");
				code = code.innerText.trim();
				title = title.innerText.trim();
				courses.push(Course.templateFromCode(code, title));
			});
			resolve(courses);
			/*
			table.querySelectorAll('a').forEach((item) => {
				q[ptr].push(item.getAttribute('href'));

				promises[ptr] = promises[ptr].then( ( (i)=>{
					return Course.fromURL(q[i].pop(), io);
				} ).bind(this, ptr) );
				promises[ptr] = promises[ptr].then((fetched_course) => {
					courses.push(fetched_course);
				}, (err) => {
					console.warn("Cannot process course");
					console.warn(err);
				});

				++ptr;
				ptr%=4;
			});
			Promise.all(promises).then(() => {
				// console.log(`Fetched ${courses.length} courses for ${url}`);
				resolve(courses);
			});
			*/
		});
	});
}

// Initialization class methods

Catalog.fromTerm = function(term, baseURL, cb) {
	if (!baseURL) {
		baseURL = "https://courses.illinois.edu/";
	}
	if (!term) {
		term = "DEFAULT/DEFAULT";
	}
	var io = new http_io(baseURL);
	return new Promise((resolve, reject) => {
		getTerm(term, io, cb).then((val) => {
			try {
				var catalog = new Catalog(val.depts, val.courses, term);
				// catalog.resolveDependencies();
				resolve(catalog);
			} catch(e) {
				reject(e);
			}
		}, (err) => {
			reject(err);
		});
	});
};

Catalog.fromStorage = function(storage) {
	if (!storage) {
		throw "Storage object unavailable";
	}
	let index = JSON.parse(storage.getItem('index'));
	let depts = JSON.parse(storage.getItem('depts'));
	let meta = JSON.parse(storage.getItem('meta'));
	var courses = [];
	index.forEach((file) => {
		let data = JSON.parse(storage.getItem(file));
		courses.push(new Course(data));
	});

	let catalog = new Catalog(depts, courses, meta.term);
	catalog.storage = storage;
	return catalog;
}

Catalog.fromLocalStorage = Catalog.fromStorage.bind({}, window.localStorage);

Catalog.fromDirectory = function(dirname) {
	return Catalog.fromStorage(new fs_io(dirname));
}

// Utility methods

Catalog.parseCourseCode = function(courseid) {
	try {
		var number = parseInt(/\d+/.exec(courseid)[0]);
		if (number < 100) {
			throw "Course number too low";
		}
		var dept = /[A-Za-z]*/.exec(courseid)[0].toUpperCase();
		return {dept, number};
	} catch(e) {
		return null;
	}
}

Catalog.getDefaultTerm = function() {
	return Promise.resolve().then(() => {
		var io = new http_io("https://courses.illinois.edu/schedule");
		return io.getItem("DEFAULT/DEFAULT").then((data) => {
			var doc = html2document(data);
			var term = doc.querySelector("h1").innerText;
			term = term.trim().toLowerCase();
			return term.replace(/(\w+) (\d+)/, "$2/$1");
		});
	});
}

module.exports = Catalog;
window.Catalog = Catalog;
<|endoftext|>


<commit_before><commit_msg>clean code<commit_after><|endoftext|>


<commit_before>var xray = require('x-ray');
var x = xray();

var signo;
var previsor = 'maya';
var duracao;
var duracaoTodos = [];
var signosTodos = [];
var previsorTodos = [];

function help() {
	console.log('Utilização: node '+basename(process.argv[1])+' <signo> [diaria|semanal|semanal-amor|mensal|anual] [previsor]');
}

function basename(file) {
	if(file.lastIndexOf('/') !== -1) {
		return file.substring(file.lastIndexOf('/') + 1);
	}
	else if(file.lastIndexOf('\\') !== -1) {
		return file.substring(file.lastIndexOf('\\') + 1);
	} else {
		return file;
	}
}

switch(process.argv.length) {
	case 3:
		signo = process.argv[2].toLowerCase();
		if(signo === '-h' || signo === '--help') {
			help();
			return;
		}
		break;
	case 4:
		signo = process.argv[2].toLowerCase();
		duracao = process.argv[3].toLowerCase();
		break;
	case 5:
		signo = process.argv[2].toLowerCase();
		duracao = process.argv[3].toLowerCase();
		previsor = process.argv[4].toLowerCase();
		break;
	default:
		help();
		return;
	break;
}

switch(signo) {
	case 'caranguejo':
		signo = 'cancer';
	break;
}

var http = require('http');

var options = {
    host: 'lifestyle.sapo.pt',
    port: 80,
    path: '/astral/previsoes/'+previsor+'?signo='+signo
};

var content = "";

var req = http.request(options, function(res) {
    res.setEncoding("utf8");
    res.on("data", function (chunk) {
        content += chunk;
    });

    res.on("end", function () {
        HTML2Horoscopo(content);
    });
});

req.on('error', function(err) {
	console.error('Não foi possivel conectar. Provavelmente tem a ligacao em baixo.');
	return;
});

req.end();

function HTML2Horoscopo(string) {
	x(string, '#astrological_sign option', ['@value'])(function(err, data) {
		for (var i = 0; i < data.length; i++) {
			signosTodos.push(data[i]);
		}
		x(string, '#predictor option',
			[{
				value: '@value',
				selected: '@selected'
			}]
			)(function(err, data) {
			for (var i = 0; i < data.length; i++) {
				var obj = data[i];
				previsorTodos.push(obj.value);
				//if(obj.selected === 'selected') previsor = obj.value;
			}

			var getRealDataPromise = new Promise(function(resolve, reject) {
				if(signosTodos.length !== 0 && previsorTodos.length !== 0)  return resolve();
				var options2 = {
				    host: 'lifestyle.sapo.pt',
				    port: 80,
				    path: '/astral/previsoes/maya?signo=carneiro'
				};

				var content2 = "";

				var req2 = http.request(options2, function(res2) {
				    res2.setEncoding("utf8");
				    res2.on("data", function (chunk2) {
				        content2 += chunk2;
				    });

				    res2.on("end", function () {
				        x(content2, '#astrological_sign option', ['@value'])(function(err, data) {
							for (var i = 0; i < data.length; i++) {
								signosTodos.push(data[i]);
							}
							x(content2, '#predictor option',
								[{
									value: '@value',
									selected: '@selected'
								}]
								)(function(err, data) {
								for (var i = 0; i < data.length; i++) {
									var obj = data[i];
									previsorTodos.push(obj.value);
									//if(obj.selected === 'selected') previsor = obj.value;
								}
								/*x(content2, '.tabs-nav', ['a@href'])(function(err, data) {
									for (var i = 0; i < data.length; i++) {
										duracaoTodos.push(data[i].substring(data[i].indexOf('#') + 1));
									}*/

									if(signosTodos.length !== 0 && previsorTodos.length !== 0)  return resolve();
									else {
										var erroMsg = "Nao consegui encontrar";
										if(signosTodos.length === 0) {
											erroMsg += " os signos e";
										}
										if(previsorTodos.length === 0) {
											erroMsg += " os previsores e";
										}

										erroMsg = erroMsg.replace(/e$/, "");
										erroMsg += "existentes."
										return reject(new Error(erroMsg));
									}
								//});
							});
						});
				    });
				});

				req2.on('error', function(err) {
					console.error('Não foi possivel conectar. Tente outra vez.');
					return;
				});

				req2.end();
			});

			getRealDataPromise.catch(function(err) {
				console.error('Erro: '+err.message);
				return;
			});
			getRealDataPromise.then(function() {
				if(signosTodos.indexOf(signo) === -1) {
					var textoTodosSignos = signosTodos[0];
					for (var i = 1; i < signosTodos.length; i++) {
						textoTodosSignos += (i !== signosTodos.length - 1) ? (', '+signosTodos[i]) : (' ou '+signosTodos[i]);
					}
					console.error('Erro: Nao existe o signo "' + signo + '".\nEscolha '+textoTodosSignos+'.');
					return;
				}
				x(string, '.tabs-nav', ['a@href'])(function(err, data) { // isto e para ir buscar a duracaoTodos
					// a verificacao de previsor tem de vir antes da de duracao
					var textoTodosPrevisores = previsorTodos[0];
					for (var i = 1; i < previsorTodos.length; i++) {
						textoTodosPrevisores += (i !== previsorTodos.length - 1) ? (', '+previsorTodos[i]) : (' ou '+previsorTodos[i]);
					}
					if(previsorTodos.indexOf(previsor) === -1) {
						console.error('Erro: Nao existe o(a) previsor(a) "' + previsor + '".\nEscolha um de: '+textoTodosPrevisores+'.');
						return;
					}

					for (var i = 0; i < data.length; i++) {
						duracaoTodos.push(data[i].substring(data[i].lastIndexOf('#') + 1));
					}
					if(!duracao || duracao.length === 0 || duracao === '-') {
						duracao = duracaoTodos[0];
					} else {
						if(duracaoTodos.indexOf(duracao) === -1) { // duracao nao existe no array duracaoTodos
							console.error('Erro: ' + previsor + ' nao tem a opcao "' + duracao + '".\nEscolha "'+duracaoTodos.join('" ou "')+'".');
							return;
						}
					}

					x(string, '#'+duracao, ['p'])(function(err, data) {
						var output = "";
						for (var i = 0; i < data.length; i++) {
							var texto = data[i];
							var arrayTmpTexto = [];
							var alreadyWrote = false;
							if(texto.indexOf('
') !== -1) {
								arrayTmpTexto = texto.split('
');
								for (var j = 0; j < arrayTmpTexto.length; j++) {
									output += arrayTmpTexto[j] + '\n';
								}
								alreadyWrote = true;
							}
							if(texto.indexOf('
') !== -1) {
								arrayTmpTexto = texto.split('
');
								for (var j = 0; j < arrayTmpTexto.length; j++) {
									output += arrayTmpTexto[j] + '\n';
								}
								alreadyWrote = true;
							}
							if(!alreadyWrote) {
								output += texto + '\n';
							}
						}
						output = output.replace(/\n$/, "");
						console.log(output);
					});
				});
			});
		});
	});
}<commit_msg>help ouput, comando de node para bash<commit_after>var xray = require('x-ray');
var x = xray();

var signo;
var previsor = 'maya';
var duracao;
var duracaoTodos = [];
var signosTodos = [];
var previsorTodos = [];

function help() {
	//console.log('Utilização: node '+basename(process.argv[1])+' <signo> [diaria|semanal|semanal-amor|mensal|anual] [previsor]');
	console.log('Utilização: horos <signo> [diaria|semanal|semanal-amor|mensal|anual] [previsor]');
}

function basename(file) {
	if(file.lastIndexOf('/') !== -1) {
		return file.substring(file.lastIndexOf('/') + 1);
	}
	else if(file.lastIndexOf('\\') !== -1) {
		return file.substring(file.lastIndexOf('\\') + 1);
	} else {
		return file;
	}
}

switch(process.argv.length) {
	case 3:
		signo = process.argv[2].toLowerCase();
		if(signo === '-h' || signo === '--help') {
			help();
			return;
		}
		break;
	case 4:
		signo = process.argv[2].toLowerCase();
		duracao = process.argv[3].toLowerCase();
		break;
	case 5:
		signo = process.argv[2].toLowerCase();
		duracao = process.argv[3].toLowerCase();
		previsor = process.argv[4].toLowerCase();
		break;
	default:
		help();
		return;
	break;
}

switch(signo) {
	case 'caranguejo':
		signo = 'cancer';
	break;
}

var http = require('http');

var options = {
    host: 'lifestyle.sapo.pt',
    port: 80,
    path: '/astral/previsoes/'+previsor+'?signo='+signo
};

var content = "";

var req = http.request(options, function(res) {
    res.setEncoding("utf8");
    res.on("data", function (chunk) {
        content += chunk;
    });

    res.on("end", function () {
        HTML2Horoscopo(content);
    });
});

req.on('error', function(err) {
	console.error('Não foi possivel conectar. Provavelmente tem a ligacao em baixo.');
	return;
});

req.end();

function HTML2Horoscopo(string) {
	x(string, '#astrological_sign option', ['@value'])(function(err, data) {
		for (var i = 0; i < data.length; i++) {
			signosTodos.push(data[i]);
		}
		x(string, '#predictor option',
			[{
				value: '@value',
				selected: '@selected'
			}]
			)(function(err, data) {
			for (var i = 0; i < data.length; i++) {
				var obj = data[i];
				previsorTodos.push(obj.value);
				//if(obj.selected === 'selected') previsor = obj.value;
			}

			var getRealDataPromise = new Promise(function(resolve, reject) {
				if(signosTodos.length !== 0 && previsorTodos.length !== 0)  return resolve();
				var options2 = {
				    host: 'lifestyle.sapo.pt',
				    port: 80,
				    path: '/astral/previsoes/maya?signo=carneiro'
				};

				var content2 = "";

				var req2 = http.request(options2, function(res2) {
				    res2.setEncoding("utf8");
				    res2.on("data", function (chunk2) {
				        content2 += chunk2;
				    });

				    res2.on("end", function () {
				        x(content2, '#astrological_sign option', ['@value'])(function(err, data) {
							for (var i = 0; i < data.length; i++) {
								signosTodos.push(data[i]);
							}
							x(content2, '#predictor option',
								[{
									value: '@value',
									selected: '@selected'
								}]
								)(function(err, data) {
								for (var i = 0; i < data.length; i++) {
									var obj = data[i];
									previsorTodos.push(obj.value);
									//if(obj.selected === 'selected') previsor = obj.value;
								}
								/*x(content2, '.tabs-nav', ['a@href'])(function(err, data) {
									for (var i = 0; i < data.length; i++) {
										duracaoTodos.push(data[i].substring(data[i].indexOf('#') + 1));
									}*/

									if(signosTodos.length !== 0 && previsorTodos.length !== 0)  return resolve();
									else {
										var erroMsg = "Nao consegui encontrar";
										if(signosTodos.length === 0) {
											erroMsg += " os signos e";
										}
										if(previsorTodos.length === 0) {
											erroMsg += " os previsores e";
										}

										erroMsg = erroMsg.replace(/e$/, "");
										erroMsg += "existentes."
										return reject(new Error(erroMsg));
									}
								//});
							});
						});
				    });
				});

				req2.on('error', function(err) {
					console.error('Não foi possivel conectar. Tente outra vez.');
					return;
				});

				req2.end();
			});

			getRealDataPromise.catch(function(err) {
				console.error('Erro: '+err.message);
				return;
			});
			getRealDataPromise.then(function() {
				if(signosTodos.indexOf(signo) === -1) {
					var textoTodosSignos = signosTodos[0];
					for (var i = 1; i < signosTodos.length; i++) {
						textoTodosSignos += (i !== signosTodos.length - 1) ? (', '+signosTodos[i]) : (' ou '+signosTodos[i]);
					}
					console.error('Erro: Nao existe o signo "' + signo + '".\nEscolha '+textoTodosSignos+'.');
					return;
				}
				x(string, '.tabs-nav', ['a@href'])(function(err, data) { // isto e para ir buscar a duracaoTodos
					// a verificacao de previsor tem de vir antes da de duracao
					var textoTodosPrevisores = previsorTodos[0];
					for (var i = 1; i < previsorTodos.length; i++) {
						textoTodosPrevisores += (i !== previsorTodos.length - 1) ? (', '+previsorTodos[i]) : (' ou '+previsorTodos[i]);
					}
					if(previsorTodos.indexOf(previsor) === -1) {
						console.error('Erro: Nao existe o(a) previsor(a) "' + previsor + '".\nEscolha um de: '+textoTodosPrevisores+'.');
						return;
					}

					for (var i = 0; i < data.length; i++) {
						duracaoTodos.push(data[i].substring(data[i].lastIndexOf('#') + 1));
					}
					if(!duracao || duracao.length === 0 || duracao === '-') {
						duracao = duracaoTodos[0];
					} else {
						if(duracaoTodos.indexOf(duracao) === -1) { // duracao nao existe no array duracaoTodos
							console.error('Erro: ' + previsor + ' nao tem a opcao "' + duracao + '".\nEscolha "'+duracaoTodos.join('" ou "')+'".');
							return;
						}
					}

					x(string, '#'+duracao, ['p'])(function(err, data) {
						var output = "";
						for (var i = 0; i < data.length; i++) {
							var texto = data[i];
							var arrayTmpTexto = [];
							var alreadyWrote = false;
							if(texto.indexOf('
') !== -1) {
								arrayTmpTexto = texto.split('
');
								for (var j = 0; j < arrayTmpTexto.length; j++) {
									output += arrayTmpTexto[j] + '\n';
								}
								alreadyWrote = true;
							}
							if(texto.indexOf('
') !== -1) {
								arrayTmpTexto = texto.split('
');
								for (var j = 0; j < arrayTmpTexto.length; j++) {
									output += arrayTmpTexto[j] + '\n';
								}
								alreadyWrote = true;
							}
							if(!alreadyWrote) {
								output += texto + '\n';
							}
						}
						output = output.replace(/\n$/, "");
						console.log(output);
					});
				});
			});
		});
	});
}<|endoftext|>