const data = [
            { id: 'isbn', name: 'ISBN' },
            { id: 'issn', name: 'ISSN' },
            { id: '0003', name: 'Standard Technical Report number' },
            { id: '0004', name: 'Publisher Number' },
            { id: '0005', name: 'CODEN' },
            { id: '0006', name: 'Control Number (001)' },
            { id: '0007', name: 'GPO Item Number' },
            { id: 'lccn', name: 'LCCN' },
            { id: '0009', name: 'System Control Number' },
            { id: '0010', name: 'Other Standard Identifier' },
            { id: 'asin', name: 'ASIN' },
            { id: 'UkMac', name: 'UkMac' },
            { id: 'StEdNL', name: 'StEdNL' },
            { id: 'bnb', name: 'BNB' },
            { id: '0015', name: 'OCLC' },
];

const identifierTypes = {

  selectOptions: selected => data.map(
    it => ({
      label: it.name,
      value: it.id,
      selected: it.id === selected,
    })),

  typeById: id => data.find(it => it.id === id),
};

export default identifierTypes;

const data = [
            { id: 'isbn', name: 'ISBN' },
            { id: 'issn', name: 'ISSN' },
            { id: '0003', name: 'Standard Technical Report number' },
            { id: '0004', name: 'Publisher Number' },
            { id: '0005', name: 'CODEN' },
            { id: '0006', name: 'Control Number (001)' },
            { id: '0007', name: 'GPO Item Number' },
            { id: 'lccn', name: 'LCCN' },
            { id: '0009', name: 'System Control Number' },
            { id: '0010', name: 'Other Standard Identifier' },
            { id: 'asin', name: 'ASIN' },
            { id: 'UkMaC', name: 'UkMac' },
            { id: 'StEdNL', name: 'StEdNL' },
            { id: 'bnb', name: 'BNB' },
            { id: '0015', name: 'OCLC' },
];

const identifierTypes = {

  selectOptions: selected => data.map(
    it => ({
      label: it.name,
      value: it.id,
      selected: it.id === selected,
    })),

  typeById: id => data.find(it => it.id === id),
};

export default identifierTypes;

Fix typo in identifier type code.


module.exports = new function() {

  var webdriver = require("selenium-webdriver");

  webdriver.WebDriver.prototype.waitJqueryReady = function() {
    var self = this;

    return self.flow_.execute(function() {
      self.executeScript("return typeof jQuery != String(undefined) ? (!jQuery.active === jQuery.isReady) : null;").then(function(isReady) {
        switch (isReady) {
          case true:
            return true
            break;

          case false:
            self.waitJqueryReady();
            break;

          case null:
            self.controlFlow().timeout(30*1000)
            break;
        }
      })
    }, "WebDriver.waitJqueryReady()");

  }

  return webdriver;
}

module.exports = new function() {

  var webdriver = require("selenium-webdriver");

  webdriver.WebDriver.prototype.waitJqueryReady = function() {
    var self = this;

    return self.flow_.execute(function() {
      self.switchTo().alert().then(
        function() {
          return true;
        },
        function() {
          self.executeScript("return typeof jQuery != String(undefined) ? (!jQuery.active === jQuery.isReady) : null;").then(function(isReady) {
            switch (isReady) {
              case true:
                return true
              break;

              case false:
                self.waitJqueryReady();
              break;

              case null:
                self.controlFlow().timeout(30*1000)
              break;
            }
          });
        }
      );
    }, "WebDriver.waitJqueryReady()");

  }

  return webdriver;
}

Fix for alert box error


describe('Valencia-Tech Repair Database website', function() {

  beforeEach(function () {
        browser.get('http://localhost:3000');
    });

    /*---------------------------------------------*/

  it('should have a title', function(){
        expect(browser.getTitle()).toEqual('Valencia Tech Repair');
    });

})// End main test funcction

describe('Valencia-Tech Repair Database website', function() {

    /*---------------------------------------------*/

  it('should have a title', function(){
        browser.get('http://localhost:3000');
        expect(browser.getTitle()).toEqual('Valencia Tech Repair');
    });

})// End main test funcction

Rework of test file due to Protractor error


const express = require('express');
const app = express();

const port = process.env.PORT || 8080;

app.get('/', (req, res) => res.send('Hello World!'));

app.listen(8080, () => console.log(`Example app listening on port ${port}!!!`));

const express = require('express');
const app = express();
const proxy = require('http-proxy-middleware');
const nano = require('nano')('http://couchdb:5984'),
    simpleshelfDB = nano.use('simpleshelf-dev-personal');

const port = process.env.PORT || 8080;

app.use('/', express.static('output-public'));
app.get('/simpleshelf', (req, res) => {
    nano.db.list(function(err, body) {
        if (err) {
            console.warn(err);
            res.send('Error when retrieving current databases.');
        } else {
            // body is an array
            body.forEach(function(db) {
                console.log(db);
            });
            res.send('Listed current databases to console.');
        }
    });
});

/*app.all('*', (req, res) => {
    // res.send(`Hello world, from ${req.path} route`);
    console.info(`Rec'd ${req.method} method from ${req.path} path`);
    res.send('!!');
});*/

app.use('/api', proxy({
    target: 'http://couchdb:5984',
    changeOrigin: true,
    pathRewrite: {
        '^/api' : ''           // remove base path
    },
    logLevel: 'debug'
}));

app.listen(8080, () => console.log(`Example app listening on port ${port}!!!`));

Add nano & proxy access to couchdb


$(document).on('page:load', init_default_data_block);
$(document).ready(init_default_data_block);

function init_default_data_block() {
    $('.default_data_block .title').click(function () {
        toggle_default_data_bloc(this, 400);
    });

    $('.default_data_block.default_visible').each(function() {
        toggle_default_data_bloc($(this).find('.title'), 0);
    });

    function toggle_default_data_bloc(element, duration){
        var block = $(element).parents('.show-block');
        if (block.attr("id") == "messages") {
          block.children(".last-message").toggle();
        }

        block.children(".body").slideToggle(duration);

        block.find(".carret-right").toggle();
        block.find(".carret-down").toggle();
    }
}

$(document).on('page:load', init_default_data_block);
$(document).ready(init_default_data_block);

function init_default_data_block() {
    $('.default_data_block .title').click(function () {
        toggle_default_data_bloc(this, 400);
    });

    $('.new-action').click(function () {
        var messages_block = $(this).parents().closest(".default_data_block").find(".title")
        toggle_default_data_bloc(messages_block, 400);
    });

    $('.default_data_block.default_visible').each(function() {
        toggle_default_data_bloc($(this).find('.title'), 0);
    });

    function toggle_default_data_bloc(element, duration){
        var block = $(element).parents('.show-block');
        if (block.attr("id") == "messages") {
          block.children(".last-message").toggle();
        }

        block.children(".body").slideToggle(duration);

        block.find(".carret-right").toggle();
        block.find(".carret-down").toggle();
    }
}

Add new-action button to toggle default_block for messages


import moment from 'moment';

Template.dateCell.helpers({
  'formattedDate': function () {
    // Load the Finnish locale
    moment.locale('fi');

    // Create resident latest activity variable
    var activity = this;

    // Convert latest activity date to 'from now' format
    var activityDateFormatted = moment(activity.activityDate).fromNow();

    return activityDateFormatted;
  }
});

import moment from 'moment';

Template.dateCell.helpers({
  'formattedDate': function () {
    // Get client locale
    const clientLocale = TAPi18n.getLanguage();

    // Load the client locale into Moment
    moment.locale(clientLocale);

    // Create resident latest activity variable
    var activity = this;

    // Convert latest activity date to 'from now' format
    var activityDateFormatted = moment(activity.activityDate).fromNow();

    return activityDateFormatted;
  }
});

Use client locale for date format


import Ember from 'ember';
import RSVP from 'rsvp';
import WithDropzone from 'canvas-web/mixins/with-dropzone';
import layout from './template';
import styles from './styles';

const { inject, run } = Ember;

export default Ember.Component.extend(WithDropzone, {
  layout,
  localClassNames: ['teams-show-route'],
  styles,

  store: inject.service(),
  teamsList: inject.service(),

  disablePointer: Ember.String.htmlSafe('pointer-events: none'),

  processDrops({ dataTransfer }) {
    this.set('processingDrop', true);

    return this.readTemplates(dataTransfer).then(templates => {
      const uploads = templates.map(run.bind(this, 'uploadTemplate'));
      return RSVP.all(uploads);
    }).then(_ => {
      this.set('processingDrop', false);
    }).catch(err => {
      this.set('processingDrop', false);
      throw err;
    });
  },

  uploadTemplate(template) {
    const team = this.get('team');

    template.isTemplate = template.is_template;

    return this.get('store')
               .createRecord('canvas', Object.assign(template, { team }))
               .save();
  },

  actions: {
    didCreateCanvas(canvas) {
      this.sendAction('didCreateCanvas', canvas);
    }
  }
});

import Ember from 'ember';
import RSVP from 'rsvp';
import WithDropzone from 'canvas-web/mixins/with-dropzone';
import layout from './template';
import styles from './styles';

const { inject, run } = Ember;

export default Ember.Component.extend(WithDropzone, {
  layout,
  localClassNames: ['teams-show-route'],
  styles,

  store: inject.service(),
  teamsList: inject.service(),

  disablePointer: Ember.String.htmlSafe('pointer-events: none'),

  processDrops({ dataTransfer }) {
    this.set('processingDrop', true);

    return this.readTemplates(dataTransfer).then(templates => {
      const uploads = templates.map(run.bind(this, 'uploadTemplate'));
      return RSVP.all(uploads);
    }).then(_ => {
      this.set('processingDrop', false);
    }).catch(err => {
      this.set('processingDrop', false);
      throw err;
    });
  },

  uploadTemplate(template) {
    const team = this.get('team');

    Reflect.deleteProperty(template, 'id');
    template.isTemplate = template.is_template;

    return this.get('store')
               .createRecord('canvas', Object.assign(template, { team }))
               .save();
  },

  actions: {
    didCreateCanvas(canvas) {
      this.sendAction('didCreateCanvas', canvas);
    }
  }
});

Delete ID from template on drop


import express from 'express';

import * as User from '../../controllers/users';
import * as Recipe from '../../controllers/recipes';
import * as Favorite from '../../controllers/favorites';

import * as Auth from '../../middleware/auth';

const user = express.Router();

const newUser = new User.default();
const newRecipe = new Recipe.default();
const newFavorite = new Favorite.default();
const newAuth = new Auth.default();

user.post('/signup', newUser.signUp);
user.post('/signin', newUser.signIn);

user.use('*', newAuth.verify);
user.get('/myRecipes', newRecipe.getUserRecipes);

user.route('/:userId/recipes/:recipeId')
  .post(newFavorite.addToFavorite)
  .delete(newFavorite.removeFromFavorites);

user.get('/:userId/recipes', newFavorite.getFavRecipes);

export default user;

import express from 'express';

import * as User from '../../controllers/users';
import * as Recipe from '../../controllers/recipes';
import * as Favorite from '../../controllers/favorites';

import * as Auth from '../../middleware/auth';

const user = express.Router();

const newUser = new User.default();
const newRecipe = new Recipe.default();
const newFavorite = new Favorite.default();
const newAuth = new Auth.default();

user.post('/signup', newUser.signUp);
user.post('/signin', newUser.signIn);

user.use('*', newAuth.verify);
user.get('/myRecipes', newRecipe.getUserRecipes);

user.route('/:userId/profile')
  .get(newUser.getUser)

// TODO update user details and password routes
  .patch(newUser.getUser);
user.patch('/:userId/password', newUser.getUser);

user.route('/:userId/recipes/:recipeId')
  .post(newFavorite.addToFavorite)
  .delete(newFavorite.removeFromFavorites);

