var TurbolinksAdapter = {
  beforeMount: function(){
    document.addEventListener('turbolinks:before-cache', () => {
      this.$destroy();
    });

    this.$originalEl = this.$el.outerHTML;
  },
  destroyed: function() {
    this.$el.outerHTML = this.$originalEl;
  }
};

export default TurbolinksAdapter;

function destroyVue() {
  this.$destroy();
  document.removeEventListener('turbolinks:before-cache', destroyVue.bind(this))
}

var TurbolinksAdapter = {
  beforeMount: function(){
    document.addEventListener('turbolinks:before-cache', destroyVue.bind(this))
    this.$originalEl = this.$el.outerHTML;
  },
  destroyed: function() {
    this.$el.outerHTML = this.$originalEl;
  }
};

export default TurbolinksAdapter;

Remove event listener automatically on page change


var rest = require('restler');

module.exports = {
  'gif': function(input, cb) {
    var self = this;
    var query = encodeURIComponent(input.parsed);
    var options = { rejectUnauthorized: false };
    var baseUrl = 'https://ticketap.com/rightgif';
    var url = baseUrl + '?text='+query;
    rest.get(url, options).on('complete', function(data) {
      var img;
      if(data.gifs && data.gifs.length > 0) {
        img = self.chooseRandom(data.gifs).url;
      } else {
        img = data.url;
      }
      cb(null, 'word!  ' + img);
    });
  },
  'chooseRandom': function(gifs) {
    return gifs[Math.floor(Math.random() * gifs.length)];
  }
};

var rest = require('restler');

module.exports = {
  'gif': function(input, cb) {
    var self = this;
    var query = encodeURIComponent(input.parsed);
    var options = { rejectUnauthorized: false };
    var baseUrl = 'https://ticketap.com/rightgif';
    var url = baseUrl + '?text='+query;
    rest.get(url, options).on('complete', function(data) {
      var img;
      if (data.gifs && data.gifs.length > 0) {
        img = self.chooseRandom(data.gifs).url;
      } else {
        img = data.url;
      }
      cb(null, 'word!  ' + img);
    });
  },
  'chooseRandom': function(gifs) {
    return gifs[Math.floor(Math.random() * gifs.length)];
  }
};

Add extra space for convention.


var map = null;

$(document).on('pageshow', '#map', function() {
    // draw the map once
    if (map == null) drawMap();
});