user.get('/:userId/recipes', newFavorite.getFavRecipes);

export default user;

Add get profile feature to backend


jQuery.noConflict(); // Allow the test to run with other libs or jQuery's.

// load testswarm agent
(function() {
	var url = window.location.search;
	url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
	if ( !url || url.indexOf("http") !== 0 ) {
		return;
	}
	document.write("<scr" + "ipt src='http://testswarm.com/js/inject.js?" + (new Date).getTime() + "'></scr" + "ipt>");
})();

jQuery.noConflict(); // Allow the test to run with other libs or jQuery's.

// load testswarm agent
(function() {
	var url = window.location.search;
	url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + 9 ) );
	if ( !url || url.indexOf("http") !== 0 ) {
		return;
	}
	document.write("<scr" + "ipt src='http://swarm.jquery.org/js/inject.js?" + (new Date).getTime() + "'></scr" + "ipt>");
})();

Update the TestSwarm URL to point to the new jQuery swarm location.


var _ = require('lodash');

function parseId(postData, type) {
  type = type || 'tags';
  return postData[type].data.map(function(t) { return t._id; });
}

function getSimilarityScore(arrA, arrB) {
  if (!arrA.length || !arrB.length) return 0;
  return _.intersection(arrA, arrB).length / (arrA.length + arrB.length);
}

function getPostSimilarity(postA, postB) {
  return getSimilarityScore(
    parseId(postA, 'tags'),
    parseId(postB, 'tags')
  ) + getSimilarityScore(
    parseId(postA, 'categories'),
    parseId(postB, 'categories')
  );
}

/**
 * Related Posts helper
 * @description Find related posts.
 * @example
 *      related_posts(post, 3);
 */

hexo.extend.helper.register('related_posts', function (target, max) {
  var posts, relatedPosts;

  max = max || 3;
  posts = hexo.locals.get('posts').data;

  return posts.map(function(p) {
    p.similarityScore = getPostSimilarity(target, p);
    return p;
  }).sort(function(a, b) {
    return b.similarityScore - a.similarityScore;
  }).filter(function(p) {
    return (p._id !== target._id) && (p.similarityScore > 0);
  }).slice(0, max);
});

var _ = require('lodash');

function parseId(postData, type) {
  type = type || 'tags';
  return postData[type].data.map(function(t) { return t._id; });
}

function getSimilarityScore(arrA, arrB) {
  if (!arrA.length || !arrB.length) return 0;
  return Math.sqrt(
    _.intersection(arrA, arrB).length / Math.max(arrA.length, arrB.length)
  );
}

function getPostSimilarity(postA, postB) {
  return getSimilarityScore(
    parseId(postA, 'tags'),
    parseId(postB, 'tags')
  ) * 2 + getSimilarityScore(
    parseId(postA, 'categories'),
    parseId(postB, 'categories')
  );
}

/**
 * Related Posts helper
 * @description Find related posts.
 * @example
 *      related_posts(post, 3);
 */

hexo.extend.helper.register('related_posts', function (target, max) {
  var posts, relatedPosts;

  max = max || 3;
  posts = hexo.locals.get('posts').data;

  return posts.map(function(p) {
    p.similarityScore = getPostSimilarity(target, p);
    return p;
  }).sort(function(a, b) {
    return b.similarityScore - a.similarityScore;
  }).filter(function(p) {
    return (p._id !== target._id) && (p.similarityScore > 0);
  }).slice(0, max);
});

Improve precision of related post s


module = module.exports = function (arr) {
    var len = arr.length,
        random,
        temp;

    while (len) {
        random = Math.floor(Math.random() * len);
        len -= 1;
        temp = arr[len];
        arr[len] = arr[random];
        arr[random] = temp;
    }

    return arr;
}

module = module.exports = function (arr) {
    var len = arr.length,
        random,
        temp;

    if (!Array.isArray(arr)) {
        throw new Error('shuffle-array expect an array as parameter.');
    }

    while (len) {
        random = Math.floor(Math.random() * len);
        len -= 1;
        temp = arr[len];
        arr[len] = arr[random];
        arr[random] = temp;
    }

    return arr;
}

Check if the given parameter is an array.


'use strict';
const execa = require('execa');
const getos = require('getos');
const pify = require('pify');

module.exports = () => {
	if (process.platform !== 'linux') {
		return Promise.reject(new Error('Only Linux systems are supported'));
	}

	return execa('lsb_release', ['-a', '--short']).then(res => {
		const stdout = res.stdout.split('\n');

		return {
			os: stdout[0],
			name: stdout[1],
			release: stdout[2],
			code: stdout[3]
		};
	}).catch(() => {
		return pify(getos)(res => {
			return {
				os: res.dist,
				name: `${res.dist} ${res.release}`,
				release: res.release,
				code: res.codename
			};
		});
	});
};

'use strict';
const execa = require('execa');
const getos = require('getos');
const pify = require('pify');

module.exports = () => {
	if (process.platform !== 'linux') {
		return Promise.reject(new Error('Only Linux systems are supported'));
	}

	return execa('lsb_release', ['-a', '--short']).then(res => {
		const stdout = res.stdout.split('\n');

		return {
			os: stdout[0],
			name: stdout[1],
			release: stdout[2],
			code: stdout[3]
		};
	}).catch(() => {
		return pify(getos).then(res => {
			return {
				os: res.dist,
				name: `${res.dist} ${res.release}`,
				release: res.release,
				code: res.codename
			};
		});
	});
};

Fix returned promise upon errors


'use strict';
const fs = require('fs');
const Discord = require('discord.js');

const Nix = require('./lib/nix');
const cfg = require('./config.js');

const discordClient = new Discord.Client();

let nix = new Nix(discordClient, cfg);

// Load every command in the commands folder
fs.readdirSync('./lib/commands')
  .forEach(file => {
    nix.addCommand(require('./lib/commands/' + file));
  });

nix.listen()
  .subscribe(
    () => {},
    (error) => onNixError(error),
    () => onNixComplete()
);

function onNixError(error) {
  console.error(error);
  nix.messageOwner('Unhandled error: ' + error)
    .subscribe(
      () => {},
      () => {},
      () => process.exit(1)
    )
}

function onNixComplete() {
  console.log('Shutting down');
  nix.messageOwner('Nix shutting down')
    .subscribe(
      () => {},
      () => {},
      () => process.exit(0)
    );
}

'use strict';
const fs = require('fs');
const Discord = require('discord.js');

const Nix = require('./lib/nix');
const cfg = require('./config.js');

const discordClient = new Discord.Client();

let nix = new Nix(discordClient, cfg);

// Load every command in the commands folder
fs.readdirSync('./lib/commands')
  .forEach(file => {
    nix.addCommand(require('./lib/commands/' + file));
  });

nix.listen()
  .subscribe(
    () => {},
    (error) => onNixError(error),
    () => onNixComplete()
);

function onNixError(error) {
  console.error(error);
  nix.messageOwner('Shutting down due to unhandled error: ' + error)
    .subscribe(
      () => {},
      () => {},
      () => process.exit(1)
    );
}

function onNixComplete() {
  console.log('Shutting down');
  nix.messageOwner('Nix shutting down')
    .subscribe(
      () => {},
      () => {},
      () => process.exit(0)
    );
}

Update final catch error message for the owner


var through = require('through2'),
    gutil = require('gulp-util'),
    po = require('node-po'),
    PluginError = gutil.PluginError;

module.exports = function () {

    function write (f, enc, cb){
        if (f.isNull()) {
            this.push(file);
            return cb();
        }

        if (f.isStream()) {
            this.emit('error', new PluginError('gulp-po-json',
                'Streaming not supported'));
            return cb();
        }

        var pofile = po.parse(f.contents.toString()),
            res = {},
            dic = {},
            i,
            l;

        if (!pofile) {
            this.emit('error', new PluginError('gulp-po-json',
                'Unable to parse file ' + f.path));
            return cb();
        }

        res.meta = pofile.headers;
        res.dic = dic;

        for (i = 0, l = pofile.items.length; i < l; i += 1) {
            res.dic[pofile.items[i].msgid] = pofile.items[i].msgstr[0];
        }
        this.push(JSON.stringify(res));
        cb();
    }

    function end (cb) {
        cb();
    }

    return through.obj(write, end);
};

var through = require('through2'),
    gutil = require('gulp-util'),
    po = require('node-po'),
    PluginError = gutil.PluginError;

module.exports = function () {

    function write (f, enc, cb){
        if (f.isNull()) {
            this.push(file);
            return cb();
        }

        if (f.isStream()) {
            this.emit('error', new PluginError('gulp-po-json',
                'Streaming not supported'));
            return cb();
        }

        var pofile = po.parse(f.contents.toString('utf-8')),
            res = {},
            dic = {},
            i,
            l;

        if (!pofile) {
            this.emit('error', new PluginError('gulp-po-json',
                'Unable to parse file ' + f.path));
            return cb();
        }

        res.meta = pofile.headers;
        res.dic = dic;

        for (i = 0, l = pofile.items.length; i < l; i += 1) {
            res.dic[pofile.items[i].msgid] = pofile.items[i].msgstr[0];
        }
        this.push(JSON.stringify(res));
        cb();
    }

    function end (cb) {
        cb();
    }

    return through.obj(write, end);
};

Make sure content of po files is read in utf8


import { NativeModules } from 'react-native';

const { RNTensorflow } = NativeModules;

class Tensorflow {

  initWithModel(modelFileName) {
    RNTensorflow.initTensorflow(modelFileName)
  }

  feedWithDims(inputName, src, dims) {
    RNTensorflow.feed(inputName, src, dims);
  }

  feed(inputName, src) {
    RNTensorflow.feed(inputName, src);
  }

  run(outputNames) {
    RNTensorflow.run(outputNames);
  }

  runWithStats(outputNames) {
    RNTensorflow.run(outputNames, true);
  }

  fetch(outputName, outputSize) {
    return RNTensorflow.fetch(outputName, dst);
  }

  graph() {
    return RNTensorflow.graph();
  }

  graphOperation(operationName) {
    return RNTensorflow.graphOperation(operationName);
  }

  stats() {
    return RNTensorflow.stats();
  }

  close() {
    RNTensorflow.close();
  }
}

export default new Tensorflow();

import { NativeModules } from 'react-native';

const { RNTensorflow } = NativeModules;

class Tensorflow {

  static initWithModel(modelFileName, cb) {
    tensorflow = new Tensorflow(modelFileName)
    cb(tensorflow)
    tensorflow.close()
  }

  constructor(modelFileName) {
    super()
    RNTensorflow.initTensorflow(modelFileName)
  }

  feedWithDims(inputName, src, dims) {
    RNTensorflow.feed(inputName, src, dims);
  }

  feed(inputName, src) {
    RNTensorflow.feed(inputName, src);
  }

  run(outputNames) {
    RNTensorflow.run(outputNames);
  }

  runWithStats(outputNames) {
    RNTensorflow.run(outputNames, true);
  }

  fetch(outputName, outputSize) {
    return RNTensorflow.fetch(outputName, dst);
  }

  graph() {
    return RNTensorflow.graph();
  }

  stats() {
    return RNTensorflow.stats();
  }

  close() {
    RNTensorflow.close();
  }
}

export default Tensorflow;

Allow multiple tensorflow instances in js


/* eslint-env node */
'use strict';

var Append = require('./lib/broccoli-append');
var path = require('path');

module.exports = {
  name: 'ember-qunit-assert-helpers',

  postprocessTree(type, tree) {
    this._requireBuildPackages();
    if (type === 'all' && this.app.tests) {
      var appendPath = path.join(__dirname, '/vendor/ember-qunit-assert-helpers-loader.js');
      return new Append(tree, /test-support[A-Za-z0-9-]*/, appendPath);
    } else {
      return tree;
    }
  }
};