function drawMap() {
    $('#map_canvas').css('height', 500);

    var latlng = new google.maps.LatLng(-34.397, 150.644);
    var mapOptions = {
	center: latlng,
	zoom: 8,
	mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
}

var map = null;

$(document).on('pageshow', '#map', function() {
    // Draw the map once
    if (map == null) initMap();
});

function initMap() {
    $('#map_canvas').css('height', 500);

    var latlng = new google.maps.LatLng(34.87728, 135.576798); // kutc
    var mapOptions = {
	center: latlng,
	zoom: 8,
	mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

    // Get posts and create markers
    var api_uri = 'http://mpmc.dip.jp/~otknoy/michishiki_api_server/select.py';
    $.getJSON(api_uri, function(json) {
	for (var i = 0; i < json.length; i++) {
	    createMarker(map, json[i].title, json[i].latitude, json[i].longitude);
	}
    });
}

function createMarker(map, title, latitude, longitude) {
    var latlng = new google.maps.LatLng(latitude, longitude);
    var marker = new google.maps.Marker({
	position: latlng,
	map: map,
	title : title
	});
    return marker;
}

Create markers based on retrieved posts


'use strict';

var peg = require('pegjs');

class PegJsPlugin {

  constructor(config) {
    this.config = config.plugins.pegjs;
    this.config.output = 'source';
  }

  compile(file) {
    var parser;
    try {
      parser = peg.generate(file.data, this.config);
    } catch(error) {
      if (error instanceof peg.parser.SyntaxError) {
        error.message = `${error.message} at ${error.location.start.line}:${error.location.start.column}`;
      }
      return Promise.reject(error);
    }
    return Promise.resolve({data: parser});
  }

}

// brunchPlugin must be set to true for all Brunch plugins
PegJsPlugin.prototype.brunchPlugin = true;
// The type of file to generate
PegJsPlugin.prototype.type = "javascript";
// The extension for files to process
PegJsPlugin.prototype.extension = "pegjs";

module.exports = PegJsPlugin;

'use strict';

var peg = require('pegjs');

class PegJsPlugin {

  constructor(config) {
    this.config = config.plugins.pegjs;
    // The output of the below peg.generate() function must be a string, not an
    // object
    this.config.output = 'source';
  }

  compile(file) {
    var parser;
    try {
      parser = peg.generate(file.data, this.config);
    } catch(error) {
      if (error instanceof peg.parser.SyntaxError) {
        error.message = `${error.message} at ${error.location.start.line}:${error.location.start.column}`;
      }
      return Promise.reject(error);
    }
    return Promise.resolve({data: parser});
  }

}

// brunchPlugin must be set to true for all Brunch plugins
PegJsPlugin.prototype.brunchPlugin = true;
// The type of file to generate
PegJsPlugin.prototype.type = "javascript";
// The extension for files to process
PegJsPlugin.prototype.extension = "pegjs";

module.exports = PegJsPlugin;

Add comment explaining explicit setting of output


#!/usr/bin/env node
const yargs = require('yargs');

yargs
.usage('$0 command')
.command('all', 'run all bundled commands', yargs => {
	const operations = require('./src');
	console.log("yargs", yargs)

	for (const key of Object.keys(operations)) {
		operations[key]();
	}
})
.command('fix-libraries', 'add any missing build configurations to all xcode projects in node_modules', yargs => {
	require('./src/fix-libraries')();
})
.command('fix-script', 'replace the react native ios bundler with our scheme aware one', yargs => {
	require('./src/fix-script')();
})
.command('hide-library-schemes', `hide any schemes that come from your node modules directory so they don't clutter up the menu.`, yargs => {
	require('./src/hide-library-schemes')();
})
.command('verify-config', `check the configuration and ensure we have both a postinstall script and xcodeSchemes configurations.`, yargs => {
	require('./src/verify-config')();
})
.demand(1, 'must provide a valid command')
.help('h')
.alias('h', 'help')
.argv;

#!/usr/bin/env node
const yargs = require('yargs');

yargs
.usage('$0 command')
.command('all', 'run all bundled commands', yargs => {
	const operations = require('./src');
	console.log("yargs" yargs)

	for (const key of Object.keys(operations)) {
		operations[key]();
	}
})
.command('fix-libraries', 'add any missing build configurations to all xcode projects in node_modules', yargs => {
	require('./src/fix-libraries')();
})
.command('fix-script', 'replace the react native ios bundler with our scheme aware one', yargs => {
	require('./src/fix-script')();
})
.command('hide-library-schemes', `hide any schemes that come from your node modules directory so they don't clutter up the menu.`, yargs => {
	require('./src/hide-library-schemes')();
})
.command('verify-config', `check the configuration and ensure we have both a postinstall script and xcodeSchemes configurations.`, yargs => {
	require('./src/verify-config')();
})
.demand(1, 'must provide a valid command')
.help('h')
.alias('h', 'help')
.argv;

Revert "debugging the ios directory issue"


require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const login = require('./login.js');
const getPullRequests = require('./getPullRequests.js');
const Maybe = require('folktale/maybe');
const app = express();
app.use(bodyParser.json());
app.use(cookieParser());

app.post('/api/login', (req, res) => {
    const {username, password, server} = req.body;
    const loginObj = {
        username,
        password,
        server
    };
    login(loginObj).then(() => {
        res.cookie('login', loginObj, {
            maxAge: 900000,
            httpOnly: false
        });
        res.sendStatus(200);
    }, (error) => {
        res.sendStatus(error.statusCode);
    });
});

app.post('/api/logout', (req, res) => {
    res.clearCookie('login');
    res.sendStatus(200);
});

app.get('/api/pullrequests', (req, res) => {
    Maybe.fromNullable(req.cookies.login).matchWith({
        Just: ({value}) => {
            getPullRequests(value).then(data => res.json(data), error => {
                console.log('index.js', '40', '', error);
                res.sendStatus(500);
            });
        },
        Nothing: () => res.sendStatus(401)
    });
});

app.set('port', process.env.PORT);
app.listen(app.get('port'));

require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const login = require('./login.js');
const getPullRequests = require('./getPullRequests.js');
const Maybe = require('folktale/maybe');
const app = express();
app.use(bodyParser.json());
app.use(cookieParser());

app.post('/api/login', (req, res) => {
    const {username, password, server} = req.body;
    const loginObj = {
        username,
        password,
        server
    };
    login(loginObj).then(() => {
        res.cookie('login', loginObj, {
            httpOnly: true
        });
        res.sendStatus(200);
    }, (error) => {
        res.sendStatus(error.statusCode);
    });
});

app.post('/api/logout', (req, res) => {
    res.clearCookie('login');
    res.sendStatus(200);
});

app.get('/api/pullrequests', (req, res) => {
    Maybe.fromNullable(req.cookies.login).matchWith({
        Just: ({value}) => {
            getPullRequests(value).then(data => res.json(data), error => {
                console.log('index.js', '40', '', error);
                res.sendStatus(500);
            });
        },
        Nothing: () => res.sendStatus(401)
    });
});

app.set('port', process.env.PORT);
app.listen(app.get('port'));

Set cookie to http only


'use strict';

module.exports = function (movieString) {

  var baseName = movieString.replace(/\.(avi|mkv|mpeg|mpg|mov|mp4|m4v)/i, '');
  var movie = baseName.match(/(.*?)(directors(.?)cut|480p|720p|1080p|dvdrip|xvid|cd[0-9]|bluray|dvdscr|brrip|divx|S[0-9]{1,3}E[0-9]{1,3}|Season[\s,0-9]{1,4}|[\{\(\[]?[0-9]{4}).*/i);

  if (movie && movie[1]) {
    movie = movie[1].replace(/\./g, ' ').trim();
  } else {
    movie = baseName;
  }

  movie = movie.substring(movie.indexOf('-') + 1);

  return movie;
};

'use strict';

module.exports = function (movieString) {

  var baseName = movieString.replace(/\.(avi|mkv|mpeg|mpg|mov|mp4|m4v)$/i, '');
  var movie = baseName.match(/(.*?)(directors(.?)cut|480p|720p|1080p|dvdrip|xvid|cd[0-9]|bluray|dvdscr|brrip|divx|S[0-9]{1,3}E[0-9]{1,3}|Season[\s,0-9]{1,4}|[\{\(\[]?[0-9]{4}).*/i);

  if (movie && movie[1]) {
    movie = movie[1].replace(/\./g, ' ').trim();
  } else {
    movie = baseName;
  }

  movie = movie.substring(movie.indexOf('-') + 1);

  return movie;
};

Fix match error on file extension check


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

var path = require('path');

module.exports = {
  name: 'ember-solr',

  config: function(environment, appConfig) {
    if (!appConfig.solrBaseURL || appConfig.solrBaseURL.indexOf(':') === -1) {
      return;
    }

    var solrSchemeAndHost = appConfig.solrBaseURL;
    var solrHostEnd = solrSchemeAndHost.indexOf('/', solrSchemeAndHost.indexOf('://') + 3);
    if (solrHostEnd > 0) {
      solrSchemeAndHost = solrSchemeAndHost.substring(0, solrHostEnd);
    }

    var ENV = {
      contentSecurityPolicy: {
        'script-src': "'self' " + solrSchemeAndHost
      }
    }

    return ENV;
  },

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

    app.import(path.join(app.bowerDirectory, 'json-bignum', 'lib', 'json-bignum.js'));
  }
};

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

var path = require('path');

module.exports = {
  name: 'ember-solr',

  _appendPolicy: function(csp, key, value) {
    var v = csp[key] || '';
    if (v) {
      v += ' ';
    }
    csp[key] = v + value;
  },

  config: function(environment, appConfig) {
    if (!appConfig.solrBaseURL || appConfig.solrBaseURL.indexOf(':') === -1) {
      return;
    }

    var solrSchemeAndHost = appConfig.solrBaseURL;
    var solrHostEnd = solrSchemeAndHost.indexOf('/', solrSchemeAndHost.indexOf('://') + 3);
    if (solrHostEnd > 0) {
      solrSchemeAndHost = solrSchemeAndHost.substring(0, solrHostEnd);
    }

    var csp = appConfig.contentSecurityPolicy || {};

    this._appendPolicy(csp, 'connect-src', solrSchemeAndHost);
    this._appendPolicy(csp, 'script-src', solrSchemeAndHost);

    var ENV = {
      contentSecurityPolicy: csp
    };

    return ENV;
  },

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

    app.import(path.join(app.bowerDirectory, 'json-bignum', 'lib', 'json-bignum.js'));
  }
};

Include solrBaseURL in 'connect-src' content security policy too.


import React, { PropTypes, PureComponent } from 'react';
import { View, Platform, WebView, ActivityIndicator } from 'react-native';

export default class SVGImage extends PureComponent {
  static propTypes = {
    style: PropTypes.any,
    source: PropTypes.shape({
      uri: PropTypes.string,
    }).isRequired,
    showWebviewLoader: PropTypes.bool,
    height: PropTypes.number,
  };

  static defaultProps = {
    style: {},
    source: { uri: '' },
    showWebviewLoader: Platform.OS === 'android',
    height: null,
  };

  renderLoader = () => (
    <View style={[this.props.style, { flex: 1, alignItems: 'center', justifyContent: 'center' }]}>
      <ActivityIndicator />
    </View>
  );

  render() {
    const { showWebviewLoader, source: { uri }, height, ...props } = this.props;

    const html = `
      <!DOCTYPE html>\n
      <html>
        <head>
          <style type="text/css">
            img {
                max-width: 100%;
                max-height: 100%;
                margin: 0 auto;
            }
          </style>
        </head>
        <body>
          <img src="${uri}" height="${height}" align="middle" />
        </body>
      </html>
    `;

    return (
      <WebView
        source={{ html }}
        startInLoadingState={showWebviewLoader}
        renderLoading={showWebviewLoader ? this.renderLoader : null}
        {...props}
      />
    );
  }
}

import React, { PropTypes, PureComponent } from 'react';
import { View, Platform, WebView, ActivityIndicator } from 'react-native';

export default class SVGImage extends PureComponent {
  static propTypes = {
    style: PropTypes.any,
    source: PropTypes.shape({
      uri: PropTypes.string,
    }).isRequired,
    showWebviewLoader: PropTypes.bool,
    height: PropTypes.number,
  };

  static defaultProps = {
    style: {},
    source: { uri: '' },
    showWebviewLoader: Platform.OS === 'android',
    height: null,
  };

  renderLoader = () => (
    <View style={[this.props.style, { flex: 1, alignItems: 'center', justifyContent: 'center' }]}>
      <ActivityIndicator />
    </View>
  );

  render() {
    const { showWebviewLoader, source: { uri }, height, ...restOfProps } = this.props;

    const html = `
      <!DOCTYPE html>\n
      <html>
        <head>
          <style type="text/css">
            img {
                max-width: 100%;
                max-height: 100%;
                margin: 0 auto;
            }
            body { margin: 0; }
          </style>
        </head>
        <body>
          <img src="${uri}" height="${height}" align="middle" />
        </body>
      </html>
    `;

    return (
      <WebView
        startInLoadingState={showWebviewLoader}
        renderLoading={showWebviewLoader ? this.renderLoader : null}
        {...restOfProps}
        source={{ html }}
      />
    );
  }
}

Remove extra margin around SVG images


#!/usr/bin/env node
'use strict';

var
  clipboard = require('copy-paste'),
  request   = require('request');

var
  FAILURE_EXIT = 1,
  SUCCESS_EXIT = 1;

var options = {
  url: 'http://www.lgtm.in/g',
  method: 'GET',
  json: true
};

request(options, function (error, response, json) {
  if (error) {
    console.log("Error:", error);
    return 1;
  }
  var lgtm = "![LGTM]("+ json.imageUrl +")";
  return clipboard.copy(lgtm);
});

#!/usr/bin/env node
'use strict';

var
  clipboard = require('copy-paste'),
  request   = require('request');

var
  FAILURE_EXIT = 1,
  SUCCESS_EXIT = 1;

var options = {
  url: 'http://www.lgtm.in/g',
  method: 'GET',
  json: true
};

request(options, function (error, response, json) {
  if (error) {
    console.log("Error:", error);
    return 1;
  }
  var lgtm = "![LGTM]("+ json.imageUrl +")";
  console.log(lgtm);
  return clipboard.copy(lgtm);
});

Add log to see if it's working or not


module.exports = EventSender;

function EventSender(httpResponse) {
  this.httpResponse = httpResponse;
  this.httpResponse.setHeader('Content-Type', 'text/event-stream');
}

EventSender.prototype.send = function EventSender_send(event) {
  if (typeof(event.data) === 'undefined') {
    event.data = '';
  } else if (typeof(event.data) !== 'string') {
    event.data = JSON.stringify(event.data);
  }
  this.httpResponse.write(
    (event.name ? 'event: ' + event.name + '\n' : '') +
    dataize(event.data) +
    '\n\n'
  );
};

function dataize(string) {
  return string.split('\n').map(function (line) {
    return 'data: ' + line;
  }).join('\n');
}

module.exports = EventSender;

var assert = require('assert');

function EventSender(httpResponse) {
  assert(httpResponse);
  assert.equal(typeof(httpResponse.setHeader), 'function', "The HTTP response must have a #setHeader() method.");
  assert.equal(typeof(httpResponse.write), 'function', "The HTTP response must have a #write() method.");

  this.httpResponse = httpResponse;
  this.httpResponse.setHeader('Content-Type', 'text/event-stream');
}

EventSender.prototype.send = function EventSender_send(event) {
  if (typeof(event.data) === 'undefined') {
    event.data = '';
  } else if (typeof(event.data) !== 'string') {
    event.data = JSON.stringify(event.data);
  }
  this.httpResponse.write(
    (event.name ? 'event: ' + event.name + '\n' : '') +
    dataize(event.data) +
    '\n\n'
  );
};

function dataize(string) {
  return string.split('\n').map(function (line) {
    return 'data: ' + line;
  }).join('\n');
}

Add assertions about the constructor parameter


app.service('TopicService', ['$rootScope', '$firebase', function($rootScope, $firebase) {
  var topicsRef = $firebase(fb.child('topics'));

  this.list = function() {
    return topicsRef;
  };

  this.add = function(topic) {
    topicsRef.$add(topic);
  };

  this.remove = function(topic) {
    topicsRef.$child(topic.$id).$remove();
  };

}]);

app.service('TopicService', ['$rootScope', '$firebase', function($rootScope, $firebase) {
  var topicsRef = $firebase(fb.child('topics'));

  this.list = function() {
    return topicsRef;
  };

  this.add = function(topic) {
    topic['user'] = $rootScope.user.given_name;
    topicsRef.$add(topic);
  };

  this.remove = function(topic) {
    topicsRef.$child(topic.$id).$remove();
  };

}]);

Add user reference to topic


"use strict";
define([], function(){
	var FocusDirective =  function ($parse) {
			return{
				link : function(scope, element,attrs) {
					scope.$watch($parse(attrs.focus), function(value) {
						if (value === true)
							element[0].focus();
					});
				}
			}
        };
	FocusDirective.$inject = ['$parse'];
	return {
		focus: FocusDirective
	};
});

"use strict";
define([], function(){
	var FocusDirective =  function ($timeout,$parse) {
			return{
				link : function(scope, element,attrs) {
					scope.$watch($parse(attrs.focus), function(value) {
						if (value === true)
							$timeout(function(){element[0].focus();});
					});
				}
			}
        };
	FocusDirective.$inject = ['$timeout','$parse'];
	return {
		focus: FocusDirective
	};
});

Implement timeout on focus directive


var mongoose     = require('mongoose');
var Schema       = mongoose.Schema;

var Objectid = mongoose.Schema.Types.ObjectId;
var Mixed = mongoose.Schema.Types.Mixed;

var TagSchema   = new Schema({
	name: { type: String, unique: true, index: true, set: toLower },
	type: { type: String, index: true }
});

TagSchema.set("_perms", {
	admin: "crud",
	user: "cr",
	all: "r"
});

function toLower (v) {
	return v.toLowerCase();
}

module.exports = mongoose.model('Tag', TagSchema);

var mongoose     = require('mongoose');
var Schema       = mongoose.Schema;

var Objectid = mongoose.Schema.Types.ObjectId;
var Mixed = mongoose.Schema.Types.Mixed;

var TagSchema   = new Schema({
	name: { type: String, unique: true, index: true, set: toLower },
	type: { type: String, index: true }
});

TagSchema.set("_perms", {
	admin: "crud",
	user: "cr",
	all: "cr"
});

function toLower (v) {
	return v.toLowerCase();
}

module.exports = mongoose.model('Tag', TagSchema);

Allow all users to add tags


import Ember from 'ember';

/**
 * @module components
 * @class sl-pagination-per-page-select
 */
export default Ember.Component.extend({

    /**
     * Class names for the root element
     *
     * @property {array} classNames
     */
    classNames: [ 'sl-pagination-per-page-select form-inline' ],

    /**
     * HTML tag name for the root element
     *
     * @property {string} tagName
     * @default "span"
     */
    tagName: 'span'
});

import Ember from 'ember';

/** @module sl-components/components/sl-pagination-per-page-select */
export default Ember.Component.extend({

    /**
     * HTML tag name for the root element
     *
     * @property {Ember.String} tagName
     * @default  "span"
     */
    tagName: 'span',

    /**
     * Class names for the root element
     *
     * @property {Ember.Array} classNames
     */
    classNames: [ 'sl-pagination-per-page-select form-inline' ]
});

Refactor to follow style guides


var options = require('optimist').argv;
var express = require('express');
var app = express();

app.configure(function(){
  app.set('port', options.port || process.env.PORT || 3000);
});

app.get('/', (function(){
  var started = new Date();
  return function(req,res) {
    res.send({
      started: started,
      uptime: (Date.now() - Number(started)) / 1000
    });
  }
})());

app.listen(app.get('port'), function() {
  console.log('express-app listening on http://localhost:%d', app.get('port'));
});

var options = require('optimist').argv;
var express = require('express');
var app = express();

app.configure(function(){
  app.set('port', options.port || process.env.PORT || 3000);
});

app.get('/', (function(){
  var started = new Date();
  return function(req,res) {
    res.send({
      started: started,
      uptime: (Date.now() - Number(started)) / 1000
    });
  }
})());

console.log('express-app listening on http://localhost:%d', app.get('port'));
app.listen(app.get('port'));

Print the port that will be listened to


/*
    Copyright 2015 Leafbird

  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.
*/

describe('configure', function() {

  it('verify if a leafbird global object has defined', function() {
    expect(leafbird).toBeDefined();
  });

  it('verify if leafbird global variable has a Leafbird object instance',
    function() {
      if(!(leafbird instanceof Leafbird)) {
        fail('leafbird global variable is not a Leafbird instance.');
      }
    }
  );

  it('verify if Leafbird has a configure method', function() {
    if(typeof leafbird.configure !== 'function') {
      fail('The Leafbird object has not a configure method');
    }
  });

  it('verify if configure method make configuration on the leafbird object',
    function() {
      leafbird.configure({});
      expect(leafbird.config).toEqual(undefined);
    }
  );
});

/*
    Copyright 2015 Leafbird

  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.
*/

describe('configure', function() {

  it('verify if a leafbird global object has defined', function() {
    expect(leafbird).toBeDefined();
  });

  it('verify if leafbird global variable has a Leafbird object instance',
    function() {
      if(!(leafbird instanceof Leafbird)) {
        fail('leafbird global variable is not a Leafbird instance.');
      }
    }
  );

  it('verify if Leafbird has a configure method', function() {
    if(typeof leafbird.configure !== 'function') {
      fail('The Leafbird object has not a configure method');
    }
  });

  it('verify if configure method make configuration on the leafbird object',
    function() {
      var configObject = {
        "someConfig": "someValue"
      };

      leafbird.configure(configObject);
      expect(leafbird.config).toEqual(configObject);
    }
  );

});

Change test of configure() to validate if configure sets de parameters on the Leafbird config


const path = require('path')

// Private: re-join the segments split from an absolute path to form another absolute path.
function absolute (...parts) {
  const candidate = path.join(...parts)
  return path.isAbsolute(candidate) ? candidate : path.join(path.sep, candidate)
}

module.exports = {absolute}

const path = require('path')

// Private: re-join the segments split from an absolute path to form another absolute path.
function absolute (...parts) {
  let candidate = parts.length !== 1 ? path.join(parts) : parts[0]
  if (process.platform === 'win32' && /^[A-Z]:$/.test(candidate)) candidate += '\\'
  return path.isAbsolute(candidate) ? candidate : path.join(path.sep, candidate)
}

module.exports = {absolute}

Handle win32 drive letters when reconstituting paths


var RadiodanClient  = require('./lib/radiodan-client'),
    MessagingClient = require('./lib/messaging-client');

module.exports.create = function (opts) {
  opts = opts || {};

  var client = MessagingClient.create(opts);
  return RadiodanClient.create(client);
};

var RadiodanClient  = require('./lib/radiodan-client'),
    MessagingClient = require('./lib/messaging-client'),
    logger = require('./lib/utils').logger;

module.exports.create = function (opts) {
  opts = opts || {};

  var client = MessagingClient.create(opts);
  return RadiodanClient.create(client);
};

module.exports.setLogLevel = function (level) {
  logger.setLevel(level);
};

Allow caller to set custom log level


/*global define*/
define([
    'underscore',
    'backbone',
    'marionette'
], function (_, Backbone) {
    'use strict';

    var GraphiteModel = Backbone.Model.extend({
        url: function() {
            throw('you need to define a url function');
        },
        parse: function(resp) {
            return _.reduce(resp, function(memo, value) {
                memo[value.text] = value.id;
                return memo;
            }, {});
        },
        initialize: function(attrs, options) {
            this.graphiteHost = Backbone.Marionette.getOption(options, 'graphiteHost');
        },
        fetchMetrics: function(host) {
            this.host = host;
            return this.fetch();
        },
        defaults: {
        }
    });

    return GraphiteModel;
});

/*global define*/
define([
        'underscore',
        'backbone',
        'marionette'
], function(_, Backbone) {
    'use strict';

    var GraphiteModel = Backbone.Model.extend({
        url: function() {
            throw ('you need to define a url function');
        },
        parse: function(resp) {
            return _.reduce(resp, function(memo, value) {
                memo[value.text] = value.id;
                return memo;
            }, {});
        },
        initialize: function(attrs, options) {
            this.graphiteHost = Backbone.Marionette.getOption(options, 'graphiteHost');
        },
        fetchMetrics: function(host) {
            this.host = host;
            return this.fetch({
                reset: true
            });
        },
        defaults: {}
    });

    return GraphiteModel;
});

Reset graphite model on each request


// @flow
import { NARROW_SPACE, WIDE_SPACE, NARROW_BAR, WIDE_BAR } from "../Core/Characters"

export function rect(x: number, height: number, width: number, filled: boolean): string {
	return `<rect x="${x}" y="0" width="${width}" height="${height}" fill="${filled ? "black" : "white"}"/>`
}

export function renderBarcodeToSVG(input: string, height: number, baseWidth: number): string {
	let svg = ""
	let x = 0

	for (const char of input) {
		switch (char) {
			case NARROW_SPACE:
				svg += rect(x, height, baseWidth, false)
				x += baseWidth
				break
			case WIDE_SPACE:
				svg += rect(x, height, baseWidth * 3, false)
				x += baseWidth * 3
				break
			case NARROW_BAR:
				svg += rect(x, height, baseWidth, true)
				x += baseWidth
				break
			case WIDE_BAR:
				svg += rect(x, height, baseWidth * 3, true)
				x += baseWidth * 3
				break
		}
	}

	return `<svg viewBox="0 0 ${x} ${height}">${svg}</svg>`
}

// @flow
import { NARROW_SPACE, WIDE_SPACE, NARROW_BAR, WIDE_BAR } from "../Core/Characters"

const NARROW_WIDTH = 1
const WIDE_WIDTH = 3

export function rect(x: number, wide: boolean, filled: boolean): string {
	return `<rect x="${x}" y="0" width="${wide ? WIDE_WIDTH : NARROW_WIDTH}" height="1" fill="${filled ? "black" : "white"}"/>`
}

export function renderBarcodeToSVG(input: string): string {
	let svg = ""
	let x = 0

	for (const char of input) {
		switch (char) {
			case NARROW_SPACE:
				svg += rect(x, false, false)
				x += NARROW_WIDTH
				break
			case WIDE_SPACE:
				svg += rect(x, true, false)
				x += WIDE_WIDTH
				break
			case NARROW_BAR:
				svg += rect(x, false, true)
				x += NARROW_WIDTH
				break
			case WIDE_BAR:
				svg += rect(x, true, true)
				x += WIDE_WIDTH
				break
		}
	}

	return `<svg viewBox="0 0 ${x} 1">${svg}</svg>`
}

Make SVG dimensions normalized and remove width and height attrs.


import $ from 'jquery';
import { onMessage, addMessage } from '../messageQueue.js';
import { getCurrentScene } from '../currentScene.js';

export default class {
  constructor() {
    this.$frame = $('#game');
  }
  start() {
    this.messageBox = $('<div class="message-box">');
    this.$frame.append(this.messageBox);
    onMessage((message) => this.displayMessage(message));
    addMessage(getCurrentScene().descriptionMessage());
  }
  displayMessage(message) {
    this.messageBox.children().addClass('disabled');
    this.messageBox.append(message);
    this.$frame.scrollTop(this.$frame[0].scrollHeight);
  }
}

import $ from 'jquery';
import Tooltip from '../Tooltip.js';
import { onMessage, addMessage } from '../messageQueue.js';
import { getCurrentScene } from '../currentScene.js';

export default class {
  constructor() {
    this.$frame = $('#game');
  }
  start() {
    this.messageBox = $('<div class="message-box">');
    this.$frame.append(this.messageBox);
    onMessage((message) => this.displayMessage(message));
    addMessage(getCurrentScene().descriptionMessage());
  }
  displayMessage(message) {
    this.messageBox.children().addClass('disabled');
    this.messageBox.append(message);
    for (var el of this.messageBox.find(".tooltip")) {
      new Tooltip(el);
    }
    this.$frame.scrollTop(this.$frame[0].scrollHeight);
  }
}

Initialize tooltips when showing message


import { UPDATE_SEARCH_PARAMS } from "../actions";

const searchParamsReducer = ( state = {
  reviewed: false,
  quality_grade: "needs_id",
  verifiable: true
}, action ) => {
  if ( action.type === UPDATE_SEARCH_PARAMS ) {
    return Object.assign( {}, state, action.params );
  }
  return state;
};

export default searchParamsReducer;

import { UPDATE_SEARCH_PARAMS } from "../actions";

const searchParamsReducer = ( state = {
  reviewed: false,
  verifiable: true,
  // This is a hack to get around our node API's cache control settings, since
  // it defaults to something, and we hit obs search repeatedly for stats. A
  // better approach might be to have a separate endpoints that delivers these
  // stats uncached, or disable cache-control when viewer_id is set or
  // something.
  ttl: -1
}, action ) => {
  if ( action.type === UPDATE_SEARCH_PARAMS ) {
    return Object.assign( {}, state, action.params );
  }
  return state;
};

export default searchParamsReducer;

Fix issue with cache-control screwing up reviewed stats.


var BaseView = require('views/map-view');

module.exports = BaseView.extend({
    gRouteOptions: {
        polylineOptions: {
            strokeColor: '#e6a640'
        }
    },
    initialize: function () {
        this.collection.on('sort', this.renderDirections, this);
        this.collection.on('reset', this.render, this);
        BaseView.prototype.initialize.apply(this, arguments);
    },

    handleReset: function () {
        this.renderWaypoints();
    },

    render: function() {

        this.renderSelf();
        this.renderWaypoints();
        this.fitBounds();
        return this;
    }
});

var BaseView = require('views/map-view');

module.exports = BaseView.extend({
    gRouteOptions: {
        polylineOptions: {
            strokeColor: '#e6a640'
        }
    },
    initialize: function () {
        this.collection.on('sort', this.renderDirections, this);
        this.collection.on('reset', this.render, this);
        BaseView.prototype.initialize.apply(this, arguments);
    },

    handleReset: function () {
        this.renderWaypoints();
    },

    render: function() {

        this.renderSelf();
        this.renderWaypoints();
        this.fitBounds();
        this.clearRoutes();
        return this;
    }
});

Clear the optimized route after changing scenario


// Add your blacklisted sites to this array. Subdomain and TLD are optional and flexible.
var BLACKLIST = [
	'agolo.com',
	'youtube',
	'twitter.com',
	'mail.google'
];

/** Convert the array to an object and export it **/

var empty = {};

// Adapted from: https://egghead.io/lessons/javascript-introducing-reduce-reducing-an-array-into-an-object
var reducer = function(aggregate, element) {
	if (!aggregate[element]) {
		aggregate[element] = 1;
	}
	return aggregate;
}

module.exports = BLACKLIST.reduce(reducer, empty);

// Add your blacklisted sites to this array. Subdomain and TLD are optional and flexible.
var BLACKLIST = [
	'agolo.com',
	'youtube',
	'twitter.com',
	'mail.google',
	'imgur.com',
	'bit.ly',
	'tinyurl'
];

/** Convert the array to an object and export it **/

var empty = {};

// Adapted from: https://egghead.io/lessons/javascript-introducing-reduce-reducing-an-array-into-an-object
var reducer = function(aggregate, element) {
	if (!aggregate[element]) {
		aggregate[element] = 1;
	}
	return aggregate;
}

module.exports = BLACKLIST.reduce(reducer, empty);

Add more sites to blacklist


/* jshint node: true */

module.exports = function(environment) {
  var ENV = {
    modulePrefix: 'dummy',
    environment: environment,
    baseURL: '/',
    locationType: 'auto',
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. 'with-controller': true
      }
    },

    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    }
  };

  if (environment === 'development') {
    // ENV.APP.LOG_RESOLVER = true;
    // ENV.APP.LOG_ACTIVE_GENERATION = true;
    // ENV.APP.LOG_TRANSITIONS = true;
    // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
    // ENV.APP.LOG_VIEW_LOOKUPS = true;
  }

  if (environment === 'test') {
    // Testem prefers this...
    ENV.baseURL = '/';
    ENV.locationType = 'none';

    // keep test console output quieter
    ENV.APP.LOG_ACTIVE_GENERATION = false;
    ENV.APP.LOG_VIEW_LOOKUPS = false;

    ENV.APP.rootElement = '#ember-testing';
  }

  if (environment === 'production') {

  }

  return ENV;
};

/* jshint node: true */

module.exports = function(environment) {
  var ENV = {
    modulePrefix: 'dummy',
    environment: environment,
    baseURL: '/',
    locationType: 'auto',
    EmberENV: {
      FEATURES: {
        // Here you can enable experimental features on an ember canary build
        // e.g. 'with-controller': true
      }
    },

    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    }
  };

  if (environment === 'development') {
    // ENV.APP.LOG_RESOLVER = true;
    // ENV.APP.LOG_ACTIVE_GENERATION = true;
    // ENV.APP.LOG_TRANSITIONS = true;
    // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
    // ENV.APP.LOG_VIEW_LOOKUPS = true;
  }

  if (environment === 'test') {
    // Testem prefers this...
    ENV.baseURL = '/';
    ENV.locationType = 'none';

    // keep test console output quieter
    ENV.APP.LOG_ACTIVE_GENERATION = false;
    ENV.APP.LOG_VIEW_LOOKUPS = false;

    ENV.APP.rootElement = '#ember-testing';
  }

  if (environment === 'production') {
    ENV.baseURL = '/ember-inplace-edit';
  }

  return ENV;
};

Set base URL for production in demo


import Terrain from 'react-icons/lib/md/terrain'
import SnowFlake from 'react-icons/lib/ti/weather-snow'
import Calendar from 'react-icons/lib/fa/calendar'
import { SkiDayRow } from './SkiDayRow'

export const SkiDayList = ({days}) => (

				Date
				Resort
				Powder
				Backcountry

			{days.map((day, i) =>
				<SkiDayRow key={i}
                   resort={day.resort}
									 date={day.date}
									 powder={day.powder}
									 backcountry={day.backcountry}/>
				)}

)

import Terrain from 'react-icons/lib/md/terrain'
import SnowFlake from 'react-icons/lib/ti/weather-snow'
import Calendar from 'react-icons/lib/fa/calendar'
import { SkiDayRow } from './SkiDayRow'

export const SkiDayList = ({days}) => (

				Date
				Resort
				Powder
				Backcountry

			{days.map((day, i) =>
				<SkiDayRow key={i}
                   {...day}/>
				)}

)

Refactor using the array spread operator.


var React = require('react');
var actions = require('../actions');
var { Navigation } = require('react-router');
var QueryStore = require('../stores/query_store.js');

var QueryList = React.createClass({
    mixins: [QueryStore.listenTo, Navigation],
    getInitialState() {
        return { queries: [] };
    },
    _onChange() {
        this.setState({ queries: QueryStore.all() });
    },
    chooseQuery(q) {
        this.props.chooseQuery(q);
    },
    deleteQuery(q) {
        actions.deleteQuery(q.path);
    },
    render() {
        return

          {this.state.queries.map(q =>

                  {q.data.name}

{q.data.query}

                  {false ?  : ''}

)}

;
    }
});

module.exports = QueryList;

var React = require('react');
var actions = require('../actions');
var { Navigation } = require('react-router');
var QueryStore = require('../stores/query_store.js');

var QueryList = React.createClass({
    mixins: [QueryStore.listenTo, Navigation],
    getInitialState() {
        return { queries: [] };
    },
    _onChange() {
        this.setState({ queries: QueryStore.all() });
    },
    chooseQuery(q) {
        this.props.chooseQuery(q);
    },
    deleteQuery(q) {
        actions.deleteQuery(q.path);
    },
    render() {
        return

          {this.state.queries.map((q, i) =>

                  {q.data.name}

{q.data.query}

                  {false ?  : ''}

)}

;
    }
});

module.exports = QueryList;

Add keys to query list


/**
 *  Imports svg into items with groups
 *  Stetson Alpha - Paper.js
 *
 */

var ImportSVG = function()
{
    //initialize
    function initialize()
    {

    };

    /**
     *
     * Takes the svg dom obj and parses the data
     * to create a layer with groups (if needed) with
     * items inside. Should support nested groups.
     *
     * takes in a svg object (xml dom)
     * returns Paper.js Layer
     */
    this.importSVG = function(svg)
    {
        return layer;
    };

    /**
     * Creates a Paper.js Group by parsing
     * a specific svg g node
     *
     * takes in a svg object (xml dom)
     * returns Paper.js Group
     */
    function importGroup(svg)
    {
        return group;
    };

    /**
     * Creates a Paper.js Path by parsing
     * a specific svg node (rect, path, circle, polygon, etc)
     * and creating the right path object based on the svg type.
     *
     * takes in a svg object (xml dom)
     * returns Paper.js Group
     */
    function importPath(svg)
    {
        return path;
    };

    initialize(); // calls the init function after class is loaded
};

/**
 *  Imports svg into items with groups
 *  Stetson Alpha - Paper.js
 *
 */

var ImportSVG = this.ImportSVG = Base.extend({
{
    //initialize
    initialize: function()
    {

    },

    /**
     *
     * Takes the svg dom obj and parses the data
     * to create a layer with groups (if needed) with
     * items inside. Should support nested groups.
     *
     * takes in a svg object (xml dom)
     * returns Paper.js Layer
     */
    importSVG: function(svg)
    {
        //TODO: return layer;
    },

    /**
     * Creates a Paper.js Group by parsing
     * a specific svg g node
     *
     * takes in a svg object (xml dom)
     * returns Paper.js Group
     */
    importGroup: function(svg)
    {
        //TODO: return group;
    },

    /**
     * Creates a Paper.js Path by parsing
     * a specific svg node (rect, path, circle, polygon, etc)
     * and creating the right path object based on the svg type.
     *
     * takes in a svg object (xml dom)
     * returns Paper.js Group
     */
    importPath: function(svg)
    {
        //TODO: return path;
    }
});

Reformat the code to match the rest of Paper.js


/* eslint-disable no-underscore-dangle */

import { avoidWarnForRequire } from './utils';
import { toggleNetworkInspect } from './networkInspect';

let availableDevMenuMethods = {};

export const checkAvailableDevMenuMethods = async (enableNetworkInspect = false) => {
  const done = await avoidWarnForRequire('NativeModules', 'AsyncStorage');
  const NativeModules = window.__DEV__ ? window.require('NativeModules') : {};
  const AsyncStorage = window.__DEV__ ? window.require('AsyncStorage') : {};
  done();

  // RN 0.43 use DevSettings, DevMenu will be deprecated
  const DevSettings = NativeModules.DevSettings || NativeModules.DevMenu;
  // Currently `show dev menu` is only on DevMenu
  const showDevMenu =
    (DevSettings && DevSettings.show) || NativeModules.DevMenu
      ? NativeModules.DevMenu.show
      : undefined;

  const methods = {
    ...DevSettings,
    show: showDevMenu,
    networkInspect: toggleNetworkInspect,
    clearAsyncStorage: () => AsyncStorage.clear().catch(f => f),
  };
  const result = Object.keys(methods).filter(key => !!methods[key]);
  availableDevMenuMethods = methods;

  toggleNetworkInspect(enableNetworkInspect);
  postMessage({ __AVAILABLE_METHODS_CAN_CALL_BY_RNDEBUGGER__: result });
};

export const invokeDevMenuMethod = (name, args = []) => {
  const method = availableDevMenuMethods[name];
  if (method) method(...args);
};

/* eslint-disable no-underscore-dangle */

import { avoidWarnForRequire } from './utils';
import { toggleNetworkInspect } from './networkInspect';

let availableDevMenuMethods = {};

export const checkAvailableDevMenuMethods = async (enableNetworkInspect = false) => {
  const done = await avoidWarnForRequire('NativeModules', 'AsyncStorage');
  const NativeModules = window.__DEV__ ? window.require('NativeModules') : {};
  const AsyncStorage = window.__DEV__ ? window.require('AsyncStorage') : {};
  done();

  // RN 0.43 use DevSettings, DevMenu will be deprecated
  const DevSettings = NativeModules.DevSettings || NativeModules.DevMenu;
  // Currently `show dev menu` is only on DevMenu
  const showDevMenu =
    (DevSettings && DevSettings.show) ||
    (NativeModules.DevMenu && NativeModules.DevMenu.show) ||
    undefined;

  const methods = {
    ...DevSettings,
    show: showDevMenu,
    networkInspect: toggleNetworkInspect,
    clearAsyncStorage: () => AsyncStorage.clear().catch(f => f),
  };
  const result = Object.keys(methods).filter(key => !!methods[key]);
  availableDevMenuMethods = methods;

  toggleNetworkInspect(enableNetworkInspect);
  postMessage({ __AVAILABLE_METHODS_CAN_CALL_BY_RNDEBUGGER__: result });
};

export const invokeDevMenuMethod = (name, args = []) => {
  const method = availableDevMenuMethods[name];
  if (method) method(...args);
};

Fix get showDevMenu on worker


import Ember from 'ember';

const { trim } = Ember.$;

export function cleanQuery(query) {
  return trim(query).replace(/[\-,?~!@#$%&*+\-'="]/, '');
}

import Ember from 'ember';

const { trim } = Ember.$;

export function cleanQuery(query) {
  return trim(query).replace(/[\-,?~!@#$%&*+\-'="]/, ' ');
}

Replace bad chars with a space when cleaning up queries


'use strict';
const problem47 = require('./problem-0047');

describe('consecutiveDistinctPrimeFactors', () => {
  xit('finds first consecutive numbers with distinct prime factors for known input', () => {
    let max = Number.MAX_SAFE_INTEGER;
    expect(problem47.consecutiveDistinctPrimeFactors(max, 1, 2, 2)).toEqual([14]);
    expect(problem47.consecutiveDistinctPrimeFactors(max, 1, 3, 3)).toEqual([644]);
  });

  it('finds all consecutive numbers with distinct prime factors up to max', () => {
    expect(problem47.consecutiveDistinctPrimeFactors(37, null, 2, 2)).toEqual([14, 20, 21, 33, 34, 35]);
  });
});

'use strict';
const problem47 = require('./problem-0047');

describe('consecutiveDistinctPrimeFactors', () => {
  it('finds first consecutive numbers with distinct prime factors for known input', () => {
    let max = Number.MAX_SAFE_INTEGER;
    expect(problem47.consecutiveDistinctPrimeFactors(max, 1, 2, 2)).toEqual([14]);
    expect(problem47.consecutiveDistinctPrimeFactors(max, 1, 3, 3)).toEqual([644]);
  });

  it('finds all consecutive numbers with distinct prime factors up to max', () => {
    expect(problem47.consecutiveDistinctPrimeFactors(37, null, 2, 2)).toEqual([14, 20, 21, 33, 34, 35]);
  });
});

Fix test for project euler 47


export function up(knex) {
  return knex.schema.table('comments', (table) => {
    table.integer('hide_type').defaultTo(0).notNullable();
    table.index('hide_type', 'comments_hide_type_idx', 'btree');
  });
}

export function down(knex) {
  return knex.schema.table('comments', (table) => {
    table.dropIndex('', 'comments_hide_type_idx');
    table.dropColumn('hide_type');
  });
}

export async function up(knex) {
  await knex.schema
    .table('comments', (table) => {
      table.integer('hide_type').defaultTo(0).notNullable();
      table.index('hide_type', 'comments_hide_type_idx', 'btree');
    })
    .raw('alter table "comments" alter column "user_id" drop not null')
    .raw('alter table "comments" add constraint "comments_user_id_check" check (("hide_type" = 0) = ("user_id" is not null))');
}

export async function down(knex) {
  const { rows: [{ exists }] } = await knex.raw('select exists(select 1 from "comments" where "user_id" is null)');
  if (exists) {
    throw new Error('There are comments with null value in "user_id" column. Remove them before start this migration.');
  }

  await knex.schema
    .raw('alter table "comments" drop constraint "comments_user_id_check"')
    .raw('alter table "comments" alter column "user_id" set not null')
    .table('comments', (table) => {
      table.dropIndex('', 'comments_hide_type_idx');
      table.dropColumn('hide_type');
    });
}

Allow null in comments.user_id in DB migration


import React, { PropTypes } from 'react';
import { createStyleSheet } from 'stylishly';
import Paper from 'material-ui/Paper';

const styleSheet = createStyleSheet('FlatButtons', (theme) => {
  return {
    root: theme.mixins.gutters({
      paddingTop: 5,
      paddingBottom: 5,
    }),
  };
});

export default function PaperSheet(props, context) {
  const classes = context.styleManager.render(styleSheet);
  return (

      <Paper className={classes.root} zDepth={4}>

This is a sheet of paper.

          Paper can be used to build surface or other elements for your application.

      </Paper>

  );
}

PaperSheet.contextTypes = {
  styleManager: PropTypes.object.isRequired,
};

import React, { PropTypes } from 'react';
import { createStyleSheet } from 'stylishly';
import Paper from 'material-ui/Paper';

const styleSheet = createStyleSheet('PaperSheet', (theme) => {
  return {
    root: theme.mixins.gutters({
      paddingTop: 5,
      paddingBottom: 5,
    }),
  };
});

export default function PaperSheet(props, context) {
  const classes = context.styleManager.render(styleSheet);
  return (

      <Paper className={classes.root} zDepth={4}>

This is a sheet of paper.

          Paper can be used to build surface or other elements for your application.

      </Paper>

  );
}

PaperSheet.contextTypes = {
  styleManager: PropTypes.object.isRequired,
};

Fix paper stylesheet name in docs


import React from 'react';
import { Link } from 'react-router';

import Icon from '../widgets/Icon';
import Avatar from '../widgets/Avatar';

import './UserList.scss';

export default class UserList extends React.Component {
  render() {
    return (
      <div className="UserList pvm">
        <Avatar md username={this.props.username} className="mrm" />
        <Link to={`/@${this.props.username}`}>@{this.props.username}</Link>{ ' ' }
        <Icon name="person_add" />
      </div>
    );
  }
};

import React from 'react';
import { Link } from 'react-router';

import Icon from '../widgets/Icon';
import Avatar from '../widgets/Avatar';

import './UserList.scss';

export default class UserList extends React.Component {
  render() {
    return (
      <div className="UserList pvm">
        <Avatar md username={this.props.username} className="mrm" />
        <Link to={`/@${this.props.username}`}>@{this.props.username}</Link>
      </div>
    );
  }
};

Remove add follower button in user list


import Ember from 'ember';

export default Ember.ArrayController.extend({
  persistedCats: function() {
    return this.filterBy('id');
  }.property('@each.id'),

  actions: {
    createCat: function() {
      var _this = this;

      this.get('newCat').save().then(function() {
        _this.set('newCat', _this.store.createRecord('cat'));
      });
    }
  }
});

import Ember from 'ember';

export default Ember.ArrayController.extend({
  persistedCats: function() {
    return this.filterBy('id');
  }.property('@each.id'),
  uploading: false,
  actions: {
    createCat: function() {
      var _this = this;

      this.get('newCat').save().then(function() {
        _this.set('newCat', _this.store.createRecord('cat'));
      });
    }
  }
});

Make property uploading and default = false


$('#tiny_inner_image').bind('change', function (event) {
    formElement = document.getElementById("tinymce_file_uploader");
    data = new FormData(formElement);
    ed = tinymce.get('news_type_text');

    var tmpMsg = flashes.info('', 'Bild wird hochgeladen');
    ed.getBody().setAttribute('contenteditable', 'false');
    var tinyContainer = $('.mce-tinymce.mce-container.mce-panel');
    tinyContainer.css({opacity: 0.5});

    $.ajax({
        url: $('#tinymce_file_uploader').attr('action'),
        type: 'POST',
        data: data,
        contentType: false,
        processData: false,
        success: function (response) {
            if (typeof(tinymce) != 'undefined') {
                ed.selection.setContent(response);
                // Remove uploaded image, so it is possibly to reupload the same
                $('#tiny_inner_image').closest('form').get(0).reset();
                flashes.success('', 'Bild wurde hochgeladen');
            }
        },
        error: function (response) {
            if (response.status == 400) {
                flashes.danger('', response.responseText);
            } else {
                flashes.danger('', 'Bild konnte nicht hochgeladen werden');
            }
        },
        complete: function () {
            ed.getBody().setAttribute('contenteditable', 'true');
            tmpMsg.alert('close');
            tinyContainer.css({opacity: 1});
        }
    });
});

$('#tiny_inner_image').bind('change', function (event) {
    formElement = document.getElementById("tinymce_file_uploader");
    data = new FormData(formElement);
    ed = tinymce.get('news_type_text');

    var tmpMsg = flashes.info('', 'Bild wird hochgeladen');
    ed.getBody().setAttribute('contenteditable', 'false');
    var tinyContainer = $('.mce-tinymce.mce-container.mce-panel');
    tinyContainer.css({opacity: 0.5});

    $.ajax({
        url: $('#tinymce_file_uploader').attr('action'),
        type: 'POST',
        data: data,
        contentType: false,
        processData: false,
        success: function (response) {
            if (typeof(tinymce) != 'undefined') {
                ed.selection.setContent(response);
                flashes.success('', 'Bild wurde hochgeladen');
            }
        },
        error: function (response) {
            if (response.status == 400) {
                flashes.danger('', response.responseText);
            } else {
                flashes.danger('', 'Bild konnte nicht hochgeladen werden');
            }
        },
        complete: function () {
            $('#tiny_inner_image').closest('form').get(0).reset();
            ed.getBody().setAttribute('contenteditable', 'true');
            tmpMsg.alert('close');
            tinyContainer.css({opacity: 1});
        }
    });
});

Reset image, even after error


require (['dojo/domReady!'], function () {

});

require ([
    'dojo/query',
    'dojo/dom-class',
    'dojo/topic',
    'dojo/on',

	'dojo/domReady!'
], function (
	query,
	domClass,
	topic,
	on
) {

	var refreshButtons = query ('.js-datasource-refresh'),
		currentHarvesting = false;

	topic.subscribe ('publisher/active-tasks', function (tasks) {
		var isHarvesting = false;

		for (var i = 0; i < tasks.list.length; ++ i) {
			var task = tasks.list[i];
			if (task.message.type == 'HARVEST') {
				isHarvesting = true;
				break;
			}
		}

		if (isHarvesting === currentHarvesting) {
			return;
		}

		currentHarvesting = isHarvesting;

		refreshButtons.forEach (function (button) {
			domClass[isHarvesting ? 'add' : 'remove'] (button, 'disabled');
		});
	});

	refreshButtons.on ('click', function (e) {
		e.preventDefault ();
		e.stopPropagation ();

		if (domClass.contains (this, 'disabled')) {
			return;
		}

		domClass.add (this, 'disabled');
	});
});

Refresh button state (disabled) is updated based on active tasks.


'use strict';

/* global Connector */

if (location.href === 'http://bandzone.cz/' || location.href === 'https://bandzone.cz/') {
	Connector.playerSelector = '#stats';

	Connector.getArtist = function () {
		var text = $('.stat:has(.ui-miniaudioplayer-state-playing) h4').text().trim();
		return text || null;
	};

	Connector.getTrack = function () {
		var text = $('.stat:has(.ui-miniaudioplayer-state-playing) .songTitle').text().trim();
		return text || null;
	};

	Connector.isPlaying = function () {
		return $('.ui-miniaudioplayer-state-playing').length;
	};
} else {
	Connector.playerSelector = '#playerWidget';

	Connector.getArtist = function () {
		var text = $('.profile-name h1').text().replace($('.profile-name span').text(), '').trim();
		return text || null;
	};

	Connector.trackSelector = '.ui-state-active .ui-audioplayer-song-title';

	Connector.isPlaying = function () {
		return $('ui-audioplayer-button').text() === 'stop';
	};
}

'use strict';

/* global Connector */

if (location.href === 'http://bandzone.cz/' || location.href === 'https://bandzone.cz/') {
	Connector.playerSelector = '#stats';

	Connector.getArtist = function () {
		var text = $('.stat:has(.ui-miniaudioplayer-state-playing) h4').text().trim();
		return text || null;
	};

	Connector.getTrack = function () {
		var text = $('.stat:has(.ui-miniaudioplayer-state-playing) .songTitle').text().trim();
		return text || null;
	};

	Connector.isPlaying = function () {
		return $('.ui-miniaudioplayer-state-playing').length;
	};
} else {
	Connector.playerSelector = '#playerWidget';

	Connector.getArtist = function () {
		var text = $('.profile-name h1').text().replace($('.profile-name span').text(), '').trim();
		return text || null;
	};

	Connector.trackSelector = '.ui-state-active .ui-audioplayer-song-title';

	Connector.isPlaying = function () {
		return $('.ui-audioplayer-button').text() === 'stop';
	};
}

Fix Bandzone playing state recognition


var PluginPage = require("./PluginPage");

var page = new PluginPage("Badge", "de.appplant.cordova.plugin.badge", function(parent) {

  cordova.plugins.notification.badge.promptForPermission();

  var input = tabris.create("TextInput", {
    text: "23",
    layoutData: {left: 10, top: 10, right: 10}
  }).appendTo(parent);

  tabris.create("Button", {
    layoutData: {left: 10, top: [input, 10], right: 10},
    text: "Set Badge"
  }).appendTo(parent).on("selection", function() {
    var badge = input.get("text");
    cordova.plugins.notification.badge.set(badge);
  });

});

module.exports = page;

var PluginPage = require("./PluginPage");

var page = new PluginPage("Badge", "de.appplant.cordova.plugin.badge", function(parent) {

  var input = tabris.create("TextInput", {
    text: "23",
    layoutData: {left: 10, top: 10, right: 10}
  }).appendTo(parent);

  tabris.create("Button", {
    layoutData: {left: 10, top: [input, 10], right: 10},
    text: "Set Badge"
  }).appendTo(parent).on("selection", function() {
    var badge = input.get("text");
    cordova.plugins.notification.badge.set(badge);
  });

});

module.exports = page;

Fix cordova example error caused by badge plugin update


var http = require('http');
http.createServer(require('./lrdata').urls).listen(8080);
console.log("Server running");

process.on('uncaughtException',function(error){
    console.log(error);
})

Add top level error handler.


import express from 'express';
import { apolloServer } from 'graphql-tools';
import Schema from './data/schema';
import Mocks from './data/mocks';

const GRAPHQL_PORT = 8080;

const graphQLServer = express();
graphQLServer.use('/', apolloServer({
  graphiql: true,
  pretty: true,
  schema: Schema,
  mocks: Mocks,
}));
graphQLServer.listen(GRAPHQL_PORT, () => console.log(
  `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}`
));

import express from 'express';
import { apolloServer } from 'graphql-tools';
import Schema from './data/schema';
import Mocks from './data/mocks';

const GRAPHQL_PORT = 8080;

const graphQLServer = express();
graphQLServer.use('/graphql', apolloServer({
  graphiql: true,
  pretty: true,
  schema: Schema,
  mocks: Mocks,
}));
graphQLServer.listen(GRAPHQL_PORT, () => console.log(
  `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}/graphql`
));

Use /graphql instead of graphql


var twilio = require('twilio'),
    express = require('express'),
    orderPizza = require('orderpizza'),
    sendText = require('sendText');

var app = express();

var textResponse = function(request, response) {
    console.log('got here');
    if (twilio.validateExpressRequest(request, '08b1eaf92fd66749470c93088253c7b4', { url: 'http://samshreds.com:7890/text' })) {
        response.header('Content-Type', 'text/xml');
        var body = request.param('Body').trim();
        var from = request.param('From');
        console.log(body);
        response.send('<Response><Sms>LOL.</Sms></Response>');
    } else {
        response.statusCode = 403;
        response.render('forbidden');
    }
};

app.get('/text', textResponse);

app.listen('7890', function() {
    console.log('Visit http://localhost:7890/ in your browser to see your TwiML document!');
});

var twilio = require('twilio'),
    express = require('express'),
    orderPizza = require('orderpizza'),
    kegapi = require('kegapi'),
    sendText = require('sendText');

var app = express();

var textResponse = function(request, response) {
    console.log('got here');
    if (twilio.validateExpressRequest(request, '08b1eaf92fd66749470c93088253c7b4', { url: 'http://samshreds.com:7890/text' })) {
        response.header('Content-Type', 'text/xml');
        var body = request.param('Body').trim();
        var from = request.param('From');
        console.log(body);
        response.send('<Response><Sms>LOL.</Sms></Response>');
    } else {
        response.statusCode = 403;
        response.render('forbidden');
    }
};

app.get('/text', textResponse);

app.listen('7890', function() {
    console.log('Visit http://localhost:7890/ in your browser to see your TwiML document!');
});

setInterval(function() {
    kegapi.getDrinks(function(volume) {
        if(volume > 0) {
            sendText('+16107616189', 'I noticed you have been drinking from the keg a lot! Do you want some pizza?.', function() {});
            orderPizza();
        }
    });
}, 60000);

Add interval for checking flow meter


var React = require('react-native');
var deviceScreen = require('Dimensions').get('window');

var {
  StyleSheet,
} = React;

module.exports = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  menu: {
    flex: 1,
    backgroundColor: 'transparent',
    position: 'absolute',
    top: 0,
    left: 0,
  },
  frontView: {
    flex: 1,
    position: 'absolute',
    left: 0,
    top: 0,
    backgroundColor: '#ffffff',
    width: deviceScreen.width,
    height: deviceScreen.height,
  }
});

var React = require('react-native');
var deviceScreen = require('Dimensions').get('window');

var {
  StyleSheet,
} = React;

module.exports = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  menu: {
    flex: 1,
    backgroundColor: 'transparent',
    position: 'absolute',
    top: 0,
    left: 0,
  },
  frontView: {
    flex: 1,
    position: 'absolute',
    left: 0,
    top: 0,
    backgroundColor: 'transparent',
    width: deviceScreen.width,
    height: deviceScreen.height,
  }
});

Change background color to transparent


"use strict";

var ResourceReferenceView = require('../resource_reference').View;

var InlineFormulaView = function(node, viewFactory) {
  ResourceReferenceView.call(this, node, viewFactory);
};

InlineFormulaView.Prototype = function() {

  this.render = function() {
    var formula = this.node.document.get(this.node.target);
    var formulaView = this.viewFactory.createView(formula);
    this.el.innerHTML = formulaView.render().el.innerHTML;
    return this;
  };

};
InlineFormulaView.Prototype.prototype = ResourceReferenceView.prototype;
InlineFormulaView.prototype = new InlineFormulaView.Prototype();

module.exports = InlineFormulaView;

"use strict";

var ResourceReferenceView = require('../resource_reference').View;

var InlineFormulaView = function(node, viewFactory) {
  ResourceReferenceView.call(this, node, viewFactory);
};

InlineFormulaView.Prototype = function() {

  this.createElement = function() {
    var el = document.createElement('span');
    return el;
  };

  this.render = function() {
    var formula = this.node.document.get(this.node.target);
    var formulaView = this.viewFactory.createView(formula);
    this.el.innerHTML = formulaView.render().el.innerHTML;
    return this;
  };

};
InlineFormulaView.Prototype.prototype = ResourceReferenceView.prototype;
InlineFormulaView.prototype = new InlineFormulaView.Prototype();

module.exports = InlineFormulaView;

Fix regression (do not render inline-formulas as <a> tag)


/*
 * Copyright (C) 2014 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import router from './router'
import {monitorLtiMessages} from '@canvas/lti/jquery/messages'

router.start()
monitorLtiMessages()

/*
 * Copyright (C) 2014 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import router from './router'
import {monitorLtiMessages} from '@canvas/lti/jquery/messages'
import ready from '@instructure/ready'

ready(() => {
  router.start()
  monitorLtiMessages()
})

Fix flakey selenium specs for files


import { initOptions, keycloak } from "keycloak"
;(async() => {
  keycloak.onTokenExpired = () =>
    keycloak
      .updateToken()
      .then(() => {
        console.info("Token refreshed")
      })
      .catch(error => {
        console.warn(
          "Keycloak client failed to refresh token, re-authentication is needed"
        )
        console.warn(error)
      })

  try {
    const authenticated = await keycloak.init({ onLoad: initOptions.onLoad })
    if (!authenticated) {
      console.info("Keycloak client not authenticated, reloading page...")
      window.location.reload()
      return
    }
  } catch (error) {
    console.info("Error occurred during Keycloak client initialization")
    console.err(error)
    return
  }

  console.info("Authenticated successfully")
  try {
    require("index.js")
  } catch (error) {
    console.error(error)
  }
})()

export default keycloak

import { initOptions, keycloak } from "keycloak"
;(async() => {
  keycloak.onTokenExpired = () =>
    keycloak
      .updateToken()
      .then(() => {
        console.info("Token refreshed")
      })
      .catch(error => {
        console.warn(
          "Keycloak client failed to refresh token, re-authentication is needed"
        )
        console.warn(error)
      })

  try {
    const authenticated = await keycloak.init({ onLoad: initOptions.onLoad })
    if (!authenticated) {
      console.info("Keycloak client not authenticated, reloading page...")
      window.location.reload()
      return
    }
  } catch (error) {
    console.info("Error occurred during Keycloak client initialization")
    console.error(error)
    return
  }

  console.info("Authenticated successfully")
  try {
    require("index.js")
  } catch (error) {
    console.error(error)
  }
})()

export default keycloak

Fix typo in error handling, preventing an error to be thrown while catching a top level error


/*jshint node:true*/
module.exports = {
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed",
  "disable_watching": true,
  "launch_in_ci": [
    "PhantomJS"
  ],
  "launch_in_dev": [
    "PhantomJS",
    "Chrome"
  ]
};

module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [
    'Chrome'
  ],
  browser_args: {
    Chrome: {
      mode: 'ci',
      args: [
        // --no-sandbox is needed when running Chrome inside a container
        process.env.TRAVIS ? '--no-sandbox' : null,

        '--disable-gpu',
        '--headless',
        '--remote-debugging-port=0',
        '--window-size=1440,900'
      ].filter(Boolean)
    }
  }
};

Change to use Chrome for CI testing


'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    City = mongoose.model('City');

/**
 * Find city by id
 */
exports.city = function(req, res, next, id) {
    City.load(id, function(err, city) {
        if (err) return next(err);
        if (!city) return next(new Error('Failed to load city ' + id));
        req.city = city;
        next();
    });
};

/**
 * Show a city
 */
exports.show = function(req, res) {
    res.jsonp(req.city);
};

/**
 * List of Cities
 */
exports.all = function(req, res) {
    City.find().sort('-created').exec(function(err, cities) {
        if (err) {
            return res.jsonp(500, {
                error: 'Cannot list the cities'
            });
        }
        res.jsonp(cities);
    });
};

'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
    City = mongoose.model('City'),
    _ = require('lodash');

/**
 * Find city by id
 */
exports.city = function(req, res, next, id) {
    City.load(id, function(err, city) {
        if (err) return next(err);
        if (!city) return next(new Error('Failed to load city ' + id));
        city.records = _.sortBy(city.records, 'created');
        req.city = city;
        next();
    });
};

/**
 * Show a city
 */
exports.show = function(req, res) {
    res.jsonp(req.city);
};

/**
 * List of Cities
 */
exports.all = function(req, res) {
    City.find().exec(function(err, cities) {
        if (err) {
            return res.jsonp(500, {
                error: 'Cannot list the cities'
            });
        }

        _.each(cities, function(city){
            city.records = _.sortBy(city.records, 'created');
        });

        res.jsonp(cities);
    });
};

Order the records by creation date


"use strict";

var program = require('commander');
var path    = require('path');
var os = require('os');

var newCommand = require('./commands/new');
var pkg        = require(path.resolve(__dirname, '..', 'package.json'));

/**
 * Get the ball-rolling for the whole program
 */
module.exports = function() {
	setProgramBaseSettings();
	setNewCommand();
	initProgram();
}

/**
 * Setup the 'new' command
 */
function setNewCommand() {
	program
		.command('new')
		.description('Create a new project (on-screen wizard)')
		.action(function() {
			newCommand.init(getProgramOptions());
		});
}

/**
 * Initialise program
 */
function initProgram() {
	program.parse(process.argv);

	if (!process.argv.slice(2).length) {
		program.outputHelp();
	}
}

/**
 * Get program option flags
 */
function getProgramOptions() {
	return {
		silent: program.silent,
		verbose: program.verbose
	}
}

/**
 * Set program base settings: version, option flags
 */
function setProgramBaseSettings() {
	program
		.version(pkg.version)
		.option('-s, --silent', 'Surpress all on-screen messages')
		.option('-v, --verbose', 'Show all on-screen messages');
}

"use strict";

var program = require('commander');
var path    = require('path');
var os = require('os');

var newCommand = require('./commands/new');
var pkg        = require(path.resolve(__dirname, '..', 'package.json'));

/**
 * Get the ball-rolling for the whole program
 */
module.exports = function() {
	setProgramBaseSettings();
	setNewCommand();
	initProgram();
}

/**
 * Setup the 'new' command
 */
function setNewCommand() {
	program
		.command('new [env]')
		.description('Create a new project (on-screen wizard)')
		.option("-B, --base", "Use the base install pre-set")
		.action(function(env, options) {
			//console.log('Base install mode: ', options.base)

			newCommand.init(getProgramOptions());
		});
}

/**
 * Initialise program
 */
function initProgram() {
	program.parse(process.argv);

	if (!process.argv.slice(2).length) {
		program.outputHelp();
	}
}

/**
 * Get program option flags
 */
function getProgramOptions() {
	return {
		silent: program.silent,
		verbose: program.verbose
	}
}

/**
 * Set program base settings: version, option flags
 */
function setProgramBaseSettings() {
	program
		.version(pkg.version)
		.option('-s, --silent', 'Surpress all on-screen messages')
		.option('-v, --verbose', 'Show all on-screen messages');
}

Add base install argument to commander new command


'use strict';

var db                      = require('../../../db')
  , assign                  = require('es5-ext/object/assign')
  , getCostsPrintController = require('eregistrations/server/routes/business-process-costs-print');

module.exports = assign(require('eregistrations/server/routes/authenticated')(), {
	'costs-print': getCostsPrintController(db.BusinessProcessDemo)
});

// Server-only GET router

'use strict';

var getRoutes = require('eregistrations/server/routes/business-process')
  , db        = require('../../../db');

module.exports = getRoutes(db.BusinessProcessDemo);

Update up to changes in eregistrations


angular.module( 'app' )
.controller( 'ApplicationCtrl', function( $scope, UserSvc, jwtHelper ) {
    $scope.$on( 'login', function( _, user ) {
        $scope.currentUser = user
    })
    if (window.localStorage.token) {
        $scope.$emit( 'login', jwtHelper.decodeToken(window.localStorage.token) )
        UserSvc.getUser()
    }
    $scope.logout = function() {
        if ($scope.currentUser) {
            delete $scope.currentUser
            UserSvc.removeToken()
        }
    }
})

angular.module( 'app' )
.controller( 'ApplicationCtrl', function( $scope, $window, UserSvc, jwtHelper ) {
    $scope.$on( 'login', function( _, user ) {
        $scope.currentUser = user
    })
    if ($window.localStorage.token) {
        $scope.$emit( 'login', jwtHelper.decodeToken($window.localStorage.token) )
        UserSvc.getUser()
    }
    $scope.logout = function() {
        if ($scope.currentUser) {
            delete $scope.currentUser
            UserSvc.removeToken()
        }
    }
})

Use angular $window instead of window global


System.config({
    map : {
        'app': 'app',
        'rxjs': 'https://unpkg.com/rxjs@5.0.0-beta.6',
        '@angular/common': 'https://unpkg.com/@angular/common@2.0.0',
        '@angular/compiler': 'https://unpkg.com/@angular/compiler@2.0.0',
        '@angular/core': 'https://unpkg.com/@angular/core@2.0.0',
        '@angular/platform-browser': 'https://unpkg.com/@angular/platform-browser@2.0.0',
        '@angular/platform-browser-dynamic': 'https://unpkg.com/@angular/platform-browser-dynamic@2.0.0'
    },
    packages:{
        'app':  { main: 'main.ts',  defaultExtension: 'ts' },
        '@angular/common': { main: 'bundles/common.umd.js', defaultExtension: 'js' },
        '@angular/compiler': { main: 'bundles/compiler.umd.js', defaultExtension: 'js' },
        '@angular/core': { main: 'bundles/core.umd.js', defaultExtension: 'js' },
        '@angular/platform-browser': { main: 'bundles/platform-browser.umd.js', defaultExtension: 'js' },
        '@angular/platform-browser-dynamic': { main: 'bundles/platform-browser-dynamic.umd.js', defaultExtension: 'js' },
    },
    // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
    transpiler: 'typescript',
    typescriptOptions: {
        emitDecoratorMetadata: true
    }
});

System.config({
    map : {
        'app': 'app',
        'rxjs': 'https://unpkg.com/rxjs@5.0.0-beta.12',
        '@angular/common': 'https://unpkg.com/@angular/common@2.0.0',
        '@angular/compiler': 'https://unpkg.com/@angular/compiler@2.0.0',
        '@angular/core': 'https://unpkg.com/@angular/core@2.0.0',
        '@angular/platform-browser': 'https://unpkg.com/@angular/platform-browser@2.0.0',
        '@angular/platform-browser-dynamic': 'https://unpkg.com/@angular/platform-browser-dynamic@2.0.0'
    },
    packages:{
        'app':  { main: 'main.ts',  defaultExtension: 'ts' },
        '@angular/common': { main: 'bundles/common.umd.js', defaultExtension: 'js' },
        '@angular/compiler': { main: 'bundles/compiler.umd.js', defaultExtension: 'js' },
        '@angular/core': { main: 'bundles/core.umd.js', defaultExtension: 'js' },
        '@angular/platform-browser': { main: 'bundles/platform-browser.umd.js', defaultExtension: 'js' },
        '@angular/platform-browser-dynamic': { main: 'bundles/platform-browser-dynamic.umd.js', defaultExtension: 'js' },
    },
    // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
    transpiler: 'typescript',
    typescriptOptions: {
        emitDecoratorMetadata: true
    }
});

Update rxjs in GTN to latest version


"use strict";

// Third Party
const curry = require("lodash/fp/curry");
const find = require("lodash/fp/find");
const flow = require("lodash/fp/flow");
const get = require("lodash/fp/get");
const startsWith = require("lodash/fp/startsWith");

module.exports = curry((fields, name) => startsWith("customField_", name) ?
  flow(find({ id: name }), get("name"))(fields) :
  name
);

"use strict";

// Third Party
const curry = require("lodash/fp/curry");
const find = require("lodash/fp/find");
const flow = require("lodash/fp/flow");
const get = require("lodash/fp/get");
const startsWith = require("lodash/fp/startsWith");
const toLower = require("lodash/fp/toLower");

module.exports = curry((fields, name) => startsWith("customfield_", toLower(name)) ?
  flow(find({ id: name }), get("name"))(fields) :
  name
);

Fix issue where customfield prefix could contain variable letters


Router.route('/', {
    name: 'home'
});

Router.route('/dashboard', {

});

Router.route('/register');

Router.route('/wizard/:step?', {
  name: 'registerWizard'
});

Router.route('/edit/:_id', {
    name: 'editRegistration'
});

// Route for individuals to review their registration(s)
Router.route('/view', {
  name: "registrantsView"
});

var requiresUserLogin = function () {
    if (!Meteor.user()) {
        this.render('login');
    } else {
        this.next();
    }
};

// Make sure user is logged in with registrar role
var requiresRegistrarAccess = function () {
  const userId = Meteor.userId();

  if (Roles.userIsInRole(userId, 'registrar')) {
    this.next();
  } else {
    this.render('notFound');
  }
};

// User login required for event registration
Router.onBeforeAction(requiresUserLogin, {only: ['register', 'view']});

// Admin-only access to certain routes
Router.onBeforeAction(requiresRegistrarAccess, {only: ['dashboard', 'editRegistration']});

Router.route('/', {
    name: 'home'
});

Router.route('/dashboard', {

});

Router.route('/register');

Router.route('/wizard/:step?', {
  name: 'registerWizard'
});

Router.route('/edit/:_id', {
    name: 'editRegistration'
});

// Route for individuals to review their registration(s)
Router.route('/view', {
  name: "registrantsView"
});

var requiresUserLogin = function () {
    if (!Meteor.user()) {
        this.render('login');
    } else {
        this.next();
    }
};

// Make sure user is logged in with registrar role
var requiresRegistrarAccess = function () {
  const userId = Meteor.userId();

  if (Roles.userIsInRole(userId, 'registrar')) {
    this.next();
  } else {
    this.render('notFound');
  }
};

// User login required for event registration
Router.onBeforeAction(requiresUserLogin, {only: ['register', 'registerWizard', 'view']});

// Admin-only access to certain routes
Router.onBeforeAction(requiresRegistrarAccess, {only: ['dashboard', 'editRegistration']});

Add requiresUserLogin to registerWizard route


/*global module:false*/
module.exports = function(grunt) {
    grunt.initConfig({
        watch: {
            reload: {
                files: ['src/*', 'src/js/*.js', 'src/css/*.css', 'grunt.js'],
                tasks: 'tinylr-reload'
            }
        }
    });

    grunt.registerTask('default', 'tinylr-start serve watch');
    grunt.registerTask('serve', 'Start server', function() {
        grunt.log.writeln('Surf to :8080/dev.html now!');
        require('./serve').listen(8080);
    });

    ['tiny-lr'].forEach(grunt.loadNpmTasks);
};

/*global module:false*/
module.exports = function(grunt) {
    grunt.initConfig({
        watch: {
            reload: {
                files: ['src/*', 'src/js/*.js', 'src/js/utils/*.js', 'src/css/*.css', 'grunt.js'],
                tasks: 'tinylr-reload'
            }
        }
    });

    grunt.registerTask('default', 'tinylr-start serve watch');
    grunt.registerTask('serve', 'Start server', function() {
        grunt.log.writeln('Surf to :8080/dev.html now!');
        require('./serve').listen(8080);
    });

    ['tiny-lr'].forEach(grunt.loadNpmTasks);
};

Make utils to be watched


import { inject as service } from '@ember/service';
import Component from '@ember/component';
import layout from './template';
import LazyIcon from 'shared/mixins/lazy-icon';

export default Component.extend(LazyIcon, {
  scope:         service(),
  layout,
  classNames:    ['namespace-app'],
  latestVersion: null,
});

import { inject as service } from '@ember/service';
import Component from '@ember/component';
import layout from './template';
import LazyIcon from 'shared/mixins/lazy-icon';

export default Component.extend(LazyIcon, {
  scope:         service(),
  layout,
  classNames:    ['namespace-app'],
  latestVersion: null,

  didRender() {
    this.initAppIcon();
  },
});

Fix apps icon missing issue


angular.module('app').directive('ngCepValidator', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function($scope, $element, $attrs, ngModel) {
      $scope.$watch($attrs.ngModel, function(value) {
        if(value) {
          if(value.match(/^[0-9]{5}-[0-9]{3}$/)) {
            ngModel.$setValidity($attrs.ngModel, true);
          } else {
            ngModel.$setValidity($attrs.ngModel, false);
          }
        } else {
            ngModel.$setValidity($attrs.ngModel, false);
        }
      });
    }
  }
})

angular.module('app').directive('ngCepValidator', function($http) {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function($scope, $element, $attrs, ngModel) {
      $scope.$watch($attrs.ngModel, function(value) {
        if(value) {
          if(value.match(/^[0-9]{5}-[0-9]{3}$/)) {
            $http.get('http://api.postmon.com.br/v1/cep/' + value)
              .then(function(response) {
                console.log(response);
              });
            ngModel.$setValidity($attrs.ngModel, true);
          } else {
            ngModel.$setValidity($attrs.ngModel, false);
          }
        } else {
            ngModel.$setValidity($attrs.ngModel, false);
        }
      });
    }
  }
})

Insert new files, AngularJS para Zumbis, Aula 14


/**
 * Configuration for Herald
 */
{
	/*
	 * Herald core bundles
	 */
	"bundles" : [ {
		"name" : "org.cohorte.herald.api"
	}, {
		"name" : "org.cohorte.herald.core"
	} ]
}

/**
 * Configuration for Herald
 */
{
	/*
	 * Herald core bundles
	 */
	"bundles" : [ {
		"name" : "org.cohorte.herald.api"
	}, {
		"name" : "org.cohorte.herald.core"
	}, {
		"name" : "org.cohorte.herald.shell"
	} ]
}

Add herald namespace to OSGi shell in the configuration file.