/* eslint-env node */
'use strict';

var Append = require('./lib/broccoli-append');
var path = require('path');

module.exports = {
  name: 'ember-qunit-assert-helpers',

  postprocessTree(type, tree) {
    if (this._requireBuildPackages) {
      this._requireBuildPackages();
    }

    if (type === 'all' && this.app.tests) {
      var appendPath = path.join(__dirname, '/vendor/ember-qunit-assert-helpers-loader.js');
      return new Append(tree, /test-support[A-Za-z0-9-]*/, appendPath);
    } else {
      return tree;
    }
  }
};

Check if `_requireBuildPackages()` exists before calling it


'use strict';
var postcssCached = require('postcss-cached');
var through = require('through2');
var applySourceMap = require('vinyl-sourcemans-apply');
var gulpUtil = require('gulp-util');

module.exports = function(options) {
  options = Object(options);
  var postcssCachedInstance = postcssCached();

  var gulpPlugin = through.obj(function(file, encoding, callback) {
    var fileOptions = Object(options);
    fileOptions.from = file.path;
    fileOptions.map = fileOptions.map || file.sourceMap;

    try {
      var result = postcssCachedInstance
        .processCss(file.contents.toString('utf8'), fileOptions);
      file.contents = new Buffer(result.css);
      if (fileOptions.map) {
        applySourceMap(file, result.map);
      }
      this.push(file);
      callback();
    } catch(e) {
      callback(new gulpUtil.PluginError('gulp-postcss-cached', e));
    }
  });

  gulpPlugin.use = postcssCachedInstance.use.bind(postcssCachedInstance);

  return gulpPlugin;
};

'use strict';
var postcssCached = require('postcss-cached');
var through = require('through2');
var applySourceMap = require('vinyl-sourcemaps-apply');
var gulpUtil = require('gulp-util');

module.exports = function(options) {
  options = Object(options);
  var postcssCachedInstance = postcssCached();

  var gulpPlugin = through.obj(function(file, encoding, callback) {
    var fileOptions = Object(options);
    fileOptions.from = file.path;
    fileOptions.map = fileOptions.map || file.sourceMap;

    try {
      var result = postcssCachedInstance
        .processCss(file.contents.toString('utf8'), fileOptions);
      file.contents = new Buffer(result.css);
      if (fileOptions.map) {
        applySourceMap(file, result.map);
      }
      this.push(file);
      callback();
    } catch(e) {
      callback(new gulpUtil.PluginError('gulp-postcss-cached', e));
    }
  });

  gulpPlugin.use = postcssCachedInstance.use.bind(postcssCachedInstance);

  return gulpPlugin;
};

Fix typo in require statement


var cookie = require('cookie');

var _cookies = cookie.parse((typeof document !== 'undefined') ? document.cookie : '');

for (var key in _cookies) {
  try {
    _cookies[key] = JSON.parse(_cookies[key]);
  } catch(e) {
    // Not serialized object
  }
}

function load(name) {
  return _cookies[name];
}

function save(name, val, opt) {
  _cookies[name] = val;

  // Cookies only work in the browser
  if (typeof document === 'undefined') return;

  // allow you to work with cookies as objects.
  if (typeof val === 'object') val = JSON.stringify(val);

  document.cookie = cookie.serialize(name, val, opt);
}

function remove(name) {
  if (typeof document === 'undefined') return;
  document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}

var reactCookie = {
  load: load,
  save: save,
  remove: remove
};

if (typeof module !== 'undefined') {
  module.exports = reactCookie
}

if (typeof window !== 'undefined') {
  window['reactCookie'] = reactCookie;
}

var cookie = require('cookie');

var _cookies = cookie.parse((typeof document !== 'undefined') ? document.cookie : '');

for (var key in _cookies) {
  try {
    _cookies[key] = JSON.parse(_cookies[key]);
  } catch(e) {
    // Not serialized object
  }
}

function load(name) {
  return _cookies[name];
}

function save(name, val, opt) {
  _cookies[name] = val;

  // Cookies only work in the browser
  if (typeof document === 'undefined') return;

  // allow you to work with cookies as objects.
  // make sure a serialized value returns as serialized again
  if (typeof val === 'object' || typeof val === 'string') val = JSON.stringify(val);

  document.cookie = cookie.serialize(name, val, opt);
}

function remove(name) {
  if (typeof document === 'undefined') return;
  document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}

var reactCookie = {
  load: load,
  save: save,
  remove: remove
};

if (typeof module !== 'undefined') {
  module.exports = reactCookie
}

if (typeof window !== 'undefined') {
  window['reactCookie'] = reactCookie;
}

Make sure serialized content don't get unserialized


const redis = require('./redis');
const config = require('../config/index.js');

const getRequest = async (requestId) => {
  // Set TTL for request
  redis.expire(`requests:${requestId}`, config('requests_ttl'));
  return await redis.hgetallAsync(`requests:${requestId}`);
};

const createRequest = async (requestDetails) => {
  // get new unique id for request
  const requestId = await redis.incrAsync('next_request_id');

  // create a new request entry in Redis
  const {user_id, pickup, dropoff, requested_pickup_time, size, weight} = requestDetails;
  const [pickup_lat, pickup_long] = pickup.split(',');
  const [dropoff_lat, dropoff_long] = dropoff.split(',');
  redis.hmsetAsync(`requests:${requestId}`,
    'user_id', user_id,
    'pickup_lat', pickup_lat,
    'pickup_long', pickup_long,
    'dropoff_lat', dropoff_lat,
    'dropoff_long', dropoff_long,
    'requested_pickup_time', requested_pickup_time,
    'size', size,
    'weight', weight,
  );

  // Set TTL for request
  redis.expire(`requests:${requestId}`, 43200);
  return requestId;
};

const deleteRequest = async (requestId) => {
  return await redis.del(`requests:${requestId}`);
};

module.exports = {
  createRequest,
  getRequest,
  deleteRequest
};

const redis = require('./redis');
const config = require('../config');

const getRequest = async (requestId) => {
  // Set TTL for request
  redis.expire(`requests:${requestId}`, config('requests_ttl'));
  return await redis.hgetallAsync(`requests:${requestId}`);
};

const createRequest = async (requestDetails) => {
  // get new unique id for request
  const requestId = await redis.incrAsync('next_request_id');

  // create a new request entry in Redis
  const {user_id, pickup, dropoff, requested_pickup_time, size, weight} = requestDetails;
  const [pickup_lat, pickup_long] = pickup.split(',');
  const [dropoff_lat, dropoff_long] = dropoff.split(',');
  redis.hmsetAsync(`requests:${requestId}`,
    'user_id', user_id,
    'pickup_lat', pickup_lat,
    'pickup_long', pickup_long,
    'dropoff_lat', dropoff_lat,
    'dropoff_long', dropoff_long,
    'requested_pickup_time', requested_pickup_time,
    'size', size,
    'weight', weight,
  );

  // Set TTL for request
  redis.expire(`requests:${requestId}`, config('requests_ttl'));
  return requestId;
};

const deleteRequest = async (requestId) => {
  return await redis.del(`requests:${requestId}`);
};

module.exports = {
  createRequest,
  getRequest,
  deleteRequest
};

Remove another constant and shorten require path


var OpenLayersPlusLegend = {};

OpenLayersPlusLegend = {};

OpenLayersPlusLegend.attach = function(context) {
  var data = $(context).data('openlayers');
  if (data && data.map.behaviors.openlayers_plus_behavior_legend) {
    var layer, i;
    for (i in data.openlayers.layers) {
      layer = data.openlayers.layers[i];
      if (data.map.behaviors.openlayers_plus_behavior_legend[layer.drupalID]) {
        if (!$('div.openlayers-legends', context).size()) {
          $(context).append("

");
        }
        layer.events.register('visibilitychanged', layer, OpenLayersPlusLegend.setLegend);

        // Trigger the setLegend() method at attach time. We don't know whether
        // our behavior is being called after the map has already been drawn.
        OpenLayersPlusLegend.setLegend(layer);
      }
    }
  }
};

OpenLayersPlusLegend.setLegend = function(layer) {
  // The layer param may vary based on the context from which we are called.
  layer = layer.object ? layer.object : layer;

  var name = layer.drupalID;
  var map = $(layer.map.div);
  var data = map.data('openlayers');
  var legend = data.map.behaviors.openlayers_plus_behavior_legend[name];
  var legends = $('div.openlayers-legends', map);
  if (layer.visibility && $('#openlayers-legend-'+ name, legends).size() === 0) {
    legends.append(legend);
  }
  else if (!layer.visibility) {
    $('#openlayers-legend-'+name, legends).remove();
  }
};

var OpenLayersPlusLegend = function(opts) {
    var self = this;
    this.map = $(opts[0]).data('map');

    this.setLegend = function(layer) {
        // The layer param may vary based on the context from which we are called.
        layer = layer.object ? layer.object : layer;
        if ('legend' in layer) {
            var legend_content = layer.legend || 'your mother';
            var legends = $('div.openlayers-legends', self.map.div);
            if (layer.visibility && !('legendDiv' in layer)) {
                layer.legendDiv = $("

").append(legend_content);
                legends.append(layer.legendDiv);
            }
            else if (!layer.visibility && ('legendDiv' in layer)) {
                layer.legendDiv.remove();
                delete layer.legendDiv;
            }
        }
    };

    this.map.layers.forEach(function (layer) {
        if (!$('div.openlayers-legends', self.map.div).size()) {
            $(self.map.div).append("

");
        }
        layer.events.register('visibilitychanged', layer, self.setLegend);
        self.setLegend(layer);
    });
};

Rewrite OL+ legend to be non-drupaly.


module.exports = function(grunt) {
  "use strict";

  // Project configuration.
  grunt.initConfig({
    pkg: '<json:package.json>',

    test: {
      files: ['test/**/*.js']
    },

    lint: {
      files: ['grunt.js', 'lib/**/*.js', 'test/**/*.js']
    },

    watch: {
      files: '<config:lint.files>',
      tasks: 'default'
    },

    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        node: true,
        es5: true
      },
      globals: {
        exports: true
      }
    },

    server: {
      app: {
        src: './lib/server.js',
        port: 8000,
        watch: './lib/letternode.js'
      }
    }
  });

  grunt.loadNpmTasks('grunt-hustler');

  // Default task.
  grunt.registerTask('default', 'lint test');

  grunt.registerTask('dev', 'lint test watch');

};

module.exports = function(grunt) {
  "use strict";

  // Project configuration.
  grunt.initConfig({
    pkg: '<json:package.json>',

    test: {
      files: ['test/**/*.js']
    },

    lint: {
      files: ['grunt.js', 'lib/**/*.js', 'test/**/*.js']
    },

    watch: {
      files: '<config:lint.files>',
      tasks: 'default'
    },

    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        node: true,
        es5: true
      },
      globals: {
        exports: true
      }
    },

    server: {
      app: {
        src: './lib/server.js',
        port: 8000,
        watch: './lib/**/*.js'
      }
    }
  });

  grunt.loadNpmTasks('grunt-hustler');

  // Default task.
  grunt.registerTask('default', 'lint test');

  grunt.registerTask('dev', 'lint test watch');

};

Add all javascript sources to server-watcher.


'use strict'

function ReInterval (callback, interval, args) {
  var self = this;

  this._callback = callback;
  this._args = args;

  this._interval = setInterval(callback, interval, this._args);

  this.reschedule = function (interval) {

    var now = Date.now();
    if (self._interval)
      clearInterval(self._interval);
    self._interval = setInterval(self._callback, interval, self._args);
  };

  this.clear = function () {
    if (self._interval) {
      clearInterval(self._interval);
      self._interval = undefined;
      self._callback = undefined;
      self._args = undefined;
    }
  };
}