var http = require('http');
var server = http.createServer().listen(8005);
var io = require('socket.io')(server);
var cookie = require('cookie');
var querystring = require('querystring');

io.use(function (socket, next) {
  if (socket.request.headers.cookie) {
    socket.request.cookie = cookie.parse(socket.request.headers.cookie);
    return next();
  }
  return next(new Error('not authorized'));
});

io.on('connection', function (socket) {
  var id = socket.request.cookie.sessionid.slice(-8);

  console.log('client connected', id);

  socket.on('client', function (data) {
    console.log('received from', id, ':', data);
    socket.broadcast.emit('server', data);
  });

  socket.on('disconnect', function (data) {
    console.log('client disconnected');
  });
});

var http = require('http');
var server = http.createServer().listen(8005);
var io = require('socket.io')(server);
var cookie = require('cookie');
var querystring = require('querystring');

io.use(function (socket, next) {
  if (socket.request.headers.cookie) {
    socket.request.cookie = cookie.parse(socket.request.headers.cookie);
    return next();
  }
  return next(new Error('not authorized'));
});

io.on('connection', function (socket) {
  socket.on('client', function (data) {
    socket.broadcast.emit('server', data);
  });
});

Remove debug output from socket.io server


import React, { Component } from 'react';
import Dialog from 'material-ui/lib/dialog';
import FlatButton from 'material-ui/lib/flat-button';
import RaisedButton from 'material-ui/lib/raised-button';

// NOTE: For emit `onTouchTap` event.
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

export default class PromoteModal extends Component {
  constructor(props) {
    super(props);
    this.state = { open: false };
  }

  handleOpen() {
    this.setState({ open: true });
  }

  handleClose() {
    this.setState({ open: false });
  }

  render() {
    const actions = [
      <FlatButton label="Cancel" primary={true} onTouchTap={this.handleClose.bind(this)} />,
      <FlatButton label="Submit" primary={true} onTouchTap={this.handleClose.bind(this)} />
    ];

    return (
      <div>
        <RaisedButton label="Modal" onTouchTap={this.handleOpen.bind(this)} />
        <Dialog title="" actions={actions} modal={true} open={this.state.open} />
      </div>
    );
  }
}

import React, { Component } from 'react';
import Dialog from 'material-ui/lib/dialog';
import FlatButton from 'material-ui/lib/flat-button';
import RaisedButton from 'material-ui/lib/raised-button';

// NOTE: For emit `onTouchTap` event.
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

export default class PromoteModal extends Component {
  constructor(props) {
    super(props);
    this.state = { open: false };
  }

  handleOpen() {
    this.setState({ open: true });
  }

  handleClose() {
    this.props.onHidePromoteModal();
    this.setState({ open: this.props.open });
  }