function reInterval () {
  if (typeof arguments[0] !== 'function')
    throw new Error('callback needed');
  if (typeof arguments[1] !== 'number')
    throw new Error('interval needed');

  var args;

  if (arguments.length > 0) {
    args = new Array(arguments.length - 2);

    for (var i = 0; i < args.length; i++) {
      args[i] = arguments[i + 2];
    }
  }

  return new ReInterval(arguments[0], arguments[1], args);
}

module.exports = reInterval;

'use strict'

function ReInterval (callback, interval, args) {
  var self = this;

  this._callback = callback;
  this._args = args;

  this._interval = setInterval(callback, interval, this._args);

  this.reschedule = function (interval) {
    // if no interval entered, use the interval passed in on creation
    if (!interval)
      interval = self._interval;

    if (self._interval)
      clearInterval(self._interval);
    self._interval = setInterval(self._callback, interval, self._args);
  };

  this.clear = function () {
    if (self._interval) {
      clearInterval(self._interval);
      self._interval = undefined;
    }
  };

  this.destroy = function () {
    if (self._interval) {
      clearInterval(self._interval);
    }
    self._callback = undefined;
    self._interval = undefined;
    self._args = undefined;
  };
}

function reInterval () {
  if (typeof arguments[0] !== 'function')
    throw new Error('callback needed');
  if (typeof arguments[1] !== 'number')
    throw new Error('interval needed');

  var args;

  if (arguments.length > 0) {
    args = new Array(arguments.length - 2);

    for (var i = 0; i < args.length; i++) {
      args[i] = arguments[i + 2];
    }
  }

  return new ReInterval(arguments[0], arguments[1], args);
}

module.exports = reInterval;

Update Reschedule and Clear functions, create Destroy function.


import React from 'react'
import Document, { Head, Main, NextScript } from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    const sheet = new ServerStyleSheet()
    const page = renderPage((App) => (props) =>
      sheet.collectStyles(<App {...props} />)
    )
    const styleTags = sheet.getStyleElement()
    return { ...page, styleTags }
  }

  render() {
    return (
      <html lang="en">
        <Head>
          <title>Styled MDL</title>
          {this.props.styleTags}
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}

import React from 'react'
import Document, { Head, Main, NextScript } from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    const sheet = new ServerStyleSheet()
    const page = renderPage((App) => (props) =>
      sheet.collectStyles(<App {...props} />)
    )
    const styleTags = sheet.getStyleElement()
    return { ...page, styleTags }
  }

  render() {
    return (
      <html lang="en">
        <Head>
          <title>Styled MDL</title>
          <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700" rel="stylesheet" />
          {this.props.styleTags}
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    )
  }
}

Include roboto font in app head - DW


var _ = require('underscore');
var AWS = require('aws-sdk');
var moment = require('moment');
var path = require('path');
var async = require('async');

var Uploader = require('s3-streaming-upload').Uploader;

var DynamoBackup = require('./lib/dynamo-backup');

var runningAsScript = require.main === module;

if (runningAsScript) {
    var dynamoBackup = new DynamoBackup({ bucket: 'markitx-backups-test', stopOnFailure: true, readPercentage: .5, includedTables: ['development-asset-projects'] });
    dynamoBackup.on('error', function(data) {
        console.log('Error backing up ' + data.tableName);
        console.log(data.error);
        process.exit();
    });

    dynamoBackup.backupAllTables(function() {
        console.log('Finished backing up DynamoDB');
    });
} else {
    module.exports = DynamoBackup;
}

var _ = require('underscore');
var AWS = require('aws-sdk');
var moment = require('moment');

var DynamoBackup = require('./lib/dynamo-backup');

var runningAsScript = require.main === module;

if (runningAsScript) {
    var runTimes = {};

    var dynamoBackup = new DynamoBackup({ bucket: 'markitx-backups-test', stopOnFailure: true, readPercentage: .5 });
    dynamoBackup.on('error', function(data) {
        console.log('Error backing up ' + data.tableName);
        console.log(data.error);
        process.exit();
    });
    dynamoBackup.on('start-backup', function(tableName) {
        runTimes[tableName] = moment();
        console.log('Starting to copy table ' + tableName);
    });
    dynamoBackup.on('end-backup', function(tableName) {
        var endTime = moment();
        var startTime = runTimes[tableName];
        console.log('Done copying table ' + tableName + '. Took ' + endTime.diff(startTime, 'minutes', true).toFixed(2) + ' minutes');
    });

    dynamoBackup.backupAllTables(function() {
        console.log('Finished backing up DynamoDB');
    });
} else {
    module.exports = DynamoBackup;
}

Add console logging to script


var stringsAndFlowComments = /(`(?:.|\s)*?`|'(?:.|\s)*?'|`(?:.|\s)*?`|"(?:.|\s)*?"|\/\*.*?(?::{1,2}|flow-include).*?(?:.|\s)*?\*\/)/;