  render() {
    const actions = [
      <FlatButton label="Cancel" primary={true} onTouchTap={this.handleClose.bind(this)} />,
      <FlatButton label="Submit" primary={true} onTouchTap={this.handleClose.bind(this)} />
    ];

    return (
      <div>
        <Dialog title="" actions={actions} modal={true} open={this.props.open} />
      </div>
    );
  }
}

Use `open` of props. and close hander call onHidePromoteModal action.


/**
 *
 * @source: error.js
 *
 * @licstart  The following is the entire license notice for the
 *  JavaScript code in this page.
 *
 * Copyright (C) 2014  Richard Louie Orilla
 *
 *
 * The JavaScript code in this page is free software: you can
 * redistribute it and/or modify it under the terms of the GNU
 * General Public License (GNU GPL) as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version.  The code is distributed WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.
 *
 * As additional permission under GNU GPL version 3 section 7, you
 * may distribute non-source (e.g., minimized or compacted) forms of
 * that code without the copy of the GNU GPL normally required by
 * section 4, provided you include this license notice and a URL
 * through which recipients can access the Corresponding Source.
 *
 * @licend  The above is the entire license notice
 * for the JavaScript code in this page.
 *
 */

function Error (line, symbol, detail) {

	this.line = line;
	this.symbol = symbol;
	this.detail = detail;
}

var errorHandler = {

	count: {

		value: 0,
		reset: function () {

			errorHandler.value = 0;
		}
	}
}

/**
 *
 * @source: error.js
 *
 * @licstart  The following is the entire license notice for the
 *  JavaScript code in this page.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * @licend  The above is the entire license notice
 * for the JavaScript code in this page.
 *
 */

function Error (line, symbol, detail) {

	this.line = line;
	this.symbol = symbol;
	this.detail = detail;
}

var errorHandler = {

	count: {

		value: 0,
		reset: function () {

			errorHandler.value = 0;
		}
	}
}

Change license from GPL3 to MPL2


/**
 * Production environment settings
 *
 * This file can include shared settings for a production environment,
 * such as API keys or remote database passwords.  If you're using
 * a version control solution for your Sails app, this file will
 * be committed to your repository unless you add it to your .gitignore
 * file.  If your repository will be publicly viewable, don't add
 * any private information to this file!
 *
 */

module.exports = {

  /***************************************************************************
   * Set the default database connection for models in the production        *
   * environment (see config/connections.js and config/models.js )           *
   ***************************************************************************/

  // models: {
  //   connection: 'someMysqlServer'
  // },

  /***************************************************************************
   * Set the port in the production environment to 80                        *
   ***************************************************************************/

  // port: 80,

  /***************************************************************************
   * Set the log level in production environment to "silent"                 *
   ***************************************************************************/

  // log: {
  //   level: "silent"
  // }
  connections: {
    postgresql: {
      adapter: 'sails-postgresql',
      url: process.env.DATABASE_URL,
      pool: false,
      ssl: true,
      schema: true
    }
  }

};