function removeComments(code){
	return code.split(stringsAndFlowComments)
	.map( function(chunk){
		if(chunk.trim().search(/\/\*.*?(?::{1,2}|flow-include).*?(?:.|\s)*?\*\//) === 0){
			var include = /\/\*.*?(?::{2}|flow-include)(.*?(?:.|\s)*)\*\//;
			var inline  = /\/\*(.*?:.*?(?:.|\s)*)\*\//;
			var pattern = include.test(chunk) ? include : inline;

			var flowInside = pattern.exec(chunk);
			if(flowInside && flowInside.length >= 2 && flowInside[1].length > 0){
				return flowInside[1];
			}
		}
		return chunk;
	}).join('');
}

module.exports = removeComments;

var stringsAndFlowComments = /(`(?:[^`\\]|\\.)*?`|'(?:[^'\\]|\\.)*?'|"(?:[^"\\]|\\.)*?"|\/\*.*?(?::{1,2}|flow-include).*?[\s\S]*?\*\/)/;

function removeComments(code){
	return code.split(stringsAndFlowComments)
	.map( function(chunk){
		if(chunk.trim().search(/\/\*.*?(?::{1,2}|flow-include).*?[\s\S]*?\*\//) === 0){
			var include = /\/\*.*?(?::{2}|flow-include)(.*?[\s\S]*)\*\//;
			var inline  = /\/\*(.*?:.*?[\s\S]*)\*\//;
			var pattern = include.test(chunk) ? include : inline;

			var flowInside = pattern.exec(chunk);
			if(flowInside && flowInside.length >= 2 && flowInside[1].length > 0){
				return flowInside[1];
			}
		}
		return chunk;
	}).join('');
}

module.exports = removeComments;

Make the regexp a bit more efficient and correct


'use strict'

var through = require('through2')

module.exports = function (/*streams...*/) {
  var firstTick = true;
  var sources = []
  var output  = through.obj()
  var args = arguments

  if (args[0] instanceof Array){
    args = args[0]
  }

  output.setMaxListeners(0)

  output.add = add

  output.on('unpipe', remove)

  Array.prototype.slice.call(args).forEach(add)

  return output

  function add (source) {
    sources.push(source)
    source.once('end', remove.bind(null, source))
    source.pipe(output, {end: false})
    return source
  }

  function remove (source) {
    sources = sources.filter(function (it) { return it !== source })
    if (!sources.length && output.readable) { output.emit('end') }
  }
}

'use strict'

var through = require('through2')

module.exports = function (/*streams...*/) {
  var firstTick = true;
  var sources = []
  var output  = through.obj()

  output.setMaxListeners(0)

  output.add = add

  output.on('unpipe', remove)

  Array.prototype.slice.call(arguments).forEach(add)

  return output

  function add (stream_or_arr) {
    var new_sources = stream_or_arr instanceof Array ? stream_or_arr : [stream_or_arr]
    sources = sources.concat(new_sources)

    Array.prototype.slice.call(new_sources).forEach(function (source) {
      source.once('end', remove.bind(null, source))
      source.pipe(output, {end: false})
    })
    return this
  }

  function remove (source) {
    sources = sources.filter(function (it) { return it !== source })
    if (!sources.length && output.readable) { output.emit('end') }
  }
}

Move the array handling logic into `add`


var Pagemaki = require("pagemaki");
var Buffer = require("buffer").Buffer;
var through = require("through");

/**
 * Returns a file handling function that can
 * be piped to from within a gulp workflow
 *
 * @return {[type]} [description]
 */
module.exports = function (options) {

  var maker = new Pagemaki(options);

  function write(file) {

    var stream = this;

    if (!file._contents) {
      return;
    }

    maker.make({
      contents: file._contents.toString(),
      extension: file.relative.split(".").pop()
    }, function (err, made) {
      file._contents = new Buffer(made);
      stream.queue(file);
    });

  }

  return through(write);

};

var Pagemaki = require("pagemaki");
var Buffer = require("buffer").Buffer;
var through = require("through");

/**
 * Returns a file handling function that can
 * be piped to from within a gulp workflow
 *
 * @return {[type]} [description]
 */
module.exports = function (options) {

  var maker = new Pagemaki(options);

  function write(file) {

    var stream = this;

    if (!file._contents) {
      return;
    }

    maker.make({
      contents: file._contents.toString(),
      extension: file.relative.split(".").pop()
    }, function (err, made) {
      file._contents = new Buffer(made);
      file.path = file.path.replace(/\.markdown$/, ".html");
      stream.queue(file);
    });

  }

  return through(write);

};

Switch .markdown extension to .html after conversion


'use strict';

var domain = require('domain');

var eos = require('end-of-stream');
var tick = require('next-tick');
var once = require('once');
var exhaust = require('stream-exhaust');

function noop(){}

function asyncDone(fn, cb){
  cb = once(cb);

  var d = domain.create();
  d.once('error', onError);
  var domainBoundFn = d.bind(fn);

  function done(error, result){
    d.removeListener('error', onError);
    d.exit();
    return cb(error, result);
  }

  function onSuccess(result){
    return done(null, result);
  }

  function onError(error){
    return done(error);
  }

  function asyncRunner(){
    var result = domainBoundFn(done);

    if(result && typeof result.on === 'function'){
      // assume node stream
      d.add(result);
      eos(exhaust(result), { error: false }, onSuccess);
      return;
    }

    if(result && typeof result.subscribe === 'function'){
      // assume RxJS observable
      result.subscribe(noop, onError, onSuccess);
      return;
    }

    if(result && typeof result.then === 'function'){
      // assume promise
      result.then(onSuccess, onError);
      return;
    }
  }

  tick(asyncRunner);
}

module.exports = asyncDone;

'use strict';

var domain = require('domain');

var eos = require('end-of-stream');
var tick = require('next-tick');
var once = require('once');
var exhaust = require('stream-exhaust');

function noop(){}

var eosConfig = {
  error: false
};

function asyncDone(fn, cb){
  cb = once(cb);

  var d = domain.create();
  d.once('error', onError);
  var domainBoundFn = d.bind(fn);

  function done(error, result){
    d.removeListener('error', onError);
    d.exit();
    return cb(error, result);
  }

  function onSuccess(result){
    return done(null, result);
  }

  function onError(error){
    return done(error);
  }

  function asyncRunner(){
    var result = domainBoundFn(done);

    if(result && typeof result.on === 'function'){
      // assume node stream
      d.add(result);
      eos(exhaust(result), eosConfig, onSuccess);
      return;
    }

    if(result && typeof result.subscribe === 'function'){
      // assume RxJS observable
      result.subscribe(noop, onError, onSuccess);
      return;
    }

    if(result && typeof result.then === 'function'){
      // assume promise
      result.then(onSuccess, onError);
      return;
    }
  }

  tick(asyncRunner);
}

module.exports = asyncDone;

Reduce object creation for end-of-stream options


'use strict'

require("babel-core/register")
require("babel-polyfill")

const convert = require('pinyin-convert')
const split = require('pinyin-split')

const execute = () => {
	const text = document.querySelector('#input').value
	if (text) {
		const re = /^[a-züāáǎàēéěèōóǒòūúǔùīíǐì]+$/i
		if (re.test(text)) {
			split(text).then((data) => {
				document.querySelector('#output').innerHTML = data.join(' ')
			}, console.log)
		} else {
			convert(text, {keepSpaces: true}).then((data) => {
				document.querySelector('#output').innerHTML = data
			}, console.log)
		}
	}
}

document.querySelector('#convert').addEventListener('click', execute)

document.querySelector('#input').addEventListener('keyup', (event) => {
	if (event.keyCode == 13) {
		event.preventDefault()
		execute()
	}
})

'use strict'

require("babel-core/register")
require("babel-polyfill")

const pinyin = require('pinyin-api')

const execute = () => {
	const text = document.querySelector('#input').value
	if (text) {
		const re = /^[a-züāáǎàēéěèōóǒòūúǔùīíǐì]+$/i
		if (re.test(text)) {
			pinyin.split(text).then((data) => {
				document.querySelector('#output').innerHTML = data.join(' ')
			}, console.log)
		} else {
			pinyin.convert(text, {keepSpaces: true}).then((data) => {
				document.querySelector('#output').innerHTML = data
			}, console.log)
		}
	}
}

document.querySelector('#convert').addEventListener('click', execute)

document.querySelector('#input').addEventListener('keyup', (event) => {
	if (event.keyCode == 13) {
		event.preventDefault()
		execute()
	}
})

Update to use new module pinyin-api


module.exports = {

  port: 1337,
  serverUrl: process.env.SERVER_URL || 'http://127.0.0.1:1337'

};

module.exports = {

  port: 1337,
  serverUrl: process.env.SERVER_URL || 'http://127.0.0.1:1337',

  hookTimeout: 180000

};

Increase hook timeout to 3 min


const Buffer = require('safe-buffer').Buffer
const utils = require('ethereumjs-util')

module.exports = {
  getBlock: function (blockTag, cb) {
    var hash

    if (Buffer.isBuffer(blockTag)) {
      hash = utils.sha3(blockTag)
    } else if (Number.isInteger(blockTag)) {
      hash = utils.sha3(utils.toBuffer(blockTag).toString('hex'))
    } else {
      cb(new Error('Unknown blockTag type'))
    }

    var block = {
      hash: function () {
        return hash
      }
    }

    cb(null, block)
  },

  delBlock: function (hash, cb) {
    cb(null)
  }
}

const Buffer = require('safe-buffer').Buffer
const utils = require('ethereumjs-util')

module.exports = {
  getBlock: function (blockTag, cb) {
    var hash

    if (Buffer.isBuffer(blockTag)) {
      hash = utils.sha3(blockTag)
    } else if (Number.isInteger(blockTag)) {
      hash = utils.sha3('0x' + utils.toBuffer(blockTag).toString('hex'))
    } else {
      cb(new Error('Unknown blockTag type'))
    }

    var block = {
      hash: function () {
        return hash
      }
    }

    cb(null, block)
  },

  delBlock: function (hash, cb) {
    cb(null)
  }
}

Add 0x to blockhash generation in getBlock for fakeBlockchain for consistent hashes


pageflow.ConfigurationEditorView.register('audio_loop', {
  configure: function() {
    this.tab('general', function() {
      this.group('general');

      this.input('additional_title', pageflow.TextInputView);
      this.input('additional_description', pageflow.TextAreaInputView, {size: 'short'});
    });

    this.tab('files', function() {
      this.input('audio_file_id', pageflow.FileInputView, {collection: pageflow.audioFiles});
      this.input('background_image_id', pageflow.FileInputView, {collection: pageflow.imageFiles});
      this.input('thumbnail_image_id', pageflow.FileInputView, {
        collection: pageflow.imageFiles,
        positioning: false
      });
    });

    this.tab('options', function() {
      this.group('options');
    });
  }
});

pageflow.ConfigurationEditorView.register('audio_loop', {
  configure: function() {
    this.tab('general', function() {
      this.group('general');
    });

    this.tab('files', function() {
      this.input('audio_file_id', pageflow.FileInputView, {collection: pageflow.audioFiles});
      this.input('background_image_id', pageflow.FileInputView, {collection: pageflow.imageFiles});
      this.input('thumbnail_image_id', pageflow.FileInputView, {
        collection: pageflow.imageFiles,
        positioning: false
      });
    });

    this.tab('options', function() {
      this.group('options');
    });
  }
});

Remove Additional Info Box Fields for Audio Loop Page


/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
({
    testEmptyItems:{
        test:function(cmp){
            var element = cmp.getElement();
            $A.test.assertTrue(element.className.indexOf("uiMessage")!=-1, "Expected to see a message to indicate no data.");
            $A.test.assertEquals("No data found.", $A.test.getText(element).trim(), "Message to indicate no data is absent or incorrect");
        }
    }
})

/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
({
    testEmptyItems:{
        test:function(cmp){
            var element = cmp.getElement();
            $A.test.assertTrue($A.util.hasClass(element, "uiMessage"), "Expected to see a message to indicate no data.");
            var text = $A.test.getText(element);
            $A.test.assertEquals("No data found.", $A.util.trim(text), "Message to indicate no data is absent or incorrect");
        }
    }
})

Use our $A.util classes for browser compat


/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-cli-trackjs',

  contentFor: function (type, config) {
    var trackOpts;
    var trackConfig;
    var trackConfiguration;
    var trackBoilerPlate;
    var addonConfig;

    if (type === 'head') {
      trackOpts = config.trackJs || {};
      trackConfig = trackOpts.config || {};

      trackConfiguration = '<script type="text/javascript" id="trackjs-configuration">window._trackJs = ' + JSON.stringify(trackConfig) + ';</script>';

      if (trackOpts.url) {
        trackBoilerPlate = '<script type="text/javascript" id="trackjs-boilerplate" src="' + trackOpts.url + '" crossorigin="anonymous"></script>';
      }

      return [trackConfiguration, trackBoilerPlate].join('\n');
    }
  },

  included: function (app) {
    this._super.included(app);

    var options = app.options['ember-cli-trackjs'];

    if (!(options && options.cdn)) {
      app.import(app.bowerDirectory + '/trackjs/tracker.js');
    }
  }
};

/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-cli-trackjs',

  contentFor: function (type, config) {
    var trackOpts;
    var trackConfig;
    var trackConfiguration;
    var trackBoilerPlate;
    var addonConfig;

    if (type === 'head-footer') {
      trackOpts = config.trackJs || {};
      trackConfig = trackOpts.config || {};

      trackConfiguration = '<script type="text/javascript" id="trackjs-configuration">window._trackJs = ' + JSON.stringify(trackConfig) + ';</script>';

      if (trackOpts.url) {
        trackBoilerPlate = '<script type="text/javascript" id="trackjs-boilerplate" src="' + trackOpts.url + '" crossorigin="anonymous"></script>';
      }

      return [trackConfiguration, trackBoilerPlate].join('\n');
    }
  },

  included: function (app) {
    this._super.included(app);

    var options = app.options['ember-cli-trackjs'];

    if (!(options && options.cdn)) {
      app.import(app.bowerDirectory + '/trackjs/tracker.js');
    }
  }
};

Insert Script Tag at Foot of the `<head>` Tag


'use strict'

var toArray = require('stream-to-array')
var Promise = require('bluebird')

module.exports = streamToPromise

function streamToPromise (stream) {
  var promise
  if (stream.readable) {
    promise = fromReadable(stream)
  } else if (stream.writable) {
    promise = fromWritable(stream)
  } else {
    promise = Promise.resolve()
  }
  return promise
}

function fromReadable (stream) {
  var promise = toArray(stream)

  // Ensure stream is in flowing mode
  stream.resume()

  return promise
    .then(function (parts) {
      var buffers = []
      for (var i = 0, l = parts.length; i < l; ++i) {
        var part = parts[i]
        buffers.push((part instanceof Buffer) ? part : new Buffer(part))
      }
      return Buffer.concat(buffers)
    })
}

function fromWritable (stream) {
  return new Promise(function (resolve, reject) {
    stream.once('finish', resolve)
    stream.once('error', reject)
  })
}

'use strict'

var toArray = require('stream-to-array')
var Promise = require('bluebird')

module.exports = streamToPromise

function streamToPromise (stream) {
  var promise
  if (stream.readable) {
    promise = fromReadable(stream)
  } else if (stream.writable) {
    promise = fromWritable(stream)
  } else {
    promise = Promise.resolve()
  }
  return promise
}

function fromReadable (stream) {
  var promise = toArray(stream)

  // Ensure stream is in flowing mode
  stream.resume()

  return promise
    .then(function concat (parts) {
      return Buffer.concat(parts.map(bufferize))
    })
}

function fromWritable (stream) {
  return new Promise(function (resolve, reject) {
    stream.once('finish', resolve)
    stream.once('error', reject)
  })
}

function bufferize (chunk) {
  return Buffer.isBuffer(chunk) ? chunk : new Buffer(chunk)
}

Simplify readable concat w/ Buffer.isBuffer and [].map


/**
 * External dependencies.
 */

var mongoose = require('mongoose');

/**
 * Drop all known mongoose collections before
 * each test.
 *
 * @param {Object} hydro
 * @api public
 */

module.exports = function(hydro) {
  hydro.on('pre:test', function(file, done) {
    var collections = Object.keys(mongoose.connection.collections);
    var len = collections.length;
    if (len === 0) return done();
    collections.forEach(function(collection) {
      mongoose.connection.collections[collection].drop(function() {
        if (--len === 0) done();
      });
    });
  });
};

/**
 * External dependencies.
 */

var mongoose = require('mongoose');

/**
 * Drop all known mongoose collections before
 * each test.
 *
 * @param {Object} hydro
 * @api public
 */

module.exports = function(hydro) {
  hydro.on('pre:test', function(file, done) {
    var collections = Object.keys(mongoose.connection.collections);
    var len = collections.length;
    if (len === 0) return done();

    var timeout = setTimeout(function() {
      throw new Error('mongoose collections drop took more than 2s. Make sure that you have established a database connection');
    }, 2000);

    var end = function() {
      clearTimeout(timeout);
      done();
    };

    collections.forEach(function(collection) {
      mongoose.connection.collections[collection].drop(function() {
        if (--len === 0) end();
      });
    });
  });
};

Throw an error if dropping the collections took more than 2s


var delim = "---\n";
var assign = require('object-assign');

module.exports = function(converter) {

    return function (pages, done) {

        try {

            pages.forEach(function(page){

                var content = page.content;

                var frontmatter;

                content = content.split(delim);

                if(content.length > 1) {

                    frontmatter = converter(content[1]);

                    page = assign(page, frontmatter);

                    content = content.slice(2);
                }

                page.content = content.join(delim);
            });

            done(null, pages);
        }
        catch(e) {

            done(e);
        }
    };
};

var assign = require('object-assign');

module.exports = function(converter, delim) {

    delim = delim || '---';

    return function (pages, done) {

        try {

            pages.forEach(function(page){

                var content = page.content;

                var frontmatter;

                content = content.split(delim).map(function(v){

                    return v.trim();
                });

                if(content.length > 1) {

                    frontmatter = converter(content[1]);

                    page = assign(page, frontmatter);

                    content = content.slice(2);
                }

                page.content = content.join(delim);
            });

            done(null, pages);
        }
        catch(e) {

            done(e);
        }
    };
};

Add delim support and trim


/* eslint-env node */

module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [ ],
  browser_args: {
    Chrome: [
      '--disable-gpu',
      '--headless',
      '--remote-debugging-port=9222',
      '--window-size=1440,900'
    ]
  }
};

/* eslint-env node */

module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [ ],
  browser_args: {
    Chrome: [
      // --no-sandbox is needed when running Chrome inside a container
      process.env.TRAVIS ? '--no-sandbox' : null,
      '--disable-gpu',
      '--headless',
      '--remote-debugging-port=9222',
      '--window-size=1440,900'
    ]
  }
};

Fix Chrome tests on Travis


var express = require('express');
var router = express.Router();

router.get('/search', function(req, res) {
    if (!req.query.hasOwnProperty("inp")) return res.sendStatus(400);
    res.render('searchres', { search: req.query.inp });
});

/* GET home page. */
router.get('/', function(req, res, next) {
    res.render('index', { title: 'unicode-webapp' });
});

module.exports = router;

var express = require('express');
var router = express.Router();

router.get('/search', function(req, res, next) {
    if (!req.query.hasOwnProperty("inp")) {
        var err = new Error('Bad Request');
        err.status = 400;
        next(err);
    }
    res.render('searchres', { search: req.query.inp });
});

/* GET home page. */
router.get('/', function(req, res, next) {
    res.render('index', { title: 'unicode-webapp' });
});

module.exports = router;

Use error handlers for 400 page


'use strict';

var fs = require( 'fs' );
var routes = {};

// load all definitions
fs.readdirSync( __dirname ).filter( function( file ) {
  // return true IF not a dotfile AND not this file
  return ( ( file.indexOf( '.' ) !== 0 ) && ( file !== 'index.js' ) );
}).forEach( function( file ) {
  file = file.split( '.' ) [ 0 ];
  routes[ file ] = require( './' + file );
});

module.exports = routes;

// module.exports = {
// 	auth: {
// 		login: require( './auth/login' ),
// 		enforce: require( './auth/enforce' ),
//     newUser: require( './auth/newUser' )
// 	},
// 	api: {
// 		task: require( './api/task' ),
//     topic: require( './api/topic' )
// 	},
//   task: require( './task' ),
//   topic: require( './topic' ),
// };

Remove old commented out code.


//exports.list = function (req, res) {
//  res.send({
//      "lat": 5.552,
//      "long": 2.342,
//      "message": "Bong!",
//      "tags": ["Lifestyle", "Restaurant", "YOLO"],
//      "relevance": 1337,
//      "user": 42
//    });
//};

var db = require('../database.js');
var posts = db.get('posts');

exports.list = function (req, res) {
  var collection = db.get('posts');
  collection.find({}, {}, function (e, docs) {
    res.send(docs);
  });
};

exports.create = function (req, res) {
  req.assert('lat', 'not a valid latitude value').isLat();
  req.assert('long', 'not a valid longitude value').isLong();
  req.assert('message', 'required').notEmpty();
  req.sanitize('lat').toFloat();
  req.sanitize('long').toFloat();
  req.sanitize('message').toString();

  var errors = req.validationErrors();
  if (errors) {
    res.send({'error': errors});
    return;
  }
  var post = {
    "lat": req.param('lat'),
    "long": req.param('long'),
    "message": 'empty',
    "tags": [],
    "relevance": 100,
    "user": 0
  };
  posts.insert(post);
  res.json(post);
};

//exports.list = function (req, res) {
//  res.send({
//      "lat": 5.552,
//      "long": 2.342,
//      "message": "Bong!",
//      "tags": ["Lifestyle", "Restaurant", "YOLO"],
//      "relevance": 1337,
//      "user": 42
//    });
//};

var db = require('../database.js');
var posts = db.get('posts');

exports.list = function (req, res) {
  var collection = db.get('posts');
  collection.find({}, {}, function (e, docs) {
    res.send(docs);
  });
};

exports.create = function (req, res) {
  req.assert('lat', 'not a valid latitude value').isLat();
  req.assert('long', 'not a valid longitude value').isLong();
  req.assert('message', 'required').notEmpty();
  req.sanitize('lat').toFloat();
  req.sanitize('long').toFloat();
  req.sanitize('message').toString();

  var errors = req.validationErrors();
  if (errors) {
    res.send({'error': errors});
    return;
  }
  var post = {
    "lat": req.param('lat'),
    "long": req.param('long'),
    "message": req.param('message'),
    "tags": [],
    "relevance": 100,
    "user": 0
  };
  posts.insert(post);
  res.json(post);
};

Add message parameter to database when creating a post


(function () {
    'use strict';

    angular
        .module('app')
        .controller('StudentController', StudentController);

    function StudentController($scope, $http) {
        var vm = this;

        vm.students = [];

        vm.createStudentInput = {};

        vm.createStudent = function () {
            $http.post("api/student/createStudent", JSON.stringify(vm.createStudentInput))
                .then(function (response) {
                    // Re-load data
                    vm.students = response.data;

                    // Close dialog
                    $('#formCreateStudent').modal('toggle');
                });
        }

        $http.get("api/student/getAll")
            .then(function(response) {
                vm.students = response.data;
            });
    }
})();

(function () {
    'use strict';

    angular
        .module('app')
        .controller('StudentController', StudentController);

    function StudentController($scope, $http) {
        var vm = this;

        vm.students = [];

        vm.createStudentInput = {};

        vm.createStudent = function () {
            $http.post("api/student/createStudent", JSON.stringify(vm.createStudentInput))
                .then(function (response) {
                    // Re-load data
                    vm.students = response.data;

                    // Close dialog
                    $('#formCreateStudent').modal('toggle');
                });
        }

        vm.searchStudent = function () {
            $http.get("api/student/searchStudent", {
                params: { firstName: vm.searchStudent.FirstName }
            }).then(function (respone) {
                site.log.debug(respone);
                vm.students = respone.data;
            });
        }

        $http.get("api/student/getAll")
            .then(function(response) {
                vm.students = response.data;
            });
    }
})();

Add get method with parameters


"use strict";

// http://www.google.com/finance/match?matchtype=matchall&q=msft
// http://www.google.com/finance/match?&q=?matchtype=matchall&q=msft
(function () {
    angular
        .module("conpa")
        .factory("googleService", googleService);

    googleService.$inject = ["$http"];
    function googleService($http) {
        var service = {
            quoteLookup: quoteLookup
        };

        return service;

        function quoteLookup(query) {
            var url = "http://www.google.com/finance/match?" +
                    "matchtype=matchall";

            return $http.get(url, {
                params: {
                    q: query
                }
            }).then(function (res) {
                return res.data.matches.map(function (quote) {
                    return {
                        symbol: quote.t,
                        name: quote.n,
                        exchDisp: quote.e,
                        type: quote.id
                    };
                });
            });
        }
    }

}());

"use strict";

(function () {
    angular
        .module("conpa")
        .factory("googleService", googleService);

    googleService.$inject = ["$http"];
    function googleService($http) {
        var service = {
            quoteLookup: quoteLookup
        };

        return service;

        function quoteLookup(query) {
            var url = "http://www.google.com/finance/match?" +
                    "matchtype=matchall";

            return $http.get(url, {
                params: {
                    q: query
                }
            }).then(function (res) {
                return res.data.matches.map(function (quote) {
                    return {
                        symbol: quote.t,
                        name: quote.n,
                        exchDisp: quote.e,
                        type: quote.id
                    };
                });
            });
        }
    }

}());

Remove url commented in google sevice.


var PrintDocumentationCommand = function () {
  var handle = function () {
    console.log('Space Kitty - Version 1.0.0');
    console.log('');
    console.log('├── create             ─ Create a new project');
    console.log('├── make');
    console.log('|    ├── command       ─ Create a dispatchable command');
    console.log('|    ├── collection    ─ Create a collection (only supports Mongo)');
    console.log('|    ├── meteor-method ─ Create a Meteor method');
    console.log('|    ├── migration     ─ Create a migration (uses percolate:migrations)');
    console.log('|    └── view          ─ Create a view module');
    console.log('├── remind-me');
    console.log('|    ├── meteor-call   ─ Reminds you how to call a meteor method');
    console.log('|    └── react-loop    ─ Reminds you how to achieve dynamic children in React');
    console.log('└── meow               ─ Verify that Space Kitty can meow');
  };

  return {
    handle: handle
  }
};

module.exports = PrintDocumentationCommand;

var pjson = require('./package.json');

var PrintDocumentationCommand = function () {
  var handle = function () {
    console.log('Space Kitty - Version ' + pjson.version);
    console.log('');
    console.log('├── create             ─ Create a new project');
    console.log('├── make');
    console.log('|    ├── command       ─ Create a dispatchable command');
    console.log('|    ├── collection    ─ Create a collection (only supports Mongo)');
    console.log('|    ├── meteor-method ─ Create a Meteor method');
    console.log('|    ├── migration     ─ Create a migration (uses percolate:migrations)');
    console.log('|    └── view          ─ Create a view module');
    console.log('├── remind-me');
    console.log('|    ├── meteor-call   ─ Reminds you how to call a meteor method');
    console.log('|    └── react-loop    ─ Reminds you how to achieve dynamic children in React');
    console.log('└── meow               ─ Verify that Space Kitty can meow');
  };

  return {
    handle: handle
  }
};

module.exports = PrintDocumentationCommand;

Use package version for printing


// Load the book metadata into MongoDB from book_metadata.json

var databaseURI = "localhost:27017/bldata";
var collections = ["bookmeta"];
var db = require("mongojs").connect(databaseURI, collections);

var fs = require('fs');
var file = '../../../data/bldata/imagedirectory/book_metadata.json';

var bookdata;
fs.readFile(file, 'utf8', function (err, data) {
	if (err) {
		console.log('Error: ' + err);
		return;
	}

	bookdata = JSON.parse(data);
	for (var id in bookdata) {
		var meta = bookdata[id];
		meta._id = id;
		// add to Mongo:
		db.bookmeta.update({"_id" : id}, meta, {"upsert" : true});
	}
});

// Load the book metadata into MongoDB from book_metadata.json

var databaseURI = "localhost:27017/bldata";
var collections = ["bookmeta"];
var db = require("mongojs").connect(databaseURI, collections);

var fs = require('fs');
var file = '../../../data/bldata/imagedirectory/book_metadata.json';

var bookdata;
var waitingCount = 0;
fs.readFile(file, 'utf8', function (err, data) {
	if (err) {
		console.log('Error: ' + err);
		return;
	}

	bookdata = JSON.parse(data);
	for (var i = 0; i < bookdata.length; i++) {
		var meta = bookdata[i];
		meta._id = meta.identifier;
		// add to Mongo:
		waitingCount++;
		db.bookmeta.update({"_id" : meta._id}, meta, {"upsert" : true}, function() { waitingCount--;});
	}

	// give save thread a chance to finish by waiting a second
	console.log("Waiting to finish..");
	waitForFinish();
});

function waitForFinish() {
	setTimeout((function() {
		console.log(waitingCount);
		if (waitingCount <= 0) {
			process.exit();
		} else {
			waitForFinish();
		}
	}), 1000);
}

Update to match new book data JSON format (list not hash) Also fixed the waiting issue after completion


Package.describe({
  summary: "Wraps the request module from Npm in a fiber.",
  version: '0.0.0'
});

Npm.depends({request: "2.33.0"});

Package.on_use(function (api) {
  api.add_files('request-server.js', 'server');
  api.export('Request');
});

Package.describe({
  summary: "Wraps the request module from Npm in a fiber.",
  version: '0.0.0'
});

Npm.depends({request: "2.47.0"});

Package.on_use(function (api) {
  api.add_files('request-server.js', 'server');
  api.export('Request');
});

Upgrade request to 2.47.0 from 2.33.0


import React, { PropTypes } from 'react'
import {
  matchContext as matchContextType
} from './PropTypes'

class MatchProvider extends React.Component {
  static propTypes = {
    match: PropTypes.any,
    children: PropTypes.node
  }

  static childContextTypes = {
    match: matchContextType.isRequired
  }

  constructor(props) {
    super(props)

    this.state = {
      parent: props.match,
      matches: []
    }
  }

  addMatch = match => {
    const { matches } = this.state

    this.setState({
      matches: matches.concat([match])
    })
  }

  removeMatch = match => {
    const { matches } = this.state

    this.setState({
      matches: matches.splice(matches.indexOf(match), 1)
    })
  }

  getChildContext() {
    return {
      match: {
        addMatch: this.addMatch,
        removeMatch: this.removeMatch,

        parent: this.state.parent,
        matches: this.state.matches,

        matchFound: () => this.state.matches.length > 0
      }
    }
  }

  render() {
    return this.props.children
  }
}

export default MatchProvider

import React, { PropTypes } from 'react'
import {
  matchContext as matchContextType
} from './PropTypes'

class MatchProvider extends React.Component {
  static propTypes = {
    match: PropTypes.any,
    children: PropTypes.node
  }

  static childContextTypes = {
    match: matchContextType.isRequired
  }

  constructor(props) {
    super(props)

    this.state = {
      parent: props.match
    }

    // When accessing state along this.context, it appears any enqueued setState
    // calls don't get dispatched on the server (renderToString) and something
    // like Miss will never work. This works around that by using a simple
    // instance variable. Sorry it's not idiomatic React!
    this.matches = []
  }

  addMatch = match => {
    this.matches = this.matches.concat([match])
  }

  removeMatch = match => {
    this.matches = this.matches.splice(this.matches.indexOf(match), 1)
  }

  getChildContext() {
    return {
      match: {
        addMatch: this.addMatch,
        removeMatch: this.removeMatch,

        parent: this.state.parent,
        matches: this.matches,

        matchFound: () => this.matches.length > 0
      }
    }
  }

  render() {
    return this.props.children
  }
}

export default MatchProvider

Use an instance variable for match tracking.


var constructGeolocationLink = function constructGeolocationLink($wrapper){
    var geolocationIsSupported = false;
    if ("geolocation" in navigator) {
        geolocationIsSupported = true;
    }

    if(geolocationIsSupported) {
        var t1 = $wrapper.attr('data-link-text') || 'Use my current location';
        var t2 = $wrapper.attr('data-loading-text') || 'Getting location\u2026';

        var $a = $('<a>').text(t1).addClass('geolocation-link');
        $a.on('click', function(){
            var that = this;
            $(this).text(t2);
            navigator.geolocation.getCurrentPosition(function(position) {
              $.getJSON(
                  '/geolocator/' + position.coords.latitude + ',' + position.coords.longitude,
                  function ( data ) {
                    if ( data['error'] ) {
                      $(that).text(data['error']);
                    } else if ( data['url'] ) {
                        window.location=data['url']
                    }
                  });
            });
        })
        $a.appendTo($wrapper);
    }
}

$(function(){
    $('.js-geolocation-link').each(function(){
        constructGeolocationLink( $(this) );
    });
});

var constructGeolocationLink = function constructGeolocationLink($wrapper){
    var geolocationIsSupported = false;
    if ("geolocation" in navigator) {
        geolocationIsSupported = true;
    }

    if(geolocationIsSupported) {
        var t1 = $wrapper.attr('data-link-text') || 'Use my current location';
        var t2 = $wrapper.attr('data-loading-text') || 'Getting location\u2026';

        var $a = $('<a>').text(t1).addClass('geolocation-link');
        $a.on('click', function(){
            var that = this;
            $(this).text(t2);
            navigator.geolocation.getCurrentPosition(function(position) {
              $.getJSON(
                  '/geolocator/' + position.coords.latitude + ',' + position.coords.longitude,
                  function ( data ) {
                    if ( data['error'] ) {
                      $(that).text(data['error']);
                    } else if ( data['url'] ) {
                        window.location=data['url']
                    } else {
                      $(that).text(data['error']);
                    }
                  });
            });
        })
        $a.appendTo($wrapper);
    }
}

$(function(){
    $('.js-geolocation-link').each(function(){
        constructGeolocationLink( $(this) );
    });
});

Add the Javascript half of the new Geolocation code


const fountain = require('fountain-generator');

module.exports = fountain.Base.extend({
  writing() {
    const name = this.options.name || 'myComponent';
    const titleCase = string => string.charAt(0).toUpperCase() + string.slice(1);
    const lowerCase = string => string.charAt(0).toLowerCase() + string.slice(1);
    const path = this.options.dir ? `app/${this.options.dir}` : `app`;
    const typings = this.options.dir ? this.options.dir.split('/').reduce(prev => `../${prev}`, '../../typings/index.d.ts') : '../../typings/index.d.ts';
    const props = {
      componentName: lowerCase(name),
      className: titleCase(name),
      modules: this.config.get('props').modules,
      typings
    };
    this.copyTemplate(`src/app/component.js`, `src/${path}/${name}.js`, props);
    this.copyTemplate(`src/app/component.spec.js`, `src/${path}/${name}.spec.js`, props);
  }
});

const fountain = require('fountain-generator');

module.exports = fountain.Base.extend({
  writing() {
    const name = this.options.name || 'myComponent';
    const titleCase = string => string.charAt(0).toUpperCase() + string.slice(1);
    const lowerCase = string => string.charAt(0).toLowerCase() + string.slice(1);
    const path = this.options.dir ? `app/${this.options.dir}` : `app`;
    const typings = this.options.dir ? this.options.dir.split('/').reduce(prev => `../${prev}`, '../../typings/index.d.ts') : '../../typings/index.d.ts';
    const props = {
      componentName: lowerCase(name),
      className: titleCase(name),
      modules: this.config.get('props').modules,
      js: this.config.get('props').js,
      framework: this.config.get('props').framework,
      typings
    };
    this.copyTemplate(`src/app/component.js`, `src/${path}/${name}.js`, props);
    this.copyTemplate(`src/app/component.spec.js`, `src/${path}/${name}.spec.js`, props);
  }
});

Add missing props for copyTemplate


describe("Gilded Rose", function() {
  var foo;

  // beforeEach(function() {
  //   foo = 0;
  //   foo += 1;
  // });

  // afterEach(function() {
  //   foo = 0;
  // });

  it("should do something", function() {

  });

  // it("is a syntax example", function() {
  //   expect(true).toBe(true);
  // });

  // it("can have a negative case", function() {
  //   expect(false).not.toBe(true);
  // });

  // describe("Another spec", function() {
  //   it("is just a function, so it can contain any code", function() {
  //     var foo = 0;
  //     foo += 1;

  //     expect(foo).toEqual(1);
  //   });

  //   it("The 'toBeLessThan' matcher is for mathematical comparisons", function() {
  //     var pi = 3, e = 2;

  //     expect(e).toBeLessThan(pi);
  //     expect(pi).not.toBeLessThan(e);
  //   });

  //   it("The 'toBeGreaterThan' is for mathematical comparisons", function() {
  //     var pi = 3, e = 2;

  //     expect(pi).toBeGreaterThan(e);
  //     expect(e).not.toBeGreaterThan(pi);
  //   });
  // });

});

describe("Gilded Rose", function() {
  // var foo;

  // beforeEach(function() {
  //   foo = 0;
  // });

  // afterEach(function() {
  //   foo = 0;
  // });

  it("should do something", function() {

  });

  // it("is a syntax example", function() {
  //   expect(true).toBe(true);
  // });

  // it("can have a negative case", function() {
  //   expect(false).not.toBe(true);
  // });

  // describe("Another spec", function() {
  //   it("is just a function, so it can contain any code", function() {
  //     var foo = 0;
  //     foo += 1;

  //     expect(foo).toEqual(1);
  //   });

  //   it("has mathematical comparisons", function() {
  //     expect(2).toBeLessThan(3);
  //     expect(3).not.toBeLessThan(2);
  //     expect(3).toBeGreaterThan(2);
  //     expect(2).not.toBeGreaterThan(3);
  //   });
  // });

});

Update Jasmine syntax examples to make them shorter.


define('editor-plugin-sticky-toolbar', [], function () {
  return function(toolbarNode) {
    return function() {
      var toolbarOffsetTop,
          scrolled = false;

      // Listen for scroll - TODO Debounce
      document.addEventListener('scroll', function () {
        if(!scrolled){
          toolbarOffsetTop = toolbarNode.offsetTop;
          scrolled = true;
        }
        toolbarNode.classList.toggle('is-sticky', (toolbarOffsetTop <= window.scrollY));
      });
    };
  };
});

define('editor-plugin-sticky-toolbar', [], function () {
  return function(toolbarNode, options) {
    return function() {
      var toolbarOffsetTop,
          scrolled = false;

      // Listen for scroll - TODO Debounce
      document.addEventListener('scroll', function () {
        if(!scrolled){
          toolbarOffsetTop = toolbarNode.offsetTop;
          scrolled = true;
        }
        toolbarNode.classList.toggle('is-sticky', (toolbarOffsetTop <= window.scrollY));
      });
    };
  };
});

Allow additional options params in sticky toolbar plugin


//@flow

import React from "react";
import { Title, Wrapper } from "./styled-components";
import { MainNav } from "../../elements/navigation-main";
import { Highlight } from "../../elements/highlight";
import { Skewify } from "../../elements/skewify";
import { MobileMenuButton } from "../../elements/mobile-menu-button";
import addActiveState from "../../global/hoc/addActiveState";

type props = {
  openMobileNav: () => mixed,
  closeMobileNav: () => mixed,
  ui: {
    mobileMenuIsOpen: boolean,
    breakpoints: {
      main: {
        device: string
      }
    }
  }
};

const ActiveTitle = addActiveState(Title);

export const HeaderMain = (props: props) =>
  <Wrapper>
    {props.ui.breakpoints.main.device === "mobile" &&
      <MobileMenuButton {...props} />}
    <ActiveTitle>
      <Highlight url="/" highlightColor="transparent">
        Oliver <Skewify>Askew</Skewify>
      </Highlight>
    </ActiveTitle>
    {props.ui.breakpoints.main.device === "desktop" && <MainNav {...props} />}
  </Wrapper>;

//@flow

import React from "react";
import { Title, Wrapper } from "./styled-components";
import { MainNav } from "../../elements/navigation-main";
import { Highlight } from "../../elements/highlight";
import { Skewify } from "../../elements/skewify";
import { MobileMenuButton } from "../../elements/mobile-menu-button";
import addActiveState from "../../global/hoc/addActiveState";

type props = {
  openMobileNav: () => mixed,
  closeMobileNav: () => {},
  newMobileMenuButtonStatus: ()=>{},
  ui: {
    mobileMenuButtonStatus: string,
    mobileMenuIsOpen: boolean,
    breakpoints: {
      [string]: {
        [string]: mixed
      }
    }
  }
};

const ActiveTitle = addActiveState(Title);

export const HeaderMain = (props: props) =>
  <Wrapper>
    {props.ui.breakpoints.main.device === "mobile" &&
      <MobileMenuButton {...props} />}
    <ActiveTitle>
      <Highlight url="/" highlightColor="transparent">
        Oliver <Skewify>Askew</Skewify>
      </Highlight>
    </ActiveTitle>
    {props.ui.breakpoints.main.device === "desktop" && <MainNav {...props} />}
  </Wrapper>;

Adjust prop type defs in navigation-main


let ServiceConfig = {
  BLACKLIST: [
    'uris',
    'ports',
    'version',
    'versionInfo',
    'deployments',
    'tasks',
    'taskStats',
    'tasksHealthy',
    'tasksRunning',
    'tasksStaged',
    'tasksUnhealthy'
  ]
};

module.exports = ServiceConfig;

let ServiceConfig = {
  BLACKLIST: [
    'uris',
    'ports',
    'version',
    'versions',
    'versionInfo',
    'deployments',
    'tasks',
    'taskStats',
    'tasksHealthy',
    'tasksRunning',
    'tasksStaged',
    'tasksUnhealthy'
  ]
};

module.exports = ServiceConfig;

Add versions to the Blacklist


var express = require('express');
var app = express();
//var mongoose = require('mongoose');
//var config = require('./config');

//mongoose.connect('mongodb://localhost/my_database');

app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));

app.post('/createUser', function(request, response) {
  response.send('Hello World!');
});

app.get('/readUser', function(request, response) {

}

app.post('/deleteUser', function(request, response) {
  response.send('Hello World!');
});

app.listen(app.get('port'), function() {
  console.log("Node app is running at localhost:" + app.get('port'));
});

var express = require('express');
var app = express();
//var mongoose = require('mongoose');
//var config = require('./config');

//mongoose.connect('mongodb://localhost/my_database');

app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));

app.get('/', function(request, response) {
  response.send('Hello World!');
});

app.post('/createUser', function(request, response) {
  response.send('Hello World!');
});

app.get('/readUser', function(request, response) {

}

app.post('/deleteUser', function(request, response) {
  response.send('Hello World!');
});

app.listen(app.get('port'), function() {
  console.log("Node app is running at localhost:" + app.get('port'));
});

Add root to test heroku


'use strict';

const path = require('path');
const pkg = require(path.resolve('./package.json'));
const semver = require('semver');
const versions = require('./versions.json');

const presetEnv = require.resolve('babel-preset-env');
const presetStage3 = require.resolve('babel-preset-stage-3');

module.exports = function(context, options) {
  options = options || {};

  const modules = options.modules || false;
  const targets = {};

  if (pkg.browserslist) {
    targets.browsers = pkg.browserslist;
  }

  if (pkg.engines && pkg.engines.node) {
    const version = pkg.engines.node;

    if (semver.valid(version)) {
      targets.node = version;
    } else if (semver.validRange(version)) {
      targets.node = semver.minSatisfying(versions.node, version);
    }
  }

  return {
    presets: [
      [presetEnv, {modules, targets}],
      presetStage3,
    ],
  };
};

'use strict';

const path = require('path');
const pkg = require(path.resolve('./package.json'));
const semver = require('semver');
const versions = require('./versions.json');

const presetEnv = require.resolve('babel-preset-env');
const presetStage3 = require.resolve('babel-preset-stage-3');

module.exports = function(context, options) {
  options = options || {};

  const debug = options.debug || false;
  const modules = options.modules || false;
  const targets = {};

  if (pkg.browserslist) {
    targets.browsers = pkg.browserslist;
  }

  if (pkg.engines && pkg.engines.node) {
    const version = pkg.engines.node;

    if (semver.valid(version)) {
      targets.node = version;
    } else if (semver.validRange(version)) {
      targets.node = semver.minSatisfying(versions.node, version);
    }
  }

  return {
    presets: [
      [presetEnv, {debug, modules, targets}],
      presetStage3,
    ],
  };
};

Add in a debug option that defaults to false


/* jshint node: true */
'use strict';

let fs = require('fs');

module.exports = {
  name: 'ember-cli-ifa',

  isDevelopingAddon: function() {
    return false;
  },

  postBuild: function (build) {
    let indexFilePath = build.directory + '/index.html';
    let indexFileBuffer = fs.readFileSync(indexFilePath);
    let indexFile = indexFileBuffer.toString('utf8');

    let files = fs.readdirSync(build.directory + '/assets');
    let totalFiles = files.length;

    let assetFileName = null;
    for (let i = 0; i < totalFiles; i++) {
      if (files[i].match(/^assetMap-/i)) {
        assetFileName = files[i];
        break;
      }
    }

    if (assetFileName) {
      fs.writeFileSync(
        indexFilePath,
        indexFile.replace(/__asset_map_placeholder__/, '/assets/' + assetFileName)
      );
    }
  },

  contentFor(type, config) {
    if (type === 'head-footer' && config.ifa && config.ifa.enabled) {
      return '<script>var __assetMapFilename__ = "__asset_map_placeholder__";</script>';
    }
  }
};

/* jshint node: true */
'use strict';

let fs = require('fs');

module.exports = {
  name: 'ember-cli-ifa',

  isDevelopingAddon: function() {
    return false;
  },

  postBuild: function (build) {
    let indexFilePath = build.directory + '/index.html';
    let indexFileBuffer = fs.readFileSync(indexFilePath);
    let indexFile = indexFileBuffer.toString('utf8');

    let files = fs.readdirSync(build.directory + '/assets');
    let totalFiles = files.length;

    let assetFileName = null;
    for (let i = 0; i < totalFiles; i++) {
      if (files[i].match(/^assetMap/i)) {
        assetFileName = files[i];
        break;
      }
    }

    if (assetFileName) {
      fs.writeFileSync(
        indexFilePath,
        indexFile.replace(/__asset_map_placeholder__/, '/assets/' + assetFileName)
      );
    }
  },

  contentFor(type, config) {
    if (type === 'head-footer' && config.ifa && config.ifa.enabled) {
      return '<script>var __assetMapFilename__ = "__asset_map_placeholder__";</script>';
    }
  }
};

Remove - from assetMap file name


var parser = require('js-yaml')
var optionalByteOrderMark = '\\ufeff?'
var pattern = '^(' +
  optionalByteOrderMark +
  '(= yaml =|---)' +
  '$([\\s\\S]*?)' +
  '^(?:\\2|\\.\\.\\.)\\s*' +
  '$' +
  (process.platform === 'win32' ? '\\r?' : '') +
  '(?:\\n)?)'
// NOTE: If this pattern uses the 'g' flag the `regex` variable definition will
// need to be moved down into the functions that use it.
var regex = new RegExp(pattern, 'm')

module.exports = extractor
module.exports.test = test

function extractor (string) {
  string = string || ''

  var lines = string.split(/(\r?\n)/)
  if (lines[0] && /= yaml =|---/.test(lines[0])) {
    return parse(string)
  } else {
    return { attributes: {}, body: string }
  }
}

function parse (string) {
  var match = regex.exec(string)

  if (!match) {
    return {
      attributes: {},
      body: string
    }
  }

  var yaml = match[match.length - 1].replace(/^\s+|\s+$/g, '')
  var attributes = parser.load(yaml) || {}
  var body = string.replace(match[0], '')

  return { attributes: attributes, body: body, frontmatter: yaml }
}

function test (string) {
  string = string || ''

  return regex.test(string)
}

var parser = require('js-yaml')
var optionalByteOrderMark = '\\ufeff?'
var platform = typeof process !== 'undefined' ? process.platform : ''
var pattern = '^(' +
  optionalByteOrderMark +
  '(= yaml =|---)' +
  '$([\\s\\S]*?)' +
  '^(?:\\2|\\.\\.\\.)\\s*' +
  '$' +
  (platform === 'win32' ? '\\r?' : '') +
  '(?:\\n)?)'
// NOTE: If this pattern uses the 'g' flag the `regex` variable definition will
// need to be moved down into the functions that use it.
var regex = new RegExp(pattern, 'm')

module.exports = extractor
module.exports.test = test

function extractor (string) {
  string = string || ''

  var lines = string.split(/(\r?\n)/)
  if (lines[0] && /= yaml =|---/.test(lines[0])) {
    return parse(string)
  } else {
    return { attributes: {}, body: string }
  }
}

function parse (string) {
  var match = regex.exec(string)

  if (!match) {
    return {
      attributes: {},
      body: string
    }
  }

  var yaml = match[match.length - 1].replace(/^\s+|\s+$/g, '')
  var attributes = parser.load(yaml) || {}
  var body = string.replace(match[0], '')

  return { attributes: attributes, body: body, frontmatter: yaml }
}

function test (string) {
  string = string || ''

  return regex.test(string)
}

Fix for environments without process var


/**
 * Config object, import as JSON
 * @type {Object}
 *
 * @example
 * {
 *   "consulateUrls": {
 *     "country": "https://example.com/countries.php",
 *     "consulate": "https://example.com/consulates.php",
 *     "agenda": "https://example.com/agenda.xhtml"
 *   },
 *   "telegram": {
 *     "baseUrl": "https://api.telegram.org/bot<bot-token>/"
 *   }
 * }
 */
var config = require('./config');
var fetch  = require('./fetcher');
var notify = require('./notifier');

function error(err) {
  console.error(err);
}

fetch(config.consulateUrls, function callback(err, data) {
  if (err) return error(err);
  console.log(JSON.stringify(data, null, 2));
  return notify('available-dates-summary', data, 7438652);
});

Add config object description and example


var _ = require('underscore');
var async = require('async');
var request = require('request');
var linters = require('./linters');

var repoURL = 'https://api.github.com/repos/nicolasmccurdy/repos';
var options = {
  headers: {
    Accept: 'application/vnd.github.v3',
    'User-Agent': 'ghlint'
  },
  qs: {
    client_id: process.env.GHLINT_ID,
    client_secret: process.env.GHLINT_SECRET
  },
  url: repoURL
};
var commitOptions = _.extend(options, { url: repoURL + '/commits' });

module.exports = {
  linters: linters,
  lintAll: function (callback) {
    request(options, function (err, repo) {
      request(commitOptions, function (err, commits) {
        callback(err, linters.map(function (linter) {
          return {
            message: linter.message,
            result: linter.lint(repo, commits)
          };
        }));
      });
    });
  }
};

var _ = require('underscore');
var async = require('async');
var request = require('request');
var linters = require('./linters');

var repoURL = 'https://api.github.com/repos/nicolasmccurdy/repos';
var githubRequest = request.defaults({
  headers: {
    Accept: 'application/vnd.github.v3',
    'User-Agent': 'ghlint'
  },
  qs: {
    client_id: process.env.GHLINT_ID,
    client_secret: process.env.GHLINT_SECRET
  }
});

module.exports = {
  linters: linters,
  lintAll: function (callback) {
    githubRequest(repoURL, function (err, repo) {
      githubRequest(repoURL + '/commits', function (err, commits) {
        callback(err, linters.map(function (linter) {
          return {
            message: linter.message,
            result: linter.lint(repo, commits)
          };
        }));
      });
    });
  }
};

Use request.defaults() to simplify GitHub API calls


const Source = require("./Ship/PollSource.js");
const Connection = require("./Ship/Connection.js");
const MessageRouter = require("./Ship/MessageRouter.js");
const CommandSource = require("./Ship/CommandSource.js");

const helpCommand = require("./Ship/Commands/Help.js");
const bindOurCommands = require("./Commands.js");

const config = require("./config.json");

const connection = new Connection(config.auth.id,config.auth.key);
const source = new Source(connection);
const messageSource = new MessageRouter(source);

let commandSource;

console.log("Pinging telegram to check connection and get out username...");
connection.getMe().then(me=>{
  console.log(`> Response. We are "${me.username}".`);
  console.log("> Binding commands to command source.");
  commandSource = new CommandSource(messageSource,me.username);
  helpCommand.bind("help",commandSource);
  bindOurCommands(commandSource);
  console.log("> Starting message source.");
  source.start();
});

process.on('unhandledRejection', err => {
  console.log(`${new Date()} WARN: Unandled error in promise:`,err);
});

Add unhandled promise rejection handler