/**
 * Production environment settings
 *
 * This file can include shared settings for a production environment,
 * such as API keys or remote database passwords.  If you're using
 * a version control solution for your Sails app, this file will
 * be committed to your repository unless you add it to your .gitignore
 * file.  If your repository will be publicly viewable, don't add
 * any private information to this file!
 *
 */

module.exports = {

  /***************************************************************************
   * Set the default database connection for models in the production        *
   * environment (see config/connections.js and config/models.js )           *
   ***************************************************************************/

  // models: {
  //   connection: 'someMysqlServer'
  // },

  /***************************************************************************
   * Set the port in the production environment to 80                        *
   ***************************************************************************/

  // port: 80,

  /***************************************************************************
   * Set the log level in production environment to "silent"                 *
   ***************************************************************************/

  // log: {
  //   level: "silent"
  // }
  connections: {
    postgresql: {
      adapter: 'sails-postgresql',
      url: process.env.DATABASE_URL,
      pool: false,
      ssl: true,
      schema: true
    }
  },
  push: {
    gcm: process.env.GCMKey
  }

};

Set GCM key for Heroku


#!/usr/bin/env node

'use strict';

process.logging = function() {
  return console.log;
};

process.logStream = process.stdout;

var dictator = require('..');
var fs = require('fs');

var filename = process.argv[2] || 'dictator.json';
var procs = JSON.parse(fs.readFileSync(filename));

dictator.rule(procs);
process.on('SIGINT', function() { dictator.terminate(procs); });
process.on('exit', function() { dictator.terminate(procs); });

#!/usr/bin/env node

'use strict';

process.logging = function() {
  return console.log;
};

process.logStream = process.stdout;
process.logStream.setMaxListeners(0);

var dictator = require('..');
var fs = require('fs');

var filename = process.argv[2] || 'dictator.json';
var procs = JSON.parse(fs.readFileSync(filename));

dictator.rule(procs);
process.on('SIGINT', function() { dictator.terminate(procs); });
process.on('exit', function() { dictator.terminate(procs); });

Disable stdout max listener limit


var fs = require('fs')

var contents = fs.readFileSync(process.argv[2])
var lines = contents.toString().split('\n').length - 1
console.log(lines)

// メモ：'utf8'を'readFileSync'に二つ目の関数として渡すと'.toString'なくて
// も動いていますよ！
// fs.readFileSync(process.argv[2], 'utf8').split('\n').length - 1

var fs = require('fs')

var contents = fs.readFileSync(process.argv[2])
var lines = contents.toString().split('\n').length - 1
console.log(lines)

// 注：'readFileSync' の二つ目の引数に 'utf8' を渡すと、
// '.toString' を使わずに文字列を受け取ることが出来ます！
// fs.readFileSync(process.argv[2], 'utf8').split('\n').length - 1

Update Japanese Message on My_First_Io


'use strict';

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

function createColumnsObj(lists) {
  var columns = {};

  for(var list in lists) {
    lists[list].forEach(function(column) {
      columns[column.name] = 0;
    });
  }

  return columns;
}

exports.cumulativeFlow = function(cards, lists) {
  var columns = createColumnsObj(lists);

  cards.forEach(function(card) {
    card.time.listTime.forEach(function(step) {
      var isInList = utils.searchList(step.list.id, lists);
      if (isInList && step.duration) {
        columns[step.list.name] += step.duration;
      }
    });
  });

  return columns;
};

'use strict';

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

function createColumnsObj(lists) {
  var columns = {};

  for(var list in lists) {
    lists[list].forEach(function(column) {
      columns[column.name] = 0;
    });
  }

  return columns;
}

exports.cumulativeFlow = function(cards, lists) {
  var columns = createColumnsObj(lists);

  cards.forEach(function(card) {
    var listName = utils.searchList(card.idList, lists);

    if (listName === 'done') {
      card.time.listTime.forEach(function(step) {
        columns[step.list.name] += step.duration;
      });
    }

  });

  var cumulativeFlow = [];
  for (var column in columns) {
    var current = {};

    if (columns[column]) {
      current = {
        name: column,
        data: utils.getHumanReadableTime(columns[column])
      };

      cumulativeFlow.push(current);
    }
  }
  return cumulativeFlow;
};

Add cumulative flow values for graph


import * as Backbone from 'backbone';
import SearchBoxView from '../views/searchBox-view';
import SearchResultsView from '../views/searchResults-view';
import dispatcher from '../helpers/dispatcher';

class AppRouter extends Backbone.Router {

  get routes() {
    return {
      '': 'loadDefault',
      'search/(?*queryString)': 'showSearchResults'
    };
  }

  initialize() {
    this.listenTo(dispatcher, 'router:go', this.go);
  }

  go(route) {
    this.navigate(route, {trigger: true});
  }

  loadDefault() {
    new SearchBoxView();
  }

  showSearchResults(queryString) {
    new SearchResultsView({query: queryString});
  }

}

export default AppRouter;

import * as Backbone from 'backbone';
import Items from '../collections/items';
import SearchBoxView from '../views/searchBox-view';
import SearchResultsView from '../views/searchResults-view';
import DocumentSet from '../helpers/search';
import dispatcher from '../helpers/dispatcher';

class AppRouter extends Backbone.Router {

  get routes() {
    return {
      '': 'loadDefault',
      'search/(?*queryString)': 'showSearchResults'
    };
  }

  initialize() {
    this.listenTo(dispatcher, 'router:go', this.go);
  }

  go(route) {
    this.navigate(route, {trigger: true});
  }

  loadDefault() {
    new SearchBoxView();
  }

  showSearchResults(queryString) {
    let q = queryString.substring(2);

    DocumentSet.search(q).then(function(result) {
      let currentDocuments = new DocumentSet(result).documents;
      let docCollection = new Items(currentDocuments);
      new SearchResultsView({collection: docCollection}).render();
    });
  }

}

export default AppRouter;

Use search class to get data and create an item collection